#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); }