Uniformly light/shadow accumulation

I’m working with the ProgressiveLightMap class and my goal is to accumulate uniformly lights and shadows in a scene.

For testing that, I set a light which move all around an object that is in the middle, so I would like to get the same amount of shadows in each side of the object. The light is moved 0’1º each time (x3600 times) so it makes a perfect 360º circle. The truth is that I’m displaying 10 lights at a time to speed up the convergence, so there’re 10 lights (x360 times).

But as you can see in the pictures there is less light in one side than in the other:

How should I accumulate the shadows in order to save correctly how much light is in my scene?

Here is the part of the code where I call to the update method of the ProgressiveLightMap class:

    // Loop to accumulate 10 lights at a time during 360º
    const lightCount = 10
    let angle = 0
    while (angle < 360){

        for ( let l = 0; l < lightCount; l ++ ) {
            dirLight[l].intensity = 1.0 / lightCount
            dirLight[l].position.set( ...createPositionVector(angle, 30, 200))
            angle += 1 / lightCount  // 0.0º, 0.1º, 0.2º, ..., 359.9º

        // Accumulate shadows
        if ( params[ 'Enable' ] ) {
            progressiveSurfacemap.update( camera, 360, true );

You can find the rest of the code here:


i am using this formula, it is random but very uniform over a couple of frames. i guess it can be changed to a deterministic function, too but i didn’t really care for that.

// position - the origin of the light source
// radius - how much the position is offset
// ambient - factor between 0 and 1 (0.5 is a good value)

for (let l = 0; l < gLights.current.children.length; l++) {
          light = gLights.current.children[l]
          if (Math.random() > ambient) {
              position[0] + THREE.MathUtils.randFloatSpread(radius),
              position[1] + THREE.MathUtils.randFloatSpread(radius),
              position[2] + THREE.MathUtils.randFloatSpread(radius)
          } else {
            let lambda = Math.acos(2 * Math.random() - 1) - Math.PI / 2.0
            let phi = 2 * Math.PI * Math.random()
              Math.cos(lambda) * Math.cos(phi) * length,
              Math.abs(Math.cos(lambda) * Math.sin(phi) * length),
              Math.sin(lambda) * length

you can try all these values in this sandbox

Thanks for the idea!
But I need to use the Progressive Light Map class :frowning:

Maybe @zalo the author of the class can help us here? :melting_face: :pray: