Say I have a nice spaceship rendered in my scene. I then zoom out and the ship becomes smaller. This is all quite simple to achieve. Now at some point I want to replace the spaceship object with a simple triangle representing the ship. At this stage the icon for the ship should be rendered instead of the ship. Obviously the triangle should move based on the ship's movement and my camera movements. The triangle should not change orientation, so even if I rotate the camera or have the ship roll the triangle should stay the same orientation. So on a canvas this would be very simple to do. I would just take the x and y components of the 3d object and draw my triangle at the coordinates. My problem is that I do not know how to draw on the WebGL canvas directly? Is it possible? If not do anybody have any pointers to strategies to get this done? I would be happy if I could get nudged in the right direction :) Thanks in advance.
Update : What I eventually decided to do was to use the orthographic camera overlay approach suggested below and in a couple of other places.
Use Sprite object for icon. Then place icon right between spaceship and camera in a specific distance from the camera (using Raycaster or just calculation).
Use of orthographic overlay as mentioned by #WestLangley is also possible. Since you would have to calculate ship's position relative to your canvas in this case, maybe you could even create pure HTML overlay using DIV and place your icon in it as IMG object.
Related
I'm interested in if it would be possible to reproduce the Labeled Geometry three.js example on an animated asset, and if so, how?
I want to attach labels to an animated 3D model but they do not move along with the asset (even if I parent them to it) I'm guessing because the animation performs a mesh deformation itself.
Is there a performant way to have, say, the sprite's position reference that of a specific vertex in the animated mesh buffer? Something that would not require me to manually update the sprite's position whenever the mesh's animation progresses. Ideally I would like to parent the sprite to a particular face or vertex on the mesh, but as far as I know there is no way to do this.
Thanks in advance for any help!
Is it possible to turn off sizeAttenuation for an Object3D in THREE.js?
I ask because I'm drawing a trajectory on a very large scale using arrow helper to indicate the direction of motion, and I want the heads of the arrows to stay oriented correctly (unlike using a pointcloud w/ sprite points), but also not shrink/grow as you zoom the camera.
Any other ideas? Can I achieve the same effect using a pointcloud/lines?
sizeAttenuation is just rescaling the sprite based on it's position to give a sense of a "virtual size". Object3D's have an actual size so they scale with perspective.
Outside of switching to an Orthographic Camera (might not be ideal for everything else you're doing), the only things that come to mind are
position the arrow closer to the camera always, so it doesn't change size
constantly adjust the scale of the arrow to make it larger/smaller in the scene, so it appears to be the same size on the screen.
I have a scene with many Object3D objects containing blocks, cylinders and meshes. I also have a perspective camera and use trackballcontrols. What I need is a way to set the camera position without modifying the FOV or the camera angle and insure that all objects in the scene are visible on screen. I have successfully done this with preset top, bottom, left and right views using the bounding box of the entire scene, but I need this to work from any camera angle since the user can rotate the view using trackball controls into any position.
If there were a way to get a 2d bounding rectangle based on the camera position, target and the list of objects, I think I could get it to work, but I am having trouble finding how to do this.
The functionality would work like this: With a scene containing many objects, the user rotates the camera with the mouse to some arbitrary position and then clicks a "Zoom All" button. Then, the camera is zoomed(moved) out or in(keeping FOV constant) to make all objects fit to the screen.
How about rotate and translate the whole szene, so that the camera lies on an axis looking at the origin.
From there get the bounding box, calculate the needed distance for the camera and translate the camera.
Then rotate and translate the whole szene back.
I have given up trying to orbit a camera around my scene in Three.js and have now decided to revert to doing what I used to do in XNA, just rotate everything except the camera.
The reason I have given up is because I cannot get the camera to orbit properly 360 degrees in all the axis, it starts inverting after going over the top or under the bottom. Using THREE.OrbitControls does not solve this because it merely restricts rotation in the problematic axis instead of fixing the problem.
My problem is now getting this other rotation story working. What I have done is put all objects except the camera in another object "rotSection" and I am now just rotating that object. This is working but rotation is always performed according to the relative (0, 0, 0) position of the rotation object which seems to always stay in the one corner but I would like to rotate around the centre of my world on not around the edge. I have tried to centre the rotSection relative to the scene but it still rotates around its corner and not its centre. Any idea how I can get rotation of an Object3D around a certain point?
The engines don’t move the ship at all. The ship stays where it is and
the engines move the universe around it.
Futurama
The camera in 3d technically never rotates, everything else is rotated and move in order to bring it to camera's local space. You don't have to do any tricks in order to do this, this should be the core of the 3d engine, setting the matrices, setting up the shaders, and doing the correct transforms. Three.js does this for you.
Perhaps you should look into quaternions? Specifically the axisAngle conversion to quats. THREE.OrbitControls won't do what you want.
I was wondering if there's a way to project a shadow without have a "ground" plane where project it.
I'd like to do that because the camera can be moved around the object and would be ugly see it pass through the ground.
I'm using Three.js latest-version with the WebGl renderer.
Yes this is possible by applying ShadowMaterial to the plane geometry. This material can receive shadows and is completely transparent. so you just position the plane geometry at the desired location in the scene and you are good to go. check out this. https://threejs.org/docs/#api/en/materials/ShadowMaterial
This is technically impossible, you could write a shader that renders the shadow on a transparent plane, that way you would not notice it when the "camera" goes through the plane, only when it goes through the shadow itself.
To do so you can lerp between the shadowratio and a transparent black or white in the pixel shader and then set the corresponding blending states on the rendering context.