[Solved] Updating PointLight radius after adding to scene

Hey, just wanted to see if anyone can tell me what I’m doing wrong here… I’m trying to decrease a pointlight based on a percentage of lifetime. So i’m creating the light like this:

private void createPointLight(Entity e) {
    PointLightComponent plc = e.get(PointLightComponent.class);
    BodyPosition bp = e.get(BodyPosition.class);

    PointLight pl = new PointLight();
    pl.setColor(plc.getColor());
    pl.setRadius(plc.getRadius());

    pointLightMap.put(e.getId(), pl);

    //Create pointer to the threadsafe same position buffer array as modelviewstate. 
    //Ensure it is the same by initialising it everywhere it's used
    bp.initialize(e.getId(), 12);
    bufferMap.put(e.getId(), bp.getBuffer());

    rootNode.addLight(pl);
}

And updating it like this:

decayingPointLights.applyChanges();

    for (Entity e : decayingPointLights) {

        if (pointLightMap.containsKey(e.getId())) {
            PointLightComponent plc = e.get(PointLightComponent.class);
            Decay d = e.get(Decay.class);

            PointLight pl = pointLightMap.get(e.getId());

            double percentage = d.getPercent();
            
            float factor = (float) (1 - (FastMath.pow((float)percentage, 5f)));
            
            float newRadius = Math.max(plc.getRadius() * factor , 0f);

            ColorRGBA oldColor = pl.getColor();
            ColorRGBA newColor = oldColor.clone();
            newColor.a = factor;
            
            pl.setColor(newColor);
            pl.setRadius(newRadius);
            
            if (factor < 0.5) {
                log.info(String.valueOf(pl.getRadius()) + " " + pl.getColor());
            }
        }
    }

The log was just to make sure my factor was working - now, the radius and alpha is decreasing as I want it to, but there’s no change in the lighting in the scene…’

Here’s the output from the log:

19:58:36,481 INFO [LightState] 138.6073 Color[1.0, 0.0, 0.0, 0.2772146]
19:58:36,497 INFO [LightState] 117.23256 Color[1.0, 0.0, 0.0, 0.23446512]
19:58:36,514 INFO [LightState] 93.824776 Color[1.0, 0.0, 0.0, 0.18764955]
19:58:36,530 INFO [LightState] 70.141045 Color[1.0, 0.0, 0.0, 0.1402821]
19:58:36,547 INFO [LightState] 44.515133 Color[1.0, 0.0, 0.0, 0.089030266]
19:58:36,564 INFO [LightState] 18.401415 Color[1.0, 0.0, 0.0, 0.03680283]
19:58:36,580 INFO [LightState] 0.0 Color[1.0, 0.0, 0.0, -0.017885804]

Is the parent node of the light present and correct?

Yea, I add the lights directly to the root node. the lighting actually works, I just can’t seem to turn down the lights once they are in the scene :slight_smile:

The alpha channel of the light color is never used in the shader, changing it has no effect.
It you want to reduce the intensity you have to decrease you red channel in your case.
You should see the radius decrease visually though… but note that radius 0 means no attenuation at all, so it will light the whole scene with a radius 0.

Thank you for the information. I wonder why I can’t see the radius decreasing - will have to investigate a bit more.

So I could decrease the ColorRGBA (though not through the alpha-channel) ending up with a Black color - would the light then not shine, or would it shine black ? :smiley:

Black is no light at all. There is no such thing as black light in jME.

Allright.

Would decreased radius have the same effect as decreased color (or more black to be precise) ?

If you are looking to lowering the light intensity IMO the color is the way to go. The decreasing the radius with a constant color will not produce the same effect and may look weird.

A pixel color is multiplied by the light color:

// example code....
vec4 pixelColor = vec4(1.0, 0.5, 0.3, 1.0);
vec4 lightStrengthAtThisDistance = vec4(0.2345, 0.435, 0.76453, 1.0);

vec4 actualColor = vec4(pixelColor.rgb * lightStrengthAtThisDistance.rgb, pixelColor.a);

so if you multiply the color by black (0, 0, 0) it will be black, or dark. If you multiply it by white (1, 1, 1) - it will be full brightness. That’s how lights work. The radius is the attenuation, or reduction in light color over distance. So reducing the radius to 0.001 will effectively make the light “off”. But as remy mentioned, the small area where the attenuation value is still positive will still be light, and probably look like a lightbulb that does not affect anything.

Thanks for the feedback . I’ll try to make a more thorough test, and perhaps record it. RIght now, my requirement is actually a projectile that lights up the environment. I’ll try to set the color instead of decreasing radius, to see which effect that has.

I’m using Lighting.j3md

Maybe off-topic but do you know the limit of number of point light? I do similar things and use lights for thrusters, explosions and well maybe also for bullets as it has a very nice visual effect for my space game :slight_smile:

There is no limit technically. However each additional light take away some performance.
If you are using multiple lights and the standard lighting shader you should consider using single pass lighting instead of the default lighting.
To do so:

// set the default light mode to single pass (only necessary for lighting.j3md, PBRLighting only uses single pass)
renderManager.setPreferredLightMode(TechniqueDef.LightMode.SinglePass);

// Set the maximum number of light to handle in one pass per geometry.
renderManager.setSinglePassLightBatchSize(5);

The legacy lighting mode (multi pass) is rendering the geometries once for each lights it’s affected by.
The Single pass mode renders up to N lights in the same pass (N being 5 in the above example).
This reduces the number of draw calls and enhances the perf.

Note: if you set 5 as the number and at some point a geom is affected by more that 5 lights, no big deal it will just do another pass with 5 lights and os on until all lights are rendered.

Then you are going to say… “why not set it to 1000 and never look back?”. because even if you have 2 ligths to render and that you set N to 5 the shader will still do 5 iterations per pixel.
So basically you want to find the best compromise with this number.
Experiment with it, look at the fps and the rendered objects count as an indicator.

2 Likes

Been a while since I’ve seen pictures of it - got anything new to show off?

the laser beam in the WIP thread is currently the newest progress. currently figuring out how battle grounds should be designed. Beside that I started to prototype weapons and how they should behave. Maybe I should think of a own thread to post updates :smiley:

Modifying the color with ColorRGBA.mult(float scalar) does a very nice job. Thanks.

I read your suggestion of single pass and batch in another thread as it also solves that problem with light and few big triangles vs many small triangles and strang lightning. But I was not aware of „limitless“ lights :slight_smile: so this single pass seems in many way the better option. As well I have now a good description what this batch size means :+1:

1 Like

I should write a documentation about it…

1 Like