前言
在3D场景中,阴影扮演着至关重要的角色。如果没有阴影,整个场景看起来会非常不真实。因此,阴影是营造出真实感和深度感的关键因素之一。
在本文中,我们就来看看,在THREE.JS 中如何实现阴影效果。
阴影实现步骤
目标:灯光阴影
- 材质要满足能够对光照有反应 (不受光照影响的材质:MeshBasicMaterial)
- 设置渲染器开启阴影的计算
renderer.shadowMap.enabled = true
- 设置光照投射阴影
directionalLight.castShadow = true
- 设置物体投射阴影
sphere.castShadow = true
- 设置物体接收阴影
plane.receiveShadow = true
下面,我们通过一个小demo来看看效果:
1. 创建场景和相机
// 1、创建场景const scene = new THREE.Scene();// 2、创建相机const camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000);// 设置相机位置camera.position.set(0, 0, 10);scene.add(camera);// 1、创建场景 const scene = new THREE.Scene(); // 2、创建相机 const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); // 设置相机位置 camera.position.set(0, 0, 10); scene.add(camera);// 1、创建场景 const scene = new THREE.Scene(); // 2、创建相机 const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); // 设置相机位置 camera.position.set(0, 0, 10); scene.add(camera);
2. 开启渲染器阴影投射 --renderer.shadowMap.enabled = true;
// 初始化渲染器const renderer = new THREE.WebGLRenderer();// 设置渲染的尺寸大小renderer.setSize(window.innerWidth, window.innerHeight);// 开启场景中的阴影贴图renderer.shadowMap.enabled = true;// 初始化渲染器 const renderer = new THREE.WebGLRenderer(); // 设置渲染的尺寸大小 renderer.setSize(window.innerWidth, window.innerHeight); // 开启场景中的阴影贴图 renderer.shadowMap.enabled = true;// 初始化渲染器 const renderer = new THREE.WebGLRenderer(); // 设置渲染的尺寸大小 renderer.setSize(window.innerWidth, window.innerHeight); // 开启场景中的阴影贴图 renderer.shadowMap.enabled = true;
3. 设置光照投射阴影 --directionalLight.castShadow = true;
//直线光源const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);directionalLight.position.set(10, 10, 10);directionalLight.castShadow = true;scene.add(directionalLight);//直线光源 const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); directionalLight.position.set(10, 10, 10); directionalLight.castShadow = true; scene.add(directionalLight);//直线光源 const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); directionalLight.position.set(10, 10, 10); directionalLight.castShadow = true; scene.add(directionalLight);
4. 创建一个小球并设置投射阴影 --sphere.castShadow = true;
const sphereGeometry = new THREE.SphereBufferGeometry(1, 20, 20);const material = new THREE.MeshStandardMaterial();const sphere = new THREE.Mesh(sphereGeometry, material);// 投射阴影sphere.castShadow = true;scene.add(sphere);const sphereGeometry = new THREE.SphereBufferGeometry(1, 20, 20); const material = new THREE.MeshStandardMaterial(); const sphere = new THREE.Mesh(sphereGeometry, material); // 投射阴影 sphere.castShadow = true; scene.add(sphere);const sphereGeometry = new THREE.SphereBufferGeometry(1, 20, 20); const material = new THREE.MeshStandardMaterial(); const sphere = new THREE.Mesh(sphereGeometry, material); // 投射阴影 sphere.castShadow = true; scene.add(sphere);
5. 创建一个平面并设置接收阴影 --plane.receiveShadow = true;
// // 创建平面const planeGeometry = new THREE.PlaneBufferGeometry(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 planeGeometry = new THREE.PlaneBufferGeometry(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 planeGeometry = new THREE.PlaneBufferGeometry(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);
效果:
完整代码:
import * as THREE from "three";// 导入轨道控制器import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";// 导入动画库import gsap from "gsap";// 导入dat.guiimport * as dat from "dat.gui";import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";// 目标:// 灯光阴影// 1、材质要满足能够对光照有反应// 2、设置渲染器开启阴影的计算 renderer.shadowMap.enabled = true;// 3、设置光照投射阴影 directionalLight.castShadow = true;// 4、设置物体投射阴影 sphere.castShadow = true;// 5、设置物体接收阴影 plane.receiveShadow = true;// 1、创建场景const scene = new THREE.Scene();// 2、创建相机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.SphereBufferGeometry(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.PlaneBufferGeometry(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); // soft white lightscene.add(light);//直线光源const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);directionalLight.position.set(10, 10, 10);directionalLight.castShadow = true;scene.add(directionalLight);// 初始化渲染器const renderer = new THREE.WebGLRenderer();// 设置渲染的尺寸大小renderer.setSize(window.innerWidth, window.innerHeight);// 开启场景中的阴影贴图renderer.shadowMap.enabled = true;// console.log(renderer);// 将webgl渲染的canvas内容添加到bodydocument.body.appendChild(renderer.domElement);// // 使用渲染器,通过相机将场景渲染进来// renderer.render(scene, camera);// 创建轨道控制器const controls = new OrbitControls(camera, renderer.domElement);// 设置控制器阻尼,让控制器更有真实效果,必须在动画循环里调用.update()。controls.enableDamping = true;// 添加坐标轴辅助器const axesHelper = new THREE.AxesHelper(5);scene.add(axesHelper);// 设置时钟const clock = new THREE.Clock();function render() {controls.update();renderer.render(scene, camera);// 渲染下一帧的时候就会调用render函数requestAnimationFrame(render);}render();// 监听画面变化,更新渲染画面window.addEventListener("resize", () => {// console.log("画面变化了");// 更新摄像头camera.aspect = window.innerWidth / window.innerHeight;// 更新摄像机的投影矩阵camera.updateProjectionMatrix();// 更新渲染器renderer.setSize(window.innerWidth, window.innerHeight);// 设置渲染器的像素比renderer.setPixelRatio(window.devicePixelRatio);});import * as THREE from "three"; // 导入轨道控制器 import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; // 导入动画库 import gsap from "gsap"; // 导入dat.gui import * as dat from "dat.gui"; import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader"; // 目标: // 灯光阴影 // 1、材质要满足能够对光照有反应 // 2、设置渲染器开启阴影的计算 renderer.shadowMap.enabled = true; // 3、设置光照投射阴影 directionalLight.castShadow = true; // 4、设置物体投射阴影 sphere.castShadow = true; // 5、设置物体接收阴影 plane.receiveShadow = true; // 1、创建场景 const scene = new THREE.Scene(); // 2、创建相机 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.SphereBufferGeometry(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.PlaneBufferGeometry(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); // soft white light scene.add(light); //直线光源 const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); directionalLight.position.set(10, 10, 10); directionalLight.castShadow = true; scene.add(directionalLight); // 初始化渲染器 const renderer = new THREE.WebGLRenderer(); // 设置渲染的尺寸大小 renderer.setSize(window.innerWidth, window.innerHeight); // 开启场景中的阴影贴图 renderer.shadowMap.enabled = true; // console.log(renderer); // 将webgl渲染的canvas内容添加到body document.body.appendChild(renderer.domElement); // // 使用渲染器,通过相机将场景渲染进来 // renderer.render(scene, camera); // 创建轨道控制器 const controls = new OrbitControls(camera, renderer.domElement); // 设置控制器阻尼,让控制器更有真实效果,必须在动画循环里调用.update()。 controls.enableDamping = true; // 添加坐标轴辅助器 const axesHelper = new THREE.AxesHelper(5); scene.add(axesHelper); // 设置时钟 const clock = new THREE.Clock(); function render() { controls.update(); renderer.render(scene, camera); // 渲染下一帧的时候就会调用render函数 requestAnimationFrame(render); } render(); // 监听画面变化,更新渲染画面 window.addEventListener("resize", () => { // console.log("画面变化了"); // 更新摄像头 camera.aspect = window.innerWidth / window.innerHeight; // 更新摄像机的投影矩阵 camera.updateProjectionMatrix(); // 更新渲染器 renderer.setSize(window.innerWidth, window.innerHeight); // 设置渲染器的像素比 renderer.setPixelRatio(window.devicePixelRatio); });import * as THREE from "three"; // 导入轨道控制器 import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; // 导入动画库 import gsap from "gsap"; // 导入dat.gui import * as dat from "dat.gui"; import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader"; // 目标: // 灯光阴影 // 1、材质要满足能够对光照有反应 // 2、设置渲染器开启阴影的计算 renderer.shadowMap.enabled = true; // 3、设置光照投射阴影 directionalLight.castShadow = true; // 4、设置物体投射阴影 sphere.castShadow = true; // 5、设置物体接收阴影 plane.receiveShadow = true; // 1、创建场景 const scene = new THREE.Scene(); // 2、创建相机 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.SphereBufferGeometry(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.PlaneBufferGeometry(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); // soft white light scene.add(light); //直线光源 const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); directionalLight.position.set(10, 10, 10); directionalLight.castShadow = true; scene.add(directionalLight); // 初始化渲染器 const renderer = new THREE.WebGLRenderer(); // 设置渲染的尺寸大小 renderer.setSize(window.innerWidth, window.innerHeight); // 开启场景中的阴影贴图 renderer.shadowMap.enabled = true; // console.log(renderer); // 将webgl渲染的canvas内容添加到body document.body.appendChild(renderer.domElement); // // 使用渲染器,通过相机将场景渲染进来 // renderer.render(scene, camera); // 创建轨道控制器 const controls = new OrbitControls(camera, renderer.domElement); // 设置控制器阻尼,让控制器更有真实效果,必须在动画循环里调用.update()。 controls.enableDamping = true; // 添加坐标轴辅助器 const axesHelper = new THREE.AxesHelper(5); scene.add(axesHelper); // 设置时钟 const clock = new THREE.Clock(); function render() { controls.update(); renderer.render(scene, camera); // 渲染下一帧的时候就会调用render函数 requestAnimationFrame(render); } render(); // 监听画面变化,更新渲染画面 window.addEventListener("resize", () => { // console.log("画面变化了"); // 更新摄像头 camera.aspect = window.innerWidth / window.innerHeight; // 更新摄像机的投影矩阵 camera.updateProjectionMatrix(); // 更新渲染器 renderer.setSize(window.innerWidth, window.innerHeight); // 设置渲染器的像素比 renderer.setPixelRatio(window.devicePixelRatio); });
总结
开启阴影只要记住关键的几步即可。如有错误之处,欢迎大家留言指出,谢谢大家了。
© 版权声明
文章版权归作者所有,未经允许请勿转载,侵权请联系 admin@trc20.tw 删除。
THE END