In this fiddle, when i change the following parameters i do not see any visible change(s)
directionalLight.shadowCameraVisible = true;
directionalLight.shadowCameraLeft = 1000;
directionalLight.shadowCameraRight = 1000;
directionalLight.shadowCameraBottom = 1000;
directionalLight.shadowCameraTop = 1000;
Are there any hidden setting(s)? What is functionality of these parameters.
Documentation does not help either, Any suggestions?
Those parameters affect only orthographic camera. So you need to set your camera to THREE.OrthographicCamera(). Here is some tutorial on how to use shadows: Casting Shadows.
Generally, you don't see any visible changes because you only have one cube on your scene, so there is nothing that you are casting your shadow on. Add some more geometries to your scene and see how you can settle things based on this tutorial.
Hope that helps!
Related
I need to make light (sun) for casting shadows to all scene (DirectionalLight is the best, right?), but the quality is bad, so I'm trying to make the settings of the shadow: on/off, Low, Normal, High:
a = 512 ... 8192; b = 300 ... 8000
light.castShadow = checked; - no update (but if reload an objects it is work)
light.shadow.mapSize.width/height = a; - this works
light.shadow.camera.top/bottom/left/right = b; - no updating
Tried to see the changes, but nothing works:
light.shadow.camera.updateProjectionMatrix(); - shadows disappear at all
scene.updateMatrixWorld();
camera.updateProjectionMatrix();
camera.updateMatrixWorld();
camera.updateMatrix();
Is the any better way to do a sun?
And how to redraw the shadows?
Adding an example to better understand what I mean ->
Example
According to this link: https://github.com/mrdoob/three.js/wiki/Updates
Properties that can't be easily changed in runtime (once material is
rendered at least once):
numbers and types of uniforms
numbers and types of lights
presence or not of: texture, fog, vertex colors, skinning, morphing, shadow map, alpha test
Changes in these require building of new shader program. You'll need to set material.needsUpdate flag to true.
if you want to change shadow mapSize when runtime, you have to dispose()
light.shadow.map.dispose()
light.shadow.map = null
let s = 1024
light.shadow.mapSize = new THREE.Vector2(s, s)
https://threejs.org/docs/#manual/en/introduction/How-to-dispose-of-objects
It seems that with three.js, a face facing away from a spotlight still receives shadows caused by other meshes between this face and the spotlight. How can we avoid such shadows?
See this jsfiddle for example. In this example, we have a simple scene with a spotlight, an ambient light, a cube, a sphere, and a camera. The frustum of the shadow camera of the spotlight is set to visible.
As we can see, the sphere casts shadow on the farthest face of the cube from the sphere, but this looks wrong because this face is facing away from the spotlight and is not lit by it. I would like to avoid this.
Please note that this jsfiddle is a simplified version of what I would like to achieve. In the actual code, the mesh shape is more complicated and the camera is moved around, and because of these, neither turning off the shadow nor reducing shadowCameraFar is an option for me.
Here is what I think is the most relevant part of the code. See the link to jsfiddle above for the full code.
sphereMesh.castShadow = true;
...
cubeMesh.receiveShadow = true;
...
light.castShadow = true;
light.shadowCameraVisible = true;
light.shadowCameraNear = 200;
light.shadowCameraFar = 1000;
light.shadowCameraFov = 30;
light.shadowBias = 0;
light.shadowDarkness = 0.5;
light.shadowMapWidth = 2048;
light.shadowMapHeight = 2048;
...
scene.add(new THREE.AmbientLight(0x404040));
...
var renderer = new THREE.WebGLRenderer();
...
renderer.shadowMapEnabled = true;
renderer.shadowMapType = THREE.PCFShadowMap;
The third figure in question “really weird ghosty shadows using three.js” by Eno seems to illustrate the same issue, but it is not the main point of that question, and I do not find the answer to my question in the answer to that question.
Is it possible to create a dynamic animation by applying transformations to the bones of a 3D model using three.js? I tried moving and rotating the bones of a SkinnedMesh, but the mesh was not updated.
loader = new THREE.JSONLoader();
loader.load('/JS-Projects/Virtual-Jonah/Modelos/initialPose.js',function jsonReady( geometry )
{
mesh = new THREE.SkinnedMesh( geometry, new THREE.MeshNormalMaterial({skinning : true}) );
mesh.scale.set( 10, 10, 10 );
mesh.position.z = mesh.position.y = mesh.position.x = 0;
mesh.geometry.dynamic = true;
scene.add( mesh );
var index = 0;
for (var i = 0; i < mesh.bones.length; i++)
{
if (mesh.bones[i].name == "forearm_R")
{
index = i;
break;
}
}
setInterval (function ()
{
mesh.bones[index].useQuaternion = false;
mesh.bones[index].position.z += 10;
mesh.bones[index].matrixAutoUpdate = true;
mesh.bones[index].matrixWorldNeedsUpdate = true;
mesh.geometry.verticesNeedUpdate = true;
mesh.geometry.normalsNeedUpdate = true;
renderer.render(scene, camera);
}, 33);
renderer.render(scene, camera);
});
The model I am using was created with makeHuman (nightly build), exported to Collada, imported in Blender and exported to the three.js JSON model. The link to the model is the following:
https://www.dropbox.com/sh/x1606vnaoghes1y/gG_BcZcEKd/initial
Thank you!
Yes, you can!
You need to set mesh.skeleton.bones[i], both mesh.skeleton.bones[i].rotation and mesh.skeleton.bones[i].position. Rotation is of type Euler. Position is of type Vector3. I have actually tested this using my code from here https://github.com/lucasdealmeidasm/three-mm3d (that includes a working skinned mesh with bone-attachable objects) and one can indeed do that.
Note that Inateno's answer is very wrong, there are many instances where this is necessary.
For example, in a FPS, one uses both dynamic and non-dynamic animation.
When a character runs and holds a gun, the direction he points the gun at is dynamically set (one could use mesh.skeleton.bones[i].rotation where "i" is the index for bone assigned to the arm for that) while the rest of the animation, including the walking, is made in the editor and loaded. One can, in three.js, use "THREE.AnimationHandler.update(delta);" and then change single bones' position and rotation in code to solve those issues.
I know you can export a bone driven animation from Blender in JSON format, for use in THREE.js, there are a few tutorials of that around the web. I hope this helps. Good Luck.
If I understund you want to create animations yourself inside the code ?
You are note supposed to do this, in Unity you have a simple animation editor, you never manipulate bones directly in code.
It's long, boring, unperforming. To animate a model use animation directly.
Here's a result of animation with some bones manipulation but there is an animation over.
http://threejs.org/examples/webgl_animation_skinning_morph.html
Here is a tutorial about making simple animation if you need http://blog.romanliutikov.com/post/60461559240/rigging-and-skeletal-animation-in-three-js
And here a related post about animations problems just in case
Blender exports a three.js animation - bones rotate strangely
Hope this will help you :)
I've been playing with three.js here - 2toria.com/pool
The issue I'm having is trying to get my shadows to look better. At the moment, they look like this:-
A bit pixellated. Is there a way I can make them look smoother, like here:-
I've tried a few things, but I can't find the right settings. My renderer is set up like this:-
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
renderer.shadowMapType = THREE.PCFShadowMap;
I thought shadowMapSoft would have done it, but no. Any ideas/help?
Indeed, I've had the same problem. My fix was to increase my light sources shadowMapWidth and Height. In my case it was a spotLight:
spotLight = new THREE.SpotLight( 0xAAAAAA );
spotLight.castShadow = true;
spotLight.shadowCameraFov = VIEW_ANGLE;
spotLight.shadowBias = 0.0001;
spotLight.shadowDarkness = 0.2;
spotLight.shadowMapWidth = 2048;
spotLight.shadowMapHeight = 2048;
Oh one more thing, if you increase the map size by power's of two you smooth out the shadow's more and more, but you will see a performance hit with complex geometry. So try 2048, maybe 4096 see how they work for ya.
I noticed you have renderer.shadowMapType. I'm gonna have to look into that, may make my own projects that much better, thanks :)
In Three.js, I want a camera to be pointed at a point in 3D space.
For this purpose, I tried using the camera.lookAt function like so:
camera.lookAt(new THREE.Vector3(-100,-100,0));
However, I found out that the call has no effect whatsoever. It just does nothing at all. I tried changing the numbers in the vector, and I always get the same look on screen, when it should be changing.
I just found now that if I remove the THREE.TrackballControls I have in my code, the camera.lookAt() works as it should. Is there something wrong with how I use THREE.TrackballControls? This is how I initialize them:
controls = new THREE.TrackballControls( camera, renderer.domElement );
controls.rotateSpeed = 10.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.2;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 1.0;
var radius = 5;
controls.minDistance = radius * 1.1;
controls.maxDistance = radius * 100;
controls.keys = [ 65, 83, 68 ]; // [ rotateKey, zoomKey, panKey ]*/
And then in my render function I do:
function render() {
controls.update();
renderer.render(scene, camera);
}
Documentation on Three.js is pretty scarce, so I thought I'd ask here. Am I doing something wrong?
Looking at the source code of THREE.TrackballControls, I figured out that I can make the camera look where I want by setting trackballControls.target to the THREE.Vector3 I want it to look at, and then rerendering the scene.
Yes Please beware... It seems that having THREE.TrackballControls or THREE.OrbitControls seems to override the camera.lookAt function as your are passing in your camera when you instantiate an instance of the controls. You might want to get rid of the controls and then performing camera.lookAt() or tween your camera some other way to verify that the controls are having a overriding effect on your Camera. I googled for a while why camera.lookat() seemed to have no effect.
In my opinion, we are not supposed to mess with the original code. I found a way around to achieve the objective of looking at any particular point.
After having declared your "control" variable, simply execute these two lines of code:
// Assuming you know how to set the camera and myCanvas variables
control = new THREE.OrbitControls(camera, myCanvas);
// Later in your code
control.object.position.set(camX, camY, camZ);
control.target = new THREE.Vector3(targetX, targetY, targetZ);
Keep in my mind that this will switch the center of the focus to your new target. In other words, your new target will be the center of all rotations of the camera. Some parts will be difficult to look at as you became familiar to manipulate the camera assuming the default center. Try zoom in as much as you can and you will have a sense of what I am saying
Hope this help.
I figured it out. To prevent THREE.TrackballControls or THREE.OrbitControls from overriding camera.lookAt upon initialization, you need to change the line that sets the control's target property to equal the sum of the camera.position vector and the camera.getWorldDirection() vector, instead of how it's currently implemented using a new THREE.Vector3() (which defaults to (0, 0, 0)).
So, for THREE.TrackballControls, change line 39 to:
this.target = new THREE.Vector3().addVectors(/*new line for readability*/
object.position, object.getWorldDirection());
Same goes for THREE.OrbitControls, on line 36.
I actaully haven't tested it on TrackballControls.js but it does work on OrbitControls.js. Hope this helps.
Here's an alternative solution: create an object (i.e. cube) with 0 dimensions.
var cameraTarget = new THREE.Mesh( new THREE.CubeGeometry(0,0,0));
In the render function set the camera.lookAt to the position of the cameraTarget.
function render() {
camera.lookAt( cameraTarget.position );
renderer.render( scene, camera );
}
Then just move cameraTarget around as you wish.
I ran into the same problem and was able to make it work by using OrbitControls.target. Below is what I did after declaring a controller.
controller = new THREE.OrbitControls(camera, renderer.domElement);
controller.addEventListener('change', renderer.domElement);
controller.target = new THREE.Vector3(0, 1, 0);