Does Three.js support additive blending for opaque?

Hello :disguised_face:
Perhaps blending is a bad word as it’s used in a transparent context, but what Im wondering is whether Three.js supports additively drawing opaque objects in a scene. The simplest example:

I have two square, opaque planes in a scene, one behind the other. Each one gives color vec4( 0.5, 0.0, 0.0, 1.0 ) (half red). Where they overlap on the screen, I want the color to be added, meaning vec4( 1.0, 0.0, 0.0, 1.0 ).
I need that kind of color accumulation for each mesh drawn in the scene.
I tried material blending modes, with no success. All the resources online only talk about transparency blending.

Does anyone know if it’s possible out of the box through some settings, or do I need to use the renderer webgl context api? (im using webgl2 btw)
Thank you for reading :smiley_cat:

as far as I understand, transparent = false material pixels are either replaced by or replace the other color, i.e. no blending is performed

That is the default behavior yes, but Im wondering if there is some trick around this with the frame buffer or whatever. Im currently looking into more low-level webgl api stuff.

Intuitively it doesnt seem like a very complicated feature - just pretty rare :sweat_smile:

I’m pretty sure this can be achieved with:

const material = new THREE.MeshBasicMaterial({
    color: 0x800000,
    blending: THREE.AdditiveBlending
});

If your background is fully black, when the two planes overlap, they’ll add up to 0xff0000.

2 Likes

Hi marquizzo, thanks for the answer. I played around in the editor and turns out this is true, but the materials also need either depthWrite or depthTest set to false:

I failed to detect this due to other issues inside my app, which were entirely my fault…

Thank you again for help! :pray: :blush:

1 Like

So to complete @marquizzo 's answer for others:

const material = new THREE.MeshBasicMaterial({
    color: 0x800000,
    blending: THREE.AdditiveBlending,
    depthWrite: false
});
2 Likes

Ugh, I keep giving half-right answers that are missing a small detail. Thanks for catching that!

4 Likes

I’m pretty sure it’s not because of depth writing. Blending basically controls compositing behavior - how source pixels get written on top of the render target.

If you get to that point of compositing and you try to render under something that’s already there, that is - depth test fails - no compositing will take place.

I think that’s what you’re observing, and the “right” solution would be to make sure that render order is controlled to produce effect you desire.

I have worked quite a bit with blending modes in webgl and three.js specifically and it’s a topic that takes a bit of time to wrap your head around.

1 Like