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

Godot着色器中如何确定灯光相对于TileMap瓦片的位置?

问题

我给TileMap里的特定瓦片材质分配了Godot CanvasItem着色器,需要在着色器里获取灯光相对于瓦片底部的位置。目前我通过以下代码计算瓦片右下角坐标:

varying vec2 bottom_right_corner;

void vertex() {
    vec2 world_vertex_position = (MODEL_MATRIX * vec4(VERTEX, 0.0, 1.0)).xy;
    bottom_right_corner = floor(world_vertex_position / 32.0 + 1.0) * 32.0;
}

void light() {
    // How to compare bottom_right_corner.y with LIGHT_POSITION.y ?
}

我认为需要对坐标进行变换才能与LIGHT_POSITION做比较,但不确定具体变换方式,请问该如何实现这种比较?

解决方法

在Godot的CanvasItem着色器中,LIGHT_POSITION和你计算的bottom_right_corner处于不同坐标空间,必须统一到同一空间才能直接对比。

坐标空间差异说明

  • bottom_right_corner是通过MODEL_MATRIX转换得到的世界空间坐标。
  • LIGHT_POSITION在light()函数中默认是裁剪空间坐标,需要转换为世界空间才能和瓦片坐标匹配。

实现方案一:将灯光位置转世界空间

在顶点着色器中计算逆投影视图模型矩阵,传递到光函数中完成坐标转换:

varying vec2 bottom_right_corner;
varying mat4 inv_projection_view_model;

void vertex() {
    vec2 world_vertex_position = (MODEL_MATRIX * vec4(VERTEX, 0.0, 1.0)).xy;
    bottom_right_corner = floor(world_vertex_position / 32.0 + 1.0) * 32.0;
    
    // 计算逆矩阵,用于裁剪空间到世界空间的转换
    inv_projection_view_model = inverse(PROJECTION_MATRIX * VIEW_MATRIX * MODEL_MATRIX);
}

void light() {
    // 将裁剪空间的灯光位置转换为世界空间
    vec4 light_world_pos = inv_projection_view_model * vec4(LIGHT_POSITION, 0.0, 1.0);
    vec2 light_world_xy = light_world_pos.xy;
    
    // 现在可以直接对比y坐标
    float relative_y = bottom_right_corner.y - light_world_xy.y;
    // 根据relative_y的值实现灯光相对位置的逻辑,比如判断灯光是否在瓦片底部上方/下方
}

实现方案二:将瓦片坐标转裁剪空间

如果不需要世界空间坐标,也可以把瓦片右下角坐标转换到裁剪空间,直接和LIGHT_POSITION对比:

varying vec2 bottom_right_corner_clip;

void vertex() {
    vec2 world_vertex_position = (MODEL_MATRIX * vec4(VERTEX, 0.0, 1.0)).xy;
    vec2 bottom_right_corner_world = floor(world_vertex_position / 32.0 + 1.0) * 32.0;
    
    // 转换为裁剪空间坐标
    bottom_right_corner_clip = (PROJECTION_MATRIX * VIEW_MATRIX * vec4(bottom_right_corner_world, 0.0, 1.0)).xy;
}

void light() {
    // 直接对比裁剪空间的y坐标
    float relative_y = bottom_right_corner_clip.y - LIGHT_POSITION.y;
}

注意事项

  • 确认代码中的瓦片尺寸32.0和TileMap的瓦片大小完全一致,避免坐标计算误差。
  • 若使用Godot 4.x,矩阵变量名有所调整:PROJECTION_MATRIX改为PROJECTION,VIEW_MATRIX改为VIEW,需对应修改代码。

内容的提问来源于stack exchange,提问作者Antoine Aubry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 12:05:55