Jump to content
  • Advertisement
Sign in to follow this  
ddamicoAVI

Multiple Spot Lights with HLSL

This topic is 3960 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been testing XNA/HLSL for the last few weeks. I was able to render a model I created along with some simple lighting effects. I want to add multiple spots lights to my scene. After reviewing the Materials And Lights tutorial from I saw how they added two light sources. I attempted to replicate their procedures and ran out of arithmetic instructions in my Pixel Shader. So what I tried is use two passes. However, after the scene renders it only shows the second spotlight. Is there a better way to do this? I posted my FX file below.
struct VS_SpotOut
{
	float4 position : POSITION;
	float2 texCoord : TEXCOORD0;
	float3 interPos : TEXCOORD1;
	float att : TEXCOORD2;
	float3 lightVec : TEXCOORD4;
	float3 lightDir : TEXCOORD6;
};

struct VS_SpotIn
{
	float4 position : POSITION0;
	float2 texCoord : TEXCOORD0;

};

float CalculateFallOff(float alpha)
{
	float result;
	
	float nom = cos(alpha) - cos(phi);
	float donom = cos(theta) - cos(phi);
	result = pow(nom/donom,1);
	
	return result;
};
VS_SpotOut VS_Spot(VS_SpotIn input, uniform int CurrentLight)
{
	VS_SpotOut output;
	float4x4 wvp = mul(mul(World, View), Projection);
	output.position = mul(input.position, wvp);
	output.interPos = mul(input.position, World);
	output.lightDir = mul(-lightDirection, World);
	output.texCoord = input.texCoord;

	output.lightVec = lightPosition[CurrentLight] - output.interPos.xyz;
	output.att = 1-(1/pow(length(output.lightVec),4));
		
	return output;
}

float4 PS_Spot(VS_SpotOut input) : COLOR
{
	float4 FinalColor = {0.0f,0.0f,0.0f,1.0f};
	
	float4 TextureColor = tex2D(ColoredTextureSampler,input.texCoord);
	
	float alpha;

	alpha = acos(dot(input.lightVec,input.lightDir)/(length(input.lightVec)*length(input.lightDir)));  
		
	if (alpha < phi && alpha > theta)
	{
		FinalColor =  input.att * (CalculateFallOff(alpha) * (TextureColor)) ;
	}
	else if (alpha < theta)
	{
		FinalColor =  input.att * (TextureColor) ;
	}
	
	FinalColor.a = 1.0;
	return FinalColor ;
}
technique SpotLight
{
	
    pass Pass0
    {
        VertexShader = compile vs_2_0 VS_Spot(0);
        PixelShader = compile ps_2_0 PS_Spot();
    }
    pass Pass1
    {
        VertexShader = compile vs_2_0 VS_Spot(1);
        PixelShader = compile ps_2_0 PS_Spot();
    }
    
}
 

Share this post


Link to post
Share on other sites
Advertisement
You need to enable additive blending before rendering your second pass. Basically this means that the output of your second pass will be summed with the contents of the frame buffer, which should contain the results of your first pass. Unfortunately I have no idea how this is done in XNA, as I haven't so much as looked at the API. In Direct3D9 it's done by calling IDirect3DDevice9::SetRenderState 3 times, specifying (D3DRS_ALPHABLENDENABLE, TRUE), (D3DRS_SRCBLEND, D3DBLEND_ONE), and (D3DRS_DESTBLEND, D3DBLEND_ONE). I have no idea if there's anything at all equivalent to that in XNA, but I thought I'd share anyway.

Also you should keep in mind that you can increase the limit on your arithmetic instructions by using a higher pixel shader version. These include ps_2_a (Nvidia-optimized), ps_2_b (ATI X-series optimized), and ps_3_0. Of course you'll have to ensure the device supports these before you use your shader, and again I have no idea how that's done in XNA.

Share this post


Link to post
Share on other sites
Thanks for the reply. I found how to do it in XNA and how to do it in HLSL both yield the same result. Both lights show up but the scene is somewhat transparent. Any ideas?

XNA: I put this code in my Draw method

graphics.GraphicsDevice.RenderState.AlphaBlendEnable = true;
graphics.GraphicsDevice.RenderState.SourceBlend = Blend.One;
graphics.GraphicsDevice.RenderState.DestinationBlend = Blend.One;



One Light:

Free Image Hosting at www.ImageShack.us

Two Lights:
Free Image Hosting at www.ImageShack.us

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!