Skip to main content
gamedev.net
🔒 Locked

Directional Light Problems

Started by chowarth Sep 24, 2010 at 10:18 AM 3 replies 1k views
Original Post
chowarth
chowarth
Trying to change one of my lights from a point light to a directional light and getting a little stuck.

Wondering if anyone can shed a little light (pardon the pun ^^) into where I'm going wrong.

Thanks

cbuffer cb0{// Current lighting information - ambient + two point lightsfloat4 AmbientColour;float4 Light1Position;   // Point light 1 - positionfloat4 Light1Colour;     // Point light 1 - colourfloat  Light1Brightness; // Point light 1 - brightnessfloat4 Light2Position;   // light 2...float4 Light2Colour;float  Light2Brightness;// Shininess of material and camera position needed for specular calculationfloat4 CameraPosition;float SpecularPower;};// Access to texture 0Texture2D Texture; SamplerState MeshTextureSampler;//-----------------------------------------------------------------------------// Input / output structures//-----------------------------------------------------------------------------struct PS_Input{	float4 Position      : SV_Position; // New semantics for DX10 - pixel position from vertex shader - not used in DX9	float2 TexCoord0     : TEXCOORD0;	float3 WorldPosition : TEXCOORD1; // The world position of the pixel	float3 WorldNormal   : TEXCOORD2; // The world normal of the pixel};struct PS_Output{	float4 Colour : SV_Target; // New semantics for DX10 - output to render target -replaces COLOR semantic in DX9};//-----------------------------------------------------------------------------// Main function//-----------------------------------------------------------------------------void main( in PS_Input i, out PS_Output o ) {	// Renormalise world normal for the pixel as it has been interpolated from the vertex world normals & may not be length 1	float3 WorldNormal = normalize( i.WorldNormal );	// Lighting preparation	// Get normalised vector to camera for specular equation (common for all lights)	float3 CameraDir = normalize( CameraPosition - i.WorldPosition );	// Accumulate diffuse and specular colour effect from each light	float3 TotalDiffuseColour = AmbientColour;	float3 TotalSpecularColour = 0;	//Light 1 - Point Light	// Calculate diffuse lighting from the 1st light. Standard equation: Diffuse = light colour * max(0, N.L)	float3 LightDir = Light1Position - i.WorldPosition;	float LightDist = length( LightDir );	float LightStrength = saturate( Light1Brightness / LightDist );	LightDir /= LightDist;	float3 DiffuseColour = LightStrength * Light1Colour * saturate( dot( WorldNormal, LightDir ) );	TotalDiffuseColour += DiffuseColour;	// Calculate specular lighting from the 1st light. Standard equation: Specular = light colour * max(0, (N.H)^p)	// Slight tweak here: multiply by diffuse colour rather than light colour	float3 Halfway = normalize( CameraDir + LightDir );	TotalSpecularColour += DiffuseColour * saturate( pow( dot( WorldNormal, Halfway ), SpecularPower ) );	// Second light - Directional light	// Calculate diffuse lighting from the 2nd light	LightDir = Light2Position - i.WorldPosition;	LightDist = length( LightDir );	LightStrength = saturate( Light2Brightness / LightDist );	LightDir /= LightDist;	//Check if the pixel is in line of sight of the light	float diffuseFactor = dot( -LightDir, WorldNormal );	if( diffuseFactor > 0.0f )	{		DiffuseColour = LightStrength * Light2Colour * saturate( dot( WorldNormal, LightDir ) );		TotalDiffuseColour += DiffuseColour;		// Calculate specular lighting from the 2nd light		Halfway = normalize( CameraDir + LightDir );		TotalSpecularColour += DiffuseColour * saturate( pow( dot( WorldNormal, Halfway ), SpecularPower ) );	}	// Final blending	// Combine lighting colours with texture - alpha channel of texture is a specular map	float4 TextureColour = Texture.Sample( MeshTextureSampler, i.TexCoord0 );	o.Colour.rgb = TotalDiffuseColour * TextureColour.rgb + TotalSpecularColour * TextureColour.a; 	// Set alpha blending to 1 (no alpha available in texture)	o.Colour.a = 1.0f;}
Dancin_Fool
Dancin_Fool
Remove the attenuation portion of your directional light calculation and upload a constant direction rather than calculating it with light position - world position as a directional light won't have a position.
chowarth
chowarth
Thanks for the pointers.
Ok I decided to simplify this all a bit, removed one of the lights and added Light1Dir to the constant buffer, which gets sent in and is set to (0.5f, -0.5f, 0.5f ), but now I'm getting no light at all.

/**********************************************	DirLight.psh	Test file for a directional light***********************************************///-----------------------------------------------------------------------------// Global variables//-----------------------------------------------------------------------------cbuffer cb0{// Current lighting information - ambient + two point lightsfloat4 AmbientColour;float4 Light1Position;   // Point light 1 - positionfloat4 Light1Colour;     // Point light 1 - colourfloat  Light1Brightness; // Point light 1 - brightnessfloat3 Light1Dir;// Shininess of material and camera position needed for specular calculationfloat4 CameraPosition;float SpecularPower;};// Access to texture 0Texture2D Texture; SamplerState MeshTextureSampler;//-----------------------------------------------------------------------------// Input / output structures//-----------------------------------------------------------------------------struct PS_Input{	float4 Position      : SV_Position; // New semantics for DX10 - pixel position from vertex shader - not used in DX9	float2 TexCoord0     : TEXCOORD0;	float3 WorldPosition : TEXCOORD1; // The world position of the pixel	float3 WorldNormal   : TEXCOORD2; // The world normal of the pixel};struct PS_Output{	float4 Colour : SV_Target; // New semantics for DX10 - output to render target -replaces COLOR semantic in DX9};//-----------------------------------------------------------------------------// Main function//-----------------------------------------------------------------------------void main( in PS_Input i, out PS_Output o ) {	// Renormalise world normal for the pixel as it has been interpolated from the vertex world normals & may not be length 1	float3 WorldNormal = normalize( i.WorldNormal );	// Lighting preparation	// Get normalised vector to camera for specular equation (common for all lights)	float3 CameraDir = normalize( CameraPosition - i.WorldPosition );	// Accumulate diffuse and specular colour effect from each light	float3 TotalDiffuseColour = AmbientColour;	float3 TotalSpecularColour = 0;	// First light - Point light	// Calculate diffuse lighting from the 1st light. Standard equation: Diffuse = light colour * max(0, N.L)	//float3 LightDir = Light1Position - i.WorldPosition;	float3 LightDir = Light1Dir;	//float LightDist = length( LightDir );	//float LightStrength = saturate( Light1Brightness / LightDist );	//LightDir /= LightDist;	float diffuseFactor = dot( LightDir, WorldNormal );	if( diffuseFactor > 0.0f )	{		float3 DiffuseColour = /*LightStrength * */ Light1Colour * saturate( dot( WorldNormal, LightDir ) );		TotalDiffuseColour += DiffuseColour;		// Calculate specular lighting from the 1st light. Standard equation: Specular = light colour * max(0, (N.H)^p)		// Slight tweak here: multiply by diffuse colour rather than light colour		float3 Halfway = normalize( CameraDir + LightDir );		TotalSpecularColour += DiffuseColour * saturate( pow( dot( WorldNormal, Halfway ), SpecularPower ) );	}	// Final blending	// Combine lighting colours with texture - alpha channel of texture is a specular map	float4 TextureColour = Texture.Sample( MeshTextureSampler, i.TexCoord0 );	o.Colour.rgb = TotalDiffuseColour * TextureColour.rgb + TotalSpecularColour * TextureColour.a; 	// Set alpha blending to 1 (no alpha available in texture)	o.Colour.a = 1.0f;}


Sorry if this is sounding a little stupid, but I'm trying get to grips with it all.

[Edited by - chowarth on September 24, 2010 12:52:19 PM]
Dancin_Fool
Dancin_Fool
Make sure you're uploading a normalized direction vector for your light direction, that might be causing some issues. Also try only returning this portion of your code in the rgb channel of your return value.

saturate( dot( WorldNormal, LightDir ) );


That's essentially your diffuse lighting value, then you can at least debug if there's a problem with your normals or light direction.
chowarth
chowarth
Got it all working now, it appears the problem was caused by the: float3 LightDir, changed it to a float4 and it works perfectly.

Thank you for the earlier pointers, all helped.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.