deck.gl icon indicating copy to clipboard operation
deck.gl copied to clipboard

fix(core): correct opacity in interleaved mode

Open felixpalmer opened this issue 6 months ago • 3 comments

Background

When using PostProcessEffect with interleaved: true, due to clearing of the canvas the result is the basemap is completely cleared with a solid grey color:

Screenshot 2025-05-22 at 09 40 00

With this change, the clearing is applied only when needed, and the blending in ScreenPass is fixed to give correct results. Here is a layer, drawn with opacity with a ink postprocess applied, in interleaved mode.

https://github.com/user-attachments/assets/18a06a92-3100-41f4-ab52-1d47eb2b3a7e

In order to test, the layer browser has been enhanced to include a toggle for interleaved rendering

Change List

  • Do not clear canvas in deck-renderer when clearCanvas is explicitly set to false
  • Correct blending in ScreenPass (only used in PostProcessEffect)
  • Tidy up RasterLayer
  • Enhance layer browser to support interleaved

felixpalmer avatar May 22 '25 07:05 felixpalmer

Some more background, as this is quite tricky to get right. There are two cases to consider:

  • Alpha added via Layer rendering (e.g. opacity prop set to 0.5)
  • Alpha added via postprocess (e.g. a zoom blur will add translucent pixels)

Here are some example renders:

Postprocessing with a shader that just writes out the input color

Current behavior (master)

https://github.com/user-attachments/assets/aa117469-f0d9-4942-a0b8-45d940601a38

The blending setup is incorrectly darkening the output, when it should not

New behavior (this PR)

https://github.com/user-attachments/assets/14e199e9-eaa6-4398-9adf-cfd4d585e68a

Color is now correct, only the opacity is modified

Postprocessing with zoom blur

Current behavior (master)

https://github.com/user-attachments/assets/b802383f-d71c-4e4d-a256-0a0c96b85629

Translucent pixels from postprocess are correct, but layer is darkened

New behavior (this PR)

https://github.com/user-attachments/assets/73c34a2b-eba9-4ea8-82ad-45518dad3a56

Layer no longer darkened, but the blending of the postprocess is wrong

New behavior including fix in luma

The issue is that two effects in luma.gl are using per-multiplied alpha in the shader, which is incorrect. The blending should be handled by the blend modes, not in the shader

https://github.com/user-attachments/assets/954f45f5-3813-4978-96a1-a9712c65333a

With the luma fix, we finally get the correct result 🥵 !

felixpalmer avatar Jun 04 '25 13:06 felixpalmer

The failing render test is due to the issue in luma. Running with the luma fix this result is fixed:

Screenshot 2025-06-03 at 15 19 52

Current (incorrect) golden image:

post-process-effects

felixpalmer avatar Jun 04 '25 13:06 felixpalmer

Thank you very much for this write up and examples! The new results look wayyyyyy better.

We never mentioned issues with PostProcessing in our limitations, but I'd believe if they've silently been problematic this whole time.

I'd been aware of an undocumented limitation we had about not being able to achieve basic blending effects like "additive" via deck prop parameters in v8 and below, but I consider that technique a hack since it interfered with the interleaved renderer. I'd prefer officially supporting an "additive" effect via PostProcessing.

Great work. I think it's worth mentioning formal support for interleaved PostProcessing effects in the 9.2 release.

chrisgervang avatar Jun 04 '25 16:06 chrisgervang

Coverage Status

coverage: 91.711% (+0.02%) from 91.695% when pulling 40de65a66bb81500a3c1cc5e33c5cf6bf7ac0fce on felix/mapbox-interleaved-opacity into b04748bd6c9bfaeaf1a0a8cd9f1f501ea4095960 on master.

coveralls avatar Jul 14 '25 14:07 coveralls