floor.glsl 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. @header package main
  2. @header import sg "third-party:sokol/gfx"
  3. @vs vs
  4. layout(binding=0) uniform floor_vs_params {
  5. mat4 mvp;
  6. mat4 model;
  7. vec3 camera_pos;
  8. };
  9. in vec4 position;
  10. out vec3 world_pos;
  11. out vec3 cam_pos;
  12. out vec2 uv_coords;
  13. void main() {
  14. vec4 wp = model * position;
  15. world_pos = wp.xyz;
  16. cam_pos = camera_pos;
  17. uv_coords = world_pos.xz;
  18. gl_Position = mvp * position;
  19. }
  20. @end
  21. @fs fs
  22. in vec3 world_pos;
  23. in vec3 cam_pos;
  24. in vec2 uv_coords;
  25. out vec4 frag_color;
  26. // =========================================================================
  27. // UTILS
  28. // =========================================================================
  29. // 1. ANTI-ALIASED CHECKERBOARD (IQ Method)
  30. float getCheckerboard(vec2 p) {
  31. vec2 w = fwidth(p) + 0.001;
  32. vec2 i = 2.0 * (abs(fract((p - 0.5 * w) * 0.5) - 0.5) -
  33. abs(fract((p + 0.5 * w) * 0.5) - 0.5)) / w;
  34. return 0.5 - 0.5 * i.x * i.y;
  35. }
  36. // 2. PSEUDO-RANDOM NOISE
  37. float hash(vec2 p) {
  38. return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
  39. }
  40. void main() {
  41. float tile_size = 1.0;
  42. vec2 uv = uv_coords / tile_size;
  43. // --- 1. РАСЧЕТ ПЛОТНОСТИ ПИКСЕЛЕЙ (Исправление углов) ---
  44. // Используем length для идеальных диагоналей в углах экрана
  45. vec2 deriv = fwidth(uv);
  46. float pixel_density = length(deriv);
  47. // --- 2. БАЗОВАЯ ШАХМАТКА ---
  48. float t = getCheckerboard(uv);
  49. // --- 3. ШУМ (Безопасная шероховатость) ---
  50. // Шум исчезает на горизонте (noise_mask), чтобы не было мусора
  51. float noise_mask = 1.0 - smoothstep(0.3, 0.8, pixel_density);
  52. float grain = hash(floor(uv));
  53. // Добавляем шум, но маскируем его по расстоянию
  54. t += (grain - 0.5) * 0.1 * noise_mask;
  55. // --- 4. ЦВЕТА (ЧИСТО СЕРЫЕ) ---
  56. // Убрал все цветные смещения, остались только значения яркости
  57. vec3 col_black = vec3(0.20); // Средне-серый (было темно-серый)
  58. vec3 col_white = vec3(0.60); // Светло-серый
  59. vec3 fog_color = vec3(0.02); // Почти черный
  60. vec3 col = mix(col_black, col_white, t);
  61. // --- 5. HORIZON FADE ---
  62. float fade_start = 0.4;
  63. float fade_end = 1.8;
  64. float fade = smoothstep(fade_start, fade_end, pixel_density);
  65. // Средний серый (автоматически получается из цветов выше)
  66. vec3 mid_gray = (col_black + col_white) * 0.5;
  67. col = mix(col, mid_gray, fade);
  68. // --- 6. ТУМАН ---
  69. float dist = length(world_pos.xz - cam_pos.xz);
  70. float fog_density = 0.02;
  71. float fog = 1.0 - exp(-dist * fog_density);
  72. col = mix(col, fog_color, fog);
  73. // --- 7. ГАММА КОРРЕКЦИЯ ---
  74. col = pow(col, vec3(1.0 / 2.2));
  75. frag_color = vec4(col, 1.0);
  76. }
  77. @end
  78. @program floor vs fs