I'm using three.js to make some solar system, all my objects are sphere (suns and planets), but I found this really weird and ghosty square shadow:
Another ghost shadow seems to be that, the shadow that sphere A casts on sphere B, appears on both the front and back side of sphere B, like this:
I am so confused since I don't really remember create any square stuff and I've checked my code for like million times without any finding.
Finally, I dismissed all the lights in the world, and set the background to light color, it appears:
But when I move my camera to the back of it, it just disappears, like a "1-dimension" square created by some high-level creature from the universe.
This is my final project which is due next week, I really don't know how to explain this to my professor.
Appreciate any help! Thanks a lot!
below is my code that creates objects:
function init() {
container = document.createElement('div');
document.body.appendChild(container);
renderer = new THREE.WebGLRenderer({
antialias : true, alpha: true
});
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
renderer.shadowMapEnabled = true;
container.appendChild(renderer.domElement);
scene = new THREE.Scene();
scene.updateMatrixWorld(true);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 1000 );
camera.position.set(5,5,5);
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.staticMoving = false;
controls.dynamicDampingFactor = 0.2;
var light = new THREE.AmbientLight( 0x222222 );
scene.add( light ); // this is the light I tried to close
var light = new THREE.DirectionalLight( 0xffffff, 0 );
light.position.set(0,0,5);
scene.add( light ); // this is the light I tried to close
light.castShadow = true;
light.shadowCameraNear = 0.01;
light.shadowCameraFar = 15;
light.shadowCameraFov = 45;
light.shadowCameraLeft = -1;
light.shadowCameraRight = 1;
light.shadowCameraTop = 1;
light.shadowCameraBottom= -1;
//light.shadowCameraVisible = true
light.shadowBias = 0.001;
light.shadowDarkness = 0.2;
light.shadowMapWidth = 1024;
light.shadowMapHeight = 1024;
//////////////////////////////////////////////////////////////////////////////////
// render the scene //
//////////////////////////////////////////////////////////////////////////////////
onRenderFcts.push(function(){
controls.update();
renderer.render( scene, camera );
});
window.addEventListener('keydown', onKeyDown, false);
renderer.domElement.addEventListener( 'mousemove', onMouseMove, false );
renderer.domElement.addEventListener( 'click', onMouseClick, false );
}
function createSun (){
var geometry = new THREE.SphereGeometry(0.5, 32, 32)
var texture = THREE.ImageUtils.loadTexture(THREEx.Planets.baseURL+'images/sunmap.jpg')
var material = new THREE.MeshPhongMaterial({
map : texture,
bumpMap : texture,
bumpScale: 0.05,
emissive: new THREE.Color('#ff9933'),
specular: new THREE.Color('#ffff66'),
shininess: 800,
wireframeLinewidth: 500
})
var mesh = new THREE.Mesh(geometry, material)
mesh.receiveShadow = true;
mesh.castShadow = true;
mesh.matrixWorldNeedsUpdate = true;
return mesh
}
function createMoon (){
var geometry = new THREE.SphereGeometry(0.5, 32, 32)
var material = new THREE.MeshPhongMaterial({
map : THREE.ImageUtils.loadTexture(THREEx.Planets.baseURL+'images/moonmap1k.jpg'),
bumpMap : THREE.ImageUtils.loadTexture(THREEx.Planets.baseURL+'images/moonbump1k.jpg'),
bumpScale: 0.002,
})
var mesh = new THREE.Mesh(geometry, material)
return mesh
}
function add_objects() {
// star field
var geometry = new THREE.SphereGeometry(900, 32, 32);
var material = new THREE.MeshBasicMaterial({
map : THREE.ImageUtils.loadTexture('images/earthcloudmap.jpg'),
side : THREE.BackSide
});
var starSphere = new THREE.Mesh(geometry, material);
scene.add(starSphere);
// reference points
originPoint = new THREE.Object3D();
scene.add(originPoint);
onRenderFcts.push(function (delta, now) {
originPoint.rotation.x += rotateFactor * delta;
originPoint.rotation.z += rotateFactor * delta;
});
sunsBasePoint = new THREE.Object3D();
originPoint.add(sunsBasePoint);
onRenderFcts.push(function (delta, now) {
sunsBasePoint.rotation.y += rotateFactor * delta;
sunsBasePoint.rotation.z += rotateFactor * delta;
});
// stars
sun1 = createSun();
sun1.name = 'sun1';
sun1.position.set(0,0,-1.5);
sunsBasePoint.add(sun1);
onRenderFcts.push(function (delta, now) {
sun1.rotation.y -= 1/2 * delta;
sun1.rotation.z += 1/4 * delta;
});
objects.push(sun1);
sun2 = createSun();
sun2.name = 'sun2';
sun2.position.set(1,-1.5,0);
sun2.scale.multiplyScalar(0.8)
sunsBasePoint.add(sun2);
onRenderFcts.push(function (delta, now) {
sun2.rotation.x -= 1/4 * delta;
sun2.rotation.y += 1/8 * delta;
});
objects.push(sun2);
sun3 = createSun();
sun3.name = 'sun3';
sun3.position.set(-1,1,1.5);
sun3.scale.multiplyScalar(1.5);
sunsBasePoint.add(sun3);
onRenderFcts.push(function (delta, now) {
sun3.rotation.y -= 1/8 * delta;
sun3.rotation.x += 1/4 * delta;
});
objects.push(sun3);
threeBodyPlanet = createMoon();
threeBodyPlanet.name = "Three Body Planet";
threeBodyPlanet.position.set(0.5,-0.5,0.5);
threeBodyPlanet.scale.multiplyScalar(1/5);
threeBodyPlanet.receiveShadow = true;
threeBodyPlanet.castShadow = true;
originPoint.add(threeBodyPlanet);
objects.push(threeBodyPlanet);
}
function debug() {
var debugaxis = function(axisLength){
//Shorten the vertex function
function v(x,y,z){
return new THREE.Vertex(new THREE.Vector3(x,y,z));
}
//Create axis (point1, point2, colour)
function createAxis(p1, p2, color){
var line, lineGeometry = new THREE.Geometry(),
lineMat = new THREE.LineBasicMaterial({color: color, lineWidth: 1});
lineGeometry.vertices.push(p1, p2);
line = new THREE.Line(lineGeometry, lineMat);
scene.add(line);
}
createAxis(v(-axisLength/25, 0, 0), v(axisLength, 0, 0), 0xFF0000);
createAxis(v(0, -axisLength/25, 0), v(0, axisLength, 0), 0x00FF00);
createAxis(v(0, 0, -axisLength/25), v(0, 0, axisLength), 0x0000FF);
};
//To use enter the axis length
debugaxis(100);
// lens flares
var textureFlare0 = THREE.ImageUtils.loadTexture( "lensflare0.png" );
var textureFlare2 = THREE.ImageUtils.loadTexture( "lensflare2.png" );
var textureFlare3 = THREE.ImageUtils.loadTexture( "lensflare3.png" );
addLight( 0.55, 0.9, 0.5, 0, 0, 100 );
//addLight( 0.08, 0.8, 0.5, 0, 0, -10 );
//addLight( 0.995, 0.5, 0.9, 50, 50, -10 );
function addLight( h, s, l, x, y, z ) {
var light = new THREE.PointLight( 0xffffff, 1.5, 4500 );
light.color.setHSL( h, s, l );
light.position.set( x, y, z );
scene.add( light );
var flareColor = new THREE.Color( 0xffffff );
flareColor.setHSL( h, s, l + 0.5 );
var lensFlare = new THREE.LensFlare( textureFlare0, 700, -0.1, THREE.AdditiveBlending, flareColor );
lensFlare.add( textureFlare2, 512, 0.0, THREE.AdditiveBlending );
lensFlare.add( textureFlare2, 512, 0.0, THREE.AdditiveBlending );
lensFlare.add( textureFlare2, 512, 0.0, THREE.AdditiveBlending );
lensFlare.add( textureFlare3, 60, 0.6, THREE.AdditiveBlending );
lensFlare.add( textureFlare3, 70, 0.7, THREE.AdditiveBlending );
lensFlare.add( textureFlare3, 120, 0.9, THREE.AdditiveBlending );
lensFlare.add( textureFlare3, 70, 1.0, THREE.AdditiveBlending );
lensFlare.customUpdateCallback = lensFlareUpdateCallback;
lensFlare.position = light.position;
lensFlare.size = 70;
scene.add( lensFlare );
}
function lensFlareUpdateCallback( object ) {
var f, fl = object.lensFlares.length;
var flare;
var vecX = -object.positionScreen.x * 2;
var vecY = -object.positionScreen.y * 2;
//var size = object.size ? object.size : 1000;
for( f = 0; f < fl; f++ ) {
flare = object.lensFlares[ f ];
flare.x = object.positionScreen.x + vecX * flare.distance;
flare.y = object.positionScreen.y + vecY * flare.distance;
//flare.scale = size / camera.distance;
flare.rotation = 0;
}
object.lensFlares[ 2 ].y += 0.025;
object.lensFlares[ 3 ].rotation = object.positionScreen.x * 0.5 + THREE.Math.degToRad( 45 );
};
}
-------------updating-------------
Thanks for yaku's help, I found that the weird square is indeed because of the camera shadow,like in the pics below:
After I increased the shadow parameters, the square shadow seems to be gone, but the remaining shadows on the back of the spheres are still kind of weird in its texture, like this:
It looks like very low resolution shadow made of small squares, why?
Thanks a lot!
------one more question------
All yaku said works!
But I found out there's no shadows of the spheres themselves.
I called
mesh.castShadow = mesh.receiveShadow = true;
every time I create the spheres.
I remember there were these shadows now they are gone...
What might the reason of it?
Thanks!
Not sure, but have you checked the shadow camera dimensions? Looks like the frustum of the shadow camera could be too small, and what you are seeing could be everything inside the frustum is in shadow and the rest unaffected. The light square could be some weird remnant of the shadow camera, shadow maps can be unwieldy..
Set
light.shadowCameraVisible = true;
and adjust the other shadow parameters so that the box encapsulates the whole scene.