terrain.vert.glsl 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #version 150
  2. // This is the default terrain vertex shader. Most of the time you can just copy
  3. // this and reuse it, and just modify the fragment shader.
  4. in vec4 p3d_Vertex;
  5. uniform mat4 p3d_ModelViewProjectionMatrix;
  6. uniform mat4 p3d_ModelMatrix;
  7. uniform struct {
  8. sampler2D data_texture;
  9. sampler2D heightfield;
  10. int view_index;
  11. int terrain_size;
  12. int chunk_size;
  13. } ShaderTerrainMesh;
  14. out vec2 terrain_uv;
  15. out vec3 vtx_pos;
  16. void main() {
  17. // Terrain data has the layout:
  18. // x: x-pos, y: y-pos, z: size, w: clod
  19. vec4 terrain_data = texelFetch(ShaderTerrainMesh.data_texture,
  20. ivec2(gl_InstanceID, ShaderTerrainMesh.view_index), 0);
  21. // Get initial chunk position in the (0, 0, 0), (1, 1, 0) range
  22. vec3 chunk_position = p3d_Vertex.xyz;
  23. // CLOD implementation
  24. float clod_factor = smoothstep(0, 1, terrain_data.w);
  25. chunk_position.xy -= clod_factor * fract(chunk_position.xy * ShaderTerrainMesh.chunk_size / 2.0)
  26. * 2.0 / ShaderTerrainMesh.chunk_size;
  27. // Scale the chunk
  28. chunk_position *= terrain_data.z * float(ShaderTerrainMesh.chunk_size)
  29. / float(ShaderTerrainMesh.terrain_size);
  30. chunk_position.z *= ShaderTerrainMesh.chunk_size;
  31. // Offset the chunk, it is important that this happens after the scale
  32. chunk_position.xy += terrain_data.xy / float(ShaderTerrainMesh.terrain_size);
  33. // Compute the terrain UV coordinates
  34. terrain_uv = chunk_position.xy;
  35. // Sample the heightfield and offset the terrain - we do not need to multiply
  36. // the height with anything since the terrain transform is included in the
  37. // model view projection matrix.
  38. chunk_position.z += texture(ShaderTerrainMesh.heightfield, terrain_uv).x;
  39. gl_Position = p3d_ModelViewProjectionMatrix * vec4(chunk_position, 1);
  40. // Output the vertex world space position - in this case we use this to render
  41. // the fog.
  42. vtx_pos = (p3d_ModelMatrix * vec4(chunk_position, 1)).xyz;
  43. }