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

如何在Godot的着色器中判断相机角度以切换对应纹理

回答

核心结论

完全可以通过读取CAMERA_MATRIX实现你要的视角关联纹理切换需求,以下是具体原理和实现方案:

CAMERA_MATRIX的旋转变化逻辑

Godot着色器内置的CAMERA_MATRIX是相机的世界空间变换矩阵,存储了相机的位置、旋转、缩放信息。当相机旋转时,矩阵的前三行前三列的旋转分量会同步更新,你可以从中提取相机的当前朝向,和你预设的4个固定视角朝向做匹配。

实现方案

你可以根据实际需求选择两种实现路径:

1. 着色器内实现(性能最优)

适合需要无延迟实时切换纹理的场景,直接在片元着色器中完成朝向判断和纹理采样:

  • 预先给着色器定义4个sampler2D类型的uniform变量,分别对应4个视角的手绘投影纹理
  • 从CAMERA_MATRIX中提取相机前向向量:vec3 camera_forward = normalize(-CAMERA_MATRIX[2].xyz); (Godot中相机默认前向为-Z轴,因此需要取负得到世界空间下的前向方向)
  • 将提取到的相机前向向量,和你预设的4个视角的固定前向向量分别做点积运算,点积结果最接近1的就是当前匹配的视角
  • 采样对应视角的纹理输出即可
    示例代码片段:
shader_type spatial;
// 关闭光照,匹配2D手绘视觉效果
uniform bool disable_lighting = true;
uniform sampler2D tex_front : source_color;
uniform sampler2D tex_back : source_color;
uniform sampler2D tex_left : source_color;
uniform sampler2D tex_right : source_color;

void fragment() {
    vec3 cam_forward = normalize(-CAMERA_MATRIX[2].xyz);
    // 预设四个视角的前向方向,可根据你实际的视角设置调整数值
    vec3 dir_front = vec3(0.0, 0.0, 1.0);
    vec3 dir_back = vec3(0.0, 0.0, -1.0);
    vec3 dir_left = vec3(1.0, 0.0, 0.0);
    vec3 dir_right = vec3(-1.0, 0.0, 0.0);
    
    // 计算点积,值越大说明两个朝向越接近
    float dot_front = dot(cam_forward, dir_front);
    float dot_back = dot(cam_forward, dir_back);
    float dot_left = dot(cam_forward, dir_left);
    float dot_right = dot(cam_forward, dir_right);
    
    // 适配投影纹理的UV计算,替换原有模型UV,避免纹理错位
    vec2 proj_uv = (VIEW_MATRIX * vec4(VERTEX, 1.0)).xy * 0.5 + 0.5;
    
    // 匹配最接近的视角,采样对应纹理
    float max_dot = max(max(dot_front, dot_back), max(dot_left, dot_right));
    vec4 tex_col;
    if (max_dot == dot_front) {
        tex_col = texture(tex_front, proj_uv);
    } else if (max_dot == dot_back) {
        tex_col = texture(tex_back, proj_uv);
    } else if (max_dot == dot_left) {
        tex_col = texture(tex_left, proj_uv);
    } else {
        tex_col = texture(tex_right, proj_uv);
    }
    
    ALBEDO = tex_col.rgb;
    ALPHA = tex_col.a;
    if (disable_lighting) {
        SHADING_MODE = SHADING_MODE_UNSHADED;
    }
}

提示:如果你的模型有动画或者不规则形变,用上述VIEW_MATRIX计算投影UV的方式,能保证手绘纹理始终和相机视角对齐,不会出现拉伸错位。

2. 脚本层实现(逻辑更灵活)

如果你需要在切换视角时同步处理其他逻辑(比如播放切换动画、修改碰撞体等),可以在GDScript/C#中完成朝向判断,再给材质传递纹理索引:

  • 在脚本中每帧获取当前相机的全局前向朝向,和预设的4个视角朝向做匹配
  • 匹配完成后给材质的uniform变量传递对应纹理索引,或者直接替换材质的纹理资源
  • 这种方式不需要频繁修改着色器代码,调整视角规则更方便

内容的提问来源于stack exchange,提问作者Richard Garfield

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 09:42:02