2014-10-07 79 views
0

使怪異的圖案真希望有人能幫助我在這裏 - 我很少無法解決的錯誤在C#中,因爲我有在它經歷了相當數量的,但我沒有很多去與HLSL。自定義HLSL着色跨越icosphere

鏈接到下面的圖像是相同的模型(上運行程序生成)的兩倍,使用我的自定義着色器,下面列出使用BasicEffect和第二時間的第一(白色)的時間。事實上,它與BasicEffect一起使用,我認爲這不是爲模型或類似的東西生成法線問題。

我已經包括了不同層次的細分,以更好地說明這個問題。值得一提的是,兩種效果都使用相同的照明方向。

https://imagizer.imageshack.us/v2/801x721q90/673/qvXyBk.png

這裏是我的shader代碼(隨意挑選它拆開,任何提示都非常歡迎):

float4x4 WorldViewProj; 

float4x4 NormalRotation = float4x4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1); 

float4 ModelColor = float4(1, 1, 1, 1); 
bool TextureEnabled = false; 
Texture ModelTexture; 
sampler ColoredTextureSampler = sampler_state 
{ 
    texture = <ModelTexture>; 
    magfilter = LINEAR; minfilter = LINEAR; mipfilter = LINEAR; 
    AddressU = mirror; AddressV = mirror; 
}; 

float4 AmbientColor = float4(1, 1, 1, 1); 
float AmbientIntensity = 0.1; 
float3 DiffuseLightDirection = float3(1, 0, 0); 
float4 DiffuseColor = float4(1, 1, 1, 1); 
float DiffuseIntensity = 1.0; 

struct VertexShaderInput 
{ 
    float4 Position : POSITION0; 
    float4 Normal : NORMAL0; 
    float2 TextureCoordinates : TEXCOORD0; 
}; 

struct VertexShaderOutput 
{ 
    float4 Position : POSITION0; 
    float4 Color : COLOR0; 
    float2 TextureCoordinates : TEXCOORD0; 
}; 

VertexShaderOutput VertexShaderFunction(VertexShaderInput input) 
{ 
    VertexShaderOutput output = (VertexShaderOutput)0; 

    output.Position = mul(input.Position, WorldViewProj); 

    float4 normal = mul(input.Normal, NormalRotation); 
    float lightIntensity = dot(normal, DiffuseLightDirection); 
    output.Color = saturate(DiffuseColor * DiffuseIntensity * lightIntensity); 

    output.TextureCoordinates = input.TextureCoordinates; 

    return output; 
} 

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 
{ 
    float4 pixBaseColor = ModelColor; 
    if (TextureEnabled == true) 
    { 
     pixBaseColor = tex2D(ColoredTextureSampler, input.TextureCoordinates); 
    } 
    float4 lighting = saturate((input.Color + AmbientColor * AmbientIntensity) * pixBaseColor); 
    return lighting; 
} 

technique BestCurrent 
{ 
    pass Pass1 
    { 
     VertexShader = compile vs_2_0 VertexShaderFunction(); 
     PixelShader = compile ps_2_0 PixelShaderFunction(); 
    } 
} 
+0

有幾件事情要嘗試:1)確保正常化之前,在點產品中使用它。 2)法線和光線方向矢量需要指向點積(從表面出來)的相同方向。如果你的照明意圖是+ x方向,那麼在做點積之前,你需要將它排除到-x方向。 3)可能不是問題,但要確保'input.Normal'的第四個分量是0或'NormalRotation'矩陣不包含任何翻譯。 – megadan 2014-10-08 06:40:30

+0

在點積中使用它之前,還要確保光線方向已標準化 – megadan 2014-10-08 15:14:49

+0

第一句通過標準化法線立即解決了我的問題。可以花幾天時間俯瞰!非常感謝您的快速回復。如果您將此作爲答案發送,我會標記它。 – 2014-10-08 21:53:13

回答

0

在一般情況下,實現照明方程式時,有幾件事情確保:

  1. 法線,光線方向和其他方向矢量在使用點積之前應進行歸一化。你的情況,你可以添加類似:

    normal = normalize(normal);

    同樣應DiffuseLightDirection做,如果它已經不歸。它已經與你的默認值,但如果你的應用程序改變它,它可能不會正常化了。爲此,最好在應用程序代碼中進行規範化處理,因爲只需在其更改時執行一次,而不是每個頂點執行一次。

    還要記住,如果你是乘以包含規模矩陣向量,向量將不再是標準化的,所以它需要被重新歸一化。

  2. 的光的方向和在其從表面出來的相同的方向上正常必須指向。您的默認燈光方向是(1,0,0)。如果你希望光線指向+ x方向,那麼在用法線執行點積之前,你必須實際上否定矢量,以便它像平常一樣從表面指出。如果你已經考慮到了這一點,那麼這不是問題。因爲它們只是一個方向不是位置

  3. 載體不能被翻譯。因此,確保何時用矩陣轉換它們非常重要,該矩陣要麼是向量的第四個分量(w)是0,要麼是轉換它的矩陣沒有翻譯。將w設置爲0將在乘法過程中將矩陣的任何轉換歸零。由於你的矩陣被稱爲NormalRotation,我假設它只包含一個旋轉,所以這可能不是問題。