Scene with custom blend mode (difference/invert)

Hello,

I have a dom logo and some text inside a container under my Three WebGL canvas which contains a black and white image sprite on a black background. Scrolling down the page will zoom out of the sprite.

I was going to set mix-blend-mode: difference (to invert the text if the image overlaps it) on my canvas but I realized it’s not very performant while also zooming the Three camera. So I’ve been trying to figure out how to do the same thing in Three to get my whole scene to do difference blending (not included with the default Three blend modes) with the dom element rendered under it. Can anyone point me in the right direction, if I need to write a custom shader and how to implement that shader to blend my scene with the dom background).

This is what I want to do, the a.DEMO logo is an svg element under my Three canvas which renders the artwork. The parts of the artwork that overlap the logo are supposed to be inverted.

mockup

Any chances to share your progress as a live example?

You cannot influence this blending with shader code.

Here is my live example: jsfiddle, scroll to zoom out of the artwork.

This is the desired effect with mix-blend-mode: difference on CSS:41, performance drops noticeably in Firefox and Chrome with it on, so that’s why I want to move that effect to Three.

1 Like

You will have a better performance if you are going to use a pure WebGL approach. So you might want to render the shirt first and then use post-processing in order to blend the logo to the scene. You can use THREE.RenderPass to render the scene to a fullscreen-quad and then blend the logo texture with a custom THREE.ShaderPass.

You might want to study the post-processing examples of three.js to get a better understanding of the related workflow:

https://threejs.org/examples/?q=postprocessing

2 Likes

After some experimenting and researching looks like I got the basics set up, but one thing I still can’t figure out is how to grab the color of the background (dom behind canvas) into my shader so I can modify the texture color with it.

I have a RenderPass and ShaderPass with a custom shader set up, I don’t know how I should finish this shader though, here is my new jsfiddle

My custom shader is at lines 5-34, and the EffectComposer setup is at lines 66-80.

I’ve have actually suggested a pure WebGL solution. So no SVG and DOM elements. Your logo has to be a JPEG or PNG so you can use it as a texture (it’s going to be the tDiffuse2 uniform).

I see, unfortunately for this scenario I will be putting a lot of text and dom components on the page too so I would prefer to still use the dom, is there another solution/compromise you would suggest?

Not that I’m aware of. Maybe someone else of the community can enlighten us.

1 Like

BTW: This is definitely not possible.

Apologies if it’s against forum etiquette to resurrect an old post, but I am trying to achieve this exact same result and my searches keep leading me back to this thread. If it is better to start a new topic I can do so.

I’ve set up a stripped back example of my project here: https://jsfiddle.net/0ce93gh8/17/
Where I have a background mesh & a logo mesh.
I wonder could you provide any more guidance or advice on how to use the logo texture in a shaderPass and achieve a difference blend? I’m quite lost with the custom shaders.

Many thanks.

Here is my production code:

I wrote a difference shader (lines 12-41) that takes in an inputBuffer (my background) and an overlayBuffer (the logo and frame). Pass setup is on lines 54-146.

Here is the page:

Thanks for sharing @jep !
Really appreciate it. I’ll dig into this now and see what I can learn.