2010-11-11 105 views
2

我一直在努力,現在一兩天的創建HLSL簡單點光,我在本指南被以下: D3DBook:(Lighting) Direct Light SourcesHLSL點光源問題

具體的衰減函數部分的點光源。這裏是我的代碼:

//------------------------------------------------------------------------------------------------------ 
// Global params provided by the app 
//------------------------------------------------------------------------------------------------------ 
uniform extern float4x4 gWVP; 
uniform extern float4x4 gWorldViewIT; //for normals 
uniform extern float4x4 gWorldView;//work out view vector from all vertices 
uniform extern float4x4 gLightMatrix;//light in view space 
uniform extern float4x4 gWorld; 

uniform extern float4 gDiffuseMtrl; 
uniform extern float4 gAmbMtrl; 
uniform extern float4 gSpecMtrl; 

//lights 
uniform extern float4 gLightCol = {1, 1, 1, 1}; //set to white 
//uniform extern float4 gLightPos[4]; 
uniform extern float4 gLightPos[4] = {{0,0,3,0},{0,0,-1,0},{0,100,1,0},{0,-100,0,0}}; 
uniform extern float gLightPow[4] = {25,25,0.1,0.1};//range of light 


uniform extern float roughness;//roughness per object 
uniform extern float ref;//reflectance at normal//used in fresnel calculation 

//pi 
const shared float pi= 3.14159f; 

//attenuation constants 
const float a_a = 0.0f; 
const float a_b = 0.1f; 
const float a_c = 1.0f; 


//calculate light attenuation 
float atten(float distance, float range, float a, float b, float c) 
{ 
    float atten = 1.0f/((a * distance * distance) + (b * distance) + c); 

    //step clamps to 0 if out of range 
    return step(distance, range) * saturate(atten); 
} 


//--------------------------------------------------------------------------------------------------------------------------- 
// Input channel (vertex shader) 
//--------------------------------------------------------------------------------------------------------------------------- 
struct InputVS 
{ 
    float3 posL : POSITION0; 
    float3 Norm : NORMAL; 

}; 
//--------------------------------------------------------------------------------------------------------------------------- 
// Output channel (vertex shader) 
//--------------------------------------------------------------------------------------------------------------------------- 
struct OutputVS 
{ 
    float4 posH  : POSITION0; 
    float4 col  : COLOR0; 
}; 

//vertex shader//passthrough 
OutputVS gourardVS(InputVS input) 
{ 
    float n = 1/roughness; 
    //Zero out our output 
    OutputVS outVS = (OutputVS)0; 

    //Transform to homogeneous clipspace 
    outVS.posH = mul(float4(input.posL, 1.0f), gWVP); 

    float4 col_amb = gAmbMtrl*gLightCol; 
    float4 col_diff = gDiffuseMtrl*gLightCol; 
    float4 col_spec = gSpecMtrl*gLightCol; 

    //ambient term 
    float4 ambient={0.2, 0.2, 0.2, 1.00f}; 

    float4 finalColour=0; 

    float diff = 0; 

    float3 pWorld = mul(float4(input.posL, 1.0f), gWorld).xyz; 

    //normal 
    float3 N =normalize(mul(float4(input.Norm, 1.0f),gWorldViewIT)); 

    //point lights 
    float attenu = atten(distance(pWorld, gLightPos[1]), gLightPow[1], a_a, a_b, a_c); 

    float3 l_dir= normalize(gLightPos[1] - pWorld); 

    //n dot l 
    float dotNL = max(0, dot(N, l_dir)); 

    finalColour = float4(attenu * dotNL * col_diff); 
    //} 
    outVS.col = finalColour;// + (ambient * col_amb); 
    outVS.col.a = 1; 


    //return 
    return outVS; 
} 
//--------------------------------------------------------------------------------------------------------------------------- 
// Input channel pixel shader 
//--------------------------------------------------------------------------------------------------------------------------- 
struct InputPS{ 
    float4 posH  : POSITION0; 
    float4 col  : COLOR0; 
}; 

float4 noPS(InputPS input): COLOR 
{ 
return input.col; 
} 

technique Phong{ 
    pass P0 
    { 
      Lighting  = TRUE; 
      SpecularEnable = TRUE; 
     vertexShader = compile vs_3_0 gourardVS(); 
     pixelShader = compile ps_3_0 noPS(); 
     //specify render device states associated with the pass 
     //FillMode = WireFrame; 
     //ShadeMode = Gouraud; 
    } 
} 

我敢肯定,在傳遞的矩陣是正確的,因爲我已經改變用途這從一個定向光例子,所以這只是離開HLSL代碼作爲問題的根源。這會輸出正確的頂點,但無論我在燈位置和功率陣列上使用什麼值,它們都幾乎不亮。

+1

您是否考慮過使用PIX來調試着色器? – 2010-11-13 01:19:26

+0

不知道PIX,我會仔細看看。謝謝。 – 2010-11-13 12:34:32

回答

2

我終於發現了問題,光的方向是在世界空間而法線在查看空間,我已經忘記由視圖矩陣(gLightMatrix)這裏來轉換光的方向被修改後的代碼:

... 
float3 l_dir= normalize(gLightPos[1] - pWorld); 

float3 L=normalize(mul(l_dir, gLightMatrix)); 

//n dot l 
float dotNL = max(0, dot(N, L)); 

finalColour = float4(attenu * dotNL * col_diff); 
... 

無論如何,謝謝大家,看看。