Раздетые тени на объектах коллада
У меня есть сцена с двумя объектами коллада и направленным светом. Первая коллада - в значительной степени плоскость, а вторая состоит из нескольких коробок.
Похоже, что при рендеринге сцены некоторые "боковые" тени действительно удаляются, хотя отбрасываемые на землю тени довольно хорошо отображаются.
,
Когда я искал ответ, я понял, что это может быть проблемой с моей колладой, поэтому я добавил базовый куб в сцену (большой прежде всего), но, похоже, у него та же проблема.
Кто-нибудь есть совет или уже знает эту проблему?
Я использую последнюю редакцию three.js atm (r71), протестированную в Google Chrome и Mozilla Firefox (MacOS). Я уже пытался настроить почти все атрибуты shadow* направленного света, за исключением тех, которые связаны с shadowCascade (который я не использую). Я также проверил, чтобы настроить атрибуты рендерера, связанные с тенями.
Вот мои настройки освещения:
var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );
directionalLight.target.position = THREE.Vector3(0, 0, 0);
directionalLight.position.set( 250, 500, 250 );
directionalLight.castShadow = true;
directionalLight.shadowCameraNear = 100;
directionalLight.shadowCameraFar = 1000;
directionalLight.shadowMapWidth = 2048;
directionalLight.shadowMapHeight = 2048;
directionalLight.shadowBias = 0.0001;
directionalLight.shadowDarkness = 0.5;
directionalLight.shadowCameraLeft = -300;
directionalLight.shadowCameraRight = 300;
directionalLight.shadowCameraTop = 300;
directionalLight.shadowCameraBottom = -300;
directionalLight.shadowCameraVisible = true;
Мои объекты коллада довольно большие, как и границы теневой камеры.
Моя настройка рендерера:
renderer = new THREE.WebGLRenderer( {antialias: true} );
renderer.setClearColor(0x222222);
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
renderer.shadowMapType = THREE.PCFSoftShadowMap;
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
Вот еще один вид сцены (в основном показывает мои настройки освещения).
РЕДАКТИРОВАТЬ: Вот фрагмент:
var container;
var camera, scene, renderer, controls;
var particleLight;
scene = new THREE.Scene();
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.set( 300, 100, 0 );
// Controls
controls = new THREE.OrbitControls( camera );
// Cube
var geometry = new THREE.BoxGeometry( 100, 100, 100 );
var material = new THREE.MeshLambertMaterial();
var cube = new THREE.Mesh( geometry, material );
cube.position.y = 50;
cube.rotation.y = 0.8;
cube.castShadow = true;
cube.receiveShadow = true;
scene.add( cube );
// Plane
var planeGeometry = new THREE.PlaneBufferGeometry( 300, 300, 300 );
var plane = new THREE.Mesh( planeGeometry, material );
plane.position.set( 0, 0, 0 );
plane.rotation.x = -1.6;
plane.castShadow = true;
plane.receiveShadow = true;
scene.add( plane );
// Light
var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );
directionalLight.target.position = THREE.Vector3(0, 0, 0);
directionalLight.position.set( 250, 500, 250 );
directionalLight.castShadow = true;
directionalLight.shadowCameraNear = 100;
directionalLight.shadowCameraFar = 1000;
directionalLight.shadowMapWidth = 2048;
directionalLight.shadowMapHeight = 2048;
directionalLight.shadowBias = 0.0001;
directionalLight.shadowDarkness = 0.5;
directionalLight.shadowCameraLeft = -300;
directionalLight.shadowCameraRight = 300;
directionalLight.shadowCameraTop = 300;
directionalLight.shadowCameraBottom = -300;
directionalLight.shadowCameraVisible = true;
scene.add( directionalLight );
scene.add( new THREE.AmbientLight( 0x555555 ) );
renderer = new THREE.WebGLRenderer( {antialias: true} );
renderer.setClearColor(0x222222);
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
renderer.shadowMapType = THREE.PCFSoftShadowMap;
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
render();
}
var clock = new THREE.Clock();
function render() {
var timer = Date.now() * 0.0005;
camera.lookAt(new THREE.Vector3(0, 0, 0));
renderer.render( scene, camera );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>
<script src="http://threejs.org/examples/js/controls/OrbitControls.js"></script>
Заранее спасибо.
1 ответ
Вы получаете самозатенение, потому что лучи направленного света точно параллельны некоторым граням вашей геометрии. Переместите направленный свет в немного другое место. Например,
directionalLight.position.set( 250, 500, 200 );
Обычно, light.shadow.bias
используется для устранения проблем самозатенения, но он не будет эффективным, когда луч света и лицо параллельны, как в вашем случае.
Также установите shadow.bias
быть отрицательным, чтобы помочь смягчить артефакты на других лицах.
directionalLight.shadow.bias = - 0.01;
Это, к сожалению, приведет, как обычно, к другому артефакту: "Питер Паннинг".
Эти виды компромиссов являются общими. Вам просто нужно найти приемлемый компромисс. (Может быть, установить смещение в зависимости от положения камеры.)
three.js r.75