Reputation: 860
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
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