Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
float3 Refract(float3 position, float4 surface, float refractionIndex){
//ray origin is the camera position
float3 viewerPosition =;
//ray end is the vertex's undistorted position
float3 vertexPosition = position;
//get the vector from the camera to the vertex
float3 worldRay = vertexPosition - viewerPosition;
//normalize it for direction
float3 worldRayDir = normalize(worldRay);
//surface is a vector4 that defines a plane
float3 worldPlaneNormal =;
//define a known position on the plane
float3 worldPlaneOrigin = worldPlaneNormal * surface.w;
//get the vector result of the worldRay entering the water
float3 refraction = refract(worldRayDir, normalize(worldPlaneNormal), refractionIndex);
//raycast from the vertex, backwards along the refraction vector
float denom = dot(-worldPlaneNormal, -refraction);
float3 p010 = worldPlaneOrigin - vertexPosition;
float t = dot(p010, -worldPlaneNormal) / denom;
float3 intersection = vertexPosition + refraction * -t;
//get the vector from the camera to the intersection, this is the perceived position
float3 originToIntersection = intersection - viewerPosition;
//starting from the camera, move the vector along the perceived position vector by the original ray length
return viewerPosition + normalize(originToIntersection) * length(worldRay);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment