阴影 / 平行光
<template>
<div id="webgl"></div>
</template>
<script setup>
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
const scene = new THREE.Scene();
const sphereGemometry = new THREE.SphereGeometry(1, 20, 20)
const material = new THREE.MeshStandardMaterial()
const sphere = new THREE.Mesh(sphereGemometry, material)
sphere.castShadow = true
scene.add(sphere)
const planeGeometry = new THREE.PlaneGeometry(50, 50)
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 directionalLight = new THREE.DirectionalLight(0xffffff, 0.9)
directionalLight.position.set(5, 5, 5)
directionalLight.castShadow = true
scene.add(directionalLight)
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 10);
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true
document.body.appendChild(renderer.domElement);
renderer.render(scene, camera);
const controls = new OrbitControls(camera, renderer.domElement);
function render(time) {
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render()
</script>
阴影模糊
directionalLight.shadow.radius = 20
directionalLight.shadow.mapSize.set(4096, 4096)
设置投影相机
directionalLight.shadow.camera.near = 0.5
directionalLight.shadow.camera.far = 500
directionalLight.shadow.camera.top = 5
directionalLight.shadow.camera.bottom = -5
directionalLight.shadow.camera.left = -5
directionalLight.shadow.camera.right = 5
const gui = new GUI();
gui.add(directionalLight.shadow.camera,"near").min(0).max(10).step(0.1).onChange(()=>{
directionalLight.shadow.camera.updateProjectionMatrix()
})
聚光灯(手电)
const spotLight = new THREE.SpotLight(0xffffff, 1);
spotLight.position.set(5, 5, 5)
spotLight.castShadow = true
spotLight.shadow.radius = 20
spotLight.shadow.mapSize.set(4096, 4096)
spotLight.target = sphere
spotLight.intensity = 2
spotLight.target = sphere
spotLight.angle = Math.PI / 6
spotLight.distance = 0
spotLight.penumbra = 0
spotLight.decay = 0
scene.add(spotLight);
const spotLightHelper = new THREE.SpotLightHelper( spotLight );
scene.add( spotLightHelper );
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
const gui = new GUI();
gui.add(sphere.position, "x").min(-5).max(5).step(0.1)
gui.add(spotLight, "angle").min(0).max(Math.PI / 2).step(0.01)
gui.add(spotLight, "distance").min(0).max(10).step(0.01)
gui.add(spotLight, "penumbra").min(0).max(1).step(0.01)
gui.add(spotLight, "decay").min(0).max(5).step(0.01)
点光源
const pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.position.set(1, 1, 1)
pointLight.castShadow = true
scene.add(pointLight);
const sphereSize = 1;
const pointLightHelper = new THREE.PointLightHelper( pointLight, sphereSize );
scene.add( pointLightHelper );
点光源还可以直接添加在物体上面(实现小球围绕着大球旋转)
<template>
<div id="webgl"></div>
</template>
<script setup>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
const gui = new GUI();
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.set(0, 0, 10)
scene.add(camera)
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(50, 50)
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 smallBall = new THREE.Mesh(
new THREE.SphereGeometry(0.1, 20, 20),
new THREE.MeshBasicMaterial({ color: 0xff0000 })
)
smallBall.position.set(2, 2, 2)
const pointLight = new THREE.PointLight(0xff0000, 1);
pointLight.castShadow = true
pointLight.shadow.radius = 20
pointLight.shadow.mapSize.set(512, 512);
smallBall.add(pointLight)
scene.add(smallBall);
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.shadowMap.enabled = true
renderer.physicallyCorrectLights = true
document.body.appendChild(renderer.domElement)
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)
const clock = new THREE.Clock()
function render () {
let time = clock.getElapsedTime()
smallBall.position.x = Math.sin(time) * 3
smallBall.position.z = Math.cos(time) * 3
smallBall.position.y = 2 + Math.sin(time * 10) / 2
controls.update()
renderer.render(scene, camera);
requestAnimationFrame(render)
}
render()
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setPixelRatio(window.devicePixelRatio)
})
</script>