threejs(5) – detaillierte Erklärung von Licht und Schatten

1. Grundlegende Verwendung und Prinzipien der Gsap-Animationsbibliothek

npm-Adresse: https://snyk.io/advisor/npm-package/gsap

Fügen Sie hier eine Bildbeschreibung ein

import * as THREE from "three";
// 导入轨道控制器
import {
    
     OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 导入动画库
import gsap from "gsap";

// console.log(THREE);

// 目标:掌握gsap设置各种动画效果

// 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 cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterial = new THREE.MeshBasicMaterial({
    
     color: 0xffff00 });
// 根据几何体和材质创建物体
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

// 修改物体的位置
// cube.position.set(5, 0, 0);
// cube.position.x = 3;
// 缩放
// cube.scale.set(3, 2, 1);
// cube.scale.x = 5;
// 旋转
cube.rotation.set(Math.PI / 4, 0, 0, "XZY");

// 将几何体添加到场景中
scene.add(cube);

console.log(cube);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// console.log(renderer);
// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// // 使用渲染器,通过相机将场景渲染进来
// renderer.render(scene, camera);

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);

// 添加坐标轴辅助器
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);
// 设置时钟
const clock = new THREE.Clock();

// 设置动画
var animate1 = gsap.to(cube.position, {
    
    
  x: 5,
  duration: 5,
  ease: "power1.inOut",
  //   设置重复的次数,无限次循环-1
  repeat: -1,
  //   往返运动
  yoyo: true,
  //   delay,延迟2秒运动
  delay: 2,
  onComplete: () => {
    
    
    console.log("动画完成");
  },
  onStart: () => {
    
    
    console.log("动画开始");
  },
});
gsap.to(cube.rotation, {
    
     x: 2 * Math.PI, duration: 5, ease: "power1.inOut" });

window.addEventListener("dblclick", () => {
    
    
  //   console.log(animate1);
  if (animate1.isActive()) {
    
    
    //   暂停
    animate1.pause();
  } else {
    
    
    //   恢复
    animate1.resume();
  }
});

function render() {
    
    
  renderer.render(scene, camera);
  //   渲染下一帧的时候就会调用render函数
  requestAnimationFrame(render);
}

render();

2. Eigenschaften und Methoden der Gsap-Steuerungsanimation

import * as THREE from "three";
// 导入轨道控制器
import {
    
     OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 导入动画库
import gsap from "gsap";

// console.log(THREE);

// 目标:监听页面尺寸变化,修改渲染画面

// 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 cubeGeometry = new THREE.BoxGeometry(1, 1, 1);
const cubeMaterial = new THREE.MeshBasicMaterial({
    
     color: 0xffff00 });
// 根据几何体和材质创建物体
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);

// 修改物体的位置
// cube.position.set(5, 0, 0);
// cube.position.x = 3;
// 缩放
// cube.scale.set(3, 2, 1);
// cube.scale.x = 5;
// 旋转
cube.rotation.set(Math.PI / 4, 0, 0, "XZY");

// 将几何体添加到场景中
scene.add(cube);

console.log(cube);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 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();

// 设置动画
var animate1 = gsap.to(cube.position, {
    
    
  x: 5,
  duration: 5,
  ease: "power1.inOut",
  //   设置重复的次数,无限次循环-1
  repeat: -1,
  //   往返运动
  yoyo: true,
  //   delay,延迟2秒运动
  delay: 2,
  onComplete: () => {
    
    
    console.log("动画完成");
  },
  onStart: () => {
    
    
    console.log("动画开始");
  },
});
gsap.to(cube.rotation, {
    
     x: 2 * Math.PI, duration: 5, ease: "power1.inOut" });

window.addEventListener("dblclick", () => {
    
    
  //   console.log(animate1);
  if (animate1.isActive()) {
    
    
    //   暂停
    animate1.pause();
  } else {
    
    
    //   恢复
    animate1.resume();
  }
});

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);
});

3. Detaillierte Erklärung von Lichtern und Schatten

Fügen Sie hier eine Bildbeschreibung ein

// 导入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";
import {
    
     TransformControls } from "three/addons/controls/TransformControls.js";

// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(
  45, // 视角
  window.innerWidth / window.innerHeight, // 宽高比
  0.1, // 近平面
  1000 // 远平面
);

// 创建渲染器
const renderer = new THREE.WebGLRenderer({
    
    
  antialias: true, // 开启抗锯齿
});
// 设置渲染器允许投射阴影
renderer.shadowMap.enabled = true;
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1;
document.body.appendChild(renderer.domElement);

// 设置相机位置
camera.position.z = 15;
camera.position.y = 2.4;
camera.position.x = 0.4;
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;
// 设置旋转速度
// controls.autoRotate = true;
controls.addEventListener("change", () => {
    
    
  renderer.render(scene, camera);
});

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

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

// 创建GUI
const gui = new GUI();

// rgbeLoader 加载hdr贴图
let rgbeLoader = new RGBELoader();
rgbeLoader.load("./texture/Video_Copilot-Back Light_0007_4k.hdr", (envMap) => {
    
    
  // 设置球形贴图
  envMap.mapping = THREE.EquirectangularReflectionMapping;
  // envMap.mapping = THREE.EquirectangularRefractionMapping;
  // 设置环境贴图
  scene.background = envMap;
  // 设置环境贴图
  // scene.environment = envMap;
});
const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);
const material1 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xccccff,
});
const torusKnot = new THREE.Mesh(geometry, material1);
torusKnot.position.set(4, 0, 0);
scene.add(torusKnot);

let sphereGeometry = new THREE.SphereGeometry(1, 32, 32);
const material2 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xffffff,
});
const sphere = new THREE.Mesh(sphereGeometry, material2);
sphere.castShadow = true;
sphere.receiveShadow = true;
scene.add(sphere);

let boxGeometry = new THREE.BoxGeometry(1, 1, 1);
const material3 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xffcccc,
});
const box = new THREE.Mesh(boxGeometry, material3);
box.position.set(-4, 0, 0);
scene.add(box);

// 创建平面
let planeGeometry = new THREE.PlaneGeometry(24, 24, 1, 1);
let planeMaterial = new THREE.MeshPhysicalMaterial({
    
    
  color: 0x999999,
});
let planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
planeMesh.rotation.x = -Math.PI / 2;
planeMesh.position.set(0, -1, 0);
scene.add(planeMesh);
// 设置接收阴影
planeMesh.receiveShadow = true;
planeMesh.castShadow = true;

// 添加环境光
let ambientLight = new THREE.AmbientLight(0xffffff, 0.1);
scene.add(ambientLight);

// 添加平行光
let directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight.position.set(10, 10, 0);
// 默认平行光的目标是原点
directionalLight.target.position.set(0, 0, 0);
scene.add(directionalLight);

// 设置光投射阴影
directionalLight.castShadow = true;

// 添加平行光辅助器
let directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight);
scene.add(directionalLightHelper);

gui.add(sphere.position, "z", -10, 10).name("z");

console.log(directionalLight);
directionalLight.shadow.camera.left = -10;
directionalLight.shadow.camera.right = 10;
directionalLight.shadow.camera.top = 10;
directionalLight.shadow.camera.bottom = -10;
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 50;
// 设置阴影的纹理大小
directionalLight.shadow.mapSize.width = 2048;
directionalLight.shadow.mapSize.height = 2048;

4. Detaillierte Einstellungen für lineares Licht und Schatten

Fügen Sie hier eine Bildbeschreibung ein

// 导入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";
import {
    
     TransformControls } from "three/addons/controls/TransformControls.js";

// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(
  45, // 视角
  window.innerWidth / window.innerHeight, // 宽高比
  0.1, // 近平面
  1000 // 远平面
);

// 创建渲染器
const renderer = new THREE.WebGLRenderer({
    
    
  antialias: true, // 开启抗锯齿
});
// 设置渲染器允许投射阴影
renderer.shadowMap.enabled = true;
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1;
document.body.appendChild(renderer.domElement);

// 设置相机位置
camera.position.z = 15;
camera.position.y = 2.4;
camera.position.x = 0.4;
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;
// 设置旋转速度
// controls.autoRotate = true;
controls.addEventListener("change", () => {
    
    
  renderer.render(scene, camera);
});

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

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

// 创建GUI
const gui = new GUI();

// rgbeLoader 加载hdr贴图
let rgbeLoader = new RGBELoader();
rgbeLoader.load("./texture/Video_Copilot-Back Light_0007_4k.hdr", (envMap) => {
    
    
  // 设置球形贴图
  envMap.mapping = THREE.EquirectangularReflectionMapping;
  // envMap.mapping = THREE.EquirectangularRefractionMapping;
  // 设置环境贴图
  scene.background = envMap;
  // 设置环境贴图
  // scene.environment = envMap;
});
const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);
const material1 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xccccff,
});
const torusKnot = new THREE.Mesh(geometry, material1);
torusKnot.position.set(4, 0, 0);
scene.add(torusKnot);

let sphereGeometry = new THREE.SphereGeometry(1, 32, 32);
const material2 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xffffff,
});
const sphere = new THREE.Mesh(sphereGeometry, material2);
sphere.castShadow = true;
sphere.receiveShadow = true;
scene.add(sphere);

let boxGeometry = new THREE.BoxGeometry(1, 1, 1);
const material3 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xffcccc,
});
const box = new THREE.Mesh(boxGeometry, material3);
box.position.set(-4, 0, 0);
scene.add(box);

// 创建平面
let planeGeometry = new THREE.PlaneGeometry(24, 24, 1, 1);
let planeMaterial = new THREE.MeshPhysicalMaterial({
    
    
  color: 0x999999,
});
let planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
planeMesh.rotation.x = -Math.PI / 2;
planeMesh.position.set(0, -1, 0);
scene.add(planeMesh);
// 设置接收阴影
planeMesh.receiveShadow = true;
planeMesh.castShadow = true;

// 添加环境光
let ambientLight = new THREE.AmbientLight(0xffffff, 0.1);
scene.add(ambientLight);

// 添加平行光
let directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight.position.set(10, 10, 0);
// 默认平行光的目标是原点
directionalLight.target.position.set(0, 0, 0);
scene.add(directionalLight);

// 设置光投射阴影
directionalLight.castShadow = true;

// 添加平行光辅助器
let directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight);
scene.add(directionalLightHelper);

gui.add(sphere.position, "z", -10, 10).name("z");

console.log(directionalLight);
directionalLight.shadow.camera.left = -10;
directionalLight.shadow.camera.right = 10;
directionalLight.shadow.camera.top = 10;
directionalLight.shadow.camera.bottom = -10;
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 50;
// 设置阴影的纹理大小 数值越大越清晰 但是越耗性能
directionalLight.shadow.mapSize.width = 2048;
directionalLight.shadow.mapSize.height = 2048;

5. Detaillierte Erläuterung jedes Spotlight-Attributs

// 添加聚光灯
let spotLight = new THREE.SpotLight(0xffffff, 2);
spotLight.position.set(0, 10, 0);
spotLight.target.position.set(0, 0, 0); // 朝向
spotLight.castShadow = true; // 投射阴影

spotLight.angle = Math.PI / 8; // 角度
spotLight.distance = 100; // 距离
spotLight.penumbra = 0.5; // 衰减
spotLight.decay = 2; // 衰减快慢
scene.add(spotLight);

Fügen Sie hier eine Bildbeschreibung ein

// 导入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";
import {
    
     TransformControls } from "three/addons/controls/TransformControls.js";

// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(
  45, // 视角
  window.innerWidth / window.innerHeight, // 宽高比
  0.1, // 近平面
  1000 // 远平面
);

// 创建渲染器
const renderer = new THREE.WebGLRenderer({
    
    
  antialias: true, // 开启抗锯齿
});
// 设置渲染器允许投射阴影
renderer.shadowMap.enabled = true;
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1;
document.body.appendChild(renderer.domElement);

// 设置相机位置
camera.position.z = 15;
camera.position.y = 2.4;
camera.position.x = 0.4;
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;
// 设置旋转速度
// controls.autoRotate = true;
controls.addEventListener("change", () => {
    
    
  renderer.render(scene, camera);
});

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

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

// 创建GUI
const gui = new GUI();

// rgbeLoader 加载hdr贴图
let rgbeLoader = new RGBELoader();
rgbeLoader.load("./texture/Video_Copilot-Back Light_0007_4k.hdr", (envMap) => {
    
    
  // 设置球形贴图
  envMap.mapping = THREE.EquirectangularReflectionMapping;
  // envMap.mapping = THREE.EquirectangularRefractionMapping;
  // 设置环境贴图
  scene.background = envMap;
  // 设置环境贴图
  // scene.environment = envMap;
});
const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);
const material1 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xccccff,
});
const torusKnot = new THREE.Mesh(geometry, material1);
torusKnot.position.set(4, 0, 0);
scene.add(torusKnot);

let sphereGeometry = new THREE.SphereGeometry(1, 32, 32);
const material2 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xffffff,
});
const sphere = new THREE.Mesh(sphereGeometry, material2);
sphere.castShadow = true;
sphere.receiveShadow = true;
scene.add(sphere);

let boxGeometry = new THREE.BoxGeometry(1, 1, 1);
const material3 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xffcccc,
});
const box = new THREE.Mesh(boxGeometry, material3);
box.position.set(-4, 0, 0);
scene.add(box);

// 创建平面
let planeGeometry = new THREE.PlaneGeometry(24, 24, 1, 1);
let planeMaterial = new THREE.MeshPhysicalMaterial({
    
    
  color: 0x999999,
});
let planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
planeMesh.rotation.x = -Math.PI / 2;
planeMesh.position.set(0, -2, 0);
scene.add(planeMesh);
// 设置接收阴影
planeMesh.receiveShadow = true;
planeMesh.castShadow = true;

// 添加环境光
let ambientLight = new THREE.AmbientLight(0xffffff, 0.1);
scene.add(ambientLight);

// 添加平行光
// let directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
// directionalLight.position.set(0, 10, 0);
// // 默认平行光的目标是原点
// directionalLight.target.position.set(0, 0, 0);
// scene.add(directionalLight);

// // 设置光投射阴影
// directionalLight.castShadow = true;

// // 添加平行光辅助器
// let directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight);
// scene.add(directionalLightHelper);

// gui.add(sphere.position, "z", -10, 10).name("z");

// console.log(directionalLight);
// directionalLight.shadow.camera.left = -10;
// directionalLight.shadow.camera.right = 10;
// directionalLight.shadow.camera.top = 10;
// directionalLight.shadow.camera.bottom = -10;
// directionalLight.shadow.camera.near = 0.5;
// directionalLight.shadow.camera.far = 50;
// // 设置阴影的纹理大小
// directionalLight.shadow.mapSize.width = 2048;
// directionalLight.shadow.mapSize.height = 2048;

// 添加聚光灯
let spotLight = new THREE.SpotLight(0xffffff, 2);
spotLight.position.set(0, 10, 0);
spotLight.target.position.set(0, 0, 0); // 朝向
spotLight.castShadow = true; // 投射阴影

spotLight.angle = Math.PI / 8; // 角度
spotLight.distance = 100; // 距离
spotLight.penumbra = 0.5; // 衰减
spotLight.decay = 2; // 衰减快慢
scene.add(spotLight);

// 添加聚光灯辅助器
let spotLightHelper = new THREE.SpotLightHelper(spotLight);
scene.add(spotLightHelper);

console.log(spotLight);

spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;

6. Detaillierte Erläuterung jedes Attributs einer Punktlichtquelle

Fügen Sie hier eine Bildbeschreibung ein

// 导入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";
import {
    
     TransformControls } from "three/addons/controls/TransformControls.js";

// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(
  45, // 视角
  window.innerWidth / window.innerHeight, // 宽高比
  0.1, // 近平面
  1000 // 远平面
);

// 创建渲染器
const renderer = new THREE.WebGLRenderer({
    
    
  antialias: true, // 开启抗锯齿
});
// 设置渲染器允许投射阴影
renderer.shadowMap.enabled = true;

renderer.setSize(window.innerWidth, window.innerHeight);
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1;
document.body.appendChild(renderer.domElement);

// 设置相机位置
camera.position.z = 15;
camera.position.y = 2.4;
camera.position.x = 0.4;
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;
// 设置旋转速度
// controls.autoRotate = true;
controls.addEventListener("change", () => {
    
    
  renderer.render(scene, camera);
});

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

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

// 创建GUI
const gui = new GUI();

// rgbeLoader 加载hdr贴图
let rgbeLoader = new RGBELoader();
rgbeLoader.load("./texture/Video_Copilot-Back Light_0007_4k.hdr", (envMap) => {
    
    
  // 设置球形贴图
  envMap.mapping = THREE.EquirectangularReflectionMapping;
  // envMap.mapping = THREE.EquirectangularRefractionMapping;
  // 设置环境贴图
  scene.background = envMap;
  // 设置环境贴图
  // scene.environment = envMap;
});
const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);
const material1 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xccccff,
});
const torusKnot = new THREE.Mesh(geometry, material1);
torusKnot.position.set(4, 0, 0);
scene.add(torusKnot);

let sphereGeometry = new THREE.SphereGeometry(1, 32, 32);
const material2 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xffffff,
});
const sphere = new THREE.Mesh(sphereGeometry, material2);
sphere.castShadow = true;
sphere.receiveShadow = true;
scene.add(sphere);

let boxGeometry = new THREE.BoxGeometry(1, 1, 1);
const material3 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xffcccc,
});
const box = new THREE.Mesh(boxGeometry, material3);
box.position.set(-4, 0, 0);
scene.add(box);

// 创建平面
let planeGeometry = new THREE.PlaneGeometry(24, 24, 1, 1);
let planeMaterial = new THREE.MeshPhysicalMaterial({
    
    
  color: 0x999999,
});
let planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
planeMesh.rotation.x = -Math.PI / 2;
planeMesh.position.set(0, -2, 0);
scene.add(planeMesh);
// 设置接收阴影
planeMesh.receiveShadow = true;
planeMesh.castShadow = true;

// 添加环境光
let ambientLight = new THREE.AmbientLight(0xffffff, 0.1);
scene.add(ambientLight);


// 添加点光源
let pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.position.set(0, 5, 0);
pointLight.castShadow = true; // 阴影
scene.add(pointLight);

pointLight.distance = 15;
pointLight.decay = 2; // 衰减快慢
pointLight.shadow.mapSize.width = 2048;
pointLight.shadow.mapSize.height = 2048;
// 添加点光源辅助器
let pointLightHelper = new THREE.PointLightHelper(pointLight);
scene.add(pointLightHelper);

7. Der Unterschied zwischen Punktlichtquelle und Scheinwerfer

Punktlichter und Scheinwerfer sind beide Lichttypen in three.js, und der Hauptunterschied zwischen ihnen besteht darin, wie sie die Szene beleuchten.

  • Ein Punktlicht ist eine Art von Licht, das von einem einzigen Punkt aus Licht in alle Richtungen ausstrahlt. Es beleuchtet alle Objekte in der Szene, unabhängig von ihrer Ausrichtung oder Position. Punktlichtquellen eignen sich zur Simulation von Situationen, in denen eine Lichtquelle fest installiert ist und in alle Richtungen leuchtet, beispielsweise die Sonne oder eine Glühbirne.

  • Ein Strahler ist eine gerichtete Lichtart, die Licht in eine bestimmte Richtung abstrahlt. Der Strahler hat einen kegelförmigen Strahl und die Größe des Strahls kann durch Einstellen des Strahlerwinkels angepasst werden. Strahler werden üblicherweise verwendet, um gerichtete Lichtquellen wie Taschenlampen oder Autolichter zu simulieren.

Im Allgemeinen eignen sich Punktlichter für Situationen, in denen die gesamte Szene beleuchtet werden muss, während Punktlichter für Situationen geeignet sind, in denen gerichtete Lichtquellen simuliert werden müssen.

8. Häufig gestellte Fragen zu Schatteneffekt, Transparenz, Textur und Schatten

Fügen Sie hier eine Bildbeschreibung ein

// 导入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";
// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(
  45, // 视角
  window.innerWidth / window.innerHeight, // 宽高比
  0.1, // 近平面
  1000 // 远平面
);

// 创建渲染器
const renderer = new THREE.WebGLRenderer({
    
    
  antialias: true, // 开启抗锯齿
});
// 设置渲染器允许投射阴影
renderer.shadowMap.enabled = true;
// renderer.useLegacyLights = false;
// renderer.physicallyCorrectLights = true;

renderer.setSize(window.innerWidth, window.innerHeight);
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1;
document.body.appendChild(renderer.domElement);

// 设置相机位置
camera.position.z = 15;
camera.position.y = 2.4;
camera.position.x = 0.4;
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;
// 设置旋转速度
// controls.autoRotate = true;
controls.addEventListener("change", () => {
    
    
  renderer.render(scene, camera);
});

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

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

// 创建GUI
const gui = new GUI();

// rgbeLoader 加载hdr贴图
let rgbeLoader = new RGBELoader();
rgbeLoader.load("./texture/Video_Copilot-Back Light_0007_4k.hdr", (envMap) => {
    
    
  // 设置球形贴图
  envMap.mapping = THREE.EquirectangularReflectionMapping;
  // envMap.mapping = THREE.EquirectangularRefractionMapping;
  // 设置环境贴图
  scene.background = envMap;
  // 设置环境贴图
  // scene.environment = envMap;
});
const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);
const material1 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xccccff,
});
const torusKnot = new THREE.Mesh(geometry, material1);
torusKnot.position.set(4, 0, 0);
scene.add(torusKnot);
torusKnot.receiveShadow = true;
torusKnot.castShadow = true;

let sphereGeometry = new THREE.SphereGeometry(1, 32, 32);
const material2 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xffffff,
});
const sphere = new THREE.Mesh(sphereGeometry, material2);
sphere.castShadow = true;
sphere.receiveShadow = true;
scene.add(sphere);

let boxGeometry = new THREE.BoxGeometry(1, 1, 1);
let alphaTexture = new THREE.TextureLoader().load("./texture/16.jpg");
const material3 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xffcccc,
  alphaMap: alphaTexture,
  transparent: true,
  side: THREE.DoubleSide,
  alphaTest: 0.5,
  shadowSide: THREE.BackSide,
});

const box = new THREE.Mesh(boxGeometry, material3);
box.position.set(-4, 0, 0);
scene.add(box);
box.receiveShadow = true;
box.castShadow = true;

// 创建平面
let planeGeometry = new THREE.PlaneGeometry(24, 24, 1, 1);
let planeMaterial = new THREE.MeshPhysicalMaterial({
    
    
  color: 0x999999,
});
let planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
planeMesh.rotation.x = -Math.PI / 2;
planeMesh.position.set(0, -2, 0);
scene.add(planeMesh);
// 设置接收阴影
planeMesh.receiveShadow = true;
planeMesh.castShadow = true;

// 添加环境光
let ambientLight = new THREE.AmbientLight(0xffffff, 0.1);
scene.add(ambientLight);

// 添加点光源
let pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.position.set(0, 5, 0);
pointLight.castShadow = true;
scene.add(pointLight);

pointLight.distance = 15;
pointLight.decay = 2;
pointLight.shadow.mapSize.width = 2048;
pointLight.shadow.mapSize.height = 2048;
pointLight.shadow.bias = -0.01; // 偏移

// 添加点光源辅助器
let pointLightHelper = new THREE.PointLightHelper(pointLight);
scene.add(pointLightHelper);

9. Dynamische kaskadierende Schatteneinstellungen für große Szenen

let csm = new CSM({
    
     // 级联阴影
  maxFar: params.far, // 最远距离
  cascades: 4, // 等级
  // mode: params.mode,
  parent: scene,
  shadowMapSize: 1024,
  lightDirection: new THREE.Vector3( // 方向
    params.lightX,
    params.lightY,
    params.lightZ
  ).normalize(),
  camera: camera, // 相机
});

Fügen Sie hier eine Bildbeschreibung ein

// 导入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";
import {
    
     CSM } from "three/addons/csm/CSM.js";

const params = {
    
    
  orthographic: false,
  fade: false,
  far: 1000,
  mode: "practical",
  lightX: -1,
  lightY: -1,
  lightZ: -1,
  margin: 100,
  lightFar: 1000,
  lightNear: 1,
  autoUpdateHelper: true,
  updateHelper: function () {
    
    
    csmHelper.update();
  },
};
// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(
  45, // 视角
  window.innerWidth / window.innerHeight, // 宽高比
  0.1, // 近平面
  1000 // 远平面
);

// 创建渲染器
const renderer = new THREE.WebGLRenderer({
    
    
  antialias: true, // 开启抗锯齿
});
// 设置渲染器允许投射阴影
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1;
document.body.appendChild(renderer.domElement);

// 设置相机位置
camera.position.z = 15;
camera.position.y = 2.4;
camera.position.x = 0.4;
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;
// 设置旋转速度
// controls.autoRotate = true;
controls.addEventListener("change", () => {
    
    
  renderer.render(scene, camera);
});

// 添加平行光
let directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight.position
  .set(params.lightX, params.lightY, params.lightZ)
  .normalize()
  .multiplyScalar(-200);
// 默认平行光的目标是原点
directionalLight.target.position.set(0, 0, 0);
scene.add(directionalLight);

// 设置光投射阴影
// directionalLight.castShadow = true;

// 添加平行光辅助器
let directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight);
scene.add(directionalLightHelper);

// console.log(directionalLight);
// directionalLight.shadow.camera.left = -10;
// directionalLight.shadow.camera.right = 10;
// directionalLight.shadow.camera.top = 10;
// directionalLight.shadow.camera.bottom = -10;
// directionalLight.shadow.camera.near = 0.5;
// directionalLight.shadow.camera.far = 50;
// // 设置阴影的纹理大小
// directionalLight.shadow.mapSize.width = 2048;
// directionalLight.shadow.mapSize.height = 2048;

let cameraHelper = new THREE.CameraHelper(directionalLight.shadow.camera);
scene.add(cameraHelper);

let csm = new CSM({
    
     // 级联阴影
  maxFar: params.far, // 最远距离
  cascades: 4, // 等级
  // mode: params.mode,
  parent: scene,
  shadowMapSize: 1024,
  lightDirection: new THREE.Vector3( // 方向
    params.lightX,
    params.lightY,
    params.lightZ
  ).normalize(),
  camera: camera, // 相机
});
csm.fade = true;
csm.updateFrustums();
// 渲染函数
function animate() {
    
    
  controls.update();
  camera.updateMatrixWorld();
  csm.update();
  requestAnimationFrame(animate);
  // 渲染
  renderer.render(scene, camera);
}
animate();

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

// 创建GUI
const gui = new GUI();

// rgbeLoader 加载hdr贴图
let rgbeLoader = new RGBELoader();
rgbeLoader.load("./texture/Video_Copilot-Back Light_0007_4k.hdr", (envMap) => {
    
    
  // 设置球形贴图
  envMap.mapping = THREE.EquirectangularReflectionMapping;
  // envMap.mapping = THREE.EquirectangularRefractionMapping;
  // 设置环境贴图
  scene.background = envMap;
  // 设置环境贴图
  // scene.environment = envMap;
});

const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);
const material1 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xccccff,
});
csm.setupMaterial(material1);
const torusKnot = new THREE.Mesh(geometry, material1);
torusKnot.position.set(4, 0, 0);
scene.add(torusKnot);
torusKnot.receiveShadow = true;
torusKnot.castShadow = true;

let sphereGeometry = new THREE.SphereGeometry(1, 32, 32);
const material2 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xffffff,
});
csm.setupMaterial(material2);
const sphere = new THREE.Mesh(sphereGeometry, material2);
sphere.castShadow = true;
sphere.receiveShadow = true;
scene.add(sphere);

let boxGeometry = new THREE.BoxGeometry(1, 1, 1);
const material3 = new THREE.MeshPhysicalMaterial({
    
    
  color: 0xffcccc,
});
csm.setupMaterial(material3);
const box = new THREE.Mesh(boxGeometry, material3);
box.position.set(-4, 0, 0);
scene.add(box);
box.receiveShadow = true;
box.castShadow = true;

// 创建平面
let planeGeometry = new THREE.PlaneGeometry(24, 24, 1, 1);
let planeMaterial = new THREE.MeshPhysicalMaterial({
    
    
  color: 0x999999,
});
csm.setupMaterial(planeMaterial);
let planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
planeMesh.rotation.x = -Math.PI / 2;
planeMesh.position.set(0, -1, 0);
scene.add(planeMesh);
// 设置接收阴影
planeMesh.receiveShadow = true;
planeMesh.castShadow = true;

// 添加环境光
let ambientLight = new THREE.AmbientLight(0xffffff, 0.1);
scene.add(ambientLight);
gui.add(sphere.position, "z", -10, 10).name("z");
gui.add(csm, "fade").onChange((value) => {
    
    
  csm.fade = value;
  csm.updateFrustums();
});

Acho que você gosta

Origin blog.csdn.net/woyebuzhidao321/article/details/134057499
Recomendado
Clasificación