56 lines
1.9 KiB
GLSL
56 lines
1.9 KiB
GLSL
#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;
|
|
}
|