【问题标题】:three.js: Casting SpotLight Shadowsthree.js:投射 SpotLight 阴影
【发布时间】:2021-04-17 21:14:25
【问题描述】:

全部。

我正在使用three.js 127,按照文档添加SpotLight。但是,阴影不会出现在场景中。下面,你可以找到我的场景。我已经将平面设置为接收阴影以及启用投射阴影的其他元素,但场景上没有渲染阴影。

const canvas = document.getElementById('webgl-output')

const init = () => {
  const scene = new THREE.Scene()
  const camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    0.1,
    1000,
  )
  const renderer = new THREE.WebGLRenderer({
    canvas,
  })
  renderer.setClearColor(new THREE.Color(0x000000))
  renderer.setSize(window.innerWidth, window.innerHeight)

  const planeGeometry = new THREE.PlaneGeometry(60, 20)
  const planeMaterial = new THREE.MeshLambertMaterial({
    color: 0xaaaaaa,
  })

  const plane = new THREE.Mesh(planeGeometry, planeMaterial)
  plane.receiveShadow = true
  plane.rotation.x = -0.5 * Math.PI
  plane.position.x = 15
  plane.position.y = 0
  plane.position.z = 0
  scene.add(plane)

  // Creating a cube
  const cubeGeometry = new THREE.BoxGeometry(4, 4, 4)
  const cubeMaterial = new THREE.MeshLambertMaterial({
    color: 0xff0000,
  })
  const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
  cube.castShadow = true
  cube.position.x = -4
  cube.position.y = 3
  cube.position.z = 0
  scene.add(cube)

  // Creating a sphere
  const sphereGeometry = new THREE.SphereGeometry(4, 20, 20)
  const sphereMaterial = new THREE.MeshLambertMaterial({
    color: 0x7777ff,
  })
  const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
  sphere.castShadow = true
  sphere.position.x = 20
  sphere.position.y = 4
  sphere.position.z = 2
  scene.add(sphere)

  // Position and point the camera to the center of the scene
  camera.position.x = -30
  camera.position.y = 12
  camera.position.z = 30
  camera.lookAt(scene.position)

  // Add spotlight for the shadows
  const spotLight = new THREE.SpotLight(0xffffff)
  spotLight.position.set(8, 40, 80)

  spotLight.castShadow = true

  spotLight.shadow.mapSize.width = 1024
  spotLight.shadow.mapSize.height = 1024

  spotLight.shadow.camera.near = 8
  spotLight.shadow.camera.far = 80
  spotLight.shadow.camera.fov = 16

  scene.add(spotLight)

  renderer.render(scene, camera)
}

init()

我是否遗漏了一些东西来渲染阴影?

【问题讨论】:

    标签: three.js


    【解决方案1】:

    我从您的代码中注意到一些可能导致此问题的情况:

    1. 最大的问题是您没有在渲染器上启用 shadowMap,您可以这样做:
    renderer.shadowMap.enabled = true;
    

    这部分似乎没有出现在您链接的 SpotLight 文档中,更多信息可以在 SpotLightShadow 的文档中找到。

    1. 在 JS 沙箱上尝试后,我仍然没有看到阴影,但似乎聚光灯离得太远了,它的“z”位置设置为 80。我把这个值稍微小了一点(40),它似乎可以解决问题。帮助我解决问题的是使用帮助程序和 OrbitControls,这使得调试变得更容易:
    import { OrbitControls } from 'https://cdn.jsdelivr.net/npm/three@0.127/examples/jsm/controls/OrbitControls.js';
    ...
    
    spotLight.position.set(8, 40, 40); // Third parameter (z) with value of 80 was too far away
    
    controls = new OrbitControls(camera, renderer.domElement);
    helper = new THREE.PointLightHelper(pointLight);
    scene.add(helper);
    

    这里是一个固定版本的JSFiddle:https://jsfiddle.net/tombugolya/hx61L5vp/17/

    【讨论】:

    • 感谢您的回答。我只是按照您的解决方案修复了它。我只是在学习three.js。谢谢。
    • 乐于助人!祝你学习顺利。如果您能接受我的回答,认为这是可以提高我的代表的最佳答案,谢谢 :)
    • 我刚做了。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2016-06-21
    • 1970-01-01
    • 2013-08-03
    • 2017-12-12
    • 1970-01-01
    • 2019-01-14
    • 1970-01-01
    相关资源
    最近更新 更多