threejs 3d

本文档详细介绍了使用Three.js进行3D渲染的基础知识,包括官网资源、本地搭建、新打包工具Parcel的使用,以及如何创建场景、物体、控制器等。深入探讨了材质、纹理、PBR物理渲染、灯光与阴影效果,同时提供了各种纹理贴图的获取途径和环境贴图的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 官网

https://threejs.org/(外网,访问较慢)

2. 本地搭建官网

https://github.com/mrdoob/three.js/

下载压缩包进行本地启动
在这里插入图片描述

3. 新的打包工具(parcel)

官网

https://www.parceljs.cn/

使用

npm install -g parcel-bundler
parcel index.html

4. 使用threejs去渲染第一个场景和物体

<template>
  <div class="container" ref="container"></div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import * as THREE from "three";
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 1. 创建场景
const scene = new THREE.Scene();
// 2. 创建相机
// 2. 创建相机
const camere = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
// 3. 改变相机的位置
camere.position.set(0, 0, 10);
// 4. 添加相机到场景中
scene.add(camere);
// 5. 添加物体(点、线、面),材质
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: "red" }); // 不透光材质
// 6. 创建物体
const cube = new THREE.Mesh(geometry, material);
// 7. 添加物体到场景中
scene.add(cube);
// 8. 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 9. 设置渲染器的大小
renderer.setSize(window.innerWidth, window.innerHeight);

const render = () => {
  // 11. 使用渲染器将相机场景渲染出来
  renderer.render(scene, camere);
  requestAnimationFrame(render);
}

const container = ref(null);
onMounted(() => {
  // 初始化轨道控制器
  const controlls = new OrbitControls(camere, renderer.domElement);
  controlls.enableDamping = true;
  // 10. 将webgl渲染的canvas内容添加到dom节点中
  container.value.append(renderer.domElement);
  render();
})

</script>

<style>
* {
  margin: 0;
  padding: 0;
}
.container {
  width: 100vw;
  height: 100vh;
  background-color: skyblue;
}
</style>

5. 添加轨道控制器

// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 初始化轨道控制器
const controlls = new OrbitControls(camere, renderer.domElement);
controlls.enableDamping = true;

6. 坐标辅助器

// 添加坐标辅助器
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);

7. 控制物体移动

cube.position.set(10, 10, 10)
cube.position.x += 0.1;

8. 物体的缩放与旋转

cube.scale.set(3, 1, 1);
cube.scale.x += 0.1;
cube.rotation.set(Math.PI / 3, 20, 10);

9. requestAnimationFrame

一般一帧在16毫秒左右

10. gsap

官网

https://greensock.com/gsap/

使用

import { gsap } from "gsap";
// gsap
// gsap
const animation = gsap.to(cube.position, {
  x: 2,
  duration: 5,
  ease: "elastic",
});

多种使用方式,详细查看官网

11. 根据尺寸实现自适应画面

// 监听画面的变化,更新渲染
  window.addEventListener("resize", () => {
    // 首先更新摄像头
    camere.aspect = window.innerWidth / window.innerHeight;
    camere.updateProjectionMatrix();

    // 更新渲染器
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setPixelRatio(window.devicePixelRatio);
  })

12. 通过js来控制是否全屏

// 双击进入全屏
  window.addEventListener("dblclick", () => {
    const fullScreenElement = document.fullscreenElement;
    if (!fullScreenElement) {
      renderer.domElement.requestFullscreen();
    } else {
      document.exitFullscreen();
    }
  })

13. dat.gui

安装

npm i dat.gui

使用

import datGui from "dat.gui";
// dat.gui
const gui = new datGui.GUI();
// 修改位置
gui
  .add(cube.position, "x")
  .min(0)
  .max(10)
  .step(0.01)
  .name("位置")
  .onChange((val) => {
    console.log("值被修改", val);
}).onFinishChange((val) => {
    console.log("完全被修改", val);
})
// 旋转
gui
  .add(cube.rotation, "x")
  .min(0)
  .max(89)
  .step(0.01)
  .name("旋转")
  .onChange((val) => {
    console.log("值被修改", val);
})
// 缩放
gui
  .add(cube.scale, "x")
  .min(0)
  .max(89)
  .step(0.01)
  .name("缩放")
  .onChange((val) => {
    console.log("值被修改", val);
})

14. 常见网格集合体

  • BoxGeometry
  • CircleGeometry
  • SphereGeometry
  • BufferGeometry
  • TorusGeometry

15. 材质与纹理

// 纹理
const textureLoader = new THREE.TextureLoader();
// vue写法
// eslint-disable-next-line @typescript-eslint/no-var-requires
const logoTextureLoader = textureLoader.load(require("./assets/logo.png"));
const material = new THREE.MeshBasicMaterial({
  map: logoTextureLoader,
}); // 不透光材质

16. 纹理的偏移、旋转和重复

logoTextureLoader.offset.x = 0.2;
logoTextureLoader.offset.y = 0.2;
logoTextureLoader.rotation = Math.PI / 4;
logoTextureLoader.repeat.set(2, 3);

17. 透明材质和纹理

需要贴图,alpha是一张灰度纹理,用于控制整个表面的不透明度。(黑色:完全透明;白色完全不透明)。默认值为null。

const material = new THREE.MeshBasicMaterial({
  map: logoTextureLoader,
  alphaMap: alphaTextureLoader,
  transparent: true,
}); // 不透光材质

18. 环境遮挡贴图和强度

此纹理的红色通道用作环境光遮挡贴图。默认值为空。aoMap需要第二组UV。

19. PBR

什么是PBR

物理属性的引擎渲染

PBR的组成部分

灯光属性:直接照明、间接照明、直接高光、间接高光、阴影、环境光
表面属性:基础色、法线、高光、粗糙度、金属度

20. 粗糙度和粗糙度贴图

rougness:材质的粗糙程度,0.0表示光滑的镜面反射,1.0表示完全漫反射。默认值为1.0。如果还提供rougnessMap,则两个值相乘。
rougnessMap:该纹理的绿色通道用于改变材质的粗糙度。

21. 金属度和金属贴图

metalness:材质和金属的相似度,非金属材质,如木材或石材,使用0.0,金属使用1.0,通常没有中间值。默认值为0.0。0.0到1.0之间的值可用于生锈金属的外观。如果还提供metalnessMap,则两个值相乘。
metalnessMap:该纹理的蓝色通道用于改变材质的金属度。

22. 法线贴图

normalMap: 纹理创建法线贴图。RGB值影响每个像素片段的表面法线,并改变颜色的照明方式。法线贴图不改变表面的实际形状,只改变照明。如果材料有一个使用左手习惯的法线映射,normalScale的y分量应该被否定,以补偿不同的手性。

23. 如何获取各种类型的纹理贴图

网站:

24. 纹理加载进度情况

LoadingManager

const manager = new THREE.LoadingManager();
manager.onStart = function ( url, itemsLoaded, itemsTotal ) {
	console.log( 'Started loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' );
};

manager.onLoad = function ( ) {
	console.log( 'Loading complete!');
};

manager.onProgress = function ( url, itemsLoaded, itemsTotal ) {
	console.log( 'Loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' );
};

manager.onError = function ( url ) {
	console.log( 'There was an error loading ' + url );
};

const loader = new THREE.OBJLoader( manager );
loader.load( 'file.obj', function ( object ) {
	//
} );

25. 环境贴图

envMap

26. 灯光和阴影的关系与设置

  1. 材质要满足能够对光照有但应
  2. 设置渲染器开启阴影的计算 renderer.shadowMap.enabled = true
  3. 设置光照投影阴影directionalLight.catsShadow = true
  4. 设置物体投影阴影sphere.catsShadow = true
  5. 设置物体接收阴影plane.catsShadow = true

27. 平行光阴影

设置阴影模糊度

directionalLight.shadow.radius = 20

设置阴影贴图模糊度

directionalLight.shadow.mapSize.set(2048, 2048)

28. 聚光灯

SpotLight

const spotLight = new THREE.SpotLight( 0xffffff );
spotLight.position.set( 100, 1000, 100 );
spotLight.map = new THREE.TextureLoader().load( url );

spotLight.castShadow = true;

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

spotLight.shadow.camera.near = 500;
spotLight.shadow.camera.far = 4000;
spotLight.shadow.camera.fov = 30;

scene.add( spotLight );

29. 点光源

PointLight

const light = new THREE.PointLight( 0xff0000, 1, 100 );
light.position.set( 50, 50, 50 );
scene.add( light );

30. 杂记

renderer.setClearColor

设置透明颜色和不透明度。

球环境贴图

texture.mapping = THREE.EquirectangularReflectionMapping

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值