Rendering Sprites in Three.js over 3D Object and also behind without clipping - three.js

I need a way to render a sprite always over top of a 3DObject, but it also must disappear behind it when the camera is rotated.
I first tried disabling the depth-buffer write but this will always render the Sprite in front.
Is there a way to hide it when its behind, but prevent clipping with the Object?
Edit 1:
The Problem is not exactly about z-fighting because the depthbuffer values of the sprite and the object are not equal.
The Sprite is a Billboard, so it will always face the camera, but it clips with the object, when rotating the camera.
Thank you for your help

Related

Reference existing WebGL depth buffer when rendering a new ThreeJS scene

I have an existing WebGL canvas that is being rendered without using ThreeJS, and is for all intents and purposes a black box to me, apart from two facts: (1) I have access to the underlying webgl canvas DOM element and can position and resize it on the screen, and (2) I know the properties of the camera for the scene, and get updates on every render cycle for that camera.
The problem I need to solve can be simplified to the following: I need to have my own separate ThreeJS canvas that displays both the black box canvas data, and then elements that I draw, like a cube for a simple example. I can already easily overlay the two canvases, set the transparency on my canvas for everything but the cube, and then align the two with the camera events from the black box library. This works quite well.
The issue with this is that when I draw my objects, like a cube, they don't respect the depth buffer of the black box canvas. So I might have a cube that is properly aligned with the backing scene and movements of the scene, but then it isn't properly masked when something in the black box canvas is closer to the camera than the cube. My thought is that I need to solve this in one of two ways: (1) I can have my renderer write to the other canvas with autoClear = false and preserveDrawingBuffer = true, or (2) I can somehow copy the depth buffer from the black box canvas into my canvas, and then set up my renderer so that it respects the new depth buffer.
I haven't been successful with either approach yet, so I'm wondering if this is possible, and if so which of the above approaches, or what other approach, can solve this problem?
--Edit--
See https://jsfiddle.net/zdxyoajb/ for angular/typescript implementation of the above attempts. In the following animate loop, if I comment out the overlayRenderer lines, the below sphere will be red and offset from the center (as it should be), but if I don't comment the lines, I get the below image. I also get the following error:
WebGL: INVALID_OPERATION: uniformMatrix4fv: location is not from current program
animate() {
requestAnimationFrame(() => this.animate());
this.blackBoxCamera.copy(this.overlayCamera);
this.blackBoxRenderer.render(this.blackBoxScene, this.blackBoxCamera);
this.overlayRenderer.state.reset();
this.overlayRenderer.render(this.overlayScene, this.overlayCamera);
}

Creating a magnifying-glass effect in three.js WebGL

I'm working with an orthographic view in three.js/WebGL renderer, and I want a magnifying glass that tracks with the user mouse. I'm looking for the best way of doing this that's efficient.
When working with html5 canvas raw commands, this was easy: I simply defined a circular clip region, zoomed my coordinates, and re-drew the whole scene. With 3d objects, it's less obvious how do to it.
The method I've found so far is to do the following:
Define a second camera that looks into the zoomed region. Set the orthographic clip coordinates to be small so that it doesn't need to do much work
Create a THREE.WebGLRenderTarget
Tell the renderer and all my line textures that the resolution is about to change
Render the scene into the RenderTarget
Add a CircleGeometry as a MeshObject at the spot at the mouse position (in world coordinate but above the rest of the scene, close to the camera). Call this the lens.
Give the lens the WebGLRenderTarget as a texture.
Go back to my default camera, reset all my resolution parameters, and redraw the scene with the 'lens' object added.
This works (see image below) but I'm worried about parts of it:
I have to render twice per frame
Lines don't draw well, because the resolution problems. I have to keep track of all materials that need to know screen resolution and update all of them twice per screen render.
Related problems:
I want to overlay some plot axes on top of this, and possibly gridlines. These would change as the view pans. I'm not sure if I should make these 3d objects, or do it in a 2d canvas context I lay overtop.
I want to overlay some plot lines, and have them show up sensibly in the zoomed view. "Sensible" here is hard to figure out: I don't want them too fat in the zoomed view, but I also don't want to scale them up as much as the image detail (which is being rendered as a texture onto Plane objects behind).
This is a long post, but I'm still new to three.js and looking for good ideas.

Unity3D: Sprite renderer vs image renderer issues on canvas

I'm using sprites for an animated menu in my game.
I tried two methods:
Image Renderer: Replacing the image per frame with the sprite slice in the animation window
Sprite Renderer: Same method
I'm playing the sprite animation with no loop then rotating the transform on the z-axis.
The problem is that with the image the Screen Space overlay works well but the rotation of the transform causes the sprite to look glitchy and rough. With the sprite renderer however the Screen Space must be put to Camera and the sprites get placed between other assets in the world.
Example: http://postimg.org/image/436q9jvax/
Is there a way to either fix the roughness on the rotation using image or force the Camera Screen Space on top? My only concern with the 2nd option would be in relation to responsiveness for multiple devices.
The easiest fix was to apply "sorting layers" to the canvas with the sprite renderers on to keep it on top.
I did however incorporate #beuzel's idea about separate cameras in the end and opted for 2D sprites with physics instead of a 3D rendered animation on canvas.
http://postimg.org/image/6qmtiirb9/
Thanks for making the good sample. A fix for the menu intersecting the world is using a seperate camera for the GUI layer. The rough animation might be a pixel perfect setting in the sprite rendering (just guessing).
I don't have enough reputation points to write this as a comment.

How to create an orthographic/isometric directional light with three.js

I'm trying to create a shadow in my orthographic scene in three.js. I'd like to have a directional light so the shadow is offset from all objects equally in the scene. I am however having problems using DirectionalLight.
My first problem is that I can't get the shado to cover the entire scene, only part of it ever has a shadow. I played with the light's frustum settings, but can't figure out how to get it to cover the scene. Ideally I'd want the frustrum to match that of the camera.
The second problem is that the shadows aren't "clean". If I use a SpotLight the shadows have nice crisp borders (but obviously not the universal directionality I want). When I use a DirectionalLight the borders are misshappen and blurry.
In the samples the tile is a simply box created with CubeGeometry.
How can I create an ortographic directional light source for my scene?

Three.js - transparent objects when rotated with TrackballControls don't behave like transparent

When I add to the scene two objects and set their transparency as true with some opacity and using TrackballControls I rotate the scene by mouse, the object which was initially further from camera loses its transparency.
I read that this is Z-buffer problem and further objects from camera will be displayed first. But when I rotate the scene using TrackballControls, camera changes its position, so transparent objects should be displayed correctly. But it is not like that.
Here in this picture - on the right is frontview, on the left is backview which is not displayed correctly:
http://www.foto-ondruskova.cz/Experiment/lenses.jpg
Please, any solutions?
I have come across this problem and setting alphaTest: 0.5 to the material as suggested here solved my problem. But it is hit and miss. Give it a try. Hopefully it works!

Resources