【问题标题】:three.js r75 pointLight shadows in wrong placesthree.js r75 pointLight 阴影在错误的地方
【发布时间】:2016-04-19 23:10:32
【问题描述】:

我有一个jsfiddle,其中包含一个固定的太阳和月亮以及一个围绕太阳运行的移动行星地球。

这是两个灯光(环境和点)和示例对象的代码。

        var light2 = new THREE.AmbientLight(0x444444);//... for lighting the Sun and other MeshBasicMaterial meshes.
        scene.add(light2);

        //... PointLight
        //  http://threejs.org/docs/#Reference/Lights/PointLight
        var light3 = new THREE.PointLight( 0xffffff, 10, 150000,1);
        light3.castShadow = true;
        light3.shadow.camera.near = 1;
        light3.shadow.camera.far = 5000;
        light3.shadow.camera.fov = 90;
        // light3.shadowCameraVisible = true;
        light3.shadow.bias = 0.001;
        scene.add( light3 );            

        // SPHERES

        var sphereGeom = new THREE.SphereGeometry( 40, 32, 16 );
var SunMaterial = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
        this.Sun01 = new THREE.Mesh( sphereGeom.clone(), SunMaterial );
        Sun01.position.set(-500, 0, 220);           
        scene.add( Sun01 );
        //Sun01.castShadow = false;
        //Sun01.receiveShadow = false;

        light3.position.set( Sun01.position.x, Sun01.position.y , Sun01.position.z);

var moonMaterial = new THREE.MeshPhongMaterial( { color: 0xaa00aa } );
        var Moon02 = new THREE.Mesh( sphereGeom.clone(), moonMaterial );                
        Moon02.scale.set( 0.5,0.5,0.5 );
        Moon02.position.set(-200, 0, 220);
        scene.add( Moon02 );
        Moon02.castShadow = true;
        Moon02.receiveShadow = false;

有两个问题。

首先遥远的固定卫星即使在射程内也不会被 PointLight 照亮。

其次,来自遥远卫星的阴影出现在(绕太阳运行的)地球上,即使地球比那些固定的卫星更靠近太阳。

请注意,内部固定的月亮(名为 Moon02,颜色为洋红色)确实会被 PointLight 照亮,并且确实会在地球上投下阴影。

这是渲染器设置代码:-

renderer = new THREE.WebGLRenderer();
                renderer.setClearColor( 0x000022 );
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );

                //... Enable Shadows
        renderer.shadowMap.enabled = true;//.shadowMapEnabled = true;
        //renderer.shadowMap.type    = THREE.BasicShadowMap;//
                //renderer.shadowMap.type    = THREE.PCFShadowMap
            renderer.shadowMap.type    = THREE.PCFSoftShadowMap;

我的问题 = 需要做什么来 (a) 照亮外层卫星并 (b) 确保外层卫星的阴影不会出现在(内部,更靠近太阳的)地球上。

【问题讨论】:

    标签: three.js shadow


    【解决方案1】:

    简单地说,你把事情间隔得太远了。

    从点光源计算阴影非常昂贵。事实上,THREE.js 只是为它添加了功能a few months ago。我在文档中还没有找到任何可靠的东西,但似乎对从点光源计算出的阴影有多远有硬编码限制。

    解决方案很简单:减少对象之间的空间。当十几个就足够时,绝对没有理由让物体彼此相距数千个单位。我解决了你的两个问题just by reducing all distances and scales by a factor of 10. 我还调整了 PointLight 的强度,因为 10 太苛刻了哈哈。

    // color, intensity, falloff radius, falloff amount
    // if falloff radius is 0 then there is no falloff
    var light3 = new THREE.PointLight( 0xffffff, 1, 0, 0);
    

    【讨论】:

    • “当十几个就足够时,绝对没有理由让对象彼此相距数千个单位”但我的应用程序不是一件艺术品 - 它是科学的,引入人工距离单位是不可取。 “将所有距离和比例缩小 10 倍”是一件大事。我不明白为什么three.js 应该有大距离的问题。但是感谢(希望是暂时的)解决方法:-)。
    • @steveOw 好吧,距离是任意的。即使你的应用程序是科学的,你也可以在 THREE.js 中使用你想要的任何单位,因为在它们之间转换很简单。如果它可以帮助您保持实际距离的心智模型,然后除以 1,000 之类的干净数字,并以数百万米而不是数百万公里(或其他)的形式思考。
    • 另外,一般来说,THREE.js 远距离没有太大问题,我觉得只有 PointLight 给你带来了麻烦。向各个方向投射光影是很困难的,因为投射的“光线”是距离的平方,所以它们只能走这么远。相比之下,DirectionalLight 不会散开,它的光线永远是平行的,这更容易计算。可能存在某种未记录的“比例因子”,您可以对其进行调整而不是更改其他所有内容,但我不知道有一个。
    • 按照您的想法,我刚刚在three.js github 中找到了这个 - “在点光阴影贴图代码中,我们应用了 1 / 1000 的比例因子......”。看来这是我问题的根源。
    猜你喜欢
    • 2013-06-11
    • 2018-04-23
    • 2012-06-10
    • 1970-01-01
    • 2015-03-27
    • 1970-01-01
    • 2017-08-29
    • 2016-06-21
    • 1970-01-01
    相关资源
    最近更新 更多