Math 在Direct3D中使用像素着色器绘制旋转球体

Math 在Direct3D中使用像素着色器绘制旋转球体,math,mapping,shader,direct3d,hlsl,Math,Mapping,Shader,Direct3d,Hlsl,我想在Direct3D中画一个纹理圆,看起来像一个真正的3D球体。为此,我拍摄了一个billard球的照片,并尝试在HLSL中编写一个像素着色器,该着色器将其映射到一个简单的预变换四元体上,这样一来,它看起来就像一个三维球体,当然,除了照明之外 到目前为止,我得到的是: struct PS_INPUT { float2 Texture : TEXCOORD0; }; struct PS_OUTPUT { float4 Color : COLOR0; }; sampler2D

我想在Direct3D中画一个纹理圆,看起来像一个真正的3D球体。为此,我拍摄了一个billard球的照片,并尝试在HLSL中编写一个像素着色器,该着色器将其映射到一个简单的预变换四元体上,这样一来,它看起来就像一个三维球体,当然,除了照明之外

到目前为止,我得到的是:

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,希望绕垂直轴旋转球体。结果是:

正如您所看到的,当球到达边缘时,球的印记看起来不自然地变形。有人知道这有什么原因吗?此外,如何实现绕任意轴的旋转


提前谢谢

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

仅此而已,它现在运行得很好。此外,我还知道如何旋转球体。在计算u和v之前,只需旋转点p,方法是将其与3D旋转矩阵相乘,例如

结果如下所示:


如果有人对我如何使纹理平滑一点有任何建议,请留下评论。

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

仅此而已,它现在运行得很好。此外,我还知道如何旋转球体。在计算u和v之前,只需旋转点p,方法是将其与3D旋转矩阵相乘,例如

结果如下所示:

如果有人对我如何使纹理平滑一点有任何建议,请留下评论