Issues with calculate final pixel color with multiple point lights DX11

504 Views Asked by At

As the header denotes I've got some issues calculating the final pixel color when rendering a scene with multiple point lights. When I calculate one light, the scene looks just fine but when I calculate more than one the light it seems to be a bit wacky! The images below show five point lights in a diagonal pattern (just for visual debugging).

https://i.stack.imgur.com/7Eqvx.jpg

As I mentioned above, when I calculate one point light it works just fine as shown below http://imgur.com/9LXVz79

HLSL code of the Pixel shader is posted below.

//================
//  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

There are 1 best solutions below

0
On BEST ANSWER

The main thing I'm seeing is on the range check: You are using return rather than continue.

Additionally, the ambient color should be added only once, not for each light.