2013-07-24 58 views
2

我想在Direct3D中繪製一個帶紋理的圓圈,它看起來像一個真正的3D球體。爲了達到這個目的,我拍了一個柱狀球的texture,並試圖在HLSL中編寫一個像素着色器,它將它映射到一個簡單的預先變換的四邊形上,使其看起來像一個三維球體(除了光照, 當然)。在Direct3D中使用像素着色器繪製旋轉球體

這是我到目前爲止有:

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]。之後,我按照this article中的公式計算當前點的正確紋理座標。

起初,結果看起來不錯,但我希望能夠任意旋轉這個球體的幻覺。所以我逐漸增加了u,希望圍繞垂直軸旋轉球體。這是結果:

rotating billard ball

正如你可以看到,球的印記看起來過度的變形,當它到達的邊緣。任何人都可以看到這個的任何理由?另外,我怎樣才能實現圍繞任意軸的旋轉?

在此先感謝!

回答

4

我終於自己發現了這個錯誤:z值的計算對應於球體前半部分的當前點(x, y)是錯誤的。當然,它必須是:

z on a unit sphere

這一切,它的工作原理就像現在exspected。此外,我想出瞭如何旋轉球體。在計算uv之前,您只需旋轉點p,方法是將其與例如this one等3D旋轉矩陣相乘。

結果如下所示:

rotating billard ball

如果任何人有任何意見,我怎麼能平滑紋理豆蔻位,請發表評論。