#version 330 core out vec4 FragColor; // 视口大小(像素,建议传入 framebuffer 尺寸,HiDPI 下要乘 devicePixelRatio) uniform vec2 uViewport; // 以像素为单位的网格间距:细网格/粗网格 uniform float uMinorStep; uniform float uMajorStep; // 生成抗锯齿网格线(返回 0..1,1 表示在线上) float gridLine(float stepPx) { vec2 coord = gl_FragCoord.xy; vec2 q = coord / stepPx; // 距离最近网格线的归一化距离,再用 fwidth 做抗锯齿 vec2 g = abs(fract(q - 0.5) - 0.5) / fwidth(q); float line = 1.0 - min(min(g.x, g.y), 1.0); return line; } void main() { vec2 viewport = max(uViewport, vec2(1.0)); vec2 uv = gl_FragCoord.xy / viewport; // 0..1 // 背景渐变:上更亮、下稍灰,常见 3D 软件的“科技感”底色 vec3 topCol = vec3(0.99, 0.99, 1.00); vec3 botCol = vec3(0.94, 0.95, 0.98); vec3 col = mix(botCol, topCol, uv.y); // 网格线:细线 + 粗线(每隔一段更深一点) float minor = gridLine(max(uMinorStep, 1.0)); float major = gridLine(max(uMajorStep, 1.0)); vec3 minorCol = vec3(0.80, 0.82, 0.87); vec3 majorCol = vec3(0.70, 0.73, 0.80); col = mix(col, minorCol, minor * 0.22); col = mix(col, majorCol, major * 0.35); // 轻微 vignette(四角略暗),让画面更“聚焦” vec2 p = uv * 2.0 - 1.0; float v = clamp(1.0 - dot(p, p) * 0.12, 0.0, 1.0); col *= mix(1.0, v, 0.35); FragColor = vec4(col, 1.0); }