ThreeJS update shadow for buffergeometry - javascript

I have a model .gltf loaded in ThreeJS with a keyframe animation that change the shape of the object ( it's a point level animation ). It's working fine, but the shadow doesn't change!
I played around with geometry.computeVertexNormals(), but when I apply that, my model turns total black.
Can someone help me with this one?
Thanks,
Simone

There should be no reason to call BufferGeometry.computeVertexNormals(). You can enable shadow casting by doing this:
gltf.scene.traverse( function ( object ) {
if ( object.isMesh ) {
object.castShadow = true;
}
}
If the model should also receive shadows, set the property receiveShadows to true, too.
You also need to enable shadows on the renderer, properly configure the shadow camera of your light and ensure that the floor has a material that can receive shadows (e.g. not MeshBasicMaterial). An example like the following might be a good orientation:
https://threejs.org/examples/webgl_animation_skinning_blending

Related

Threejs skybox out of range

I am writing a 3d game in javascript with threejs. I made a skybox, and it works, but if I make my cameras near and far distances too small it doesn't show.
I understand why this happens, the camera attached to my player doesn't see as far as the skybox. If I make my cameras "near" and "far" attributes large enough (corresponding to the size of my game map) I can make it so that my skybox is always within range, but I don't want that, since I don't want the camera to see all the objects that far away.
Any ideas of how to force the camera to see the skybox but still have a small "far" attribute so as to no see all the objects in the world?
Any help would be greatly appreciated.
There’s scene.background, which can be set to a CubeTexture.
Just want to add an example, because someone might find it useful here:
var loader = new THREE.CubeTextureLoader();
loader.load([
'./img/sky/galaxy-X.jpg', './img/sky/galaxy+X.jpg',
'./img/sky/galaxy-Y.jpg', './img/sky/galaxy+Y.jpg',
'./img/sky/galaxy-Z.jpg', './img/sky/galaxy+Z.jpg'
] , function(texture)
{
scene.background = texture;
});

Three.js: Panorama Cube to Zoom In and Transition Into a Different Panorama Cube

I am new to Three.js. I am using this example with 6 image cube for panorama effect, where one can pan, zoom in and out around cubes.
https://threejs.org/examples/?q=panorama#webgl_panorama_equirectangular
I want to figure out how, at maximum zoom-in level, I can transition user into a different panorama cube (with different image source), mapped to this particular cube part. So I would, sort of, open the next scene to take user further to the next level in his journey.
This is nearly what Google Street View does when you click on arrows to move forward down the road.
I do not see many examples out there. I researched and saw this may be possible with creating 2 scenes? Any ideas how to make it functional I would appreciate.
Detecting WHEN to transition:
In the example given, the mouse events are all given. The zoom is handled in onDocumentMouseWheel by adjusting the camera's fov property. "Zoom In" reduces the fov, and "Zoom Out" increases it. It would be trivial to detect when the fov has reached a minimum/maximum value, which would trigger your transition to a new scene.
Detecting WHERE to transition:
The next step is determining into which new scene you will transition. You could do something hotspot-like, where you shoot a ray from the camera to see if it hit a particular place (for example a THREE.Sphere which you have strategically positioned). But for simplicity, let's assume you only have the 6 directions you mentioned, and that you're still using the example's mouse control.
Camera movement is handled in onDocumentMouseMove by updating the lat and lon variables (which appear to be in degrees). (Note: It seems lon increases without bounds, so for clarity it might be good to give it a reset value so it can only ever be between 0.0-359.99 or something.) You can get all math-y to check the corners better, or you could simply check your 45's:
if(lat > 45){
// you're looking up
}
else if(lat < -45){
// you're looking down
}
else{
// you're looking at a side, check "lon" instead
}
Your look direction determines to which scene you will transition, should you encounter your maximum zoom.
Transitioning
There are lots of ways you can do this. You could simply replace the texture on the cube that makes up the panorama. You could swap in a totally different THREE.Scene. You could reset the camera--or not. You could play with the lights dimming out/in while the transition happens. You could apply some post-processing to obscure the transition effect. This part is all style, and it's all up to you.
Addressing #Marquizzo's concern:
The lighting is simply a suggestion for a transition. The example doesn't use a light source because the material is a MeshBasicMaterial (doesn't require lighting). The example also doesn't use scene.background, but applies the texture to an inverted sphere. There are other methods one can use if you simply can't affect the "brightness" of the texture (such as CSS transitions).
I added the following code the the example to make it fade in and out, just as an example.
// These are in the global scope, defined just before the call to init();
// I moved "mesh" to the global scope to access its material during the animation loop.
var mesh = null,
colorChange = -0.01;
// This code is inside the "update" function, just before the call to renderer.render(...);
// It causes the color of the material to vary between white/black, giving the fading effect.
mesh.material.color.addScalar(colorChange);
if(mesh.material.color.r + colorChange < 0 || mesh.material.color.r + colorChange > 1){ // not going full epsilon checking for an example...
colorChange = -colorChange;
}
One could even affect the opacity value of the material to make one sphere fade away, and another sphere fade into place.
My main point is that the transition can be accomplished in a variety of ways, and that it's up to #Vad to decide what kind of effect to use.

How do I add a point to an obj file in three.js?

How can I add a point (when I say point I mean a sphere to show that this is where you clicked) to an obj file in three.js onClick? I want it to add to the obj file such that it rotates with it and I would also like to be able to read/save the data of where this point was placed. Is this possible in three.js, and if so how?
Just to be clear - you want to add this to the scene or to an OBJ file that is produced by Three.js?
To add a point to the scene you will need to have a 'work plane' where you are intending the point (as the center of the sphere) to be placed. You would capture the relevant coordinates based on user mouse position within the scene and assign these values the appropriate X, Y or Z value, creating a vector and adding the Sphere to the scene.
To add this to an OBJ file would require that you are writing the file out... or procedurally creating an OBJ in memory, and then writing this out which would be more tedious.
To export an OBJ of your scene, you could try Exporting Threejs Scene to Obj Format
Hii you have to follow below steps to do what you want :-
when mouse click on the object :- add a child mesh in object .
when mouse click else on screen ,remove that mesh object
when mouse interact with now mesh (mouse down event ) ,rotate the object or else you want
Hope it helps you.

Keyboard Controls With DeviceOrientationControls

I am currently creating a VR web app using three.js. As the camera controls I am using the device orientation controls used here in the google cardboard three.js demo.
What I need to do is add keyboard controls to this(e.g Up arrow to go forward etc). I've fiddled around with moving the camera on the two axis (x and z) here:
if (e.keyCode == '38') {
camera.position.set(0, 10, camera.position.z+4);
controls.target.set(
camera.position.x +4,
camera.position.y,
camera.position.z
);
effect.render(scene, camera);
...
However I want to make the character move relative to where they are looking (e.g You look one way and press the Up arrow and the character moves the way you looking). Like a first person view.
Does anyone have any ideas on how this is done? Ive tried using the first person controls from three.js but this eliminates the head tracking which is essential for a VR game.
Any answers would be greatly appreciated. (My source code is practically just the Google cardboard three.js demo code with a function added in too detect key presses)
I solved this by different approach. I created an object3d which is moving in scene. Model and camera are child of this object.
I'm rotating object 3d with camera and in the same time rotate model in opposite direction. When i rotate camera object looks keeping direction. when i want to move object, just translateX object with camera and make model rotation to 0. That did the trick.
On long distances (I have millions of units) started to be jerky. Reason is lost precision.
I solved it by keeping position of object at 0,0,0 and move all other things in opposite direction. That makes your model is still on 0,0,0 coords with right rotation and world is moving around.
Most simple example:
you trying something like
scene.add(character_model);
scene.add(camera);
//camera.rotate ....
character_model.translateX(1);
character_model.rotateX(1);
//etc ...
and now you trying to move camera around the pivot (character_model), but this is overcomplicated mathematics.
Try:
var controls_dimension = new THREE.Object3D();
scene.add(controls_dimension);
controls_dimension.add(character_model);
controls_dimension.add(camera);
//use controls to rotate with this object, not with character_model
controls_dimension.rotateX(2);
// in the same rotate model to opposite direction. You can make
// illusion of rotating camera, not a model.
character_model.rotateX(2*-1);
/*
when you want to go in camera direction=controls_dimension=controls_dimension.translateX(1)
and we moving (you most only animate model rotation to controls_dimension.rotation)
*/

How can I use reflection in three.js?

I want to have a reflecting cube surface in a WebGL page with Three.js. It should resemble a mobile phone display, which reflects some light, but it still has to be black.
I have created an example of a reflecting cube (and also a reflective sphere) with detailed comments. The live version is at
http://stemkoski.github.com/Three.js/Reflection.html
with nicely formatted code at
https://github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/Reflection.html
(This is part of a collection of tutorial examples at http://stemkoski.github.com/Three.js/)
The main points are:
add to your scene a second camera (a CubeCamera) positioned at the object whose surface should be reflective
create a material and set the environment map as the results of rendering from this second camera, e.g.
for example:
var mirrorCubeMaterial = new THREE.MeshBasicMaterial(
{ envMap: mirrorCubeCamera.renderTarget } );
in your render function, you have to render from all your cameras. Temporarily hide the object that is reflecting (so that it doesn't get in the way of the camera you are going to use), render from that camera, then unhide the reflective object.
for example:
mirrorCube.visible = false;
mirrorCubeCamera.updateCubeMap( renderer, scene );
mirrorCube.visible = true;
These code snippets are from the links I posted above; check them out!

Categories

Resources