aboutsummaryrefslogtreecommitdiff
path: root/data/shaders/light-refract.frag
blob: f71a283d0fc60c1614afb02698978d9bf789dd15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
uniform sampler2D DistanceMap;
uniform sampler2D NormalMap;
uniform sampler2D ImageMap;

varying vec3 vertex_normal;
varying vec4 vertex_position;
varying vec4 MapCoord;

void main()
{
    const vec4 lightSpecular = vec4(0.8, 0.8, 0.8, 1.0);
    const vec4 matSpecular = vec4(1.0, 1.0, 1.0, 1.0);
    const float matShininess = 100.0;
    const vec2 point_five = vec2(0.5);
    // Need the normalized eye direction and surface normal vectors to
    // compute the refraction vector through the "front" surface of the object.
    vec3 eye_direction = normalize(-vertex_position.xyz);
    vec3 normalized_normal = normalize(vertex_normal);
    vec3 front_refraction = refract(eye_direction, normalized_normal, 1.5);
    // Offset the base map coordinate by the refaction vector, and re-normalize
    // to texture coordinate space [0, 1].
    vec4 mc_perspective = MapCoord / MapCoord.w;
    vec4 distance_value = texture2D(DistanceMap, mc_perspective.st);
    float frontToBack = distance_value.z - mc_perspective.z;
    vec3 back_position = (front_refraction - vertex_position) + frontToBack;
    vec2 normcoord = (mc_perspective.st + front_refraction.st + point_five) * point_five;
    vec3 back_normal = texture2D(NormalMap, normcoord).xyz;
    // Now refract again, using the normal from the lookup.
    vec3 back_refraction = refract(back_position, back_normal.xyz, 1.0);
    vec2 imagecoord = (normcoord + back_refraction.st + point_five) * point_five;
    vec4 texel = texture2D(ImageMap, imagecoord);
    // Add in a specular component
    vec3 light_direction = normalize(vertex_position.xyz/vertex_position.w -
                                     LightSourcePosition.xyz/LightSourcePosition.w);
    vec3 reflection = reflect(light_direction, normalized_normal);
    float specularTerm = pow(max(0.0, dot(reflection, eye_direction)), matShininess);
    vec4 specular = (lightSpecular * matSpecular);
    gl_FragColor = (specular * specularTerm) + texel;
}