Skip to content

灯光与阴影的设置

代码

js
// 导入 threejs
import * as THREE from 'three'
// 导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
// 导入 lil.gui
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';
// 导入 hdr 加载器
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
// 导入 gltf 加载器
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
// 导入 draco 解码器
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';

/**
 * 目标:灯光与阴影
 * 灯光阴影
 * 1. 材质要满足能够对光照有反应
 * 2. 设置渲染器开启阴影的计算 renderer.shadowMap.enabled = true;
 * 3. 设置光照投射阴影 directionalLight.castShadow = true
 * 4. 设置物体投射阴影 sphere.castShadow = true
 * 5. 设置物体接收阴影 plane.receiverShadow = true
 */

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
)

const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.shadowMap.enabled = true
document.body.appendChild(renderer.domElement)

camera.position.z = 20;
camera.position.y = 2;
camera.position.x = 2;
camera.lookAt(0, 0, 0)

const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);

const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;

// 创建一个球,并添加到场景中
const sphereGeometry = new THREE.SphereGeometry(1, 20, 20);
const material = new THREE.MeshStandardMaterial()
const sphere = new THREE.Mesh(sphereGeometry, material)
// 投射阴影
sphere.castShadow = true
scene.add(sphere)


// 创建平面
const planeGeometry = new THREE.PlaneGeometry(10, 10);
const plane = new THREE.Mesh(planeGeometry, material)
plane.position.set(0, -1, 0)
plane.rotation.x = -Math.PI / 2
// 接收阴影
plane.receiveShadow = true
scene.add(plane)

// 灯光
const light = new THREE.AmbientLight(0xffffff, 0.5)
scene.add(light)

// 直线光源
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5)
directionalLight.position.set(20, 10, 10)
directionalLight.castShadow = true
scene.add(directionalLight)

// 渲染函数
function animate() {
  controls.update()
  renderer.render(scene, camera)
}

animate()

// 监听窗口变化
window.addEventListener('resize', () => {
  // 重置渲染器宽高比
  renderer.setSize(window.innerWidth, innerHeight)
  // 重置相机宽高比
  camera.aspect = window.innerWidth / window.innerHeight
  // 更新相机投影矩阵
  camera.updateProjectionMatrix()
})

let eventObj = {
  Fullscreen: function () {
    document.body.requestFullscreen()
  },
  ExitFullscreen: function () {
    document.exitFullscreen()
  }
}

// 创建GUI
const gui = new GUI()
// 添加按钮
gui.add(eventObj, 'Fullscreen').name('全屏')
gui.add(eventObj, 'ExitFullscreen').name('退出全屏')

Released under the MIT License.