I tried to do this because it’s needed for this mockup.
Here’s the link to the mockup - https://www.figma.com/design/qEiDTsGobLyugZeyD3ONdi/INSECA--APP-WEB?node-id=1806-4059&t=bMMpGIYJlHkIaRTr-0
Do you see the lens effect in the mockup? I wanted to replicate it. According to this mockup, HTML behind the lens must remain visible. That’s why there’s a blue circle behind the text, which should move unpredictably when scrolling. If it gets covered by the scene, it will look wrong.
Yes, it is possible. A Three.js canvas is just another HTML element, so you can control how it stacks with other elements using normal CSS.
If you want to see HTML behind the Three.js canvas, the canvas must be transparent and layered above the HTML content. In Three.js you can enable transparency like this when creating the renderer:
const renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setClearColor(0x000000, 0);
This allows the HTML to be visible behind the WebGL scene. Another common pattern is putting the canvas inside a container and using overflow and positioning to keep everything aligned during scroll.
If things move chaotically while scrolling, it is usually related to viewport units (like 100vh), mobile browser UI resizing, or the canvas being tied to scroll transforms. Using a fixed container or recalculating renderer size on resize/scroll can help stabilize it.
Here’s a small interactive example of a scene with a controller running in the browser if you want to see how layering and interaction can work in a Three.js environment:
Thank you. Very interesting example. I replaced your model with my lens. And as I understand it, to get a real refraction effect, you need to use WebGLRenderTarget. But if you use it, there will be no transparency, so the HTML not will be visible behind. SThere are two ways: either follow your approach and add artificial aberrations and magnification, or change the web app’s design layout. Because again, in the layout, the blue area rotates when scrolling. And it’s located on a layer behind the text. And if this rotating area is obscured by the scene, result will look incorrect.
Refraction needs knowledge about the back of the scene. If the HTML is just DOM-based, Three.js will not see it. Maybe you have to find a way how to grab an image of the HTML page and let Three.js use it as background.
Maybe this demo from the official R3F examples could be helpful: