SvinSimpe
SvinSimpe

Reputation: 860

Issues with calculate final pixel color with multiple point lights DX11

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.sstatic.net/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 );
}

Upvotes: 0

Views: 504

Answers (1)

Andres Urquijo
Andres Urquijo

Reputation: 111

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.

Upvotes: 1

Related Questions