@eva/plugin-renderer-rain-puddle 2.1.0-beta.14

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 ADDED
@@ -0,0 +1,36 @@
1
+ # @eva/plugin-renderer-rain-puddle
2
+
3
+ Rain, puddle reflection and bounded ripple effects built on Eva.js `ShaderEffect`
4
+ and `SceneCapture`.
5
+
6
+ ```ts
7
+ import {
8
+ RainPuddle,
9
+ RainPuddleSystem,
10
+ registerRainPuddleEffects,
11
+ } from '@eva/plugin-renderer-rain-puddle';
12
+
13
+ registerRainPuddleEffects();
14
+
15
+ await game.init({
16
+ systems: [
17
+ rendererSystem,
18
+ new RainPuddleSystem(),
19
+ sceneCaptureSystem,
20
+ shaderEffectSystem,
21
+ ],
22
+ });
23
+ ```
24
+
25
+ Attach `SceneCapture` to an owner object, put `ShaderEffect` with
26
+ `eva.rain-puddle.puddle` and `eva.rain-puddle.rain` on two full-screen surfaces,
27
+ then add one `RainPuddle` controller. The controller owns the runtime knobs and a
28
+ fixed ripple ring; shader sources and Pixi resources never enter serialized DSL
29
+ data.
30
+
31
+ The built-in effects currently declare WebGL support. Hosts should request
32
+ `backendPreference: 'webgl2'` and `backendRequired: true`, or provide a fallback
33
+ before enabling a WebGPU-only renderer.
34
+
35
+ See `examples/src/rain-puddle.ts` for the complete layer order, live reflection
36
+ proxies, pointer ripples, ground splashes and controls.
@@ -0,0 +1,529 @@
1
+ globalThis.EVA = globalThis.EVA || {};
2
+ globalThis.EVA.plugin = globalThis.EVA.plugin || {};
3
+ globalThis.EVA.plugin.renderer = globalThis.EVA.plugin.renderer || {};
4
+ globalThis.EVA.plugin.renderer.rain = globalThis.EVA.plugin.renderer.rain || {};
5
+ var _EVA_IIFE_puddle = function (exports, eva_js, pluginRendererShaderEffect, pixi_js, pluginRendererSceneCapture) {
6
+ 'use strict';
7
+
8
+ const RIPPLE_STRIDE = 4;
9
+ const DEFAULT_MAX_RIPPLES = 4;
10
+ const MAX_SHADER_RIPPLES = 8;
11
+ class RainPuddle extends eva_js.Component {
12
+ constructor() {
13
+ super(...arguments);
14
+ this.rainAmount = 0.65;
15
+ this.waterLevel = 0.5;
16
+ this.groundLevel = 0.545;
17
+ this.groundFeather = 0.02;
18
+ this.reflectionStrength = 0.55;
19
+ this.rippleDuration = 1.6;
20
+ this.maxRipples = DEFAULT_MAX_RIPPLES;
21
+ this.quality = 'high';
22
+ this.reflectionTexture = '';
23
+ this.rainSurfaceName = 'rain-surface';
24
+ this.puddleSurfaceName = 'puddle-surface';
25
+ this.rippleUniformData = new Float32Array(DEFAULT_MAX_RIPPLES * RIPPLE_STRIDE);
26
+ this.rippleDirectionUniformData = new Float32Array(DEFAULT_MAX_RIPPLES * 4);
27
+ this.clickRippleUniformData = new Float32Array([-2, -2, 99, 0]);
28
+ this.activeRippleCount = 0;
29
+ this.nextRippleIndex = 0;
30
+ }
31
+ init(params = {}) {
32
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
33
+ this.rainAmount = clamp01((_a = params.rainAmount) !== null && _a !== void 0 ? _a : this.rainAmount);
34
+ this.waterLevel = clamp01((_b = params.waterLevel) !== null && _b !== void 0 ? _b : this.waterLevel);
35
+ this.groundLevel = clamp01((_c = params.groundLevel) !== null && _c !== void 0 ? _c : this.groundLevel);
36
+ this.groundFeather = clamp((_d = params.groundFeather) !== null && _d !== void 0 ? _d : this.groundFeather, 0.001, 1);
37
+ this.reflectionStrength = clamp01((_e = params.reflectionStrength) !== null && _e !== void 0 ? _e : this.reflectionStrength);
38
+ this.rippleDuration = Math.max(0.05, (_f = params.rippleDuration) !== null && _f !== void 0 ? _f : this.rippleDuration);
39
+ this.maxRipples = clampInteger((_g = params.maxRipples) !== null && _g !== void 0 ? _g : this.maxRipples, 1, MAX_SHADER_RIPPLES);
40
+ this.quality = (_h = params.quality) !== null && _h !== void 0 ? _h : this.quality;
41
+ this.reflectionTexture = (_j = params.reflectionTexture) !== null && _j !== void 0 ? _j : this.reflectionTexture;
42
+ this.rainSurfaceName = (_k = params.rainSurfaceName) !== null && _k !== void 0 ? _k : this.rainSurfaceName;
43
+ this.puddleSurfaceName = (_l = params.puddleSurfaceName) !== null && _l !== void 0 ? _l : this.puddleSurfaceName;
44
+ this.rippleUniformData = new Float32Array(this.maxRipples * RIPPLE_STRIDE);
45
+ this.rippleDirectionUniformData = new Float32Array(this.maxRipples * 4);
46
+ this.clickRippleUniformData = new Float32Array([-2, -2, 99, 0]);
47
+ this.resetRipples();
48
+ }
49
+ emitRipple(input) {
50
+ var _a;
51
+ const index = this.nextRippleIndex;
52
+ const offset = index * RIPPLE_STRIDE;
53
+ const wasActive = this.rippleUniformData[offset + 2] >= 0;
54
+ this.rippleUniformData[offset] = clamp01(input.x);
55
+ this.rippleUniformData[offset + 1] = clamp01(input.y);
56
+ this.rippleUniformData[offset + 2] = 0;
57
+ this.rippleUniformData[offset + 3] = clamp01((_a = input.strength) !== null && _a !== void 0 ? _a : 1);
58
+ const direction = normalizedDirection(input.direction);
59
+ const directionOffset = index * 4;
60
+ this.rippleDirectionUniformData[directionOffset] = direction.x;
61
+ this.rippleDirectionUniformData[directionOffset + 1] = direction.y;
62
+ if (!wasActive) this.activeRippleCount += 1;
63
+ this.nextRippleIndex = (index + 1) % this.maxRipples;
64
+ }
65
+ emitClickRipple(input) {
66
+ var _a;
67
+ this.clickRippleUniformData[0] = clamp01(input.x);
68
+ this.clickRippleUniformData[1] = clamp01(input.y);
69
+ this.clickRippleUniformData[2] = 0;
70
+ this.clickRippleUniformData[3] = clamp01((_a = input.strength) !== null && _a !== void 0 ? _a : 1);
71
+ }
72
+ advanceRipples(deltaSeconds) {
73
+ if (!(deltaSeconds > 0)) return;
74
+ for (let index = 0; index < this.maxRipples; index += 1) {
75
+ const ageOffset = index * RIPPLE_STRIDE + 2;
76
+ const age = this.rippleUniformData[ageOffset];
77
+ if (age < 0) continue;
78
+ const nextAge = age + deltaSeconds;
79
+ if (nextAge >= this.rippleDuration) {
80
+ this.rippleUniformData[ageOffset] = -1;
81
+ this.activeRippleCount -= 1;
82
+ } else {
83
+ this.rippleUniformData[ageOffset] = nextAge;
84
+ }
85
+ }
86
+ if (this.clickRippleUniformData[2] >= 0 && this.clickRippleUniformData[2] < this.rippleDuration) {
87
+ this.clickRippleUniformData[2] += deltaSeconds;
88
+ }
89
+ }
90
+ getRippleDirection(index) {
91
+ var _a, _b;
92
+ const offset = index * 4;
93
+ return {
94
+ x: (_a = this.rippleDirectionUniformData[offset]) !== null && _a !== void 0 ? _a : 0,
95
+ y: (_b = this.rippleDirectionUniformData[offset + 1]) !== null && _b !== void 0 ? _b : 0
96
+ };
97
+ }
98
+ resetRipples() {
99
+ this.rippleUniformData.fill(0);
100
+ for (let index = 0; index < this.maxRipples; index += 1) {
101
+ this.rippleUniformData[index * RIPPLE_STRIDE + 2] = -1;
102
+ }
103
+ this.rippleDirectionUniformData.fill(0);
104
+ this.clickRippleUniformData.set([-2, -2, 99, 0]);
105
+ this.nextRippleIndex = 0;
106
+ this.activeRippleCount = 0;
107
+ }
108
+ }
109
+ RainPuddle.componentName = 'RainPuddle';
110
+ function normalizedDirection(direction) {
111
+ var _a, _b;
112
+ const x = typeof direction === 'number' ? direction : Number((_a = direction === null || direction === void 0 ? void 0 : direction.x) !== null && _a !== void 0 ? _a : 0);
113
+ const y = typeof direction === 'number' ? 0 : Number((_b = direction === null || direction === void 0 ? void 0 : direction.y) !== null && _b !== void 0 ? _b : 0);
114
+ const length = Math.hypot(x, y);
115
+ if (!(length > 0)) return {
116
+ x: 0,
117
+ y: 1
118
+ };
119
+ return {
120
+ x: x / length,
121
+ y: y / length
122
+ };
123
+ }
124
+ function clamp(value, min, max) {
125
+ return Math.min(max, Math.max(min, value));
126
+ }
127
+ function clamp01(value) {
128
+ return clamp(value, 0, 1);
129
+ }
130
+ function clampInteger(value, min, max) {
131
+ return Math.round(clamp(value, min, max));
132
+ }
133
+ function __decorate(decorators, target, key, desc) {
134
+ var c = arguments.length,
135
+ r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc,
136
+ d;
137
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
138
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
139
+ }
140
+ let RainPuddleSystem = class RainPuddleSystem extends eva_js.System {
141
+ constructor() {
142
+ super(...arguments);
143
+ this.name = 'RainPuddleSystem';
144
+ this.bindings = new Map();
145
+ }
146
+ update() {
147
+ this.consumeObserverChanges();
148
+ }
149
+ consumeObserverChanges() {
150
+ for (const changed of this.componentObserver.clear()) {
151
+ this.componentChanged(changed);
152
+ }
153
+ }
154
+ componentChanged(changed) {
155
+ if (changed.componentName !== RainPuddle.componentName) return;
156
+ if (changed.type === eva_js.OBSERVER_TYPE.REMOVE) {
157
+ this.bindings.delete(changed.gameObject.id);
158
+ return;
159
+ }
160
+ if (changed.type === eva_js.OBSERVER_TYPE.ADD) {
161
+ this.bindings.set(changed.gameObject.id, {
162
+ component: changed.component
163
+ });
164
+ }
165
+ }
166
+ frameStart(frame) {
167
+ this.consumeObserverChanges();
168
+ const deltaSeconds = Math.min(0.1, Math.max(0, frame.rafDeltaTime / 1000));
169
+ for (const binding of this.bindings.values()) {
170
+ const component = binding.component;
171
+ component.advanceRipples(deltaSeconds);
172
+ binding.rainEffect = this.resolveEffect(binding.rainEffect, component.rainSurfaceName);
173
+ binding.puddleEffect = this.resolveEffect(binding.puddleEffect, component.puddleSurfaceName);
174
+ if (binding.rainEffect) {
175
+ binding.rainEffect.uniforms.rainAmount = component.rainAmount;
176
+ binding.rainEffect.uniforms.quality = qualityValue(component.quality);
177
+ }
178
+ if (binding.puddleEffect) {
179
+ binding.puddleEffect.uniforms.waterLevel = component.waterLevel;
180
+ binding.puddleEffect.uniforms.groundLevel = component.groundLevel;
181
+ binding.puddleEffect.uniforms.groundFeather = component.groundFeather;
182
+ binding.puddleEffect.uniforms.reflectionStrength = component.reflectionStrength;
183
+ binding.puddleEffect.uniforms.rippleDuration = component.rippleDuration;
184
+ binding.puddleEffect.uniforms.ripples = component.rippleUniformData;
185
+ binding.puddleEffect.uniforms.rippleDirections = component.rippleDirectionUniformData;
186
+ binding.puddleEffect.uniforms.clickRipple = component.clickRippleUniformData;
187
+ binding.puddleEffect.uniforms.reflectionTexture = component.reflectionTexture;
188
+ }
189
+ }
190
+ }
191
+ onDestroy() {
192
+ this.bindings.clear();
193
+ }
194
+ resolveEffect(current, name) {
195
+ var _a, _b, _c;
196
+ if ((current === null || current === void 0 ? void 0 : current.gameObject) && !current.gameObject.destroyed) return current;
197
+ if (!name) return undefined;
198
+ const gameObject = (_c = (_b = (_a = this.game) === null || _a === void 0 ? void 0 : _a.findAllByName) === null || _b === void 0 ? void 0 : _b.call(_a, name)) === null || _c === void 0 ? void 0 : _c[0];
199
+ return gameObject === null || gameObject === void 0 ? void 0 : gameObject.getComponent(pluginRendererShaderEffect.ShaderEffect);
200
+ }
201
+ };
202
+ RainPuddleSystem.systemName = 'RainPuddleSystem';
203
+ RainPuddleSystem = __decorate([eva_js.decorators.componentObserver({
204
+ RainPuddle: []
205
+ })], RainPuddleSystem);
206
+ var RainPuddleSystem$1 = RainPuddleSystem;
207
+ function qualityValue(quality) {
208
+ if (quality === 'low') return 0;
209
+ if (quality === 'medium') return 0.55;
210
+ return 1;
211
+ }
212
+ const RAIN_EFFECT_ID = 'eva.rain-puddle.rain';
213
+ const PUDDLE_EFFECT_ID = 'eva.rain-puddle.puddle';
214
+ const normalizedScreenFilterVert = `
215
+ in vec2 aPosition;
216
+ out vec2 vTextureCoord;
217
+
218
+ uniform vec4 uOutputFrame;
219
+ uniform vec4 uOutputTexture;
220
+
221
+ void main() {
222
+ vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy;
223
+ position.x = position.x * (2.0 / uOutputTexture.x) - 1.0;
224
+ position.y = position.y * (2.0 * uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z;
225
+ gl_Position = vec4(position, 0.0, 1.0);
226
+ vTextureCoord = aPosition;
227
+ }
228
+ `;
229
+ const rainFragment = `
230
+ in vec2 vTextureCoord;
231
+ out vec4 finalColor;
232
+
233
+ uniform sampler2D uTexture;
234
+ uniform float uTime;
235
+ uniform float uRainAmount;
236
+ uniform float uQuality;
237
+
238
+ float hash21(vec2 p) {
239
+ return fract(sin(dot(p, vec2(41.31, 289.17))) * 28419.231);
240
+ }
241
+
242
+ float rainLayer(vec2 uv, float scale, float speed, float width, float length, float brightness) {
243
+ vec2 p = uv * vec2(150.0 * scale, 78.0 * scale);
244
+ p.x += p.y * 0.24;
245
+ // Texture coordinates grow downwards in Pixi. Subtracting time makes the
246
+ // streak cells travel towards increasing screen Y instead of rising upward.
247
+ p.y -= uTime * speed;
248
+ vec2 id = floor(p);
249
+ vec2 cell = fract(p) - 0.5;
250
+ float seed = hash21(id);
251
+ float thinLine = 1.0 - smoothstep(width, width * 2.0, abs(cell.x + seed * 0.16 - 0.08));
252
+ float longStreak = 1.0 - smoothstep(length, length * 1.35, abs(cell.y));
253
+ return thinLine * longStreak * brightness * step(1.0 - uRainAmount, seed);
254
+ }
255
+
256
+ void main() {
257
+ vec2 uv = vTextureCoord;
258
+ float detail = mix(0.78, 1.0, uQuality);
259
+ float rain = rainLayer(uv, 0.72 * detail, 1.15, 0.010, 0.42, 0.28);
260
+ rain += rainLayer(uv + vec2(0.17, 0.0), 1.28 * detail, 1.78, 0.007, 0.46, 0.62);
261
+ float alpha = clamp(rain, 0.0, 0.82);
262
+ finalColor = vec4(vec3(0.66, 0.82, 0.96) * alpha, alpha);
263
+ }
264
+ `;
265
+ const puddleFragment = `
266
+ in vec2 vTextureCoord;
267
+ out vec4 finalColor;
268
+
269
+ uniform sampler2D uTexture;
270
+ uniform sampler2D uReflection;
271
+ uniform float uTime;
272
+ uniform float uWaterLevel;
273
+ uniform float uGroundLevel;
274
+ uniform float uGroundFeather;
275
+ uniform float uReflectionStrength;
276
+ uniform float uRippleDuration;
277
+ uniform vec4 uRipples[${MAX_SHADER_RIPPLES}];
278
+ uniform vec4 uRippleDirections[${MAX_SHADER_RIPPLES}];
279
+ uniform vec4 uClickRipple;
280
+
281
+ float puddleShape(vec2 uv, vec2 center, vec2 radii, float seed) {
282
+ vec2 p = (uv - center) / radii;
283
+ float angle = atan(p.y, p.x);
284
+ float edgeNoise = sin(angle * 5.0 + seed) * 0.075 + sin(angle * 9.0 - seed) * 0.035;
285
+ float distanceToCenter = length(p) + edgeNoise;
286
+ return 1.0 - smoothstep(0.72 + (1.0 - uWaterLevel) * 0.20, 1.02, distanceToCenter);
287
+ }
288
+
289
+ float ring(vec2 uv, vec2 center, float radius, float width) {
290
+ float distanceToCenter = length(uv - center);
291
+ return 1.0 - smoothstep(width, width * 2.1, abs(distanceToCenter - radius));
292
+ }
293
+
294
+ float projectedFootWave(vec2 uv, vec4 state, vec2 direction) {
295
+ float phase = clamp(state.z / 1.10, 0.0, 1.0);
296
+ float fade = (1.0 - phase) * state.w;
297
+ vec2 wakeCenter = state.xy - direction * phase * 0.014;
298
+ vec2 delta = uv - wakeCenter;
299
+ float projectedDistance = length(vec2(delta.x, delta.y * 3.0));
300
+ float radius = 0.006 + phase * 0.058;
301
+ float leading = 1.0 - smoothstep(0.0018, 0.0040, abs(projectedDistance - radius));
302
+ float secondary = 1.0 - smoothstep(0.0015, 0.0033, abs(projectedDistance - radius * 0.63));
303
+ vec2 trailDelta = uv - (wakeCenter - direction * 0.018 * phase);
304
+ float trailDistance = length(vec2(trailDelta.x, trailDelta.y * 3.0));
305
+ float trail = 1.0 - smoothstep(0.0020, 0.0045, abs(trailDistance - radius * 0.76));
306
+ return (leading + secondary * 0.34 + trail * 0.42) * fade;
307
+ }
308
+
309
+ void main() {
310
+ vec2 uv = vTextureCoord;
311
+ float mask = puddleShape(uv, vec2(0.26, 0.68), vec2(0.21, 0.12), 0.3);
312
+ mask = max(mask, puddleShape(uv, vec2(0.56, 0.77), vec2(0.26, 0.10), 2.2));
313
+ mask = max(mask, puddleShape(uv, vec2(0.82, 0.59), vec2(0.14, 0.18), 4.1));
314
+ mask *= smoothstep(uGroundLevel, uGroundLevel + max(uGroundFeather, 0.0001), uv.y);
315
+ mask *= smoothstep(0.04, 0.17, uWaterLevel);
316
+
317
+ float smallWaves = sin(uv.y * 920.0 + uTime * 2.2) + sin(uv.x * 700.0 - uTime * 1.7);
318
+ vec2 distortion = vec2(smallWaves * 0.00075, sin(uv.x * 510.0 + uTime * 2.0) * 0.0011);
319
+
320
+ for (int index = 0; index < 5; index++) {
321
+ float fi = float(index);
322
+ float phase = fract(uTime * (0.13 + fi * 0.023) + fi * 0.618);
323
+ vec2 center = vec2(fract(fi * 0.347 + 0.14), fract(fi * 0.613 + 0.52));
324
+ float radius = phase * 0.075;
325
+ float rainRipple = ring(uv, center, radius, 0.0018) * (1.0 - phase);
326
+ distortion += normalize(uv - center + vec2(0.0001)) * rainRipple * 0.004;
327
+ }
328
+
329
+ float clickPhase = clamp(uClickRipple.z / 1.55, 0.0, 1.0);
330
+ float clickRing = ring(uv, uClickRipple.xy, clickPhase * 0.14, 0.0025) * (1.0 - clickPhase) * uClickRipple.w;
331
+ distortion += normalize(uv - uClickRipple.xy + vec2(0.0001)) * clickRing * 0.012;
332
+
333
+ float footRing = 0.0;
334
+ vec2 footPush = vec2(0.0);
335
+ for (int index = 0; index < ${MAX_SHADER_RIPPLES}; index++) {
336
+ vec4 state = uRipples[index];
337
+ if (state.z < 0.0 || state.z >= uRippleDuration) continue;
338
+ float wave = projectedFootWave(uv, state, uRippleDirections[index].xy);
339
+ footRing += wave;
340
+ footPush += (uv - state.xy) * wave;
341
+ }
342
+ footRing = clamp(footRing, 0.0, 1.5);
343
+ distortion += normalize(footPush + vec2(0.0001)) * footRing * 0.0065;
344
+
345
+ vec4 reflection = texture(uReflection, clamp(uv + distortion, vec2(0.002), vec2(0.998)));
346
+ vec3 waterTint = vec3(0.055, 0.15, 0.23);
347
+ float reflectedAmount = reflection.a * uReflectionStrength;
348
+ vec3 color = mix(waterTint, reflection.rgb + vec3(0.03, 0.06, 0.09), reflectedAmount);
349
+ color += vec3(0.30, 0.48, 0.58) * (clickRing + footRing * 1.10 + 0.18 * max(0.0, smallWaves)) * 0.24;
350
+ float alpha = mask * (0.82 + 0.16 * uWaterLevel);
351
+ finalColor = vec4(color * alpha, alpha);
352
+ }
353
+ `;
354
+ function numberUniform(uniforms, key, fallback) {
355
+ const value = uniforms[key];
356
+ return typeof value === 'number' && Number.isFinite(value) ? value : fallback;
357
+ }
358
+ const rainFactory = () => {
359
+ const group = new pixi_js.UniformGroup({
360
+ uTime: {
361
+ value: 0,
362
+ type: 'f32'
363
+ },
364
+ uRainAmount: {
365
+ value: 0.65,
366
+ type: 'f32'
367
+ },
368
+ uQuality: {
369
+ value: 1,
370
+ type: 'f32'
371
+ }
372
+ });
373
+ const filter = new pixi_js.Filter({
374
+ glProgram: pixi_js.GlProgram.from({
375
+ name: RAIN_EFFECT_ID,
376
+ vertex: normalizedScreenFilterVert,
377
+ fragment: rainFragment
378
+ }),
379
+ resources: {
380
+ rainUniforms: group
381
+ },
382
+ antialias: 'on'
383
+ });
384
+ return {
385
+ filter,
386
+ update(frame, uniforms) {
387
+ const values = group.uniforms;
388
+ values.uTime = frame.rafTime / 1000;
389
+ values.uRainAmount = numberUniform(uniforms, 'rainAmount', 0.65);
390
+ values.uQuality = numberUniform(uniforms, 'quality', 1);
391
+ },
392
+ destroy() {
393
+ filter.destroy();
394
+ }
395
+ };
396
+ };
397
+ Object.defineProperty(rainFactory, 'backends', {
398
+ value: ['webgl']
399
+ });
400
+ const puddleFactory = () => {
401
+ const rippleBuffer = new Float32Array(MAX_SHADER_RIPPLES * 4);
402
+ const rippleDirectionBuffer = new Float32Array(MAX_SHADER_RIPPLES * 4);
403
+ const clickRippleBuffer = new Float32Array([-2, -2, 99, 0]);
404
+ for (let index = 0; index < MAX_SHADER_RIPPLES; index += 1) rippleBuffer[index * 4 + 2] = -1;
405
+ const group = new pixi_js.UniformGroup({
406
+ uTime: {
407
+ value: 0,
408
+ type: 'f32'
409
+ },
410
+ uWaterLevel: {
411
+ value: 0.5,
412
+ type: 'f32'
413
+ },
414
+ uGroundLevel: {
415
+ value: 0.545,
416
+ type: 'f32'
417
+ },
418
+ uGroundFeather: {
419
+ value: 0.02,
420
+ type: 'f32'
421
+ },
422
+ uReflectionStrength: {
423
+ value: 0.55,
424
+ type: 'f32'
425
+ },
426
+ uRippleDuration: {
427
+ value: 1.6,
428
+ type: 'f32'
429
+ },
430
+ uRipples: {
431
+ value: rippleBuffer,
432
+ type: 'vec4<f32>',
433
+ size: MAX_SHADER_RIPPLES
434
+ },
435
+ uRippleDirections: {
436
+ value: rippleDirectionBuffer,
437
+ type: 'vec4<f32>',
438
+ size: MAX_SHADER_RIPPLES
439
+ },
440
+ uClickRipple: {
441
+ value: clickRippleBuffer,
442
+ type: 'vec4<f32>'
443
+ }
444
+ });
445
+ const filter = new pixi_js.Filter({
446
+ glProgram: pixi_js.GlProgram.from({
447
+ name: PUDDLE_EFFECT_ID,
448
+ vertex: normalizedScreenFilterVert,
449
+ fragment: puddleFragment
450
+ }),
451
+ resources: {
452
+ puddleUniforms: group,
453
+ uReflection: pixi_js.Texture.EMPTY.source
454
+ },
455
+ antialias: 'on'
456
+ });
457
+ let boundTextureKey = '';
458
+ return {
459
+ filter,
460
+ update(frame, uniforms) {
461
+ const values = group.uniforms;
462
+ values.uTime = frame.rafTime / 1000;
463
+ values.uWaterLevel = numberUniform(uniforms, 'waterLevel', 0.5);
464
+ values.uGroundLevel = numberUniform(uniforms, 'groundLevel', 0.545);
465
+ values.uGroundFeather = numberUniform(uniforms, 'groundFeather', 0.02);
466
+ values.uReflectionStrength = numberUniform(uniforms, 'reflectionStrength', 0.55);
467
+ values.uRippleDuration = numberUniform(uniforms, 'rippleDuration', 1.6);
468
+ const incomingRipples = uniforms.ripples;
469
+ rippleBuffer.fill(0);
470
+ for (let index = 0; index < MAX_SHADER_RIPPLES; index += 1) rippleBuffer[index * 4 + 2] = -1;
471
+ if (incomingRipples instanceof Float32Array) {
472
+ rippleBuffer.set(incomingRipples.subarray(0, rippleBuffer.length));
473
+ }
474
+ rippleDirectionBuffer.fill(0);
475
+ const incomingDirections = uniforms.rippleDirections;
476
+ if (incomingDirections instanceof Float32Array) {
477
+ rippleDirectionBuffer.set(incomingDirections.subarray(0, rippleDirectionBuffer.length));
478
+ }
479
+ clickRippleBuffer.set([-2, -2, 99, 0]);
480
+ const incomingClickRipple = uniforms.clickRipple;
481
+ if (incomingClickRipple instanceof Float32Array) {
482
+ clickRippleBuffer.set(incomingClickRipple.subarray(0, clickRippleBuffer.length));
483
+ }
484
+ const textureKey = typeof uniforms.reflectionTexture === 'string' ? uniforms.reflectionTexture : '';
485
+ if (textureKey && textureKey !== boundTextureKey) {
486
+ const texture = pluginRendererSceneCapture.getSceneCaptureTexture(textureKey);
487
+ if (texture) {
488
+ filter.resources.uReflection = texture.source;
489
+ boundTextureKey = textureKey;
490
+ }
491
+ }
492
+ },
493
+ destroy() {
494
+ filter.destroy();
495
+ }
496
+ };
497
+ };
498
+ Object.defineProperty(puddleFactory, 'backends', {
499
+ value: ['webgl']
500
+ });
501
+ function registerRainPuddleEffects() {
502
+ if (!pluginRendererShaderEffect.getShaderEffect(RAIN_EFFECT_ID)) pluginRendererShaderEffect.registerShaderEffect(RAIN_EFFECT_ID, rainFactory);
503
+ if (!pluginRendererShaderEffect.getShaderEffect(PUDDLE_EFFECT_ID)) pluginRendererShaderEffect.registerShaderEffect(PUDDLE_EFFECT_ID, puddleFactory);
504
+ }
505
+ function unregisterRainPuddleEffects() {
506
+ pluginRendererShaderEffect.unregisterShaderEffect(RAIN_EFFECT_ID);
507
+ pluginRendererShaderEffect.unregisterShaderEffect(PUDDLE_EFFECT_ID);
508
+ }
509
+ const rainPuddleShaderSources = {
510
+ vertex: normalizedScreenFilterVert,
511
+ rainFragment,
512
+ puddleFragment
513
+ };
514
+ exports.DEFAULT_MAX_RIPPLES = DEFAULT_MAX_RIPPLES;
515
+ exports.MAX_SHADER_RIPPLES = MAX_SHADER_RIPPLES;
516
+ exports.PUDDLE_EFFECT_ID = PUDDLE_EFFECT_ID;
517
+ exports.RAIN_EFFECT_ID = RAIN_EFFECT_ID;
518
+ exports.RIPPLE_STRIDE = RIPPLE_STRIDE;
519
+ exports.RainPuddle = RainPuddle;
520
+ exports.RainPuddleSystem = RainPuddleSystem$1;
521
+ exports.rainPuddleShaderSources = rainPuddleShaderSources;
522
+ exports.registerRainPuddleEffects = registerRainPuddleEffects;
523
+ exports.unregisterRainPuddleEffects = unregisterRainPuddleEffects;
524
+ Object.defineProperty(exports, '__esModule', {
525
+ value: true
526
+ });
527
+ return exports;
528
+ }({}, EVA, EVA.plugin.renderer.shader.effect, PIXI, EVA.plugin.renderer.scene.capture);
529
+ globalThis.EVA.plugin.renderer.rain.puddle = globalThis.EVA.plugin.renderer.rain.puddle || _EVA_IIFE_puddle;
@@ -0,0 +1 @@
1
+ globalThis.EVA=globalThis.EVA||{},globalThis.EVA.plugin=globalThis.EVA.plugin||{},globalThis.EVA.plugin.renderer=globalThis.EVA.plugin.renderer||{},globalThis.EVA.plugin.renderer.rain=globalThis.EVA.plugin.renderer.rain||{};var _EVA_IIFE_puddle=function(e,t,n,i,r){"use strict";class a extends t.Component{constructor(){super(...arguments),this.rainAmount=.65,this.waterLevel=.5,this.groundLevel=.545,this.groundFeather=.02,this.reflectionStrength=.55,this.rippleDuration=1.6,this.maxRipples=4,this.quality="high",this.reflectionTexture="",this.rainSurfaceName="rain-surface",this.puddleSurfaceName="puddle-surface",this.rippleUniformData=new Float32Array(16),this.rippleDirectionUniformData=new Float32Array(16),this.clickRippleUniformData=new Float32Array([-2,-2,99,0]),this.activeRippleCount=0,this.nextRippleIndex=0}init(e={}){var t,n,i,r,a,u,s,c,p,f,d,m,h,v;this.rainAmount=l(null!==(t=e.rainAmount)&&void 0!==t?t:this.rainAmount),this.waterLevel=l(null!==(n=e.waterLevel)&&void 0!==n?n:this.waterLevel),this.groundLevel=l(null!==(i=e.groundLevel)&&void 0!==i?i:this.groundLevel),this.groundFeather=o(null!==(r=e.groundFeather)&&void 0!==r?r:this.groundFeather,.001,1),this.reflectionStrength=l(null!==(a=e.reflectionStrength)&&void 0!==a?a:this.reflectionStrength),this.rippleDuration=Math.max(.05,null!==(u=e.rippleDuration)&&void 0!==u?u:this.rippleDuration),this.maxRipples=(m=null!==(s=e.maxRipples)&&void 0!==s?s:this.maxRipples,h=1,v=8,Math.round(o(m,h,v))),this.quality=null!==(c=e.quality)&&void 0!==c?c:this.quality,this.reflectionTexture=null!==(p=e.reflectionTexture)&&void 0!==p?p:this.reflectionTexture,this.rainSurfaceName=null!==(f=e.rainSurfaceName)&&void 0!==f?f:this.rainSurfaceName,this.puddleSurfaceName=null!==(d=e.puddleSurfaceName)&&void 0!==d?d:this.puddleSurfaceName,this.rippleUniformData=new Float32Array(4*this.maxRipples),this.rippleDirectionUniformData=new Float32Array(4*this.maxRipples),this.clickRippleUniformData=new Float32Array([-2,-2,99,0]),this.resetRipples()}emitRipple(e){var t;const n=this.nextRippleIndex,i=4*n,r=this.rippleUniformData[i+2]>=0;this.rippleUniformData[i]=l(e.x),this.rippleUniformData[i+1]=l(e.y),this.rippleUniformData[i+2]=0,this.rippleUniformData[i+3]=l(null!==(t=e.strength)&&void 0!==t?t:1);const a=function(e){var t,n;const i="number"==typeof e?e:Number(null!==(t=null==e?void 0:e.x)&&void 0!==t?t:0),r="number"==typeof e?0:Number(null!==(n=null==e?void 0:e.y)&&void 0!==n?n:0),a=Math.hypot(i,r);return a>0?{x:i/a,y:r/a}:{x:0,y:1}}(e.direction),o=4*n;this.rippleDirectionUniformData[o]=a.x,this.rippleDirectionUniformData[o+1]=a.y,r||(this.activeRippleCount+=1),this.nextRippleIndex=(n+1)%this.maxRipples}emitClickRipple(e){var t;this.clickRippleUniformData[0]=l(e.x),this.clickRippleUniformData[1]=l(e.y),this.clickRippleUniformData[2]=0,this.clickRippleUniformData[3]=l(null!==(t=e.strength)&&void 0!==t?t:1)}advanceRipples(e){if(e>0){for(let t=0;t<this.maxRipples;t+=1){const n=4*t+2,i=this.rippleUniformData[n];if(i<0)continue;const r=i+e;r>=this.rippleDuration?(this.rippleUniformData[n]=-1,this.activeRippleCount-=1):this.rippleUniformData[n]=r}this.clickRippleUniformData[2]>=0&&this.clickRippleUniformData[2]<this.rippleDuration&&(this.clickRippleUniformData[2]+=e)}}getRippleDirection(e){var t,n;const i=4*e;return{x:null!==(t=this.rippleDirectionUniformData[i])&&void 0!==t?t:0,y:null!==(n=this.rippleDirectionUniformData[i+1])&&void 0!==n?n:0}}resetRipples(){this.rippleUniformData.fill(0);for(let e=0;e<this.maxRipples;e+=1)this.rippleUniformData[4*e+2]=-1;this.rippleDirectionUniformData.fill(0),this.clickRippleUniformData.set([-2,-2,99,0]),this.nextRippleIndex=0,this.activeRippleCount=0}}function o(e,t,n){return Math.min(n,Math.max(t,e))}function l(e){return o(e,0,1)}a.componentName="RainPuddle";let u=class extends t.System{constructor(){super(...arguments),this.name="RainPuddleSystem",this.bindings=new Map}update(){this.consumeObserverChanges()}consumeObserverChanges(){for(const e of this.componentObserver.clear())this.componentChanged(e)}componentChanged(e){e.componentName===a.componentName&&(e.type!==t.OBSERVER_TYPE.REMOVE?e.type===t.OBSERVER_TYPE.ADD&&this.bindings.set(e.gameObject.id,{component:e.component}):this.bindings.delete(e.gameObject.id))}frameStart(e){this.consumeObserverChanges();const t=Math.min(.1,Math.max(0,e.rafDeltaTime/1e3));for(const e of this.bindings.values()){const n=e.component;n.advanceRipples(t),e.rainEffect=this.resolveEffect(e.rainEffect,n.rainSurfaceName),e.puddleEffect=this.resolveEffect(e.puddleEffect,n.puddleSurfaceName),e.rainEffect&&(e.rainEffect.uniforms.rainAmount=n.rainAmount,e.rainEffect.uniforms.quality=c(n.quality)),e.puddleEffect&&(e.puddleEffect.uniforms.waterLevel=n.waterLevel,e.puddleEffect.uniforms.groundLevel=n.groundLevel,e.puddleEffect.uniforms.groundFeather=n.groundFeather,e.puddleEffect.uniforms.reflectionStrength=n.reflectionStrength,e.puddleEffect.uniforms.rippleDuration=n.rippleDuration,e.puddleEffect.uniforms.ripples=n.rippleUniformData,e.puddleEffect.uniforms.rippleDirections=n.rippleDirectionUniformData,e.puddleEffect.uniforms.clickRipple=n.clickRippleUniformData,e.puddleEffect.uniforms.reflectionTexture=n.reflectionTexture)}}onDestroy(){this.bindings.clear()}resolveEffect(e,t){var i,r,a;if((null==e?void 0:e.gameObject)&&!e.gameObject.destroyed)return e;if(!t)return;const o=null===(a=null===(r=null===(i=this.game)||void 0===i?void 0:i.findAllByName)||void 0===r?void 0:r.call(i,t))||void 0===a?void 0:a[0];return null==o?void 0:o.getComponent(n.ShaderEffect)}};u.systemName="RainPuddleSystem",u=function(e,t,n,i){var r,a=arguments.length,o=a<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,n):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,n,i);else for(var l=e.length-1;l>=0;l--)(r=e[l])&&(o=(a<3?r(o):a>3?r(t,n,o):r(t,n))||o);return a>3&&o&&Object.defineProperty(t,n,o),o}([t.decorators.componentObserver({RainPuddle:[]})],u);var s=u;function c(e){return"low"===e?0:"medium"===e?.55:1}const p="eva.rain-puddle.rain",f="eva.rain-puddle.puddle",d="\nin vec2 aPosition;\nout vec2 vTextureCoord;\n\nuniform vec4 uOutputFrame;\nuniform vec4 uOutputTexture;\n\nvoid main() {\n vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy;\n position.x = position.x * (2.0 / uOutputTexture.x) - 1.0;\n position.y = position.y * (2.0 * uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z;\n gl_Position = vec4(position, 0.0, 1.0);\n vTextureCoord = aPosition;\n}\n",m="\nin vec2 vTextureCoord;\nout vec4 finalColor;\n\nuniform sampler2D uTexture;\nuniform float uTime;\nuniform float uRainAmount;\nuniform float uQuality;\n\nfloat hash21(vec2 p) {\n return fract(sin(dot(p, vec2(41.31, 289.17))) * 28419.231);\n}\n\nfloat rainLayer(vec2 uv, float scale, float speed, float width, float length, float brightness) {\n vec2 p = uv * vec2(150.0 * scale, 78.0 * scale);\n p.x += p.y * 0.24;\n // Texture coordinates grow downwards in Pixi. Subtracting time makes the\n // streak cells travel towards increasing screen Y instead of rising upward.\n p.y -= uTime * speed;\n vec2 id = floor(p);\n vec2 cell = fract(p) - 0.5;\n float seed = hash21(id);\n float thinLine = 1.0 - smoothstep(width, width * 2.0, abs(cell.x + seed * 0.16 - 0.08));\n float longStreak = 1.0 - smoothstep(length, length * 1.35, abs(cell.y));\n return thinLine * longStreak * brightness * step(1.0 - uRainAmount, seed);\n}\n\nvoid main() {\n vec2 uv = vTextureCoord;\n float detail = mix(0.78, 1.0, uQuality);\n float rain = rainLayer(uv, 0.72 * detail, 1.15, 0.010, 0.42, 0.28);\n rain += rainLayer(uv + vec2(0.17, 0.0), 1.28 * detail, 1.78, 0.007, 0.46, 0.62);\n float alpha = clamp(rain, 0.0, 0.82);\n finalColor = vec4(vec3(0.66, 0.82, 0.96) * alpha, alpha);\n}\n",h="\nin vec2 vTextureCoord;\nout vec4 finalColor;\n\nuniform sampler2D uTexture;\nuniform sampler2D uReflection;\nuniform float uTime;\nuniform float uWaterLevel;\nuniform float uGroundLevel;\nuniform float uGroundFeather;\nuniform float uReflectionStrength;\nuniform float uRippleDuration;\nuniform vec4 uRipples[8];\nuniform vec4 uRippleDirections[8];\nuniform vec4 uClickRipple;\n\nfloat puddleShape(vec2 uv, vec2 center, vec2 radii, float seed) {\n vec2 p = (uv - center) / radii;\n float angle = atan(p.y, p.x);\n float edgeNoise = sin(angle * 5.0 + seed) * 0.075 + sin(angle * 9.0 - seed) * 0.035;\n float distanceToCenter = length(p) + edgeNoise;\n return 1.0 - smoothstep(0.72 + (1.0 - uWaterLevel) * 0.20, 1.02, distanceToCenter);\n}\n\nfloat ring(vec2 uv, vec2 center, float radius, float width) {\n float distanceToCenter = length(uv - center);\n return 1.0 - smoothstep(width, width * 2.1, abs(distanceToCenter - radius));\n}\n\nfloat projectedFootWave(vec2 uv, vec4 state, vec2 direction) {\n float phase = clamp(state.z / 1.10, 0.0, 1.0);\n float fade = (1.0 - phase) * state.w;\n vec2 wakeCenter = state.xy - direction * phase * 0.014;\n vec2 delta = uv - wakeCenter;\n float projectedDistance = length(vec2(delta.x, delta.y * 3.0));\n float radius = 0.006 + phase * 0.058;\n float leading = 1.0 - smoothstep(0.0018, 0.0040, abs(projectedDistance - radius));\n float secondary = 1.0 - smoothstep(0.0015, 0.0033, abs(projectedDistance - radius * 0.63));\n vec2 trailDelta = uv - (wakeCenter - direction * 0.018 * phase);\n float trailDistance = length(vec2(trailDelta.x, trailDelta.y * 3.0));\n float trail = 1.0 - smoothstep(0.0020, 0.0045, abs(trailDistance - radius * 0.76));\n return (leading + secondary * 0.34 + trail * 0.42) * fade;\n}\n\nvoid main() {\n vec2 uv = vTextureCoord;\n float mask = puddleShape(uv, vec2(0.26, 0.68), vec2(0.21, 0.12), 0.3);\n mask = max(mask, puddleShape(uv, vec2(0.56, 0.77), vec2(0.26, 0.10), 2.2));\n mask = max(mask, puddleShape(uv, vec2(0.82, 0.59), vec2(0.14, 0.18), 4.1));\n mask *= smoothstep(uGroundLevel, uGroundLevel + max(uGroundFeather, 0.0001), uv.y);\n mask *= smoothstep(0.04, 0.17, uWaterLevel);\n\n float smallWaves = sin(uv.y * 920.0 + uTime * 2.2) + sin(uv.x * 700.0 - uTime * 1.7);\n vec2 distortion = vec2(smallWaves * 0.00075, sin(uv.x * 510.0 + uTime * 2.0) * 0.0011);\n\n for (int index = 0; index < 5; index++) {\n float fi = float(index);\n float phase = fract(uTime * (0.13 + fi * 0.023) + fi * 0.618);\n vec2 center = vec2(fract(fi * 0.347 + 0.14), fract(fi * 0.613 + 0.52));\n float radius = phase * 0.075;\n float rainRipple = ring(uv, center, radius, 0.0018) * (1.0 - phase);\n distortion += normalize(uv - center + vec2(0.0001)) * rainRipple * 0.004;\n }\n\n float clickPhase = clamp(uClickRipple.z / 1.55, 0.0, 1.0);\n float clickRing = ring(uv, uClickRipple.xy, clickPhase * 0.14, 0.0025) * (1.0 - clickPhase) * uClickRipple.w;\n distortion += normalize(uv - uClickRipple.xy + vec2(0.0001)) * clickRing * 0.012;\n\n float footRing = 0.0;\n vec2 footPush = vec2(0.0);\n for (int index = 0; index < 8; index++) {\n vec4 state = uRipples[index];\n if (state.z < 0.0 || state.z >= uRippleDuration) continue;\n float wave = projectedFootWave(uv, state, uRippleDirections[index].xy);\n footRing += wave;\n footPush += (uv - state.xy) * wave;\n }\n footRing = clamp(footRing, 0.0, 1.5);\n distortion += normalize(footPush + vec2(0.0001)) * footRing * 0.0065;\n\n vec4 reflection = texture(uReflection, clamp(uv + distortion, vec2(0.002), vec2(0.998)));\n vec3 waterTint = vec3(0.055, 0.15, 0.23);\n float reflectedAmount = reflection.a * uReflectionStrength;\n vec3 color = mix(waterTint, reflection.rgb + vec3(0.03, 0.06, 0.09), reflectedAmount);\n color += vec3(0.30, 0.48, 0.58) * (clickRing + footRing * 1.10 + 0.18 * max(0.0, smallWaves)) * 0.24;\n float alpha = mask * (0.82 + 0.16 * uWaterLevel);\n finalColor = vec4(color * alpha, alpha);\n}\n";function v(e,t,n){const i=e[t];return"number"==typeof i&&Number.isFinite(i)?i:n}const g=()=>{const e=new i.UniformGroup({uTime:{value:0,type:"f32"},uRainAmount:{value:.65,type:"f32"},uQuality:{value:1,type:"f32"}}),t=new i.Filter({glProgram:i.GlProgram.from({name:p,vertex:d,fragment:m}),resources:{rainUniforms:e},antialias:"on"});return{filter:t,update(t,n){const i=e.uniforms;i.uTime=t.rafTime/1e3,i.uRainAmount=v(n,"rainAmount",.65),i.uQuality=v(n,"quality",1)},destroy(){t.destroy()}}};Object.defineProperty(g,"backends",{value:["webgl"]});const R=()=>{const e=new Float32Array(32),t=new Float32Array(32),n=new Float32Array([-2,-2,99,0]);for(let t=0;t<8;t+=1)e[4*t+2]=-1;const a=new i.UniformGroup({uTime:{value:0,type:"f32"},uWaterLevel:{value:.5,type:"f32"},uGroundLevel:{value:.545,type:"f32"},uGroundFeather:{value:.02,type:"f32"},uReflectionStrength:{value:.55,type:"f32"},uRippleDuration:{value:1.6,type:"f32"},uRipples:{value:e,type:"vec4<f32>",size:8},uRippleDirections:{value:t,type:"vec4<f32>",size:8},uClickRipple:{value:n,type:"vec4<f32>"}}),o=new i.Filter({glProgram:i.GlProgram.from({name:f,vertex:d,fragment:h}),resources:{puddleUniforms:a,uReflection:i.Texture.EMPTY.source},antialias:"on"});let l="";return{filter:o,update(i,u){const s=a.uniforms;s.uTime=i.rafTime/1e3,s.uWaterLevel=v(u,"waterLevel",.5),s.uGroundLevel=v(u,"groundLevel",.545),s.uGroundFeather=v(u,"groundFeather",.02),s.uReflectionStrength=v(u,"reflectionStrength",.55),s.uRippleDuration=v(u,"rippleDuration",1.6);const c=u.ripples;e.fill(0);for(let t=0;t<8;t+=1)e[4*t+2]=-1;c instanceof Float32Array&&e.set(c.subarray(0,e.length)),t.fill(0);const p=u.rippleDirections;p instanceof Float32Array&&t.set(p.subarray(0,t.length)),n.set([-2,-2,99,0]);const f=u.clickRipple;f instanceof Float32Array&&n.set(f.subarray(0,n.length));const d="string"==typeof u.reflectionTexture?u.reflectionTexture:"";if(d&&d!==l){const e=r.getSceneCaptureTexture(d);e&&(o.resources.uReflection=e.source,l=d)}},destroy(){o.destroy()}}};Object.defineProperty(R,"backends",{value:["webgl"]});const y={vertex:d,rainFragment:m,puddleFragment:h};return e.DEFAULT_MAX_RIPPLES=4,e.MAX_SHADER_RIPPLES=8,e.PUDDLE_EFFECT_ID=f,e.RAIN_EFFECT_ID=p,e.RIPPLE_STRIDE=4,e.RainPuddle=a,e.RainPuddleSystem=s,e.rainPuddleShaderSources=y,e.registerRainPuddleEffects=function(){n.getShaderEffect(p)||n.registerShaderEffect(p,g),n.getShaderEffect(f)||n.registerShaderEffect(f,R)},e.unregisterRainPuddleEffects=function(){n.unregisterShaderEffect(p),n.unregisterShaderEffect(f)},Object.defineProperty(e,"__esModule",{value:!0}),e}({},EVA,EVA.plugin.renderer.shader.effect,PIXI,EVA.plugin.renderer.scene.capture);globalThis.EVA.plugin.renderer.rain.puddle=globalThis.EVA.plugin.renderer.rain.puddle||_EVA_IIFE_puddle;