我一直在尝试根据纹理中的颜色设置图块的颜色。纹理的大小相当于图块地图的大小,其中每个像素代表一个图块。我需要此信息,因为我想根据该纹理的数据在图块颜色上应用 alpha 值。
我对着色器还比较陌生,所以我正在努力弄清楚如何将图块 UV 转换为映射到纹理中的正确像素。
我尝试了以下代码,它有点有效:
vec2 global_pos = FRAGCOORD.xy;
vec2 tile_position = floor(global_pos / tile_size);
vec2 uv = tile_position / (tilemap_size / tile_size);
vec4 color_map_color = texture(corruption_base_texture, uv);
vec4 final_color = mix(COLOR, color_map_color, 0.5);
COLOR = final_color;
这使我能够从纹理中获取正确的值,尽管坐标完全偏离。它创建了一种效果,其中 TileMap 本身几乎就像一个窗口,我可以通过它查看正确的纹理。
我的猜测是,我需要对相机位置等应用额外的偏移,但具体如何,我不确定。
任何信息都会有所帮助,包括与我需要的一些偏移一起使用的着色器代码的链接。我在 GodotShaders 网站上查看了其他几个着色器,但大多数都完全实现了自己的 TileMap,而不是使用内置的。
我最终弄清楚了。我需要获取从顶点着色器绘制的图块的全局位置。我使用了 godot 文档建议的稍微修改的版本here。然后,我必须根据该位置创建一个样本点,将其限制在样本纹理内的某个范围内。这是完成的代码:
shader_type canvas_item;
uniform sampler2D corruption_base_texture : filter_nearest;
uniform vec4 tint_color : source_color;
// TODO: Add noise.
const float tile_size = 16.0;
varying flat vec2 world_pos;
void vertex() {
world_pos = (MODEL_MATRIX * vec4(VERTEX, 0.0, 1.0)).xy;
}
void fragment() {
vec4 color = texture(TEXTURE, UV);
int sample_x = int(floor((world_pos.x + tile_size / 2.0) / tile_size));
int sample_y = int(floor((world_pos.y + tile_size / 2.0) / tile_size));
float sample_value = texelFetch(corruption_base_texture, ivec2(sample_x, sample_y), 0).r;
if (sample_value > 0.0)
{
color = mix(color, tint_color, sample_value);
}
COLOR = color;
}
我希望这对遇到类似问题的人有所帮助。