Jump to content
  • Advertisement
Sign in to follow this  
lowcost

Please help with D3D Point Light Attenuation

This topic is 4950 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

Dear Community, My problem lies with D3D point lights. As you know, the useful tweak values for the point lights are max range, attenuation 0,1 and 2. I want to make a generic all-purpose light which will give a full rounded light based on the maxrange parameter. Surely it's not too much to ask you might think - but it has driven me to my wits end! I have made an application to change the maxrange and att0, att1 and att2 values to create a graceful, full looking light that falls off nicely to maxrange, however... my problem is actually finding a formula which will take maxrange value and give me the "fullest" looking light possible for the maxrange by giving me the resultant att0, att1 and att2 values back. By fullest, I mean nice and bright in the middle, and falling off to the edges in a predictable manner. I understand att0 will probably be a constant though (so I've read). Do you have any formulas you can offer which will give me att0, att1 and att2 values which will do this based off max range? I would be very grateful - tearing my hair out at the moment. I'm not too good with maths so I'm just basically trying my best! Any help you can give, no matter how big or small will be really appreciated! Thanks in advance, Rob

Share this post


Link to post
Share on other sites
Advertisement
I think, it's good enough to compute att1, so that value at maximum range will be small enough for example 1/100.
So the equation, you want is: 1 / (att1 * MaxRange) = 1/100.

Share this post


Link to post
Share on other sites
Thank you for your quick reply!

I plugged in final = 1.0/(att1 * maxrange) for att1, and it works however there is almost no falloff to black at all unfortunately. It is like a very rough fullbright blob of light.

Perhaps I am doing something wrong?

Share this post


Link to post
Share on other sites
I think you need to solve for att1, if I'm reading this correctly,

1 / (att1 * MaxRange) = 1/100

means: one divided by the product of att1, and MaxRange is equal to 1/100, so then we need to say, (att1 * MaxRange) needs to be 100. so:

att1 = 100 / MaxRange;

i used 512 in MaxRange and got this:

100 / 512 = 0.1953125

1 / (0.1953125 * 512) = 0.01

Let me know if that helps.


[Edited by - mozie on November 27, 2004 4:35:44 PM]

Share this post


Link to post
Share on other sites
Thanks! So in basic psudocode, this is:

temp = 512/maxrange
att1 = 1/(temp*maxrange)

I plugged this in but the effect from att1 doesn't seem to work! Sorry if I'm being really difficult - just trying to get to grips with it all...

Share this post


Link to post
Share on other sites
If you turn the brightness up, it looks a bit rough to be honest. Perhaps att2 needs tweaking too.

Surely someone has actually had experience in dx lights and has made a little routine to adjust these two values? :)

Finally, I've made a test application (please turn brightness up if you wish to see the falloff better) and it can be found here. You will see the problem I'm having trying to make a light which I can just change the maxrange and have it still bright as possible with lovely-looking falloff to black.

http:/www.redflame.net/files/d3dlight.zip

Thanks!
Rob

Share this post


Link to post
Share on other sites
Quote:
Original post by lowcost
Thanks! So in basic psudocode, this is:

temp = 512/maxrange
att1 = 1/(temp*maxrange)

I plugged this in but the effect from att1 doesn't seem to work! Sorry if I'm being really difficult - just trying to get to grips with it all...


I was using 512 as an example for the lights max range, so maybe it would look like this:

d3dlight0.Attenuation1 = m_lightscale / d3dlight0.Range;

m_lightscale would be 100, if you want the light that reaches Range to be 1/100th intense. if you want it to be 1/1000th substitute 1000 into m_lightscale.

My current project uses only 1 spotlight in the scene, so I dont use Attenuation. So maybe I'm completly off.
I got most of this from the DX9 CHM. Check this part out if you dont follow, plug "Attenuation and Spotlight Factor" into the search tab. It might just get you more confused though too. ;)

Share this post


Link to post
Share on other sites
Just DL'd the program you have, and I set the att vals like so:

att0: 0.0
att1: 0.6
att2: 0.0
range: 90.6
height:24.2

att = 1 / ( 0.6 * 90.6 ) = 1/54.36th

and I thought that the light looked pretty soft.

http://hatekick.000freehosting.com/softlight.JPG

EDIT: link problem

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I'm having this exact same problem in a game I'm working on.

I've tried formulas based on range, tried manually adjusting the values, etc.

The attenuation seems to affect the way objects are lit within the range of the light, but the result at falloff is never smooth (always choppy).

The DirectX documentation on attenuation is no help. The falloff on the cone of spotlights seems to work fine, but I don't think those even work well when an object reaches the falloff from the range of the light.

Anyone else find a solution to this?

Share this post


Link to post
Share on other sites
Here is my own little light code. I wrote it because I didnt have a light class in my object manager, and I wanted to play with the lights after this thread, maybe it will help someone. the bulk of the class is not present, just the implimention in the manager. and the CalcAtt function of the class is given tho.


// my CObjectLight class is mostly just an interface for D3DLIGHT9
CObjectLight* aLight;

// inside of the virtual DX RestoreDeviceObjects somewhere ;)
..
..
// var 2 is a D3DLIGHTTYPE enum
aLight->InitLight(0, D3DLIGHT_POINT);
aLight->SetRange(120.0f);
aLight->CalcAtt(20.0f);
aLight->SetSpecular(D3DXCOLOR(0.0f,0.0f,1.0f,0.75f));
aLight->SetAmbient(D3DXCOLOR(0.0f,0.50f,2.0f,0.5f));
aLight->SetDiffuse(D3DXCOLOR(1.0f,0.0f,0.0f,0.75f));
aLight->SetDirection(Vector3(0.0f,0.0f,-1.0f));
aLight->Set();

if(aLight->IsEnabled() == FALSE)
aLight->Toggle();
..
..

// InitLight sets the d3d light ref number
// and sets it up as type, should be called
// prior to custom colors, range, etc
void CObjectLight::InitLight(int setref, D3DLIGHTTYPE LightType)
{
ref = setref;
SetInternal(Vector3(0.0f,0.0f,0.0f));
SetDirection(Vector3(0.0f,0.0f,1.0f));
Type = LightType;
Range = 100;
CalcAtt(25.0f);
Theta = 0;
Phi = 0;
switch(Type)
{
case D3DLIGHT_POINT:
{
// point light
break;
}
case D3DLIGHT_SPOT:
{
// spot light
Falloff = 1.0f;
Theta = (D3DX_PI/180)*45;
Phi = (D3DX_PI/180)*90;
break;
}
case D3DLIGHT_DIRECTIONAL:
{
// directional light
break;
}
case D3DLIGHT_FORCE_DWORD:
{
// force_dword
break;
}
}
Diffuse = D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);
Ambient = D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);
Specular = D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);

Set();

Enabled = FALSE;
}

// CalcAtt uses the Range to set att1
void CObjectLight::CalcAtt(float endth)
{
Att0 = 0.0f;

if(Range > 0.0f)
Att1 = endth / Range;
else
Att1 = 0.0f;

Att2 = 0.0f;
}



aLight->Set() just pushes all my redundant vers
into the D3DLIGHT9, and calls d3dDev->SetLight(ref, Enabled);
I use two functions: bool IsEnabled(), and; bool Toggle()
to toggle the light off/on with d3dDev->SetLight calls.

changing nothing but the D3DLIGHTTYPE from POINT to SPOT (number of balls is different too i guess ;), gets me these.

http://hatekick.000freehosting.com/pointlight_balls.JPG
http://hatekick.000freehosting.com/spotlight_balls.jpg

might show the att in use, because the A,D, and S of the light are set to different colors, some with different levels than others, so the light seems to layer, this is in part a result of the att1 being set, you can see in the code, i set it up so:
the light would be 1/25th at Range, and it interplotes up from there as it gets closer to the light. the 'd' velue in the DX9 CHM formula that DX uses to calculate the final att of the vertex, is the magnitude of a vector from the vertex in question, to the light source.

I made the Toggle, because I was reading the optimizing lights thread here, and thought it might come in handy in the future (maybe).

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!