terrain.frag.glsl 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #version 150
  2. // This is the terrain fragment shader. There is a lot of code in here
  3. // which is not necessary to render the terrain, but included for convenience -
  4. // Like generating normals from the heightmap or a simple fog effect.
  5. // Most of the time you want to adjust this shader to get your terrain the look
  6. // you want. The vertex shader most likely will stay the same.
  7. in vec2 terrain_uv;
  8. in vec3 vtx_pos;
  9. out vec4 color;
  10. uniform struct {
  11. sampler2D data_texture;
  12. sampler2D heightfield;
  13. int view_index;
  14. int terrain_size;
  15. int chunk_size;
  16. } ShaderTerrainMesh;
  17. uniform sampler2D p3d_Texture0;
  18. uniform vec3 wspos_camera;
  19. // Compute normal from the heightmap, this assumes the terrain is facing z-up
  20. vec3 get_terrain_normal() {
  21. const float terrain_height = 50.0;
  22. vec3 pixel_size = vec3(1.0, -1.0, 0) / textureSize(ShaderTerrainMesh.heightfield, 0).xxx;
  23. float u0 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.yz).x * terrain_height;
  24. float u1 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.xz).x * terrain_height;
  25. float v0 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.zy).x * terrain_height;
  26. float v1 = texture(ShaderTerrainMesh.heightfield, terrain_uv + pixel_size.zx).x * terrain_height;
  27. vec3 tangent = normalize(vec3(1.0, 0, u1 - u0));
  28. vec3 binormal = normalize(vec3(0, 1.0, v1 - v0));
  29. return normalize(cross(tangent, binormal));
  30. }
  31. void main() {
  32. vec3 diffuse = texture(p3d_Texture0, terrain_uv * 16.0).xyz;
  33. vec3 normal = get_terrain_normal();
  34. // Add some fake lighting - you usually want to use your own lighting code here
  35. vec3 fake_sun = normalize(vec3(0.7, 0.2, 0.6));
  36. vec3 shading = max(0.0, dot(normal, fake_sun)) * diffuse;
  37. shading += vec3(0.07, 0.07, 0.1);
  38. // Fake fog
  39. float dist = distance(vtx_pos, wspos_camera);
  40. float fog_factor = smoothstep(0, 1, dist / 1000.0);
  41. shading = mix(shading, vec3(0.7, 0.7, 0.8), fog_factor);
  42. color = vec4(shading, 1.0);
  43. }