javascript - 去除 collada 对象上的阴影

标签 javascript three.js shadow directional-light

我有一个包含两个 collada 对象和一个定向光的场景。 第一个 collada 几乎是一个平面,第二个是由多个盒子组成的。

似乎在渲染场景时,一些“侧面”阴影确实被剥离了,尽管转换在地面上的阴影渲染得很好。

Here's a screenshot of the shadows .

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

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

我使用的是最新的 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;

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

这是另一个场景 Here's another view of the scene (主要是展示我的灯光设置)。

编辑:这是一个片段:

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>

提前致谢。

最佳答案

您正在获得自阴影,因为定向光的光线与几何体的某些面完全平行。将定向光移动到稍微不同的位置。例如,

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

通常,light.shadow.bias 用于解决自阴影问题,但当光线和面部平行时,它不会有效,就像您的情况一样。

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

directionalLight.shadow.bias = - 0.01;

不幸的是,这通常会导致另一个神器:“Peter Panning”。

这类权衡很常见。您只需要找到一个可以接受的折衷方案。 (也许可以根据相机位置设置偏差。)

three.js r.75

关于javascript - 去除 collada 对象上的阴影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30799206/

相关文章:

javascript - 如何使用 javascript 或 jquery 将整个 html 页面转换为 pdf

javascript - 页面加载后对内容进行排序

javascript - 在 Android 4.4 上获取 Chromium WebView?

ios - 没有边框和阴影的 UITextField

javascript - Zurb 轨道 slider 未加载

javascript - 三个 JS 圆线几何颜色为负值

three.js - JSONLoader vs ObjectLoader,有什么区别? (三.js)

three.js - 片段着色器三js中的抗锯齿

python - Ursina Python 引擎 : Lighting, 阴影和光晕效果

macos - SceneKit:是否可以在透明对象上转换阴影?