@iamahmarfaraz/react-liquid-bg 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +161 -0
- package/dist/index.cjs.js +403 -0
- package/dist/index.esm.js +1560 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# react-liquid-bg
|
|
2
|
+
|
|
3
|
+
A high-performance WebGL liquid fluid background component for React.
|
|
4
|
+
|
|
5
|
+
Built and maintained by **Ahmar Faraz**.
|
|
6
|
+
|
|
7
|
+
`react-liquid-bg` provides a real-time, GPU-accelerated liquid simulation using WebGL and GLSL shaders.
|
|
8
|
+
It is designed for production React applications where visuals, performance, and clean architecture matter.
|
|
9
|
+
|
|
10
|
+
This is **not** a CSS animation or video background.
|
|
11
|
+
This is a real fluid simulation running entirely on the GPU.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- Real-time WebGL fluid simulation
|
|
18
|
+
- GPU-accelerated shader pipeline
|
|
19
|
+
- Interactive mouse-based fluid motion
|
|
20
|
+
- Full-screen responsive canvas
|
|
21
|
+
- Simple React component API
|
|
22
|
+
- Zero external animation libraries
|
|
23
|
+
- Production-grade architecture
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install react-liquid-bg
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
or
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
yarn add react-liquid-bg
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Basic Usage
|
|
42
|
+
|
|
43
|
+
```jsx
|
|
44
|
+
import LiquidBG from "react-liquid-bg";
|
|
45
|
+
|
|
46
|
+
function App() {
|
|
47
|
+
return (
|
|
48
|
+
<div className="relative min-h-screen">
|
|
49
|
+
<LiquidBG enabled={true} />
|
|
50
|
+
<div className="relative z-10">Your App Content</div>
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default App;
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Conditional Usage
|
|
61
|
+
|
|
62
|
+
```jsx
|
|
63
|
+
<LiquidBG enabled={tab === null} />
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The simulation starts when `enabled` is true and pauses when false.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Props
|
|
71
|
+
|
|
72
|
+
| Prop | Type | Required | Description |
|
|
73
|
+
|-----|------|----------|-------------|
|
|
74
|
+
| enabled | boolean | Yes | Starts or pauses the fluid simulation |
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## How It Works
|
|
79
|
+
|
|
80
|
+
The engine is a custom WebGL fluid solver using:
|
|
81
|
+
|
|
82
|
+
- Velocity advection
|
|
83
|
+
- Density advection
|
|
84
|
+
- Pressure solving
|
|
85
|
+
- Curl and vorticity forces
|
|
86
|
+
- Double framebuffer (ping-pong) rendering
|
|
87
|
+
- GLSL fragment shaders
|
|
88
|
+
|
|
89
|
+
All heavy computation is done on the GPU for maximum performance.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Architecture Overview
|
|
94
|
+
|
|
95
|
+
### React Layer
|
|
96
|
+
- Exposes `<LiquidBG />`
|
|
97
|
+
- Controls lifecycle and canvas mount
|
|
98
|
+
- No re-renders during simulation
|
|
99
|
+
|
|
100
|
+
### Engine Layer
|
|
101
|
+
- WebGL context initialization
|
|
102
|
+
- Shader compilation and linking
|
|
103
|
+
- Framebuffer and texture management
|
|
104
|
+
|
|
105
|
+
### Simulation Layer
|
|
106
|
+
- Velocity field updates
|
|
107
|
+
- Pressure correction
|
|
108
|
+
- Vorticity and curl
|
|
109
|
+
- Density transport
|
|
110
|
+
|
|
111
|
+
### Rendering Layer
|
|
112
|
+
- Shader-based rendering
|
|
113
|
+
- Optional bloom and dithering
|
|
114
|
+
- Fullscreen adaptive scaling
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Interaction
|
|
119
|
+
|
|
120
|
+
- Mouse movement injects force
|
|
121
|
+
- Clicks generate splats
|
|
122
|
+
- Idle state keeps subtle motion
|
|
123
|
+
- Auto-resizes on window resize
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Performance
|
|
128
|
+
|
|
129
|
+
- Fully GPU-driven
|
|
130
|
+
- No React state updates per frame
|
|
131
|
+
- Optimized shaders and buffers
|
|
132
|
+
- Suitable for production apps
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Browser Support
|
|
137
|
+
|
|
138
|
+
- Chrome (recommended)
|
|
139
|
+
- Edge
|
|
140
|
+
- Firefox (WebGL enabled)
|
|
141
|
+
- Safari (WebGL enabled)
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## License
|
|
146
|
+
|
|
147
|
+
MIT License
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Author
|
|
152
|
+
|
|
153
|
+
**Ahmar Faraz**
|
|
154
|
+
Software Engineer
|
|
155
|
+
|
|
156
|
+
GitHub: https://github.com/iamahmarfaraz
|
|
157
|
+
LinkedIn: https://www.linkedin.com/in/iamahmarfaraz/
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
If you use this library in production, attribution is appreciated.
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const re=require("react");var ee={exports:{}},V={};var oe;function ce(){if(oe)return V;oe=1;var f=Symbol.for("react.transitional.element"),e=Symbol.for("react.fragment");function r(i,v,n){var x=null;if(n!==void 0&&(x=""+n),v.key!==void 0&&(x=""+v.key),"key"in v){n={};for(var P in v)P!=="key"&&(n[P]=v[P])}else n=v;return v=n.ref,{$$typeof:f,type:i,key:x,ref:v!==void 0?v:null,props:n}}return V.Fragment=e,V.jsx=r,V.jsxs=r,V}var K={};var ae;function ve(){return ae||(ae=1,process.env.NODE_ENV!=="production"&&(function(){function f(t){if(t==null)return null;if(typeof t=="function")return t.$$typeof===w?null:t.displayName||t.name||null;if(typeof t=="string")return t;switch(t){case S:return"Fragment";case E:return"Profiler";case D:return"StrictMode";case C:return"Suspense";case b:return"SuspenseList";case Q:return"Activity"}if(typeof t=="object")switch(typeof t.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),t.$$typeof){case N:return"Portal";case Z:return t.displayName||"Context";case B:return(t._context.displayName||"Context")+".Consumer";case A:var m=t.render;return t=t.displayName,t||(t=m.displayName||m.name||"",t=t!==""?"ForwardRef("+t+")":"ForwardRef"),t;case j:return m=t.displayName||null,m!==null?m:f(t.type)||"Memo";case X:m=t._payload,t=t._init;try{return f(t(m))}catch{}}return null}function e(t){return""+t}function r(t){try{e(t);var m=!1}catch{m=!0}if(m){m=console;var o=m.error,a=typeof Symbol=="function"&&Symbol.toStringTag&&t[Symbol.toStringTag]||t.constructor.name||"Object";return o.call(m,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",a),e(t)}}function i(t){if(t===S)return"<>";if(typeof t=="object"&&t!==null&&t.$$typeof===X)return"<...>";try{var m=f(t);return m?"<"+m+">":"<...>"}catch{return"<...>"}}function v(){var t=Y.A;return t===null?null:t.getOwner()}function n(){return Error("react-stack-top-frame")}function x(t){if($.call(t,"key")){var m=Object.getOwnPropertyDescriptor(t,"key").get;if(m&&m.isReactWarning)return!1}return t.key!==void 0}function P(t,m){function o(){H||(H=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",m))}o.isReactWarning=!0,Object.defineProperty(t,"key",{get:o,configurable:!0})}function k(){var t=f(this.type);return O[t]||(O[t]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),t=this.props.ref,t!==void 0?t:null}function c(t,m,o,a,u,s){var l=o.ref;return t={$$typeof:F,type:t,key:m,props:o,_owner:a},(l!==void 0?l:null)!==null?Object.defineProperty(t,"ref",{enumerable:!1,get:k}):Object.defineProperty(t,"ref",{enumerable:!1,value:null}),t._store={},Object.defineProperty(t._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(t,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(t,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:u}),Object.defineProperty(t,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:s}),Object.freeze&&(Object.freeze(t.props),Object.freeze(t)),t}function U(t,m,o,a,u,s){var l=m.children;if(l!==void 0)if(a)if(te(l)){for(a=0;a<l.length;a++)J(l[a]);Object.freeze&&Object.freeze(l)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else J(l);if($.call(m,"key")){l=f(t);var g=Object.keys(m).filter(function(T){return T!=="key"});a=0<g.length?"{key: someKey, "+g.join(": ..., ")+": ...}":"{key: someKey}",G[l+a]||(g=0<g.length?"{"+g.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
|
|
2
|
+
let props = %s;
|
|
3
|
+
<%s {...props} />
|
|
4
|
+
React keys must be passed directly to JSX without using spread:
|
|
5
|
+
let props = %s;
|
|
6
|
+
<%s key={someKey} {...props} />`,a,l,g,l),G[l+a]=!0)}if(l=null,o!==void 0&&(r(o),l=""+o),x(m)&&(r(m.key),l=""+m.key),"key"in m){o={};for(var p in m)p!=="key"&&(o[p]=m[p])}else o=m;return l&&P(o,typeof t=="function"?t.displayName||t.name||"Unknown":t),c(t,l,o,v(),u,s)}function J(t){y(t)?t._store&&(t._store.validated=1):typeof t=="object"&&t!==null&&t.$$typeof===X&&(t._payload.status==="fulfilled"?y(t._payload.value)&&t._payload.value._store&&(t._payload.value._store.validated=1):t._store&&(t._store.validated=1))}function y(t){return typeof t=="object"&&t!==null&&t.$$typeof===F}var d=re,F=Symbol.for("react.transitional.element"),N=Symbol.for("react.portal"),S=Symbol.for("react.fragment"),D=Symbol.for("react.strict_mode"),E=Symbol.for("react.profiler"),B=Symbol.for("react.consumer"),Z=Symbol.for("react.context"),A=Symbol.for("react.forward_ref"),C=Symbol.for("react.suspense"),b=Symbol.for("react.suspense_list"),j=Symbol.for("react.memo"),X=Symbol.for("react.lazy"),Q=Symbol.for("react.activity"),w=Symbol.for("react.client.reference"),Y=d.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,$=Object.prototype.hasOwnProperty,te=Array.isArray,M=console.createTask?console.createTask:function(){return null};d={react_stack_bottom_frame:function(t){return t()}};var H,O={},L=d.react_stack_bottom_frame.bind(d,n)(),W=M(i(n)),G={};K.Fragment=S,K.jsx=function(t,m,o){var a=1e4>Y.recentlyCreatedOwnerStacks++;return U(t,m,o,!1,a?Error("react-stack-top-frame"):L,a?M(i(t)):W)},K.jsxs=function(t,m,o){var a=1e4>Y.recentlyCreatedOwnerStacks++;return U(t,m,o,!0,a?Error("react-stack-top-frame"):L,a?M(i(t)):W)}})()),K}var ne;function de(){return ne||(ne=1,process.env.NODE_ENV==="production"?ee.exports=ce():ee.exports=ve()),ee.exports}var ge=de();let q={sim_resolution:128,dye_resolution:512,paused:!1,clamp_values:!0,embedded_dither:!0,dissipation:.985,velocity:.995,pressure:.8,pressure_iteration:20,fluid_color:[[0,0,0],[.4,.2,0]],curl:15,emitter_size:.6,render_shaders:!0,multi_color:!0,render_bloom:!1,bloom_iterations:8,bloom_resolution:256,intensity:.8,threshold:.6,soft_knee:.7,background_color:{r:15,g:15,b:15},transparent:!0};const ie={alpha:!0,depth:!1,stencil:!1,antialias:!1,preserveDrawingBuffer:!1,powerPreference:"default"},_={vertex:`
|
|
7
|
+
precision highp float;
|
|
8
|
+
|
|
9
|
+
attribute vec2 aPosition;
|
|
10
|
+
varying vec2 vUv;
|
|
11
|
+
varying vec2 vL;
|
|
12
|
+
varying vec2 vR;
|
|
13
|
+
varying vec2 vT;
|
|
14
|
+
varying vec2 vB;
|
|
15
|
+
uniform vec2 texelSize;
|
|
16
|
+
|
|
17
|
+
void main () {
|
|
18
|
+
vUv = aPosition * 0.5 + 0.5;
|
|
19
|
+
vL = vUv - vec2(texelSize.x, 0.0);
|
|
20
|
+
vR = vUv + vec2(texelSize.x, 0.0);
|
|
21
|
+
vT = vUv + vec2(0.0, texelSize.y);
|
|
22
|
+
vB = vUv - vec2(0.0, texelSize.y);
|
|
23
|
+
gl_Position = vec4(aPosition, 0.0, 1.0);
|
|
24
|
+
}`,clear:`
|
|
25
|
+
precision mediump float;
|
|
26
|
+
precision mediump sampler2D;
|
|
27
|
+
|
|
28
|
+
varying highp vec2 vUv;
|
|
29
|
+
uniform sampler2D uTexture;
|
|
30
|
+
uniform float value;
|
|
31
|
+
|
|
32
|
+
void main () {
|
|
33
|
+
gl_FragColor = value * texture2D(uTexture, vUv);
|
|
34
|
+
}
|
|
35
|
+
`,color:`
|
|
36
|
+
precision mediump float;
|
|
37
|
+
|
|
38
|
+
uniform vec4 color;
|
|
39
|
+
|
|
40
|
+
void main () {
|
|
41
|
+
gl_FragColor = color;
|
|
42
|
+
}
|
|
43
|
+
`,background:`
|
|
44
|
+
void main() {
|
|
45
|
+
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
|
46
|
+
}
|
|
47
|
+
`,display:`
|
|
48
|
+
precision highp float;
|
|
49
|
+
precision highp sampler2D;
|
|
50
|
+
|
|
51
|
+
varying vec2 vUv;
|
|
52
|
+
uniform sampler2D uTexture;
|
|
53
|
+
|
|
54
|
+
void main () {
|
|
55
|
+
vec3 C = texture2D(uTexture, vUv).rgb;
|
|
56
|
+
float a = max(C.r, max(C.g, C.b));
|
|
57
|
+
gl_FragColor = vec4(C, a);
|
|
58
|
+
}
|
|
59
|
+
`,displayBloom:`
|
|
60
|
+
precision highp float;
|
|
61
|
+
precision highp sampler2D;
|
|
62
|
+
|
|
63
|
+
varying vec2 vUv;
|
|
64
|
+
uniform sampler2D uTexture;
|
|
65
|
+
uniform sampler2D uBloom;
|
|
66
|
+
uniform sampler2D uDithering;
|
|
67
|
+
uniform vec2 ditherScale;
|
|
68
|
+
|
|
69
|
+
void main () {
|
|
70
|
+
vec3 C = texture2D(uTexture, vUv).rgb;
|
|
71
|
+
vec3 bloom = texture2D(uBloom, vUv).rgb;
|
|
72
|
+
vec3 noise = texture2D(uDithering, vUv * ditherScale).rgb;
|
|
73
|
+
noise = noise * 2.0 - 1.0;
|
|
74
|
+
bloom += noise / 800.0;
|
|
75
|
+
bloom = pow(bloom.rgb, vec3(1.0 / 2.2));
|
|
76
|
+
C += bloom;
|
|
77
|
+
float a = max(C.r, max(C.g, C.b));
|
|
78
|
+
gl_FragColor = vec4(C, a);
|
|
79
|
+
}
|
|
80
|
+
`,displayShading:`
|
|
81
|
+
precision highp float;
|
|
82
|
+
precision highp sampler2D;
|
|
83
|
+
|
|
84
|
+
varying vec2 vUv;
|
|
85
|
+
varying vec2 vL;
|
|
86
|
+
varying vec2 vR;
|
|
87
|
+
varying vec2 vT;
|
|
88
|
+
varying vec2 vB;
|
|
89
|
+
uniform sampler2D uTexture;
|
|
90
|
+
uniform vec2 texelSize;
|
|
91
|
+
|
|
92
|
+
void main () {
|
|
93
|
+
vec3 L = texture2D(uTexture, vL).rgb;
|
|
94
|
+
vec3 R = texture2D(uTexture, vR).rgb;
|
|
95
|
+
vec3 T = texture2D(uTexture, vT).rgb;
|
|
96
|
+
vec3 B = texture2D(uTexture, vB).rgb;
|
|
97
|
+
vec3 C = texture2D(uTexture, vUv).rgb;
|
|
98
|
+
|
|
99
|
+
float dx = length(R) - length(L);
|
|
100
|
+
float dy = length(T) - length(B);
|
|
101
|
+
|
|
102
|
+
vec3 n = normalize(vec3(dx, dy, length(texelSize)));
|
|
103
|
+
vec3 l = vec3(0.0, 0.0, 1.0);
|
|
104
|
+
|
|
105
|
+
float diffuse = clamp(dot(n, l) + 0.7, 0.7, 1.0);
|
|
106
|
+
C.rgb *= diffuse;
|
|
107
|
+
|
|
108
|
+
float a = max(C.r, max(C.g, C.b));
|
|
109
|
+
gl_FragColor = vec4(C, a);
|
|
110
|
+
}
|
|
111
|
+
`,displayBloomShading:`
|
|
112
|
+
precision highp float;
|
|
113
|
+
precision highp sampler2D;
|
|
114
|
+
|
|
115
|
+
varying vec2 vUv;
|
|
116
|
+
varying vec2 vL;
|
|
117
|
+
varying vec2 vR;
|
|
118
|
+
varying vec2 vT;
|
|
119
|
+
varying vec2 vB;
|
|
120
|
+
uniform sampler2D uTexture;
|
|
121
|
+
uniform sampler2D uBloom;
|
|
122
|
+
uniform sampler2D uDithering;
|
|
123
|
+
uniform vec2 ditherScale;
|
|
124
|
+
uniform vec2 texelSize;
|
|
125
|
+
|
|
126
|
+
void main () {
|
|
127
|
+
vec3 L = texture2D(uTexture, vL).rgb;
|
|
128
|
+
vec3 R = texture2D(uTexture, vR).rgb;
|
|
129
|
+
vec3 T = texture2D(uTexture, vT).rgb;
|
|
130
|
+
vec3 B = texture2D(uTexture, vB).rgb;
|
|
131
|
+
vec3 C = texture2D(uTexture, vUv).rgb;
|
|
132
|
+
|
|
133
|
+
float dx = length(R) - length(L);
|
|
134
|
+
float dy = length(T) - length(B);
|
|
135
|
+
|
|
136
|
+
vec3 n = normalize(vec3(dx, dy, length(texelSize)));
|
|
137
|
+
vec3 l = vec3(0.0, 0.0, 1.0);
|
|
138
|
+
|
|
139
|
+
float diffuse = clamp(dot(n, l) + 0.7, 0.7, 1.0);
|
|
140
|
+
C *= diffuse;
|
|
141
|
+
|
|
142
|
+
vec3 bloom = texture2D(uBloom, vUv).rgb;
|
|
143
|
+
vec3 noise = texture2D(uDithering, vUv * ditherScale).rgb;
|
|
144
|
+
noise = noise * 2.0 - 1.0;
|
|
145
|
+
bloom += noise / 800.0;
|
|
146
|
+
bloom = pow(bloom.rgb, vec3(1.0 / 2.2));
|
|
147
|
+
C += bloom;
|
|
148
|
+
|
|
149
|
+
float a = max(C.r, max(C.g, C.b));
|
|
150
|
+
gl_FragColor = vec4(C, a);
|
|
151
|
+
}
|
|
152
|
+
`,bloomPreFilter:`
|
|
153
|
+
precision mediump float;
|
|
154
|
+
precision mediump sampler2D;
|
|
155
|
+
|
|
156
|
+
varying vec2 vUv;
|
|
157
|
+
uniform sampler2D uTexture;
|
|
158
|
+
uniform vec3 curve;
|
|
159
|
+
uniform float threshold;
|
|
160
|
+
|
|
161
|
+
void main () {
|
|
162
|
+
vec3 c = texture2D(uTexture, vUv).rgb;
|
|
163
|
+
float br = max(c.r, max(c.g, c.b));
|
|
164
|
+
float rq = clamp(br - curve.x, 0.0, curve.y);
|
|
165
|
+
rq = curve.z * rq * rq;
|
|
166
|
+
c *= max(rq, br - threshold) / max(br, 0.0001);
|
|
167
|
+
gl_FragColor = vec4(c, 0.0);
|
|
168
|
+
}
|
|
169
|
+
`,bloomBlur:`
|
|
170
|
+
precision mediump float;
|
|
171
|
+
precision mediump sampler2D;
|
|
172
|
+
|
|
173
|
+
varying vec2 vL;
|
|
174
|
+
varying vec2 vR;
|
|
175
|
+
varying vec2 vT;
|
|
176
|
+
varying vec2 vB;
|
|
177
|
+
uniform sampler2D uTexture;
|
|
178
|
+
|
|
179
|
+
void main () {
|
|
180
|
+
vec4 sum = vec4(0.0);
|
|
181
|
+
sum += texture2D(uTexture, vL);
|
|
182
|
+
sum += texture2D(uTexture, vR);
|
|
183
|
+
sum += texture2D(uTexture, vT);
|
|
184
|
+
sum += texture2D(uTexture, vB);
|
|
185
|
+
sum *= 0.25;
|
|
186
|
+
gl_FragColor = sum;
|
|
187
|
+
}
|
|
188
|
+
`,bloomFinal:`
|
|
189
|
+
precision mediump float;
|
|
190
|
+
precision mediump sampler2D;
|
|
191
|
+
|
|
192
|
+
varying vec2 vL;
|
|
193
|
+
varying vec2 vR;
|
|
194
|
+
varying vec2 vT;
|
|
195
|
+
varying vec2 vB;
|
|
196
|
+
uniform sampler2D uTexture;
|
|
197
|
+
uniform float intensity;
|
|
198
|
+
|
|
199
|
+
void main () {
|
|
200
|
+
vec4 sum = vec4(0.0);
|
|
201
|
+
sum += texture2D(uTexture, vL);
|
|
202
|
+
sum += texture2D(uTexture, vR);
|
|
203
|
+
sum += texture2D(uTexture, vT);
|
|
204
|
+
sum += texture2D(uTexture, vB);
|
|
205
|
+
sum *= 0.25;
|
|
206
|
+
gl_FragColor = sum * intensity;
|
|
207
|
+
}
|
|
208
|
+
`,splat:`
|
|
209
|
+
precision highp float;
|
|
210
|
+
precision highp sampler2D;
|
|
211
|
+
|
|
212
|
+
varying vec2 vUv;
|
|
213
|
+
uniform sampler2D uTarget;
|
|
214
|
+
uniform float aspectRatio;
|
|
215
|
+
uniform vec3 color;
|
|
216
|
+
uniform vec2 point;
|
|
217
|
+
uniform float radius;
|
|
218
|
+
|
|
219
|
+
void main () {
|
|
220
|
+
vec2 p = vUv - point.xy;
|
|
221
|
+
p.x *= aspectRatio;
|
|
222
|
+
vec3 splat = exp(-dot(p, p) / radius) * color;
|
|
223
|
+
vec3 base = texture2D(uTarget, vUv).xyz;
|
|
224
|
+
gl_FragColor = vec4(base + splat, 1.0);
|
|
225
|
+
}
|
|
226
|
+
`,advectionManualFiltering:`
|
|
227
|
+
precision highp float;
|
|
228
|
+
precision highp sampler2D;
|
|
229
|
+
|
|
230
|
+
varying vec2 vUv;
|
|
231
|
+
uniform sampler2D uVelocity;
|
|
232
|
+
uniform sampler2D uSource;
|
|
233
|
+
uniform vec2 texelSize;
|
|
234
|
+
uniform vec2 dyeTexelSize;
|
|
235
|
+
uniform float dt;
|
|
236
|
+
uniform float dissipation;
|
|
237
|
+
|
|
238
|
+
vec4 bilerp (sampler2D sam, vec2 uv, vec2 tsize) {
|
|
239
|
+
vec2 st = uv / tsize - 0.5;
|
|
240
|
+
|
|
241
|
+
vec2 iuv = floor(st);
|
|
242
|
+
vec2 fuv = fract(st);
|
|
243
|
+
|
|
244
|
+
vec4 a = texture2D(sam, (iuv + vec2(0.5, 0.5)) * tsize);
|
|
245
|
+
vec4 b = texture2D(sam, (iuv + vec2(1.5, 0.5)) * tsize);
|
|
246
|
+
vec4 c = texture2D(sam, (iuv + vec2(0.5, 1.5)) * tsize);
|
|
247
|
+
vec4 d = texture2D(sam, (iuv + vec2(1.5, 1.5)) * tsize);
|
|
248
|
+
|
|
249
|
+
return mix(mix(a, b, fuv.x), mix(c, d, fuv.x), fuv.y);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
void main () {
|
|
253
|
+
vec2 coord = vUv - dt * bilerp(uVelocity, vUv, texelSize).xy * texelSize;
|
|
254
|
+
gl_FragColor = dissipation * bilerp(uSource, coord, dyeTexelSize);
|
|
255
|
+
gl_FragColor.a = 1.0;
|
|
256
|
+
}
|
|
257
|
+
`,advection:`
|
|
258
|
+
precision highp float;
|
|
259
|
+
precision highp sampler2D;
|
|
260
|
+
|
|
261
|
+
varying vec2 vUv;
|
|
262
|
+
uniform sampler2D uVelocity;
|
|
263
|
+
uniform sampler2D uSource;
|
|
264
|
+
uniform vec2 texelSize;
|
|
265
|
+
uniform float dt;
|
|
266
|
+
uniform float dissipation;
|
|
267
|
+
|
|
268
|
+
void main () {
|
|
269
|
+
vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;
|
|
270
|
+
gl_FragColor = dissipation * texture2D(uSource, coord);
|
|
271
|
+
gl_FragColor.a = 1.0;
|
|
272
|
+
}
|
|
273
|
+
`,divergence:`
|
|
274
|
+
precision mediump float;
|
|
275
|
+
precision mediump sampler2D;
|
|
276
|
+
|
|
277
|
+
varying highp vec2 vUv;
|
|
278
|
+
varying highp vec2 vL;
|
|
279
|
+
varying highp vec2 vR;
|
|
280
|
+
varying highp vec2 vT;
|
|
281
|
+
varying highp vec2 vB;
|
|
282
|
+
uniform sampler2D uVelocity;
|
|
283
|
+
|
|
284
|
+
void main () {
|
|
285
|
+
float L = texture2D(uVelocity, vL).x;
|
|
286
|
+
float R = texture2D(uVelocity, vR).x;
|
|
287
|
+
float T = texture2D(uVelocity, vT).y;
|
|
288
|
+
float B = texture2D(uVelocity, vB).y;
|
|
289
|
+
|
|
290
|
+
vec2 C = texture2D(uVelocity, vUv).xy;
|
|
291
|
+
if (vL.x < 0.0) { L = -C.x; }
|
|
292
|
+
if (vR.x > 1.0) { R = -C.x; }
|
|
293
|
+
if (vT.y > 1.0) { T = -C.y; }
|
|
294
|
+
if (vB.y < 0.0) { B = -C.y; }
|
|
295
|
+
|
|
296
|
+
float div = 0.5 * (R - L + T - B);
|
|
297
|
+
gl_FragColor = vec4(div, 0.0, 0.0, 1.0);
|
|
298
|
+
}
|
|
299
|
+
`,curl:`
|
|
300
|
+
precision mediump float;
|
|
301
|
+
precision mediump sampler2D;
|
|
302
|
+
|
|
303
|
+
varying highp vec2 vUv;
|
|
304
|
+
varying highp vec2 vL;
|
|
305
|
+
varying highp vec2 vR;
|
|
306
|
+
varying highp vec2 vT;
|
|
307
|
+
varying highp vec2 vB;
|
|
308
|
+
uniform sampler2D uVelocity;
|
|
309
|
+
|
|
310
|
+
void main () {
|
|
311
|
+
float L = texture2D(uVelocity, vL).y;
|
|
312
|
+
float R = texture2D(uVelocity, vR).y;
|
|
313
|
+
float T = texture2D(uVelocity, vT).x;
|
|
314
|
+
float B = texture2D(uVelocity, vB).x;
|
|
315
|
+
float vorticity = R - L - T + B;
|
|
316
|
+
gl_FragColor = vec4(0.5 * vorticity, 0.0, 0.0, 1.0);
|
|
317
|
+
}
|
|
318
|
+
`,vorticity:`
|
|
319
|
+
precision highp float;
|
|
320
|
+
precision highp sampler2D;
|
|
321
|
+
|
|
322
|
+
varying vec2 vUv;
|
|
323
|
+
varying vec2 vL;
|
|
324
|
+
varying vec2 vR;
|
|
325
|
+
varying vec2 vT;
|
|
326
|
+
varying vec2 vB;
|
|
327
|
+
uniform sampler2D uVelocity;
|
|
328
|
+
uniform sampler2D uCurl;
|
|
329
|
+
uniform float curl;
|
|
330
|
+
uniform float dt;
|
|
331
|
+
|
|
332
|
+
void main () {
|
|
333
|
+
float L = texture2D(uCurl, vL).x;
|
|
334
|
+
float R = texture2D(uCurl, vR).x;
|
|
335
|
+
float T = texture2D(uCurl, vT).x;
|
|
336
|
+
float B = texture2D(uCurl, vB).x;
|
|
337
|
+
float C = texture2D(uCurl, vUv).x;
|
|
338
|
+
|
|
339
|
+
vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L));
|
|
340
|
+
force /= length(force) + 0.0001;
|
|
341
|
+
force *= curl * C;
|
|
342
|
+
force.y *= -1.0;
|
|
343
|
+
|
|
344
|
+
vec2 vel = texture2D(uVelocity, vUv).xy;
|
|
345
|
+
gl_FragColor = vec4(vel + force * dt, 0.0, 1.0);
|
|
346
|
+
}
|
|
347
|
+
`,pressure:`
|
|
348
|
+
precision mediump float;
|
|
349
|
+
precision mediump sampler2D;
|
|
350
|
+
|
|
351
|
+
varying highp vec2 vUv;
|
|
352
|
+
varying highp vec2 vL;
|
|
353
|
+
varying highp vec2 vR;
|
|
354
|
+
varying highp vec2 vT;
|
|
355
|
+
varying highp vec2 vB;
|
|
356
|
+
uniform sampler2D uPressure;
|
|
357
|
+
uniform sampler2D uDivergence;
|
|
358
|
+
|
|
359
|
+
vec2 boundary (vec2 uv) {
|
|
360
|
+
return uv;
|
|
361
|
+
// uncomment if you use wrap or repeat texture mode
|
|
362
|
+
// uv = min(max(uv, 0.0), 1.0);
|
|
363
|
+
// return uv;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
void main () {
|
|
367
|
+
float L = texture2D(uPressure, boundary(vL)).x;
|
|
368
|
+
float R = texture2D(uPressure, boundary(vR)).x;
|
|
369
|
+
float T = texture2D(uPressure, boundary(vT)).x;
|
|
370
|
+
float B = texture2D(uPressure, boundary(vB)).x;
|
|
371
|
+
float C = texture2D(uPressure, vUv).x;
|
|
372
|
+
float divergence = texture2D(uDivergence, vUv).x;
|
|
373
|
+
float pressure = (L + R + B + T - divergence) * 0.25;
|
|
374
|
+
gl_FragColor = vec4(pressure, 0.0, 0.0, 1.0);
|
|
375
|
+
}
|
|
376
|
+
`,gradientSubtract:`
|
|
377
|
+
precision mediump float;
|
|
378
|
+
precision mediump sampler2D;
|
|
379
|
+
|
|
380
|
+
varying highp vec2 vUv;
|
|
381
|
+
varying highp vec2 vL;
|
|
382
|
+
varying highp vec2 vR;
|
|
383
|
+
varying highp vec2 vT;
|
|
384
|
+
varying highp vec2 vB;
|
|
385
|
+
uniform sampler2D uPressure;
|
|
386
|
+
uniform sampler2D uVelocity;
|
|
387
|
+
|
|
388
|
+
vec2 boundary (vec2 uv) {
|
|
389
|
+
return uv;
|
|
390
|
+
// uv = min(max(uv, 0.0), 1.0);
|
|
391
|
+
// return uv;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
void main () {
|
|
395
|
+
float L = texture2D(uPressure, boundary(vL)).x;
|
|
396
|
+
float R = texture2D(uPressure, boundary(vR)).x;
|
|
397
|
+
float T = texture2D(uPressure, boundary(vT)).x;
|
|
398
|
+
float B = texture2D(uPressure, boundary(vB)).x;
|
|
399
|
+
vec2 velocity = texture2D(uVelocity, vUv).xy;
|
|
400
|
+
velocity.xy -= vec2(R - L, T - B);
|
|
401
|
+
gl_FragColor = vec4(velocity, 0.0, 1.0);
|
|
402
|
+
}
|
|
403
|
+
`};function he(f){Object.assign(q,f)}const ue="data:image/png;base64,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";let le=!1;function pe(f){let e=[];e.push(new se);let r=f.getContext("webgl2",ie);const i=!!r;i||(r=f.getContext("webgl",ie)||f.getContext("experimental-webgl",ie));let v=k();P()&&(q.render_shaders=!1),v.supportLinearFiltering||(q.render_shaders=!1,q.render_bloom=!1);const n={baseVertex:c(r.VERTEX_SHADER,_.vertex),clear:c(r.FRAGMENT_SHADER,_.clear),color:c(r.FRAGMENT_SHADER,_.color),background:c(r.FRAGMENT_SHADER,_.background),display:c(r.FRAGMENT_SHADER,_.display),displayBloom:c(r.FRAGMENT_SHADER,_.displayBloom),displayShading:c(r.FRAGMENT_SHADER,_.displayShading),displayBloomShading:c(r.FRAGMENT_SHADER,_.displayBloomShading),bloomPreFilter:c(r.FRAGMENT_SHADER,_.bloomPreFilter),bloomBlur:c(r.FRAGMENT_SHADER,_.bloomBlur),bloomFinal:c(r.FRAGMENT_SHADER,_.bloomFinal),splat:c(r.FRAGMENT_SHADER,_.splat),advectionManualFiltering:c(r.FRAGMENT_SHADER,_.advectionManualFiltering),advection:c(r.FRAGMENT_SHADER,_.advection),divergence:c(r.FRAGMENT_SHADER,_.divergence),curl:c(r.FRAGMENT_SHADER,_.curl),vorticity:c(r.FRAGMENT_SHADER,_.vorticity),pressure:c(r.FRAGMENT_SHADER,_.pressure),gradientSubtract:c(r.FRAGMENT_SHADER,_.gradientSubtract)};let x=U(v.supportLinearFiltering);function P(){return/Mobi|Android/i.test(navigator.userAgent)}function k(){let J,y,d,F,N;i?(r.getExtension("EXT_color_buffer_float"),N=r.getExtension("OES_texture_float_linear")):(F=r.getExtension("OES_texture_half_float"),N=r.getExtension("OES_texture_half_float_linear"));const S=i?r.HALF_FLOAT:F.HALF_FLOAT_OES;r.clearColor(0,0,0,1),i?(J=D(r.RGBA16F,r.RGBA,S),y=D(r.RG16F,r.RG,S),d=D(r.R16F,r.RED,S)):(J=D(r.RGBA,r.RGBA,S),y=D(r.RGBA,r.RGBA,S),d=D(r.RGBA,r.RGBA,S));function D(E,B,Z){let A,C=r.createTexture();r.bindTexture(r.TEXTURE_2D,C),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MIN_FILTER,r.NEAREST),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MAG_FILTER,r.NEAREST),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_S,r.CLAMP_TO_EDGE),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_T,r.CLAMP_TO_EDGE),r.texImage2D(r.TEXTURE_2D,0,E,4,4,0,B,Z,null);let b=r.createFramebuffer();if(r.bindFramebuffer(r.FRAMEBUFFER,b),r.framebufferTexture2D(r.FRAMEBUFFER,r.COLOR_ATTACHMENT0,r.TEXTURE_2D,C,0),A=r.checkFramebufferStatus(r.FRAMEBUFFER)===r.FRAMEBUFFER_COMPLETE,!A)switch(E){case r.R16F:return D(r.RG16F,r.RG,Z);case r.RG16F:return D(r.RGBA16F,r.RGBA,Z);default:return null}return{internalFormat:E,format:B}}return{formatRGBA:J,formatRG:y,formatR:d,halfFloatTexType:S,supportLinearFiltering:N}}function c(J,y){const d=r.createShader(J);if(r.shaderSource(d,y),r.compileShader(d),!r.getShaderParameter(d,r.COMPILE_STATUS))throw r.getShaderInfoLog(d);return d}function U(J){return{clearProgram:new R(n.baseVertex,n.clear,r),colorProgram:new R(n.baseVertex,n.color,r),backgroundProgram:new R(n.baseVertex,n.background,r),displayProgram:new R(n.baseVertex,n.display,r),displayBloomProgram:new R(n.baseVertex,n.displayBloom,r),displayShadingProgram:new R(n.baseVertex,n.displayShading,r),displayBloomShadingProgram:new R(n.baseVertex,n.displayBloomShading,r),bloomPreFilterProgram:new R(n.baseVertex,n.bloomPreFilter,r),bloomBlurProgram:new R(n.baseVertex,n.bloomBlur,r),bloomFinalProgram:new R(n.baseVertex,n.bloomFinal,r),splatProgram:new R(n.baseVertex,n.splat,r),advectionProgram:new R(n.baseVertex,J?n.advection:n.advectionManualFiltering,r),divergenceProgram:new R(n.baseVertex,n.divergence,r),curlProgram:new R(n.baseVertex,n.curl,r),vorticityProgram:new R(n.baseVertex,n.vorticity,r),pressureProgram:new R(n.baseVertex,n.pressure,r),gradientSubtractProgram:new R(n.baseVertex,n.gradientSubtract,r)}}return{programs:x,webGL:r,colorFormats:v,pointers:e}}function Te(f,e,r,i,v){if(le){let o=[];o.push(new se),v=o}le=!0;const n=q;let x=[],P=[],k,c,U,J,y,d,F,N,S,D;const E=(e.bindBuffer(e.ARRAY_BUFFER,e.createBuffer()),e.bufferData(e.ARRAY_BUFFER,new Float32Array([-1,-1,-1,1,1,1,1,-1]),e.STATIC_DRAW),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,e.createBuffer()),e.bufferData(e.ELEMENT_ARRAY_BUFFER,new Uint16Array([0,1,2,0,2,3]),e.STATIC_DRAW),e.vertexAttribPointer(0,2,e.FLOAT,!1,0,0),e.enableVertexAttribArray(0),o=>{e.bindFramebuffer(e.FRAMEBUFFER,o),e.drawElements(e.TRIANGLES,6,e.UNSIGNED_SHORT,0)});let B=(n.embedded_dither,Q(ue));A(),O(Math.random()*20+5);let Z=Date.now();w();function A(){const o=r.halfFloatTexType,a=r.formatRGBA,u=r.formatRG,s=r.formatR,l=r.supportLinearFiltering?e.LINEAR:e.NEAREST;let g=t(n.sim_resolution),p=t(n.dye_resolution),T=t(n.bloom_resolution);k=g.width,c=g.height,U=p.width,J=p.height,y=y?j(y,U,J,a.internalFormat,a.format,o,l):C(U,J,a.internalFormat,a.format,o,l),d=d?j(d,k,c,u.internalFormat,u.format,o,l):C(k,c,u.internalFormat,u.format,o,l),D=b(T.width,T.height,a.internalFormat,a.format,o,l),F=b(k,c,s.internalFormat,s.format,o,e.NEAREST),N=b(k,c,s.internalFormat,s.format,o,e.NEAREST),S=C(k,c,s.internalFormat,s.format,o,e.NEAREST),x.length=0;for(let h=0;h<n.bloom_iterations;h++){let I=T.width>>h+1,z=T.height>>h+1;if(I<2||z<2)break;let fe=b(I,z,a.internalFormat,a.format,o,l);x.push(fe)}}function C(o,a,u,s,l,g){let p=b(o,a,u,s,l,g),T=b(o,a,u,s,l,g);return{get read(){return p},set read(h){p=h},get write(){return T},set write(h){T=h},swap(){let h=p;p=T,T=h}}}function b(o,a,u,s,l,g){e.activeTexture(e.TEXTURE0);let p=e.createTexture();e.bindTexture(e.TEXTURE_2D,p),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,g),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,g),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,u,o,a,0,s,l,null);let T=e.createFramebuffer();return e.bindFramebuffer(e.FRAMEBUFFER,T),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,p,0),e.viewport(0,0,o,a),e.clear(e.COLOR_BUFFER_BIT),{texture:p,fbo:T,width:o,height:a,attach(h){return e.activeTexture(e.TEXTURE0+h),e.bindTexture(e.TEXTURE_2D,p),h}}}function j(o,a,u,s,l,g,p){return o.read=X(o.read,a,u,s,l,g,p),o.write=b(a,u,s,l,g,p),o}function X(o,a,u,s,l,g,p){let T=b(a,u,s,l,g,p);return i.clearProgram.bind(),e.uniform1i(i.clearProgram.uniforms.uTexture,o.attach(0)),e.uniform1f(i.clearProgram.uniforms.value,1),E(T.fbo),T}function Q(o){let a=e.createTexture();e.bindTexture(e.TEXTURE_2D,a),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.REPEAT),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.REPEAT),e.texImage2D(e.TEXTURE_2D,0,e.RGB,1,1,0,e.RGB,e.UNSIGNED_BYTE,new Uint8Array([255,255,255]));let u={texture:a,width:1,height:1,attach(l){return e.activeTexture(e.TEXTURE0+l),e.bindTexture(e.TEXTURE_2D,a),l}},s=new Image;return s.src=o,s.onload=()=>{u.width=s.width,u.height=s.height,e.bindTexture(e.TEXTURE_2D,a),e.texImage2D(e.TEXTURE_2D,0,e.RGB,e.RGB,e.UNSIGNED_BYTE,s)},u}function w(){L(),Y(),n.paused||$(.016),te(null),requestAnimationFrame(w)}function Y(){P.length>0&&O(P.pop());for(let o=0;o<v.length;o++){const a=v[o];a.moved&&(H(a.x,a.y,a.dx,a.dy,a.color),o!==1&&(a.moved=!1))}if(n.multi_color){if(Z+100<Date.now()){Z=Date.now();for(let o=0;o<v.length;o++){const a=v[o];a.color=W()}}v[0]&&!v[0].moved&&H(f.width*.5,f.height*.5,0,0,{r:0,g:0,b:0})}}function $(o){e.disable(e.BLEND),e.viewport(0,0,k,c),i.curlProgram.bind(),e.uniform2f(i.curlProgram.uniforms.texelSize,1/k,1/c),e.uniform1i(i.curlProgram.uniforms.uVelocity,d.read.attach(0)),E(N.fbo),i.vorticityProgram.bind(),e.uniform2f(i.vorticityProgram.uniforms.texelSize,1/k,1/c),e.uniform1i(i.vorticityProgram.uniforms.uVelocity,d.read.attach(0)),e.uniform1i(i.vorticityProgram.uniforms.uCurl,N.attach(1)),e.uniform1f(i.vorticityProgram.uniforms.curl,n.curl),e.uniform1f(i.vorticityProgram.uniforms.dt,o),E(d.write.fbo),d.swap(),i.divergenceProgram.bind(),e.uniform2f(i.divergenceProgram.uniforms.texelSize,1/k,1/c),e.uniform1i(i.divergenceProgram.uniforms.uVelocity,d.read.attach(0)),E(F.fbo),i.clearProgram.bind(),e.uniform1i(i.clearProgram.uniforms.uTexture,S.read.attach(0)),e.uniform1f(i.clearProgram.uniforms.value,n.pressure),E(S.write.fbo),S.swap(),i.pressureProgram.bind(),e.uniform2f(i.pressureProgram.uniforms.texelSize,1/k,1/c),e.uniform1i(i.pressureProgram.uniforms.uDivergence,F.attach(0));for(let u=0;u<n.pressure_iteration;u++)e.uniform1i(i.pressureProgram.uniforms.uPressure,S.read.attach(1)),E(S.write.fbo),S.swap();i.gradientSubtractProgram.bind(),e.uniform2f(i.gradientSubtractProgram.uniforms.texelSize,1/k,1/c),e.uniform1i(i.gradientSubtractProgram.uniforms.uPressure,S.read.attach(0)),e.uniform1i(i.gradientSubtractProgram.uniforms.uVelocity,d.read.attach(1)),E(d.write.fbo),d.swap(),i.advectionProgram.bind(),e.uniform2f(i.advectionProgram.uniforms.texelSize,1/k,1/c),r.supportLinearFiltering||e.uniform2f(i.advectionProgram.uniforms.dyeTexelSize,1/k,1/c);let a=d.read.attach(0);e.uniform1i(i.advectionProgram.uniforms.uVelocity,a),e.uniform1i(i.advectionProgram.uniforms.uSource,a),e.uniform1f(i.advectionProgram.uniforms.dt,o),e.uniform1f(i.advectionProgram.uniforms.dissipation,n.velocity),E(d.write.fbo),d.swap(),e.viewport(0,0,U,J),r.supportLinearFiltering||e.uniform2f(i.advectionProgram.uniforms.dyeTexelSize,1/U,1/J),e.uniform1i(i.advectionProgram.uniforms.uVelocity,d.read.attach(0)),e.uniform1i(i.advectionProgram.uniforms.uSource,y.read.attach(1)),e.uniform1f(i.advectionProgram.uniforms.dissipation,n.dissipation),E(y.write.fbo),y.swap()}function te(o){n.render_bloom&&M(y.read,D),e.blendFunc(e.ONE,e.ONE_MINUS_SRC_ALPHA),e.enable(e.BLEND);let a=e.drawingBufferWidth,u=e.drawingBufferHeight;if(e.viewport(0,0,a,u),!n.transparent){i.colorProgram.bind();let s=n.background_color;e.uniform4f(i.colorProgram.uniforms.color,s.r/255,s.g/255,s.b/255,1),E(o)}if(n.transparent&&(i.backgroundProgram.bind(),e.uniform1f(i.backgroundProgram.uniforms.aspectRatio,f.width/f.height),E(null)),n.render_shaders){let s=n.render_bloom?i.displayBloomShadingProgram:i.displayShadingProgram;if(s.bind(),e.uniform2f(s.uniforms.texelSize,1/a,1/u),e.uniform1i(s.uniforms.uTexture,y.read.attach(0)),n.render_bloom){e.uniform1i(s.uniforms.uBloom,D.attach(1)),e.uniform1i(s.uniforms.uDithering,B.attach(2));let l=m(B,a,u);e.uniform2f(s.uniforms.ditherScale,l.x,l.y)}}else{let s=n.render_bloom?i.displayBloomProgram:i.displayProgram;if(s.bind(),e.uniform1i(s.uniforms.uTexture,y.read.attach(0)),n.render_bloom){e.uniform1i(s.uniforms.uBloom,D.attach(1)),e.uniform1i(s.uniforms.uDithering,B.attach(2));let l=m(B,a,u);e.uniform2f(s.uniforms.ditherScale,l.x,l.y)}}E(o)}function M(o,a){if(x.length<2)return;let u=a;e.disable(e.BLEND),i.bloomPreFilterProgram.bind();let s=n.threshold*n.soft_knee+1e-4,l=n.threshold-s,g=s*2,p=.25/s;e.uniform3f(i.bloomPreFilterProgram.uniforms.curve,l,g,p),e.uniform1f(i.bloomPreFilterProgram.uniforms.threshold,n.threshold),e.uniform1i(i.bloomPreFilterProgram.uniforms.uTexture,o.attach(0)),e.viewport(0,0,u.width,u.height),E(u.fbo),i.bloomBlurProgram.bind();for(let T=0;T<x.length;T++){let h=x[T];e.uniform2f(i.bloomBlurProgram.uniforms.texelSize,1/u.width,1/u.height),e.uniform1i(i.bloomBlurProgram.uniforms.uTexture,u.attach(0)),e.viewport(0,0,h.width,h.height),E(h.fbo),u=h}e.blendFunc(e.ONE,e.ONE),e.enable(e.BLEND);for(let T=x.length-2;T>=0;T--){let h=x[T];e.uniform2f(i.bloomBlurProgram.uniforms.texelSize,1/u.width,1/u.height),e.uniform1i(i.bloomBlurProgram.uniforms.uTexture,u.attach(0)),e.viewport(0,0,h.width,h.height),E(h.fbo),u=h}e.disable(e.BLEND),i.bloomFinalProgram.bind(),e.uniform2f(i.bloomFinalProgram.uniforms.texelSize,1/u.width,1/u.height),e.uniform1i(i.bloomFinalProgram.uniforms.uTexture,u.attach(0)),e.uniform1f(i.bloomFinalProgram.uniforms.intensity,n.intensity),e.viewport(0,0,a.width,a.height),E(a.fbo)}function H(o,a,u,s,l){e.viewport(0,0,k,c),i.splatProgram.bind(),e.uniform1i(i.splatProgram.uniforms.uTarget,d.read.attach(0)),e.uniform1f(i.splatProgram.uniforms.aspectRatio,f.width/f.height),e.uniform2f(i.splatProgram.uniforms.point,o/f.width,1-a/f.height),e.uniform3f(i.splatProgram.uniforms.color,u,-s,1),e.uniform1f(i.splatProgram.uniforms.radius,n.emitter_size/100),E(d.write.fbo),d.swap(),e.viewport(0,0,U,J),e.uniform1i(i.splatProgram.uniforms.uTarget,y.read.attach(0)),e.uniform3f(i.splatProgram.uniforms.color,l.r,l.g,l.b),E(y.write.fbo),y.swap()}function O(o){for(let a=0;a<o;a++){const u=Math.random()*f.width,s=Math.random()*f.height,l=(Math.random()-.5)*600,g=(Math.random()-.5)*600,p=W();H(u,s,l,g,p)}}function L(){(f.width!=f.clientWidth||f.height!=f.clientHeight)&&(f.width=f.clientWidth,f.height=f.clientHeight,A())}function W(){let o=G(Math.random(),1,1);return o.r*=.15,o.g*=.15,o.b*=.15,o}function G(o,a,u){let s,l,g,p,T,h,I,z;switch(p=Math.floor(o*6),T=o*6-p,h=u*(1-a),I=u*(1-T*a),z=u*(1-(1-T)*a),p%6){case 0:s=u,l=z,g=h;break;case 1:s=I,l=u,g=h;break;case 2:s=h,l=u,g=z;break;case 3:s=h,l=I,g=u;break;case 4:s=z,l=h,g=u;break;case 5:s=u,l=h,g=I;break}return{r:s,g:l,b:g}}function t(o){let a=e.drawingBufferWidth/e.drawingBufferHeight;a<1&&(a=1/a);let u=Math.round(o*a),s=Math.round(o);return e.drawingBufferWidth>e.drawingBufferHeight?{width:u,height:s}:{width:s,height:u}}function m(o,a,u){return{x:a/o.width,y:u/o.height}}window.addEventListener("mousemove",o=>{const a=f.getBoundingClientRect(),u=o.clientX-a.left,s=o.clientY-a.top;if(u<0||s<0||u>a.width||s>a.height)return;const l=v[0];l.down=!0,l.moved=!0,l.dx=(u-l.x)*5,l.dy=(s-l.y)*5,l.x=u,l.y=s}),f.addEventListener("mousedown",()=>{v[0].down=!0,v[0].color=W()}),window.addEventListener("mouseup",()=>{v[0].down=!1}),window.addEventListener("keydown",o=>{o.code==="KeyP"&&(n.paused=!n.paused),o.key===" "&&P.push(parseInt(Math.random()*20)+5)})}class R{constructor(e,r,i){if(this.uniforms={},this.webGL=i,this.program=i.createProgram(),i.attachShader(this.program,e),i.attachShader(this.program,r),i.linkProgram(this.program),!i.getProgramParameter(this.program,i.LINK_STATUS))throw i.getProgramInfoLog(this.program);const v=i.getProgramParameter(this.program,i.ACTIVE_UNIFORMS);for(let n=0;n<v;n++){const x=i.getActiveUniform(this.program,n).name;this.uniforms[x]=i.getUniformLocation(this.program,x)}}bind(){this.webGL.useProgram(this.program)}}class se{constructor(){this.id=-1,this.x=0,this.y=0,this.dx=0,this.dy=0,this.down=!1,this.moved=!1,this.color=[30,0,300]}}class Ee{constructor(e){this.canvas=e,this.webGL=null,this.programs=null,this.colorFormats=null,this.pointers=null,this.active=!1,this._started=!1}start(){if(!this.active){if(!this._started){const{webGL:e,programs:r,colorFormats:i,pointers:v}=pe(this.canvas);this.webGL=e,this.programs=r,this.colorFormats=i,this.pointers=v,Te(this.canvas,this.webGL,this.colorFormats,this.programs,this.pointers),this._started=!0}this.active=!0}}pause(){this.active&&(this.active=!1,this.webGL&&this.webGL.clear(this.webGL.COLOR_BUFFER_BIT))}destroy(){this.active=!1,this.webGL=null,this.programs=null,this.colorFormats=null,this.pointers=null,this._started=!1}}function me({enabled:f=!0,style:e={},className:r="",pointerEvents:i=!0}){const v=re.useRef(null),n=re.useRef(null);return re.useEffect(()=>{if(!v.current)return;n.current||(n.current=new Ee(v.current));const x=n.current;return f?x.start():x.pause(),()=>{n.current&&(n.current.destroy?.(),n.current=null)}},[f]),ge.jsx("canvas",{ref:v,className:r,style:{position:"fixed",inset:0,width:"100vw",height:"100vh",zIndex:0,pointerEvents:i?"auto":"none",...e}})}exports.LiquidBG=me;exports.default=me;exports.setBehaviors=he;
|