使用three.js真的很奇怪的鬼影阴影 [英] really weird ghosty shadows using three.js

查看:326
本文介绍了使用three.js真的很奇怪的鬼影阴影的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用three.js制作一些太阳系,我所有的对象都是球体(太阳和行星),但是我发现这确实很奇怪且幽灵的正方形阴影:

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:

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

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?

非常感谢!

------另一个问题------

------one more question------

所有yaku所说的作品!

All yaku said works!

但是我发现球体本身没有阴影.

But I found out there's no shadows of the spheres themselves.

我打电话给

mesh.castShadow = mesh.receiveShadow = true;

每次创建球体时.

我记得现在这些阴影消失了...

I remember there were these shadows now they are gone...

这可能是什么原因?

谢谢!

推荐答案

不确定,但是您检查过阴影摄像机的尺寸吗?似乎阴影摄像机的截锥体可能太小,您所看到的可能是截锥体内部的所有物体都处于阴影中,其余部分均不受影响.浅色正方形可能是阴影摄像机的一部分怪异物,阴影贴图可能很笨拙.

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..

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

Set light.shadowCameraVisible = true; and adjust the other shadow parameters so that the box encapsulates the whole scene.

这篇关于使用three.js真的很奇怪的鬼影阴影的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆