Jump to content

Recommended Posts

How do light intensity, radius, and falloff work? Specifically, with respect to the light value at a given distance from the source. (Equations appreciated!)

I've noticed that a high intensity shrinks the resulting calculated radius and concentrates brightness, whereas falloff does the opposite.

Ultimately, I need to be able to determine at what distance from a light source the light value will be a given value (such as .075) using GetCalculatedRadius() and intensity/radius/falloff.

Edited by Bumber64
On 4/8/2022 at 5:22 AM, Bumber64 said:

If nobody has an answer, is there somebody at Klei I should ask?

 

unfortunately, questions don't always get answered on the forums. You could try asking on the discord server?

  • Developer
On 3/24/2022 at 10:21 AM, Bumber64 said:

Ultimately, I need to be able to determine at what distance from a light source the light value will be a given value (such as .075) using GetCalculatedRadius() and intensity/radius/falloff.

TheSim:GetLightAtPoint(x, y, z, threshold) will tell you what the values are but if you want to directly calculate them then it is a bit involved I will try to explain. Ambient light is calculated by taking the magnitude of TheSim:GetAmbientColour() vector with each component normalized first. Each entity with a light that overlaps the point with their light radius will add to a running sum. The value that is added is calculated by a series of calculations. Assign A to be log(intensity), B to be falloff / A, C to be (distance / radius) ^ (-B), D to be e ^ (A  * C), E to be the standard luminance of the light, F to be E * D. F is added to the running sum. D will be forced to 1 if A is 0.

  • Like 5
  • Thanks 2
  • Big Ups 3

@JesseB_Klei

How is E calculated? I tried using a formula found here:

local function sRGBtoLin(c)
    return (c <= 0.04045) and (c / 12.92) or math.pow(((c + 0.055) / 1.055), 2.4)
end

local function luminance(r, g, b)
    return (0.2126 * sRGBtoLin(r) + 0.7152 * sRGBtoLin(g) + 0.0722 * sRGBtoLin(b))
end

However, the result seems to be too low for anything but white (1, 1, 1) when comparing E to (GetLightAtPoint - ambient) using a light with intensity 1 (A == 0).

  • Developer
7 minutes ago, Bumber64 said:

@JesseB_Klei

How is E calculated? I tried using a formula found here:


local function sRGBtoLin(c)
    return (c <= 0.04045) and (c / 12.92) or math.pow(((c + 0.055) / 1.055), 2.4)
end

local function luminance(r, g, b)
    return (0.2126 * sRGBtoLin(r) + 0.7152 * sRGBtoLin(g) + 0.0722 * sRGBtoLin(b))
end

However, the result seems to be too low for anything but white (1, 1, 1) when comparing E to (GetLightAtPoint - ambient) using a light with intensity 1 (A == 0).

You will need to remove the sRGB conversion function and use each r g b channel as a normalized from 0 to 1 in your luminance function.

  • Like 2
  • Thanks 2
  • Big Ups 1

Here are the finished functions:

local function light_at_dist(l, dist) --light value at distance from source
    local A = math.log(l:GetIntensity())
    local B = -(l:GetFalloff() / A)
    local C = (dist / l:GetRadius()) ^ B
    local D = math.exp(A * C)
    local r, g, b = l:GetColour()
    local E = 0.2126 * r + 0.7152 * g + 0.0722 * b

    return D * E
end

local function dist_for_light(l, threshold) --dist from source with threshold value
    local threshold = threshold or 0.075

    local A = math.log(l:GetIntensity())
    local B = -(l:GetFalloff() / A)
    local r, g, b = l:GetColour()
    local E = 0.2126 * r + 0.7152 * g + 0.0722 * b

    return math.exp(math.log(math.log(threshold / E) / A) / B) * l:GetRadius()
end

Lua gracefully handles the case where A == 0.

Edited by Bumber64
  • Ninja 1
  • Big Ups 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...