Depth peel and transparency

I’m experimenting with depth peeling using three.js.

I’ve struggled a bit with achieving the correct blending. I have two examples:

The first one, uses 4 buffers and composes two layers in the fragment shader in its own pass. Here i was a bit confused about alpha multiplication, but i ended up getting the correct blending with the background. Ie. when i switch between the normal mode and depth peel mode, boxes blend the same with the background and opaque objects underneath.

https://raw.githack.com/pailhead/three.js/depth-peel-example/examples/webgl_materials_depthpeel.html

image

Left shows default transparency, to the right is my formula which i got off of wikipedia. I’m not sure what’s going on, but does looks slightly less correct on the left? It seems bright.

I got another version now where i’m trying to blend without the shader, switching up the dst/src and drawing each layer front to back in another offscreen buffer.

https://raw.githack.com/pailhead/three.js/depth-peel-stencil/examples/webgl_materials_depthpeel.html

This is the blending func for my full screen quad:

compositeMaterial.blendSrc = THREE.OneMinusDstAlphaFactor
compositeMaterial.blendDst = THREE.OneFactor

And i do this with premultipliedAlpha: false in all the transparent materials.

gl_FragColor.xyz *= gl_FragColor.a;

Again, blending with the background looks the same, but the transparent layers different.

Quastions:

  1. Is there some blending “standard” that i can compare to, ie. given this scene, expect most engines to output this image.
  2. Is three’s blending correct? I can’t tell which one seems more plausible.
  3. What could i be doing wrong if this is wrong?
  4. What am i even looking at, is the transparency accumulating differently, and the brighter one is just more solid? Could also be that im adding a bit of black with each peel.
5 Likes

not sure what the problem is - but it looks like you lose some alpha when combining, judging by the result. Also, though I’m not sure - but sorting seems off as well, based on some of the artifacts where no transparency should occur (i guess?).

looks awesome by the way :slight_smile:

I didn’t write the depth from the opaque objects initially but it should be fixed in the same link now, are you seeing something else at the moment?

I think that’s it, i’m somehow getting black from the peels, and it might even be only when i blit.

by the way, i feel your rendering phases are not synchronized, there seems to be a 1 frame ghosting going on.

I think i finally nailed some ungodly combination of premultiplied alpha, fragment multiplication and blending modes and achieved the same result as three.js. Yeey.

2 Likes

Good grief. I’ve spent a couple of days now going through this stencil logic. While everything made sense, i could not get it to work. I totally forgot that when flip flopping between the targets, i skip a layer of stencil logic, which messes all passes that follow.

I wasn’t able to figure out how to share the depth / stencil buffer between two targets even though it is possible. These buffers get created per target, inside the renderer, and cached inside as well.

I did something like this:

And was able to get the stencil buffer to work between two targets. With each of these peels, rendered into different targets, the same stencil buffer is written and tested against. The opaque white boxes should clip all the transparent layers now :smiley:

https://raw.githack.com/pailhead/three.js/depth-peel-stencil/examples/webgl_materials_depthpeel.html

Weird, i’m getting an error that im drawing and reading from the same texture, but i can’t tell where its coming from since it seems to be working correctly.

2 Likes

I get 60 fps on my iphone in half rez, but with depth artifacts :frowning:

It looks really good! I’ve been having headache with transparency for a while, to a point where I decided to abandon it completely to avoid the hacks necessary to make it look “OK” with standard three.js transparency. I think this is one of those things that most people can’t be bothered with as it’s too much work, but it almost everyone could benefit from.

3 Likes

Everyone who hacks their threejs so render targets can share stencil buffers :joy:

1 Like

If this gets accepted it would be possible to make an extension out of this.

Nice, the peel is definitely more plausible/realistic than the default transparency.

There’s still a case where the color turns solid instead of showing multiple colors from multiple objects that are behind.

F.e. in the following video, I’m looking from below, and moving the mouse to show the area where we see two colors when peel is disabled, then with peel enabled the color becomes implausibly solid instead of showing at least two colors from behind:

1 Like

Can you do a screen shot? Define what makes it inplausible I’m really curious

1 Like

A common transparency problem is liquid inside glass like in this model. Does depth peeling help with this case?

Great work on this so far btw👏

I’m not entirely sure about that one. I don’t see any flickering from sorting, which is what i sort of expected given the shape of the glass and the liquid. It’s pretty opaque though so hard to see. What is the problem with this model?

There’s more details in this thread:

In the video, when peel is enabled, the blue where my cursor is (and the green in the object above it too) becomes solid and brighter. It seems that the other colors should continue to bleed through there, instead of there being only solid blue (and green). Just keep replaying at 4 seconds to see where I enable it at 5 seconds, and it seems some objects are visibly lost from the background.

Regardless it’s really awesome!

Ahh I didn’t realize that was a different video. Have you tried increasing the layers from 1? 1 doesn’t really work, 2 should be ok-ish. Ie. you didn’t actually enable the effect :slight_smile:

1 Like

@looeee

Here’s that gltf, im not sure if i hooked everything up right but it doesn’t actually look that much different until you put something else in.

https://raw.githack.com/pailhead/three.js/depth-peel-stencil-gltf/examples/webgl_materials_depthpeel.html

I added the “most complicated transparency example” from mrdoob too, one inside the bottle one outside:

image

Seems like its working ok.

2 Likes

image

Meh there’s some weirdness when double and single sided are mixed.