Aaaah, that was it. Works great with more layers!
This seems fantastic. Do we know if this is going to be part of core threejs as it seems to cure quite a common and anoying problem?
Cannot be done as long as threejs locks some specific internals. In this case the target renderbuffers. Editing one line in the core would allow for this to be an example or a plugin.
Is there a reason why they wouldnt want this as an example / plugin? Is there any downside(performance etc.) to your approach?
Well, the algorithm and the approach are a tradeoff. It has upsides and downsides compared to other transparency rendering approaches.
But, allowing users access to the targets render buffer is a different thing. Three.js has many places where this pattern happens:
function private_function(){
_private_object = public.foo || _private.foo
}
Which is awesome! For example customDepthMaterial
works like this. It’s not really documented, it’s not really explained how it works, but it works. Somewhere deep inside WebGLRenderer
you have:
Or
result = customMaterial || materialVariants[ variantIndex ];
So, if you don’t provide customMaterial
yourself by slapping it onto a mesh:
mesh.customDepthMaterial //undefined
mesh.customDepthMaterial = myDepthMaterial
It will just use something internal.
When we work with THREE.WebGLRenderTarget
three.js creates a render buffer for each target and does not give you any access to it.
My approach requires two different targets to use the same render buffer. Following the pattern present in so many places in three.js you could do.
myRenderTarget = new THREE.WebGLRenderTarget() // render buffer created and you cant access it
instead:
myRenderTarget.renderBuffer = myRenderBuffer
myOtherTarget.renderBuffer = myRenderBuffer
As a result, my example could work, but so could many others that we don’t know or that are yet to be written.
I have no idea why this is pattern is selectively applied in some areas but then not in others.
Perhaps you could add a comment here and we could both figure it out
The color jumps abruptly when crossing the critical angle where the blue and the red are equally close to the camera. That does not look natural.
What’s the critical angle?
Hm, I kind of assumed it was when the spheres are equally close, but I am not sure. Try
camera.position.set(-18.0, -2.5, 26.8)
-ish for the pair in the bottle, and camera.position.set(-0.35, -5.40, 31.96)
for the pair outside (both with lookAt
before enabling the controls). Update: It looks like disabling and enabling again after increasing the peel iteration thing solves the problem. I thought it would respond dynamically to changes on that slider.
Additionally, there is a problem with click handling, which makes using the GUI difficult. I guess it may be another instance of forgetting to supply a domElement
to the OrbitControls
.
Ah yes the ui is broken beyond belief. It’s not on by default in that scene, i think double sided is messing things up etc. Not being able to share render buffers turned me off from this whole project.