我正在尝试从顶点着色器中的深度纹理重建位置。通常,这是在Pixel Shader中完成的,但出于某种原因,我需要在VS中转换一些几何体。
所以我的方法。
1)我在View Space中计算View Frustrum角 我使用这个输入NDC。通过Inverse(view * proj)转换这些值,将它们放入World Space,然后通过视图矩阵进行转换。
//GL - Left Handed - need to "swap" front and back Z coordinate
MyMath::Vector4 cornersVector4[] =
{
//front
MyMath::Vector4(-1, -1, 1, 1), //A
MyMath::Vector4( 1, -1, 1, 1), //B
MyMath::Vector4( 1, 1, 1, 1), //C
MyMath::Vector4(-1, 1, 1, 1), //D
//back
MyMath::Vector4(-1, -1, -1, 1), //E
MyMath::Vector4( 1, -1, -1, 1), //F
MyMath::Vector4( 1, 1, -1, 1), //G
MyMath::Vector4(-1, 1, -1, 1), //H
};
如果我打印调试输出,看起来是正确的(相机位置在距离近平面远的地方,远远不够远)
2)将值发布到着色器
3)在着色器中我这样做:
vec3 _cornerPos0 = cornerPos0.xyz * mat3(viewInv);
vec3 _cornerPos1 = cornerPos1.xyz * mat3(viewInv);
vec3 _cornerPos2 = cornerPos2.xyz * mat3(viewInv);
vec3 _cornerPos3 = cornerPos3.xyz * mat3(viewInv);
float x = (TEXCOORD1.x / 100.0); //TEXCOORD1.x = <0, 100>
float y = (TEXCOORD1.y / 100.0); //TEXCOORD1.y = <0, 100>
vec3 ray = mix(mix(_cornerPos0, _cornerPos1, x),
mix(_cornerPos2, _cornerPos3, x),
y);
float depth = texture2D(depthTexture, vec2(x, y));
//depth is created in draw pass before with depth = vertexViewPos.z / farClipPlane;
vec3 reconstructed_posWS = camPos + (depth * ray);
但是,如果我这样做,将我的几何体从[0,0,0]
转换为reconstructed_posWS
,则只覆盖部分屏幕。什么可能是不正确的?
PS:有些计算是无用的(转换为空格,然后转换回来),但速度不是关注atm。