2013-04-06 63 views
1

我正在使用rastertek框架進行地形生成。我有從頂點着色器渲染的地形,但我不知道如何計算着色器中的法線。 Theres在其中一個類中生成函數調用,從地形生成法線,但只有在cpu上生成terrain時才起作用。繼承人的頂點着色器的代碼,我使用的是:頂點着色器中的正常計算?

//////////////////////////////////////////////////////////////////////////////// 
// Filename: terrain.vs 
//////////////////////////////////////////////////////////////////////////////// 
#include "terrain.fx" 

///////////// 
// GLOBALS // 
///////////// 

cbuffer MatrixBuffer 
{ 
    matrix worldMatrix; 
    matrix viewMatrix; 
    matrix projectionMatrix; 
}; 


////////////// 
// TYPEDEFS // 
////////////// 
struct VertexInputType 
{ 
    float4 position : POSITION; 
    float3 normal : NORMAL; 
}; 

struct PixelInputType 
{ 
    float4 position : SV_POSITION; 
    float3 normal : NORMAL; 
}; 


//////////////////////////////////////////////////////////////////////////////// 
// Vertex Shader 
//////////////////////////////////////////////////////////////////////////////// 
PixelInputType TerrainVertexShader(VertexInputType input) 
{ 
    PixelInputType output; 

    input.position.y = input.position.y + terrain(input.position.x,input.position.z); 

    // Change the position vector to be 4 units for proper matrix calculations. 
    input.position.w = 1.0f; 

    // Calculate the position of the vertex against the world, view, and projection matrices. 
    output.position = mul(input.position, worldMatrix); 
    output.position = mul(output.position, viewMatrix); 
    output.position = mul(output.position, projectionMatrix); 

    // Calculate the normal vector against the world matrix only. 
    output.normal = mul(input.normal, (float3x3)worldMatrix); 

    // Normalize the normal vector. 
    output.normal = normalize(output.normal); 

    return output; 
} 
+0

爲什麼你想這樣做?每次頂點着色器調用時你想計算法線?我不認爲這是個好主意。爲什麼不能用cpu生成所有的法線? – acrilige 2013-04-06 21:08:03

+0

@Acrilige:節省內存帶寬...如果你已經超過了你的內存預算,但擁有GPU的多餘能力,這些東西可能非常有用......同樣你也許不會超過你的內存預算,但是你可能會發現你可能會堵塞一個負載更多地進入你的shader withotu傷害表現。爲什麼不使用它? – Goz 2013-04-07 13:10:24

+0

我會知道,謝謝你的解釋 – acrilige 2013-04-07 13:23:58

回答

3

你在着色器生成法線很大的問題是,你需要周圍的頂點的知識。這是你可以用幾何着色器但不能用頂點着色器克服的問題。計算法線的一種簡單方法是計算所有碰到您正在查看的頂點的多邊形法線(將由2條邊形成的矢量並將它們交叉爲面法線),然後將它們相加並歸一化。因此,如果您沒有訪問幾何着色器,唯一真正的解決方案是使用CPU。即使這樣,這也不是計算頂點法線的最佳方法。您仍然可以發現使用更復雜的算法會更好,這會給您帶來更多問題!所以是的,CPU或幾何着色器......基本上,這些都是你的選擇。

+0

我該如何訪問轉換的頂點?在CPU上,我有一個平面數組,我通過循環來計算法線,但如果我轉換GPU上的頂點,那麼數組值不會從平坦表面改變,我得到的照明,就好像地形是平面。 – ExplodingFirework 2013-04-07 15:35:53

+0

爲什麼你需要轉換的正常?它只是世界矩陣乘以正常值(確保w是0,但是這個乘法雖然!) – Goz 2013-04-07 18:27:04

+0

我已經將法線乘以世界矩陣並且它不能正確點亮。至於使w = 0,那是input.position.w?我試過了,它沒有改變任何東西。 – ExplodingFirework 2013-04-07 19:58:30