@toriistudio/shader-ui 0.0.7 → 0.0.9
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/dist/index.d.mts +27 -4
- package/dist/index.d.ts +27 -4
- package/dist/index.js +817 -139
- package/dist/index.mjs +813 -139
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3533,11 +3533,8 @@ import {
|
|
|
3533
3533
|
} from "react";
|
|
3534
3534
|
import * as THREE8 from "three";
|
|
3535
3535
|
|
|
3536
|
-
// src/
|
|
3537
|
-
import {
|
|
3538
|
-
createContext,
|
|
3539
|
-
useContext
|
|
3540
|
-
} from "react";
|
|
3536
|
+
// src/context/SceneProvider.tsx
|
|
3537
|
+
import { createContext, useContext } from "react";
|
|
3541
3538
|
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
3542
3539
|
var SceneProviderContext = createContext(null);
|
|
3543
3540
|
function SceneProvider({
|
|
@@ -3732,7 +3729,15 @@ function ShaderPass({
|
|
|
3732
3729
|
context.renderer.setRenderTarget(prevTarget);
|
|
3733
3730
|
context.renderer.autoClear = prevAutoClear;
|
|
3734
3731
|
},
|
|
3735
|
-
[
|
|
3732
|
+
[
|
|
3733
|
+
clear,
|
|
3734
|
+
clearColor,
|
|
3735
|
+
enabled,
|
|
3736
|
+
resolutionUniform,
|
|
3737
|
+
target,
|
|
3738
|
+
timeUniform,
|
|
3739
|
+
uniforms
|
|
3740
|
+
]
|
|
3736
3741
|
);
|
|
3737
3742
|
const sharedContextRef = sharedScene?.contextRef;
|
|
3738
3743
|
const shouldCreateOwnScene = !sharedContextRef;
|
|
@@ -3762,13 +3767,10 @@ function ShaderPass({
|
|
|
3762
3767
|
renderOnce();
|
|
3763
3768
|
return;
|
|
3764
3769
|
}
|
|
3765
|
-
const unregister = register(
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
},
|
|
3770
|
-
priority
|
|
3771
|
-
);
|
|
3770
|
+
const unregister = register((ctx, delta, elapsed) => {
|
|
3771
|
+
void elapsed;
|
|
3772
|
+
handleRender(ctx, delta);
|
|
3773
|
+
}, priority);
|
|
3772
3774
|
return () => {
|
|
3773
3775
|
unregister?.();
|
|
3774
3776
|
};
|
|
@@ -4221,82 +4223,21 @@ function ExpandingRingPass({
|
|
|
4221
4223
|
}
|
|
4222
4224
|
|
|
4223
4225
|
// src/components/RenderPipeline.tsx
|
|
4224
|
-
import { useEffect as useEffect14, useMemo as useMemo12 } from "react";
|
|
4226
|
+
import { Fragment, useEffect as useEffect14, useMemo as useMemo12 } from "react";
|
|
4225
4227
|
import * as THREE16 from "three";
|
|
4226
4228
|
|
|
4227
|
-
// src/components/CombineShaderPass.tsx
|
|
4228
|
-
import { useMemo as useMemo11 } from "react";
|
|
4229
|
-
import * as THREE14 from "three";
|
|
4230
|
-
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
4231
|
-
var VERT = `
|
|
4232
|
-
out vec2 vUv;
|
|
4233
|
-
|
|
4234
|
-
void main() {
|
|
4235
|
-
vUv = uv;
|
|
4236
|
-
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
4237
|
-
}
|
|
4238
|
-
`;
|
|
4239
|
-
var FRAG = `
|
|
4240
|
-
precision highp float;
|
|
4241
|
-
|
|
4242
|
-
in vec2 vUv;
|
|
4243
|
-
|
|
4244
|
-
uniform sampler2D uTextureA;
|
|
4245
|
-
uniform sampler2D uTextureB;
|
|
4246
|
-
|
|
4247
|
-
out vec4 fragColor;
|
|
4248
|
-
|
|
4249
|
-
void main() {
|
|
4250
|
-
vec4 a = texture(uTextureA, vUv);
|
|
4251
|
-
vec4 b = texture(uTextureB, vUv);
|
|
4252
|
-
vec3 rgb = a.rgb + b.rgb;
|
|
4253
|
-
float alpha = max(a.a, b.a);
|
|
4254
|
-
fragColor = vec4(rgb, alpha);
|
|
4255
|
-
}
|
|
4256
|
-
`;
|
|
4257
|
-
function CombineShaderPass({
|
|
4258
|
-
inputA,
|
|
4259
|
-
inputB,
|
|
4260
|
-
target = null,
|
|
4261
|
-
clear = true,
|
|
4262
|
-
priority = 0
|
|
4263
|
-
}) {
|
|
4264
|
-
const uniforms = useMemo11(
|
|
4265
|
-
() => ({
|
|
4266
|
-
uTextureA: { value: inputA },
|
|
4267
|
-
uTextureB: { value: inputB }
|
|
4268
|
-
}),
|
|
4269
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4270
|
-
[]
|
|
4271
|
-
);
|
|
4272
|
-
uniforms.uTextureA.value = inputA;
|
|
4273
|
-
uniforms.uTextureB.value = inputB;
|
|
4274
|
-
return /* @__PURE__ */ jsx18(
|
|
4275
|
-
ShaderPass,
|
|
4276
|
-
{
|
|
4277
|
-
vertexShader: VERT,
|
|
4278
|
-
fragmentShader: FRAG,
|
|
4279
|
-
uniforms,
|
|
4280
|
-
target,
|
|
4281
|
-
clear,
|
|
4282
|
-
priority,
|
|
4283
|
-
blending: THREE14.NoBlending
|
|
4284
|
-
}
|
|
4285
|
-
);
|
|
4286
|
-
}
|
|
4287
|
-
|
|
4288
4229
|
// src/components/TargetPreview.tsx
|
|
4289
4230
|
import {
|
|
4290
4231
|
useCallback as useCallback8,
|
|
4291
4232
|
useEffect as useEffect13,
|
|
4292
4233
|
useRef as useRef11
|
|
4293
4234
|
} from "react";
|
|
4294
|
-
import * as
|
|
4295
|
-
import { jsx as
|
|
4235
|
+
import * as THREE14 from "three";
|
|
4236
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
4296
4237
|
function TargetPreview({
|
|
4297
4238
|
target,
|
|
4298
4239
|
renderOrder = 0,
|
|
4299
|
-
blending =
|
|
4240
|
+
blending = THREE14.NoBlending,
|
|
4300
4241
|
transparent = true,
|
|
4301
4242
|
toneMapped = false,
|
|
4302
4243
|
className,
|
|
@@ -4309,11 +4250,11 @@ function TargetPreview({
|
|
|
4309
4250
|
const sharedScene = useSceneContext();
|
|
4310
4251
|
const sharedReady = sharedScene?.ready ?? true;
|
|
4311
4252
|
const handleCreate = useCallback8(() => {
|
|
4312
|
-
const scene = new
|
|
4313
|
-
const camera = new
|
|
4253
|
+
const scene = new THREE14.Scene();
|
|
4254
|
+
const camera = new THREE14.OrthographicCamera(-1, 1, 1, -1, 0, 1);
|
|
4314
4255
|
camera.position.z = 1;
|
|
4315
|
-
const geometry = new
|
|
4316
|
-
const material = new
|
|
4256
|
+
const geometry = new THREE14.PlaneGeometry(2, 2);
|
|
4257
|
+
const material = new THREE14.MeshBasicMaterial({
|
|
4317
4258
|
map: target.texture,
|
|
4318
4259
|
toneMapped,
|
|
4319
4260
|
transparent,
|
|
@@ -4321,7 +4262,7 @@ function TargetPreview({
|
|
|
4321
4262
|
depthWrite: false,
|
|
4322
4263
|
depthTest: false
|
|
4323
4264
|
});
|
|
4324
|
-
const mesh = new
|
|
4265
|
+
const mesh = new THREE14.Mesh(geometry, material);
|
|
4325
4266
|
mesh.renderOrder = renderOrder;
|
|
4326
4267
|
scene.add(mesh);
|
|
4327
4268
|
assetsRef.current = { scene, camera, mesh, geometry, material };
|
|
@@ -4360,12 +4301,9 @@ function TargetPreview({
|
|
|
4360
4301
|
handleRender(context);
|
|
4361
4302
|
return;
|
|
4362
4303
|
}
|
|
4363
|
-
const unregister = register(
|
|
4364
|
-
(ctx)
|
|
4365
|
-
|
|
4366
|
-
},
|
|
4367
|
-
renderOrder
|
|
4368
|
-
);
|
|
4304
|
+
const unregister = register((ctx) => {
|
|
4305
|
+
handleRender(ctx);
|
|
4306
|
+
}, renderOrder);
|
|
4369
4307
|
return () => {
|
|
4370
4308
|
unregister?.();
|
|
4371
4309
|
};
|
|
@@ -4387,7 +4325,7 @@ function TargetPreview({
|
|
|
4387
4325
|
if (!shouldCreateOwnScene) {
|
|
4388
4326
|
return null;
|
|
4389
4327
|
}
|
|
4390
|
-
return /* @__PURE__ */
|
|
4328
|
+
return /* @__PURE__ */ jsx18(
|
|
4391
4329
|
"div",
|
|
4392
4330
|
{
|
|
4393
4331
|
ref: containerRef,
|
|
@@ -4402,30 +4340,260 @@ function TargetPreview({
|
|
|
4402
4340
|
);
|
|
4403
4341
|
}
|
|
4404
4342
|
|
|
4343
|
+
// src/components/CombineShaderPass.tsx
|
|
4344
|
+
import { useMemo as useMemo11 } from "react";
|
|
4345
|
+
import * as THREE15 from "three";
|
|
4346
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
4347
|
+
var COMBINE_MODE = {
|
|
4348
|
+
add: 0,
|
|
4349
|
+
screen: 1,
|
|
4350
|
+
multiply: 2,
|
|
4351
|
+
overlay: 3,
|
|
4352
|
+
max: 4,
|
|
4353
|
+
min: 5,
|
|
4354
|
+
difference: 6,
|
|
4355
|
+
alphaOver: 7,
|
|
4356
|
+
premultipliedOver: 8,
|
|
4357
|
+
lerp: 9,
|
|
4358
|
+
mask: 10
|
|
4359
|
+
};
|
|
4360
|
+
var TONEMAP = {
|
|
4361
|
+
none: 0,
|
|
4362
|
+
reinhard: 1,
|
|
4363
|
+
aces: 2
|
|
4364
|
+
};
|
|
4365
|
+
var VERT = `
|
|
4366
|
+
out vec2 vUv;
|
|
4367
|
+
|
|
4368
|
+
void main() {
|
|
4369
|
+
vUv = uv;
|
|
4370
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
4371
|
+
}
|
|
4372
|
+
`;
|
|
4373
|
+
var FRAG = `
|
|
4374
|
+
precision highp float;
|
|
4375
|
+
|
|
4376
|
+
in vec2 vUv;
|
|
4377
|
+
|
|
4378
|
+
uniform sampler2D uTextureA;
|
|
4379
|
+
uniform sampler2D uTextureB;
|
|
4380
|
+
uniform sampler2D uMaskTexture;
|
|
4381
|
+
|
|
4382
|
+
uniform int uMode;
|
|
4383
|
+
uniform float uOpacityA;
|
|
4384
|
+
uniform float uOpacityB;
|
|
4385
|
+
uniform float uMix;
|
|
4386
|
+
uniform int uMaskChannel;
|
|
4387
|
+
uniform float uMaskThreshold;
|
|
4388
|
+
uniform bool uInvertMask;
|
|
4389
|
+
uniform bool uClampOutput;
|
|
4390
|
+
uniform int uTonemap;
|
|
4391
|
+
uniform bool uHasMask;
|
|
4392
|
+
|
|
4393
|
+
out vec4 fragColor;
|
|
4394
|
+
|
|
4395
|
+
float overlayChannel(float base, float blend) {
|
|
4396
|
+
return base < 0.5
|
|
4397
|
+
? (2.0 * base * blend)
|
|
4398
|
+
: (1.0 - 2.0 * (1.0 - base) * (1.0 - blend));
|
|
4399
|
+
}
|
|
4400
|
+
|
|
4401
|
+
vec3 overlayBlend(vec3 base, vec3 blend) {
|
|
4402
|
+
return vec3(
|
|
4403
|
+
overlayChannel(base.r, blend.r),
|
|
4404
|
+
overlayChannel(base.g, blend.g),
|
|
4405
|
+
overlayChannel(base.b, blend.b)
|
|
4406
|
+
);
|
|
4407
|
+
}
|
|
4408
|
+
|
|
4409
|
+
float sampleMask(vec2 uv) {
|
|
4410
|
+
vec4 maskSample = texture(uMaskTexture, uv);
|
|
4411
|
+
float m = maskSample.r;
|
|
4412
|
+
if (uMaskChannel == 1) {
|
|
4413
|
+
m = maskSample.g;
|
|
4414
|
+
} else if (uMaskChannel == 2) {
|
|
4415
|
+
m = maskSample.b;
|
|
4416
|
+
} else if (uMaskChannel == 3) {
|
|
4417
|
+
m = maskSample.a;
|
|
4418
|
+
}
|
|
4419
|
+
if (uInvertMask) {
|
|
4420
|
+
m = 1.0 - m;
|
|
4421
|
+
}
|
|
4422
|
+
return m;
|
|
4423
|
+
}
|
|
4424
|
+
|
|
4425
|
+
vec3 tonemapReinhard(vec3 color) {
|
|
4426
|
+
return color / (color + vec3(1.0));
|
|
4427
|
+
}
|
|
4428
|
+
|
|
4429
|
+
vec3 tonemapAces(vec3 color) {
|
|
4430
|
+
// ACES approximation by Krzysztof Narkowicz
|
|
4431
|
+
float a = 2.51;
|
|
4432
|
+
float b = 0.03;
|
|
4433
|
+
float c = 2.43;
|
|
4434
|
+
float d = 0.59;
|
|
4435
|
+
float e = 0.14;
|
|
4436
|
+
return clamp((color * (a * color + b)) / (color * (c * color + d) + e), 0.0, 1.0);
|
|
4437
|
+
}
|
|
4438
|
+
|
|
4439
|
+
void main() {
|
|
4440
|
+
vec4 a = texture(uTextureA, vUv);
|
|
4441
|
+
vec4 b = texture(uTextureB, vUv);
|
|
4442
|
+
|
|
4443
|
+
a.rgb *= uOpacityA;
|
|
4444
|
+
a.a *= uOpacityA;
|
|
4445
|
+
b.rgb *= uOpacityB;
|
|
4446
|
+
b.a *= uOpacityB;
|
|
4447
|
+
|
|
4448
|
+
vec3 rgb = vec3(0.0);
|
|
4449
|
+
float alpha = 0.0;
|
|
4450
|
+
|
|
4451
|
+
if (uMode == 0) {
|
|
4452
|
+
rgb = a.rgb + b.rgb;
|
|
4453
|
+
alpha = max(a.a, b.a);
|
|
4454
|
+
} else if (uMode == 1) {
|
|
4455
|
+
rgb = 1.0 - (1.0 - a.rgb) * (1.0 - b.rgb);
|
|
4456
|
+
alpha = max(a.a, b.a);
|
|
4457
|
+
} else if (uMode == 2) {
|
|
4458
|
+
rgb = a.rgb * b.rgb;
|
|
4459
|
+
alpha = max(a.a, b.a);
|
|
4460
|
+
} else if (uMode == 3) {
|
|
4461
|
+
rgb = overlayBlend(a.rgb, b.rgb);
|
|
4462
|
+
alpha = max(a.a, b.a);
|
|
4463
|
+
} else if (uMode == 4) {
|
|
4464
|
+
rgb = max(a.rgb, b.rgb);
|
|
4465
|
+
alpha = max(a.a, b.a);
|
|
4466
|
+
} else if (uMode == 5) {
|
|
4467
|
+
rgb = min(a.rgb, b.rgb);
|
|
4468
|
+
alpha = max(a.a, b.a);
|
|
4469
|
+
} else if (uMode == 6) {
|
|
4470
|
+
rgb = abs(a.rgb - b.rgb);
|
|
4471
|
+
alpha = max(a.a, b.a);
|
|
4472
|
+
} else if (uMode == 7) {
|
|
4473
|
+
float outA = a.a + b.a * (1.0 - a.a);
|
|
4474
|
+
vec3 premult = a.rgb * a.a + b.rgb * b.a * (1.0 - a.a);
|
|
4475
|
+
vec3 outRgb = outA > 1e-6 ? premult / outA : vec3(0.0);
|
|
4476
|
+
rgb = outRgb;
|
|
4477
|
+
alpha = outA;
|
|
4478
|
+
} else if (uMode == 8) {
|
|
4479
|
+
rgb = a.rgb + b.rgb * (1.0 - a.a);
|
|
4480
|
+
alpha = a.a + b.a * (1.0 - a.a);
|
|
4481
|
+
} else if (uMode == 9) {
|
|
4482
|
+
float t = uHasMask ? sampleMask(vUv) : uMix;
|
|
4483
|
+
rgb = mix(b.rgb, a.rgb, t);
|
|
4484
|
+
alpha = mix(b.a, a.a, t);
|
|
4485
|
+
} else if (uMode == 10) {
|
|
4486
|
+
float t = uHasMask ? sampleMask(vUv) : uMix;
|
|
4487
|
+
bool chooseA = t > uMaskThreshold;
|
|
4488
|
+
rgb = chooseA ? a.rgb : b.rgb;
|
|
4489
|
+
alpha = chooseA ? a.a : b.a;
|
|
4490
|
+
}
|
|
4491
|
+
|
|
4492
|
+
if (uTonemap == 1) {
|
|
4493
|
+
rgb = tonemapReinhard(rgb);
|
|
4494
|
+
} else if (uTonemap == 2) {
|
|
4495
|
+
rgb = tonemapAces(rgb);
|
|
4496
|
+
}
|
|
4497
|
+
|
|
4498
|
+
if (uClampOutput) {
|
|
4499
|
+
rgb = clamp(rgb, 0.0, 1.0);
|
|
4500
|
+
alpha = clamp(alpha, 0.0, 1.0);
|
|
4501
|
+
}
|
|
4502
|
+
|
|
4503
|
+
fragColor = vec4(rgb, alpha);
|
|
4504
|
+
}
|
|
4505
|
+
`;
|
|
4506
|
+
function CombineShaderPass({
|
|
4507
|
+
inputA,
|
|
4508
|
+
inputB,
|
|
4509
|
+
mode = "add",
|
|
4510
|
+
opacityA = 1,
|
|
4511
|
+
opacityB = 1,
|
|
4512
|
+
clampOutput = true,
|
|
4513
|
+
mix = 0.5,
|
|
4514
|
+
maskTexture,
|
|
4515
|
+
maskChannel = 0,
|
|
4516
|
+
maskThreshold = 0.5,
|
|
4517
|
+
invertMask = false,
|
|
4518
|
+
tonemap = "none",
|
|
4519
|
+
target = null,
|
|
4520
|
+
clear = true,
|
|
4521
|
+
priority = 0
|
|
4522
|
+
}) {
|
|
4523
|
+
const uniforms = useMemo11(
|
|
4524
|
+
() => ({
|
|
4525
|
+
uTextureA: { value: inputA },
|
|
4526
|
+
uTextureB: { value: inputB },
|
|
4527
|
+
uMaskTexture: { value: maskTexture ?? inputA },
|
|
4528
|
+
uMode: { value: COMBINE_MODE[mode] },
|
|
4529
|
+
uOpacityA: { value: opacityA },
|
|
4530
|
+
uOpacityB: { value: opacityB },
|
|
4531
|
+
uMix: { value: mix },
|
|
4532
|
+
uMaskChannel: { value: maskChannel },
|
|
4533
|
+
uMaskThreshold: { value: maskThreshold },
|
|
4534
|
+
uInvertMask: { value: invertMask },
|
|
4535
|
+
uClampOutput: { value: clampOutput },
|
|
4536
|
+
uTonemap: { value: TONEMAP[tonemap] },
|
|
4537
|
+
uHasMask: { value: Boolean(maskTexture) }
|
|
4538
|
+
}),
|
|
4539
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4540
|
+
[]
|
|
4541
|
+
);
|
|
4542
|
+
uniforms.uTextureA.value = inputA;
|
|
4543
|
+
uniforms.uTextureB.value = inputB;
|
|
4544
|
+
uniforms.uMaskTexture.value = maskTexture ?? inputA;
|
|
4545
|
+
uniforms.uMode.value = COMBINE_MODE[mode];
|
|
4546
|
+
uniforms.uOpacityA.value = opacityA;
|
|
4547
|
+
uniforms.uOpacityB.value = opacityB;
|
|
4548
|
+
uniforms.uMix.value = mix;
|
|
4549
|
+
uniforms.uMaskChannel.value = maskChannel;
|
|
4550
|
+
uniforms.uMaskThreshold.value = maskThreshold;
|
|
4551
|
+
uniforms.uInvertMask.value = invertMask;
|
|
4552
|
+
uniforms.uClampOutput.value = clampOutput;
|
|
4553
|
+
uniforms.uTonemap.value = TONEMAP[tonemap];
|
|
4554
|
+
uniforms.uHasMask.value = Boolean(maskTexture);
|
|
4555
|
+
return /* @__PURE__ */ jsx19(
|
|
4556
|
+
ShaderPass,
|
|
4557
|
+
{
|
|
4558
|
+
vertexShader: VERT,
|
|
4559
|
+
fragmentShader: FRAG,
|
|
4560
|
+
uniforms,
|
|
4561
|
+
target,
|
|
4562
|
+
clear,
|
|
4563
|
+
priority,
|
|
4564
|
+
blending: THREE15.NoBlending
|
|
4565
|
+
}
|
|
4566
|
+
);
|
|
4567
|
+
}
|
|
4568
|
+
|
|
4405
4569
|
// src/components/RenderPipeline.tsx
|
|
4406
|
-
import { Fragment, jsx as jsx20, jsxs } from "react/jsx-runtime";
|
|
4570
|
+
import { Fragment as Fragment2, jsx as jsx20, jsxs } from "react/jsx-runtime";
|
|
4407
4571
|
var DEFAULT_TARGET_OPTIONS = {
|
|
4408
4572
|
depthBuffer: false,
|
|
4409
4573
|
stencilBuffer: false
|
|
4410
4574
|
};
|
|
4411
4575
|
function RenderPipeline({
|
|
4412
4576
|
passes,
|
|
4577
|
+
combine,
|
|
4413
4578
|
preview = true,
|
|
4414
4579
|
previewProps
|
|
4415
4580
|
}) {
|
|
4416
4581
|
const sharedScene = useSceneContext();
|
|
4417
4582
|
const size = sharedScene?.size ?? { width: 1, height: 1 };
|
|
4583
|
+
const shouldCombine = Boolean(combine);
|
|
4418
4584
|
const targets = useMemo12(() => {
|
|
4419
4585
|
const entries = passes.map((_, index) => ({
|
|
4420
4586
|
key: `pass_${index}`,
|
|
4421
4587
|
target: new THREE16.WebGLRenderTarget(1, 1, DEFAULT_TARGET_OPTIONS)
|
|
4422
4588
|
}));
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4589
|
+
if (shouldCombine) {
|
|
4590
|
+
entries.push({
|
|
4591
|
+
key: "combine",
|
|
4592
|
+
target: new THREE16.WebGLRenderTarget(1, 1, DEFAULT_TARGET_OPTIONS)
|
|
4593
|
+
});
|
|
4594
|
+
}
|
|
4427
4595
|
return entries;
|
|
4428
|
-
}, [passes]);
|
|
4596
|
+
}, [passes, shouldCombine]);
|
|
4429
4597
|
useEffect14(() => {
|
|
4430
4598
|
if (size.width <= 1 || size.height <= 1) return;
|
|
4431
4599
|
targets.forEach(({ target }) => {
|
|
@@ -4443,7 +4611,9 @@ function RenderPipeline({
|
|
|
4443
4611
|
throw new Error("RenderPipeline requires at least 2 passes.");
|
|
4444
4612
|
}
|
|
4445
4613
|
const passTargets = targets.filter((entry) => entry.key.startsWith("pass_"));
|
|
4446
|
-
const combineTarget = targets.find(
|
|
4614
|
+
const combineTarget = targets.find(
|
|
4615
|
+
(entry) => entry.key === "combine"
|
|
4616
|
+
)?.target;
|
|
4447
4617
|
const firstEnabledIndex = passes.findIndex((pass) => pass.enabled !== false);
|
|
4448
4618
|
const secondEnabledIndex = passes.findIndex(
|
|
4449
4619
|
(pass, index) => index > firstEnabledIndex && pass.enabled !== false
|
|
@@ -4453,7 +4623,7 @@ function RenderPipeline({
|
|
|
4453
4623
|
if (!passes.length) return null;
|
|
4454
4624
|
const lastEnabledIndex = [...passes].map((pass, index) => ({ pass, index })).filter(({ pass }) => pass.enabled !== false).map(({ index }) => index).pop();
|
|
4455
4625
|
if (lastEnabledIndex === void 0) return null;
|
|
4456
|
-
if (lastEnabledIndex <= Math.max(firstEnabledIndex, secondEnabledIndex)) {
|
|
4626
|
+
if (shouldCombine && lastEnabledIndex <= Math.max(firstEnabledIndex, secondEnabledIndex)) {
|
|
4457
4627
|
return combineTarget ?? null;
|
|
4458
4628
|
}
|
|
4459
4629
|
return passOutputTarget(lastEnabledIndex);
|
|
@@ -4474,7 +4644,7 @@ function RenderPipeline({
|
|
|
4474
4644
|
},
|
|
4475
4645
|
`pass_${index}`
|
|
4476
4646
|
);
|
|
4477
|
-
if (!combineRendered && combineTarget && index === secondEnabledIndex) {
|
|
4647
|
+
if (shouldCombine && !combineRendered && combineTarget && index === secondEnabledIndex) {
|
|
4478
4648
|
const inputA = passOutputTarget(firstEnabledIndex)?.texture ?? inputTexture;
|
|
4479
4649
|
const inputB = passOutputTarget(secondEnabledIndex)?.texture ?? inputTexture;
|
|
4480
4650
|
combineRendered = true;
|
|
@@ -4484,18 +4654,19 @@ function RenderPipeline({
|
|
|
4484
4654
|
/* @__PURE__ */ jsx20(
|
|
4485
4655
|
CombineShaderPass,
|
|
4486
4656
|
{
|
|
4657
|
+
...combine,
|
|
4487
4658
|
inputA,
|
|
4488
4659
|
inputB,
|
|
4489
4660
|
target: combineTarget
|
|
4490
4661
|
}
|
|
4491
4662
|
)
|
|
4492
|
-
] });
|
|
4663
|
+
] }, `combine_${index}`);
|
|
4493
4664
|
}
|
|
4494
4665
|
previousOutput = target;
|
|
4495
4666
|
return element;
|
|
4496
4667
|
});
|
|
4497
4668
|
const outputTarget = getOutputTarget();
|
|
4498
|
-
return /* @__PURE__ */ jsxs(
|
|
4669
|
+
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
4499
4670
|
renderedPasses,
|
|
4500
4671
|
preview && outputTarget && /* @__PURE__ */ jsx20(
|
|
4501
4672
|
TargetPreview,
|
|
@@ -4567,20 +4738,23 @@ function useMouse({
|
|
|
4567
4738
|
const handleMouseLeave = () => {
|
|
4568
4739
|
mouse.set(center?.x ?? 0.5, center?.y ?? 0.5);
|
|
4569
4740
|
};
|
|
4570
|
-
const moveTarget = element ?? window;
|
|
4571
|
-
moveTarget.addEventListener("mousemove", handleMouseMove);
|
|
4572
|
-
moveTarget.addEventListener("mouseleave", handleMouseLeave);
|
|
4573
4741
|
if (element) {
|
|
4742
|
+
element.addEventListener("mousemove", handleMouseMove);
|
|
4743
|
+
element.addEventListener("mouseleave", handleMouseLeave);
|
|
4574
4744
|
element.addEventListener("mouseenter", updateRect);
|
|
4745
|
+
} else if (hasWindow) {
|
|
4746
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
4575
4747
|
}
|
|
4576
4748
|
if (hasWindow) {
|
|
4577
4749
|
window.addEventListener("resize", handleResize);
|
|
4578
4750
|
}
|
|
4579
4751
|
return () => {
|
|
4580
|
-
moveTarget.removeEventListener("mousemove", handleMouseMove);
|
|
4581
|
-
moveTarget.removeEventListener("mouseleave", handleMouseLeave);
|
|
4582
4752
|
if (element) {
|
|
4753
|
+
element.removeEventListener("mousemove", handleMouseMove);
|
|
4754
|
+
element.removeEventListener("mouseleave", handleMouseLeave);
|
|
4583
4755
|
element.removeEventListener("mouseenter", updateRect);
|
|
4756
|
+
} else if (hasWindow) {
|
|
4757
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
4584
4758
|
}
|
|
4585
4759
|
if (hasWindow) {
|
|
4586
4760
|
window.removeEventListener("resize", handleResize);
|
|
@@ -4753,13 +4927,14 @@ function NoiseWarpPass({
|
|
|
4753
4927
|
}
|
|
4754
4928
|
|
|
4755
4929
|
// src/components/DitherPulseRing.tsx
|
|
4756
|
-
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
4930
|
+
import { Fragment as Fragment3, jsx as jsx23, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
4757
4931
|
function DitherPulseRing({
|
|
4758
4932
|
spriteTextureSrc = DITHER_SPRITE_TEXTURE_SRC,
|
|
4759
4933
|
glyphDitherEnabled = true,
|
|
4760
4934
|
diffuseEnabled = false,
|
|
4761
4935
|
blurEnabled = false,
|
|
4762
4936
|
noiseWarpEnabled = false,
|
|
4937
|
+
combineMode,
|
|
4763
4938
|
noiseWarpRadius,
|
|
4764
4939
|
noiseWarpStrength,
|
|
4765
4940
|
diffuseRadius,
|
|
@@ -4796,6 +4971,7 @@ function DitherPulseRing({
|
|
|
4796
4971
|
diffuseEnabled,
|
|
4797
4972
|
blurEnabled,
|
|
4798
4973
|
noiseWarpEnabled,
|
|
4974
|
+
combineMode,
|
|
4799
4975
|
noiseWarpRadius,
|
|
4800
4976
|
noiseWarpStrength,
|
|
4801
4977
|
diffuseRadius,
|
|
@@ -4821,6 +4997,7 @@ function DitherPulseRingContent({
|
|
|
4821
4997
|
diffuseEnabled = false,
|
|
4822
4998
|
blurEnabled = false,
|
|
4823
4999
|
noiseWarpEnabled = false,
|
|
5000
|
+
combineMode,
|
|
4824
5001
|
noiseWarpRadius,
|
|
4825
5002
|
noiseWarpStrength,
|
|
4826
5003
|
diffuseRadius,
|
|
@@ -4836,6 +5013,22 @@ function DitherPulseRingContent({
|
|
|
4836
5013
|
ringPosition,
|
|
4837
5014
|
ringAlpha
|
|
4838
5015
|
}) {
|
|
5016
|
+
const normalizeHexColor = (hex) => {
|
|
5017
|
+
if (!hex) return null;
|
|
5018
|
+
const normalized = hex.replace("#", "");
|
|
5019
|
+
if (normalized.length !== 6) return null;
|
|
5020
|
+
const r = parseInt(normalized.slice(0, 2), 16) / 255;
|
|
5021
|
+
const g = parseInt(normalized.slice(2, 4), 16) / 255;
|
|
5022
|
+
const b = parseInt(normalized.slice(4, 6), 16) / 255;
|
|
5023
|
+
return [r, g, b];
|
|
5024
|
+
};
|
|
5025
|
+
const resolveColor = (color) => {
|
|
5026
|
+
if (!color) return null;
|
|
5027
|
+
if (typeof color === "string") {
|
|
5028
|
+
return normalizeHexColor(color);
|
|
5029
|
+
}
|
|
5030
|
+
return color;
|
|
5031
|
+
};
|
|
4839
5032
|
const glyphUniforms = {};
|
|
4840
5033
|
glyphUniforms.trackMouse = false;
|
|
4841
5034
|
const noiseUniforms = {};
|
|
@@ -4859,49 +5052,529 @@ function DitherPulseRingContent({
|
|
|
4859
5052
|
const borderUniforms = {};
|
|
4860
5053
|
if (borderThickness !== void 0) borderUniforms.thickness = borderThickness;
|
|
4861
5054
|
if (borderIntensity !== void 0) borderUniforms.intensity = borderIntensity;
|
|
4862
|
-
|
|
5055
|
+
const resolvedBorderColor = resolveColor(borderColor);
|
|
5056
|
+
if (resolvedBorderColor) borderUniforms.color = resolvedBorderColor;
|
|
4863
5057
|
if (borderDitherStrength !== void 0) {
|
|
4864
5058
|
borderUniforms.ditherStrength = borderDitherStrength;
|
|
4865
5059
|
}
|
|
4866
5060
|
if (borderTonemap !== void 0) borderUniforms.tonemap = borderTonemap;
|
|
4867
5061
|
if (borderAlpha !== void 0) borderUniforms.alpha = borderAlpha;
|
|
4868
5062
|
const ringUniforms = {};
|
|
4869
|
-
|
|
5063
|
+
const resolvedRingColor = resolveColor(ringColor);
|
|
5064
|
+
if (resolvedRingColor) ringUniforms.color = resolvedRingColor;
|
|
4870
5065
|
if (ringSpeed !== void 0) ringUniforms.speed = ringSpeed;
|
|
4871
5066
|
if (ringPosition) ringUniforms.position = ringPosition;
|
|
4872
5067
|
if (ringAlpha !== void 0) ringUniforms.alpha = ringAlpha;
|
|
4873
|
-
return /* @__PURE__ */
|
|
4874
|
-
|
|
5068
|
+
return /* @__PURE__ */ jsxs2(Fragment3, { children: [
|
|
5069
|
+
/* @__PURE__ */ jsx23(
|
|
5070
|
+
RenderPipeline,
|
|
5071
|
+
{
|
|
5072
|
+
passes: [
|
|
5073
|
+
{
|
|
5074
|
+
component: BorderBeamPass,
|
|
5075
|
+
props: { uniforms: borderUniforms }
|
|
5076
|
+
},
|
|
5077
|
+
{
|
|
5078
|
+
component: GlyphDitherPass,
|
|
5079
|
+
enabled: glyphDitherEnabled,
|
|
5080
|
+
props: { spriteTextureSrc, uniforms: glyphUniforms }
|
|
5081
|
+
}
|
|
5082
|
+
],
|
|
5083
|
+
combine: combineMode ? { mode: combineMode } : void 0
|
|
5084
|
+
}
|
|
5085
|
+
),
|
|
5086
|
+
/* @__PURE__ */ jsx23(
|
|
5087
|
+
RenderPipeline,
|
|
5088
|
+
{
|
|
5089
|
+
passes: [
|
|
5090
|
+
{
|
|
5091
|
+
component: BorderBeamPass,
|
|
5092
|
+
props: { uniforms: borderUniforms }
|
|
5093
|
+
},
|
|
5094
|
+
{
|
|
5095
|
+
component: ExpandingRingPass,
|
|
5096
|
+
props: { uniforms: ringUniforms }
|
|
5097
|
+
},
|
|
5098
|
+
{
|
|
5099
|
+
component: NoiseWarpPass,
|
|
5100
|
+
enabled: noiseWarpEnabled,
|
|
5101
|
+
props: { uniforms: noiseUniforms }
|
|
5102
|
+
},
|
|
5103
|
+
{
|
|
5104
|
+
component: GlyphDitherPass,
|
|
5105
|
+
enabled: glyphDitherEnabled,
|
|
5106
|
+
props: { spriteTextureSrc, uniforms: glyphUniforms }
|
|
5107
|
+
},
|
|
5108
|
+
{
|
|
5109
|
+
component: DiffusePass,
|
|
5110
|
+
enabled: diffuseEnabled,
|
|
5111
|
+
props: { uniforms: diffuseUniforms }
|
|
5112
|
+
},
|
|
5113
|
+
{
|
|
5114
|
+
component: BlurPass,
|
|
5115
|
+
enabled: blurEnabled,
|
|
5116
|
+
props: { uniforms: blurUniforms }
|
|
5117
|
+
}
|
|
5118
|
+
],
|
|
5119
|
+
combine: combineMode ? { mode: combineMode } : void 0
|
|
5120
|
+
}
|
|
5121
|
+
)
|
|
5122
|
+
] });
|
|
5123
|
+
}
|
|
5124
|
+
|
|
5125
|
+
// src/components/DitherStreamBeamCompositePass.tsx
|
|
5126
|
+
import { useMemo as useMemo16 } from "react";
|
|
5127
|
+
import * as THREE21 from "three";
|
|
5128
|
+
|
|
5129
|
+
// src/utils/createFallbackTexture.ts
|
|
5130
|
+
import * as THREE20 from "three";
|
|
5131
|
+
function createFallbackTexture() {
|
|
5132
|
+
const data = new Uint8Array([0, 0, 0, 255]);
|
|
5133
|
+
const texture = new THREE20.DataTexture(data, 1, 1, THREE20.RGBAFormat);
|
|
5134
|
+
texture.needsUpdate = true;
|
|
5135
|
+
texture.wrapS = THREE20.ClampToEdgeWrapping;
|
|
5136
|
+
texture.wrapT = THREE20.ClampToEdgeWrapping;
|
|
5137
|
+
texture.minFilter = THREE20.NearestFilter;
|
|
5138
|
+
texture.magFilter = THREE20.NearestFilter;
|
|
5139
|
+
return texture;
|
|
5140
|
+
}
|
|
5141
|
+
|
|
5142
|
+
// src/shaders/dither-godray-beam-composite/fragment.glsl
|
|
5143
|
+
var fragment_default15 = "precision highp float;\nprecision highp int;\n\nin vec2 vTextureCoord;\n\nuniform sampler2D uTexture;\nuniform float uTime;\nuniform vec2 uResolution;\nuniform float uBeamSpeed;\nuniform float uBeamDirection;\nuniform vec3 uBeamColor;\nuniform vec2 uBeamCenter;\nuniform float uBeamRadius;\nuniform float uBeamScale;\nuniform int uPathShape;\nuniform vec2 uPathPos;\nuniform float uPathAngle;\n\nout vec4 fragColor;\n\nconst float PI = 3.14159265;\nconst float TWO_PI = 6.28318531;\n\nuvec2 hash2d(uvec2 v) {\n v = v * 1664525u + 1013904223u;\n v.x += v.y * v.y * 1664525u + 1013904223u;\n v.y += v.x * v.x * 1664525u + 1013904223u;\n v ^= v >> 16u;\n v.x += v.y * v.y * 1664525u + 1013904223u;\n v.y += v.x * v.x * 1664525u + 1013904223u;\n return v;\n}\n\nfloat randomFibo(vec2 p) {\n uvec2 v = floatBitsToUint(p);\n v = hash2d(v);\n return float(v.x ^ v.y) / float(0xffffffffu);\n}\n\nfloat calculateAngle(vec2 p, vec2 c) {\n float a = atan(p.y - c.y, p.x - c.x);\n return a < 0.0 ? a + TWO_PI : a;\n}\n\nfloat angularDiff(float a, float b) {\n float d = abs(a - b);\n return d > PI ? TWO_PI - d : d;\n}\n\nfloat angularFade(float pointAngle, float peakAngle, float fadeAmount) {\n return 1.04 - smoothstep(0.0, fadeAmount, angularDiff(pointAngle, peakAngle));\n}\n\nfloat sdEquilateralTriangle(vec2 p) {\n const float k = 1.7320508;\n p.x = abs(p.x) - 1.0;\n p.y = p.y + 1.0 / k;\n if (p.x + k * p.y > 0.0) {\n p = vec2(p.x - k * p.y, -k * p.x - p.y) / 2.0;\n }\n p.x -= clamp(p.x, -2.0, 0.0);\n return -length(p) * sign(p.y);\n}\n\nvec3 dodge(vec3 src, vec3 dst) {\n return vec3(\n src.x >= 1.0 ? 1.0 : min(1.0, dst.x / max(0.001, 1.0 - src.x)),\n src.y >= 1.0 ? 1.0 : min(1.0, dst.y / max(0.001, 1.0 - src.y)),\n src.z >= 1.0 ? 1.0 : min(1.0, dst.z / max(0.001, 1.0 - src.z))\n );\n}\n\nfloat easeExpoIn(float t) {\n return t <= 0.0 ? 0.0 : pow(2.0, 10.0 * (t - 1.0));\n}\n\nvec2 rot2(vec2 v, float a) {\n float c = cos(a);\n float s = sin(a);\n return vec2(v.x * c - v.y * s, v.x * s + v.y * c);\n}\n\nvec3 beamAt(vec2 uv) {\n float aspect = uResolution.x / uResolution.y;\n vec2 center = uBeamCenter;\n\n vec2 u2 = vec2(uv.x * aspect, uv.y);\n vec2 c2 = vec2(center.x * aspect, center.y);\n\n float ringRadius = uBeamRadius;\n vec2 delta = (u2 - c2) / max(uBeamScale, 0.0001);\n float circleDist = abs(length(delta) - ringRadius);\n float squareDist = abs(max(abs(delta.x), abs(delta.y)) - ringRadius);\n float diamondDist = abs(abs(delta.x) + abs(delta.y) - ringRadius);\n float ovalDist =\n abs(length(vec2(delta.x / 1.5, delta.y)) - ringRadius);\n float triangleDist =\n abs(sdEquilateralTriangle(delta / max(ringRadius, 0.0001))) * ringRadius;\n\n float ringDist = circleDist;\n if (uPathShape == 1) {\n ringDist = squareDist;\n } else if (uPathShape == 2) {\n ringDist = diamondDist;\n } else if (uPathShape == 3) {\n ringDist = triangleDist;\n } else if (uPathShape == 4) {\n ringDist = ovalDist;\n }\n\n float b = 0.25 / (1.0 - smoothstep(0.2, 0.002, ringDist + 0.02));\n float ang = fract(0.19 + uTime * uBeamSpeed * uBeamDirection) * TWO_PI;\n b *= angularFade(calculateAngle(u2, c2), ang, PI * 0.5);\n\n vec3 col = b * pow(max(0.0, 1.0 - ringDist), 3.0) * uBeamColor;\n col = tanh(clamp(col, -40.0, 40.0));\n col += (randomFibo(gl_FragCoord.xy) - 0.5) / 255.0;\n\n return col;\n}\n\nvoid main() {\n vec2 uv = vTextureCoord;\n\n float ang = uPathAngle;\n vec2 pos = uPathPos;\n vec2 off = uv - pos;\n vec2 ro = rot2(off, -ang);\n vec2 so = ro;\n\n if (ro.x > 0.0) {\n float e = easeExpoIn(ro.x);\n so.y = ro.y / (1.0 + 4.0 * e * e);\n }\n\n vec2 st = clamp(pos + rot2(so, ang), 0.0, 1.0);\n\n vec3 beam = beamAt(st);\n vec4 img = texture(uTexture, st);\n vec3 outColor = mix(beam, dodge(img.rgb, beam), img.a);\n\n fragColor = vec4(outColor, 1.0);\n}\n";
|
|
5144
|
+
|
|
5145
|
+
// src/shaders/dither-godray-beam-composite/vertex.glsl
|
|
5146
|
+
var vertex_default14 = "out vec2 vTextureCoord;\n\nvoid main() {\n vTextureCoord = uv;\n gl_Position = vec4(position, 1.0);\n}\n";
|
|
5147
|
+
|
|
5148
|
+
// src/components/DitherStreamBeamCompositePass.tsx
|
|
5149
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
5150
|
+
function DitherStreamBeamCompositePass({
|
|
5151
|
+
inputTexture = null,
|
|
5152
|
+
beamSpeed = 0.1,
|
|
5153
|
+
beamDirection = "counterclockwise",
|
|
5154
|
+
beamColor = [0.667, 0.686, 0.941],
|
|
5155
|
+
beamCenter = [0.5, 0.95],
|
|
5156
|
+
beamRadius = 0.6,
|
|
5157
|
+
beamScale = 1,
|
|
5158
|
+
pathShape = "circle",
|
|
5159
|
+
pathPos = [0.5009, 1.0473],
|
|
5160
|
+
pathAngle = (0.999 - 0.25) * -6.28318531,
|
|
5161
|
+
target = null,
|
|
5162
|
+
clear = true,
|
|
5163
|
+
enabled = true,
|
|
5164
|
+
priority = 0
|
|
5165
|
+
}) {
|
|
5166
|
+
const fallbackTexture = useMemo16(() => createFallbackTexture(), []);
|
|
5167
|
+
const uniforms = useMemo16(
|
|
5168
|
+
() => ({
|
|
5169
|
+
uTexture: { value: inputTexture ?? fallbackTexture },
|
|
5170
|
+
uTime: { value: 0 },
|
|
5171
|
+
uResolution: { value: new THREE21.Vector2(1, 1) },
|
|
5172
|
+
uBeamSpeed: { value: beamSpeed },
|
|
5173
|
+
uBeamDirection: { value: beamDirection === "clockwise" ? -1 : 1 },
|
|
5174
|
+
uBeamColor: {
|
|
5175
|
+
value: new THREE21.Color(beamColor[0], beamColor[1], beamColor[2])
|
|
5176
|
+
},
|
|
5177
|
+
uBeamCenter: { value: new THREE21.Vector2(beamCenter[0], beamCenter[1]) },
|
|
5178
|
+
uBeamRadius: { value: beamRadius },
|
|
5179
|
+
uBeamScale: { value: beamScale },
|
|
5180
|
+
uPathShape: {
|
|
5181
|
+
value: pathShape === "square" ? 1 : pathShape === "diamond" ? 2 : pathShape === "triangle" ? 3 : pathShape === "oval" ? 4 : 0
|
|
5182
|
+
},
|
|
5183
|
+
uPathPos: { value: new THREE21.Vector2(pathPos[0], pathPos[1]) },
|
|
5184
|
+
uPathAngle: { value: pathAngle }
|
|
5185
|
+
}),
|
|
5186
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5187
|
+
[]
|
|
5188
|
+
);
|
|
5189
|
+
uniforms.uTexture.value = inputTexture ?? fallbackTexture;
|
|
5190
|
+
uniforms.uBeamSpeed.value = beamSpeed;
|
|
5191
|
+
uniforms.uBeamDirection.value = beamDirection === "clockwise" ? -1 : 1;
|
|
5192
|
+
uniforms.uBeamColor.value.setRGB(
|
|
5193
|
+
beamColor[0],
|
|
5194
|
+
beamColor[1],
|
|
5195
|
+
beamColor[2]
|
|
5196
|
+
);
|
|
5197
|
+
uniforms.uBeamCenter.value.set(
|
|
5198
|
+
beamCenter[0],
|
|
5199
|
+
beamCenter[1]
|
|
5200
|
+
);
|
|
5201
|
+
uniforms.uBeamRadius.value = beamRadius;
|
|
5202
|
+
uniforms.uBeamScale.value = beamScale;
|
|
5203
|
+
uniforms.uPathShape.value = pathShape === "square" ? 1 : pathShape === "diamond" ? 2 : pathShape === "triangle" ? 3 : pathShape === "oval" ? 4 : 0;
|
|
5204
|
+
uniforms.uPathPos.value.set(pathPos[0], pathPos[1]);
|
|
5205
|
+
uniforms.uPathAngle.value = pathAngle;
|
|
5206
|
+
return /* @__PURE__ */ jsx24(
|
|
5207
|
+
ShaderPass,
|
|
4875
5208
|
{
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
5209
|
+
vertexShader: vertex_default14,
|
|
5210
|
+
fragmentShader: fragment_default15,
|
|
5211
|
+
uniforms,
|
|
5212
|
+
inputTexture: inputTexture ?? fallbackTexture,
|
|
5213
|
+
target,
|
|
5214
|
+
clear,
|
|
5215
|
+
enabled,
|
|
5216
|
+
priority,
|
|
5217
|
+
timeUniform: "uTime",
|
|
5218
|
+
resolutionUniform: "uResolution",
|
|
5219
|
+
blending: THREE21.NoBlending
|
|
5220
|
+
}
|
|
5221
|
+
);
|
|
5222
|
+
}
|
|
5223
|
+
|
|
5224
|
+
// src/components/DitherStreamDitherPass.tsx
|
|
5225
|
+
import { useMemo as useMemo17 } from "react";
|
|
5226
|
+
import * as THREE22 from "three";
|
|
5227
|
+
|
|
5228
|
+
// src/shaders/dither-godray-dither/fragment.glsl
|
|
5229
|
+
var fragment_default16 = "precision highp float;\n\nin vec2 vTextureCoord;\n\nuniform sampler2D uTexture;\nuniform vec2 uResolution;\n\nout vec4 fragColor;\n\nvoid main() {\n vec2 uv = vTextureCoord;\n\n float ar = uResolution.x / uResolution.y;\n float ac = mix(ar, 1.0 / ar, 0.5);\n\n float gs = 0.005;\n float bg = 1.0 / gs;\n vec2 cellSize = vec2(1.0 / (bg * ar), 1.0 / bg) * ac;\n\n vec2 pos = vec2(0.5);\n vec2 off = uv - pos;\n vec2 cell = floor(off / cellSize);\n vec2 center = (cell + 0.5) * cellSize;\n vec2 pixelUv = center + pos;\n\n vec4 c = texture(uTexture, pixelUv);\n float lum = dot(c.rgb, vec3(0.2126, 0.7152, 0.0722));\n float gm = pow(mix(0.2, 2.2, 0.3), 2.2);\n\n vec2 local = mod(uv - pos, cellSize) / cellSize;\n vec2 ct = local * 2.0 - 1.0;\n float d = length(ct);\n\n float ns = 16.0;\n float si = clamp(floor(lum * ns * gm), 0.0, ns - 1.0);\n float rad = si / ns;\n float alpha = smoothstep(rad + 0.08, rad - 0.08, d);\n\n vec3 tint = (c.rgb - si * 0.04) * 1.4;\n fragColor = vec4(mix(vec3(0.0), tint, alpha), 1.0);\n}\n";
|
|
5230
|
+
|
|
5231
|
+
// src/shaders/dither-godray-dither/vertex.glsl
|
|
5232
|
+
var vertex_default15 = "out vec2 vTextureCoord;\n\nvoid main() {\n vTextureCoord = uv;\n gl_Position = vec4(position, 1.0);\n}\n";
|
|
5233
|
+
|
|
5234
|
+
// src/components/DitherStreamDitherPass.tsx
|
|
5235
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
5236
|
+
function DitherStreamDitherPass({
|
|
5237
|
+
inputTexture = null,
|
|
5238
|
+
target = null,
|
|
5239
|
+
clear = true,
|
|
5240
|
+
enabled = true,
|
|
5241
|
+
priority = 0
|
|
5242
|
+
}) {
|
|
5243
|
+
const fallbackTexture = useMemo17(() => createFallbackTexture(), []);
|
|
5244
|
+
const uniforms = useMemo17(
|
|
5245
|
+
() => ({
|
|
5246
|
+
uTexture: { value: inputTexture ?? fallbackTexture },
|
|
5247
|
+
uResolution: { value: new THREE22.Vector2(1, 1) }
|
|
5248
|
+
}),
|
|
5249
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5250
|
+
[]
|
|
5251
|
+
);
|
|
5252
|
+
uniforms.uTexture.value = inputTexture ?? fallbackTexture;
|
|
5253
|
+
return /* @__PURE__ */ jsx25(
|
|
5254
|
+
ShaderPass,
|
|
5255
|
+
{
|
|
5256
|
+
vertexShader: vertex_default15,
|
|
5257
|
+
fragmentShader: fragment_default16,
|
|
5258
|
+
uniforms,
|
|
5259
|
+
inputTexture: inputTexture ?? fallbackTexture,
|
|
5260
|
+
target,
|
|
5261
|
+
clear,
|
|
5262
|
+
enabled,
|
|
5263
|
+
priority,
|
|
5264
|
+
resolutionUniform: "uResolution",
|
|
5265
|
+
blending: THREE22.NoBlending
|
|
5266
|
+
}
|
|
5267
|
+
);
|
|
5268
|
+
}
|
|
5269
|
+
|
|
5270
|
+
// src/components/DitherStreamGodRaysPass.tsx
|
|
5271
|
+
import { useEffect as useEffect17, useMemo as useMemo18 } from "react";
|
|
5272
|
+
import * as THREE23 from "three";
|
|
5273
|
+
|
|
5274
|
+
// src/shaders/dither-godray-extract/fragment.glsl
|
|
5275
|
+
var fragment_default17 = "precision highp float;\n\nin vec2 vTextureCoord;\nuniform sampler2D uTexture;\nout vec4 fragColor;\n\nvoid main() {\n vec4 c = texture(uTexture, vTextureCoord);\n float l = dot(c.rgb, vec3(0.299, 0.587, 0.114));\n fragColor = c * smoothstep(-0.1, 0.0, l);\n}\n";
|
|
5276
|
+
|
|
5277
|
+
// src/shaders/dither-godray-extract/vertex.glsl
|
|
5278
|
+
var vertex_default16 = "out vec2 vTextureCoord;\n\nvoid main() {\n vTextureCoord = uv;\n gl_Position = vec4(position, 1.0);\n}\n";
|
|
5279
|
+
|
|
5280
|
+
// src/shaders/dither-godray-final/fragment.glsl
|
|
5281
|
+
var fragment_default18 = "precision highp float;\n\nin vec2 vTextureCoord;\nuniform sampler2D uScene;\nuniform sampler2D uGR;\nuniform float uGodrayIntensity;\nout vec4 fragColor;\n\nvoid main() {\n vec3 bg = texture(uScene, vTextureCoord).rgb;\n vec3 gr = texture(uGR, vTextureCoord).rgb;\n fragColor = vec4(bg + gr * uGodrayIntensity, 1.0);\n}\n";
|
|
5282
|
+
|
|
5283
|
+
// src/shaders/dither-godray-final/vertex.glsl
|
|
5284
|
+
var vertex_default17 = "out vec2 vTextureCoord;\n\nvoid main() {\n vTextureCoord = uv;\n gl_Position = vec4(position, 1.0);\n}\n";
|
|
5285
|
+
|
|
5286
|
+
// src/shaders/dither-godray-march/fragment.glsl
|
|
5287
|
+
var fragment_default19 = "precision highp float;\n\nin vec2 vTextureCoord;\nuniform sampler2D uTexture;\nout vec4 fragColor;\n\nvoid main() {\n vec3 col = vec3(0.0);\n vec2 pos = vec2(0.5);\n vec2 dir = (pos - vTextureCoord) * 0.02;\n float w = 1.0;\n vec2 tc = vTextureCoord;\n\n for (int i = 0; i < 16; i++) {\n col += texture(uTexture, tc).rgb * w;\n w *= 0.94;\n tc += dir;\n }\n\n fragColor = vec4(col / 16.0, length(tc - vTextureCoord));\n}\n";
|
|
5288
|
+
|
|
5289
|
+
// src/shaders/dither-godray-march/vertex.glsl
|
|
5290
|
+
var vertex_default18 = "out vec2 vTextureCoord;\n\nvoid main() {\n vTextureCoord = uv;\n gl_Position = vec4(position, 1.0);\n}\n";
|
|
5291
|
+
|
|
5292
|
+
// src/components/DitherStreamGodRaysPass.tsx
|
|
5293
|
+
import { Fragment as Fragment4, jsx as jsx26, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
5294
|
+
var TARGET_OPTIONS = {
|
|
5295
|
+
depthBuffer: false,
|
|
5296
|
+
stencilBuffer: false
|
|
5297
|
+
};
|
|
5298
|
+
function DitherStreamGodRaysPass({
|
|
5299
|
+
inputTexture = null,
|
|
5300
|
+
intensity = 2.9,
|
|
5301
|
+
target = null,
|
|
5302
|
+
enabled = true,
|
|
5303
|
+
priority = 0
|
|
5304
|
+
}) {
|
|
5305
|
+
const sharedScene = useSceneContext();
|
|
5306
|
+
const size = sharedScene?.size ?? { width: 1, height: 1 };
|
|
5307
|
+
const fallbackTexture = useMemo18(() => createFallbackTexture(), []);
|
|
5308
|
+
const extractTarget = useMemo18(
|
|
5309
|
+
() => new THREE23.WebGLRenderTarget(1, 1, TARGET_OPTIONS),
|
|
5310
|
+
[]
|
|
5311
|
+
);
|
|
5312
|
+
const marchTarget = useMemo18(
|
|
5313
|
+
() => new THREE23.WebGLRenderTarget(1, 1, TARGET_OPTIONS),
|
|
5314
|
+
[]
|
|
5315
|
+
);
|
|
5316
|
+
useEffect17(() => {
|
|
5317
|
+
return () => {
|
|
5318
|
+
extractTarget.dispose();
|
|
5319
|
+
marchTarget.dispose();
|
|
5320
|
+
};
|
|
5321
|
+
}, [extractTarget, marchTarget]);
|
|
5322
|
+
useEffect17(() => {
|
|
5323
|
+
if (size.width <= 1 || size.height <= 1) return;
|
|
5324
|
+
extractTarget.setSize(size.width, size.height);
|
|
5325
|
+
marchTarget.setSize(
|
|
5326
|
+
Math.max(1, Math.floor(size.width / 4)),
|
|
5327
|
+
Math.max(1, Math.floor(size.height / 4))
|
|
5328
|
+
);
|
|
5329
|
+
}, [extractTarget, marchTarget, size.height, size.width]);
|
|
5330
|
+
const extractUniforms = useMemo18(
|
|
5331
|
+
() => ({
|
|
5332
|
+
uTexture: { value: inputTexture ?? fallbackTexture }
|
|
5333
|
+
}),
|
|
5334
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5335
|
+
[]
|
|
5336
|
+
);
|
|
5337
|
+
const marchUniforms = useMemo18(
|
|
5338
|
+
() => ({
|
|
5339
|
+
uTexture: { value: extractTarget.texture }
|
|
5340
|
+
}),
|
|
5341
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5342
|
+
[]
|
|
5343
|
+
);
|
|
5344
|
+
const finalUniforms = useMemo18(
|
|
5345
|
+
() => ({
|
|
5346
|
+
uScene: { value: inputTexture ?? fallbackTexture },
|
|
5347
|
+
uGR: { value: marchTarget.texture },
|
|
5348
|
+
uGodrayIntensity: { value: intensity }
|
|
5349
|
+
}),
|
|
5350
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5351
|
+
[]
|
|
5352
|
+
);
|
|
5353
|
+
extractUniforms.uTexture.value = inputTexture ?? fallbackTexture;
|
|
5354
|
+
marchUniforms.uTexture.value = extractTarget.texture;
|
|
5355
|
+
finalUniforms.uScene.value = inputTexture ?? fallbackTexture;
|
|
5356
|
+
finalUniforms.uGR.value = marchTarget.texture;
|
|
5357
|
+
finalUniforms.uGodrayIntensity.value = intensity;
|
|
5358
|
+
return /* @__PURE__ */ jsxs3(Fragment4, { children: [
|
|
5359
|
+
/* @__PURE__ */ jsx26(
|
|
5360
|
+
ShaderPass,
|
|
5361
|
+
{
|
|
5362
|
+
vertexShader: vertex_default16,
|
|
5363
|
+
fragmentShader: fragment_default17,
|
|
5364
|
+
uniforms: extractUniforms,
|
|
5365
|
+
inputTexture: inputTexture ?? fallbackTexture,
|
|
5366
|
+
target: extractTarget,
|
|
5367
|
+
clear: true,
|
|
5368
|
+
enabled,
|
|
5369
|
+
priority,
|
|
5370
|
+
blending: THREE23.NoBlending
|
|
5371
|
+
}
|
|
5372
|
+
),
|
|
5373
|
+
/* @__PURE__ */ jsx26(
|
|
5374
|
+
ShaderPass,
|
|
5375
|
+
{
|
|
5376
|
+
vertexShader: vertex_default18,
|
|
5377
|
+
fragmentShader: fragment_default19,
|
|
5378
|
+
uniforms: marchUniforms,
|
|
5379
|
+
inputTexture: extractTarget.texture,
|
|
5380
|
+
target: marchTarget,
|
|
5381
|
+
clear: true,
|
|
5382
|
+
enabled,
|
|
5383
|
+
priority: priority + 1,
|
|
5384
|
+
blending: THREE23.NoBlending
|
|
5385
|
+
}
|
|
5386
|
+
),
|
|
5387
|
+
/* @__PURE__ */ jsx26(
|
|
5388
|
+
ShaderPass,
|
|
5389
|
+
{
|
|
5390
|
+
vertexShader: vertex_default17,
|
|
5391
|
+
fragmentShader: fragment_default18,
|
|
5392
|
+
uniforms: finalUniforms,
|
|
5393
|
+
inputTexture: inputTexture ?? fallbackTexture,
|
|
5394
|
+
target,
|
|
5395
|
+
clear: true,
|
|
5396
|
+
enabled,
|
|
5397
|
+
priority: priority + 2,
|
|
5398
|
+
blending: THREE23.NoBlending
|
|
5399
|
+
}
|
|
5400
|
+
)
|
|
5401
|
+
] });
|
|
5402
|
+
}
|
|
5403
|
+
|
|
5404
|
+
// src/components/DitherStreamProjectionPass.tsx
|
|
5405
|
+
import { useEffect as useEffect18, useMemo as useMemo19, useState as useState4 } from "react";
|
|
5406
|
+
import * as THREE24 from "three";
|
|
5407
|
+
|
|
5408
|
+
// src/shaders/dither-godray-projection/fragment.glsl
|
|
5409
|
+
var fragment_default20 = "precision highp float;\n\nin vec2 vTextureCoord;\n\nuniform sampler2D uTex;\nuniform float uTime;\nuniform float uProjectionSpeed;\n\nout vec4 fragColor;\n\nconst float PI = 3.14159265;\n\nvec3 ray(vec2 uv, vec2 m, float a) {\n vec2 s = (uv - 0.5) * 2.0;\n s.x *= a;\n s.y *= -1.0;\n\n float f = mix(radians(20.0), radians(120.0), 0.38);\n vec3 r = normalize(vec3(s * tan(f / 2.0), -1.0));\n\n float rx = (m.y - 0.5) * PI;\n float ry = (m.x - 0.5) * PI * 2.0;\n mat3 rY = mat3(cos(ry), 0.0, -sin(ry), 0.0, 1.0, 0.0, sin(ry), 0.0, cos(ry));\n mat3 rX = mat3(1.0, 0.0, 0.0, 0.0, cos(rx), sin(rx), 0.0, -sin(rx), cos(rx));\n\n return normalize(rX * rY * r);\n}\n\nvec2 directionToUv(vec3 d) {\n return vec2(atan(d.z, d.x) / (2.0 * PI) + 0.75, acos(clamp(d.y, -1.0, 1.0)) / PI);\n}\n\nvec4 sampleRepeat(vec2 uv) {\n vec2 f = vec2(uv.x, fract(uv.y));\n vec4 c = texture(uTex, f);\n\n float blendWidth = 0.1;\n float blendFactor = 0.0;\n if (f.y < blendWidth) {\n blendFactor = 1.0 - f.y / blendWidth;\n } else if (f.y > 1.0 - blendWidth) {\n blendFactor = (f.y - (1.0 - blendWidth)) / blendWidth;\n }\n\n if (blendFactor > 0.0) {\n blendFactor = smoothstep(0.0, 1.0, blendFactor);\n vec2 opposite = vec2(f.x, f.y > 0.5 ? f.y - 0.5 : f.y + 0.5);\n c = mix(c, texture(uTex, opposite), blendFactor);\n }\n\n return c;\n}\n\nvoid main() {\n vec2 uv = vTextureCoord;\n\n vec3 rd = ray(uv, vec2(0.5, 0.5056), 2.0);\n vec2 s = directionToUv(rd);\n\n float f = mix(radians(20.0), radians(120.0), 0.38);\n s = (s - 0.5) * (2.0 / tan(f / 2.0)) + 0.5;\n s += vec2(0.0, 0.02) * uTime * uProjectionSpeed;\n\n vec4 c = sampleRepeat(s);\n c.rgb = clamp(c.rgb - 0.14, 0.0, 1.0);\n\n float l = dot(c.rgb, vec3(0.299, 0.587, 0.114));\n c.rgb = mix(vec3(l), c.rgb, 0.79);\n c.rgb = 1.22 * (c.rgb - 0.5) + 0.5;\n c.rgb = clamp(c.rgb, 0.0, 1.0);\n\n fragColor = c;\n}\n";
|
|
5410
|
+
|
|
5411
|
+
// src/shaders/dither-godray-projection/vertex.glsl
|
|
5412
|
+
var vertex_default19 = "out vec2 vTextureCoord;\n\nvoid main() {\n vTextureCoord = uv;\n gl_Position = vec4(position, 1.0);\n}\n";
|
|
5413
|
+
|
|
5414
|
+
// src/components/DitherStreamProjectionPass.tsx
|
|
5415
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
5416
|
+
var DEFAULT_IMAGE_SRC = "https://firebasestorage.googleapis.com/v0/b/unicorn-studio.appspot.com/o/Zz28X5RDkvcGGVYLr9X6QdTIhxy1%2FUntitled%20design%20-%202025-10-14T141250.707.webp?alt=media&token=bfcd11a8-6529-41a6-a592-d78147e93840";
|
|
5417
|
+
function DitherStreamProjectionPass({
|
|
5418
|
+
imageTextureSrc = DEFAULT_IMAGE_SRC,
|
|
5419
|
+
projectionSpeed = 0.05,
|
|
5420
|
+
target = null,
|
|
5421
|
+
clear = true,
|
|
5422
|
+
enabled = true,
|
|
5423
|
+
priority = 0
|
|
5424
|
+
}) {
|
|
5425
|
+
const [imageTexture, setImageTexture] = useState4(null);
|
|
5426
|
+
const fallbackTexture = useMemo19(() => createFallbackTexture(), []);
|
|
5427
|
+
useEffect18(() => {
|
|
5428
|
+
let active = true;
|
|
5429
|
+
const loader = new THREE24.TextureLoader();
|
|
5430
|
+
loader.load(
|
|
5431
|
+
imageTextureSrc,
|
|
5432
|
+
(texture) => {
|
|
5433
|
+
if (!active) {
|
|
5434
|
+
texture.dispose();
|
|
5435
|
+
return;
|
|
4904
5436
|
}
|
|
5437
|
+
texture.wrapS = THREE24.RepeatWrapping;
|
|
5438
|
+
texture.wrapT = THREE24.RepeatWrapping;
|
|
5439
|
+
texture.minFilter = THREE24.LinearFilter;
|
|
5440
|
+
texture.magFilter = THREE24.LinearFilter;
|
|
5441
|
+
texture.generateMipmaps = true;
|
|
5442
|
+
texture.colorSpace = THREE24.NoColorSpace;
|
|
5443
|
+
texture.needsUpdate = true;
|
|
5444
|
+
setImageTexture(texture);
|
|
5445
|
+
},
|
|
5446
|
+
void 0,
|
|
5447
|
+
() => {
|
|
5448
|
+
if (!active) return;
|
|
5449
|
+
setImageTexture(fallbackTexture);
|
|
5450
|
+
}
|
|
5451
|
+
);
|
|
5452
|
+
return () => {
|
|
5453
|
+
active = false;
|
|
5454
|
+
};
|
|
5455
|
+
}, [fallbackTexture, imageTextureSrc]);
|
|
5456
|
+
const uniforms = useMemo19(
|
|
5457
|
+
() => ({
|
|
5458
|
+
uTex: { value: imageTexture ?? fallbackTexture },
|
|
5459
|
+
uTime: { value: 0 },
|
|
5460
|
+
uProjectionSpeed: { value: projectionSpeed }
|
|
5461
|
+
}),
|
|
5462
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5463
|
+
[]
|
|
5464
|
+
);
|
|
5465
|
+
uniforms.uTex.value = imageTexture ?? fallbackTexture;
|
|
5466
|
+
uniforms.uProjectionSpeed.value = projectionSpeed;
|
|
5467
|
+
return /* @__PURE__ */ jsx27(
|
|
5468
|
+
ShaderPass,
|
|
5469
|
+
{
|
|
5470
|
+
vertexShader: vertex_default19,
|
|
5471
|
+
fragmentShader: fragment_default20,
|
|
5472
|
+
uniforms,
|
|
5473
|
+
target,
|
|
5474
|
+
clear,
|
|
5475
|
+
enabled,
|
|
5476
|
+
priority,
|
|
5477
|
+
timeUniform: "uTime",
|
|
5478
|
+
blending: THREE24.NoBlending
|
|
5479
|
+
}
|
|
5480
|
+
);
|
|
5481
|
+
}
|
|
5482
|
+
|
|
5483
|
+
// src/components/DitherStreamRendererConfig.tsx
|
|
5484
|
+
import { useEffect as useEffect19 } from "react";
|
|
5485
|
+
import * as THREE25 from "three";
|
|
5486
|
+
function DitherStreamRendererConfig() {
|
|
5487
|
+
const sharedScene = useSceneContext();
|
|
5488
|
+
useEffect19(() => {
|
|
5489
|
+
const context = sharedScene?.contextRef.current;
|
|
5490
|
+
if (!context) return;
|
|
5491
|
+
const renderer = context.renderer;
|
|
5492
|
+
const prevOutputColorSpace = renderer.outputColorSpace;
|
|
5493
|
+
const prevToneMapping = renderer.toneMapping;
|
|
5494
|
+
renderer.outputColorSpace = THREE25.LinearSRGBColorSpace;
|
|
5495
|
+
renderer.toneMapping = THREE25.NoToneMapping;
|
|
5496
|
+
return () => {
|
|
5497
|
+
renderer.outputColorSpace = prevOutputColorSpace;
|
|
5498
|
+
renderer.toneMapping = prevToneMapping;
|
|
5499
|
+
};
|
|
5500
|
+
}, [sharedScene]);
|
|
5501
|
+
return null;
|
|
5502
|
+
}
|
|
5503
|
+
|
|
5504
|
+
// src/components/DitherStream.tsx
|
|
5505
|
+
import { jsx as jsx28, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
5506
|
+
function DitherStream({
|
|
5507
|
+
width = "100%",
|
|
5508
|
+
height = "100%",
|
|
5509
|
+
className = "relative h-full w-full",
|
|
5510
|
+
style,
|
|
5511
|
+
imageTextureSrc,
|
|
5512
|
+
projectionSpeed = 0.05,
|
|
5513
|
+
beamSpeed = 0.1,
|
|
5514
|
+
beamDirection = "counterclockwise",
|
|
5515
|
+
beamColor = [0.667, 0.686, 0.941],
|
|
5516
|
+
beamCenter = [0.5, 0.95],
|
|
5517
|
+
beamRadius = 0.6,
|
|
5518
|
+
beamScale = 1,
|
|
5519
|
+
beamPathShape = "circle",
|
|
5520
|
+
pathPos = [0.5009, 1.0473],
|
|
5521
|
+
pathAngle = (0.999 - 0.25) * -6.28318531,
|
|
5522
|
+
godrayIntensity = 2.9
|
|
5523
|
+
}) {
|
|
5524
|
+
const resolveColor = (color) => {
|
|
5525
|
+
if (Array.isArray(color)) return color;
|
|
5526
|
+
const normalized = color.replace("#", "");
|
|
5527
|
+
if (normalized.length !== 6)
|
|
5528
|
+
return [0.667, 0.686, 0.941];
|
|
5529
|
+
return [
|
|
5530
|
+
parseInt(normalized.slice(0, 2), 16) / 255,
|
|
5531
|
+
parseInt(normalized.slice(2, 4), 16) / 255,
|
|
5532
|
+
parseInt(normalized.slice(4, 6), 16) / 255
|
|
5533
|
+
];
|
|
5534
|
+
};
|
|
5535
|
+
const resolvedBeamColor = resolveColor(beamColor);
|
|
5536
|
+
return /* @__PURE__ */ jsxs4(
|
|
5537
|
+
SceneProvider,
|
|
5538
|
+
{
|
|
5539
|
+
width,
|
|
5540
|
+
height,
|
|
5541
|
+
className,
|
|
5542
|
+
style,
|
|
5543
|
+
manualRender: true,
|
|
5544
|
+
children: [
|
|
5545
|
+
/* @__PURE__ */ jsx28(DitherStreamRendererConfig, {}),
|
|
5546
|
+
/* @__PURE__ */ jsx28(
|
|
5547
|
+
RenderPipeline,
|
|
5548
|
+
{
|
|
5549
|
+
passes: [
|
|
5550
|
+
{
|
|
5551
|
+
component: DitherStreamProjectionPass,
|
|
5552
|
+
props: { imageTextureSrc, projectionSpeed }
|
|
5553
|
+
},
|
|
5554
|
+
{
|
|
5555
|
+
component: DitherStreamBeamCompositePass,
|
|
5556
|
+
props: {
|
|
5557
|
+
beamSpeed,
|
|
5558
|
+
beamDirection,
|
|
5559
|
+
beamColor: resolvedBeamColor,
|
|
5560
|
+
beamCenter,
|
|
5561
|
+
beamRadius,
|
|
5562
|
+
beamScale,
|
|
5563
|
+
pathShape: beamPathShape,
|
|
5564
|
+
pathPos,
|
|
5565
|
+
pathAngle
|
|
5566
|
+
}
|
|
5567
|
+
},
|
|
5568
|
+
{
|
|
5569
|
+
component: DitherStreamDitherPass
|
|
5570
|
+
},
|
|
5571
|
+
{
|
|
5572
|
+
component: DitherStreamGodRaysPass,
|
|
5573
|
+
props: { intensity: godrayIntensity }
|
|
5574
|
+
}
|
|
5575
|
+
]
|
|
5576
|
+
}
|
|
5577
|
+
)
|
|
4905
5578
|
]
|
|
4906
5579
|
}
|
|
4907
5580
|
);
|
|
@@ -4909,6 +5582,7 @@ function DitherPulseRingContent({
|
|
|
4909
5582
|
export {
|
|
4910
5583
|
AnimatedDrawingSVG,
|
|
4911
5584
|
DitherPulseRing,
|
|
5585
|
+
DitherStream,
|
|
4912
5586
|
EFECTO_ASCII_COMPONENT_DEFAULTS,
|
|
4913
5587
|
EFECTO_ASCII_POST_PROCESSING_DEFAULTS,
|
|
4914
5588
|
Efecto,
|