How to change the zOrder of object with Threejs? - three.js

I made a scene using the webgl renderer where I put multiple 3D objects that I can select and move. However when an object is selected, I'd like to draw its axes. No problem with drawing the lines to the center of the object but I'd like them to appear in front of anything else on the scene so that they are visible even if other objects are in front - Like in Blender.
I tried to play with the renderDepth param but I don't think I understood how to use it and I didn't get any result.
Thank you for your help.

If you want some objects to render "on top", or "in front", one trick is to create two scenes -- the first scene is your regular scene, and the second scene contains the objects that you want to have on top.
First, set
renderer.autoClear = false;
Then create two scenes
var scene = new THREE.Scene();
var scene2 = new THREE.Scene();
Add your objects to the first scene as usual, and add the objects you want to have "on top" to the second scene.
Then, in your render() function, do this:
renderer.clear();
renderer.render( scene, camera );
renderer.clearDepth();
renderer.render( scene2, camera );
This will render the first scene, clear the depth buffer, and then render the second scene on top.
three.js r.142

Related

THREE.js Move camera on orbit with mouse

I am trying to orbit a camera on an inclined orbit around a scene while the camera always points to the scene's origin. (Think of the camera rig installation for filming the bullet dodging scene in the first Matrix movie.)
The idea is to let the x-component of the mouse position on screen determine the position of the camera on the orbit. Hence, I created a dummy object whose position is changed in the mousemove-listener. The camera is attached to the dummy object, and the dummy object is attached to a pivot which creates the orbit inclination.
var pivot = new THREE.Object3D();
var cameraPos = new THREE.Object3D();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
cameraPos.add(camera);
pivot.rotation.y = Math.PI/4;
pivot.add(cameraPos)
I've put a minimal example together here: codepen.
The result is this erratic camera movement. Any idea WHY that happens?
I cannot figure out what I am doing wrong.
A solution
I will add that I know already how to fix it.
Step 1: Detach the camera from the dummy object cameraPos
Step 2: Set the camera position manually to the position cameraPos.
var target = new THREE.Vector3();
cameraPos.getWorldPosition(target)
camera.position.copy(target);
Outro
I really like the idea of attaching the camera to an object which follows then a prescribed path. But does attaching the camera to an object create unwanted interaction? What is the explanation for this behavior?

threejs render text on or next to object

How can I put a text next or in front of it or on its surface with three.js?
If I plot a object like a box, I'd like to give this object a visible name (so similar to tooltip, but always staying visible). Would be great if text size is adjusting to distance like object size.
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
I'm using three.js with react-force-graph to render a diagram. Objects within it are rendered with three.js
https://threejs.org/docs/#api/en/geometries/BoxGeometry.parameters
Two ways to draw text with three.js. First, create a div element, set its position (In your case, you need to write code to calculate the position relative to the canvas according to the position of camera and 3d object). Second, create a text texture.

Get mouse clicked point's 3D coordinate in three.js

I'm new in THREE.js.
I'm trying to get 3D coordinates of point on mouse click on the object (not simple objects: Box, Sphere,..) in Canvas.
In detail, I'm working with 3D objects viewer - I have camera (THREE.PerspectiveCamera), mouse controls (rotate, zoom, move), add/remove objects (my own object, loaded using loaders for THREE.js) in scene,.. And I want to add a function, which gets 3D coordinates for clicked point in 3D.
Exactly, I want coordinates of the end point of a ray - begining from mouse click on the camera_near_window and ending to the object's point, I've clicked on..
I tried a lot of ways to do it:
Getting coordinates of point on z=0 plane -- It works fine, but it is on z=0 plane and it is not that I need, cause I have OrbitControls..
THREE.js example - clickable objects -- It uses CanvasRenderer (not WebGLRenderer) and works for a little objects (but works for my project): browser crashes when I load many objects (CanvasRenderer needs 5x more memory then WebGLRenderer).
"How to get object in WebGL 3d space from a mouse click coordinate" - I tried this one too, but raycaster.intersectObjects found nothing, intersects was an empty array (maybe it works for only simple objects like box, sphere,..).
Can anyone show me the demo code which gets 3D point coords for clicked point of clicking object in 3D, please..?
So, as I think this question is useful for someone, I'll answer it myself (I'll write my resolve):
var renderer, canvas, canvasPosition, camera, scene, rayCaster, mousePosition;
function init() {
renderer = new THREE.WebGLRenderer({ antialias: false });
canvas = renderer.domElement;
canvasPosition = $(canvas).position();
camera = new THREE.PerspectiveCamera(20, $(canvas).width() / $(canvas).height(), 0.01, 1e10);
scene = new THREE.Scene();
rayCaster = new THREE.Raycaster();
mousePosition = new THREE.Vector2();
scene.add(camera);
var myObjects = new THREE.Object3D();
// myObjects.add( your object );
// myObjects.add( your object );
// myObjects.add( your object );
myObjects.name = 'MyObj_s';
scene.add(myObjects);
};
function getClicked3DPoint(evt) {
evt.preventDefault();
mousePosition.x = ((evt.clientX - canvasPosition.left) / canvas.width) * 2 - 1;
mousePosition.y = -((evt.clientY - canvasPosition.top) / canvas.height) * 2 + 1;
rayCaster.setFromCamera(mousePosition, camera);
var intersects = rayCaster.intersectObjects(scene.getObjectByName('MyObj_s').children, true);
if (intersects.length > 0)
return intersects[0].point;
};

How to find the scene position of an object, within a rotating parent object

Within my THREE scene i have an Object that rotates. The child object is positioned at (92,92,92) within the rotating Object, so it orbits the centre position (0,0,0) is a spherical path with my mouse movement. How can i find the global position of the child object in respect to the scene as it rotates. I'm fairly new to THREE.js and thankful for any support in advance.
My code:
ObjectParent = new THREE.Object3D();
scene.add( ObjectParent );
ObjectChild = new THREE.Object3D();
ObjectParent.add( ObjectChild );
ObjectChild.position.set(92,92,92);
Render:
ObjectParent.rotation.y -= (target.y + ObjectParent.rotation.y) * 0.08;
ObjectParent.rotation.x += (target.x - ObjectParent.rotation.x) * 0.07;
ObjectParent.updateMatrixWorld();
scene.updateMatrixWorld();
First of all, you usually do not need to call
ObjectParent.updateMatrixWorld();
scene.updateMatrixWorld();
inside your render loop. The renderer will do that for you.
To find the world position of a child object, you can use this pattern:
var vector = new THREE.Vector3();
...
vector.setFromMatrixPosition( child.matrixWorld );
The renderer should have previously updated the scene matrices for you. If you have changed a parent's position since the last rendering, you will have to first call
parent.updateMatrixWorld();
to update the relevant matrices.
It is a good idea to look at the three.js source code so you understand what these functions do.
three.js r.67

Reusing EffectsComposer result

I have an effectsComposer creating a result that is heavy in white.
var composer = new THREE.EffectComposer(renderer);
var renderPass = new THREE.RenderPass(shaderHeavyScene, camera);
composer.render(delta)
In the same project I have a material and scene with with a second image loaded into it.
When I replace: composer.render(delta);
with: renderer.render( secondImageScene, camera );
I can see my secondary image loaded into the three.js canvas.
My plan was to multiply the white heavy image of effectsComposer over the secondImageScene. (Revealing secondImageScene through the white)
My question is this: How would I go about multiplying the end result of the effectsComposer overtop of secondImageScene?
Use another pass that has input of two textures that were rendered in the previous passes, that multiplies them.

Resources