如何在 HLSL 中渲染到没有插值错误的球体贴图?

How to render to a sphere map without interpolation errors in HLSL?

我正在学习一些 HLSL 着色器编程,使用 MikuMikuDance 作为引擎。我无权访问主渲染器的代码,而且我仅限于 DX9 下的着色器模型 3。我正在尝试创建一个着色器,将环境渲染为球体贴图,这对某些人来说很有用,并且可以作为实验和学习的工具。我天真的方法似乎会导致插值问题。此外,似乎某些顶点被不恰当地剪裁,导致多边形未在边界处绘制。

我想我会尝试在顶点着色器中反向 运行 球体贴图代码来创建我的渲染:

Pos = mul( Pos, WorldMatrix );
Out.Eye = CameraPosition - Pos.xyz;
Pos = mul(Pos, ViewMatrix);
float far = 300000;
float3 En = normalize(Pos.xyz);
Out.Pos = float4(En.x, En.y, length(Out.Eye)/(far), 1);

这会导致透视问题,尤其是对于较大的多边形:

这对我来说很有意义;当它应该是球形时,我正在做线性插值。但是在Pos上使用nointerpolation,centroid,and/ornoperspective没有明显效果

有没有办法通过这种不寻常的投影获得正确的视角?我是不是用完全错误的方式来解决这个问题?

在不修改渲染管道的情况下,没有实用的方法来应用真正的球面变换。这不是插值问题,而是光栅化和顶点变换问题。正如您所注意到的,关键是球面投影本质上要求直线变成曲线。如果管道已经使用了某种类型的曲面细分,这可能是可能的,但除此之外,单独变换顶点永远无法使它们之间的直边变成曲线。

如果您还可以修改或添加屏幕-space 效果(例如 post-处理),您可以操纵源纹理坐标以在那里应用球形变换反而。在这种情况下,修改顶点着色器以增加 FOV 仍然是有益的,这样您就可以填充更多的半球。不过,这将是 FOV 和分辨率之间的权衡——当您接近 180 度时,预投影和 post 投影之间的分辨率差异会增加。在 179 度时,初始渲染中的几乎所有像素都将映射到半球的外环。