collada 对象上的剥离阴影 [英] Stripped shadows on collada objects

查看:19
本文介绍了collada 对象上的剥离阴影的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个场景,其中包含两个 collada 对象和一个定向灯.第一个collada几乎是一架飞机,第二个是由多个盒子组成的.

看起来在渲染场景时,一些侧面"阴影确实被剥离了,尽管投射在地面上的阴影渲染得很好.

.

当我在寻找答案时,我发现这可能是我的 collada 的问题,所以我在场景中添加了一个基本的立方体(最重要的一个),但它似乎有同样的问题.

有没有人有提示或已经知道这个问题?

我使用的是最新的three.js 修订版atm (r71),在Google Chrome 和Mozilla Firefox (MacOS) 上进行了测试.我已经尝试调整了几乎所有平行光的 shadow* 属性,除了与 shadowCascade 相关的那些(我不使用).我还测试了调整阴影相关渲染器的属性.

这是我的灯光设置:

var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );directionLight.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;方向光.shadowDarkness = 0.5;directionalLight.shadowCameraLeft = -300;directionalLight.shadowCameraRight = 300;directionalLight.shadowCameraTop = 300;directionalLight.shadowCameraBottom = -300;directionalLight.shadowCameraVisible = true;

我的 collada 对象有点大,我的 shadowCamera 边界也是如此.

我的渲染器设置:

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 容器;var 相机、场景、渲染器、控件;var 粒子光;场景 = 新的 THREE.Scene();在里面();动画();函数初始化(){容器 = document.createElement('div');document.body.appendChild(容器);camera = new THREE.PerspectiveCamera( 45, window.innerWidth/window.innerHeight, 1, 2000 );相机位置设置( 300, 100, 0 );//控件控件 = 新的 THREE.OrbitControls(camera);//立方体var geometry = new THREE.BoxGeometry(100, 100, 100);var material = new THREE.MeshLambertMaterial();var cube = new THREE.Mesh(几何,材质);立方体.位置.y = 50;立方体.旋转.y = 0.8;立方体.castShadow = true;立方体.receiveShadow = true;场景添加(立方体);//飞机var planeGeometry = new THREE.PlaneBufferGeometry(300, 300, 300);var plane = new THREE.Mesh(planeGeometry, material);平面.位置.set( 0, 0, 0 );平面.旋转.x = -1.6;plane.castShadow = 真;平面.receiveShadow = true;场景添加(平面);//光var directionalLight = new THREE.DirectionalLight( 0xffffff, 1 );directionLight.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;方向光.shadowDarkness = 0.5;directionalLight.shadowCameraLeft = -300;directionalLight.shadowCameraRight = 300;directionalLight.shadowCameraTop = 300;directionalLight.shadowCameraBottom = -300;directionalLight.shadowCameraVisible = true;场景添加(定向光);场景.添加(新三.环境光(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 );}函数 onWindowResize() {camera.aspect = window.innerWidth/window.innerHeight;相机.updateProjectionMatrix();renderer.setSize( window.innerWidth, window.innerHeight );}函数动画(){requestAnimationFrame( 动画 );使成为();}var clock = new THREE.Clock();函数渲染(){var timer = Date.now() * 0.0005;camera.lookAt(new THREE.Vector3(0, 0, 0));renderer.render(场景,相机);}

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

提前致谢.

解决方案

由于平行光的光线与几何体的某些面完全平行,因此会出现自阴影.将定向光移动到稍微不同的位置.例如,

directionalLight.position.set( 250, 500, 200 );

通常,light.shadow.bias 用于修复自阴影问题,但是当光线和面平行时,它不会有效,就像您的情况.>

此外,将 shadow.bias 设置为负值以帮助减轻其他面孔上的伪影.

directionalLight.shadow.bias = - 0.01;

不幸的是,这通常会导致另一个工件:彼得潘宁".

这些类型的权衡很常见.你只需要找到一个可以接受的妥协.(也许根据相机位置设置偏差.)

three.js r.75

I have a scene with two collada objects and a directional light. The first collada is pretty much a plane, and the second one is made of multiple boxes.

It appears that when the scene is rendered, some "side" shadows are really stripped, although the shadows casted on ground are pretty well rendered.

.

As I was searching for an answer, I figured out it might be a problem with my collada, so I added a basic cube to the scene (the big one above all), but it seems it has the same problem.

Does anyone have a tip or know this problem already?

I'm using the last three.js revision atm (r71), tested on Google Chrome and Mozilla Firefox (MacOS). I already tried to tweak pretty much all the shadow* attributes of the directional light, except the ones related with shadowCascade (which I don't use). I also tested to tweak shadow-related renderer's attributes.

Here's my light setup:

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;

My collada objects are kind of big, so are my shadowCamera bounds.

My renderer setup:

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 );

Here's another view of the scene (mostly showing my light setup).

EDIT: Here's a snippet:

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>

Thanks in advance.

解决方案

You are getting self-shadowing because the rays of the directional light are exactly parallel to some of the faces of your geometry. Move the directional light to a slightly different location. For example,

directionalLight.position.set( 250, 500, 200 );

Usually, light.shadow.bias is used to remedy self-shadowing problems, but it is not going to be effective when the light ray and face are parallel, as in your case.

Also, set shadow.bias to be negative to help alleviate artifacts on other faces.

directionalLight.shadow.bias = - 0.01;

This unfortunately will result, as it usually does, in another artifact: "Peter Panning".

These kinds of trade-offs are common. You are just going to have to find an acceptable compromise. (Maybe set the bias based on camera position.)

three.js r.75

这篇关于collada 对象上的剥离阴影的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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