Monogame + HLSL 鱼眼顶点着色器
Monogame + HLSL Fisheye Vertex Shader
我正在为一个学校项目工作,我需要在其中实现鱼眼着色器,并且我正在努力处理确定顶点深度值的过程。我知道对于 space 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
如您所见,远处的三角形渲染在近处的三角形前面。
感谢您的帮助。
如果这只是远处三角形的问题,那可能是您达到了深度缓冲区精度限制?如果你还没有这样做,你应该正确地设置你的 close/far-plane 这样你就不会在你没有渲染任何东西的场景的一部分上浪费浮点精度。
您的斜边计算的第三个元素是否正确?似乎第三个平方元素应该是 input[2]*input[2].
我通过从修改投影 z 位置 (output.Position[3]) 更改为修改相对于相机的 z 位置 (viewPosition[2]) 来解决我的问题。我 output.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);
我正在为一个学校项目工作,我需要在其中实现鱼眼着色器,并且我正在努力处理确定顶点深度值的过程。我知道对于 space 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
如您所见,远处的三角形渲染在近处的三角形前面。
感谢您的帮助。
如果这只是远处三角形的问题,那可能是您达到了深度缓冲区精度限制?如果你还没有这样做,你应该正确地设置你的 close/far-plane 这样你就不会在你没有渲染任何东西的场景的一部分上浪费浮点精度。 您的斜边计算的第三个元素是否正确?似乎第三个平方元素应该是 input[2]*input[2].
我通过从修改投影 z 位置 (output.Position[3]) 更改为修改相对于相机的 z 位置 (viewPosition[2]) 来解决我的问题。我 output.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);