? ?一、为什么 : 屏幕后处理得不到准确的世界空间下的物体的坐标, 都会使用深度纹理来重建每个像素在世界空间下的位置
? ?二、怎么做 :
? ? 1 利用vp矩阵重建
?? ?? ? 先得到vp矩阵的逆矩阵
?? ?? ? 得到ndc的坐标
?? ?? ? 利用vp逆矩阵,将ndc坐标转化成世界空间下坐标
?? ??? ?
由于是在片元着色器中进行计算处理, 会比较耗费性能
详细原理,可以了解一下,shader中从观察空间到屏幕空间所做的一些列操作
??
2 屏幕射线插值的方式重建
? ? ? ??
其中: 0 -> bottomLeft;? 1 -> bottomRight ; 2 -> topLeft ;? 3 -> topRight
-- c#
vector3 toRight = right * halfWidth
vector3 toTop = up * halfHeight
topLeft = forward + toTop - toRight
topRight = forward + toTop + toRight
bottomLeft = forward - toTop - toRight
bottomRight = forward - toTop + toRight
//set matrix
Matrix4x4 frustumDir = Matrix4x4.identity;
frustumDir.SetRow(0,bottomLeft);
frustumDir.SetRow(1,bottomRight);
frustumDir.SetRow(2,topLeft);
frustumDir.SetRow(3,topRight);
mat.SetMatrix("_FrustumDir", frustumDir);?
-- shader? vertex
//uv值和对应的索引的关系 ,对应上图
// x =0 , y = 0? result 0
// x =0 , y = 1? result 2
// x = 1 , y = 0 result 1
// x = 1 , y = 1 result 3
int ix = (int)o.uv.z;int iy = (int)o.uv.w;
o.frustumDir = _FrustumDir[ix + 2 * iy];
-- shader fragment
//vertex到fragment的过程中是有个东西叫插值的,这个插值正好能把每个像素所在的向量求出。
float depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, i.uv.zw));
float linearEyeDepth = LinearEyeDepth(depth);
float3 worldPos = _WorldSpaceCameraPos + linearEyeDepth * i.frustumDir.xyz;
|