使用多个点光源DX11计算最终像素颜色的问题

时间:2014-12-07 17:16:11

标签: directx directx-11 hlsl lighting pixel-shader

由于标题表示我在渲染具有多个点光源的场景时计算最终像素颜色存在一些问题。当我计算一盏灯时,场景看起来很好但是当我计算不止一个灯时,它看起来有点古怪!下图显示了对角线图案中的五个点光源(仅用于可视化调试)。

http://imgur.com/nkQBTVM

正如我上面提到的,当我计算一个点光时,它可以正常工作,如下所示 http://imgur.com/9LXVz79

Pixel着色器的HLSL代码发布在下方。

//================
//  PIXEL SHADER
//================
struct PointLight
{
    float3  lightPosition;
    float   range;
    float3  att;
    float   padding;
    float4  ambient;
    float4  diffuse;
};

cbuffer CB_PER_FRAME_LIGHT : register(b2)
{
    PointLight lights[5];
};


Texture2D tex;
SamplerState samplerState;


float4 PS( DS_OUTPUT input ) : SV_Target
{

    float4 finalDiffuse;
    float3 finalColor = float3( 0.0f, 0.0f, 0.0f );
    float3 LIGHTSTRENGTH;
    float4 ambient, diffuse;

    for (int i = 0; i < 5; i++)
    {
        float3 lightWorldPosition = mul( lights[i].lightPosition, world ).xyz;

        ambient = float4( 0.0f, 0.0f, 0.0f, 0.0f );
        diffuse = float4( 0.0f, 0.0f, 0.0f, 0.0f );
        LIGHTSTRENGTH = float3( 0.0f, 0.0f, 0.0f );
        finalDiffuse = tex.Sample( samplerState, input.texCoord );

        //Create the vector between light position and pixels position
        float3 lightToPixelVec = lights[i].lightPosition - input.worldPosition;

        //Find the distance between the light pos and pixel pos
        float d = length(lightToPixelVec);

        //Create the ambient light
        float3 finalAmbient = finalDiffuse * lights[i].ambient;

        //If pixel is too far, return pixel color with ambient light
        if( d > lights[i].range )
            return float4( finalAmbient, finalDiffuse.a );

        //Turn lightToPixelVec into a unit length vector describing
        //the pixels direction from the lights position
        lightToPixelVec /= d; 

        //Calculate how much light the pixel gets by the angle
        //in which the light strikes the pixels surface
        float howMuchLight = dot( lightToPixelVec, input.normal );

        //If light is striking the front side of the pixel
        if( howMuchLight > 0.0f )
        {   
            //Add light to the finalColor of the pixel
            LIGHTSTRENGTH += howMuchLight * finalDiffuse * lights[i].diffuse;

            //Calculate Light's Falloff factor
            LIGHTSTRENGTH /= lights[i].att[0] + ( lights[i].att[1] * d ) + ( lights[i].att[2] * ( d*d ) );
        }   

    //make sure the values are between 1 and 0, and add the ambient
    finalColor += saturate( LIGHTSTRENGTH + finalAmbient );

    }
    //Return Final Color
    return float4( finalColor, finalDiffuse.a );
}

1 个答案:

答案 0 :(得分:1)

我看到的主要问题是范围检查:你使用的是返回而不是继续。

此外,环境颜色应仅添加一次,而不是每个灯。