diff options
Diffstat (limited to 'glass.frag')
-rw-r--r-- | glass.frag | 114 |
1 files changed, 64 insertions, 50 deletions
@@ -17,79 +17,93 @@ void main() { float shadow = shadow2DProj(shadow_sampler, shadow_coords).x; const vec4 material_color = vec4(0.7, 0.5, 0.3, 0.0); - vec3 l = normalize(light_surf); - vec3 v = normalize(eye_surf); - vec3 h = normalize(l + v); - vec3 t = normalize(tangent_surf); - vec3 n = texture2D(normal_sampler, texcoord).xyz * 2 - 1; - /* Hack: Reduce the significance of our normal map, which otherwise - * looks incongruous with the straight edges. - */ - n = normalize(n + vec3(0,0,1)); - float n_dot_l = dot(n, l); - float n_dot_v = dot(n, v); - float n_dot_h = dot(n, h); - float v_dot_h = dot(v, h); + vec4 color; float s = .7; float d = 1 - s; float Ii = 0.9; /*intensity of incoming light */ float Iia = .1 * Ii; /*intensity of ambient light */ - float cos2_alpha = n_dot_h * n_dot_h; - float tan2_alpha = (1 - cos2_alpha) / cos2_alpha; - float Rs; + float Rs = 0; float D; - /* Aniso BRDF from Ward's "Measuring and Modeling - * Anisotropic Reflection". - */ - - /* brushed metal */ - float ward_n = .037; - float ward_m = .063; - - /* Make phi be the angle between the projections of - * the tangent and half-angle vectors onto the - * surface plane (z=0). Doing it right would involve - * projecting onto the plane defined by n. - */ - float cos_phi = dot(normalize(t.xy), normalize(h.xy)); + float Rd = (1 - F0) * 2; - float cos2_phi_over_m2 = ((cos_phi * cos_phi) / (ward_m * ward_m)); - float sin2_phi_over_n2 = ((1 - cos_phi * cos_phi) / (ward_n * ward_n)); - D = exp(-tan2_alpha * (cos2_phi_over_m2 + sin2_phi_over_n2)); - Rs = 2 * schlick_fresnel(n_dot_l) * D / - sqrt(n_dot_l * n_dot_v) / (ward_m * ward_n); + /* Calculate ambient lighting. */ - float Rd = (1 - F0) * 2; /* Ambient occlusion factor -- sample the height map we * used to generate the normal map, and reduce intensity in * the valleys. */ float heightmap = texture2D(heightmap_sampler, texcoord).x; float Ra = Rd * (.8 + .2 * heightmap); + color = material_color * Iia * Ra; + + /* Calculate specular and diffuse lighting */ + if (shadow > 0) { + vec3 l = normalize(light_surf); + vec3 v = normalize(eye_surf); + vec3 h = normalize(l + v); + vec3 t = normalize(tangent_surf); + vec3 n = texture2D(normal_sampler, texcoord).xyz * 2 - 1; + /* Hack: Reduce the significance of our normal map, which + * otherwise looks incongruous with the straight edges. + */ + n = normalize(n + vec3(0,0,1)); + + float n_dot_l = dot(n, l); + float n_dot_v = dot(n, v); + float n_dot_h = dot(n, h); + float v_dot_h = dot(v, h); + float cos2_alpha = n_dot_h * n_dot_h; + float tan2_alpha = (1 - cos2_alpha) / cos2_alpha; - gl_FragColor = max(0, n_dot_l) * step(0, n_dot_v) * - vec4(material_color.xyz * - ((Rd * d + Rs * s) * Ii * shadow), - material_color.w) + - Iia * Ra * material_color.xyzw; + /* Aniso BRDF from Ward's "Measuring and Modeling + * Anisotropic Reflection". + */ + + /* brushed metal */ + float ward_n = .037; + float ward_m = .063; + + /* Make phi be the angle between the projections of + * the tangent and half-angle vectors onto the + * surface plane (z=0). Doing it right would involve + * projecting onto the plane defined by n. + */ + float cos_phi = dot(normalize(t.xy), normalize(h.xy)); + + float cos2_phi_over_m2 = ((cos_phi * cos_phi) / (ward_m * ward_m)); + float sin2_phi_over_n2 = ((1 - cos_phi * cos_phi) / (ward_n * ward_n)); + D = exp(-tan2_alpha * (cos2_phi_over_m2 + sin2_phi_over_n2)); + Rs = 2 * schlick_fresnel(n_dot_l) * D / + sqrt(n_dot_l * n_dot_v) / (ward_m * ward_n); + Rs *= s; + + color += max(0, n_dot_l) * step(0, n_dot_v) * + vec4(material_color.xyz * + ((Rd * d + Rs) * Ii * shadow), + material_color.w); + } + + gl_FragColor = color; /* Debugging scalars -- Map [0,1] to [0.5,1] to catch negative * values. Multiply by the step function to catch when * the scalar won't come into play because Rs == 0. */ #if 0 + /* Constant visualization */ gl_FragColor = vec4(vec3(F0 / 2 + .5), 1); #endif -/* Normal visualization */ -/* -vec3 temp = vec3((normal.x + 1) / 2, - (normal.y + 1) / 2, - (normal.z + 1) / 2); -gl_FragColor = vec4(temp.xyz, 0); -*/ -/* +#if 0 + /* Normal visualization */ + gl_FragColor = vec4((normal.x + 1) / 2, + (normal.y + 1) / 2, + (normal.z + 1) / 2, + 0); +#endif +#if 0 + /* Sampler visualization */ gl_FragColor = texture2D(normal_sampler, texcoord); -*/ +#endif } |