i want to apply shadow on full object using threejs, if i rotate the object the shadow must be with the object, meaning that i want to apply the shadow for the hole object, i tried with Spotlight, but no luck i doesn't get any changes on my object, so here below is my code
light = new THREE.SpotLight( 0xffffff );
light.position.set( 200, 200, -200 );
light.castShadow = true;
light.shadowMapWidth = 1024; // power of 2
light.shadowMapHeight = 1024;
light.shadowCameraNear = 200; // keep near and far planes as tight as possible
light.shadowCameraFar = 500; // shadows not cast past the far plane
light.shadowCameraFov = 20;
light.shadowBias = -0.00022; // a parameter you can tweak if there are artifacts
light.shadowDarkness = 0.5;
light.shadowCameraVisible = true;
scene.add( light );
Did you tried to set object.receiveShadow = true; on the object on which shadows should be rendered ?
Related
I have a custom mesh geometry (three js) in mapbocx. I am trying to create a light for casting directional shadows but I always end up woth the light source in the base plane (which results in no casted shadows on my objects above the plane). Does anyone know how I can move the light source so it is above the plane? I added a helper to see the scope box and I would like to move it upwards along the z-vector in the image below.
//Create a WebGLRenderer and turn on shadows in the renderer
const renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap
//Add Ambient light
const amblight = new THREE.AmbientLight(0xffffff, 0.8);
amblight.position.set(8, 10, 5); //default; light shining from top
scene.add(amblight);
//Create a DirectionalLight and turn on shadows for the light
const light = new THREE.DirectionalLight(0xffffff, 0.5);
//light.position.set(8, 10, 5); //default; light shining from top
light.position.y = 2000;
light.position.x = 10;
light.position.z = 5;
light.castShadow = true; // default false
scene.add(light);
//scene.add(light.target);
//Set up shadow properties for the light
light.shadow.mapSize.width = 512;
light.shadow.mapSize.height = 512;
light.shadow.camera.left = -100;
light.shadow.camera.right = 100;
light.shadow.camera.top = 100;
light.shadow.camera.bottom = -100;
light.shadow.camera.near = 0.5;
light.shadow.camera.far = 100; //Scope box depth
//Create a plane that receives shadows (but does not cast them)
const planeGeometry = new THREE.PlaneGeometry(1000, 1000, 10, 10);
const planeMaterial = new THREE.MeshPhongMaterial({
color: 0x808080,
opacity: 0.8,
transparent: true,
});
const plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.receiveShadow = true;
scene.add(plane);
const meshString = result.mesh.meshString;
const mesh = meshToThreejs(rhino, meshString, THREE);
//scene.add(mesh);
//Add shadows
mesh.castShadow = true; //default is false
mesh.receiveShadow = true; //default
scene.add(mesh);
//ENd shadows
//Create a helper for the shadow camera (optional)
const helper = new THREE.CameraHelper(light.shadow.camera);
scene.add(helper);
"move the light source so it is above the plane" - It looks like you already know how to do this, just change the z number.
light.position.z = 20;
// or
light.position.set(0, 0, 20);
// Check note below - If y is up
light.position.y = 20;
// or
light.position.set(0, 20, 0);
Just a note, by default Y is up in Three.js unless you have already handled that in code not shown here. If you need to check this add the axesHelper to your scene. The X axis is red. The Y axis is green. The Z axis is blue. Make sure the camera is moved in the correct direction.
const axesHelper = new THREE.AxesHelper( 100 );
scene.add( axesHelper );
If you are still not getting shadows you could try to add a sphere like in the Three.js docs (https://threejs.org/docs/#api/en/lights/shadows/DirectionalLightShadow)
//Create a sphere that cast shadows (but does not receive them)
const sphereGeometry = new THREE.SphereGeometry( 5, 32, 32 );
const sphereMaterial = new THREE.MeshStandardMaterial( { color: 0xff0000 } );
const sphere = new THREE.Mesh( sphereGeometry, sphereMaterial );
sphere.castShadow = true; //default is false
sphere.receiveShadow = false; //default
scene.add( sphere );
If that is casting a shadow correctly then perhaps there is an issue with your mesh, or the height of those buildings is so small that the shadows are really small
I'm currently working with a directionnal ligth for my scene. A small character can move around. All shadows works. But if I start to go a bit further with the avatar, the shadows don't work anymore on it. I think it's may come from the angle of the light but I can't change it. I can draw a square around the shadow/non-shadow area.
Here is my code. Huge numbers were here for me to test things
const dirLight = new THREE.DirectionalLight( 0xffffff, 1 );
dirLight.color.setHSL( 0.1, 1, 0.95 );
dirLight.position.set( - 1, 1.75, 1 );
dirLight.position.multiplyScalar( 30 );
dirLight.distance = 1200;
dirLight.focus = 1200;
dirLight.angle = Math.PI / 1;
scene.add( dirLight );
dirLight.castShadow = true;
dirLight.shadow.mapSize.width = 2048;
dirLight.shadow.mapSize.height = 2048;
const d = 100;
dirLight.shadow.camera.left = - d;
dirLight.shadow.camera.right = d;
dirLight.shadow.camera.top = d;
dirLight.shadow.camera.bottom = - d;
dirLight.shadow.camera.far = 35000;
dirLight.shadow.bias = - 0;
const dirLightHelper = new THREE.DirectionalLightHelper( dirLight, 10 );
scene.add( dirLightHelper );
Here is the code of the ground that recive shadows
const groundGeo = new THREE.PlaneBufferGeometry( 10000, 10000 );
const groundMat = new THREE.MeshLambertMaterial( { color: 0xffffff } );
groundMat.color.setHSL( 0.095, 1, 0.75 );
const ground = new THREE.Mesh( groundGeo, groundMat );
ground.position.y = - 33;
ground.rotation.x = - Math.PI / 2;
ground.receiveShadow = true;
scene.add( ground );
I reused a huge part of the code provided by the ThreeJS example with the flamingo https://threejs.org/examples/?q=light#webgl_lights_hemisphere
Here is also a link to an imgur where I just put some picture to see the shadows
https://imgur.com/a/MGrc5cw
Thanks
If your shadows are working within a limited area, then it must be that your character is walking beyond the frustum of the shadow-camera.
To create directional shadows, you create an orthographic camera and assign its dimensions with .left, .right, .top, .bottom, in this case your camera is has 100 in each direction. When your character walks beyond those 200 units, it is outside the shadow camera, and it no longer receives shadows.
You should add a CameraHelper to the light shadow to let you see the space within its view frustum, as seen in the DirectionalLightShadow code sample
const helper = new THREE.CameraHelper( dirLight.shadow.camera );
scene.add( helper );
Maybe you could have the shadow camera follow the character so he'll always be inside of it.
I'm using three v0.85.2.
By default, all my objects are configured to cast and receive shadows :
const mesh = new Mesh(geometry, material)
mesh.castShadow = meshConfig.castShadow
mesh.receiveShadow = meshConfig.receiveShadow
shadowMap of the renderer is enabled.
Self shadows seem to be correctly rendered (green squares in the image below).
But shadows casted to other objects are missing (red squares).
The problem seems to occur with all my meshes.
I don't find a way to make them appear.
DirectionalLightShadow, there you can read how to work with shadows when you use THREE.DirectionalLight() in your scene.
Also you can play around with .left, .top, .right and .bottom properties of the shadow camera of your light source.
var light = new THREE.DirectionalLight(0xffffff,1);
light.position.set(50, 500, 22);
light.target.position.set(300, 400, 200);
light.shadow.camera.near = 0.5;
light.shadow.camera.far = 5000;
light.shadow.camera.left = -500;
light.shadow.camera.bottom = -500;
light.shadow.camera.right = 500;
light.shadow.camera.top = 500;
light.castShadow = true;
scene.add(light);
three.js r85
jsfiddle example
i am new to three js , i can able to generate the shadows using spot light but i receive unnecessary shadows too. what i need to do to remove the unwanted shadow .i need the shadows only for car and the wall and i need to remove the shadow like rectangle in the ground .
my code is as follows
var ambientLight = new THREE.AmbientLight( 0xffffff );
scene.add( ambientLight );
var light1 = new THREE.SpotLight(0xff00000);
light1.position.set(200, 1200, 0);
light1.target.position.set(0,0,0);
light1.shadowCameraVisible = true;
light1.castShadow = true;
light1.shadowDarkness = 0.8;
light1.shadowCameraNear = 400;
light1.shadowCameraFar = 1600;
//light1.shadowCameraFov = 30;
light1.shadowCameraLeft = -750;
light1.shadowCameraBottom = -500;
light1.shadowCameraRight = 1000;
light1.shadowCameraTop = 600;
var firstLight = new THREE.Object3D();
firstLight.add(light1);
scene.add(firstLight);
Thanks in advance
I see this you want selective shadow of object for the performance tweak.
The best you can do is for car model you have either .obj,.dae or which ever format loader you can load the object into scene via THREE.Object3D which has property "castShadow". Try this out:
var obj3D = new THREE.Object3D();
obj3D.add(/*content from loader*/);
obj3D.castShadow = true;
or
var mesh = new THREE.Mesh();
mesh.castShadow =true;
Enable or disable castShadow property with Mesh too.
I think this solve your problem
I've been trying for bigger parts of the night to make a export code that quickly will let me texture cubes and export them to a game i'm making, but for some reason I can't make my cube to cover the entire 128x128 width and height that I want it to have.
I have the following code:
function init(){
if( Detector.webgl ){
renderer = new THREE.WebGLRenderer({
antialias : false, // to get smoother output
preserveDrawingBuffer : true // to allow screenshot
});
renderer.setClearColorHex( 0xBBBBBB, 1 );
// uncomment if webgl is required
//}else{
// Detector.addGetWebGLMessage();
// return true;
}else{
renderer = new THREE.CanvasRenderer();
}
renderer.setSize(128,128);
document.getElementById('container').appendChild(renderer.domElement);
// add Stats.js - https://github.com/mrdoob/stats.js
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.bottom = '0px';
document.body.appendChild( stats.domElement );
var zoom = 1.0;
// create a scene
scene = new THREE.Scene();
// put a camera in the scene
camera = new THREE.OrthographicCamera(WIDTH / -zoom, HEIGHT / zoom, WIDTH / zoom, HEIGHT / -zoom, -2000, 1000);
//camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set(0.45,0.45,0.45);
camera.lookAt(scene.position);
//camera.position.set(0, 0, 5);
scene.add(camera);
// create a camera contol
//cameraControls = new THREEx.DragPanControls(camera)
// transparently support window resize
THREEx.WindowResize.bind(renderer, camera);
// allow 'p' to make screenshot
THREEx.Screenshot.bindKey(renderer);
// allow 'f' to go fullscreen where this feature is supported
//if( THREEx.FullScreen.available() ){
// THREEx.FullScreen.bindKey();
// document.getElementById('inlineDoc').innerHTML += "- <i>f</i> for fullscreen";
//}
// here you add your objects
// - you will most likely replace this part by your own
//var geometry = new THREE.TorusGeometry( 1, 0.42 );
var cubeSize = 128;
var geometry = new THREE.CubeGeometry( cubeSize, cubeSize, cubeSize );
var material = new THREE.MeshNormalMaterial();
mesh= new THREE.Mesh( geometry, material );
mesh.rotation.x = 0;
mesh.rotation.y = 0;
mesh.rotation.z = 0;
scene.add( mesh );
}
I've been trying out different "zooms" but it still ends up either too big or too small.
The point with all this is to end up with a code that can generate something like this:
https://dl.dropboxusercontent.com/u/5256694/cube_ex.png
What am I doing wrong?
Kind Regards
Hiam
Instead of thinking about the parameters of THREE.OrthographicCamera as "zoom" levels, you should think of them as coordinates of boundary planes for what the camera is able to see.
Also see the answer to Three.js - Orthographic camera for more details about using orthographic cameras in Three.js