从屏幕坐标计算光线方向矢量

时间:2012-05-03 13:39:21

标签: camera rendering hlsl

我正在寻找一种更好的方法(或者说 最好的方法)将像素坐标从任意相机传输到相应的光线方向位置/方向。

我目前的方法如下。我将“相机”定义为位置矢量,外观矢量和向上矢量,这样命名。 (请注意,外观向量是摄像机所面向的单位向量,而不是(position - lookat)方向,XNA的标准是Matrix.CreateLookAt)这三个向量可以唯一地定义摄像机位置。这是实际的代码(好吧,不是真正的,简化的抽象版本)(语言是HLSL)

float xPixelCoordShifted = (xPixelCoord / screenWidth * 2 - 1) * aspectRatio;
float yPixelCoordShifted = yPixelCoord / screenHeight * 2 - 1;
float3 right = cross(lookat, up);
float3 actualUp = cross(right, lookat);
float3 rightShift = mul(right, xPixelCoordShifted);
float3 upShift = mul(actualUp, yPixelCoordShifted);
return normalize(lookat + rightShift + upShift);

(返回值是光线的方向)

所以我要问的是 - 这是一个更好的方法,可能是使用矩阵等。这种方法的问题是,如果你的视角太宽,屏幕的边缘会变得有点像“径向拉伸”。

1 个答案:

答案 0 :(得分:0)

您可以在像素着色器中计算它(ray),HLSL代码:

float4x4 WorldViewProjMatrix; // World*View*Proj
float4x4 WorldViewProjMatrixInv; // (World*View*Proj)^(-1)

void VS( float4 vPos : POSITION,
     out float4 oPos : POSITION,
     out float4 pos  : TEXCOORD0 )
{
    oPos = mul(vPos, WorldViewProjMatrix);
    pos = oPos;
}

float4 PS( float4 pos : TEXCOORD0 )
{
    float4 posWS = mul(pos, WorldViewProjMatrixInv);
    float3 ray = posWS.xyz / posWS.w;

    return float4(0, 0, 0, 1);
}

有关相机位置和方向的信息位于View矩阵(Matrix.CreateLookAt)。