three.js 的渲染结构

news2024/9/25 17:19:26

理解three.js 的渲染结构

1 three.js 的渲染

  • Three.js 封装了场景、灯光、阴影、材质、纹理和三维算法,让你不必再直接用WebGL 开发项目。
  • three.js 在渲染三维场景时,需要创建很多对象,并将它们关联在一起。

下图便是一个基本的three.js 渲染结构。

解释一下上面的示意图:

1.1 Renderer 渲染器

Renderer 是three.js 的主要对象。当你将一个场景Scene 和一个摄像机Camera 传递到渲染器的渲染方法中,渲染器便会将摄像机视椎体中的三维场景渲染成一个二维图像显示在canvas 画布中。

1.2 Scene 场景对象

场景对象是树状结构的,其中包含了三维对象Object3D 和灯光对象Light。

  • Object3D 是可以被直接渲染出来的,Object3D是网格对象Mesh和集合对象Group的基类
  • 场景对象可以定义场景的背景色和雾效。

在场景对象的树状结构中,每个对象的变换信息都是相对的。

比如汽车和汽车里的人,人的位置是相对于汽车而言的,当汽车移动了,人的本地坐标位坐标位虽然不变,但其世界坐标位已经变了。

1.3 Camera 相机对象

按理说,相机对象是在场景里的,但是相机对象不在它所看的场景里,这就像我们自己看不见自己的眼睛一样。

因此,相机对象可以独立于场景之外。

相机对象是可以作为其它三维对象的子对象的,这样相机就会随其父对象同步变换。

1.4 Mesh 网格对象

网格对象由几何体`Geometry`和材质`Material`两部分组成,Geometry 负责塑形,Material 负责着色。 

Geometry 和Materia 是可以被多个Mesh 对象复用的

比如要绘制两个一模一样的立方体,那只需要实例化两个Mesh 即可,Geometry 和Materia可以使用一套。

1.5 Geometry 几何体对象

几何体对象负责塑形,存储了与顶点相关的数据,比如顶点点位、顶点索引、uv坐标等。

Three.js 中内置了许多基本几何体,我们也可以自定义几何体,或者从外部的模型文件里加载几何体 

1.6 Material 材质对象

材质对象负责着色,绘制几何体的表面属性,比如漫反射、镜面反射、光泽度、凹凸等。

材质对象的许多属性都可以用纹理贴图表示,比如漫反射贴图、凹凸贴图等。 

1.7 Texture 纹理对象

纹理对象就是一张图像。纹理图像的图像源可以是Image 图片、canvas 画布、Video 视频等。 

1.8 Light 光源对象

Light 对象不像Object3D 那样依托于顶点,它更多的是像Object3D 里的材质Material 那样,作用于物体的样式。

Light 对象可以理解为在为几何体添加了材质后,再利用光效配合材质对几何体的样式进行二次加工。 

2 示例-绘制多个立方体

练习一下three.js的渲染结构。

2.1. 在vue2 项目中安装three依赖

npm install three @types/three --save --registry=https://registry.npm.taobao.org 

2.2 绘制一个立方体

绘制一个立方体,其渲染结构如下:

<template><div id="threeBox"></div>
</template>

<script> import * as THREE from 'three'
export default {data() {return {}},mounted() {this.init();},methods: {init() {const scene = new THREE.Scene();const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );const renderer = new THREE.WebGLRenderer();renderer.setSize( window.innerWidth, window.innerHeight );document.querySelector("#threeBox").appendChild( renderer.domElement );const geometry = new THREE.BoxGeometry();const material = new THREE.MeshNormalMaterial();const cube = new THREE.Mesh(geometry, material);scene.add(cube);camera.position.z = 5;animate()function animate() {requestAnimationFrame( animate );cube.rotation.x += 0.01;cube.rotation.y += 0.01;renderer.render( scene, camera );}}}
} </script> 

当前这个立方体的材质是MeshNormalMaterial,并不受光照影响。

2.3 修改材质,添加光源

给立方体换个MeshPhongMaterial 材质,再添加光源。

const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshPhongMaterial({ color: 0x44aa88 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

const color = 0xffffff;
const intensity = 1;
const light = new THREE.DirectionalLight(color, intensity);
light.position.set(-1, 2, 4);
scene.add(light); 

当前的渲染结构如下:

效果如下:

2.4 绘制多个立方体

在场景中再添加两个一模一样的立方体,几何体和材质可被多个Mesh 对象共享。

<template><div id="threeBox"></div>
</template>

<script> import * as THREE from 'three'
export default {data() {return {}},mounted() {this.init();},methods: {init() {// 场景和相机const scene = new THREE.Scene();const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );camera.position.z = 5;// 渲染器const renderer = new THREE.WebGLRenderer();renderer.setSize( window.innerWidth, window.innerHeight );document.querySelector("#threeBox").appendChild( renderer.domElement );// 光源const color = 0xffffff;const intensity = 1;const light = new THREE.DirectionalLight(color, intensity);light.position.set(-1, 2, 4);scene.add(light);// 几何体和材质const geometry = new THREE.BoxGeometry();const material = new THREE.MeshPhongMaterial({ color: 0x44aa88 });// 几何体和材质可被多个Mesh 对象共享。const cubes = [-2, 0, 2].map((num) => makeInstance(num));scene.add(...cubes);//批量生成 Mesh 网格对象function makeInstance(x) {const cube = new THREE.Mesh(geometry, material);cube.position.x = x;return cube;}// 动画渲染animate()function animate() {requestAnimationFrame(animate);cubes.forEach((cube) => {cube.rotation.x += 0.01;cube.rotation.y += 0.01;});renderer.render(scene, camera);}}}
} </script> 

当前的渲染结构如下:

效果如下:

最后

为大家准备了一个前端资料包。包含54本,2.57G的前端相关电子书,《前端面试宝典(附答案和解析)》,难点、重点知识视频教程(全套)。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/129952.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python通知Epic白嫖游戏信息

每周都有免费游戏 - Epic Games 近期看到Epic在送游戏&#xff0c;目前每周都会有活动白嫖。 身为白嫖党&#xff0c;肯定要操作一下。 游戏列表&#xff1a;Epic Games Store 每周免费游戏&#xff08;331&#xff09; | indienova GameDB 游戏库 大致思路&#xff1a; 1、…

把teamtalk中的网络库(netlib)拆出来单独测试实现双工通信效果

这篇文章的基础是上一篇对于将teamtalk中的线程池&#xff0c;连接池单独拆出来的讲解 不是说这个网络库会依赖线程池&#xff0c;连接池&#xff0c;而是上一篇文章中讲了一些base目录中的文件&#xff0c;并且这个网络库会依赖一些base目录里的文件&#xff0c; 文末会将所有…

基于fpga的自动售货机(三段式状态机)

目录 1、VL38 自动贩售机1 题目介绍 思路分析 代码实现 仿真文件 2、VL39 自动贩售机2 题目介绍&#xff1a; 题目分析 代码实现 仿真文件 3、状态机基本知识 1、VL38 自动贩售机1 题目介绍 设计一个自动贩售机&#xff0c;输入货币有三种&#xff0c;为0.5/1/2元&…

JS概览 (JS基础 DOM BOM)

目录 JavaScript JS基础 JS数据类型 函数 变量的作用域 作用域链 预解析 DOM DOM树 获取元素的方法 事件高级 注册和解绑事件 DOM事件流 BOM 和DOM的区别 window 对象的常见事件 window.onload JS执行机制 具体的执行流程 例子 JavaScript JS基础 JS数据类…

鉴源论坛 · 观模丨基于AUTOSAR的TTCAN通信协议的形式化建模与分析

作者 | 郭建 上海控安可信软件创新研究院特聘专家 版块 | 鉴源论坛 观模 汽车工业发展至今&#xff0c;硬件方面如车身材料、发动机等已无太大升值空间&#xff0c;而汽车电子则有着广阔的前景。为此各大汽车厂商对汽车电子的研究都投入了大量的人力财力。2003 年&#xff0c…

链式二叉树的代码总结

今天我带来链式二叉树的代码总结。 目录前言链式二叉树代码实现的五个文档二叉树的例子前序遍历中序遍历后序遍历层序遍历求结点个数的函数求叶子的个数的函数求k层结点个数的函数查找某一个值的函数求二叉树高度的函数判断二叉树是否是完全二叉树的函数开辟二叉树结点的函数销…

【设计模式】工厂方法模式

简单工厂模式的弊端 在简单工厂模式中只提供一个工厂类&#xff0c;该工厂类处于对产品类进行实例化的中心位置&#xff0c;它需要知道每一个产品对象的创建细节&#xff0c;并决定何时实例化哪一个产品类。简单工厂模式最大的缺点是当有新产品要加入到系统中时&#xff0c;必…

实现isReactive和isReadonly

08_实现isReactive和isReadonly 一、实现isReactive isReactive: 检查一个对象是否是由 reactive 创建的响应式代理。 1. 单元测试 // src/reactivity/tests/reactive.spec.tsimport { reactive, isReactive } from ../reactive;describe(reactive, function () {it(happy pa…

Callable接口

前言 获取多线程的方法&#xff0c;我们都知道有三种&#xff0c;还有一种是实现Callable接口 实现Runnable接口实现Callable接口实例化Thread类使用线程池获取Callable接口 Callable接口&#xff0c;是一种让线程执行完成后&#xff0c;能够返回结果的 在说到Callable接口…

【Unity天空盒】卡通渲染中如何实现云的消散效果

写在前面 完成大气渲染之后&#xff0c;接下来就是考虑云渲染了。因为我想做的天空盒本身是想跟着这位大佬Unity 卡通渲染 程序化天空盒 - 知乎里叙述的进程来的&#xff0c;里面云实现的是原神里的云&#xff0c;原神又是在崩3的基础上加上了消散效果。但现在能找到的一些教程…

线程中的sleep, yield, join

1. 前言 今天以具体实例的方法来详细记录下实战中的sleep, yield, join。 到底是什么意思&#xff0c;应该怎么用呢&#xff1f;&#xff1f;&#xff1f; 2. 适合人群 对该类方法的概念比较模糊的人 3. 开始 3.1 sleep 此方法是一个静态方法&#xff0c;可以通过类名直接调…

【MyBatis】安装 + 框架搭建 + 使用 + 优化(全程一条龙服务讲解~)

目录 前言 一、准备工作 1.1、下载MyBatis 1.2、数据库设计 二、搭建框架 2.1、创建Maven项目 2.2、jar包、引入依赖 2.3、创建MyBatis核心配置文件 2.4、映射文件 2.5、通过junit测试功能 2.6、框架优化 三、小结——注意事项 前言 本篇全程从0到1搭建MyBatis框架…

Python编程 简单春节倒计时教程(附源代码)

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.应用的技术 1.Tkinter 2.PHotoimage 函数 3.label组件 二.效果图 三…

pytorch 咖啡豆识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章地址&#xff1a; 365天深度学习训练营-第P6周&#xff1a;好莱坞明星识别&#x1f356; 作者&#xff1a;K同学啊一、前期准备 1.设置GPU import torch from torch import nn …

2022 年 pnpm 为什么这么火?

pnpm是 Node.js 的替代包管理器。它是 npm 的直接替代品&#xff0c;但速度更快、效率更高。 为什么更有效率&#xff1f;当你安装一个包时&#xff0c;我们将它保存在你电脑上的全局存储中&#xff0c;然后我们从它创建一个硬链接而不是复制。也就是说&#xff1a;对于模块的…

8.移动端学习-rem适配方案

1.适配方案 1、当设备尺寸发生变化时&#xff0c;页面宽高等比例变化 2、使用媒体查询根据不同设备按比例设置html字体大小&#xff0c;页面元素使用rem做单位&#xff0c;当html字体大小变化&#xff0c;元素尺寸也会发生变化&#xff0c;从而达到等比缩放的适配 2.rem实际开…

ubuntu18.04运行ORB_SLAM2

1、基础工具安装 安装cmake、git、gcc、g。 sudo apt-get install cmake git gcc g 2、安装Eigen库 在终端输入以下代码。 sudo apt-get install libeigen3-dev 3、安装Pangolin0.5 版本过高会导致错误&#xff0c;安装依赖项。 sudo apt-get install libglew-dev libpyth…

Hadoop之Hdfs

一、基本概述 1、定义 HDFS&#xff08;Hadoop Distributed File System&#xff09;&#xff0c;它是一个文件系统&#xff0c;用于存储文件&#xff0c;通过目 录树来定位文件&#xff1b;其次&#xff0c;它是分布式的。HDFS 的使用场景&#xff1a;适合一次写入&#xff0…

这是长新冠,还是我老了?浙江出国抢订单又抢CTO;脉脉发布人才迁徙报告;元宇宙产业生态图谱;GitHub今日热榜 | ShowMeAI资讯日报

&#x1f440;日报合辑 | &#x1f3a1;AI应用与工具大全 | &#x1f514;公众号资料下载 | &#x1f369;韩信子 &#x1f3a1; 这是长新冠&#xff0c;还是我老了&#xff1f; 感染后身体出现了疲劳、关节疼痛、咳嗽等新症状&#xff1f;你并不孤单&#xff01;约翰霍普金斯…

数据结构进阶 二叉树OJ题一

作者&#xff1a;小萌新 专栏&#xff1a;数据结构进阶 作者简介&#xff1a;大二学生 希望能和大家一起进步&#xff01; 本篇博客简介&#xff1a;介绍几道二叉树的oj题 二叉树OJ题题目一 根据二叉树创建字符串题目二 二叉树的层序遍历题目三 二叉树的最近公共祖先题目一 根据…