繁体   English   中英

three.js:投射聚光灯阴影

[英]three.js: Casting SpotLight Shadows

全部。

我正在使用 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()

我错过了一些东西来渲染阴影吗?

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

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

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

  1. 在 JS 沙箱上尝试此操作后,我仍然没有看到阴影,但似乎聚光灯太远了,它在它的“z”position 处设置为 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/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM