@toriistudio/shader-ui 0.0.8 → 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 +23 -3
- package/dist/index.d.ts +23 -3
- package/dist/index.js +478 -12
- package/dist/index.mjs +477 -12
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -278,7 +278,7 @@ type NoiseWarpPassUniforms = {
|
|
|
278
278
|
radius: number;
|
|
279
279
|
};
|
|
280
280
|
|
|
281
|
-
type
|
|
281
|
+
type CombineShaderMode = "add" | "screen" | "multiply" | "overlay" | "max" | "min" | "difference" | "alphaOver" | "premultipliedOver" | "lerp" | "mask";
|
|
282
282
|
|
|
283
283
|
type DitherPulseRingProps = {
|
|
284
284
|
spriteTextureSrc?: string;
|
|
@@ -286,7 +286,7 @@ type DitherPulseRingProps = {
|
|
|
286
286
|
diffuseEnabled?: boolean;
|
|
287
287
|
blurEnabled?: boolean;
|
|
288
288
|
noiseWarpEnabled?: boolean;
|
|
289
|
-
combineMode?:
|
|
289
|
+
combineMode?: CombineShaderMode;
|
|
290
290
|
noiseWarpRadius?: NoiseWarpPassUniforms["radius"];
|
|
291
291
|
noiseWarpStrength?: NoiseWarpPassUniforms["strength"];
|
|
292
292
|
diffuseRadius?: DiffusePassUniforms["diffuseRadius"];
|
|
@@ -308,4 +308,24 @@ type DitherPulseRingProps = {
|
|
|
308
308
|
};
|
|
309
309
|
declare function DitherPulseRing({ spriteTextureSrc, glyphDitherEnabled, diffuseEnabled, blurEnabled, noiseWarpEnabled, combineMode, noiseWarpRadius, noiseWarpStrength, diffuseRadius, blurRadius, borderThickness, borderIntensity, borderColor, borderDitherStrength, borderTonemap, borderAlpha, ringColor, ringSpeed, ringPosition, ringAlpha, width, height, className, style, }: DitherPulseRingProps): react_jsx_runtime.JSX.Element;
|
|
310
310
|
|
|
311
|
-
|
|
311
|
+
type DitherStreamProps = {
|
|
312
|
+
width?: string | number;
|
|
313
|
+
height?: string | number;
|
|
314
|
+
className?: string;
|
|
315
|
+
style?: React.CSSProperties;
|
|
316
|
+
imageTextureSrc?: string;
|
|
317
|
+
projectionSpeed?: number;
|
|
318
|
+
beamSpeed?: number;
|
|
319
|
+
beamDirection?: "counterclockwise" | "clockwise";
|
|
320
|
+
beamColor?: [number, number, number] | string;
|
|
321
|
+
beamCenter?: [number, number];
|
|
322
|
+
beamRadius?: number;
|
|
323
|
+
beamScale?: number;
|
|
324
|
+
beamPathShape?: "circle" | "square" | "diamond" | "triangle" | "oval";
|
|
325
|
+
pathPos?: [number, number];
|
|
326
|
+
pathAngle?: number;
|
|
327
|
+
godrayIntensity?: number;
|
|
328
|
+
};
|
|
329
|
+
declare function DitherStream({ width, height, className, style, imageTextureSrc, projectionSpeed, beamSpeed, beamDirection, beamColor, beamCenter, beamRadius, beamScale, beamPathShape, pathPos, pathAngle, godrayIntensity, }: DitherStreamProps): react_jsx_runtime.JSX.Element;
|
|
330
|
+
|
|
331
|
+
export { AnimatedDrawingSVG, type CombineShaderMode, DitherPulseRing, DitherStream, EFECTO_ASCII_COMPONENT_DEFAULTS, EFECTO_ASCII_POST_PROCESSING_DEFAULTS, Efecto, type EfectoAsciiColorPalette, type EfectoAsciiStyle, type PublicPostProcessingSettings as EfectoPublicAsciiPostProcessingSettings, FractalFlower, MenuGlitch, type MenuGlitchUniforms, OranoParticles, type OranoParticlesUniforms, RippleWave, ShaderArt, type ShaderArtUniforms, Snow, WANDY_HAND_DEFAULTS, WandyHand };
|
package/dist/index.d.ts
CHANGED
|
@@ -278,7 +278,7 @@ type NoiseWarpPassUniforms = {
|
|
|
278
278
|
radius: number;
|
|
279
279
|
};
|
|
280
280
|
|
|
281
|
-
type
|
|
281
|
+
type CombineShaderMode = "add" | "screen" | "multiply" | "overlay" | "max" | "min" | "difference" | "alphaOver" | "premultipliedOver" | "lerp" | "mask";
|
|
282
282
|
|
|
283
283
|
type DitherPulseRingProps = {
|
|
284
284
|
spriteTextureSrc?: string;
|
|
@@ -286,7 +286,7 @@ type DitherPulseRingProps = {
|
|
|
286
286
|
diffuseEnabled?: boolean;
|
|
287
287
|
blurEnabled?: boolean;
|
|
288
288
|
noiseWarpEnabled?: boolean;
|
|
289
|
-
combineMode?:
|
|
289
|
+
combineMode?: CombineShaderMode;
|
|
290
290
|
noiseWarpRadius?: NoiseWarpPassUniforms["radius"];
|
|
291
291
|
noiseWarpStrength?: NoiseWarpPassUniforms["strength"];
|
|
292
292
|
diffuseRadius?: DiffusePassUniforms["diffuseRadius"];
|
|
@@ -308,4 +308,24 @@ type DitherPulseRingProps = {
|
|
|
308
308
|
};
|
|
309
309
|
declare function DitherPulseRing({ spriteTextureSrc, glyphDitherEnabled, diffuseEnabled, blurEnabled, noiseWarpEnabled, combineMode, noiseWarpRadius, noiseWarpStrength, diffuseRadius, blurRadius, borderThickness, borderIntensity, borderColor, borderDitherStrength, borderTonemap, borderAlpha, ringColor, ringSpeed, ringPosition, ringAlpha, width, height, className, style, }: DitherPulseRingProps): react_jsx_runtime.JSX.Element;
|
|
310
310
|
|
|
311
|
-
|
|
311
|
+
type DitherStreamProps = {
|
|
312
|
+
width?: string | number;
|
|
313
|
+
height?: string | number;
|
|
314
|
+
className?: string;
|
|
315
|
+
style?: React.CSSProperties;
|
|
316
|
+
imageTextureSrc?: string;
|
|
317
|
+
projectionSpeed?: number;
|
|
318
|
+
beamSpeed?: number;
|
|
319
|
+
beamDirection?: "counterclockwise" | "clockwise";
|
|
320
|
+
beamColor?: [number, number, number] | string;
|
|
321
|
+
beamCenter?: [number, number];
|
|
322
|
+
beamRadius?: number;
|
|
323
|
+
beamScale?: number;
|
|
324
|
+
beamPathShape?: "circle" | "square" | "diamond" | "triangle" | "oval";
|
|
325
|
+
pathPos?: [number, number];
|
|
326
|
+
pathAngle?: number;
|
|
327
|
+
godrayIntensity?: number;
|
|
328
|
+
};
|
|
329
|
+
declare function DitherStream({ width, height, className, style, imageTextureSrc, projectionSpeed, beamSpeed, beamDirection, beamColor, beamCenter, beamRadius, beamScale, beamPathShape, pathPos, pathAngle, godrayIntensity, }: DitherStreamProps): react_jsx_runtime.JSX.Element;
|
|
330
|
+
|
|
331
|
+
export { AnimatedDrawingSVG, type CombineShaderMode, DitherPulseRing, DitherStream, EFECTO_ASCII_COMPONENT_DEFAULTS, EFECTO_ASCII_POST_PROCESSING_DEFAULTS, Efecto, type EfectoAsciiColorPalette, type EfectoAsciiStyle, type PublicPostProcessingSettings as EfectoPublicAsciiPostProcessingSettings, FractalFlower, MenuGlitch, type MenuGlitchUniforms, OranoParticles, type OranoParticlesUniforms, RippleWave, ShaderArt, type ShaderArtUniforms, Snow, WANDY_HAND_DEFAULTS, WandyHand };
|
package/dist/index.js
CHANGED
|
@@ -32,6 +32,7 @@ var src_exports = {};
|
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
AnimatedDrawingSVG: () => AnimatedDrawingSVG,
|
|
34
34
|
DitherPulseRing: () => DitherPulseRing,
|
|
35
|
+
DitherStream: () => DitherStream,
|
|
35
36
|
EFECTO_ASCII_COMPONENT_DEFAULTS: () => EFECTO_ASCII_COMPONENT_DEFAULTS,
|
|
36
37
|
EFECTO_ASCII_POST_PROCESSING_DEFAULTS: () => EFECTO_ASCII_POST_PROCESSING_DEFAULTS,
|
|
37
38
|
Efecto: () => Efecto,
|
|
@@ -4593,17 +4594,20 @@ function RenderPipeline({
|
|
|
4593
4594
|
}) {
|
|
4594
4595
|
const sharedScene = useSceneContext();
|
|
4595
4596
|
const size = sharedScene?.size ?? { width: 1, height: 1 };
|
|
4597
|
+
const shouldCombine = Boolean(combine);
|
|
4596
4598
|
const targets = (0, import_react19.useMemo)(() => {
|
|
4597
4599
|
const entries = passes.map((_, index) => ({
|
|
4598
4600
|
key: `pass_${index}`,
|
|
4599
4601
|
target: new THREE16.WebGLRenderTarget(1, 1, DEFAULT_TARGET_OPTIONS)
|
|
4600
4602
|
}));
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4603
|
+
if (shouldCombine) {
|
|
4604
|
+
entries.push({
|
|
4605
|
+
key: "combine",
|
|
4606
|
+
target: new THREE16.WebGLRenderTarget(1, 1, DEFAULT_TARGET_OPTIONS)
|
|
4607
|
+
});
|
|
4608
|
+
}
|
|
4605
4609
|
return entries;
|
|
4606
|
-
}, [passes]);
|
|
4610
|
+
}, [passes, shouldCombine]);
|
|
4607
4611
|
(0, import_react19.useEffect)(() => {
|
|
4608
4612
|
if (size.width <= 1 || size.height <= 1) return;
|
|
4609
4613
|
targets.forEach(({ target }) => {
|
|
@@ -4633,7 +4637,7 @@ function RenderPipeline({
|
|
|
4633
4637
|
if (!passes.length) return null;
|
|
4634
4638
|
const lastEnabledIndex = [...passes].map((pass, index) => ({ pass, index })).filter(({ pass }) => pass.enabled !== false).map(({ index }) => index).pop();
|
|
4635
4639
|
if (lastEnabledIndex === void 0) return null;
|
|
4636
|
-
if (lastEnabledIndex <= Math.max(firstEnabledIndex, secondEnabledIndex)) {
|
|
4640
|
+
if (shouldCombine && lastEnabledIndex <= Math.max(firstEnabledIndex, secondEnabledIndex)) {
|
|
4637
4641
|
return combineTarget ?? null;
|
|
4638
4642
|
}
|
|
4639
4643
|
return passOutputTarget(lastEnabledIndex);
|
|
@@ -4654,7 +4658,7 @@ function RenderPipeline({
|
|
|
4654
4658
|
},
|
|
4655
4659
|
`pass_${index}`
|
|
4656
4660
|
);
|
|
4657
|
-
if (!combineRendered && combineTarget && index === secondEnabledIndex) {
|
|
4661
|
+
if (shouldCombine && !combineRendered && combineTarget && index === secondEnabledIndex) {
|
|
4658
4662
|
const inputA = passOutputTarget(firstEnabledIndex)?.texture ?? inputTexture;
|
|
4659
4663
|
const inputB = passOutputTarget(secondEnabledIndex)?.texture ?? inputTexture;
|
|
4660
4664
|
combineRendered = true;
|
|
@@ -4748,20 +4752,23 @@ function useMouse({
|
|
|
4748
4752
|
const handleMouseLeave = () => {
|
|
4749
4753
|
mouse.set(center?.x ?? 0.5, center?.y ?? 0.5);
|
|
4750
4754
|
};
|
|
4751
|
-
const moveTarget = element ?? window;
|
|
4752
|
-
moveTarget.addEventListener("mousemove", handleMouseMove);
|
|
4753
|
-
moveTarget.addEventListener("mouseleave", handleMouseLeave);
|
|
4754
4755
|
if (element) {
|
|
4756
|
+
element.addEventListener("mousemove", handleMouseMove);
|
|
4757
|
+
element.addEventListener("mouseleave", handleMouseLeave);
|
|
4755
4758
|
element.addEventListener("mouseenter", updateRect);
|
|
4759
|
+
} else if (hasWindow) {
|
|
4760
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
4756
4761
|
}
|
|
4757
4762
|
if (hasWindow) {
|
|
4758
4763
|
window.addEventListener("resize", handleResize);
|
|
4759
4764
|
}
|
|
4760
4765
|
return () => {
|
|
4761
|
-
moveTarget.removeEventListener("mousemove", handleMouseMove);
|
|
4762
|
-
moveTarget.removeEventListener("mouseleave", handleMouseLeave);
|
|
4763
4766
|
if (element) {
|
|
4767
|
+
element.removeEventListener("mousemove", handleMouseMove);
|
|
4768
|
+
element.removeEventListener("mouseleave", handleMouseLeave);
|
|
4764
4769
|
element.removeEventListener("mouseenter", updateRect);
|
|
4770
|
+
} else if (hasWindow) {
|
|
4771
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
4765
4772
|
}
|
|
4766
4773
|
if (hasWindow) {
|
|
4767
4774
|
window.removeEventListener("resize", handleResize);
|
|
@@ -5128,10 +5135,469 @@ function DitherPulseRingContent({
|
|
|
5128
5135
|
)
|
|
5129
5136
|
] });
|
|
5130
5137
|
}
|
|
5138
|
+
|
|
5139
|
+
// src/components/DitherStreamBeamCompositePass.tsx
|
|
5140
|
+
var import_react23 = require("react");
|
|
5141
|
+
var THREE21 = __toESM(require("three"));
|
|
5142
|
+
|
|
5143
|
+
// src/utils/createFallbackTexture.ts
|
|
5144
|
+
var THREE20 = __toESM(require("three"));
|
|
5145
|
+
function createFallbackTexture() {
|
|
5146
|
+
const data = new Uint8Array([0, 0, 0, 255]);
|
|
5147
|
+
const texture = new THREE20.DataTexture(data, 1, 1, THREE20.RGBAFormat);
|
|
5148
|
+
texture.needsUpdate = true;
|
|
5149
|
+
texture.wrapS = THREE20.ClampToEdgeWrapping;
|
|
5150
|
+
texture.wrapT = THREE20.ClampToEdgeWrapping;
|
|
5151
|
+
texture.minFilter = THREE20.NearestFilter;
|
|
5152
|
+
texture.magFilter = THREE20.NearestFilter;
|
|
5153
|
+
return texture;
|
|
5154
|
+
}
|
|
5155
|
+
|
|
5156
|
+
// src/shaders/dither-godray-beam-composite/fragment.glsl
|
|
5157
|
+
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";
|
|
5158
|
+
|
|
5159
|
+
// src/shaders/dither-godray-beam-composite/vertex.glsl
|
|
5160
|
+
var vertex_default14 = "out vec2 vTextureCoord;\n\nvoid main() {\n vTextureCoord = uv;\n gl_Position = vec4(position, 1.0);\n}\n";
|
|
5161
|
+
|
|
5162
|
+
// src/components/DitherStreamBeamCompositePass.tsx
|
|
5163
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
5164
|
+
function DitherStreamBeamCompositePass({
|
|
5165
|
+
inputTexture = null,
|
|
5166
|
+
beamSpeed = 0.1,
|
|
5167
|
+
beamDirection = "counterclockwise",
|
|
5168
|
+
beamColor = [0.667, 0.686, 0.941],
|
|
5169
|
+
beamCenter = [0.5, 0.95],
|
|
5170
|
+
beamRadius = 0.6,
|
|
5171
|
+
beamScale = 1,
|
|
5172
|
+
pathShape = "circle",
|
|
5173
|
+
pathPos = [0.5009, 1.0473],
|
|
5174
|
+
pathAngle = (0.999 - 0.25) * -6.28318531,
|
|
5175
|
+
target = null,
|
|
5176
|
+
clear = true,
|
|
5177
|
+
enabled = true,
|
|
5178
|
+
priority = 0
|
|
5179
|
+
}) {
|
|
5180
|
+
const fallbackTexture = (0, import_react23.useMemo)(() => createFallbackTexture(), []);
|
|
5181
|
+
const uniforms = (0, import_react23.useMemo)(
|
|
5182
|
+
() => ({
|
|
5183
|
+
uTexture: { value: inputTexture ?? fallbackTexture },
|
|
5184
|
+
uTime: { value: 0 },
|
|
5185
|
+
uResolution: { value: new THREE21.Vector2(1, 1) },
|
|
5186
|
+
uBeamSpeed: { value: beamSpeed },
|
|
5187
|
+
uBeamDirection: { value: beamDirection === "clockwise" ? -1 : 1 },
|
|
5188
|
+
uBeamColor: {
|
|
5189
|
+
value: new THREE21.Color(beamColor[0], beamColor[1], beamColor[2])
|
|
5190
|
+
},
|
|
5191
|
+
uBeamCenter: { value: new THREE21.Vector2(beamCenter[0], beamCenter[1]) },
|
|
5192
|
+
uBeamRadius: { value: beamRadius },
|
|
5193
|
+
uBeamScale: { value: beamScale },
|
|
5194
|
+
uPathShape: {
|
|
5195
|
+
value: pathShape === "square" ? 1 : pathShape === "diamond" ? 2 : pathShape === "triangle" ? 3 : pathShape === "oval" ? 4 : 0
|
|
5196
|
+
},
|
|
5197
|
+
uPathPos: { value: new THREE21.Vector2(pathPos[0], pathPos[1]) },
|
|
5198
|
+
uPathAngle: { value: pathAngle }
|
|
5199
|
+
}),
|
|
5200
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5201
|
+
[]
|
|
5202
|
+
);
|
|
5203
|
+
uniforms.uTexture.value = inputTexture ?? fallbackTexture;
|
|
5204
|
+
uniforms.uBeamSpeed.value = beamSpeed;
|
|
5205
|
+
uniforms.uBeamDirection.value = beamDirection === "clockwise" ? -1 : 1;
|
|
5206
|
+
uniforms.uBeamColor.value.setRGB(
|
|
5207
|
+
beamColor[0],
|
|
5208
|
+
beamColor[1],
|
|
5209
|
+
beamColor[2]
|
|
5210
|
+
);
|
|
5211
|
+
uniforms.uBeamCenter.value.set(
|
|
5212
|
+
beamCenter[0],
|
|
5213
|
+
beamCenter[1]
|
|
5214
|
+
);
|
|
5215
|
+
uniforms.uBeamRadius.value = beamRadius;
|
|
5216
|
+
uniforms.uBeamScale.value = beamScale;
|
|
5217
|
+
uniforms.uPathShape.value = pathShape === "square" ? 1 : pathShape === "diamond" ? 2 : pathShape === "triangle" ? 3 : pathShape === "oval" ? 4 : 0;
|
|
5218
|
+
uniforms.uPathPos.value.set(pathPos[0], pathPos[1]);
|
|
5219
|
+
uniforms.uPathAngle.value = pathAngle;
|
|
5220
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
5221
|
+
ShaderPass,
|
|
5222
|
+
{
|
|
5223
|
+
vertexShader: vertex_default14,
|
|
5224
|
+
fragmentShader: fragment_default15,
|
|
5225
|
+
uniforms,
|
|
5226
|
+
inputTexture: inputTexture ?? fallbackTexture,
|
|
5227
|
+
target,
|
|
5228
|
+
clear,
|
|
5229
|
+
enabled,
|
|
5230
|
+
priority,
|
|
5231
|
+
timeUniform: "uTime",
|
|
5232
|
+
resolutionUniform: "uResolution",
|
|
5233
|
+
blending: THREE21.NoBlending
|
|
5234
|
+
}
|
|
5235
|
+
);
|
|
5236
|
+
}
|
|
5237
|
+
|
|
5238
|
+
// src/components/DitherStreamDitherPass.tsx
|
|
5239
|
+
var import_react24 = require("react");
|
|
5240
|
+
var THREE22 = __toESM(require("three"));
|
|
5241
|
+
|
|
5242
|
+
// src/shaders/dither-godray-dither/fragment.glsl
|
|
5243
|
+
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";
|
|
5244
|
+
|
|
5245
|
+
// src/shaders/dither-godray-dither/vertex.glsl
|
|
5246
|
+
var vertex_default15 = "out vec2 vTextureCoord;\n\nvoid main() {\n vTextureCoord = uv;\n gl_Position = vec4(position, 1.0);\n}\n";
|
|
5247
|
+
|
|
5248
|
+
// src/components/DitherStreamDitherPass.tsx
|
|
5249
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
5250
|
+
function DitherStreamDitherPass({
|
|
5251
|
+
inputTexture = null,
|
|
5252
|
+
target = null,
|
|
5253
|
+
clear = true,
|
|
5254
|
+
enabled = true,
|
|
5255
|
+
priority = 0
|
|
5256
|
+
}) {
|
|
5257
|
+
const fallbackTexture = (0, import_react24.useMemo)(() => createFallbackTexture(), []);
|
|
5258
|
+
const uniforms = (0, import_react24.useMemo)(
|
|
5259
|
+
() => ({
|
|
5260
|
+
uTexture: { value: inputTexture ?? fallbackTexture },
|
|
5261
|
+
uResolution: { value: new THREE22.Vector2(1, 1) }
|
|
5262
|
+
}),
|
|
5263
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5264
|
+
[]
|
|
5265
|
+
);
|
|
5266
|
+
uniforms.uTexture.value = inputTexture ?? fallbackTexture;
|
|
5267
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5268
|
+
ShaderPass,
|
|
5269
|
+
{
|
|
5270
|
+
vertexShader: vertex_default15,
|
|
5271
|
+
fragmentShader: fragment_default16,
|
|
5272
|
+
uniforms,
|
|
5273
|
+
inputTexture: inputTexture ?? fallbackTexture,
|
|
5274
|
+
target,
|
|
5275
|
+
clear,
|
|
5276
|
+
enabled,
|
|
5277
|
+
priority,
|
|
5278
|
+
resolutionUniform: "uResolution",
|
|
5279
|
+
blending: THREE22.NoBlending
|
|
5280
|
+
}
|
|
5281
|
+
);
|
|
5282
|
+
}
|
|
5283
|
+
|
|
5284
|
+
// src/components/DitherStreamGodRaysPass.tsx
|
|
5285
|
+
var import_react25 = require("react");
|
|
5286
|
+
var THREE23 = __toESM(require("three"));
|
|
5287
|
+
|
|
5288
|
+
// src/shaders/dither-godray-extract/fragment.glsl
|
|
5289
|
+
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";
|
|
5290
|
+
|
|
5291
|
+
// src/shaders/dither-godray-extract/vertex.glsl
|
|
5292
|
+
var vertex_default16 = "out vec2 vTextureCoord;\n\nvoid main() {\n vTextureCoord = uv;\n gl_Position = vec4(position, 1.0);\n}\n";
|
|
5293
|
+
|
|
5294
|
+
// src/shaders/dither-godray-final/fragment.glsl
|
|
5295
|
+
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";
|
|
5296
|
+
|
|
5297
|
+
// src/shaders/dither-godray-final/vertex.glsl
|
|
5298
|
+
var vertex_default17 = "out vec2 vTextureCoord;\n\nvoid main() {\n vTextureCoord = uv;\n gl_Position = vec4(position, 1.0);\n}\n";
|
|
5299
|
+
|
|
5300
|
+
// src/shaders/dither-godray-march/fragment.glsl
|
|
5301
|
+
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";
|
|
5302
|
+
|
|
5303
|
+
// src/shaders/dither-godray-march/vertex.glsl
|
|
5304
|
+
var vertex_default18 = "out vec2 vTextureCoord;\n\nvoid main() {\n vTextureCoord = uv;\n gl_Position = vec4(position, 1.0);\n}\n";
|
|
5305
|
+
|
|
5306
|
+
// src/components/DitherStreamGodRaysPass.tsx
|
|
5307
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
5308
|
+
var TARGET_OPTIONS = {
|
|
5309
|
+
depthBuffer: false,
|
|
5310
|
+
stencilBuffer: false
|
|
5311
|
+
};
|
|
5312
|
+
function DitherStreamGodRaysPass({
|
|
5313
|
+
inputTexture = null,
|
|
5314
|
+
intensity = 2.9,
|
|
5315
|
+
target = null,
|
|
5316
|
+
enabled = true,
|
|
5317
|
+
priority = 0
|
|
5318
|
+
}) {
|
|
5319
|
+
const sharedScene = useSceneContext();
|
|
5320
|
+
const size = sharedScene?.size ?? { width: 1, height: 1 };
|
|
5321
|
+
const fallbackTexture = (0, import_react25.useMemo)(() => createFallbackTexture(), []);
|
|
5322
|
+
const extractTarget = (0, import_react25.useMemo)(
|
|
5323
|
+
() => new THREE23.WebGLRenderTarget(1, 1, TARGET_OPTIONS),
|
|
5324
|
+
[]
|
|
5325
|
+
);
|
|
5326
|
+
const marchTarget = (0, import_react25.useMemo)(
|
|
5327
|
+
() => new THREE23.WebGLRenderTarget(1, 1, TARGET_OPTIONS),
|
|
5328
|
+
[]
|
|
5329
|
+
);
|
|
5330
|
+
(0, import_react25.useEffect)(() => {
|
|
5331
|
+
return () => {
|
|
5332
|
+
extractTarget.dispose();
|
|
5333
|
+
marchTarget.dispose();
|
|
5334
|
+
};
|
|
5335
|
+
}, [extractTarget, marchTarget]);
|
|
5336
|
+
(0, import_react25.useEffect)(() => {
|
|
5337
|
+
if (size.width <= 1 || size.height <= 1) return;
|
|
5338
|
+
extractTarget.setSize(size.width, size.height);
|
|
5339
|
+
marchTarget.setSize(
|
|
5340
|
+
Math.max(1, Math.floor(size.width / 4)),
|
|
5341
|
+
Math.max(1, Math.floor(size.height / 4))
|
|
5342
|
+
);
|
|
5343
|
+
}, [extractTarget, marchTarget, size.height, size.width]);
|
|
5344
|
+
const extractUniforms = (0, import_react25.useMemo)(
|
|
5345
|
+
() => ({
|
|
5346
|
+
uTexture: { value: inputTexture ?? fallbackTexture }
|
|
5347
|
+
}),
|
|
5348
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5349
|
+
[]
|
|
5350
|
+
);
|
|
5351
|
+
const marchUniforms = (0, import_react25.useMemo)(
|
|
5352
|
+
() => ({
|
|
5353
|
+
uTexture: { value: extractTarget.texture }
|
|
5354
|
+
}),
|
|
5355
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5356
|
+
[]
|
|
5357
|
+
);
|
|
5358
|
+
const finalUniforms = (0, import_react25.useMemo)(
|
|
5359
|
+
() => ({
|
|
5360
|
+
uScene: { value: inputTexture ?? fallbackTexture },
|
|
5361
|
+
uGR: { value: marchTarget.texture },
|
|
5362
|
+
uGodrayIntensity: { value: intensity }
|
|
5363
|
+
}),
|
|
5364
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5365
|
+
[]
|
|
5366
|
+
);
|
|
5367
|
+
extractUniforms.uTexture.value = inputTexture ?? fallbackTexture;
|
|
5368
|
+
marchUniforms.uTexture.value = extractTarget.texture;
|
|
5369
|
+
finalUniforms.uScene.value = inputTexture ?? fallbackTexture;
|
|
5370
|
+
finalUniforms.uGR.value = marchTarget.texture;
|
|
5371
|
+
finalUniforms.uGodrayIntensity.value = intensity;
|
|
5372
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
5373
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5374
|
+
ShaderPass,
|
|
5375
|
+
{
|
|
5376
|
+
vertexShader: vertex_default16,
|
|
5377
|
+
fragmentShader: fragment_default17,
|
|
5378
|
+
uniforms: extractUniforms,
|
|
5379
|
+
inputTexture: inputTexture ?? fallbackTexture,
|
|
5380
|
+
target: extractTarget,
|
|
5381
|
+
clear: true,
|
|
5382
|
+
enabled,
|
|
5383
|
+
priority,
|
|
5384
|
+
blending: THREE23.NoBlending
|
|
5385
|
+
}
|
|
5386
|
+
),
|
|
5387
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5388
|
+
ShaderPass,
|
|
5389
|
+
{
|
|
5390
|
+
vertexShader: vertex_default18,
|
|
5391
|
+
fragmentShader: fragment_default19,
|
|
5392
|
+
uniforms: marchUniforms,
|
|
5393
|
+
inputTexture: extractTarget.texture,
|
|
5394
|
+
target: marchTarget,
|
|
5395
|
+
clear: true,
|
|
5396
|
+
enabled,
|
|
5397
|
+
priority: priority + 1,
|
|
5398
|
+
blending: THREE23.NoBlending
|
|
5399
|
+
}
|
|
5400
|
+
),
|
|
5401
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
5402
|
+
ShaderPass,
|
|
5403
|
+
{
|
|
5404
|
+
vertexShader: vertex_default17,
|
|
5405
|
+
fragmentShader: fragment_default18,
|
|
5406
|
+
uniforms: finalUniforms,
|
|
5407
|
+
inputTexture: inputTexture ?? fallbackTexture,
|
|
5408
|
+
target,
|
|
5409
|
+
clear: true,
|
|
5410
|
+
enabled,
|
|
5411
|
+
priority: priority + 2,
|
|
5412
|
+
blending: THREE23.NoBlending
|
|
5413
|
+
}
|
|
5414
|
+
)
|
|
5415
|
+
] });
|
|
5416
|
+
}
|
|
5417
|
+
|
|
5418
|
+
// src/components/DitherStreamProjectionPass.tsx
|
|
5419
|
+
var import_react26 = require("react");
|
|
5420
|
+
var THREE24 = __toESM(require("three"));
|
|
5421
|
+
|
|
5422
|
+
// src/shaders/dither-godray-projection/fragment.glsl
|
|
5423
|
+
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";
|
|
5424
|
+
|
|
5425
|
+
// src/shaders/dither-godray-projection/vertex.glsl
|
|
5426
|
+
var vertex_default19 = "out vec2 vTextureCoord;\n\nvoid main() {\n vTextureCoord = uv;\n gl_Position = vec4(position, 1.0);\n}\n";
|
|
5427
|
+
|
|
5428
|
+
// src/components/DitherStreamProjectionPass.tsx
|
|
5429
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
5430
|
+
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";
|
|
5431
|
+
function DitherStreamProjectionPass({
|
|
5432
|
+
imageTextureSrc = DEFAULT_IMAGE_SRC,
|
|
5433
|
+
projectionSpeed = 0.05,
|
|
5434
|
+
target = null,
|
|
5435
|
+
clear = true,
|
|
5436
|
+
enabled = true,
|
|
5437
|
+
priority = 0
|
|
5438
|
+
}) {
|
|
5439
|
+
const [imageTexture, setImageTexture] = (0, import_react26.useState)(null);
|
|
5440
|
+
const fallbackTexture = (0, import_react26.useMemo)(() => createFallbackTexture(), []);
|
|
5441
|
+
(0, import_react26.useEffect)(() => {
|
|
5442
|
+
let active = true;
|
|
5443
|
+
const loader = new THREE24.TextureLoader();
|
|
5444
|
+
loader.load(
|
|
5445
|
+
imageTextureSrc,
|
|
5446
|
+
(texture) => {
|
|
5447
|
+
if (!active) {
|
|
5448
|
+
texture.dispose();
|
|
5449
|
+
return;
|
|
5450
|
+
}
|
|
5451
|
+
texture.wrapS = THREE24.RepeatWrapping;
|
|
5452
|
+
texture.wrapT = THREE24.RepeatWrapping;
|
|
5453
|
+
texture.minFilter = THREE24.LinearFilter;
|
|
5454
|
+
texture.magFilter = THREE24.LinearFilter;
|
|
5455
|
+
texture.generateMipmaps = true;
|
|
5456
|
+
texture.colorSpace = THREE24.NoColorSpace;
|
|
5457
|
+
texture.needsUpdate = true;
|
|
5458
|
+
setImageTexture(texture);
|
|
5459
|
+
},
|
|
5460
|
+
void 0,
|
|
5461
|
+
() => {
|
|
5462
|
+
if (!active) return;
|
|
5463
|
+
setImageTexture(fallbackTexture);
|
|
5464
|
+
}
|
|
5465
|
+
);
|
|
5466
|
+
return () => {
|
|
5467
|
+
active = false;
|
|
5468
|
+
};
|
|
5469
|
+
}, [fallbackTexture, imageTextureSrc]);
|
|
5470
|
+
const uniforms = (0, import_react26.useMemo)(
|
|
5471
|
+
() => ({
|
|
5472
|
+
uTex: { value: imageTexture ?? fallbackTexture },
|
|
5473
|
+
uTime: { value: 0 },
|
|
5474
|
+
uProjectionSpeed: { value: projectionSpeed }
|
|
5475
|
+
}),
|
|
5476
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5477
|
+
[]
|
|
5478
|
+
);
|
|
5479
|
+
uniforms.uTex.value = imageTexture ?? fallbackTexture;
|
|
5480
|
+
uniforms.uProjectionSpeed.value = projectionSpeed;
|
|
5481
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
5482
|
+
ShaderPass,
|
|
5483
|
+
{
|
|
5484
|
+
vertexShader: vertex_default19,
|
|
5485
|
+
fragmentShader: fragment_default20,
|
|
5486
|
+
uniforms,
|
|
5487
|
+
target,
|
|
5488
|
+
clear,
|
|
5489
|
+
enabled,
|
|
5490
|
+
priority,
|
|
5491
|
+
timeUniform: "uTime",
|
|
5492
|
+
blending: THREE24.NoBlending
|
|
5493
|
+
}
|
|
5494
|
+
);
|
|
5495
|
+
}
|
|
5496
|
+
|
|
5497
|
+
// src/components/DitherStreamRendererConfig.tsx
|
|
5498
|
+
var import_react27 = require("react");
|
|
5499
|
+
var THREE25 = __toESM(require("three"));
|
|
5500
|
+
function DitherStreamRendererConfig() {
|
|
5501
|
+
const sharedScene = useSceneContext();
|
|
5502
|
+
(0, import_react27.useEffect)(() => {
|
|
5503
|
+
const context = sharedScene?.contextRef.current;
|
|
5504
|
+
if (!context) return;
|
|
5505
|
+
const renderer = context.renderer;
|
|
5506
|
+
const prevOutputColorSpace = renderer.outputColorSpace;
|
|
5507
|
+
const prevToneMapping = renderer.toneMapping;
|
|
5508
|
+
renderer.outputColorSpace = THREE25.LinearSRGBColorSpace;
|
|
5509
|
+
renderer.toneMapping = THREE25.NoToneMapping;
|
|
5510
|
+
return () => {
|
|
5511
|
+
renderer.outputColorSpace = prevOutputColorSpace;
|
|
5512
|
+
renderer.toneMapping = prevToneMapping;
|
|
5513
|
+
};
|
|
5514
|
+
}, [sharedScene]);
|
|
5515
|
+
return null;
|
|
5516
|
+
}
|
|
5517
|
+
|
|
5518
|
+
// src/components/DitherStream.tsx
|
|
5519
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
5520
|
+
function DitherStream({
|
|
5521
|
+
width = "100%",
|
|
5522
|
+
height = "100%",
|
|
5523
|
+
className = "relative h-full w-full",
|
|
5524
|
+
style,
|
|
5525
|
+
imageTextureSrc,
|
|
5526
|
+
projectionSpeed = 0.05,
|
|
5527
|
+
beamSpeed = 0.1,
|
|
5528
|
+
beamDirection = "counterclockwise",
|
|
5529
|
+
beamColor = [0.667, 0.686, 0.941],
|
|
5530
|
+
beamCenter = [0.5, 0.95],
|
|
5531
|
+
beamRadius = 0.6,
|
|
5532
|
+
beamScale = 1,
|
|
5533
|
+
beamPathShape = "circle",
|
|
5534
|
+
pathPos = [0.5009, 1.0473],
|
|
5535
|
+
pathAngle = (0.999 - 0.25) * -6.28318531,
|
|
5536
|
+
godrayIntensity = 2.9
|
|
5537
|
+
}) {
|
|
5538
|
+
const resolveColor = (color) => {
|
|
5539
|
+
if (Array.isArray(color)) return color;
|
|
5540
|
+
const normalized = color.replace("#", "");
|
|
5541
|
+
if (normalized.length !== 6)
|
|
5542
|
+
return [0.667, 0.686, 0.941];
|
|
5543
|
+
return [
|
|
5544
|
+
parseInt(normalized.slice(0, 2), 16) / 255,
|
|
5545
|
+
parseInt(normalized.slice(2, 4), 16) / 255,
|
|
5546
|
+
parseInt(normalized.slice(4, 6), 16) / 255
|
|
5547
|
+
];
|
|
5548
|
+
};
|
|
5549
|
+
const resolvedBeamColor = resolveColor(beamColor);
|
|
5550
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
5551
|
+
SceneProvider,
|
|
5552
|
+
{
|
|
5553
|
+
width,
|
|
5554
|
+
height,
|
|
5555
|
+
className,
|
|
5556
|
+
style,
|
|
5557
|
+
manualRender: true,
|
|
5558
|
+
children: [
|
|
5559
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(DitherStreamRendererConfig, {}),
|
|
5560
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5561
|
+
RenderPipeline,
|
|
5562
|
+
{
|
|
5563
|
+
passes: [
|
|
5564
|
+
{
|
|
5565
|
+
component: DitherStreamProjectionPass,
|
|
5566
|
+
props: { imageTextureSrc, projectionSpeed }
|
|
5567
|
+
},
|
|
5568
|
+
{
|
|
5569
|
+
component: DitherStreamBeamCompositePass,
|
|
5570
|
+
props: {
|
|
5571
|
+
beamSpeed,
|
|
5572
|
+
beamDirection,
|
|
5573
|
+
beamColor: resolvedBeamColor,
|
|
5574
|
+
beamCenter,
|
|
5575
|
+
beamRadius,
|
|
5576
|
+
beamScale,
|
|
5577
|
+
pathShape: beamPathShape,
|
|
5578
|
+
pathPos,
|
|
5579
|
+
pathAngle
|
|
5580
|
+
}
|
|
5581
|
+
},
|
|
5582
|
+
{
|
|
5583
|
+
component: DitherStreamDitherPass
|
|
5584
|
+
},
|
|
5585
|
+
{
|
|
5586
|
+
component: DitherStreamGodRaysPass,
|
|
5587
|
+
props: { intensity: godrayIntensity }
|
|
5588
|
+
}
|
|
5589
|
+
]
|
|
5590
|
+
}
|
|
5591
|
+
)
|
|
5592
|
+
]
|
|
5593
|
+
}
|
|
5594
|
+
);
|
|
5595
|
+
}
|
|
5131
5596
|
// Annotate the CommonJS export names for ESM import in node:
|
|
5132
5597
|
0 && (module.exports = {
|
|
5133
5598
|
AnimatedDrawingSVG,
|
|
5134
5599
|
DitherPulseRing,
|
|
5600
|
+
DitherStream,
|
|
5135
5601
|
EFECTO_ASCII_COMPONENT_DEFAULTS,
|
|
5136
5602
|
EFECTO_ASCII_POST_PROCESSING_DEFAULTS,
|
|
5137
5603
|
Efecto,
|
package/dist/index.mjs
CHANGED
|
@@ -4580,17 +4580,20 @@ function RenderPipeline({
|
|
|
4580
4580
|
}) {
|
|
4581
4581
|
const sharedScene = useSceneContext();
|
|
4582
4582
|
const size = sharedScene?.size ?? { width: 1, height: 1 };
|
|
4583
|
+
const shouldCombine = Boolean(combine);
|
|
4583
4584
|
const targets = useMemo12(() => {
|
|
4584
4585
|
const entries = passes.map((_, index) => ({
|
|
4585
4586
|
key: `pass_${index}`,
|
|
4586
4587
|
target: new THREE16.WebGLRenderTarget(1, 1, DEFAULT_TARGET_OPTIONS)
|
|
4587
4588
|
}));
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4589
|
+
if (shouldCombine) {
|
|
4590
|
+
entries.push({
|
|
4591
|
+
key: "combine",
|
|
4592
|
+
target: new THREE16.WebGLRenderTarget(1, 1, DEFAULT_TARGET_OPTIONS)
|
|
4593
|
+
});
|
|
4594
|
+
}
|
|
4592
4595
|
return entries;
|
|
4593
|
-
}, [passes]);
|
|
4596
|
+
}, [passes, shouldCombine]);
|
|
4594
4597
|
useEffect14(() => {
|
|
4595
4598
|
if (size.width <= 1 || size.height <= 1) return;
|
|
4596
4599
|
targets.forEach(({ target }) => {
|
|
@@ -4620,7 +4623,7 @@ function RenderPipeline({
|
|
|
4620
4623
|
if (!passes.length) return null;
|
|
4621
4624
|
const lastEnabledIndex = [...passes].map((pass, index) => ({ pass, index })).filter(({ pass }) => pass.enabled !== false).map(({ index }) => index).pop();
|
|
4622
4625
|
if (lastEnabledIndex === void 0) return null;
|
|
4623
|
-
if (lastEnabledIndex <= Math.max(firstEnabledIndex, secondEnabledIndex)) {
|
|
4626
|
+
if (shouldCombine && lastEnabledIndex <= Math.max(firstEnabledIndex, secondEnabledIndex)) {
|
|
4624
4627
|
return combineTarget ?? null;
|
|
4625
4628
|
}
|
|
4626
4629
|
return passOutputTarget(lastEnabledIndex);
|
|
@@ -4641,7 +4644,7 @@ function RenderPipeline({
|
|
|
4641
4644
|
},
|
|
4642
4645
|
`pass_${index}`
|
|
4643
4646
|
);
|
|
4644
|
-
if (!combineRendered && combineTarget && index === secondEnabledIndex) {
|
|
4647
|
+
if (shouldCombine && !combineRendered && combineTarget && index === secondEnabledIndex) {
|
|
4645
4648
|
const inputA = passOutputTarget(firstEnabledIndex)?.texture ?? inputTexture;
|
|
4646
4649
|
const inputB = passOutputTarget(secondEnabledIndex)?.texture ?? inputTexture;
|
|
4647
4650
|
combineRendered = true;
|
|
@@ -4735,20 +4738,23 @@ function useMouse({
|
|
|
4735
4738
|
const handleMouseLeave = () => {
|
|
4736
4739
|
mouse.set(center?.x ?? 0.5, center?.y ?? 0.5);
|
|
4737
4740
|
};
|
|
4738
|
-
const moveTarget = element ?? window;
|
|
4739
|
-
moveTarget.addEventListener("mousemove", handleMouseMove);
|
|
4740
|
-
moveTarget.addEventListener("mouseleave", handleMouseLeave);
|
|
4741
4741
|
if (element) {
|
|
4742
|
+
element.addEventListener("mousemove", handleMouseMove);
|
|
4743
|
+
element.addEventListener("mouseleave", handleMouseLeave);
|
|
4742
4744
|
element.addEventListener("mouseenter", updateRect);
|
|
4745
|
+
} else if (hasWindow) {
|
|
4746
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
4743
4747
|
}
|
|
4744
4748
|
if (hasWindow) {
|
|
4745
4749
|
window.addEventListener("resize", handleResize);
|
|
4746
4750
|
}
|
|
4747
4751
|
return () => {
|
|
4748
|
-
moveTarget.removeEventListener("mousemove", handleMouseMove);
|
|
4749
|
-
moveTarget.removeEventListener("mouseleave", handleMouseLeave);
|
|
4750
4752
|
if (element) {
|
|
4753
|
+
element.removeEventListener("mousemove", handleMouseMove);
|
|
4754
|
+
element.removeEventListener("mouseleave", handleMouseLeave);
|
|
4751
4755
|
element.removeEventListener("mouseenter", updateRect);
|
|
4756
|
+
} else if (hasWindow) {
|
|
4757
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
4752
4758
|
}
|
|
4753
4759
|
if (hasWindow) {
|
|
4754
4760
|
window.removeEventListener("resize", handleResize);
|
|
@@ -5115,9 +5121,468 @@ function DitherPulseRingContent({
|
|
|
5115
5121
|
)
|
|
5116
5122
|
] });
|
|
5117
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,
|
|
5208
|
+
{
|
|
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;
|
|
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
|
+
)
|
|
5578
|
+
]
|
|
5579
|
+
}
|
|
5580
|
+
);
|
|
5581
|
+
}
|
|
5118
5582
|
export {
|
|
5119
5583
|
AnimatedDrawingSVG,
|
|
5120
5584
|
DitherPulseRing,
|
|
5585
|
+
DitherStream,
|
|
5121
5586
|
EFECTO_ASCII_COMPONENT_DEFAULTS,
|
|
5122
5587
|
EFECTO_ASCII_POST_PROCESSING_DEFAULTS,
|
|
5123
5588
|
Efecto,
|