当前位置: 首页 > news >正文

[Unreal shader]深度缓冲重建世界坐标

UE中通过深度缓冲重建世界空间坐标原理和Unity shader重建原理基本一致,但是UE中重建世界坐标的实现路径与Unity是不一致的 :

• Unity中使用SAMPLE_DEPTH_TEXTUR采样的是原始深度值(RawDepth),是一个范围[0,1]的非线性深度值;UE中SceneDepth节点获取的是真实距离的线性深度(Linearepth),单位是厘米。

• Unity和UE的坐标系不同,Unity是左手坐标系,Y轴向上 (Y-Up),Z轴向前;UE是左手坐标系,Z轴向上 (Z-Up),X轴向前。这意味着Unity和UE的矩阵内容不同,Unity 的逆矩阵和 UE 的逆矩阵,里面的 16 个数字是不一样的;Clip Space 方向不同,Unity 的 UV 原点通常在左下角 (OpenGL) 或左上角 (DX),UE 的 UV 原点在左上角。这会导致 Y 轴方向可能需要1 - y反转。

• Unity和UE的单位不一致,Unity的世界单位是米,UE的世界单位是厘米,因此按照Unity的路径重建出来是 (0, 1, 0),在 UE 里重建出来则是 (0, 0, 100)。如果不缩放,特效大小会差 100 倍

因此在UE中通过深度缓冲重建世界坐标,建议使用射线法:

1. 射线法

原理公式:P´ = C + ->v * Depth / ->v * ->f

如图所示,P是像素的屏幕空间位置(ScreenPosition),是像素的世界空间位置(WorldPosition);C是相机的世界空间位置(CameraPosition);->v是相机指向像素P视线的向量(CameraVector),->f是相机朝向向量(CameraDirrction);Depth是像素P的深度值。由向量->v点乘向量->f可得向量->v->f的夹角θ的余弦值cosθDepth/cosθ获取CP´长度。向量->v* 距离CP´获得向量->CP´,向量->CP´只表示到相机C的相对距离,要获取在世界空间中的绝对位置,还需要加上相机C的世界空间坐标,即可确定像素P在世界空间中的位置。公式如下:

UE节点连线图:

2. 逆矩阵重建

UE中通过逆矩阵重建世界坐标,基本逻辑和Unity一致,由裁剪空间逆矩阵反推至世界空间,但在具体执行层面与Unity不一样

2.1 实现方法

UE中没有提供逆矩阵相关节点,因此需要使用CustomNode输入代码实现逆矩阵

//1.采样:获取纹理坐标,自动适配动态分辨率 (Screen Percentage) //GetSceneTextureUV 为UE内置函数,用于采样屏幕空间UV坐标 float2 ScreenUV = GetSceneTextureUV(Parameters); //获取 DeviceZ (采样0 ~ 1 的非线性深度) float deviceZ = LookupDeviceZ(ScreenUV); //2.几何重建 //获取NDC空间坐标,GetScreenPosition UE内置函数,直接获取NDC空间坐标 float2 ndcPos = GetScreenPosition(Parameters).xy; //通过NDC坐标构建裁剪空间齐次坐标 float4 ClipPos = float4(ndcPos, deviceZ, 1.0); //3.空间变换(Transform) //逆投影矩阵,由裁剪空间齐次坐标转为平移世界空间坐标 float4 TranslatedWorldPosH = mul(ClipPos, ResolvedView.ClipToTranslatedWorld); //透视除法(归一化),还原为平移世界空间笛卡尔2坐标 TranslatedWorldPos = TranslatedWorldPosH / TranslatedWorldPosH.w; //4.LWC还原(LWC Restore) //获取平移世界坐标偏移量 float3 PreViewTranslation = LWCToFloat(ResolvedView.PreViewTranslation); //还原绝对世界坐标 float3 WorldPos = TranslatedPos.xyz - PreViewTranslation; return WorldPos;

2.2 平移世界空间 (Translated World Space)

平移世界空间 (Translated World Space) 是 Unreal Engine (UE) 渲染管线中一个非常独特且核心的概念。它是 “以相机为原点,但坐标轴方向与世界保持一致” 的坐标系。

在计算机图形学中,GPU处理顶点和像素位置时,通常使用32位浮点数 (Float32)。Float32有一个致命弱点:数值越大,精度越低。如一个超大开放世界游戏中,玩家走到地图边缘(比如坐标1000000, 1000000),此时如果直接使用绝对世界坐标进行渲染计算:模型会开始疯狂抖动(顶点乱跳)、阴影会变成锯齿状或消失、物理计算会崩溃。为了解决这个问题,UE采用了一个聪明的策略:既然GPU处理大数值精度低,那我就强行让所有计算都发生在原点 (0,0,0) 附近。

• 绝对世界空间:世界原点固定不动;相机可能飞到十万八千里外;精度风险:高

• 平移世界空间:强行把世界原点移动到相机所在的位置,在渲染每一帧时,引擎会计算一个偏移量 PreViewTranslation(大约等于 - CameraPosition),所有的物体坐标,都加上这个偏移量,无论玩家走到地图哪里,在GPU看来,相机永远在 (0,0,0) 附近,所有要渲染的物体也都在相机附近。数值永远很小,精度永远完美。

http://www.jsqmd.com/news/280676/

相关文章:

  • logging库使用教程
  • 【毕业设计】基于springboot的隧道云视频监控管理信息平台设计与实现(源码+文档+远程调试,全bao定制等)
  • SpringBoot:封装 starter
  • 【课程设计/毕业设计】基于springboot的隧道云视频监控管理信息平台设计与实现隧道内事故、火灾、车辆滞留等问题监察【附源码、数据库、万字文档】
  • 滴滴 wsgsig secdd-challenge
  • RabbitMQ 在大数据领域的故障排查与解决方案
  • Linux 内核漏洞提权
  • 连接 AI 的隐形纽带:深度解构 MCP 传输层——从 Stdio 到 SSE 的实战抉择与架构差异
  • 计算机毕业设计springboot基于农科所农作物信息管理系统的设计与实现 基于SpringBoot的农业科研院所作物数据智慧管理平台的设计与实现面向农科机构的SpringBoot作物全生命周期
  • 测试转网络安全如何弯道超车?
  • Java计算机毕设之基于springboot的智慧医疗网上预约系统智慧医疗服务-智慧医疗服务平台(完整前后端代码+说明文档+LW,调试定制等)
  • 微服务架构演进实战 从单体到微服务的拆分原则与DDD入门
  • python mqgg 发送 json 文件
  • 学习日记day64
  • Java毕设项目:基于springboot的智慧医疗网上预约系统(源码+文档,讲解、调试运行,定制等)
  • GGUF、Safetensors、ONNX三种格式
  • springboot_ssm815大学生校园图书借阅购买管理系统--论文
  • #对象模型
  • 强烈安利8个AI论文平台,本科生搞定毕业论文!
  • springboot_ssm816大学运动场地预约器材租借管理系统--论文
  • springboot_ssm817学生信息管理系统--论文
  • leetcode 热题
  • [ACTF2020 新生赛]Upload 1(一句话木马加蚁剑)
  • 【深度测评】2026年护考刷题APP算法横评:为何“易小考”能成为护资备考首选?
  • 【毕业设计】基于springboot的智慧医疗网上预约系统(源码+文档+远程调试,全bao定制等)
  • RHCSA结课综合作业
  • 【课程设计/毕业设计】基于springboot的智慧医疗网上预约系统医院在线挂号与患者预约管理【附源码、数据库、万字文档】
  • springboot_ssm807古诗词数字化分享平台--论文
  • 异常检测:提示工程架构师如何识别提示数据中的异常行为?
  • 字节面试官:问你C++观察者模式,你答了7点他说不够深