Advertisement
Guest User

terrain.vert

a guest
Oct 17th, 2013
294
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.   * @file terrain.vert
  3.   * @brief A Vertex shader for a geo-mipmapped terrain.
  4.   * It is called for a flat plane, it gets offseted in the Y direction
  5.   * by a height value, that is fetched from a texture. The normals of
  6.   * the terrain is approximated here, from the gradient. Characters (up to 4)
  7.   * cast shadow on the terrain, with shadow mapping.
  8.   */
  9. #version 330 core
  10.  
  11. // Actually this number might be modified in the C++
  12. // program's runtime, but before shader compilation.
  13. #define SHADOW_MAP_NUM 4
  14.  
  15. layout(location = 0) in ivec2 vPosition;
  16.  
  17. uniform mat4 uProjectionMatrix, uCameraMatrix;
  18. uniform ivec2 uOffset;
  19. uniform vec3 uScales;
  20. uniform sampler2D uHeightMap;
  21. uniform int uMipmapLevel;
  22.  
  23. uniform mat4 uShadowCP[SHADOW_MAP_NUM];
  24. uniform int  uNumUsedShadowMaps;
  25.  
  26. out VertexData {
  27.   vec3  w_normal;
  28.   vec3  c_pos, w_pos;
  29.   vec2  texcoord;
  30.   vec4  shadowCoord[SHADOW_MAP_NUM];
  31.   float scInvalid[SHADOW_MAP_NUM];
  32.   float invalid;
  33.   mat3  NormalMatrix;
  34. } vout;
  35.  
  36.  
  37. float fetchHeight(ivec2 texCoord) {
  38.     return texelFetch(uHeightMap, texCoord, 0).r * 255;
  39. }
  40.  
  41. void main() {
  42.     vec2 w_offsPos = (vPosition + uOffset) / 2.0;
  43.  
  44.     ivec2 tex_size = textureSize(uHeightMap, 0);
  45.     if(abs(int(w_offsPos.x)) - 1 >= tex_size.x / 2 || abs(int(w_offsPos.y)) - 1 >= tex_size.y / 2) {
  46.         vout.invalid = 1e10;
  47.         gl_Position = vec4(0.0);
  48.         return;
  49.     } else {
  50.         vout.invalid = 0.0;
  51.     }
  52.  
  53.     ivec2 iTexcoord = ivec2(w_offsPos) + tex_size / 2;
  54.     vout.texcoord = iTexcoord / vec2(tex_size);
  55.  
  56.     float height = fetchHeight(iTexcoord);
  57.     vout.w_pos = uScales * vec3(w_offsPos.x, height, w_offsPos.y);
  58.     vout.c_pos = (uCameraMatrix * vec4(vout.w_pos, 1.0)).xyz;
  59.     vec4 w_pos = vec4(vout.w_pos, 1.0);
  60.  
  61.     // The performance drop is because of this loop.
  62.     for(int i = 0; i < min(uNumUsedShadowMaps, SHADOW_MAP_NUM); ++i) {
  63.         vec4 sc = uShadowCP[i] * w_pos;
  64.         vout.shadowCoord[i] = sc;
  65.         if(sc.w == 0) {
  66.             vout.scInvalid[i] = 1e10;
  67.         } else {
  68.             sc.xyz /= sc.w;
  69.             if(abs(sc.x) > 1.0 || abs(sc.y) > 1.0 || abs(sc.z) > 1.0) {
  70.                 vout.scInvalid[i] = 1e10;
  71.             } else {
  72.                 vout.scInvalid[i] = 0.0;
  73.             }
  74.         }
  75.     }
  76.  
  77.     // -------======{[ Normals ]}======-------
  78.  
  79.     const ivec2 iNeighbours[6] = ivec2[6](
  80.         ivec2(1, 2),   ivec2(2, 0),  ivec2(1, -2),
  81.         ivec2(-1, -2), ivec2(-2, 0), ivec2(-1, 2)
  82.     );
  83.  
  84.     vec3 neighbours[6];
  85.     for(int i = 0; i < 6; i++) {
  86.         ivec2 nPos = (vPosition + uOffset + ((1 << (uMipmapLevel + 1)) * iNeighbours[i])) / 2;
  87.         ivec2 nTexcoord = nPos + tex_size / 2;
  88.         neighbours[i] = uScales * vec3(nPos.x, fetchHeight(nTexcoord), nPos.y) - vout.w_pos;
  89.     }
  90.  
  91.     vec3 temp_normal = vec3(0.0);
  92.     for(int i = 0; i < 6; i++) {
  93.         temp_normal += normalize(cross(neighbours[i], neighbours[(i+1) % 6]));
  94.     }
  95.  
  96.     vout.w_normal = normalize(temp_normal);
  97.  
  98.     vout.NormalMatrix[0] = cross(vec3(0.0, 0.0, 1.0), vout.w_normal); // tangent - approximately (1, 0, 0)
  99.     vout.NormalMatrix[1] = cross(vout.w_normal, vout.NormalMatrix[0]); // bitangent - approximately (0, 0, 1)
  100.     vout.NormalMatrix[2] = vout.w_normal; // normal - approximately (0, 1, 0)
  101.  
  102.     gl_Position = uProjectionMatrix * vec4(vout.c_pos, 1.0);
  103. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement