Documentation
    Preparing search index...

    Variable PUNCTUAL_LIGHT_WGSLConst

    PUNCTUAL_LIGHT_WGSL: "struct PunctualLight {\n irradiance : vec3<f32>,\n direction : vec3<f32>,\n};\n\nfn punctualLight(index : i32, p : vec3<f32>) -> PunctualLight {\n let offset = lights.punctualPosition[index].xyz - p;\n let distanceSquared = max(dot(offset, offset), 1e-8);\n let d = sqrt(distanceSquared);\n let l = offset / d;\n let params = lights.punctualParams[index];\n var attenuation = 1.0 / distanceSquared;\n if (params.x > 0.0) {\n let ratio = d / params.x;\n let squared = ratio * ratio;\n attenuation = attenuation * clamp(1.0 - squared * squared, 0.0, 1.0);\n }\n if (params.w > 0.0) {\n let cosTheta = dot(lights.punctualDirection[index].xyz, -l);\n attenuation = attenuation * clamp((cosTheta - params.y) * params.z, 0.0, 1.0);\n }\n var result : PunctualLight;\n result.irradiance = lights.punctualColor[index].xyz * attenuation;\n result.direction = l;\n return result;\n}" = ...

    The light model both shaded fragment stages share — the WGSL port of gl-program.ts's PUNCTUAL_LIGHT_GLSL, one string spliced into both families for the recorded reason: the falloff and the cone are one model, and a scene mixing a LitMaterial with a StandardMaterial under the same lamp must not be able to disagree about it.

    The arithmetic is the GLSL chunk's, line for line — inverse-square with the max(d², 1e-8) guard where the division happens, KHR_lights_punctual's range window and cone ramp, the precomputed params.z reciprocal — with one syntactic difference: WGSL has no out parameters, so the direction travels back in a two-member struct instead of an out vec3 l.

    No 1/π appears here or in either lobe that consumes this — the engine's light colour × intensity is an irradiance already divided by π (R-13), which is what lets a point light and the directional light add up to one lighting model across both backends.