Max point lights

Hello, how can I have more than 4 point lights? I know there is a limit a mesh can be affected by 4 lights, but the lights dont work on anything. Only 4 do work. Each light is on different place. Thank you

Hiya I. Here’s a playground that might help. https://www.babylonjs-playground.com/#7HLWVI#4

It’s spotLights, not pointLights, but 8 are active on the same material… plus a scene hemi-light… for a grand total of 9. Notice line 27 setting maxSimultaneousLights = 10. I’m not sure what the limit is, but it appears you can exceed 4… with the right adjustments. I hope this helps.

3 Likes

Thank you for the comment. I know about this tho, but I dont need one mesh affected by 4+ lights, I just want more than 4 lights in the scene… affecting different meshes. Like imagine there were 12 meshes instead of 1 in the playground you sent… And I want each mesh affected by different light.

I tried the maxSimultaneousLights tho, but more than 12 throws me an error.

You can check it out https://varian.glitch.me/ username “iHu”, password leave empty -> login -> create lobby -> start. The white boxes on the top should represent red point lights, but only few do work.

1 Like

Ahh, I see. (or don’t see, because no lights) heh. Sorry about my mis-understanding on this. Nice scene and pretty webby welcoming, btw.

hmm. MAYBE… in some kind of movePlayer() function… you could constantly check distance to all scene.lights… from player/cam. If any of them are > someDistance away, shut them off. Conversely, if nearer than xxx, turn them on.

A single integer distance is available on BJS Vector3 class… as a static. it looks like line 28 in this playground. It can also be gotten like line 226 in this playground.

But maybe… that system needs to somehow combine-with camera.getActiveMeshes(). That would be a “2nd layer” check… ie. DON’T turn off a far-away light IF it is within sight of the user. This might require some extra invisible mesh on each side of the light. That way, when user turns-around in a hallway, they won’t see the light turn-on during their turn. (we would be waiting for lightmesh to turn “active”… which means its CENTER must enter camera-view). By the time the lightmesh center gets into camera frustum, user should already be seeing the LIGHT that is cast by the light itself, even though the lightmesh center is not yet within camera frustum (not yet active). Tough… but an interesting challenge.

Also, I think you can “bake” the lighting onto the wall/floor textures. I’m rather un-educated on this subject, but I guess it requires you to “2d-paint” the light’s illumination… onto the wall/floor textures… at the precise correct places in the scene. After all, a light… shining on a material… changes colors. You can force those color changes onto the textures… with your trusty “photo-paint” semi-transparent spray-brush. :slight_smile: Unfortunately, these fake lights can’t cast shadows. But, you can also paint-on shadows. A hanging plant beside a fake light… might cast a shadow on a nearby wall. You can also paint that shadow onto the wall’s texture, as long as the plant never moves. “Bake’n’Fake” :smiley:

I think max 11 lights on a single material… is not a surmountable limitation, currently. I wish I had better news for you. Let’s listen for more comments from wiser people than I.

1 Like

You can use something like this:

for (i =0; i < meshes01.length; i++){
light.01.includedOnlyMeshes.push(meshes01[i]);
}

where meshes01 is the mesh array of the meshes you want to include with that light. Repeat for each light with the appropriate mesh array. You might want to turn off each light before you assign meshes to that light.

A simple playground showing the use of includedOnlyMeshes

Two meshes/one light, but only one mesh is illuminated.

A more complex playground using it

In the ,babylon file that gets loaded there are five lights - 4 points and a hemi. The hemi illuminates everything the points illuminate just the 4 object meshes (no ground). the ground is then added to the green light

From the .babylon file created in Blender:

“lights”:[
{“name”:“point_purple”,“id”:“point_purple”,“type”:0,“position”:[5,4,5],“range”:5,“intensity”:2,“diffuse”:[1,0.0018,0.825],“specular”:[0,0,0],“includedOnlyMeshesIds”:[“Cube”]},
{“name”:“point_blue”,“id”:“point_blue”,“type”:0,“position”:[5,4,-5],“range”:5,“intensity”:2,“diffuse”:[0.0032,0.0063,1],“specular”:[0,0,0],“includedOnlyMeshesIds”:[“Cone”]},
{“name”:“point_green”,“id”:“point_green”,“type”:0,“position”:[-5,4,-5],“range”:5,“intensity”:4,“diffuse”:[0,1,0.0051],“specular”:[0,0,0],“includedOnlyMeshesIds”:[“Cylinder”]},
{“name”:“point_red”,“id”:“point_red”,“type”:0,“position”:[-5,4,5],“range”:5,“intensity”:2,“diffuse”:[1,0.0021,0.0021],“specular”:[0,0,0],“includedOnlyMeshesIds”:[“Sphere”]},
{“name”:“Hemi”,“id”:“Hemi”,“type”:3,“direction”:[0,1,0],“groundColor”:[0,0,0],“intensity”:0.2,“diffuse”:[1,1,1],“specular”:[0,0,0]}],

cheers, gryff :slight_smile:

2 Likes

I was thinking about the solution deactivating lights when there are not in view… I checked the camera.getActiveMeshes() function and it seems like it does not contain only meshes that are in view - wherever I look it still returns the same meshes… So I guess I will add a function which will be deactivating the lights based on the distance and if theres collision between the light and the player.

The texture solution would be a good idea if I didnt want the light to affect players too.

Thank you very much for your thoughts

This would be a solution if I didnt want a player affected by all the lights… but yes nice idea. Maybe I could include the player if he is near the light and then exclude after hes away. Thank you very much

https://playground.babylonjs.com/#KVRKS#6

Badly programmed… I was a youngster… but… you get the idea. An invisble light is turned-on over the player… as they enter a zone near-to the fake light-mesh. Essentially, if box/player distance to fake light fixture < xxx, turn-on invisible personal light parented to player/box. If > xxx, turn it off. Sneaky, huh?

I will check on that activeMeshes, thing. Camera may need to be moved/moving… to update actives/inactives. I’ll check on that… when I get a chance. Probably need to put console.log(camera.getActiveMeshes().length) inside the renderLoop… constantly outputting to console as camera pans-around.

Your light fixtures are separate mesh from walls/building, right? Or, are they part of one big building mesh? If the light fixture boxes are not separate mesh from building, then yeah, I could understand why camera.getActiveMeshes().length might not change as camera is panned/moved.

1 Like

Yea I got the idea, it is nice playground you sent. The light fixtures are separate. I wonder how the function works, because sometimes I have length over 200 sometimes less than 30 but most of the time it stays the same even when moving etc.

The property gryff mentioned light.includedOnlyMeshes is I guess the most suitable solution for me. I will include there only walls near the light (I will make many grounds and roof so I can separate it) and when a player is near the light, i will include the player too… then exclude. I didn’t realize the lights affect meshes even they are not in range… thats why only 4 works.

1 Like