I am create a modern Unity based client of an old MMO from 2000, and I am working on implementing their lighting system. Based on the data I have reverse engineered, it looks like they used a custom attenuation formula. The original client uses DirectX 7. I have found a reference sheet for DX7 light.


The relevant info starts at page 17. In the URP, in Lighting.hlsl, I have set up linear attenuation:

float range = rsqrt(distanceAndSpotAttenuation.x);
float dist = distance( positionWS, lightPositionWS);
half attenuation = 1.0f - dist/range;        

Looks good! https://i.imgur.com/5bfJ5fF.png

Everything looks good. Now I am trying to (based on the document) recreate the same linear attenuation. It should look something like this:

// DX 7
float range = rsqrt(distanceAndSpotAttenuation.x);
float dist = distance( positionWS, lightPositionWS);
half c0 = 1.0f;
half c1 = 1.0f;
half c2 = 0.0f;
half d = dist/range;
half attenuation = 1.0f / ( c0 + c1 * d + c2 * d * d );

This should give me linear attenuation according to the doc, but it ends up bleeding light way past the range of the light. So I am convinced the distance is wrong. What kind of value is expected here? Normalized distance? It doesn't specify. I have played around with the distance a lot. Set it to the attenuation in the first code example, to the raw value, and a bunch of other values. No luck: https://i.imgur.com/JWJ0HF2.png

Does anyone have any ideas?

New contributor
Satchmo White is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
  • \$\begingroup\$ We have some existing Q&A about that attenuation formula here, which might give you some insights into how it's used here. Note that this formula has no conception of a "limiting range" of a light - mathematically, it never reaches zero (though rendering with a fixed colour depth, it will eventually round to zero). \$\endgroup\$ – DMGregory Nov 19 at 22:34
  • \$\begingroup\$ @DMGregory Thanks for the link! That does explain a lot about the origins and usefulness of that formula. I appreciate the link. What it doesn't do though is explain how exactly it's anticipated that distance is specified? Is it a normalized value with 0 meaning it's at the center and 1 at the radius, or is it reversed? Or is it used another way? That's the issue I am having; translating Unity lighting variables to work with it. \$\endgroup\$ – Satchmo White Nov 19 at 22:54
  • \$\begingroup\$ There's no such thing as radius in this formula. Distance goes from 0 to infinity. You can adjust the parameters c1 and c2 to get the same output no matter what unit you measure distance in. \$\endgroup\$ – DMGregory Nov 19 at 23:49
  • \$\begingroup\$ @DMGregory I think I finally understand. I am trying to force this algorithm to work with a radius, when c1 and c2 indirectly control the distance that it shines. Where would I look for an example of a square falloff but including a radius component? \$\endgroup\$ – Satchmo White Nov 20 at 6:44
  • \$\begingroup\$ There was a similar question here about limiting the angle of a spotlight. I think you could apply a similar technique, finding the value of your existing falloff function at your desired radius, then remapping its output so that value is mapped to zero. \$\endgroup\$ – DMGregory Nov 20 at 10:25

Your Answer

Satchmo White is a new contributor. Be nice, and check out our Code of Conduct.

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.