91 lines
2.9 KiB
GLSL
91 lines
2.9 KiB
GLSL
#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);
|
||
}
|