Thanks guys.
I will try this approach (Light Halos | Learn PlayCanvas ) which may be less expensive than ara lights, i first target mobile phones for my game.
I have this environment
and want this kind of environment :
2 Likes
Maybe spotlights with cookies are an option, or is this just as expensive?
https://developer.playcanvas.com/en/tutorials/light-cookies/
yep, almost as expensive.
1 Like
The solution like in Light halos tutorial with glow halo material work fine.
I just now have an error on iOS (ok on PC) with all the Spot lights i have used for the lampposts in the streets.
Failed to link shader program. Error: FRAGMENT shader uniforms count exceeds.
MAX_FRAGMENT_UNIFORM_VECTORS(224)
May be too much lights for WebGL rendering ?
Scene link : https://playcanvas.com/editor/scene/1196860
1 Like
Ok i just found a logic solution. I will only activate lights that are in a big circle around the player.
1 Like
also, your lights don’t use shadows … and perhaps clustered lighting is a good candidate to be used.
Many thanks for this great feature! Performance is already great (2-3ms for 50-60 point lights), though we are thinking if there is something we can do to help the renderer when some of the lights are definitely not required to be rendered.
Toggling the light component on/off forces a recompile of something that hangs the main thread for a while. For the moment we just set the intensity to zero for lights that shouldn’t be rendered (for our game purposes).
Curious if there is something in addi…
playcanvas:master
← playcanvas:mvaligursky-clustered-lights
opened 02:19PM - 19 Mar 21 UTC
This is an initial implementation of clustered lighting for local lights without… shadows (omni and spot, with punctual shape - so no area lights). There will be further improvements later to allow these lights to support shadows by rendering them into a shadow atlas. Note that in this implementation, the clustering is done in the World Space instead in more commonly used Camera Space to improve performance, and allow the clustering structure to be used by multiple cameras (for example rendering to texture). It also allows us in the future to avoid rebuilds of this structure if lights don't change).
The difference compared to the current local lights implementation is that while current implementation uses all dynamic lights on all objects in the scene, clustered implementation places these lights into a 3d grid structure with specified size, and when a pixel is rendered, lights it needs are fetched from this 3d grid. Thus it works the best if the overlap of lights is not large. Example being a large level with many local lights with small range in various places inside the level. The test case (see screenshot) replicates this. The level is represented by a large cylinder and many other meshes (spheres and cones), which all get lit by the lights. Both omni and spot lights are separated with low density to minimize amount of lights a pixel needs to use.
_There is a limitation at the moment in that only diffuse part of lighting is evaluated for clustered lights, and specular is not. This will be addressed in the future._
**Changed API:**
constructor of LayerComposition now takes additional parameter, which is a GraphicsDevice. Not passing this parameter is ok for an application using single instance of Application.
**New API (all private at this point, as it might be subject to change):**
- **WorldClusters.enabled** - enables clustered lighting (disabled by default). Needs to be called before rendering, and cannot be changed after.
- **LayerComposition.clusteredLightingCells** - specifies Vec3 with number of cells of the clustering 3d grid
- **LayerComposition.clusteredLightingMaxLights** - maximum number of lights a cell can stored. Ideally with small overlap of lights this could be set to a small number, for example 8.
**Example of API use:**
```
// enabled clustered lighting. This is a temporary API and will change in the future
pc.WorldClusters.enabled = true;
// adjust default clusterered lighting parameters to handle many lights:
// 1) subdivide space with lights into this many cells:
app.scene.layers.clusteredLightingCells = new pc.Vec3(12, 16, 12);
// 2) and allow this many lights per cell:
app.scene.layers.clusteredLightingMaxLights = 48;
```
**Other changes:**
- some refactor to layer composition in how the shadow casters are updated
- mostly non functional change, apart from processing each layer only one time (slight optimization)
- optimized light management in the layer by using a Set of lights
- refactored ShadowCasters into LightCompositionData (mostly rename)
**Performance test**
(on very old Huawei phone and MacBook Pro). Note that this depends on light overlap, grid size and similar and are only representative or "common" expected scenario. This also confirmed minimal negative impact when zero or small number of lights are used.
Also note that API allows to move the cost both ways between CPU and GPU. When you use large number of cells (clusteredLightingCells), CPU update is more costly, but GPU is cheaper as light overlap is more precise. On the other hand it small number of cells is used, CPU update is fast, but GPU needs to use many lights for each pixel.
huawei 0 lights
- clustered: 0.5ms
- normal: 0.5ms
PC 0 lights
- clustered: 0.2ms
- normal: 0.2ms
huawei 5 lights
- clustered: 2.1ms
- normal: 2.8ms
huawei 50 lights
- clustered: 14.6ms
- normal: 36ms
PC 50 lights
- clustered: 3ms
- normal: 32ms
**Example** (link valid when released)
http://playcanvas.github.io/#graphics/clustered-lighting.html
This uses clustered lighting, with a grid size of 12, 16, 12, with the maximum number of lights per cell being 48, and rendering 30 point lights and 16 spot lights. In addition there is one shadowing directional light as well.
![Screen Shot 2021-04-19 at 2 12 13 PM](https://user-images.githubusercontent.com/59932779/115241915-43485400-a119-11eb-88fc-39c70c6a793d.png)
References:
https://newq.net/publications/more/s2015-many-lights-course
2 Likes
Thanks, i will look at this too, but a simple solution first would be easy i think to implement.
Hey guys,
I have tried to optimize the rendering i want, and i still have a little performance bottleneck.
I have now 61 lights in the map.
I have a simple algorithm to calculate all the lights in a circle around the player, and toggle off/on lights. I have for each check, i have to toggle on around 10-15 lights. Like @Leonidas in the thread mentioned before, i see a little lag when i toggle them on.
Is there another way to optimize that ? May be with lights less intensive ? Thanks
Try setting the intensity to 0.0 instead of disabling light entities, since that would force the light cells to be recalculated.
1 Like
Your solution needs to have all the lights activated if i understand well. So i will reach the WebGL error mentioned before MAX_FRAGMENT_UNIFORM_VECTORS
It’s not a great solution, but one thing you can do to avoid the MAX_FRAGMENT_UNIFORM_VECTORS
problem is to split your scene objects (and duplicate materials if they are shared) and lights onto different layers. That way you won’t be exposing all objects/materials to lights that they don’t have to be affected by.
1 Like
Calling @mvaligursky , curious what he thinks.
@eproasim
The lights are linked to default World layer
@vogloblinsky ,
I understand, but you can start splitting your geometry and lights up on different layers. Lights will affect all objects/materials on the same layer, regardless of whether they are in range or not. If you split your level up onto separate layers, and then the lights for those respective areas onto those same new layers, you can control the number of uniforms that are being passed to each material.
You might have some trouble lighting the player, since he would need to be lit by practically all the lights, which would cause an overload. A quick and dirty way to address that would be to have a single light for the player on his own layer that adjusts its brightness based on the proximity to the other lights.
Is this with clustered lighting enabled? As long as you don’t need shadows, it should be pretty straightforward to setup: PlayCanvas Examples
No clustered lights not enabled. All the lights are added in 3D editor mode, and just activated by code in my final game.
What would be the advantage for my use-case ?
Increased performance and it may be able to get around the iOS light limit?
Just added in my project :
pc.LayerComposition.clusteredLightingEnabled = true;
pc.app.scene.layers.clusteredLightingCells = new pc.Vec3(20, 2, 20);
pc.app.scene.layers.clusteredLightingMaxLights = 48;
and i have this warning in Chrome 91 / macOS Big Sur 11.4
[.WebGL-0x7fee69cb5600]GL ERROR :GL_INVALID_OPERATION : glDrawElements: Texture bound to texture unit 0 with internal format GL_DEPTH_COMPONENT32F is not compatible with sampler type GL_SAMPLER_2D
Is there a documentation about these options ?
The API is still in the works, the example is your best bet and you can also check the source code here:
import { Vec3 } from '../math/vec3.js';
import { math } from '../math/math.js';
import { BoundingBox } from '../shape/bounding-box.js';
import { Texture } from '../graphics/texture.js';
import { PIXELFORMAT_R8_G8_B8_A8, PIXELFORMAT_RGBA32F, ADDRESS_CLAMP_TO_EDGE, TEXTURETYPE_DEFAULT, FILTER_NEAREST } from '../graphics/constants.js';
import { LIGHTTYPE_DIRECTIONAL, LIGHTTYPE_SPOT } from './constants.js';
const tempVec3 = new Vec3();
const tempMin3 = new Vec3();
const tempMax3 = new Vec3();
const tempBox = new BoundingBox();
const epsilon = 0.000001;
const oneDiv255 = 1 / 255;
const maxTextureSize = 4096; // maximum texture size allowed to work on all devices
// packs a float value in [0..1) range to specified number of bytes and stores them in an array with start offset
// based on: https://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/
// Note: calls to Math.round are only needed on iOS, precision is somehow really bad without it,
// looks like an issue with their implementation of Uint8ClampedArray
This file has been truncated. show original
Ok, i have tryied to update parameters but it didn’t change anything.
I have another question on lighting topic. Many elements in my scene are static, like buildings.
If i understand well, using lightmaps could be a good performance improvement.
My building model don’t have “Lightmapped” option activated, so shadows are calculated in realtime. If i activate the option, i have the warning “UV1 is missing”.
When i check the model, i didn’t have the “Pipeline” option on the right panel, like in the doc (Runtime Lightmaps | Learn PlayCanvas )
Link to scene : https://playcanvas.com/editor/scene/1091565