Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Z-Fail shadow volume

By: a guest on Feb 2nd, 2013  |  syntax: OpenGL Shading  |  size: 3.45 KB  |  views: 299  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. [vertex shader]
  2. ///////////////////
  3. /** Definitions **/
  4. #version 420 core                       // OpenGL 4.2 / GLSL 420
  5.  
  6. /////////////
  7. /** Input **/
  8. layout(location = 0) in vec4 vertex;    // Vertex positions at attribute 0
  9.  
  10. ////////////////
  11. /** Uniforms **/
  12. uniform mat4 ModelMatrix;               // Model transformation matrix
  13.  
  14. //////////////
  15. /** Output **/
  16. out vec3 worldPos;                      // World-space vertex position
  17.  
  18. //////////////////
  19. /** Procedures **/
  20.  
  21. /* Main */
  22. void main()
  23. {
  24.         // Transform vertices by their model matrix from local-space position to world-space position
  25.         worldPos = (ModelMatrix * vertex).xyz;
  26. }
  27.  
  28. [geometry shader]
  29. ///////////////////
  30. /** Definitions **/
  31. #version 420 core                               // OpenGL 4.2 / GLSL 420
  32.  
  33. layout(triangles_adjacency) in;                 // Input triangle with adjacencies
  34. layout(triangle_strip, max_vertices = 18) out;  // Output triangle strips, 18 vertices at most
  35.  
  36. /////////////
  37. /** Input **/
  38. in vec3 worldPos[];                             // World-space positions
  39.  
  40. ////////////////
  41. /** Uniforms **/
  42. uniform mat4 ViewProjectionMatrix;              // View * Projection matrix
  43. uniform vec3 LightPos;                          // Light position (in world-space)
  44. uniform vec3 Offset;                            // Offset to single object (to avoid z-fighting), vector from light to object center can work just fine
  45.  
  46. //////////////////
  47. /** Procedures **/
  48.  
  49. /* Emit Triangle */
  50. // Creates triangle from specified 3 vertices (v0, v1 and v2)
  51. void emit_triangle(in vec4 v0, in vec4 v1, in vec4 v2)
  52. {
  53.         gl_Position = ViewProjectionMatrix * v0;
  54.         EmitVertex();
  55.  
  56.         gl_Position = ViewProjectionMatrix * v1;
  57.         EmitVertex();
  58.  
  59.         gl_Position = ViewProjectionMatrix * v2;
  60.         EmitVertex();
  61.  
  62.         EndPrimitive();
  63. }
  64.  
  65. /* Process Edge */
  66. // Determines whether edge(e0, e1) is part of silhouette (e.g. adjacent triangle (e1, adj, e0) isn't lit by light), if so, then extrudes this edge to infinity
  67. void process_edge(in vec3 e0, in vec3 e1, in vec3 adj)
  68. {
  69.         vec3 n = cross(e1 - adj, e0 - adj);
  70.         vec3 l = LightPos - adj;
  71.  
  72.         if(dot(n, l) < 0.0)
  73.         {
  74.                 gl_Position = ViewProjectionMatrix * vec4(e0 + Offset, 1.0);
  75.                 EmitVertex();
  76.  
  77.                 gl_Position = ViewProjectionMatrix * vec4(e0 - LightPos, 0.0);
  78.                 EmitVertex();
  79.  
  80.                 gl_Position = ViewProjectionMatrix * vec4(e1 + Offset, 1.0);
  81.                 EmitVertex();
  82.  
  83.                 gl_Position = ViewProjectionMatrix * vec4(e1 - LightPos, 0.0);
  84.                 EmitVertex();
  85.  
  86.                 EndPrimitive();
  87.         }
  88. }
  89.  
  90. /* Main */
  91. void main()
  92. {
  93.         // Determine whether current triangle is lit by light
  94.         vec3 normal = cross(worldPos[2] - worldPos[0], worldPos[4] - worldPos[0]);
  95.         vec3 lightDir = normalize(LightPos - worldPos[0]);
  96.        
  97.         if(dot(normal, lightDir) >= 0.0)
  98.         {
  99.                 // If so, emit front cap
  100.                 emit_triangle(vec4(worldPos[0] + Offset, 1), vec4(worldPos[2] + Offset, 1), vec4(worldPos[4] + Offset, 1));
  101.                 // Emit back cap
  102.                 emit_triangle(vec4(worldPos[0] - LightPos, 0), vec4(worldPos[4] - LightPos, 0), vec4(worldPos[2] - LightPos, 0));
  103.  
  104.                 // And process whether edges are part of silhouette (if so, extrude them)
  105.                 process_edge(worldPos[0], worldPos[2], worldPos[1]);
  106.                 process_edge(worldPos[2], worldPos[4], worldPos[3]);
  107.                 process_edge(worldPos[4], worldPos[0], worldPos[5]);
  108.         }
  109. }
  110.  
  111. [pixel shader]
  112. ///////////////////
  113. /** Definitions **/
  114. #version 420 core               // OpenGL 4.2 / GLSL 420
  115.  
  116. //////////////
  117. /** Output **/
  118. out vec4 mFragColor;            // Fragment color output
  119.  
  120. //////////////////
  121. /** Procedures **/
  122.  
  123. /* Main */
  124. void main()
  125. {
  126.         // Output just black color (basically we dont write to color buffer so we don't care about color)
  127.         mFragColor = vec4(0.0, 0.0, 0.0, 0.0);
  128. }