diff options
Diffstat (limited to 'ground.frag')
-rw-r--r-- | ground.frag | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/ground.frag b/ground.frag new file mode 100644 index 0000000..1938364 --- /dev/null +++ b/ground.frag @@ -0,0 +1,125 @@ +void main() +{ + gl_FragColor = vec4(1,0,0,0); +} + +#if 0 +varying vec3 light_surf; +varying vec3 eye_surf; +varying vec3 tangent_surf; +varying vec2 texcoord; +uniform sampler2D normal_sampler; +uniform sampler2D heightmap_sampler; +uniform float F0, ni; + +float schlick_fresnel(float n_dot_l) +{ + return F0 + (1 - F0) * pow(1 - n_dot_l, 5); +} + +/* This returns garbage compared to Schlick. */ +float fresnel(float v_dot_h) +{ + float c = v_dot_h; /* cos theta, v . h or l . h */ + float g = sqrt(ni * ni + c * c - 1); + float gmc = g - c; + float gpc = g + c; + float c_gpc_m_1_squared = (c * gpc - 1) * (c * gpc - 1); + float c_gmc_p_1_squared = (c * gmc + 1) * (c * gmc + 1); + + return gmc*gmc / (2 * gpc*gpc) * (1 + c_gmc_p_1_squared / + c_gpc_m_1_squared); +} + +void main() +{ + 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); + 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 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 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)); +#if 1 + D = exp(-tan2_alpha * (cos2_phi_over_m2 + sin2_phi_over_n2)); +#else + /* Ward's "computationally convenient" equation. + * Doesn't work. + */ + D = exp(-2 * (cos2_phi_over_m2 + + sin2_phi_over_n2) / + (1 + n_dot_h)); +#endif + Rs = 2 * schlick_fresnel(n_dot_l) * D / + sqrt(n_dot_l * n_dot_v) / (ward_m * ward_n); + + Rs *= step(0, n_dot_l); + Rs *= step(0, n_dot_v); + + 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); + + gl_FragColor = n_dot_l * step(0, n_dot_l) * + vec4(material_color.xyz * + (Rd * d + Rs * s), + material_color.w) + + Iia * Ra * material_color.xyzw; + + /* 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 + 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); +*/ +/* + gl_FragColor = texture2D(normal_sampler, texcoord); +*/ +} +#endif
\ No newline at end of file |