You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/posts/threejs-journey-notes-6-shaders-part1.md
+273-1Lines changed: 273 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -35,7 +35,7 @@ Two types of shaders
35
35
- *send data from vertex shader to fragment shader*, this kind of data is called **varying**
36
36
- 中间状态会 get interpolated,比如三角形每个顶点的 color 不一样的话,中间的点的颜色就会混合三种颜色。也不仅是 color 有这种效果
37
37
38
-
![[Screenshot 2025-04-03 at 11.00.10.png]]
38
+
39
39
40
40
Why creating our own shaders
41
41
- Three.js materials are limited
@@ -182,3 +182,275 @@ void main()
182
182
// ...
183
183
}
184
184
```
185
+
186
+
## Understanding the Fragment Shader
187
+
188
+
comes after vertex shader
189
+
190
+
```glsl
191
+
// instruction to decide how precise a float be
192
+
// highp: preformance hit and might not work on some devices
193
+
// mediump
194
+
// lowp: can create bugs by the lack of precision
195
+
precision mediump float;
196
+
197
+
void main()
198
+
{
199
+
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
200
+
}
201
+
```
202
+
203
+
same as vertex shader, the goal is to set `gl_FragColor`, it's also a `vec4` which is corresponding to color channels (`r`, `g`, `b`, `a`), each property goes from 0.0 to 1.0.
204
+
205
+
If alpha below 1.0, we need to set `transparent: true` in `RawShaderMaterial`.
206
+
207
+
208
+
## Attributes - only in Vertex Shader
209
+
210
+
For three.js geometry, there is already one attribute named `position` that contains the `vec3` coordinates of each vertex.
modelPosition.z += aRandom * 0.1; // apply on y to make the plane with random spikes
239
+
240
+
// ...
241
+
}
242
+
```
243
+
244
+
## Varyings - send data from Vertex Shader to Fragment Shader
245
+
246
+
define a varying called `vRandom` and assign it with `aRandom` in vertex shader, then `vRandom` can be used in fragment shader.
247
+
248
+
```glsl
249
+
// vertex.glsl
250
+
attribute float aRandom;
251
+
varying float vRandom;
252
+
253
+
void main()
254
+
{
255
+
// ...
256
+
257
+
vRandom = aRandom;
258
+
}
259
+
```
260
+
261
+
```glsl
262
+
// fragment.glsl
263
+
precision mediump float;
264
+
265
+
varying float vRandom;
266
+
267
+
void main()
268
+
{
269
+
gl_FragColor = vec4(0.5, vRandom, 1.0, 1.0);
270
+
}
271
+
```
272
+
273
+
Then the spikes on the plane is colored, and values between the vertices are **interpolated** - If the GPU is drawing a fragment right between two vertices —one having a varying of `1.0` and the other having a varying of `0.0`—the fragment value will be `0.5`.
Texture can also be used as a uniform, and we need the UV coordinates to make the texture applied accordingly.
357
+
`uv` is attributes already defined in `geometry.attributes.uv`, we can retrieve it directly.
358
+
359
+
So we need to retrieve the attribute `uv` and assign it to another varying in vertex shader, and then fragment shader can use the varying to apply on texture.
360
+
361
+
```glsl
362
+
// vertex.glsl
363
+
364
+
// ...
365
+
attribute vec2 uv;
366
+
367
+
varying vec2 vUv;
368
+
369
+
void main()
370
+
{
371
+
// ...
372
+
373
+
vUv = uv;
374
+
}
375
+
```
376
+
377
+
```glsl
378
+
// fragment.glsl
379
+
380
+
precision mediump float;
381
+
382
+
uniform vec3 uColor;
383
+
uniform sampler2D uTexture;
384
+
385
+
varying vec2 vUv;
386
+
387
+
void main()
388
+
{
389
+
vec4 textureColor = texture2D(uTexture, vUv);
390
+
gl_FragColor = textureColor;
391
+
}
392
+
```
393
+
394
+
## Color variations - as shadows (not accurate)
395
+
396
+
Store the wind elevation in a variable in vertex shader and send it to fragment shader:
- The Art of Code Youtube Channel: [https://www.youtube.com/channel/UCcAlTqd9zID6aNX3TzwxJXg](https://www.youtube.com/channel/UCcAlTqd9zID6aNX3TzwxJXg)
0 commit comments