Godot 4中Shader无法正确渲染目标像素问题排查
解决TileSet瓦片Shader坐标计算错误问题
问题核心
你遇到的问题源于对Godot中TileSet瓦片Shader的UV范围理解偏差:当为单个瓦片应用ShaderMaterial时,Shader接收的UV是瓦片局部坐标((0,0)对应瓦片左上角,(1,1)对应瓦片右下角),而非整个图集的全局UV。原代码错误地将其当作全局UV处理,导致坐标计算出现偏差。
修正后的Shader代码
shader_type canvas_item; uniform vec2 points[3]; // 三角形顶点(瓦片局部像素坐标) uniform vec2 tile_size = vec2(32.0, 32.0); uniform vec4 modulate_color : source_color; bool point_in_triangle(vec2 p, vec2 p0, vec2 p1, vec2 p2) { vec2 v0 = p2 - p0; vec2 v1 = p1 - p0; vec2 v2 = p - p0; float dot00 = dot(v0, v0); float dot01 = dot(v0, v1); float dot02 = dot(v0, v2); float dot11 = dot(v1, v1); float dot12 = dot(v1, v2); float invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01); float u = (dot11 * dot02 - dot01 * dot12) * invDenom; float v = (dot00 * dot12 - dot01 * dot02) * invDenom; return (u >= 0.0) && (v >= 0.0) && (u + v < 1.0); } void fragment() { // 直接通过UV转换为瓦片内的相对像素坐标,无需依赖全局纹理尺寸 vec2 relative_coord = UV * tile_size; // 判断当前像素是否在三角形内 if (point_in_triangle(relative_coord, points[0], points[1], points[2])) { COLOR *= modulate_color; } }
关键修改说明
- 移除了不必要的
atlas_id参数和全局坐标计算逻辑,直接通过UV * tile_size得到瓦片内的相对像素坐标,该方式完全通用,不受纹理尺寸变化影响。 - 确保
points参数传入的是瓦片自身的局部像素坐标(例如目标三角形在32x32瓦片内的顶点坐标,如(16, 0)、(0, 32)、(32, 32))。
Shader调试技巧
新手调试Shader时,可以通过可视化坐标值快速定位问题:
- 在
fragment()函数中添加临时代码,将坐标归一化后输出为颜色:
此时瓦片会显示渐变颜色,直观验证坐标是否正确映射到瓦片范围。// 临时调试:将瓦片内坐标归一化后显示为颜色 COLOR = vec4(relative_coord / tile_size, 0.0, 1.0);
内容的提问来源于stack exchange,提问作者dx_over_dt
相关产品推荐
相关产品推荐

