有没有办法防止自阴影内的面接收光?
Is there a way to prevent faces within self shadow from receiving light?
我正在 Three.js 处理城市场景,到目前为止,我只在一栋建筑物上试验灯光和阴影。该建筑在 3DS Max 中建模,然后导出为 OBJ,然后使用命令行中的 Python 转换器进行转换。
您会注意到建筑物的模型是单个对象,而我正在使用自阴影。然而,位于投射阴影中的建筑物的下部仍然被黄白色的定向光照亮。我猜这是因为它的照明只是根据它面对光源的距离来计算的,而不考虑它和光源之间可能存在的任何东西。
我一直在寻找一种方法来 "correct" 这并使它更逼真,网格会阻止光线照射到它后面的东西,即使是在它自己内部。我需要进入着色器或法线贴图吗?还是完全不同?
此外,这个问题可能是重复的,但没有给出代码或示例,所以我不确定: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();
})();
three.js 或任何其他 'similar' 基于 webgl 的库无法解决您想要做的事情。你想要的是通过 Global Illumination
方法解决的,这在 three.js 的范围之外。
在 three.js r.73 中,阴影是使用近似值实现的:阴影中的区域只是通过您设置的系数变暗:
light.shadowDarkness = 0.33;
因此,如果将 shadowDarkness
设置为 1,问题就会消失。当然,它看起来不太好。
已更新 fiddle:http://jsfiddle.net/u01jwg53/1/
很高兴知道阴影将在 three.js 的未来版本中得到改进。
three.js r.73
我正在 Three.js 处理城市场景,到目前为止,我只在一栋建筑物上试验灯光和阴影。该建筑在 3DS Max 中建模,然后导出为 OBJ,然后使用命令行中的 Python 转换器进行转换。
您会注意到建筑物的模型是单个对象,而我正在使用自阴影。然而,位于投射阴影中的建筑物的下部仍然被黄白色的定向光照亮。我猜这是因为它的照明只是根据它面对光源的距离来计算的,而不考虑它和光源之间可能存在的任何东西。
我一直在寻找一种方法来 "correct" 这并使它更逼真,网格会阻止光线照射到它后面的东西,即使是在它自己内部。我需要进入着色器或法线贴图吗?还是完全不同?
此外,这个问题可能是重复的,但没有给出代码或示例,所以我不确定: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();
})();
three.js 或任何其他 'similar' 基于 webgl 的库无法解决您想要做的事情。你想要的是通过 Global Illumination
方法解决的,这在 three.js 的范围之外。
在 three.js r.73 中,阴影是使用近似值实现的:阴影中的区域只是通过您设置的系数变暗:
light.shadowDarkness = 0.33;
因此,如果将 shadowDarkness
设置为 1,问题就会消失。当然,它看起来不太好。
已更新 fiddle:http://jsfiddle.net/u01jwg53/1/
很高兴知道阴影将在 three.js 的未来版本中得到改进。
three.js r.73