@@ -3,103 +3,97 @@ import Layout from "../../layouts/Layout.astro";
3
3
---
4
4
5
5
<script >
6
- import {
7
- useEffectPass,
8
- useWebGLContext,
9
- useCompositor,
10
- useRenderPass,
11
- useResizeObserver,
12
- } from "usegl";
13
- import {
14
- fragmentShaderSource,
15
- vertexShaderSource,
16
- mipmapFragmentShaderSource,
17
- blurFragmentShaderSource,
18
- combineFragmentShaderSource,
19
- } from "../../shaders/bloom";
20
- import { incrementRenderCount } from "../../components/renderCount";
21
-
22
- const canvas = document.querySelector("canvas");
23
-
24
- const { gl, setSize: resizeCanvas } = useWebGLContext(canvas);
25
-
26
- const positions: number[] = [];
27
- const particleCount = 100;
28
-
29
- const squareSize = Math.sqrt(particleCount) / 2;
30
- for (let i = 0; i < squareSize; i++) {
31
- for (let j = 0; j < squareSize; j++) {
32
- positions.push(i / squareSize);
33
- positions.push(j / squareSize);
34
- positions.push(-i / squareSize);
35
- positions.push(-j / squareSize);
36
- positions.push(i / squareSize);
37
- positions.push(-j / squareSize);
38
- positions.push(-i / squareSize);
39
- positions.push(j / squareSize);
40
- }
41
- }
42
-
43
- const particlesPass = useRenderPass(gl, {
44
- fragment: fragmentShaderSource,
45
- vertex: vertexShaderSource,
46
- attributes: {
47
- a_position: {
48
- data: positions,
49
- size: 2,
50
- },
51
- },
52
- });
53
-
54
- const mipmapsPass = useEffectPass({
55
- fragment: mipmapFragmentShaderSource,
56
- });
57
-
58
- const horizontalBlurPass = useEffectPass({
59
- fragment: blurFragmentShaderSource,
60
- uniforms: {
61
- u_direction: [1, 0],
62
- },
63
- });
64
-
65
- const verticalBlurPass = useEffectPass({
66
- fragment: blurFragmentShaderSource,
67
- uniforms: {
68
- u_direction: [0, 1],
69
- },
70
- });
71
-
72
- const combinePass = useEffectPass({
73
- fragment: combineFragmentShaderSource,
74
- uniforms: {
75
- u_image: () => particlesPass.target.texture,
76
- u_bloomTexture: () => verticalBlurPass.target.texture,
77
- },
78
- });
79
-
80
- const compositor = useCompositor(gl, particlesPass, [
81
- mipmapsPass,
82
- horizontalBlurPass,
83
- verticalBlurPass,
84
- combinePass,
85
- ]);
86
-
87
- useResizeObserver(canvas, ({ devicePixelSize }) => {
88
- resizeCanvas(devicePixelSize.width, devicePixelSize.height);
89
-
90
- compositor.setSize(devicePixelSize);
91
- compositor.render();
92
- });
93
-
94
- particlesPass.onAfterRender(incrementRenderCount);
6
+ import { useEffectPass, useWebGLCanvas } from "usegl";
7
+ import { fragment, vertex, mipmapsShader, blurShader, combineShader } from "../../shaders/bloom";
8
+ import { incrementRenderCount } from "../../components/renderCount";
9
+
10
+ const mipmapsPass = useEffectPass({
11
+ fragment: mipmapsShader,
12
+ });
13
+
14
+ const horizontalBlurPass = useEffectPass({
15
+ fragment: blurShader,
16
+ uniforms: {
17
+ u_direction: [1, 0],
18
+ },
19
+ });
20
+
21
+ const verticalBlurPass = useEffectPass({
22
+ fragment: blurShader,
23
+ uniforms: {
24
+ u_direction: [0, 1],
25
+ },
26
+ });
27
+
28
+ const combinePass = useEffectPass({
29
+ fragment: combineShader,
30
+ uniforms: {
31
+ u_image: ({ inputPass }) => inputPass.target!.texture,
32
+ u_bloomTexture: () => verticalBlurPass.target!.texture,
33
+ },
34
+ });
35
+
36
+ const bloomEffect = [mipmapsPass, horizontalBlurPass, verticalBlurPass, combinePass];
37
+
38
+ const vignetteEffect = useEffectPass({
39
+ fragment: /* glsl */ `
40
+ uniform sampler2D uTexture;
41
+ varying vec2 vUv;
42
+
43
+ #define SIZE .6 // (0.0 - 1.0)
44
+ #define ROUNDNESS .7 // (0.0 = rectangle, 1.0 = round)
45
+ #define STRENGTH .6 // (0.0 - 1.0)
46
+
47
+ float vignette() {
48
+ vec2 centered = vUv * 2.0 - 1.0;
49
+ float circDist = length(centered);
50
+ float rectDist = max(abs(centered.x), abs(centered.y));
51
+ float dist = mix(rectDist, circDist, ROUNDNESS);
52
+ return 1. - smoothstep(SIZE, SIZE * 2., dist) * STRENGTH;
53
+ }
54
+
55
+ void main() {
56
+ vec4 color = texture(uTexture, vUv);
57
+ color.rgb *= vignette();
58
+ gl_FragColor = color;
59
+ }
60
+ `,
61
+ });
62
+
63
+ const { gl, onAfterRender } = useWebGLCanvas({
64
+ canvas: "#glCanvas",
65
+ fragment: fragment,
66
+ vertex: vertex,
67
+ attributes: {
68
+ a_position: {
69
+ data: [
70
+ [0.1, 0.5],
71
+ [-0.3, 0],
72
+ [0.2, -0.1],
73
+ ].flat(),
74
+ size: 2,
75
+ },
76
+ a_size: {
77
+ data: [100, 300, 200],
78
+ size: 1,
79
+ },
80
+ },
81
+ postEffects: [vignetteEffect, bloomEffect],
82
+ });
83
+
84
+ gl.enable(gl.BLEND);
85
+ gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
86
+ gl.clearColor(0, 0.07, 0.15, 1);
87
+
88
+ onAfterRender(incrementRenderCount);
95
89
</script >
96
90
97
91
<Layout title =" Bloom" >
98
- <canvas ></canvas >
92
+ <canvas id = " glCanvas " ></canvas >
99
93
</Layout >
100
94
101
95
<style >
102
- canvas {
103
- aspect-ratio: 3 / 2;
104
- }
96
+ canvas {
97
+ aspect-ratio: 3 / 2;
98
+ }
105
99
</style >
0 commit comments