Files

91 lines
2.9 KiB
GLSL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#version 330 core
in vec3 vWorldPos;
in vec3 vWorldNormal;
out vec4 FragColor;
uniform vec3 uCameraPos;
uniform vec3 uRoomHalfSize;
uniform float uMinorStep;
uniform float uMajorStep;
uniform int uRenderMode; // 0=realistic, 1=dataViz (flat/unlit)
float saturate(float x) {
return clamp(x, 0.0, 1.0);
}
float gridLine(vec2 coord, float stepSize) {
stepSize = max(stepSize, 1e-4);
vec2 q = coord / stepSize;
vec2 g = abs(fract(q - 0.5) - 0.5) / fwidth(q);
return 1.0 - min(min(g.x, g.y), 1.0);
}
vec2 pickGridPlane(vec3 N, vec3 P) {
// 根据朝向选择在哪个平面画网格:
// - 地面/天花板(法线接近 ±Y用 XZ
// - 前后墙(法线接近 ±Z用 XY
// - 左右墙(法线接近 ±X用 ZY
vec3 a = abs(N);
if (a.y > a.x && a.y > a.z) return P.xz;
if (a.z > a.x) return P.xy;
return P.zy;
}
void main() {
vec3 N = normalize(vWorldNormal);
vec3 V = normalize(uCameraPos - vWorldPos);
// 区分地面/天花板/墙面配色(简单做个“房间感”)
float isFloor = step(0.8, N.y);
float isCeil = step(0.8, -N.y);
vec3 floorCol = vec3(0.90, 0.90, 0.92);
vec3 wallCol = vec3(0.96, 0.96, 0.98);
vec3 ceilCol = vec3(0.98, 0.98, 1.00);
vec3 baseCol = wallCol;
baseCol = mix(baseCol, floorCol, isFloor);
baseCol = mix(baseCol, ceilCol, isCeil);
// 在不同面上画网格:小格 + 大格
vec2 plane = pickGridPlane(N, vWorldPos);
float minor = gridLine(plane, uMinorStep);
float major = gridLine(plane, uMajorStep);
vec3 minorCol = vec3(0.78, 0.80, 0.85);
vec3 majorCol = vec3(0.68, 0.70, 0.77);
baseCol = mix(baseCol, minorCol, minor * 0.18);
baseCol = mix(baseCol, majorCol, major * 0.28);
// dataViz: flat/unlit, no lighting modulation (keep pure baseCol + grid)
if (uRenderMode == 1) {
FragColor = vec4(clamp(baseCol, 0.0, 1.0), 1.0);
return;
}
// 简单两盏灯:主光 + 补光(够用就好)
// "Front light": make the light come from the camera direction (like a headlight/flashlight).
vec3 keyL = V;
vec3 fillL = V;
float diff1 = max(dot(N, keyL), 0.0);
float diff2 = max(dot(N, fillL), 0.0);
float lighting = 0.65 + 0.25 * diff1 + 0.10 * diff2;
// 角落稍微压暗,增强“箱体/房间”感觉
vec3 p = abs(vWorldPos / max(uRoomHalfSize, vec3(1e-4)));
float corner = pow(max(p.x, max(p.y, p.z)), 6.0);
float cornerDark = mix(1.0, 0.80, corner);
// 轻微雾化:远处更亮一点点,让边界更柔和
float dist = length(uCameraPos - vWorldPos);
float fog = exp(-dist * 0.06);
vec3 fogCol = vec3(0.985, 0.987, 0.995);
vec3 col = baseCol * lighting * cornerDark;
col = mix(fogCol, col, saturate(fog));
// 增加一点边缘轮廓(靠观察方向)
float rim = pow(1.0 - saturate(dot(N, V)), 2.0);
col += rim * 0.04;
FragColor = vec4(clamp(col, 0.0, 1.0), 1.0);
}