engine icon indicating copy to clipboard operation
engine copied to clipboard

Implement Textured Area Lights

Open marklundin opened this issue 2 years ago • 8 comments

This ticket is a request for comments/progress tracker for adding textured area lights as an extension to the current LTC implementation.

image

DEMO

The above example includes an custom version of the engine (v1.54) that implements textured area lights using the current LTC shader chunks. It's using the cookie texture slot on the lighting system as the light source. Works with diffuse/specular/CC.

The blurriness/roughness is an approximation of a gaussian kernel that uses weighted samples of the mip-chain. This appears to be a better quality blur than many other approaches (especially at higher blurriness levels) but is cheaper to compute than most solutions of a similar quality. The cost is bound to the texture resolution (1k is 10 taps) and independent of the blur strength.

Tasks:

  • [x] Update Standard Material + shader chunks
  • [ ] Integrate with clustered lighting.

Optional:

  • [ ] Implement a mipmap-less approach similar to https://github.com/playcanvas/engine/pull/3783 by @slimbuck may be suitable
  • [ ] Allow lower quality/cheaper solution using 2 taps of the mip-chain

Open Questions:

  1. Should the textured area lights use the cookie texture slot or a dedicated one. The semantics are different but there may also be some practical issues if one light has a cookie and another is a textured area light. This will also have implications for the cookie atlas in clustered lighting.
  2. Is it preferable to pre-compute a mipmap-less texture in a similar way to https://github.com/playcanvas/engine/pull/3783. This may not always be required if using dynamic/video textures for example but for static ones it may be better (same code path for all devices)

Related PRs Clustered Area Lights Clustered Lights mipmap-less environment lighting

Any feedback welcome @mvaligursky @slimbuck @willeastcott

marklundin avatar Jun 10 '22 11:06 marklundin

Fantastic work so far!

  • Cookie slots are rarely used, and personally I think using them for area lights cookie texture is a perfect solution.
  • I think we'll need to implement a mipmap-less solution. This is definitely needed for clustered lights, where cookie textures are stored in an atlas.

Perhaps it could work like this:

  • a cookie texture on an area light would be expected to be a normal texture / movie texture.
  • internally, after the lights are culled, for visible area lights we'd generate a mipmap-less texture (result texture stored on a light, some private variable). Perhaps this could be handled similarly to how lights render shadows. By default it would generate mipmap-less once, but a property could be set to do it every-frame or this-frame (see SHADOWUPDATE_THISFRAME for example), giving user the control over the cost (for example every 10th frame).
  • when the area light is used for rendering, it would use the mipmap-less texture.
  • if clustered lighting is used, this mipmap-less texture would be then copied to the atlas.

I think it would be ok if this was done only for the clustered lights, saving having to do this for normal lighting as well - as this will get deprecated in not too distant future most likely.

mvaligursky avatar Jun 10 '22 14:06 mvaligursky

This is fricken amazing! 🥹

Do you have any idea what might be causing the spikes on the ministats GPU plot?

Screenshot 2022-06-10 at 17 50 11

slimbuck avatar Jun 10 '22 16:06 slimbuck

Will take a look @slimbuck, but it could well be the video texture upload which is happening independently of the update loop. I'll remove it and see if it makes a difference

marklundin avatar Jun 10 '22 18:06 marklundin

I'm not seeing the same spikes on my machine @slimbuck but I've disabled the video texture upload regardless

marklundin avatar Jun 15 '22 08:06 marklundin

I think those spikes are caused by something (likely the GPU) taking longer than one frame, so on occasions a frame is skipped. Probably nothing to worry about at this stage.

mvaligursky avatar Jun 15 '22 08:06 mvaligursky

Just an update - in the engine 1.55 https://github.com/playcanvas/engine/releases/tag/v1.55.0 we've enabled the clustered lighting as the default lighting solution.

mvaligursky avatar Jul 20 '22 11:07 mvaligursky

That's great to hear @mvaligursky. I've not managed to integrate with the clustered lighting as yet as I've not had the time. It requires a bit of thought on the atlas texture fetches and sampling the mips without any bleeding

marklundin avatar Jul 20 '22 12:07 marklundin

Yep, that should be doable, and I can help. We have some similar parts we can use:

  • cookie atlas used by clustered lights - this also handles cube map faces, and adds them all into its slot. We just need different internal mapping and sampling code. This currently uses 3x3 sub-slots, and uses 6 of them for cubemap faces.
  • texture atlas used by the prefiltered envmap, which stores mipmaps

either of these we could probably use for initial non-optimal solution.

mvaligursky avatar Jul 20 '22 12:07 mvaligursky