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
相关产品推荐
相关产品推荐

