【问题标题】:Monogame + HLSL Fisheye Vertex ShaderMonogame + HLSL 鱼眼顶点着色器
【发布时间】:2021-05-08 03:26:05
【问题描述】:

我正在为一个需要实施鱼眼着色器的学校项目工作,我正在努力确定顶点深度值的过程。我知道对于空间 P1 = (x, y, z, w) 中的一个点,P * 我的投影矩阵应该产生一个新点 P2 = (a, b, c, d),其中对于近点和之间的任何点远剪裁平面 P2.c/P2.d 产生介于 0 和 1 之间的数字。

我的 hlsl 顶点着色器包含此代码,其中 input.Position 是原始顶点位置

float distance3d(float4 input) // Finds 3d hypotenuse
{
    return sqrt(input[0] * input[0] + input[1] * input[1] + input[3] * input[3]);
}
//Vertex Position data
    float4 worldPosition = mul(input.Position, World); // object to world xform
    float4 viewPosition = mul(worldPosition, View);  // world to camera xform
    output.Position = mul(viewPosition, Projection); // perspective xform
    float z = output.Position[3];
    float distance = distance3d(output.Position) * (z < 0 ? -1 : 1);
    float f = Projection[2][2];
    float n = Projection[3][2];
    output.Position[3] = distance;
    output.Position[2] = -distance * f + square * n;

我的投影矩阵是使用这段代码生成的。

new Matrix(  -focalLength * Math.Sin(-FOV),                  0, 0, 0,
             0, -focalLength * Math.Sin(-FOV),                  0, 0,
             0, 0, -farPlane / (farPlane - nearPlane),            -1,
             0, 0, -farPlane / (farPlane - nearPlane) * nearPlane, 0);

法线投影:https://imgur.com/Z00CPP3

鱼眼投影:https://imgur.com/0qPv87V

如您所见,远三角形呈现在近三角形前面。

感谢您的帮助。

【问题讨论】:

    标签: 3d xna shader hlsl fisheye


    【解决方案1】:

    如果这只是远处三角形的问题,那可能是您达到了深度缓冲区精度限制?如果你还没有这样做,你应该正确设置你的近/远平面,这样你就不会在你没有渲染任何东西的场景中浪费浮点精度。 您的斜边计算的第三个元素是否正确?似乎第三个平方元素应该是 input[2]*input[2]。

    【讨论】:

    • 我试一试,至于斜边,投影矩阵将 z 值交换到 output.Position 的第三个索引中,因此虽然它不适用于其他位置向量,但它确实为这个工作。不幸的是,更换飞机并没有帮助。我相信无论距离如何,任何三角形都会发生这种情况,只是很难用这种特殊的地形来判断。
    【解决方案2】:

    我通过从修改投影 z 位置 (output.Position[3]) 更改为修改相对于相机的 z 位置 (viewPosition[2]) 解决了我的问题。我输出。Position[2] 需要包含斜边而不是原始 z 值,以便深度计算正常工作。

        float4 worldPosition = mul(input.Position, World); // object to world xform
        float4 viewPosition = mul(worldPosition, View);  // world to camera xform
        float z = viewPosition[2];
        float square = distance3d(viewPosition) * (z < 0 ? -1 : 1);
        viewPosition[2] = square;
        output.Position = mul(viewPosition, Projection); // perspective xform
        output.wPosition = mul(input.Position, World);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多