out vec3 oldPos; out vec3 newPos; out vec3 ray; in vec3 position; #include #include vec3 project(vec3 origin, vec3 ray, vec3 refractedLight) { vec2 tcyl = intersectCylinder(origin, ray, poolRadius, -poolHeight, poolHeight * 2.0); origin += ray * tcyl.y; float tplane = (-origin.y - poolHeight) / refractedLight.y; return origin + refractedLight * tplane; } void main() { // Collapse vertices outside the unit circle to avoid degenerate caustic triangles if (position.x * position.x + position.y * position.y > 1.0) { oldPos = vec3(0.0); newPos = vec3(0.0); ray = vec3(0.0); gl_Position = vec4(0.0); return; } vec4 info = texture(water, position.xy * 0.5 + 0.5); info.ba *= 0.5; vec3 normal = vec3(info.b, sqrt(1.0 - dot(info.ba, info.ba)), info.a); vec3 refractedLight = refract(-light, vec3(0.0, 1.0, 0.0), IOR_AIR / IOR_WATER); vec3 basePos = vec3(position.x * poolRadius, 0.0, position.y * poolRadius); ray = refract(-light, normal, IOR_AIR / IOR_WATER); oldPos = project(basePos, refractedLight, refractedLight); newPos = project(basePos + vec3(0.0, info.r, 0.0), ray, refractedLight); vec2 normalizedPos = newPos.xz / poolRadius; vec2 refractedOffset = (refractedLight.xz / poolRadius) / refractedLight.y; gl_Position = vec4(0.75 * (normalizedPos + refractedOffset), 0.0, 1.0); }