SpotLight in HLSL does not work anymore, why?

Started by
7 comments, last by xsirxx 18 years, 4 months ago
Man ohh man! I hate lighting! I have all the lights working but my spot lights which dont work anymore.... where is my shader code, and my code to run it. Basically I get weird results, either no light spot(most of time), or I cant control the falloff. Please help me out guys, Im kinda at wits end. Shaders (the SpotPS is the one that is not working)


float4 TSpotLightingPS(VS_OUTPUT1 In) : COLOR
{
	half4 Color			= tex2D(MRT0, In.TexCoord);
	half3 Normal		= normalize(2 * (tex2D(MRT1, In.TexCoord) - 0.5));
	half2 PositionXY	= tex2D(MRT2, In.TexCoord);
	half2 PositionZW	= tex2D(MRT3, In.TexCoord);	
	half4 Position		= float4(PositionXY.xy, PositionZW.xy);

	half4 Light = LightVector - Position;
	Light.w = saturate(1 - dot(Light.xyz * tester[2], Light.xyz * tester[2])); // tester[2] == LightRange
	half3 LightDirec = normalize(Light.xyz);
	half diff = saturate(dot(Normal, LightDirec));
	half cosAngle = dot( LightDir, LightDirec );
	half spotFactor = smoothstep( tester[1], tester[0], cosAngle );
	//return ( (0.1f * Color) + ( spotFactor * LightColor * (Color * diff) ) * Light.w);
	return ( ( spotFactor * LightColor * (Color * diff) ) * Light.w);
}
pixelfragment TSpotPixelFragment = compile_fragment ps_2_0 TSpotLightingPS();
pixelfragment FSpotPixelFragment = compile_fragment ps_2_0 TSpotLightingPS();

float4 OmniLightingPS(VS_OUTPUT1 In) : COLOR
{	
	half4 Color			= tex2D(MRT0, In.TexCoord);
	half3 Normal		= normalize(2 * (tex2D(MRT1, In.TexCoord) - 0.5));
	half2 PositionXY	= tex2D(MRT2, In.TexCoord);
	half2 PositionZW	= tex2D(MRT3, In.TexCoord);
	half4 Position		= float4(PositionXY.xy, PositionZW.xy);
	
	half3	toLight		= normalize(LightVector - Position.xyz); // no normalize()?
	half	Dist		= length(toLight);
	toLight				/= Dist;
	
	half	atten	= 1.0 - saturate( Dist * LightRange );
	half	D		= saturate( dot(Normal.xyz,toLight) );
	
	//return (0.1f * Color) + ((D * Color) * atten );
	return ((D * Color) * atten );
}
pixelfragment OmniPixelFragment	= compile_fragment ps_2_0 OmniLightingPS();	


Here is the code to set the values:


	else if((itLightIT->second).iType == ID_FSPOT)
	{
		//pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
		for(int i = 0; i < 4; i++)
		{
			pd3dDevice->SetSamplerState( i, D3DSAMP_MIPFILTER, D3DTEXF_NONE );
			pd3dDevice->SetSamplerState( i, D3DSAMP_MINFILTER, D3DTEXF_POINT );
			pd3dDevice->SetSamplerState( i, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
			pd3dDevice->SetSamplerState( i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
			pd3dDevice->SetSamplerState( i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
			pd3dDevice->SetSamplerState( i, D3DSAMP_SRGBTEXTURE, 0 );
		}
		SetTexture( "MRT0", mrt0 );
		SetTexture( "MRT1", mrt1 );
		SetTexture( "MRT2", mrt2 );
		SetTexture( "MRT3", mrt3 );
		SetMatrixVS("WorldViewProj", matWorldViewProj );

		float ftester = 0.0f;//0.0004f;//0.04f;


		float fHotSpot = 0.51f;
		float fFalloff = 0.49f;
		D3DXVECTOR3 HotFallRange = D3DXVECTOR3( fHotSpot, fFalloff, ftester );
		SetVector4PS( "LightColor", &(itLightIT->second).vecColor );
		SetVector4PS( "LightVector", &(itLightIT->second).vecPosition );
		SetVector3( "tester", &HotFallRange );
		SetVector3( "LightDir", &(itLightIT->second).vecRotation );//

Any help would be greatly appreciated, thanks much! --Brad
--X
Advertisement
Quote:Original post by xsirxx

Shaders (the SpotPS is the one that is not working)
Light.w = saturate(1 - dot(Light.xyz * tester[2], Light.xyz * tester[2]));


I'm probably missing someting here, but I'm a bit puzzled by this equation. The dot product above will always be 1, no? So, your saturate function will always recieve an argument of 0. What gives?
Er.. the above poster was me. Forgot to log in!
"There is no dark side of the moon." - Pink Floyd
Thats what I used out of the Programming Vertex And Pixel Shaders book. Ive also see 1 - dot(...).

I have been having a tough time finding the math explanations on lighting. One of the reasons im having such a hard time with spot lights.

Instead of that would would you put? Or know a site with some explanation for the math? :). BTW, the tester[2] if ya didnt know by the math is the lightrange.

Thanks alot btw.
Brad
--X
Since Light.w = saturate(0) all the time (at least it looks like that) and since you are multiplying everything with it in the final return statement, it's likely to screw up your spotlight altogether. Unless you get that particular equation right. Have you double checked that code with the one in the book? Or checked the book website for some updates to the code?

Also, at a guess, I would imagine that the cosAngle term should actually be something like:
half cosAngle = max(dot( LightDir, LightDirec ),0);


However, I could be wrong! ;)
Ooeerr... me again! :)
"There is no dark side of the moon." - Pink Floyd
Yea I double checked, its difference free to the books. My rotations seem to be off somehow. I am putting in Yaw, Pitch, Roll from 3dsMAX, and it wants 1.0 as straight down. When I thought straight down would be 90 degrees or 1/2pi radians? Ohh its late, who knows :(.

[Edited by - xsirxx on December 5, 2005 3:58:19 AM]
--X
Quote:Original post by Anonymous Poster

half cosAngle = max(dot( LightDir, LightDirec ),0);


I tried this btw, and it didnt seem to change anything.. same results. If I make the angles 0,1,0 (all pointing down) all the lights look perfect. The minute I change 2 angles it goes haywire... weird...
--X
*Shameless bump*

Still cant get this guys, if I put in y = 1.57(90degrees) to face down it looks right. Then somehow when I put in 3.14(180degrees) the spot light just grows in size? what gives, 180 degrees shouldnt even show up because its pointing somewhere else... any ideas on what could cause this? Also my circle doesnt change in shape when the spot light is tilted another 45degrees from the surface. Shouldnt it go oval? ANY ideas at all would help out a ton, thanks!

Brad
--X

This topic is closed to new replies.

Advertisement