今日份案例是聚光灯和阴影相关案例,在场景中添加平面、小圆柱和聚光灯,当聚光灯照圆柱会在平面上产生阴影。具体效果如下:
首先参照three.js基础案例day01搭建基础环境,下载并引用three.js,接着创建场景、相机、渲染器、控制器。
1.创建平面放在场景中
const planeGeometry = new THREE.PlaneGeometry(40, 40)
const planeMaterial = new THREE.MeshPhongMaterial({
color: 0x808080,
side: THREE.DoubleSide,
})
const plane = new THREE.Mesh(planeGeometry, planeMaterial)
// 将平面旋转
plane.rotation.x = -Math.PI / 2
// 平面位置
plane.position.set(0, -5, 0)
scene.add(plane)
注:添加平面,场景中什么都看不到有可能是太暗,可以添加背景灯
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4)
scene.add(ambientLight)
2. 创建圆柱放在场景中
const cylinderGeometry = new THREE.CylinderGeometry(1, 1, 0.5, 32)
const cylinderMaterial = new THREE.MeshPhongMaterial({ color: 0x408080 })
const cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial)
cylinder.position.set(0, 0, 0)
scene.add(cylinder)
3.添加聚光灯
const spotLight = new THREE.SpotLight(0xffffff, 1)
spotLight.position.set(-10, 10, 0)
// 照射范围
spotLight.angle = Math.PI / 10
// 边界
spotLight.penumbra = 0.2
scene.add(spotLight)
4.设置属性显示阴影
spotLight.castShadow = true
cylinder.castShadow = true
plane.receiveShadow = true
renderer.shadowMap.enabled = true
全部代码
<template>
<div id="threeId" ref="elementRef"></div>
</template>
<script setup>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { ref, onMounted } from 'vue'
let scene, camera, renderer, controls
const elementRef = ref(null)
onMounted(() => {
initScene()
render()
})
function initScene() {
scene = new THREE.Scene()
const planeGeometry = new THREE.PlaneGeometry(40, 40)
const planeMaterial = new THREE.MeshPhongMaterial({
color: 0x808080,
side: THREE.DoubleSide,
})
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4)
scene.add(ambientLight)
const plane = new THREE.Mesh(planeGeometry, planeMaterial)
plane.rotation.x = -Math.PI / 2
plane.position.set(0, -5, 0)
plane.receiveShadow = true
scene.add(plane)
const cylinderGeometry = new THREE.CylinderGeometry(1, 1, 0.5, 32)
const cylinderMaterial = new THREE.MeshPhongMaterial({ color: 0x408080 })
const cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial)
cylinder.position.set(0, 0, 0)
cylinder.castShadow = true
scene.add(cylinder)
camera = new THREE.PerspectiveCamera(
60,
window.innerWidth / window.innerHeight,
1,
1000,
)
camera.position.set(12, 12, 12)
scene.add(camera)
const spotLight = new THREE.SpotLight(0xffffff, 1)
spotLight.position.set(-10, 10, 0)
spotLight.angle = Math.PI / 10
spotLight.penumbra = 0.2
spotLight.castShadow = true
scene.add(spotLight)
renderer = new THREE.WebGLRenderer()
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.shadowMap.enabled = true
elementRef.value.appendChild(renderer.domElement)
controls = new OrbitControls(camera, renderer.domElement)
controls.update()
}
function render() {
requestAnimationFrame(render)
controls.update()
renderer.render(scene, camera)
}
</script>