|
|
@@ -0,0 +1,100 @@
|
|
|
+@header package main
|
|
|
+@header import sg "third-party:sokol/gfx"
|
|
|
+
|
|
|
+@vs vs
|
|
|
+layout(binding=0) uniform floor_vs_params {
|
|
|
+ mat4 mvp;
|
|
|
+ mat4 model;
|
|
|
+ vec3 camera_pos;
|
|
|
+};
|
|
|
+
|
|
|
+in vec4 position;
|
|
|
+
|
|
|
+out vec3 world_pos;
|
|
|
+out vec3 cam_pos;
|
|
|
+out vec2 uv_coords;
|
|
|
+
|
|
|
+void main() {
|
|
|
+ vec4 wp = model * position;
|
|
|
+ world_pos = wp.xyz;
|
|
|
+ cam_pos = camera_pos;
|
|
|
+ uv_coords = world_pos.xz;
|
|
|
+ gl_Position = mvp * position;
|
|
|
+}
|
|
|
+@end
|
|
|
+
|
|
|
+@fs fs
|
|
|
+in vec3 world_pos;
|
|
|
+in vec3 cam_pos;
|
|
|
+in vec2 uv_coords;
|
|
|
+out vec4 frag_color;
|
|
|
+
|
|
|
+// =========================================================================
|
|
|
+// UTILS
|
|
|
+// =========================================================================
|
|
|
+
|
|
|
+// 1. ANTI-ALIASED CHECKERBOARD (IQ Method)
|
|
|
+float getCheckerboard(vec2 p) {
|
|
|
+ vec2 w = fwidth(p) + 0.001;
|
|
|
+ vec2 i = 2.0 * (abs(fract((p - 0.5 * w) * 0.5) - 0.5) -
|
|
|
+ abs(fract((p + 0.5 * w) * 0.5) - 0.5)) / w;
|
|
|
+ return 0.5 - 0.5 * i.x * i.y;
|
|
|
+}
|
|
|
+
|
|
|
+// 2. PSEUDO-RANDOM NOISE
|
|
|
+float hash(vec2 p) {
|
|
|
+ return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
|
|
|
+}
|
|
|
+
|
|
|
+void main() {
|
|
|
+ float tile_size = 1.0;
|
|
|
+ vec2 uv = uv_coords / tile_size;
|
|
|
+
|
|
|
+ // --- 1. РАСЧЕТ ПЛОТНОСТИ ПИКСЕЛЕЙ (Исправление углов) ---
|
|
|
+ // Используем length для идеальных диагоналей в углах экрана
|
|
|
+ vec2 deriv = fwidth(uv);
|
|
|
+ float pixel_density = length(deriv);
|
|
|
+
|
|
|
+ // --- 2. БАЗОВАЯ ШАХМАТКА ---
|
|
|
+ float t = getCheckerboard(uv);
|
|
|
+
|
|
|
+ // --- 3. ШУМ (Безопасная шероховатость) ---
|
|
|
+ // Шум исчезает на горизонте (noise_mask), чтобы не было мусора
|
|
|
+ float noise_mask = 1.0 - smoothstep(0.3, 0.8, pixel_density);
|
|
|
+ float grain = hash(floor(uv));
|
|
|
+
|
|
|
+ // Добавляем шум, но маскируем его по расстоянию
|
|
|
+ t += (grain - 0.5) * 0.1 * noise_mask;
|
|
|
+
|
|
|
+ // --- 4. ЦВЕТА (ЧИСТО СЕРЫЕ) ---
|
|
|
+ // Убрал все цветные смещения, остались только значения яркости
|
|
|
+ vec3 col_black = vec3(0.20); // Средне-серый (было темно-серый)
|
|
|
+ vec3 col_white = vec3(0.60); // Светло-серый
|
|
|
+ vec3 fog_color = vec3(0.02); // Почти черный
|
|
|
+
|
|
|
+ vec3 col = mix(col_black, col_white, t);
|
|
|
+
|
|
|
+ // --- 5. HORIZON FADE ---
|
|
|
+ float fade_start = 0.4;
|
|
|
+ float fade_end = 1.8;
|
|
|
+ float fade = smoothstep(fade_start, fade_end, pixel_density);
|
|
|
+
|
|
|
+ // Средний серый (автоматически получается из цветов выше)
|
|
|
+ vec3 mid_gray = (col_black + col_white) * 0.5;
|
|
|
+ col = mix(col, mid_gray, fade);
|
|
|
+
|
|
|
+ // --- 6. ТУМАН ---
|
|
|
+ float dist = length(world_pos.xz - cam_pos.xz);
|
|
|
+ float fog_density = 0.02;
|
|
|
+ float fog = 1.0 - exp(-dist * fog_density);
|
|
|
+
|
|
|
+ col = mix(col, fog_color, fog);
|
|
|
+
|
|
|
+ // --- 7. ГАММА КОРРЕКЦИЯ ---
|
|
|
+ col = pow(col, vec3(1.0 / 2.2));
|
|
|
+
|
|
|
+ frag_color = vec4(col, 1.0);
|
|
|
+}
|
|
|
+@end
|
|
|
+
|
|
|
+@program floor vs fs
|