有没有办法防止自我阴影中的面部接收光线?

时间:2015-11-15 23:19:12

标签: javascript three.js lighting shadows

我正在Three.js的一个城市场景工作,到目前为止,我正在一个建筑物上尝试照明和阴影。该建筑物在3DS Max中建模,然后导出到OBJ,然后从命令行使用Python转换器进行转换。

您会注意到建筑物的模型是单个物体,我正在使用自阴影。然而,位于投射阴影内的建筑物的下部仍然被黄白色定向光照亮。我猜这是因为它的照度只是根据它面对光源的程度来计算,而不考虑它与光源之间可能存在的任何问题。

我一直在寻找一种方法来“纠正”这个并使其更加逼真,其中网格会阻挡光线击中它背后的东西,甚至在它自身内部。我是否需要进入着色器或法线贴图?或完全不同的东西?

此外,这个问题可能是重复的,但没有给出任何代码或示例,所以我不确定:Light penetrating through meshes。如果这是一个问题,请提前抱歉。

JSFiddle在这里:http://jsfiddle.net/mrfolkblues/u01jwg53/

代码的相关部分是:

var T = THREE,
    stats,
    container,
    camera = new T.PerspectiveCamera(40, window.innerWidth/window.innerHeight, 0.1, 200),
    scene = new T.Scene(),
    renderer = new T.WebGLRenderer({
        antialias: true
    }),
    radius = 35, theta = 0, thetaDelta = 0, camtarget,
    boundingbox, cube, plane, poly, polyMesh, sphere, line,
    clock = new T.Clock();

    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFShadowMap;

// construct
(function(){

    container = document.createElement( 'div' );
    document.body.appendChild( container );

    // set up renderer
    renderer.setClearColor( 0xf0f0f0 );
    renderer.setSize( window.innerWidth, window.innerHeight );
    container.appendChild(renderer.domElement);

    var light = new T.DirectionalLight( 0xfff3cb, 1.25 );
    light.position.set( 60, 25, 40 );

    var light2 = new T.DirectionalLight( 0x204fae, 1.25 );
    light2.position.set( -30, 40, 0 );

    light.castShadow = true;
    light.shadowDarkness = 0.33;
    light.shadowCameraTop = 20;
    light.shadowCameraRight = 20;
    light.shadowCameraBottom = -20;
    light.shadowCameraLeft = -20;
    light.shadowCameraNear = 0;
    light.shadowCameraFar = 200;
    light.shadowMapWidth = 2048;
    light.shadowMapHeight = 2048;
    light.shadowBias = 0.0002;

    scene.add( light );
    scene.add( light2 );

    var cube = createCube([0.5, 0.5, 0.5], [1.5, 10, 0]);

    // position camera
    camera.position.x = 0;
    camera.position.y = 20; // move camera position up
    camera.position.z = radius; // move camera out
    camtarget = cube.position;
    camera.lookAt( camtarget );

    createPlane();

    var loader = new T.JSONLoader();
    var parsed = loader.parse(window.buildingModel);

    var material = new T.MeshLambertMaterial( {
        color: 0xffffff
    } );

    var object = new THREE.Mesh( parsed.geometry, material );
    object.castShadow = true;
    object.receiveShadow = true;
    scene.add( object );

    object.position.x = 30;
    object.position.y = 0;
    object.position.z = 15;

    // add event listeners
    window.addEventListener( 'resize', onWindowResize, false );

    render();
    animate();
})();

2 个答案:

答案 0 :(得分:0)

你想做什么并不是由three.js或任何其他类似的'解决的。基于webgl的库在那里。你想要的是由Global Illumination方法解决的,这些方法超出了three.js的范围。

答案 1 :(得分:0)

在three.js r.73中,使用近似值实现阴影:阴影中的区域仅由您设置的因子变暗:

light.shadowDarkness = 0.33;

因此,如果将shadowDarkness设置为1,则问题就会消失。当然,它看起来不太好。

更新了小提琴:http://jsfiddle.net/u01jwg53/1/

请注意,在将来的three.js版本中,阴影会得到改善。

three.js r.73