historical/toontown-classic.git/panda/samples/shader-terrain/terrain.vert.glsl

57 lines
1.9 KiB
Text
Raw Normal View History

2024-01-16 11:20:27 -06:00
#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;
}