Skip to content

Realtime light attenuation and colorspace #1703

Open

Description

@slipher

The physically correct rate for light attenuation is 1/r^2, where r is the distance between the surface and the point light. We used to use a 1/r equation. This is common in colorspace-oblivious rendering since after taking into account that in sRGB a color channel of x produces an amount of light proportional to about x^2.2, the effective attenuation is 1/r^2.2 which is pretty close to 1/r^2. In a979351 the equation was changed from 1/r to 1/r^2. I doubt this was a good idea since now the effective attenuation is an excessive 1/r^4.4. In a linear colorspace we would obviously want to use 1/r^2.

With the introduction of sRGB/linear colorspace, there is the question of how to make a dynamic light API that will give consistent results between the colorspaces. The idea from the current version of #1687 seems OK: a 0-1 RGB color which is interpreted as sRGB, and an intensity which should always be interpreted as linear. Then we could use the formula convertToSRGB(color)/r^2 for the linear colorspace, and if we want to get identical results in the sRGB colorspace, color / r^(2 / 2.2) = color / r^0.90909. To make this API, unfortunately we will have to undo the changes to the 0.56 branch which got rid of the separate 'intensity' argument in favor of unbounded r/g/b.

Activity

  1. slipher commented on Mar 11, 2026

    @slipher
    MemberAuthor

    In a979351 the equation was changed from 1/r to 1/r^2. I doubt this was a good idea since now the effective attenuation is an excessive 1/r^4.4.

    I got this backward, the attenuation there would be 1/r^1.1 not 1/r^4.4.

    Anyhow, the equation we are currently using (the red line) actually isn't very close to 1/r^2. On this graph x is the distance as a proportion of the light's "radius" (cutoff distance) and y is the attenuation. x = 1 is the cutoff point where a light will not be selected for the light tile if the distance is greater than this. The 1/x and 1/x^2 curves are scaled so that they cross at x = 1. I would say our curve looks closer to 1/r. (One can try different constant factors, but I couldn't make 1/x^2 any closer that way.)

    Image



    Since the a given numerical color value in the 0-1 range represents a brighter light in linear space than in sRGB, the attenuation cutoff is too high in linear mode, resulting in hard edges on the light tiles.

    Image

  2. slipher commented on Mar 17, 2026

    @slipher
    MemberAuthor

    #1929 has a hack to fix the issue shown above, but we should still look for a better equation for the linear blend regime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions