使用three.js真的很奇怪的鬼影

时间:2013-11-30 06:58:01

标签: three.js shadow light sun

我正在使用three.js来制造太阳系,我的所有物体都是球体(太阳和行星),但我发现这非常奇怪而且强烈的方形阴影: enter image description here enter image description here

另一个鬼影似乎是,球体A投射在球体B上的阴影出现在球体B的正面和背面,如下所示: enter image description here

我很困惑,因为我不记得创建任何方形的东西,我已经检查了我的代码几百万次而没有任何发现。

最后,我解雇了世界上所有的灯光,并将背景设置为浅色,它出现了: enter image description here

但是当我将相机移到它的背面时,它就会消失,就像一个由宇宙中的某个高级生物创造的“一维”方形。 enter image description here

这是我下周要到期的最后一个项目,我真的不知道如何向我的教授解释这个。

感谢任何帮助! 非常感谢!

下面是我创建对象的代码:

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 );

    };
}

------------- -------------更新

感谢yaku的帮助,我发现奇怪的方块确实是因为相机阴影,就像下面的照片一样: enter image description here enter image description here

在我增加阴影参数后,方形阴影似乎消失了,但是球体背面的剩余阴影在纹理上仍然有些奇怪,如下所示: enter image description here enter image description here

它看起来像是由小方块组成的非常低分辨率的阴影,为什么?

非常感谢!

------还有一个问题------

所有yaku说工作!

但我发现球体本身没有阴影。 enter image description here

我致电

mesh.castShadow = mesh.receiveShadow = true;

每次我创建球体。

我记得有这些阴影现在他们已经消失了......

它可能是什么原因?

谢谢!

1 个答案:

答案 0 :(得分:1)

不确定,但你检查了阴影相机的尺寸吗?看起来像阴影相机的平截头体可能太小,而你所看到的可能是截头体内的所有东西都在阴影中而其余部分不受影响。光方块可能是阴影相机的一些奇怪的残余,阴影贴图可能很笨重。

设置light.shadowCameraVisible = true;并调整其他阴影参数,以便该框封装整个场景。