Reflections and Refractions in three JS

I have been attempting to further advance my webgl skills by attempting to replicate various webgl projects I have seen online like this one (KUBOTA FUTURE CUBE | Kubota Global Site), it seemed simple at first, a cube with a textured sphere inside of it but the devil is in the detail.
I have been able to replicate everything except for the reflection effect seen inside the glass cube.
If you look closely, you will notice that internal faces of the cube are reflecting the globe and that the cube itself has a PBR material attached creating this nice refraction effect when the cube is rotated.
I have been unable to copy this effect and I was wondering if someone could help me by just pointing in me in the right direction.
I understand how to make a mesh reflect objects (using the reflector class) within the scene but I dont know how to make this plane also have a glass like effect with proper refraction when looked at from different angles.

This would be a good walkthrough for the effect, using THREE.MeshPhysicalMaterial

The demo “Kubota Future Cube” is likely doing something more customized here, rather than a stock material.

This would be a good walkthrough for the effect, using THREE.MeshPhysicalMaterial

I am already closely familiar with PBR materials, I have no issue recreating a glass cube, just achieving the proper reflections and retractions.

The demo “Kubota Future Cube” is likely doing something more customized here, rather than a stock material.

Sounds about right, what I am curious about is how they went about achieving that.
I just wish someone more familiar with computer graphics could just point me in the right direction, as I do not have the time to jump into all the rabbit holes necessary to achieve this.

You can get very nearly the same effect (including refraction!) using only PBR materials like THREE.MeshPhysicalMaterial. I think you’ll find what you need in this tutorial.

1 Like

you can use meshtransmissionmaterial instead, it “sees” backfaces, but also has anisotropic blur and chroma. it looks imo a lot better than mpm.

some examples

it is also available for vanilla three GitHub - pmndrs/drei-vanilla: 🍦 drei-inspired helpers for threejs

ps, there’s also another one in drei just for realistic refraction alone, meshrefractionmaterial, but you would normally only use this for glass and diamonds, though in this case it could maybe work as well

1 Like

I already tried the mesh physical material before asking this questions and I got the nice refraction effect but no internal reflection.

My main issue is getting the backfaces of the cube to reflect the globe whilst also getting the refraction effect, I havent tested Drei’s mesh transmission material yet, I will give it a try see if I can get it to work.

imo thats just negative thickness, the kubota thing is probably not physically accurate but if that’s what you’re going for … HTML Markers (forked) - CodeSandbox

i don’t think this will be possible with meshphyiscalmaterial because it can’t look through itself.

Indeed it is, that’s what makes it so hard to replicate.

Yep, tried it with MSM didnt work.
My idea was to create a bunch of reflective mirror planes inside the cube itself using the three JS reflector class.
It didnt work at all.

Since r151, the transmission feature of MeshPhysicalMaterial supports this as well.

1 Like

you would have to control the thickness for backfaces separately to get the kubota cube. the sandbox that i posted yesterday HTML Markers (forked) - CodeSandbox can you try with mpm if it does that? i wasn’t able to configure it, and even if it makes the backfaces reflect the inner contents it then wouldn’t refract on the front faces.
mtm looks in my opinion better in the end due to chroma and anisotropic blur, i think anything that refracts is probably better off with that, and it can have backface thickness. vanilla version is here GitHub - pmndrs/drei-vanilla: 🍦 drei-inspired helpers for threejs

I have tried to do the same on vanilla three.js, but for some reason, backsideThickness is not working

backside requires an additional renderpass. this can’t be properly packed into a class, you need to look into the useFrame of the react component where it’s doing that and copy that code as well. it’s the material and the webglrendertarget stuff.