I have to rotate the camera during initial loading of object in three js.
So can anyone help me in which way i have to do that.Can i use Perspective Camera for this ?
for reference
https://theyearofgreta.com/
It is possible to tween the camera movement on the initial load of the object.
new TWEEN.Tween(currentPosition)
.to(targetPosition, 2000)
.onUpdate(function () {
camera.position.set(...currentPosition);
camera.lookAt(new THREE.Vector3(0, 0, 0));
});
I made a simple example to showcase the movement:
https://codepen.io/cdeep/pen/ZEygVNy
Basics of using tween for three.js animations:
http://learningthreejs.com/blog/2011/08/17/tweenjs-for-smooth-animation/
Related
I have a camera drone animation model that I attach two objects to. The camera drone is just a black sphere with a texture. I attach a red sphere to the camera drone where the lens appears on its textureis, to make it look like a security camera lens. Works great. When I move the model, the red sphere moves with the camera drone perfectly as it moves and rotates.
However, I also attach a spotlight at the exact same place on the camera drone object. My desire is to have the spotlight beam come out of the camera drone lens so that it appears to emanate from the lens. However, when the camera drone moves, the spotlight stays in place and gets left behind, despite the fact I attach the spotlight the exact same way and in the exact same place as I attach the red sphere. In other words, when the camera drone moves away, I see the spotlight hanging in space where it was first created instead of it traveling in lock step with the camera drone.
Below is the code I use to create and attach the red sphere and spotlight. The code executes when the GLB loader callback executes.
Note: self.CAC.modelInstance is where the ThreeJS object for the camera drone animation model is stored. Also, AnimatedLight is the object I created to build a spotlight and animate it. Finally, initModelArgs is an object that contains some size, position, and other settings that are loaded from a file earlier.
Can someone tell me what I am doing wrong and how to fix this problem? Also, can you tell me what it is about the way that I think how the spotlight should work that is also wrong?
// PARAMETERS: url, onLoad, onProgress, onError
self.CAC.modelLoader.load(
// url
urlToModel,
// onLoad
(glb) => {
// Size.
glb.scene.scale.x = initModelArgs.theScale;
glb.scene.scale.y = initModelArgs.theScale;
glb.scene.scale.z = initModelArgs.theScale;
self.CAC.setModelInstance(glb.scene);
// Set the initial position.
self.CAC.modelInstance.position.x = initModelArgs.initialPos_X;
self.CAC.modelInstance.position.y = initModelArgs.initialPos_Y;
self.CAC.modelInstance.position.z = initModelArgs.initialPos_Z;
// Create an animation mixer for this model.
self.CAC.modelAnimationMixer = new THREE.AnimationMixer(self.CAC.modelInstance);
// Speed
self.CAC.modelAnimationMixer.timeScale = initModelArgs.theTimeScale;
// Add the model to the scene.
g_ThreeJsScene.add(self.CAC.modelInstance);
// Initialize the model completely. The camera drone has no
// animations because we animate it manually, so we pass
// NULL to let the initializeModelCompletely() function
// know that.
self.CAC.initializeModelCompletely(null);
// NOTE: Camera drone has no animations/actions. We animate it
// manually.
// -------------------- BEGIN: SUB-OBJECTS ------------
// Call updateCenterOfModel so our bounding box and center properties
// are correct.
self.CAC.updateCenterOfModel();
// Create the sub-objects necessary for emulating a light
// projector on the camera drone.
// .................... BEGIN: SUB-OBJECT - Camera Lens ............
const radius = 3;
const cameraLensObj =
new THREE.Mesh(
new THREE.SphereBufferGeometry( radius, 20, 20 ),
new THREE.MeshPhongMaterial( { color: 0xFF0000 } ));
cameraLensObj.position.set(0, 0, 15);
// Add it to the top level animation model.
self.CAC.modelInstance.add(cameraLensObj);
// .................... END : SUB-OBJECT - Camera Lens ............
// .................... BEGIN: SUB-OBJECT - Light Beam ............
const spotLightAsLightBeam_anim_obj =
new AnimatedLight(
`${self.CAC.modelName}-lens-light-beam`,
modelDeclJsonObj,
'SpotLight',
// Tell the animated light to augment our mini-menu
// instead of creating its own.
self);
// Call initialize model on the spotlight or we will not have
// the model instance filled in.
spotLightAsLightBeam_anim_obj.initializeModel(self.CAC.parentAnimManagerObj, initModelArgs);
const spotLightModelInstanceObj = spotLightAsLightBeam_anim_obj.CAC.modelInstance;
// Position the spotlight that acts as the camera drone's light
// beam right on top of the small sphere we use to emulate
// a projector's lens.
spotLightModelInstanceObj.position.set(0, 0, 15);
// Add it to the top level animation model.
self.CAC.modelInstance.add(spotLightAsLightBeam_anim_obj.CAC.modelInstance);
// .................... END : SUB-OBJECT - Light Beam ............
Is it possible to give a 2D primitive like Ring thickness/depth? I'm trying to make a 3D door with primitives and I want to make either a ring that has some depth or a cylinder with a thicker mesh. Even if it's at the three.js layer I would like to learn how to do this so I don't have to rely on imported 3D objects for the whole design.
To extrude a shape, you will need to use THREE.js. Below is an example for how to do this.
https://threejs.org/examples/?q=extrude#webgl_geometry_extrude_shapes2
How to use THREE.js geometery inside AFrame?
You make a custom component that creates a new THREE.Geometry, and inside that component, you build your shape and extrude it (see the THREE.js example, click (<>) button in lower right to see the code).
Below is an example that makes a custom quad in a component.
You can see the glitch here.
https://glitch.com/edit/#!/custom-quad
Look in the quad.js for details.
You should be able to copy code from the three.js extrude demo, and place it into your custom component init function to build the extruded shape.
Then you can create parameters, like 'thickness', and put them in the schema, and then they can be accessed from the component name on the entity.
If you don't yet know how to write a custom component, you will need to practice this to understand how it works.
https://aframe.io/docs/0.9.0/introduction/writing-a-component.html
Here is a snippet from my glitch that makes a custom quad. It shows how to make THREE.Geometry in an AFrame custom component.
init: function (data) {
var geometry = new THREE.Geometry();
geometry.vertices = data.vertices.map(function (vertex) {
var points = vertex.split(' ').map(function(x){return parseFloat(x);});
return new THREE.Vector3(points[0], points[1], points[2], points[3]);
});
// Build the UVs on the faces.
geometry.faceVertexUvs[0].push(
[ new THREE.Vector2(1,0), new THREE.Vector2(0,1), new THREE.Vector2(1,1)
],
[ new THREE.Vector2(1,0), new THREE.Vector2(0,0), new THREE.Vector2(0,1)
]);
geometry.computeBoundingBox();
geometry.faces.push(new THREE.Face3(0, 2, 1), new THREE.Face3(0, 3, 2));
geometry.mergeVertices();
geometry.computeFaceNormals();
geometry.computeVertexNormals();
this.geometry = geometry;
//console.log(data);
}
I'm trying to add a lightmap to some mesh after loading them from a GLTF file.
All my objects have 2UV channel.
I'm waiting 'object3dset' and here is my code :
const mesh = this.el.getObject3D('mesh');
var textureLoader = new THREE.TextureLoader();
textureLoader.load("lightmap.png", function(lmap){
mesh.traverse((node) => {
if (!node.isMesh) return;
node.material.lightMap = lmap;
lmap.flipY = node.material.map.flipY; //needed to flip the texture
node.material.needsUpdate = true;
});
});
If I replace the material with a new one and set the lightmap, it's working.
But I want to find a way without recreating all materials.
The lightmap was loaded, but not easy to see.
By default metalness from Khronos Blender Exporter converted in threejs after loading GLTF result to a level 1.0. With this configuration, the lightmap is hard to see and is not corresponding to what we see in Blender.
I hope my mistake can help someone else losing too much time.
I'm in the process of developing a chrome VR web app. Now I'm desperately trying to figure out how to render a website into my into my stereoscopic scene which has some meshes in it.
So I have my renderer for the meshes, which works well. The following code is only the relevant snippets:
var renderer = new THREE.WebGLRenderer();
Then i have my stereoeffect renderer which receives the webgl renderer:
var effect = new THREE.StereoEffect(renderer);
Next is that I create the website renderer, and apply it to the stereoeffect:
var rendererCSS = new THREE.CSS3DRenderer();
var effectHUD = new THREE.StereoEffect(rendererCSS);
Then I have scenes which are being rendered:
var scene = new THREE.Scene();
var sceneCSS = new THREE.Scene();
function render(dt) {
effect.render(scene, camera);
effectHUD.render( sceneCSS, camera );
}
No what I receive is this:
A stereoscopic image of my mesh, but a non stereoscopic image of the website. The problem is that the when I try to add the css renderer into the StereoEffect renderer, the setViewport function (among others, probably) are missing.
I've tried adding the website object to the webgl renderer, but it doesn't want to render my website, so adding the website object to the scene with the meshes doesn't work.
Any help is greatly appreciated!
I've been having the same problem.
It appears there was a CSS Stereo renderer but it's been removed along with all examples. This could have been for any number of reasons so use the following with caution, or until they reintroduce compatibility:
After searching I found a remaining copy of their demo from which you can mine the code and copy its CSS3DStereoRenderer.js file.
Hopefully this helps.
i've been tinkering around with three.js and i have a canvas i'd like to use as kind of a GUI. for that i have to check if an object is in the camera frustum.
my current code:
camera.updateMatrix();
camera.updateMatrixWorld();
var frustum = new THREE.Frustum();
var projScreenMatrix = new THREE.Matrix4();
projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
frustum.setFromProjectionMatrix( camera.projectionMatrix );
if(frustum.containsPoint( mesh.position )){
//stuff happens...
};
frustum.containsPoint()keeps returning false. what am i doing wrong here?
Your code is using
frustum.setFromMatrix( camera.projectionMatrix );
But that isn't the matrix you want. Instead use:
frustum.setFromMatrix( new THREE.Matrix4().multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ) );
as answered in How to determine if plane is in Three.js camera Frustum
Three.js is doing view frustum Culling internally and only rendering when in camera frustum. Assuming that your Boundig Volumes are calculated correct, you can track weather a renderable Object3D is inside the camera view frustum when Object3D.onBeforeRender callback is called in your current frame