2

我想在 Direct3D 中绘制一个带纹理的圆,它看起来像一个真正的 3D 球体。为此,我拍摄了一个台球的纹理HLSL并尝试在 中编写一个像素着色器,它将它映射到一个简单的预变换四边形上,使其看起来像一个 3 维球体(除了照明,当然)。

这是我到目前为止所得到的:

struct PS_INPUT
{
    float2 Texture : TEXCOORD0;
};

struct PS_OUTPUT
{
    float4 Color : COLOR0;
};

sampler2D Tex0;

// main function
PS_OUTPUT ps_main( PS_INPUT In )
{
    // default color for points outside the sphere (alpha=0, i.e. invisible)
    PS_OUTPUT Out; 
    Out.Color = float4(0, 0, 0, 0);  

    float pi = acos(-1);    

    // map texel coordinates to [-1, 1]
    float x = 2.0 * (In.Texture.x - 0.5);
    float y = 2.0 * (In.Texture.y - 0.5);
    float r = sqrt(x * x + y * y);    

    // if the texel is not inside the sphere
    if(r > 1.0f)
      return Out;

    // 3D position on the front half of the sphere
    float p[3] = {x, y, sqrt(1 - x*x + y*y)};

    // calculate UV mapping
    float u = 0.5 + atan2(p[2], p[0]) / (2.0*pi);
    float v = 0.5 - asin(p[1]) / pi;   

    // do some simple antialiasing
    float alpha = saturate((1-r) * 32); // scale by half quad width
    Out.Color = tex2D(Tex0, float2(u, v));  
    Out.Color.a = alpha;  

    return Out;
}

我的四边形的纹理坐标范围从 0 到 1,所以我首先将它们映射到 [-1, 1]。之后我按照本文中的公式计算当前点的正确纹理坐标。

起初,结果看起来不错,但我希望能够任意旋转这个球体的错觉。所以我逐渐增加u了围绕垂直轴旋转球体的希望。这是结果:

旋转台球

如您所见,当球到达边缘时,球的印记看起来不自然地变形。任何人都可以看到任何原因吗?此外,我如何实现围绕任意轴的旋转?

提前致谢!

4

1 回答 1

4

我终于自己发现了错误:球体前半部分z当前点对应的值计算错误。(x, y)当然必须是:

z 在单位球面上

就是这样,它现在按预期工作。此外,我想出了如何旋转球体。您只需p在计算之前旋转该点,u并将其与像这样v的 3D 旋转矩阵相乘。

结果如下所示:

旋转台球

如果有人对我如何使纹理稍微平滑一点有任何建议,请发表评论。

于 2013-07-25T11:07:56.893 回答