2010-11-11 104 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); 
... 

无论如何,谢谢大家,看看。