Sign in to follow this  
eDuDe

Lighting with Multiple Lights

Recommended Posts

So I'm trying to avoid deferred shading right now, and just brute force multiple lights. Currently I'm trying to use a bump map to store the normals of my object as it is a textured quad, but I want a little more detail on it. Rendering with multiple lights appears to work correctly, but the Lights Color basically dominates the objects final color. I was wondering if there was a better way to brute force lighting then how I'm doing it. Also, help converting this over so that it supports point lights, parallel lights, and spot lights would be wonderful. I think right now though using shader model 2.0 is going to make that mostly impossible because of the math restrictions, but who knows. You guys are smarter then I am.
float4x4 World;
float4x4 WorldViewProjection;

texture DiffuseTex;
texture BumpTex;

#define MaxLights 9

float4 LightDirections[MaxLights];
float4 LightColors[MaxLights];

int LightCount;

sampler DiffuseSampler = sampler_state
{
    texture = <DiffuseTex>;
    AddressU  = WRAP;
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

sampler BumpSampler = sampler_state
{
    texture = <BumpTex>;
    AddressU  = WRAP;
    AddressV  = WRAP;
    AddressW  = WRAP;
    MIPFILTER = LINEAR;
    MINFILTER = LINEAR;
    MAGFILTER = LINEAR;
};

struct VS_IN 
{
	float4 pos      : POSITION;
	float3 normal   : NORMAL;
	float3 tangent  : TANGENT;
	float3 binormal : BINORMAL; 
	float2 tex      : TEXCOORD0;
};

struct PS_IN 
{
	float4 pos      : POSITION;
	float2 tex      : TEXCOORD0;
	float3 normal   : TEXCOORD1;
	float3 tangent  : TEXCOORD2;
	float3 binormal : TEXCOORD3;
	float4 wpos     : TEXCOORD4;
};


PS_IN LightingVertexShader(VS_IN input)
{
	PS_IN output;
	
	output.pos      = mul(input.pos, WorldViewProjection);
	output.tex      = input.tex;
	output.normal   = mul(input.normal, (float3x3)World);
	output.tangent  = mul(input.tangent, (float3x3)World);
	output.binormal = mul(input.binormal, (float3x3)World);
	output.wpos     = mul(input.pos, World);
	
	return output;
}

float4 LightingPixelShader(PS_IN input): COLOR
{
	float4 output = float4(0,0,0,0);
	
	float3 normal = normalize(input.normal);
	float3 tangent = normalize(input.tangent);
	float3 binormal = normalize(input.binormal);
	float3x3 TBN = float3x3(tangent, binormal, normal);
	
float3 new_normal = 2 * tex2D(BumpSampler, input.tex).rgb - float3(1, 1, 1);
	normal = normalize(mul((new_normal), TBN));
	
for( int i = 0; i < LightCount; i++ )
{
	output += max(dot(normal, -LightDirections[i]), 0) * LightColors[i];
}
	
        float4 color = tex2D(DiffuseSampler, input.tex);
        color.rgb *= output.rgb;
	
	return color;
}

technique Technique0
{
	pass P0
	{
		AlphaBlendEnable = True;
		SrcBlend = SrcAlpha;
		DestBlend = InvSrcAlpha; 
		
		VertexShader = compile vs_2_0 LightingVertexShader();
		PixelShader = compile ps_2_0  LightingPixelShader();
	}
}

Share this post


Link to post
Share on other sites
I don't see any problem with what you're doing in your shader (aside from the fact that you're not doing specular calculations). It's pretty normal that the light color is dominant....after all your lights are the source of all visible color in the scene.

Share this post


Link to post
Share on other sites
converting it to support multiple lights will mean you need to start implementing OR macro's, OR techniques based on the light type OR branching.

Macros means compiling different shader per light type
Technique means different technique per light type
Branching means extra instruction slots

correct me if i am wrong though.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this