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

Godot 4 屏幕空间转世界空间的Shader调试与解决方案

在Godot 4中实现对齐世界坐标的后处理Shader

我正在尝试用Godot 4编写基于世界空间实体的后处理Shader,目标是将屏幕XY坐标映射到世界XZ坐标,让显示的网格和世界坐标对齐,同步相机的旋转、平移与缩放效果。学习相关理论后动手实践,但作为Godot新手,没法定位问题,也难以可视化错误环节。先尝试实现基础调试图案,但效果不符合预期。

最初的尝试代码

Shader代码

shader_type canvas_item;

uniform mat4 camera_projection;
uniform mat4 camera_transform;

void fragment() {    
    vec4 clip_pos = vec4(UV.x * 2.0 - 1.0, 0.0, -(UV.y * 2.0 - 1.0), 1.0);
    vec4 view_pos = inverse(camera_projection) * clip_pos;
    view_pos /= view_pos.w;
    
    vec4 world_pos = inverse(camera_transform) * view_pos;
    
    COLOR = vec4(abs(fract(world_pos.xyz * 0.1)), 1.0);
}

传递参数的GDScript代码

var camera_projection = main_camera.get_camera_projection()
material.set_shader_parameter("camera_projection", camera_projection)
var camera_transform = main_camera.global_transform
material.set_shader_parameter("camera_transform", camera_transform)

调整clip_pos使用XY坐标后效果反而更差,最终找到正确解决方案:

正确解决方案

最终Shader代码

shader_type canvas_item;

uniform mat4 camera_projection;
uniform mat4 camera_transform;
uniform float ground_height = 0.0;

void fragment() {
    vec4 clip_pos = vec4(UV * 2.0 - 1.0, 0.0, 1.0);
    clip_pos.y *= -1.0; // !!! Y轴方向转换(Godot采用Y轴向上,裁剪空间Y轴向下)
    vec4 view_pos = inverse(camera_projection) * clip_pos;
    view_pos /= view_pos.w;

    vec4 world_pos = camera_transform * view_pos; // !!! 不需要取逆

    vec3 ray_origin = camera_transform[3].xyz;

    vec3 ray_dir = normalize(world_pos.xyz - ray_origin);

    float t = (ground_height - ray_origin.y) / ray_dir.y;
    vec3 intersection = ray_origin + t * ray_dir;

    vec3 color = fract(intersection);
    COLOR = vec4(color.r, 0.0, color.b, 1.0);
}

内容的提问来源于stack exchange,提问作者shade of blue

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 18:55:07