Hello,
I am trying to create a scene that is lit by a SpotLight and AmbientLight. I have the SpotLight set to cast shadows, but no shadows are actually visible. I have tried everything I could think of to no avail. (Note: I am running an old THREE.js version (r73) for compatibility with Physijs.)
Code:
Physijs.scripts.worker = '/js/physiworker.js';
Physijs.scripts.ammo = '/js/ammo.js';
let renderer, scene, camera, controls, sphere, spotLight, lastPos = new THREE.Vector3(), moving = false, slowing = false
function init() {
renderer = new THREE.WebGLRenderer({ antialias: true } );
renderer.setClearColor( 0xdddddd );
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setPixelRatio( window.devicePixelRatio );
renderer.domElement.tabIndex = 1
renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
scene = new Physijs.Scene()
scene.setGravity(new THREE.Vector3(0, -30, 0))
document.getElementById("inertia-container").appendChild(renderer.domElement)
camera = new THREE.PerspectiveCamera(
35,
window.innerWidth / window.innerHeight,
1,
1000
);
camera.position.set(0, 50, -50)
scene.userData.camera = camera
let ambientLight = new THREE.AmbientLight(0x666666)
spotLight = new THREE.SpotLight(0xffffff)
spotLight.castShadow = true;
spotLight.shadow.mapSize.width = 512;
spotLight.shadow.mapSize.height = 512;
spotLight.shadow.camera.width = 1500;
spotLight.shadow.camera.height = 1500;
spotLight.shadow.camera.near = 10;
spotLight.shadow.camera.far = 1000;
spotLight.shadow.focus = 1;
spotLight.position.set(500, 500, 500)
spotLightCameraHelper = new THREE.CameraHelper(spotLight.shadow.camera)
scene.add(spotLightCameraHelper)
let spotLightHelper = new THREE.SpotLightHelper(spotLight)
scene.add(spotLightHelper)
let ground = new Physijs.BoxMesh(new THREE.BoxGeometry(10000, 3, 10000), Physijs.createMaterial(new THREE.MeshPhongMaterial({color: 0xdddddd}), 1, 0.1), 0)
ground.recieveShadow = true
//ground.visible = false
let grid = new THREE.GridHelper(5000, 25)
grid.position.setY(1.52)
let sphereEmitter = new Physijs.BoxMesh(new THREE.BoxGeometry(50, 50, 50), new THREE.MeshPhongMaterial({color: 0xaaaaaa}), 0)
sphereEmitter.castShadow = true
sphereEmitter.recieveShadow = true
sphereEmitter.position.set(200, 28, 200)
setInterval(function() {
let sphereGeo = new THREE.SphereGeometry(5, 16, 8)
let newSphere = new Physijs.SphereMesh(sphereGeo, Physijs.createMaterial(new THREE.MeshPhongMaterial({color: 0x00ff00}), 0.5, 1), 0.2)
newSphere.castShadow = true
const wireframeGeometry = new THREE.WireframeGeometry( sphereGeo );
const wireframeMaterial = new THREE.LineBasicMaterial( { color: 0x000000 } );
const wireframe = new THREE.LineSegments( wireframeGeometry, wireframeMaterial );
newSphere.add( wireframe );
newSphere.userData.wireframe = wireframe
newSphere.position.set(180, 18.5, 200)
newSphere.addEventListener('collision', function(obj, linear, angular) {
if (obj != ground && obj != sphereEmitter) {
newSphere.userData.wireframe.material.setValues({color: 0xff0000})
setTimeout(function() {
newSphere.userData.wireframe.material.setValues({color: 0x000000})
}, 500)
if (!newSphere.userData.timeout) {
newSphere.userData.timeout = 10
let c = setInterval(function() {
newSphere.userData.timeout -= 1
if (newSphere.userData.timeout < 1) {
clearInterval(c)
scene.remove(newSphere)
}
}, 1000)
}
else {
newSphere.userData.timeout = 10
}
}
})
scene.add(newSphere)
setInterval(function() {
if (newSphere.position.y < -20) {
scene.remove(newSphere)
}
}, 1000)
}, 1500)
let sphereGeo = new THREE.SphereGeometry(5, 16, 8)
sphere = new Physijs.SphereMesh(sphereGeo, Physijs.createMaterial(new THREE.MeshPhongMaterial({color: 0xff0000}), 1, 0.1), 1)
sphere.position.setY(7)
sphere.userData.lastPos = new THREE.Vector3() //This is for acceleration calulations
scene.userData.focalPoint = sphere
scene.userData.lastPos = new THREE.Vector3().copy(sphere.position)
sphere.castShadow = true
sphere.recieveShadow = true
spotLight.target = sphere
setInterval(function() { //makes it easier to navigate by imposing artificial friction
if (!moving && slowing) {
let v = sphere.getLinearVelocity()
let speed = Math.abs((v.x + v.y + v.z) / 3)
if (speed > 1) {
sphere.applyCentralForce(sphere.getLinearVelocity().negate().multiplyScalar(15).setY(0))
}
else {
slowing = false
sphere.setLinearVelocity(new THREE.Vector3(0, 0, 0))
sphere.setAngularVelocity(new THREE.Vector3(0, 0, 0))
}
}
}, 100)
setInterval(function() {
let v = sphere.getLinearVelocity()
let value = Math.abs((v.x + v.y + v.z) / 3).toFixed(3)
if (value < 0.000001) {
value = 0 // we will never need speed to 10 decimal places
}
window.parent.document.getElementById("inertiaSpeed").textContent = "Sphere speed: " + value.toString() + "u/s"
let distance = sphere.position.distanceTo(sphere.userData.lastPos)
let acceleration = ((distance/100) * 100).toFixed(3)
if (acceleration < 0.000001) {
acceleration = 0
}
sphere.userData.lastPos.copy(sphere.position)
window.parent.document.getElementById("inertiaAccel").textContent = "Sphere acceleration: " + acceleration.toString() + "hu/s"
}, 100)
const wireframeGeometry = new THREE.WireframeGeometry( sphereGeo );
const wireframeMaterial = new THREE.LineBasicMaterial( { color: 0x000000 } );
const wireframe = new THREE.LineSegments( wireframeGeometry, wireframeMaterial );
sphere.add( wireframe );
window.parent.document.getElementById("inertiaReset").addEventListener("click", function() {
sphere.setLinearVelocity(new THREE.Vector3(0, 0, 0))
sphere.setAngularVelocity(new THREE.Vector3(0, 0, 0))
sphere.position.set(0, 10, 0)
sphere.__dirtyPosition = true
sphere.__dirtyRotation = true
})
controls = new THREE.OrbitControls(camera, renderer.domElement)
renderer.domElement.addEventListener("mousedown", function(e) {renderer.domElement.focus()})
renderer.domElement.addEventListener("focus", function() {
})
renderer.domElement.addEventListener("keydown", function(e) {
if (e.code == "KeyW") {
moving = true
sphere.applyCentralForce(new THREE.Vector3(0, 0, -100).applyAxisAngle(new THREE.Vector3(0, 1, 0), controls.getAzimuthalAngle()))
}
})
renderer.domElement.addEventListener("keyup", function(e) {
if (e.code == "KeyW") {
moving = false
slowing = true
}
})
scene.add(ground)
scene.add(grid)
scene.add(sphere)
scene.add(ambientLight)
scene.add(spotLight)
scene.add(sphereEmitter)
requestAnimationFrame(render)
}
function render() {
const rect = renderer.domElement.getBoundingClientRect();
const width = rect.right - rect.left;
const height = rect.bottom - rect.top;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight)
spotLight.shadow.camera.updateProjectionMatrix()
controls.update()
let diff = new THREE.Vector3().copy(sphere.position).sub(lastPos);
camera.position.add(diff);
controls.target.copy(sphere.position)
lastPos.copy(sphere.position)
spotLight.position.add(diff);
scene.simulate()
renderer.render(scene, camera)
requestAnimationFrame(render)
}
init()