really weird ghosty shadows using three.js

只谈情不闲聊 提交于 2019-12-11 20:19:17

问题


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!


回答1:


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.



来源:https://stackoverflow.com/questions/20297540/really-weird-ghosty-shadows-using-three-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!