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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 22:44:57