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

使用InverseViewProjection获取世界坐标存在精度不足及结果异常问题

Raymarching射线方向计算问题修复方案

现有方案问题分析

方案1(逆VP矩阵实现)问题

  • 核心错误1:裁剪空间坐标构造错误,你构造的scc = float4(p,0.0,1.0)中z值为0,对应裁剪空间近远平面中间位置,不是像素对应的正确射线终点,方向本身就存在偏差
  • 核心错误2:精度适配问题,大世界场景下直接用远平面世界坐标减相机世界坐标,大数相减会丢失32位浮点数精度,距离原点越远误差越大,表现为画面抖动

方案2(深度转世界位置实现)问题

  • 核心错误1:深度处理错误,你直接用投影矩阵输出的非线性深度乘屏幕空间射线,透视投影的深度是w分量插值得到的非线性值,直接相乘会导致比例错误,出现拉伸
  • 核心错误2:射线方向反转,normalize(cameraPos - wPos)得到的是从像素位置指向相机的向量,raymarching需要的是从相机指向像素的向量,方向写反
  • 核心错误3:矩阵乘法顺序不匹配,如果你的引擎用列向量优先(Unity、Unreal默认),矩阵乘法应该是mul(矩阵, 向量),你写的mul(pos, viewInverse)是行向量的写法,顺序反了就会出现旋转时方向翻转的问题

推荐修复实现

根据体积特效的不同需求选对应方案即可,代码已经做了简化适配,直接替换原有逻辑就行:

场景1:不需要深度,直接计算像素射线方向(适合体积雾、体积云等全屏特效)

该方案完全避免大坐标运算,不管相机离世界原点多远都不会出现抖动:

// 输入参数:uv、视图逆矩阵viewInverse、投影矩阵mProjection
uv.y = 1 - uv.y;
float2 p = uv * 2 - 1;
// 先计算视图空间下的射线方向,不涉及世界大坐标运算
float3 viewRay = float3(p.x / mProjection[0][0], p.y / mProjection[1][1], 1.0);
// 仅用视图逆矩阵的旋转分量转世界空间,避免精度损失
float3 rd = normalize(mul((float3x3)viewInverse, viewRay));

场景2:需要读取深度缓冲区计算射线(适合和场景物体交互的体积特效)

// 第一步先把硬件返回的非线性深度转成线性深度,引擎有内置函数直接用即可
// 无内置函数可用公式自己算:float linearDepth = (2 * near * far) / (far + near - (2 * depth - 1) * (far - near));
// 其中near是相机近裁剪面距离,far是相机远裁剪面距离
float linearDepth = LinearEyeDepth(depth, _ZBufferParams);

float4 DepthToViewPos(float linearDepth, float2 texCoord){
    float x = texCoord.x * 2 - 1;
    float y = texCoord.y * 2 - 1;
    float3 viewPos = float3(x / mProjection[0][0], y / mProjection[1][1], 1.0) * linearDepth;
    return float4(viewPos, 1.0);
}

float3 DepthToWorldPos(float linearDepth, float2 texCoord){
    float4 viewPos = DepthToViewPos(linearDepth, texCoord);
    // 如果还是出现翻转,把矩阵和向量的顺序反过来就行:mul(viewPos, viewInverse)
    float4 worldPos = mul(viewInverse, viewPos);
    return worldPos.xyz;
}

float3 wPos = DepthToWorldPos(linearDepth, uv);
// 修正方向为相机指向像素位置
float3 rd = normalize(wPos - cameraPos);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:24:03