Skip to content

Commit edb29de

Browse files
authored
Add files via upload
1 parent 2525164 commit edb29de

File tree

1 file changed

+174
-0
lines changed

1 file changed

+174
-0
lines changed

Three.js实用知识点笔记.md

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# Three.js实用知识点笔记
2+
3+
从今天开始,在本文中记录实际 Three.js 开发过程中所遇到的知识点。
4+
5+
6+
7+
<br>
8+
9+
**关于示例代码的一般约定说明:**
10+
11+
1. 举例的时候,很多都是伪代码
12+
2. 为了保证代码简洁,所以在实用某些类时没有添加 `Three.` 前缀
13+
3. 绝大多数时候都使用箭头函数
14+
4. 使用 Xxx 泛指同一类型,例如 XxxCamer 泛指各类相机
15+
16+
17+
18+
<br>
19+
20+
#### 01、每一个Object3D对象都只能有一个父级
21+
22+
这里说的 Object3D 实际上包括所有继承于 Object3D 的子类,例如 Mesh、Camera、Group 等
23+
24+
举例说明:
25+
26+
```
27+
const mesh = new Mesh(geometry,material)
28+
29+
const sceneA = new Scene()
30+
const sceneB = new Scene()
31+
32+
sceneA.add(mesh)
33+
sceneB.add(mesh)
34+
```
35+
36+
由于 mesh 只能有一个父类,所以当 sceneB 也执行 .add(mesh) 后,sceneA.children 中会自动删除掉 mesh。
37+
38+
39+
40+
<br>
41+
42+
#### 02、克隆或复制 Mesh 不会在内存中真正复制出一份 顶点(geometry)和材质(material),它们使用的是引用,而不是复制
43+
44+
Object3D 拥有 .clone() 和 .copy() 两个方法,Mesh 继承于 Object3D,所以也拥有这两个方法。
45+
46+
在 Mesh 类中扩展了 .copy() 方法,但是针对 Mesh 内部的属性 顶点和材质,实用的是引用而不是真正内存中的复制。
47+
48+
```
49+
const meshB = meshA.clone()
50+
```
51+
52+
上述代码中新复制得到的 meshB 仅仅复制了 meshA 的一些变换相关的属性,例如 matrix 等,但是对于占内存大头的 顶点和材质 这两项实用的是引用。
53+
54+
也就是说此时 meshA 和 meshB 它们共用了一份 geometry 和 material。
55+
56+
> 不用担心因为多复制了几份 mesh 而增加很多内存。
57+
58+
59+
60+
<br>
61+
62+
#### 03、添加场景(scene)或其他Object3D渲染之前和渲染之后的回调函数
63+
64+
场景 scene 继承于 Object3D,而 Object3D 可以配置 2 个渲染之前或之后的回调函数:
65+
66+
```
67+
scene.onBeforeRender = () => { ...}
68+
scnet.onAfterRende = () => { ... }
69+
```
70+
71+
使用场景举例:假设我们希望不渲染场景上的某一类元素,那么我们可以在 renderer.render() 之前通过上面 2 个回调函数进行设置
72+
73+
```
74+
scene.onBeforeRender = () => {
75+
scene.children.forEach(item => {
76+
if(item.type === 'Points'){
77+
item.visible = false
78+
}
79+
})
80+
}
81+
82+
scene.onAfterRender = () => {
83+
scene.children.forEach(item => item.visible = true)
84+
}
85+
86+
renderer.render(scene,camera)
87+
```
88+
89+
90+
91+
<br>
92+
93+
#### 04、通过 .layers 控制物体是否被渲染
94+
95+
在 Three.js 中 .layers 对应的是 Layers 这个类,Three.js 规定 Layers 级别的值取值范围为 0 - 32。
96+
97+
> 你可以把 layers 翻译成 “级别”,也可以称呼为 “层级”
98+
99+
任何继承于 Object3D 的类,例如 相机、物体 等都具有 .layers 属性。
100+
101+
它们的 .layers 默认级别都为 0。
102+
103+
不能通过直接给 .layers 赋值的方式修改级别,而是应该通过 .set(value) 这种形式。
104+
105+
```
106+
mymesh.layers.set(1)
107+
camera.layers.set(1)
108+
```
109+
110+
111+
112+
<br>
113+
114+
对于相机而言,它只能渲染出同一级别的物体元素。
115+
116+
```
117+
const meshA = new Mesh(...)
118+
//meshA.layers.set(0) //默认就是 0
119+
120+
const meshB = new Mesh(...)
121+
meshB.layers.set(1)
122+
123+
const scene = new Scene()
124+
scene.add(meshA)
125+
scene.add(meshB)
126+
127+
const cameraA = new XxxCamera()
128+
//cameraA.layers.set(0) //默认就是 0
129+
130+
const cameraB = new XxxCamera()
131+
cameraB.layers.set(1)
132+
```
133+
134+
在上面代码中:
135+
136+
1. 我们按照默认的形式添加了 meshA、cameraA,它们默认层级为 0
137+
2. 手动修改了 meshB、cameraB 的 .layers 层级为 1
138+
139+
<br>
140+
141+
那么当执行下面的代码:
142+
143+
```
144+
renderer.render(scene, cameraA)
145+
renderer.render(scene. cameraB)
146+
```
147+
148+
1. cameraA 只会渲染出场景中同一级别的 meshA
149+
2. cameraB 只会渲染出场景中同一级别的 meshB
150+
151+
152+
153+
<br>
154+
155+
也可以选择随时修改 meshA 的 .layers 值,这样 cameraB 就可以渲染到它了。
156+
157+
```
158+
meshA.layers.set(1)
159+
renderer.render(secen, cameraB)
160+
```
161+
162+
163+
164+
<br>
165+
166+
换句话说,假设我们希望控制是否渲染场景中某些元素,那么有 2 种途径:
167+
168+
1. 设置其 .visible 的值来决定是否渲染
169+
2. 设置其 .layers 的值来决定只被同一层级的相机渲染
170+
171+
172+
173+
<br>
174+

0 commit comments

Comments
 (0)