57 lines
1.9 KiB
Text
57 lines
1.9 KiB
Text
|
#version 150
|
||
|
|
||
|
// This is the terrain fragment shader. There is a lot of code in here
|
||
|
// which is not necessary to render the terrain, but included for convenience -
|
||
|
// Like generating normals from the heightmap or a simple fog effect.
|
||
|
|
||
|
// Most of the time you want to adjust this shader to get your terrain the look
|
||
|
// you want. The vertex shader most likely will stay the same.
|
||
|
|
||
|
in vec2 terrain_uv;
|
||
|
in vec3 vtx_pos;
|
||
|
out vec4 color;
|
||
|
|
||
|
uniform struct {
|
||
|
sampler2D data_texture;
|
||
|
sampler2D heightfield;
|
||
|
int view_index;
|
||
|
int terrain_size;
|
||
|
int chunk_size;
|
||
|
} ShaderTerrainMesh;
|
||
|
|
||
|
uniform sampler2D p3d_Texture0;
|
||
|
uniform vec3 wspos_camera;
|
||
|
|
||
|
// Compute normal from the heightmap, this assumes the terrain is facing z-up
|
||
|
vec3 get_terrain_normal() {
|
||
|
const float terrain_height = 50.0;
|
||
|
vec3 pixel_size = vec3(1.0, -1.0, 0) / textureSize(ShaderTerrainMesh.heightfield, 0).xxx;
|
||
|
float u0 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.yz).x * terrain_height;
|
||
|
float u1 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.xz).x * terrain_height;
|
||
|
float v0 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.zy).x * terrain_height;
|
||
|
float v1 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.zx).x * terrain_height;
|
||
|
vec3 tangent = normalize(vec3(1.0, 0, u1 - u0));
|
||
|
vec3 binormal = normalize(vec3(0, 1.0, v1 - v0));
|
||
|
return normalize(cross(tangent, binormal));
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void main() {
|
||
|
vec3 diffuse = texture(p3d_Texture0, terrain_uv * 16.0).xyz;
|
||
|
vec3 normal = get_terrain_normal();
|
||
|
|
||
|
// Add some fake lighting - you usually want to use your own lighting code here
|
||
|
vec3 fake_sun = normalize(vec3(0.7, 0.2, 0.6));
|
||
|
vec3 shading = max(0.0, dot(normal, fake_sun)) * diffuse;
|
||
|
shading += vec3(0.07, 0.07, 0.1);
|
||
|
|
||
|
|
||
|
// Fake fog
|
||
|
float dist = distance(vtx_pos, wspos_camera);
|
||
|
float fog_factor = smoothstep(0, 1, dist / 1000.0);
|
||
|
shading = mix(shading, vec3(0.7, 0.7, 0.8), fog_factor);
|
||
|
|
||
|
color = vec4(shading, 1.0);
|
||
|
}
|