Godot Tilemap Tile Shader:纹理像素映射瓦片颜色的坐标问题
解决TileMap瓦片与纹理像素对应时的坐标偏移问题
你的核心问题是用了**屏幕空间坐标(FRAGCOORD)**计算瓦片位置,没有考虑TileMap的世界位置和相机变换,导致坐标偏移。下面是修正方案:
关键思路
放弃FRAGCOORD,改用**世界空间坐标(WORLD_POS)**计算:
- 先获取瓦片在TileMap局部的相对位置,排除TileMap自身的世界位置偏移
- 将局部瓦片索引转换为纹理UV(每个瓦片对应纹理的一个像素)
修正后的Shader代码
shader_type canvas_item; // 需根据你的项目设置的参数 uniform vec2 tile_size = vec2(16.0, 16.0); // 单个瓦片的像素尺寸 uniform vec2 tilemap_tile_count = vec2(32.0, 32.0); // TileMap的总瓦片行列数 uniform vec2 tilemap_world_position; // TileMap的世界空间位置 uniform sampler2D corruption_base_texture; // 对应每个瓦片的纹理 void fragment() { // 计算当前瓦片在TileMap内的局部坐标 vec2 local_tile_pos = floor((WORLD_POS.xy - tilemap_world_position) / tile_size); // 限制坐标范围,避免采样到纹理边界外的无效区域 local_tile_pos = clamp(local_tile_pos, vec2(0.0), tilemap_tile_count - vec2(1.0)); // 转换为纹理UV,若TileMap的Y轴方向与纹理相反,取消下面一行的注释 vec2 uv = local_tile_pos / tilemap_tile_count; // uv.y = 1.0 - uv.y; // 采样纹理颜色 vec4 color_map_color = texture(corruption_base_texture, uv); // 应用颜色混合与alpha值(可根据需求调整混合逻辑) COLOR.rgb = mix(COLOR.rgb, color_map_color.rgb, 0.5); COLOR.a = color_map_color.a; }
参数设置说明
- tile_size:设置为你TileMap中单个瓦片的像素尺寸(比如常见的16x16)
- tilemap_tile_count:对应TileMap Inspector面板中「Size」的X和Y值(总瓦片数)
- tilemap_world_position:无需手动输入,通过脚本自动绑定TileMap的世界位置:
给TileMap添加如下GDScript:extends TileMap func _ready(): material.set_shader_param("tilemap_world_position", global_position)
为什么之前的代码会偏移?
FRAGCOORD是屏幕像素坐标,它会随相机移动、窗口缩放而变化,无法准确对应TileMap内的瓦片位置。改用WORLD_POS后,我们基于世界空间计算TileMap局部的瓦片索引,再映射到纹理UV,就不会出现偏移问题。
内容的提问来源于stack exchange,提问作者Knight Steele
相关产品推荐
相关产品推荐

