Hide Mesh Faces at RunTime in Three.js - three.js

I am using the version THREE.js57. I want to hide selected face at run time. Is this possible in three.js
Thanks & Regards

Indeed this is possible, you'll want to look into the Raycaster library, here's the high level steps
unproject your mouse click coordinates into the 3D scene.
cast rays into your scene and return an intersected array of collided objects
this intersected object will have the affected face and faceIndex as parameters
on collision turn the face # faceIndex transparency to 0
Have a look at these doc pages:
http://threejs.org/docs/#Reference/Core/Projector
http://threejs.org/docs/#Reference/Core/Raycaster
And this example for a start:
https://github.com/mrdoob/three.js/blob/master/examples/canvas_interactive_cubes.html
Edit:
Alright, well to then hide the face you can have a peak at this other SO post:
Can I hide faces of a mesh in three.js?
The gist is you have a multimaterial object, the first material is your default, and a second material that's fully opaque. Then when you intersect you set the face to use the second materialIndex. Anyway, the above link should do the job. Off to up vote that response. :)

Related

User painting on a canvas within A-Frame

I have an A-Frame scene that contains, among others, a <canvas> element that is the material source for a 3D scene object. I can paint on the canvas programmatically, and it shows up as texture. So far, so good.
However, I'd now also like to enable the user to paint something on the canvas using the controllers. I have added two raycasters/controls:
<a-entity laser-controls="hand: left" raycaster="objects: table2"></a-entity>
<a-entity laser-controls="hand: right" raycaster="objects: table2"></a-entity>
And on the table2 object, I have added a raycaster-listen mixin as described in https://aframe.io/docs/1.3.0/components/raycaster.html#listening-for-raycaster-intersection-data-change.
This works in so far as I get the console log entries with the world coordinates of the intersection point, but I'm absolutely stuck at how to get from the world coordinates back to the canvas coordinates I need to actually paint in the right spot.
In addition, it seems no canvas draw commands I issue in the raycaster-listen tick callback actually have any visible effect (regardless of coordinates).
Any hints appreciated!
As usual, I figured it out the next day 😉
[...] I'm absolutely stuck at how to get from the world coordinates back to the canvas coordinates I need to actually paint in the right spot.
Solution found at https://discourse.threejs.org/t/convert-camera-frustrum-to-uv-coordinate-on-texture/16791/2 - just use intersection.uv which actually contains the normalized texture coordinates of the intersection point. Scale by canvas width/height and you're done.
[...] it seems no canvas draw commands I issue in the raycaster-listen tick callback actually have any visible effect.
Solution found at aframe not rendering lottie json texture mapped to canvas but works in three.js - set texture.needsUpdate = true; in the tick callback after drawing on the canvas.

How can I give objects whole side with light?

I'm looking for an way to give specify light for some objects.
I have added new light to object to remove shadow on it, but then, the other objects also affected by additional light, and I don't want it.
I have let the object's castShadow = false; receiveShadow = false, but it doesn't work.
When the camera is positioned with the light directions, camera will see the 'light' meshes, and at the opposite position, camera will see the dark side.
I want both sides to see 'light' meshes.
(I want to remove the shadow.)
Thanks for your help. :)
I have added new light to object to remove shadow on it, but then, the other objects also affected by additional light, and I don't want it.
What you are looking for is called "selective lighting" which is not yet supported by three.js. Check out the following issue for more information:
https://github.com/mrdoob/three.js/issues/5180
The only workaround right now is to work with multiple scenes and render passes.
When the camera is positioned with the light directions, camera will see the 'light' meshes, and at the opposite position, camera will see the dark side.
When using a single directional, point or spot light, it's normal that this setup produces a lit and unlit side of a sphere mesh. You can only avoid this by adding an additional light on the other side of the mesh, by using unlit materials or again by using different scenes with different lighting setups.
three.js R112

Can't get Three.js camera up direction

I need to get the camera up direction and i've tried many ways with no luck, i'm not an expert of quaternions so i'm doubting i did it right.
I've tried:
camera.up
camera.up.applyMatrix4(camera.matrixWorld);
new THREE.Vertex3(0,1,0).applyMatrix4(camera.matrixWorld);
camera.up.normalize().applyMatrix4(camera.matrixWorld);
after this i create two planes passing by two points of my interest, and add the plane helper to the scene and i can see they are very far from where i was expecting them. (i'm expecting two planes that looks like the top and bottom of the camera frustum).
P.s. the camera is a shadow camera of a directional light so an orthographic camera, and i manipulate the directional light position and target before doing this operation, but i've called updateMatrixWorld on the light, on it's target and the camera, on the camera i've called also updateProjectionMatrix... still no results
I've made a sandbox to see what i've tried till now, and better visualize what i want to achieve:
https://codesandbox.io/embed/throbbing-cache-j5yse
once i manage to get the green arrow to point to the top of the blue triangle of the camera helper i'm good to go
In the normal render flow, shadow camera matrices are updated as part of rendering the shadow map (WebGLShadowMap.render).
However, if you want the updated matrix values before the render, then you'll need to update them manually (you already understand this part).
The shadow camera is a property of (not a child of) the DirectionalLight. As such, it doesn't follow the same rules as other scene objects when it comes to updating its matrices (because it's not really a child of the scene). Instead, you need to call the shadow property's updateMatrices method (inherited from LightShadow.updateMatrices).
const dl = new THREE.DirectionalLight(0xffffff, 1)
dl.shadow.updateMatrices(dl) // <<------------------------ Updates the shadow camera
This updates the shadow camera with information from the DirectionalLight's own matrix, and its target's matrix, to properly orient the shadow camera.
Finally, it looks like you're trying to get the "world up" of the camera. Personally, I'd use the convenience function localToWorld:
let up = new THREE.Vector3(0, 1, 0)
dl.shadow.camera.localToWorld(up) // destructively converts "up" from local-to-camera into world coordinates
via trial and errors i've figured out that what gave me the correct result was:
calling
directionalLight.shadow.updateMatrices(...)
and then
new THREE.Vector3(0,1,0).applyQuaternion(directionalLight.shadow.camera.quaternion)

Three.js Merge objects and textures

My question is related to this article:
http://blog.wolfire.com/2009/06/how-to-project-decals/
If my understanding is correct, a mesh made from the intersection of the original mesh and a cube is added to the scene to make a decal appear.
I need to save the final texture. So I was wondering if there is a way to 'merge' the texture of the original mesh and the added decal mesh?
You'd need to do some tricky stuff to convert from the model geometry space into UV coordinate space so you could draw the new pixels into the texture map. If you want to be able to use more than one material that way, you'd also probably need to implement some kind of "material map" similar to how some deferred rendering systems work. Otherwise you're limited to at most, one material per face, which wouldn't work for detailed decals with alpha.
I guess you could copy the UV coordinates from the original mesh into the decal mesh, and the use that information to reproject the decal texture into the original texture

Working with Three.js

Context: trying to take THREE.js and use it to display conic sections.
Method: creating a mesh of vertices and then connect face4's to all of them. Used two faces to produce a front and back side so that when the conic section rotates it won't matter from which angle the camera views it.
Problems encountered: 1. Trying to find a good way to create a intuitive mouse rotation scheme. If you think in spherical coordinates, then it feels like just making up/down change phi and left/right change phi would work. But that requires that you can move the camera. As far as I can tell, there is no way to change actively change the rotation of anything besides the objects. Does anyone know how to change the rotation of the camera or scene? 2. Is there a way to graph functions that is better than creating a mesh? If the mesh has many points then it is too slow, and if the mesh has few points then you cannot easily make out the shape of the conic sections.
Any sort of help would be most excellent.
I'm still starting to learn Three.js, so I'm not sure about the second part of your question.
For the first part, to change the camera, there is a very good way, which could also include zooming and moving the scene: the trackball camera.
For the exact code and how to use it, you can view:
https://github.com/mrdoob/three.js/blob/master/examples/webgl_trackballcamera_earth.html
At the botton of this page (http://mrdoob.com/122/Threejs) you can see the example in action (the globe in the third row from the bottom).
There is an orbit control script for the three.js camera.
I'm not sure if I understand the rotation bit. You do want to rotate an object, but you are correct, the rotation is relative.
When you rotate or move your camera, a matrix is calculated for that position/rotation, and it does indeed rotate the scene while keeping the camera static.
This is irrelevant though, because you work in model/world space, and you position your camera in it, the engine takes care of the rotations under the hood.
What you probably want is to set up an object, hook up your rotation with spherical coordinates, and link your camera as a child to this object. The translation along the cameras Z axis relative to the object should mimic your dolly (zoom is FOV change).
You can rotate the camera by changing its position. See the code I pasted here: https://gamedev.stackexchange.com/questions/79219/three-js-camera-turning-leftside-right
As others are saying OrbitControls.js is an intuitive way for users to manage the camera.
I tackled many of the same issues when building formulatoy.net. I used Morphing Geometries since I found mapping 3d math functions to a UV surface to require v little code and it allowed an easy way to implement different coordinate systems (Cartesian, spherical, cylindrical).
You could use particles instead of a mesh I suppose but a mesh seems best. The lattice material is not too useful if you're trying to understand a surface mathematically. At this point I'm thinking of drawing my own X,Y lines on the surface (or phi, theta lines etc) to better demonstrate cross-sections.
Hope that helps.
You can use trackball controls by which you can zoom in and out of an object,rotate the object,pan it.In trackball controls you are moving the camera around the object.Object still rotates with respect to the screen or renderer centre (0,0,0).

Resources