I can't cast shadow to a plane with directional light in three.js r79.
I have tried every thing, but never worked.
I added a CameraHelper to scene, and all things were inside the area by yellow lines around.But it just doesn't work...
Here's the screen shot:
code:
function init(canvas) {
const renderer = new THREE.WebGLRenderer({
antialias: true,
canvas: canvas,
//alpha: true
});
//renderer.setClearColor(0x777777);
renderer.shadowMap.enabled = true;
renderer.shadowMap.soft = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.shadowMap.needsUpdate = true;
renderer.setSize(innerWidth, innerHeight);
renderer.autoClear = true;
renderer.gammaInput = true;
renderer.gammaOutput = true;
const scene = new THREE.Scene();
const pCamera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 2000);
pCamera.position.x = 300;
pCamera.position.y = -200;
pCamera.position.z = 50;
pCamera.lookAt({x: 0, y: 0, z: -200});
scene.add(pCamera);
//const controls = new THREE.OrbitControls(pCamera, canvas);
//controls.maxPolarAngle = Math.PI * 0.5;
//controls.minDistance = 1000;
//controls.maxDistance = 7500;
const directLight = new THREE.DirectionalLight(0xffffff, 1);
directLight.position.x = 400;
directLight.position.y = 2000;
directLight.position.z = 500;
directLight.castShadow = true;
directLight.shadow.camera.far = 300;
directLight.shadow.camera.near = 100;
directLight.shadow.mapSize.width = 1024;
directLight.shadow.mapSize.height = 1024;
directLight.shadow.bias = 0.0039;
const d = 100;
directLight.shadow.camera.left = -d;
directLight.shadow.camera.right = d;
directLight.shadow.camera.top = -d;
directLight.shadow.camera.bottom = d;
scene.add(directLight);
const cameraHelper = new THREE.CameraHelper(directLight.shadow.camera);
scene.add(cameraHelper);
const cube = new THREE.Mesh(new THREE.BoxGeometry(50, 50, 50), new THREE.MeshLambertMaterial({color: 0xcc0000}));
cube.position.z = -200;
cube.castShadow = true;
scene.add(cube);
const plane = new THREE.Mesh(new THREE.PlaneGeometry(200, 200), new THREE.MeshLambertMaterial({color: 0x22ff11}));
plane.receiveShadow = true;
plane.position.z = -215;
scene.add(plane);
scene.add(new THREE.AmbientLight(0x212223, 0.1));
return function () {
renderer.render(scene, pCamera);
};
}
Related
Working on some kind of fictional treasure map. I'm cutting a large displacement map intosmaller tiles as I don't yet how wide the final terrain is going to be -- right now it's 5*5, but it could be wider in the future
For some reasons, I am having issues projecting shadows on the displaced planes.
I don't know where the problem is coming from. Maybe it's the way I push meshes into an array through a function, i'm afraid i'm not doing this the right way.
I'd like to achieve the result using a directional light
Here is a c4d draft of what i'm trying to achieve
and here is what i'm able to do in the browser (didnt manage to tile them properly yet :^)
var renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
var material = [];
var texture = [];
var tile = [];
var planeRes = 128;
var planesize = 1;
var dim = 5;
var size = dim * dim;
var DispScale = 2;
var geometry = new THREE.PlaneBufferGeometry(planesize,planesize,planeRes, planeRes);
function tileGenerator(inc) {
if (inc < 10) {
texture[inc] = new THREE.TextureLoader().load('cut25lowres/image_part_00' + inc + '.jpg');
} else {
texture[inc] = new THREE.TextureLoader().load('cut25lowres/image_part_0' + inc + '.jpg');
}
material[inc] = new THREE.MeshPhongMaterial({
color: 0xffffff,
displacementMap: texture[inc],
side: THREE.DoubleSide,
receiveShadow : true,
castShadow : true
});
tile[inc] = new THREE.Mesh(geometry, material[inc]);
}
for (var i = 1; i < size + 1; i++) {
tileGenerator(i);
}
for (var i = 1; i < size + 1; i++) {
tile[i].position.set(-planesize * (i % dim)+1, 0, -planesize * Math.ceil(i / dim)+1 );
tile[i].rotation.x = Math.PI / 2 + Math.PI;
tile[i].rotation.z = Math.PI / 2;
scene.add(tile[i]);
}
var dirLight = new THREE.DirectionalLight( 0xffffff, 1 );
dirLight.castShadow = true;
dirLight.shadow.camera.near = 0.1;
dirLight.shadow.camera.far = 6;
dirLight.shadow.mapSize.set( 1024, 1024 );
var targetObject = new THREE.Object3D();
targetObject.position.x = -10;
targetObject.position.z = -10;
dirLight.position.y = 3;
scene.add(targetObject);
dirLight.target = targetObject;
scene.add( dirLight );
Edit : Here is a cleaner version without the array as it's not part of the problem
jsfiddle.net/clemtre/3y9tqc6j/34
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var scene = new THREE.Scene();
var heightmap = new THREE.TextureLoader().load('https://i.imgur.com/MVYhfd7.jpeg');
var geometry = new THREE.PlaneGeometry(20, 20, 100, 100);
var material = new THREE.MeshPhongMaterial({
color: 0xffffff,
displacementMap: heightmap,
displacementScale: 10
});
var light = new THREE.DirectionalLight(0xffffff);
light.position.set(0, 1, 1).normalize();
light.castShadow = true;
scene.add(light);
var plane = new THREE.Mesh(geometry, material);
plane.rotation.x = -Math.PI/2;
scene.add(plane);
camera.position.z = -20;
camera.position.y = 5;
controls.update();
var animate = function() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
};
animate();
Many thanks!
I want my tableBoard (Surface of the table) and tableLegs to cast their shadows upon the floor
Light
import * as THREE from "three";
export default ({ scene }) => {
const lights = [];
lights[0] = new THREE.PointLight(0xffffff, 1, 0);
lights[0].position.set(0, 200, 0);
lights[0].castShadow = true;
scene.add(lights[0]);
}
Objects(Mesh)
tableLeg1.castShadow = true;
tableBoard.castShadow = true;
floor.receiveShadow = true;
tableLeg1.add(floor);
tableBoard.add(tableLeg1);
scene.add(tableBoard);
renderer
sceneSetup = () => {
const width = this.el.clientWidth;
const height = this.el.clientHeight;
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
this.camera.position.z = 5;
this.controls = new OrbitControls(this.camera, this.el);
this.renderer = new THREE.WebGLRenderer({antialias: true});
this.renderer.shadowMap.enabled = true;
this.renderer.setSize(width, height);
this.el.appendChild(this.renderer.domElement);
};
I have exactly the same three cube objects except their x position.
I want them to cast a shadow, but somehow two of them don't cast a shadow while the other one does.
Here is the pic of what's happening.
https://ibb.co/z6Vwxmf
I'm sure that castShadow is set to true on all the objects.
And I don't think I missed any shadow setting property either (because the middle object casts a shadow properly.)
These objects are created under //left cube //right cube comments in the below code.
< script >
window.addEventListener('load', init, false);
function init(event) {
createScene();
createLights();
createTile01();
createTile02();
createTile03();
createBase();
loop();
}
var scene, camera, Width, Height, renderer, container;
function createScene() {
Width = window.innerWidth;
Height = window.innerHeight;
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.x = 0;
camera.position.y = 10;
camera.position.z = 50;
camera.lookAt(scene.position);
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(Width, Height);
renderer.shadowMap.enabled = true;
container = document.getElementById('scene');
container.appendChild(renderer.domElement);
window.addEventListener('resize', handleWindowResize, false);
}
function handleWindowResize() {
Height = window.InnerHeight;
Width = window.InnerWidth;
renderer.setSize(Width, Height);
camera.aspect = Width / Height;
camera.updateProjectionMatrix();
}
var ambiLight, spotLight;
function createLights() {
ambiLight = new THREE.AmbientLight(0xffffff);
scene.add(ambiLight);
spotLight = new THREE.DirectionalLight(0xffffff);
spotLight.position.set(0, 30, -0);
spotLight.intensity = 1;
spotLight.castShadow = true;
scene.add(spotLight);
}
Tile01 = function() {
var geom = new THREE.BoxGeometry(10, 10, 2);
var mat = new THREE.MeshPhongMaterial({
color: 0x53b0df
});
this.mesh = new THREE.Mesh(geom, mat);
this.mesh.receiveShadow = true;
this.mesh.castShadow = true;
}
var tile01;
function createTile01() {
tile01 = new Tile01();
tile01.mesh.position.set(0, 0, 0);
scene.add(tile01.mesh);
}
//right cube
Tile02 = function() {
var geom = new THREE.BoxGeometry(10, 10, 2);
var mat = new THREE.MeshPhongMaterial({
color: 0x25b0cf
});
this.mesh = new THREE.Mesh(geom, mat);
this.mesh.receiveShadow = true;
this.mesh.castShadow = true;
}
var tile02;
function createTile02() {
tile02 = new Tile02();
tile02.mesh.position.set(20, 0, 0);
scene.add(tile02.mesh);
}
//left cube
Tile03 = function() {
var geom = new THREE.BoxGeometry(10, 10, 2);
var mat = new THREE.MeshPhongMaterial({
color: 0x00b0df
});
this.mesh = new THREE.Mesh(geom, mat);
this.mesh.receiveShadow = true;
this.mesh.castShadow = true;
}
var tile03;
function createTile03() {
tile03 = new Tile03();
tile03.mesh.position.set(-20, 0, 0);
scene.add(tile03.mesh);
}
Base = function() {
var geom = new THREE.CylinderGeometry(100, 30, 5, 60);
var mat = new THREE.MeshPhongMaterial({
color: 0xcf34ec
});
this.mesh = new THREE.Mesh(geom, mat);
this.mesh.castShadow = true;
this.mesh.receiveShadow = true;
}
var base;
function createBase() {
base = new Base();
base.mesh.position.set(0, -10, -20);
scene.add(base.mesh);
}
function loop() {
renderer.render(scene, camera);
requestAnimationFrame(loop);
}
< /script>
Could you help me figure out what's wrong with the setting?
I was able to resolve the issue myself.
Referring to some solutions I found at other Q/As about a shadow issue, I added a shadow.camera.left/right/top/bottom properties to the light and it worked.
The below is the code I corrected.
Now I can see the shadows of all the three objects.
var ambiLight, spotLight;
function createLights() {
ambiLight = new THREE.AmbientLight(0xffffff);
scene.add(ambiLight);
spotLight = new THREE.DirectionalLight(0xffffff);
spotLight.position.set(0, 30, -0);
spotLight.intensity = 1;
spotLight.castShadow = true;
spotLight.shadow.camera.left = -400;
spotLight.shadow.camera.right = 400;
spotLight.shadow.camera.top = 400;
spotLight.shadow.camera.bottom = -400;
spotLight.shadow.camera.near = 1;
spotLight.shadow.camera.far = 1000;
spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;
scene.add(spotLight);
}
Lathe Geometry won't cast shadows but spheres and cubes do. Why is that ?
Image
My renderer:
var webGLRenderer = new THREE.WebGLRenderer();
webGLRenderer.setClearColor(0xAAAAAA, 1.0);
webGLRenderer.setSize(window.innerWidth, window.innerHeight);
webGLRenderer.shadowMapEnabled = true;
Lathe:
var latheGeometry = new THREE.LatheGeometry(array, Math.ceil(segments), 0, 2 * Math.PI);
//var meshMaterial = new THREE.MeshBasicMaterial({color:0x00ff00, transparent:true, opacity:0.6});
var meshMaterial = new THREE.MeshLambertMaterial({color: 0xFFFFFF});
meshMaterial.side = THREE.DoubleSide;
var wireFrameMat = new THREE.MeshBasicMaterial();
wireFrameMat.wireframe = false;
latheMesh = THREE.SceneUtils.createMultiMaterialObject(latheGeometry,[meshMaterial, wireFrameMat]);
latheMesh.rotation.x = Math.PI * -0.5;
latheMesh.position.z = 0;
latheMesh.castShadow = true;
scene.add(latheMesh);
My lighting:
var pointColor = "#ffffff";
directionalLight = new THREE.DirectionalLight(pointColor);
directionalLight.position.set(-50,50,50);
directionalLight.castShadow = true;
directionalLight.receiveShadow = false;
directionalLight.shadowCameraVisible = true;
directionalLight.intensity = 1;
directionalLight.shadowCameraNear = 50;
directionalLight.shadowCameraFar = 200;
directionalLight.shadowCameraLeft = -50;
directionalLight.shadowCameraRight = 40;
directionalLight.shadowCameraTop = 50;
directionalLight.shadowCameraBottom = -50;
directionalLight.distance = 0;
directionalLight.shadowMapHeight = 1024;
directionalLight.shadowMapWidth = 1024;
//scene.add( new THREE.DirectionalLightHelper(directionalLight, 0.5) );
scene.add(directionalLight);
As you can see, only sphere can cast shadow and not latheGeometry.
THREE.SceneUtils.createMultiMaterialObject() creates a THREE.Group with a child Mesh for each material.
You need to specify the castShadow property not for the group, but for the child mesh you want to cast the shadow.
three.js r.76
I am trying to get the shadow from the ball appear on the floor, but it doesn't seem to work. Here is my code that declares the renderer, camera, lights, and objects:
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMapEnabled = true;
renderer.shadowMapType = THREE.PCFSoftShadowMap;
document.body.appendChild( renderer.domElement );
var planegeo = new THREE.PlaneGeometry(100,100);
var geomaterial = new THREE.MeshLambertMaterial({color: "#EA8E12", side: THREE.DoubleSide});
var plane = new THREE.Mesh(planegeo, geomaterial);
plane.rotation.x += 90;
plane.position.z = -2;
scene.add(plane);
var light = new THREE.AmbientLight( "#EA8E12", 101);
var light2 = new THREE.DirectionalLight("yellow", 100);
light.position.set(0, 100, 0);
light2.position.set(0, 100, 0);
scene.add(light);
scene.add(light2);
var sphereParent = new THREE.Object3D();
var geometry = new THREE.SphereGeometry(1, 100, 100);
var material = new THREE.MeshPhongMaterial( {color: "yellow", shininess: 100});
var circle = new THREE.Mesh(geometry, material);
sphereParent.add(circle);
sphereParent.position.set(0,3,0);
scene.add(sphereParent);
light2.castShadow = true;
circle.castShadow = true;
sphereParent.castShadow = true;
plane.receiveShadow = true;
Does anyone can tell me what I am missing? Thanks
This should get you started. Modify the parameters as needed:
light2.castShadow = true;
light2.shadowMapWidth = 1024;
light2.shadowMapHeight = 1024;
light2.shadowMapDarkness = 0.75;
light2.shadowCameraNear = 1;
light2.shadowCameraFar = 1000;
light2.shadowDarkness = 0.75;
/* since you have a directional light */
light2.shadowCameraLeft = -500;
light2.shadowCameraRight = 500;
light2.shadowCameraTop = 500;
light2.shadowCameraBottom = -500;
light2.shadowCameraVisible = true; /* debugging */
on the renderer side this might help:
renderer.shadowMapDebug = true;