2015-12-30 63 views
0

我目前正在嘗試在HLSL中使用Blinn-Phong底紋的遊戲中實現點光源。我遵循的教程鏈接到here
我現在的代碼是:Blinn-Phong底紋HLSL和D3D11:點光源

struct VS_INPUT 
{ 
    float4 Position : POSITION; 
    float3 Normal : NORMAL; 
    float2 TexCoord : TEXCOORD; 
}; 

struct VS_OUTPUT 
{ 
    float4 Position : SV_POSITION; 
    float4 WorldPosition : POSITION; 
    float3 Normal : NORMAL; 
    float2 TexCoord : TEXCOORD; 
}; 

struct NF3D_LIGHT_OMNIDIRECTIONAL 
{ 
    float4 Diffuse; 
    float4 Ambient; 
    float3 Position; 
    float3 Attitude; 
    float Range; 
    int BindSlot; 
}; 


//-------------------------------------------------------------------------------------- 
// Constant Buffer Variables 
//-------------------------------------------------------------------------------------- 
cbuffer CB_PROJECTION : register(b0) 
{ 
    matrix Projection; 
} 

cbuffer CB_VIEW : register(b1) 
{ 
    matrix View; 
    float4 CameraPosition; 
} 

cbuffer CB_WORLD : register(b2) 
{ 
    matrix World; 
} 

cbuffer Light : register(b5) 
{ 
    NF3D_LIGHT_OMNIDIRECTIONAL light; 
}; 


//-------------------------------------------------------------------------------------- 
// Vertex Shader 
//-------------------------------------------------------------------------------------- 
VS_OUTPUT VS(VS_INPUT Input) 
{ 
    VS_OUTPUT Output = (VS_OUTPUT)0; 

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

    // Aply the perspective to every vertex. 
    Output.Position = mul(Input.Position, World); 
    Output.WorldPosition = Output.Position; 
    Output.Position = mul(Output.Position, View); 
    Output.Position = mul(Output.Position, Projection); 

    // Normalise the normal vector. 
    Output.Normal = mul(Input.Normal, (float3x3)World); 
    Output.Normal = normalize(Output.Normal); 

    // Transfer the texture coordinates. 
    Output.TexCoord = Input.TexCoord; 

    return Output; 
} 


//-------------------------------------------------------------------------------------- 
// Pixel Shader 
//-------------------------------------------------------------------------------------- 
float4 PS(VS_OUTPUT Input) : SV_Target 
{ 
    // https://brooknovak.wordpress.com/2008/11/13/hlsl-per-pixel-point-light-using-phong-blinn-lighting-model/ 
    // Phong relfection is ambient + light-diffuse + spec highlights. 
    // I = Ia*ka*Oda + fatt*Ip[kd*Od(N.L) + ks(R.V)^n] 
    // Ref: http://www.whisqu.se/per/docs/graphics8.htm 
    // and http://en.wikipedia.org/wiki/Phong_shading 

    // Get light direction for this fragment 
    float3 lightDir = normalize(light.Position - Input.WorldPosition); 

    // Note: Non-uniform scaling not supported 
    float diffuseLighting = saturate(dot(Input.Normal, -lightDir)); // per pixel diffuse lighting 

    // Introduce fall-off of light intensity 
    diffuseLighting *= ((length(lightDir) * length(lightDir))/dot(light.Position - Input.WorldPosition, light.Position - Input.WorldPosition)); 

    // Using Blinn half angle modification for perofrmance over correctness 
    float3 h = normalize(normalize(CameraPosition.xyz - Input.WorldPosition) - lightDir); 
    float specLighting = pow(saturate(dot(h, Input.Normal)), 2.0f); 

    return saturate(light.Ambient + (light.Diffuse * diffuseLighting * 0.6f) + (specLighting * 0.5f)); 
} 

的問題在這張圖片上可以看出: enter image description here 注意幀是故意不按順序,我試圖捕捉它們,這樣的錯誤可能是非常清楚明白。

小行星是一個簡單的模型,圍繞點光源的原點。鏡面光應該在所有面和像素上均勻一致,但正如您所看到的,如果網格位於相機的前面,反射光就會形成一個尖銳的形狀。
我也意識到我的代碼是錯誤的,如果我從等式中移除鏡面光,問題就會消失。任何人都可以解釋我在這裏發生了什麼,我怎麼能解決這個問題?先謝謝你。

回答

0

我解決了!問題是:

CameraPosition.xyz - Input.WorldPosition 

它們都是float4型和刪除.xyz刪除這惱人的bug。

+1

爲什麼'WorldPosition'和'CameraPosition'' float4's無論如何?真正的解決辦法可能是讓他們成爲'float3'。因爲,你的修復可能會使它看起來更加正確,但它可能不完全正確。 – MooseBoys

+0

我不知道,它似乎是從我測試過的。謝謝你的回覆。 –