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
相关产品推荐
相关产品推荐

