Advertisement
Guest User

Reflection shader - Fragment Shader

a guest
Jun 16th, 2012
362
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #version 150
  2. #define GL_core_profile 1
  3. #extension GL_EXT_gpu_shader4 : enable
  4.  
  5. precision highp float;
  6.  
  7. uniform sampler2DMS tex_reflection;     // Multisampled texture of processed scene (e.g. after shading, etc. done)
  8. uniform float IOR;                                      // Index of refraction (not real, just hacky stuff)
  9.  
  10. out vec3 vert_vout;                 // Vertices in view space
  11. out vec3 normal_vout;               // Normals in view space
  12. out vec3 light_vout;                // Light in view space
  13. out vec4 projCoord_vout;        // Projection coordinates (projective texcoords between -1 - 1 from camera)
  14.  
  15. out vec4 Gpu_FragColor;         // Output color to fragments
  16.  
  17. /** Main **/
  18. void main()
  19. {
  20.     // Projection coordinates for textures from <-1,1> to <0,1>
  21.     vec2 projCoord = projCoord_vout.xy / projCoord_vout.w;
  22.     projCoord *= 0.5;
  23.     projCoord += 0.5;
  24.  
  25.     vec3 E = normalize(-vert_vout);                         // Eye vector
  26.     vec3 N = normalize(normal_vout);                        // Normal vector
  27.     vec3 L = normalize(light_vout - vert_vout); // Light vector
  28.     vec3 H = normalize(L + E);                                  // Half vector
  29.  
  30.     vec3 R = normalize(reflect(E, N));                  // Reflection vector
  31.  
  32.     // Now do some *magic* to compute "reflective texture coordinates" from reflection vector
  33.     R.x *= -1.0;
  34.     R.y *= -1.0;
  35.     float m = 2.0 * sqrt(R.x * R.x + R.y * R.y + (R.z + 1.0) * (R.z + 1.0));
  36.     float s = R.x / m + 0.5;
  37.     float t = R.y / m + 0.5;
  38.  
  39.     float fresnel = 1.0 - pow(dot(E, N), 2.0);                  // Mixing reflections and refractions, not even Shlicks approx.
  40.     float specular = pow(max(dot(H, N), 0.0), 16.0);        // Specular light (Blinn)
  41.  
  42.     // Again *magic* to compute offsets for "dispersion" hack
  43.     vec2 offset = projCoord + vec2(R.x, R.y) * 0.1 * IOR;
  44.     offset.x = abs(max(floor(offset.x), 0.0) - fract(abs(offset.x)));
  45.     offset.y = abs(max(floor(offset.y), 0.0) - fract(abs(offset.y)));
  46.     ivec2 iTexCoord = ivec2(vec2(800.0, 600.0) * offset);
  47.  
  48.     // Sample refraction (with dispersion hack)
  49.     vec3 refraction;
  50.     refraction.x = texelFetch(tex_reflection, iTexCoord + ivec2(1, 0), 0).x;
  51.     refraction.y = texelFetch(tex_reflection, iTexCoord, 0).y;
  52.     refraction.z = texelFetch(tex_reflection, iTexCoord - ivec2(1, 0), 0).z;
  53.  
  54.     // Sample reflection
  55.     vec3 reflection = texelFetch(tex_reflection, ivec2(vec2(800.0, 600.0) * vec2(s, t)), 0).xyz;
  56.  
  57.     // Write out depth (logarithmic depth buffer! - to linearize the errors) + color
  58.     gl_FragDepth = log(1.0 * length(vert_vout) + 1.0) / log(1.0 * 10000.0 + 1.0) * 1.0;
  59.     Gpu_FragColor = vec4(reflection * fresnel + refraction * (1.0 - fresnel) + specular, 1.0);
  60. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement