Improved transparent rendering by elalish · Pull Request #25819 · mrdoob/three.js (original) (raw)

This is a follow-on to #22425 and #22473 to make rendering transparent objects onto a transparent canvas work better so they can be composited onto DOM or AR content behind and look reasonably seamless. This is required as DOM-to-texture is not and will not be allowed due to security, and WebXR does not expose the camera feed by default, meaning those backgrounds are not available within our shaders. It also means what I'm doing is fundamentally a non-PBR hack, since blend functions can't represent light transport properly, and it's not possible to handle transmission roughness or refraction. However, we can improve significantly:

Before / Current (including #25881)
imageimage
(for historical reference) 1st draft / 2nd draft:
imageimage

Before / After:
imageimage
And it works with other CSS background colors since the canvas is transparent:
imageimageimageimage

It does require two extra steps to make it work in addition to this PR:
1) The renderer must have premultipliedAlpha: false
2) Must call renderer.setClearColor(new Color(0xFFFFFF), 0);

I haven't included these in the spirit of avoiding breaking changes and because this unblocks model-viewer. However, it might be worth looking at these defaults, as materials default premultipliedAlpha to false, while the renderer defaults to true. Also, if you set renderer.setClearColor(new Color(0xFFFFFF));, it will ignore the alpha of your context and clear to alpha = 1, which is a bit confusing. Currently the background clears to black by default, but white seems just as reasonable?