You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GLSL如何实现基于相机距离的2D网格层级渐隐效果

实现思路
  • 从SFML侧获取相机缩放参数传入着色器
    使用sf::View控制相机时,缩放比例可通过视图尺寸计算:假设1:1原始比例下视图宽度为baseViewWidth,当前视图宽度为view.getSize().x,则缩放系数zoom = baseViewWidth / view.getSize().x,数值越大代表相机拉得越近,单位像素对应的世界坐标长度越小。将该值作为uniform float zoom传入着色器即可。
  • 为两层网格定义渐隐阈值
    新增4个可调uniform参数,分别控制区块、地块网格的渐隐触发区间:
    • chunkFadeMin:区块网格开始淡入的zoom阈值,小于该值时区块网格完全隐藏
    • chunkFadeMax:区块网格完全显示的zoom阈值,大于该值时区块网格完全不透明
    • tileFadeMin:地块网格开始淡入的zoom阈值,需大于chunkFadeMax,小于该值时地块网格完全隐藏
    • tileFadeMax:地块网格完全显示的zoom阈值,大于该值时地块网格完全不透明
  • 计算每层网格的不透明度,混合到原有渲染逻辑
    用smoothstep计算每层网格在当前zoom下的不透明度,乘到原有mix的混合系数上即可,无需改动原有抗锯齿逻辑。

修改后代码

片段着色器

#version 130

uniform vec2 chunkSize = vec2(64.0, 64.0);
uniform vec2 tileSize = vec2(16.0, 16.0);

uniform vec3 chunkBorderColor = vec3(0.0, 0.0, 1.0);
uniform vec3 tileBorderColor = vec3(0.5, 0.5, 0.5);

uniform bool drawGrid = true;
// 新增传入的相机缩放参数
uniform float zoom;
// 新增渐隐阈值参数,可根据需求在C++侧动态调整
uniform float chunkFadeMin = 0.5;
uniform float chunkFadeMax = 1.0;
uniform float tileFadeMin = 1.0;
uniform float tileFadeMax = 2.0;

in vec2 texCoords;

void main() {
    vec2 uv = texCoords.xy * chunkSize;
    
    vec3 color = vec3(1.0, 1.0, 1.0);

    if(drawGrid) {
        float aa = length(fwidth(uv));

        vec2 halfChunkSize = chunkSize / 2.0;
        vec2 halfTileSize =  tileSize / 2.0;
        vec2 a = abs(mod(uv - halfChunkSize, chunkSize) - halfChunkSize);
        vec2 b = abs(mod(uv - halfTileSize, tileSize) - halfTileSize);

        // 计算两层网格当前的不透明度
        float chunkAlpha = smoothstep(chunkFadeMin, chunkFadeMax, zoom);
        float tileAlpha = smoothstep(tileFadeMin, tileFadeMax, zoom);

        // 混合时乘上不透明度系数
        color = mix(
            color, 
            tileBorderColor, 
            smoothstep(aa, .0, min(b.x, b.y)) * tileAlpha
        );

        color = mix(
            color, 
            chunkBorderColor, 
            smoothstep(aa, .0, min(a.x, a.y)) * chunkAlpha
        );
    }

    gl_FragColor.rgb = color;
    gl_FragColor.a = 1.0;
}  

顶点着色器无需改动。

SFML侧传参示例

// 假设1:1原始比例下的视图宽度为1920
const float baseViewWidth = 1920.f;
sf::View currentView = window.getView();
float zoom = baseViewWidth / currentView.getSize().x;
// 给着色器传参
shader.setUniform("zoom", zoom);
// 可按需动态调整渐隐阈值
shader.setUniform("chunkFadeMin", 0.5f);
shader.setUniform("chunkFadeMax", 1.0f);
shader.setUniform("tileFadeMin", 1.0f);
shader.setUniform("tileFadeMax", 2.0f);

参数可根据实际显示需求调整,上述示例参数的效果为:相机拉远zoom<0.5时两层网格全隐,zoom在0.51.0区间区块网格渐入,zoom在1.02.0区间地块网格渐入,zoom>2.0时两层网格完全显示。

内容的提问来源于stack exchange,提问作者Dan Medinsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 11:24:03