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!
Related
I have the following code to render a simple cube. It has dat.GUI controls to change rotation, and I want to add a color changer also. Eventually, I want to have a more complex geometry and want to be able to change the color of more than one element.
$(function(){
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, .1, 500);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xdddddd);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
var axis = new THREE.AxisHelper(10);
scene.add (axis);
var grid = new THREE.GridHelper(50, 5);
var color = new THREE.Color("rgb(255,0,0)");
grid.setColors(color, 0x000000);
scene.add(grid);
var cubeGeometry = new THREE.BoxGeometry(5, 5, 5);
var cubeMaterial = new THREE.MeshLambertMaterial({color:0x80ff});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
var planeGeometry = new THREE.PlaneGeometry(30,30,30);
var planeMaterial = new THREE.MeshLambertMaterial({color:0xffffff});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -.5*Math.PI;
plane.receiveShadow = true;
scene.add(plane);
cube.position.x += 0.001;
cube.position.y = 2.5;
cube.position.z = 2.5;
scene.add(cube);
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.castShadow = true;
spotLight.position.set (15,30,50);
scene.add(spotLight);
camera.position.x = 40;
camera.position.y = 40;
camera.position.z = 40;
camera.lookAt(scene.position);
var guiControls = new function(){
this.rotationX = 0.001;
this.rotationY = 0.001;
this.rotationZ = 0.001;
}
var datGUI = new dat.GUI();
datGUI .add(guiControls, 'rotationX', -30*Math.PI/180, 30*Math.PI/180);
datGUI .add(guiControls, 'rotationY', -30*Math.PI/180, 30*Math.PI/180);
datGUI .add(guiControls, 'rotationZ', -30*Math.PI/180, 30*Math.PI/180);
render();
function render() {
cube.rotation.x = guiControls.rotationX;
cube.rotation.y = guiControls.rotationY;
cube.rotation.z = guiControls.rotationZ;
requestAnimationFrame(render);
renderer.render(scene,camera);
}
$("#webGL-container").append(renderer.domElement);
renderer.render(scene,camera);
});
I have been able to add a gui to change color, but I cannot figure out how to bind the gui to the cube color.
var gui = new dat.GUI();
var folder = gui.addFolder('folder');
var params = {};
params.color = [255, 0, 255];
folder.addColor(params, 'color');
You can use dat.GUI to change the color of your cube by using a pattern like this one:
var params = {
color: 0xff00ff
};
var gui = new dat.GUI();
var folder = gui.addFolder( 'MATERIAL' );
folder.addColor( params, 'color' )
.onChange( function() { cube.material.color.set( params.color ); } );
folder.open();
three.js r.92
I'm implementing something similar to the buffer geometry instancing dynamic example.
Basically the idea is having one bufferGeometry duplicated and having an attribute array with the offsets of my objects (like they have in the above example).
If I try to add shadows, I only get shadows on 1 object, which I assume is because we only have 1 geometry.
Is there a way of adding shadows to all my objects?
var scene, camera, renderer, controls;
var offsets;
init();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 250, 1000);
renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFSoftShadowMap
renderer.gammaInput = true
renderer.gammaOutput = true
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
// Lights
var ambient = new THREE.AmbientLight(0xcccccc);
scene.add(ambient);
var spot = new THREE.SpotLight(0x999999, 1, 0, Math.PI / 2, 1);
spot.position.set(700, 700, 700)
spot.target.position.set(0, 0, 0);
spot.castShadow = true
spot.angle = Math.PI / 4
spot.penumbra = 0.05
spot.decay = 2
spot.distance = 10000
spot.shadow.mapSize.width = 1024
spot.shadow.mapSize.height = 1024
spot.shadow.camera.near = 1
spot.shadow.camera.far = 10000
scene.add(spot);
var spotHelper = new THREE.SpotLightHelper(spot)
scene.add(spotHelper);
// Floor
var geometry = new THREE.PlaneGeometry(3000, 3000, 10, 10);
var material = new THREE.MeshPhongMaterial({
color: new THREE.Color(0x777777),
shininess: 5
});
var ground = new THREE.Mesh(geometry, material);
ground.rotation.x = -1.57;
ground.receiveShadow = true;
scene.add(ground);
// instanced geometry
var instances = 10;
var geometry = new THREE.InstancedBufferGeometry();
var icosahedron = new THREE.BufferGeometry().fromGeometry(new THREE.IcosahedronGeometry(200, 3));
geometry.addAttribute('position', icosahedron.attributes.position);
geometry.addAttribute('normal', icosahedron.attributes.normal);
geometry.addAttribute('uv', icosahedron.attributes.uv);
geometry.setIndex(icosahedron.index);
offsets = new THREE.InstancedBufferAttribute(new Float32Array(instances * 3), 3, 1);
var vector = new THREE.Vector3();
for (var i = 0; i < offsets.count; i++) {
var x = Math.random() * 1000 - 500;
var y = Math.random() * 1000 - 500;
var z = Math.random() * 1000 - 500;
vector.set(x, y, z).normalize();
offsets.setXYZ(i, x + vector.x * 5, y + vector.y * 5, z + vector.z * 5);
}
geometry.addAttribute('offset', offsets);
var material = new THREE.ShaderMaterial({
uniforms: {},
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent,
side: THREE.DoubleSide,
});
var mesh = new THREE.Mesh(geometry, material);
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
Example JsFiddle
I'm having trouble controlling shadows in THREE.js. First off, the shadow in my scene is way too dark. From what I've read, there was a shadowDarkness property, that is know longer available in the current version of three.js. Does anyone know a work around?
Also, in the attached image: the "backface" geometry is not occluding light on the shadow of the seat - however, you can see the backface of the stool in the reflection of the sphere(cubeCamera). Does anyone know how to fix that?
On a side note: chrome gives me an error "Uncaught TypeError: Cannot set property 'visible' of undefined," regarding the
frameMesh.visible = false;
cubeCameraFrame.position.copy(frameMesh.position);
cubeCameraFrame.updateCubeMap(renderer, scene);
frameMesh.visible = true;
part of my code. Could that be effecting the shadows in some way? I can comment that part of the code and it will have little effect on the stoolframes "reflective" appearance. However it then no longer is reflects in the sphere. Any help is much appreciated.
///webGL - Locking down the Basics
/////////////////////////////////////////////////////////////Environment Settings///////////////////////////////////////////////////////////////////////
///Renderer
var scene = new THREE.Scene();
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMapType = THREE.PCFSoftShadowMap;
renderer.shadowMapEnabled = true;
document.body.appendChild(renderer.domElement);
///Camera's
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
scene.add(camera);
camera.position.set(0, 16, 25);
camera.rotation.x += -0.32;
var cubeCameraSphere = new THREE.CubeCamera(1, 1000, 256); // parameters: near, far, resolution
cubeCameraSphere.renderTarget.texture.minFilter = THREE.LinearMipMapLinearFilter; // mipmap filter
scene.add(cubeCameraSphere);
var cubeCameraFrame = new THREE.CubeCamera(1, 1000, 256); // parameters: near, far, resolution
cubeCameraFrame.renderTarget.texture.minFilter = THREE.LinearMipMapLinearFilter; // mipmap filter
scene.add(cubeCameraFrame);
///Controls
///Lights
var lightSpot_Right = new THREE.SpotLight(0xffffff);
lightSpot_Right.position.set(50, 50, 0);
lightSpot_Right.intensity = 1.25;
lightSpot_Right.castShadow = true;
lightSpot_Right.shadowDarkness = 0.1;
lightSpot_Right.shadowMapWidth = 2048;
lightSpot_Right.shadowMapHeight = 2048;
lightSpot_Right.shadowCameraNear = 1;
lightSpot_Right.shadowCameraFar = 100;
lightSpot_Right.shadowCameraFov = 65;
scene.add(lightSpot_Right);
var lightDirect_Left = new THREE.DirectionalLight(0xffffff, 0.25);
lightDirect_Left.position.set(-1, 0, 0);
scene.add(lightDirect_Left);
///Loaders
var loadTexture = new THREE.TextureLoader();
var loader = new THREE.JSONLoader();
///skyBox
var imagePrefix = "textures/";
var directions = ["skyboxRight", "skyboxLeft", "skyboxTop", "skyboxBottom", "skyboxFront", "skyboxBack"];
var imageSuffix = ".jpg";
var skyMaterialArray = [];
for (var i = 0; i < 6; i++)
skyMaterialArray.push(new THREE.MeshBasicMaterial({
map: new THREE.TextureLoader().load(imagePrefix + directions[i] + imageSuffix),
side: THREE.BackSide
}));
var skyMaterial = new THREE.MeshFaceMaterial(skyMaterialArray);
var skyGeometry = new THREE.CubeGeometry(1000, 1000, 1000);
var skyBox = new THREE.Mesh(skyGeometry, skyMaterial);
scene.add(skyBox);
////////////////////////////////////////////////////////Object Settings//////////////////////////////////////////////////////////////////
//Textures
var seatTexture = loadTexture.load("textures/Maharam_Mister_Notice_Diffuse.jpg");
seatTexture.wrapS = THREE.RepeatWrapping;
seatTexture.wrapT = THREE.RepeatWrapping;
seatTexture.repeat.set(3, 3);
var conceteDiffuse = loadTexture.load("textures/Contrete_Diffuse.jpg");
conceteDiffuse.wrapS = THREE.RepeatWrapping;
conceteDiffuse.wrapT = THREE.RepeatWrapping;
conceteDiffuse.repeat.set(3, 3);
var conceteNormal = loadTexture.load("textures/Contrete_Normal.jpg");
conceteNormal.wrapS = THREE.RepeatWrapping;
conceteNormal.wrapT = THREE.RepeatWrapping;
conceteNormal.repeat.set(3, 3);
var conceteSpecular = loadTexture.load("textures/Contrete_Specular.jpg");
conceteSpecular.wrapS = THREE.RepeatWrapping;
conceteSpecular.wrapT = THREE.RepeatWrapping;
conceteSpecular.repeat.set(3, 3);
///Materials
var seatMaterial = new THREE.MeshLambertMaterial({
map: seatTexture,
side: THREE.DoubleSide
});
var frameMaterial = new THREE.MeshPhongMaterial({
envMap: cubeCameraFrame.renderTarget,
color: 0xcccccc,
emissive: 0x404040,
shininess: 10,
reflectivity: .8
});
var frameHardwareMat = new THREE.MeshPhongMaterial({
color: 0x000000
});
var feetMat = new THREE.MeshPhongMaterial({
color: 0x050505,
shininess: 99
});
var sphereMat = new THREE.MeshPhongMaterial({
envMap: cubeCameraSphere.renderTarget
});
var groundMat = new THREE.MeshPhongMaterial({
map: conceteDiffuse,
specularMap: conceteSpecular,
normalMap: conceteNormal,
normalScale: new THREE.Vector2( 0.0, 0.6 ),
shininess: 50
});
///Geometry and Meshes
var barStool = new THREE.Object3D();
scene.add(barStool);
var seatMesh;
loader.load("models/stoolSeat.js", function (geometry, material) {
seatMesh = new THREE.Mesh(geometry, seatMaterial);
seatMesh.scale.set(.5, .5, .5);
seatMesh.castShadow = true;
seatMesh.receiveShadow = true;
barStool.add(seatMesh);
});
var frameMesh;
loader.load("models/stoolFrame.js", function (geometry, material) {
frameMesh = new THREE.Mesh(geometry, frameMaterial);
frameMesh.scale.set(.5, .5, .5);
frameMesh.castShadow = true;
barStool.add(frameMesh);
});
var frameFeetMesh;
loader.load("models/stoolFeet.js", function (geometry, material) {
frameFeetMesh = new THREE.Mesh(geometry, feetMat);
frameFeetMesh.scale.set(.5, .5, .5);
frameFeetMesh.castShadow = true;
barStool.add(frameFeetMesh);
});
var frameHardwareMesh;
loader.load("models/stoolHardware.js", function (geomtry, material) {
frameHardwareMesh = new THREE.Mesh(geomtry, frameHardwareMat);
frameHardwareMesh.scale.set(.5, .5, .5);
barStool.add(frameHardwareMesh);
});
var sphereGeo = new THREE.SphereGeometry(2.5, 50, 50);
var sphereMesh = new THREE.Mesh(sphereGeo, sphereMat);
scene.add(sphereMesh);
sphereMesh.position.set(-10, 5, 0);
var groundGeo = new THREE.PlaneGeometry(100, 50, 1);
var groundMesh = new THREE.Mesh(groundGeo, groundMat);
scene.add(groundMesh);
groundMesh.rotation.x = -90 * Math.PI / 180;
groundMesh.receiveShadow = true;
///Render Scene
var render = function () {
requestAnimationFrame(render);
barStool.rotation.y += 0.01;
skyBox.rotation.y -= 0.0002;
sphereMesh.visible = false;
cubeCameraSphere.position.copy(sphereMesh.position);
cubeCameraSphere.updateCubeMap(renderer, scene);
sphereMesh.visible = true;
//frameMesh.visible = false;
//cubeCameraFrame.position.copy(frameMesh.position);
//cubeCameraFrame.updateCubeMap(renderer, scene);
//frameMesh.visible = true;
renderer.render(scene, camera);
};
render();
Shadow darkness has been removed. The best work-around is to add ambient light to your scene.
scene.add( new THREE.AmbientLight( 0xffffff, 0.3 );
You may want to concurrently reduce the intensity of your SpotLight.
The shadow is actually correct given only back faces are casting shadows. It appears that the stool is hollow under the seat -- in other words, the seat is not a closed volume. Add a bottom to the underside of your seat.
Alternatively, you can leave your model as-is and experiment with
renderer.shadowMap.cullFace = THREE.CullFaceNone;
Finally, you are getting the error because you are accessing frameMesh in the animation loop before it is defined in the loader callback. The callback is asynchronous.
if ( frameMesh !== undefined ) {
// your code
}
three.js r.75
I am trying to add different image to each face of a cylinder in three.js, basically I want the top, bottom and side to be different images.
This is code where I have added one image which wraps the complete cylinder.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.CylinderGeometry(0.9,1,0.5,32,1, false);
var material = new THREE.MeshPhongMaterial({color: 0xffffff, side:THREE.DoubleSide, map: THREE.ImageUtils.loadTexture('cake-texture-nice-golden-ginger-33420104.jpg')});
var cone = new THREE.Mesh(geometry, material);
scene.add(cone);
var width = window.innerWidth; var height = window.innerHeight; var screenW = window.innerWidth; var screenH = window.innerHeight; /*SCREEN*/ var spdx = 0, spdy = 0; mouseX = 0, mouseY = 0, mouseDown = false; /*MOUSE*/ document.body.addEventListener("mousedown", function(event) { mouseDown = true }, false); document.body.addEventListener("mouseup", function(event) { mouseDown = false }, false); function animate() { spdy = (screenH / 2 - mouseY) / 40; spdx = (screenW / 2 - mouseX) / 40; if (mouseDown){ cone.rotation.x = spdy; cone.rotation.y = spdx; } requestAnimationFrame( animate ); render(); } // create a point light var pointLight = new THREE.PointLight( 0xFFFF8F ); // set its position pointLight.position.x = 10; pointLight.position.y = 50; pointLight.position.z = 130; // add to the scene scene.add(pointLight); camera.position.z = 5; var render = function () { requestAnimationFrame(render); //cone.rotation.x += 0.01; //cone.rotation.y += 0.001; //cone.rotation.z -= 0.02; window.addEventListener('mousemove', function (e) { var mouseX = ( e.clientX - width / 2 ); var mouseY = ( e.clientY - height / 2 ); cone.rotation.x = mouseY * 0.005; cone.rotation.y = mouseX * 0.005; cone.rotation.y += mouseY; //console.log(mouseY); }, false); renderer.render(scene, camera); }; render();
This is the pen for the cylinder: http://codepen.io/dilipmerani/pen/XmWNdV
Update-25Sep
var materialTop = new THREE.MeshPhongMaterial({color: 0xffffff, side:THREE.DoubleSide, map: THREE.ImageUtils.loadTexture('chocolate_brown_painted_textured_wall_tileable.jpg')});
var materialSide = new THREE.MeshPhongMaterial({color: 0xffffff, side:THREE.DoubleSide, map: THREE.ImageUtils.loadTexture('cake-texture-nice-golden-ginger-33420104.jpg')});
var materialBottom = new THREE.MeshPhongMaterial({color: 0xffffff, side:THREE.DoubleSide, map: THREE.ImageUtils.loadTexture('cake-texture-nice-golden-ginger-33420104.jpg')});
var materialsArray = [];
materialsArray.push(materialTop); //materialindex = 0
materialsArray.push(materialSide); // materialindex = 1
materialsArray.push(materialBottom); // materialindex = 2
var material = new THREE.MeshFaceMaterial(materialsArray);
var geometry = new THREE.CylinderGeometry(0.9,1,0.5,3,1, false);
var aFaces = geometry.faces.length;
console.log(aFaces);
for(var i=0;i<aFaces;i++) {
geometry.faces[i].materialindex;
}
var cone = new THREE.Mesh(geometry, material);
scene.add(cone);
Thanks
Create MeshFaceMaterial:
var materialTop = new THREE.MeshPhongMaterial(...);
var materialSide = new THREE.MeshPhongMaterial(...);
var materialBottom = new THREE.MeshPhongMaterial(...);
var materialsArray = [];
materialsArray.push(materialTop); //materialindex = 0
materialsArray.push(materialSide); // materialindex = 1
materialsArray.push(materialBottom); // materialindex = 2
var material = new THREE.MeshFaceMaterial(materialsArray);
Update geometry:
var geometry = new THREE.CylinderGeometry(0.9,1,0.5,32,1, false);
faces you can get from geometry.faces
Loop faces and change materialindex: geometry.faces[faceIndex].materialindex
Print geometry.faces to console and check what it has.
var aFaces = geometry.faces.length;
for(var i=0;i<aFaces;i++) {
if(i < 64){
geometry.faces[i].materialIndex = 0;
}else if(i > 63 && i < 96){
geometry.faces[i].materialIndex = 1;
}else{
geometry.faces[i].materialIndex = 2;
}
}
Build your cone
var cone = new THREE.Mesh(geometry, material);
Example of your updated code
You should create faces in mesh's geometry with some materialindex. So you'll have 3 surfaces. And than use MeshFaceMaterial(array of material for each surface).
I've looked through a number of other S.O. questions, followed all of the advice, but I'm still clueless as to why I can't get shadows to render on this very basic scene.
http://jsfiddle.net/4Txgp/
[Updated] Code:
var SCREEN_WIDTH = window.innerWidth - 25;
var SCREEN_HEIGHT = window.innerHeight - 25;
var camera, scene;
var canvasRenderer, webglRenderer;
var container, mesh, geometry, plane;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.x = 1200;
camera.position.y = 1000;
camera.lookAt({
x: 0,
y: 0,
z: 0
});
scene = new THREE.Scene();
var groundMaterial = new THREE.MeshLambertMaterial({
color: 0x6C6C6C
});
plane = new THREE.Mesh(new THREE.PlaneGeometry(10000, 10000, 100, 100), groundMaterial);
plane.rotation.x = -Math.PI / 2;
plane.receiveShadow = true;
scene.add(plane);
// LIGHTS
// scene.add(new THREE.AmbientLight(0x666666));
/*
var light;
light = new THREE.DirectionalLight(0xdfebff, 1.75);
light.position.set(600, 800, 100);
//light.position.multiplyScalar(1.3);
light.castShadow = true;
light.shadowCameraVisible = true;
light.shadowMapWidth = light.shadowMapHeight = 2048;
var d = 50;
light.shadowCameraLeft = -d;
light.shadowCameraRight = d;
light.shadowCameraTop = d;
light.shadowCameraBottom = -d;
light.shadowCameraFar = 500;
light.shadowDarkness = 0.5;
scene.add(light);
*/
var spotLight = new THREE.SpotLight( 0xffffff );
spotLight.position.set( 700, 1000, 100 );
spotLight.castShadow = true;
spotLight.shadowCameraVisible = true;
spotLight.shadowMapWidth = 2048;
spotLight.shadowMapHeight = 2048;
spotLight.shadowCameraNear = 100;
spotLight.shadowCameraFar = 2000;
spotLight.shadowCameraFov = 30;
scene.add( spotLight );
var boxgeometry = new THREE.CubeGeometry(100, 200, 100);
var boxmaterial = new THREE.MeshLambertMaterial({
color: 0x0aeedf
});
var cube = new THREE.Mesh(boxgeometry, boxmaterial);
cube.position.x = 0;
cube.position.y = 100;
cube.position.z = 0;
scene.add(cube);
// RENDERER
webglRenderer = new THREE.WebGLRenderer();
webglRenderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
//webglRenderer.domElement.style.position = "relative";
webglRenderer.shadowMapEnabled = true;
webglRenderer.shadowMapSoft = true;
container.appendChild(webglRenderer.domElement);
}
function animate() {
var timer = Date.now() * 0.0002;
camera.position.x = Math.cos(timer) * 1000;
camera.position.z = Math.sin(timer) * 1000;
requestAnimationFrame(animate);
render();
}
function render() {
camera.lookAt(scene.position);
webglRenderer.render(scene, camera);
}
I have a scene with a plane, an object (cube), a spotlight (copied directly from http://threejs.org/docs/58/#Reference/Lights/SpotLight for testing purposes) , and a camera. It renders fine, except that the cube is not casting a shadow on the "ground" (plane), and the shading looks like everything has been done in a basic material. I'm using a combo of Phongs and Lamberts.
My directional light is set to castShadow = true;, and my plane is set with receiveShadow = true, along with shadow map settings. The renderer itself has shadowMapEnabled = true.
I've tried various solutions, I remember with previous versions of ThreeJS there would be external library calls depending on what you wanted to do, but I've also seen other examples on JSFiddle just calling ThreeJS by itself, as well as examples from the official site, that work fine.
Any hints/info/constructive remarks about overlooking something simple and small?
You need to set
cube.castShadow = true;
and make sure the shadow camera far plane reaches the cube.
three.js r.144