| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 |
- #version 150
- // This is the default terrain vertex shader. Most of the time you can just copy
- // this and reuse it, and just modify the fragment shader.
- in vec4 p3d_Vertex;
- uniform mat4 p3d_ModelViewProjectionMatrix;
- uniform mat4 p3d_ModelMatrix;
- uniform struct {
- sampler2D data_texture;
- sampler2D heightfield;
- int view_index;
- int terrain_size;
- int chunk_size;
- } ShaderTerrainMesh;
- out vec2 terrain_uv;
- out vec3 vtx_pos;
- void main() {
- // Terrain data has the layout:
- // x: x-pos, y: y-pos, z: size, w: clod
- vec4 terrain_data = texelFetch(ShaderTerrainMesh.data_texture,
- ivec2(gl_InstanceID, ShaderTerrainMesh.view_index), 0);
- // Get initial chunk position in the (0, 0, 0), (1, 1, 0) range
- vec3 chunk_position = p3d_Vertex.xyz;
- // CLOD implementation
- float clod_factor = smoothstep(0, 1, terrain_data.w);
- chunk_position.xy -= clod_factor * fract(chunk_position.xy * ShaderTerrainMesh.chunk_size / 2.0)
- * 2.0 / ShaderTerrainMesh.chunk_size;
- // Scale the chunk
- chunk_position *= terrain_data.z * float(ShaderTerrainMesh.chunk_size)
- / float(ShaderTerrainMesh.terrain_size);
- chunk_position.z *= ShaderTerrainMesh.chunk_size;
- // Offset the chunk, it is important that this happens after the scale
- chunk_position.xy += terrain_data.xy / float(ShaderTerrainMesh.terrain_size);
- // Compute the terrain UV coordinates
- terrain_uv = chunk_position.xy;
- // Sample the heightfield and offset the terrain - we do not need to multiply
- // the height with anything since the terrain transform is included in the
- // model view projection matrix.
- chunk_position.z += texture(ShaderTerrainMesh.heightfield, terrain_uv).x;
- gl_Position = p3d_ModelViewProjectionMatrix * vec4(chunk_position, 1);
- // Output the vertex world space position - in this case we use this to render
- // the fog.
- vtx_pos = (p3d_ModelMatrix * vec4(chunk_position, 1)).xyz;
- }
|