@toriistudio/shader-ui 0.0.10 → 0.0.11
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 +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +34 -4
- package/dist/index.mjs +34 -4
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -316,6 +316,7 @@ type DitherStreamProps = {
|
|
|
316
316
|
children?: React.ReactNode;
|
|
317
317
|
imageTextureSrc?: string;
|
|
318
318
|
backgroundImageSrc?: string;
|
|
319
|
+
backgroundImageScale?: number;
|
|
319
320
|
backgroundDithered?: boolean;
|
|
320
321
|
projectionSpeed?: number;
|
|
321
322
|
beamSpeed?: number;
|
|
@@ -331,14 +332,16 @@ type DitherStreamProps = {
|
|
|
331
332
|
pathAngle?: number;
|
|
332
333
|
godrayIntensity?: number;
|
|
333
334
|
};
|
|
334
|
-
declare function DitherStream({ width, height, className, style, children, imageTextureSrc, backgroundImageSrc, backgroundDithered, projectionSpeed, beamSpeed, beamDirection, beamColor, beamCenter, beamRadius, beamScale, beamPathShape, beamCustomPathPoints, beamEnabled, pathPos, pathAngle, godrayIntensity, }: DitherStreamProps): react_jsx_runtime.JSX.Element;
|
|
335
|
+
declare function DitherStream({ width, height, className, style, children, imageTextureSrc, backgroundImageSrc, backgroundImageScale, backgroundDithered, projectionSpeed, beamSpeed, beamDirection, beamColor, beamCenter, beamRadius, beamScale, beamPathShape, beamCustomPathPoints, beamEnabled, pathPos, pathAngle, godrayIntensity, }: DitherStreamProps): react_jsx_runtime.JSX.Element;
|
|
335
336
|
|
|
336
337
|
type DitherStreamPathDrawerProps = {
|
|
337
338
|
enabled: boolean;
|
|
338
339
|
beamColor?: string;
|
|
339
340
|
backgroundImageSrc?: string;
|
|
341
|
+
backgroundImageScale?: number;
|
|
340
342
|
onCommit: (points: Array<[number, number]>) => void;
|
|
343
|
+
onCancel?: () => void;
|
|
341
344
|
};
|
|
342
|
-
declare function DitherStreamPathDrawer({ enabled, beamColor, backgroundImageSrc, onCommit, }: DitherStreamPathDrawerProps): react_jsx_runtime.JSX.Element | null;
|
|
345
|
+
declare function DitherStreamPathDrawer({ enabled, beamColor, backgroundImageSrc, backgroundImageScale, onCommit, onCancel, }: DitherStreamPathDrawerProps): react_jsx_runtime.JSX.Element | null;
|
|
343
346
|
|
|
344
347
|
export { AnimatedDrawingSVG, type CombineShaderMode, DitherPulseRing, DitherStream, DitherStreamPathDrawer, 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
|
@@ -316,6 +316,7 @@ type DitherStreamProps = {
|
|
|
316
316
|
children?: React.ReactNode;
|
|
317
317
|
imageTextureSrc?: string;
|
|
318
318
|
backgroundImageSrc?: string;
|
|
319
|
+
backgroundImageScale?: number;
|
|
319
320
|
backgroundDithered?: boolean;
|
|
320
321
|
projectionSpeed?: number;
|
|
321
322
|
beamSpeed?: number;
|
|
@@ -331,14 +332,16 @@ type DitherStreamProps = {
|
|
|
331
332
|
pathAngle?: number;
|
|
332
333
|
godrayIntensity?: number;
|
|
333
334
|
};
|
|
334
|
-
declare function DitherStream({ width, height, className, style, children, imageTextureSrc, backgroundImageSrc, backgroundDithered, projectionSpeed, beamSpeed, beamDirection, beamColor, beamCenter, beamRadius, beamScale, beamPathShape, beamCustomPathPoints, beamEnabled, pathPos, pathAngle, godrayIntensity, }: DitherStreamProps): react_jsx_runtime.JSX.Element;
|
|
335
|
+
declare function DitherStream({ width, height, className, style, children, imageTextureSrc, backgroundImageSrc, backgroundImageScale, backgroundDithered, projectionSpeed, beamSpeed, beamDirection, beamColor, beamCenter, beamRadius, beamScale, beamPathShape, beamCustomPathPoints, beamEnabled, pathPos, pathAngle, godrayIntensity, }: DitherStreamProps): react_jsx_runtime.JSX.Element;
|
|
335
336
|
|
|
336
337
|
type DitherStreamPathDrawerProps = {
|
|
337
338
|
enabled: boolean;
|
|
338
339
|
beamColor?: string;
|
|
339
340
|
backgroundImageSrc?: string;
|
|
341
|
+
backgroundImageScale?: number;
|
|
340
342
|
onCommit: (points: Array<[number, number]>) => void;
|
|
343
|
+
onCancel?: () => void;
|
|
341
344
|
};
|
|
342
|
-
declare function DitherStreamPathDrawer({ enabled, beamColor, backgroundImageSrc, onCommit, }: DitherStreamPathDrawerProps): react_jsx_runtime.JSX.Element | null;
|
|
345
|
+
declare function DitherStreamPathDrawer({ enabled, beamColor, backgroundImageSrc, backgroundImageScale, onCommit, onCancel, }: DitherStreamPathDrawerProps): react_jsx_runtime.JSX.Element | null;
|
|
343
346
|
|
|
344
347
|
export { AnimatedDrawingSVG, type CombineShaderMode, DitherPulseRing, DitherStream, DitherStreamPathDrawer, 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
|
@@ -5261,7 +5261,7 @@ var import_react24 = require("react");
|
|
|
5261
5261
|
var THREE22 = __toESM(require("three"));
|
|
5262
5262
|
|
|
5263
5263
|
// src/shaders/dither-godray-dither/fragment.glsl
|
|
5264
|
-
var fragment_default16 = "precision highp float;\n\nin vec2 vTextureCoord;\n\nuniform sampler2D uTexture;\nuniform sampler2D uBackgroundTexture;\nuniform float uHasBackground;\nuniform float uDitherBackground;\nuniform float uBackgroundAspect;\nuniform vec2 uResolution;\n\nout vec4 fragColor;\n\n// Object-cover UV: fills the canvas, cropping the image centered at (0.5, 0.5).\nvec2 coverUV(vec2 uv, float imageAspect, float canvasAspect) {\n vec2 offset = uv - 0.5;\n if (imageAspect > canvasAspect) {\n offset.x *= canvasAspect / imageAspect;\n } else {\n offset.y *= imageAspect / canvasAspect;\n }\n return offset + 0.5;\n}\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 // Foreground dither\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\n // Background \u2014 sampled with cover UVs\n vec2 bgUV = coverUV(uv, uBackgroundAspect, ar);\n vec2 bgCellUV = coverUV(pixelUv, uBackgroundAspect, ar);\n\n float beamReveal = smoothstep(0.4, 0.75, lum);\n vec3 bgRaw = texture(uBackgroundTexture, bgUV).rgb;\n vec3 bgRawColor = mix(vec3(0.0), bgRaw, uHasBackground * beamReveal);\n\n // Background content at cell-snapped UV (pixelated)\n vec3 bgCell = texture(uBackgroundTexture, bgCellUV).rgb;\n\n // Dithered mode: background image multiplies the beam tint.\n // bgCell * 0.6 + 0.4 maps [0,1] \u2192 [0.4, 1.0], so:\n // bright bg \u2192 tint \xD7 1.0 (same intensity as raw mode)\n // dark bg \u2192 tint \xD7 0.4 (dark areas of image dim the beam)\n // The beam's hue is always preserved; the background shows as luminance texture.\n vec3 bgCell3 = bgCell * 0.6 + 0.4;\n vec3 bgFiltered = tint * bgCell3;\n vec3 bgDotContent = mix(tint, bgFiltered, uHasBackground);\n vec3 dotColor = mix(tint, bgDotContent, uDitherBackground);\n\n // Gap (between dots): raw bg reveal in raw mode, black in dithered mode.\n vec3 gapColor = bgRawColor * (1.0 - uDitherBackground);\n\n fragColor = vec4(mix(gapColor, dotColor, alpha), 1.0);\n}\n";
|
|
5264
|
+
var fragment_default16 = "precision highp float;\n\nin vec2 vTextureCoord;\n\nuniform sampler2D uTexture;\nuniform sampler2D uBackgroundTexture;\nuniform float uHasBackground;\nuniform float uDitherBackground;\nuniform float uBackgroundAspect;\nuniform float uBackgroundScale;\nuniform vec2 uResolution;\n\nout vec4 fragColor;\n\n// Object-cover UV: fills the canvas, cropping the image centered at (0.5, 0.5).\n// scale > 1 zooms in, scale < 1 zooms out.\nvec2 coverUV(vec2 uv, float imageAspect, float canvasAspect, float scale) {\n vec2 offset = uv - 0.5;\n if (imageAspect > canvasAspect) {\n offset.x *= canvasAspect / imageAspect;\n } else {\n offset.y *= imageAspect / canvasAspect;\n }\n return (offset / scale) + 0.5;\n}\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 // Foreground dither\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\n // Background \u2014 sampled with cover UVs\n vec2 bgUV = coverUV(uv, uBackgroundAspect, ar, uBackgroundScale);\n vec2 bgCellUV = coverUV(pixelUv, uBackgroundAspect, ar, uBackgroundScale);\n\n float beamReveal = smoothstep(0.4, 0.75, lum);\n vec3 bgRaw = texture(uBackgroundTexture, bgUV).rgb;\n vec3 bgRawColor = mix(vec3(0.0), bgRaw, uHasBackground * beamReveal);\n\n // Background content at cell-snapped UV (pixelated)\n vec3 bgCell = texture(uBackgroundTexture, bgCellUV).rgb;\n\n // Dithered mode: background image multiplies the beam tint.\n // bgCell * 0.6 + 0.4 maps [0,1] \u2192 [0.4, 1.0], so:\n // bright bg \u2192 tint \xD7 1.0 (same intensity as raw mode)\n // dark bg \u2192 tint \xD7 0.4 (dark areas of image dim the beam)\n // The beam's hue is always preserved; the background shows as luminance texture.\n vec3 bgCell3 = bgCell * 0.6 + 0.4;\n vec3 bgFiltered = tint * bgCell3;\n vec3 bgDotContent = mix(tint, bgFiltered, uHasBackground);\n vec3 dotColor = mix(tint, bgDotContent, uDitherBackground);\n\n // Gap (between dots): raw bg reveal in raw mode, black in dithered mode.\n vec3 gapColor = bgRawColor * (1.0 - uDitherBackground);\n\n fragColor = vec4(mix(gapColor, dotColor, alpha), 1.0);\n}\n";
|
|
5265
5265
|
|
|
5266
5266
|
// src/shaders/dither-godray-dither/vertex.glsl
|
|
5267
5267
|
var vertex_default15 = "out vec2 vTextureCoord;\n\nvoid main() {\n vTextureCoord = uv;\n gl_Position = vec4(position, 1.0);\n}\n";
|
|
@@ -5271,6 +5271,7 @@ var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
|
5271
5271
|
function DitherStreamDitherPass({
|
|
5272
5272
|
inputTexture = null,
|
|
5273
5273
|
backgroundImageSrc,
|
|
5274
|
+
backgroundImageScale = 1,
|
|
5274
5275
|
ditherBackground = true,
|
|
5275
5276
|
target = null,
|
|
5276
5277
|
clear = true,
|
|
@@ -5326,6 +5327,7 @@ function DitherStreamDitherPass({
|
|
|
5326
5327
|
uHasBackground: { value: 0 },
|
|
5327
5328
|
uDitherBackground: { value: 1 },
|
|
5328
5329
|
uBackgroundAspect: { value: 1 },
|
|
5330
|
+
uBackgroundScale: { value: 1 },
|
|
5329
5331
|
uResolution: { value: new THREE22.Vector2(1, 1) }
|
|
5330
5332
|
}),
|
|
5331
5333
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -5336,6 +5338,7 @@ function DitherStreamDitherPass({
|
|
|
5336
5338
|
uniforms.uHasBackground.value = backgroundTexture ? 1 : 0;
|
|
5337
5339
|
uniforms.uDitherBackground.value = ditherBackground ? 1 : 0;
|
|
5338
5340
|
uniforms.uBackgroundAspect.value = backgroundAspect;
|
|
5341
|
+
uniforms.uBackgroundScale.value = backgroundImageScale;
|
|
5339
5342
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
5340
5343
|
ShaderPass,
|
|
5341
5344
|
{
|
|
@@ -5597,6 +5600,7 @@ function DitherStream({
|
|
|
5597
5600
|
children,
|
|
5598
5601
|
imageTextureSrc,
|
|
5599
5602
|
backgroundImageSrc,
|
|
5603
|
+
backgroundImageScale = 1,
|
|
5600
5604
|
backgroundDithered = true,
|
|
5601
5605
|
projectionSpeed = 0.05,
|
|
5602
5606
|
beamSpeed = 0.1,
|
|
@@ -5660,7 +5664,11 @@ function DitherStream({
|
|
|
5660
5664
|
},
|
|
5661
5665
|
{
|
|
5662
5666
|
component: DitherStreamDitherPass,
|
|
5663
|
-
props: {
|
|
5667
|
+
props: {
|
|
5668
|
+
backgroundImageSrc,
|
|
5669
|
+
backgroundImageScale,
|
|
5670
|
+
ditherBackground: backgroundDithered
|
|
5671
|
+
}
|
|
5664
5672
|
},
|
|
5665
5673
|
{
|
|
5666
5674
|
component: DitherStreamGodRaysPass,
|
|
@@ -5729,7 +5737,9 @@ function DitherStreamPathDrawer({
|
|
|
5729
5737
|
enabled,
|
|
5730
5738
|
beamColor = "#aab0f0",
|
|
5731
5739
|
backgroundImageSrc,
|
|
5732
|
-
|
|
5740
|
+
backgroundImageScale = 1,
|
|
5741
|
+
onCommit,
|
|
5742
|
+
onCancel
|
|
5733
5743
|
}) {
|
|
5734
5744
|
const overlayRef = (0, import_react28.useRef)(null);
|
|
5735
5745
|
const canvasRef = (0, import_react28.useRef)(null);
|
|
@@ -5875,6 +5885,25 @@ function DitherStreamPathDrawer({
|
|
|
5875
5885
|
},
|
|
5876
5886
|
[updatePoints]
|
|
5877
5887
|
);
|
|
5888
|
+
(0, import_react28.useEffect)(() => {
|
|
5889
|
+
if (!enabled) return;
|
|
5890
|
+
const handleKeyDown = (event) => {
|
|
5891
|
+
if (event.key !== "Escape") return;
|
|
5892
|
+
drawingRef.current = false;
|
|
5893
|
+
pointerIdRef.current = null;
|
|
5894
|
+
lastPixelPointRef.current = null;
|
|
5895
|
+
if (commitTimeoutRef.current) {
|
|
5896
|
+
clearTimeout(commitTimeoutRef.current);
|
|
5897
|
+
commitTimeoutRef.current = null;
|
|
5898
|
+
}
|
|
5899
|
+
updatePoints([]);
|
|
5900
|
+
clearCanvas();
|
|
5901
|
+
setCursor(null);
|
|
5902
|
+
onCancel?.();
|
|
5903
|
+
};
|
|
5904
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
5905
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
5906
|
+
}, [enabled, clearCanvas, updatePoints, onCancel]);
|
|
5878
5907
|
(0, import_react28.useEffect)(() => {
|
|
5879
5908
|
if (enabled) return;
|
|
5880
5909
|
drawingRef.current = false;
|
|
@@ -5916,7 +5945,7 @@ function DitherStreamPathDrawer({
|
|
|
5916
5945
|
"div",
|
|
5917
5946
|
{
|
|
5918
5947
|
ref: overlayRef,
|
|
5919
|
-
className: "absolute inset-0 z-20 cursor-crosshair touch-none",
|
|
5948
|
+
className: "absolute inset-0 z-20 cursor-crosshair touch-none overflow-hidden",
|
|
5920
5949
|
style: {
|
|
5921
5950
|
background: backgroundImageSrc ? void 0 : "radial-gradient(circle at center, rgba(102,110,164,0.10), rgba(7,9,17,0.72))",
|
|
5922
5951
|
border: "1px dashed rgba(188,196,246,0.35)"
|
|
@@ -5984,6 +6013,7 @@ function DitherStreamPathDrawer({
|
|
|
5984
6013
|
{
|
|
5985
6014
|
src: backgroundImageSrc,
|
|
5986
6015
|
className: "pointer-events-none absolute inset-0 h-full w-full object-cover",
|
|
6016
|
+
style: { transform: `scale(${backgroundImageScale})` },
|
|
5987
6017
|
alt: "",
|
|
5988
6018
|
"aria-hidden": true
|
|
5989
6019
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -5246,7 +5246,7 @@ import { useEffect as useEffect17, useMemo as useMemo17, useState as useState4 }
|
|
|
5246
5246
|
import * as THREE22 from "three";
|
|
5247
5247
|
|
|
5248
5248
|
// src/shaders/dither-godray-dither/fragment.glsl
|
|
5249
|
-
var fragment_default16 = "precision highp float;\n\nin vec2 vTextureCoord;\n\nuniform sampler2D uTexture;\nuniform sampler2D uBackgroundTexture;\nuniform float uHasBackground;\nuniform float uDitherBackground;\nuniform float uBackgroundAspect;\nuniform vec2 uResolution;\n\nout vec4 fragColor;\n\n// Object-cover UV: fills the canvas, cropping the image centered at (0.5, 0.5).\nvec2 coverUV(vec2 uv, float imageAspect, float canvasAspect) {\n vec2 offset = uv - 0.5;\n if (imageAspect > canvasAspect) {\n offset.x *= canvasAspect / imageAspect;\n } else {\n offset.y *= imageAspect / canvasAspect;\n }\n return offset + 0.5;\n}\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 // Foreground dither\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\n // Background \u2014 sampled with cover UVs\n vec2 bgUV = coverUV(uv, uBackgroundAspect, ar);\n vec2 bgCellUV = coverUV(pixelUv, uBackgroundAspect, ar);\n\n float beamReveal = smoothstep(0.4, 0.75, lum);\n vec3 bgRaw = texture(uBackgroundTexture, bgUV).rgb;\n vec3 bgRawColor = mix(vec3(0.0), bgRaw, uHasBackground * beamReveal);\n\n // Background content at cell-snapped UV (pixelated)\n vec3 bgCell = texture(uBackgroundTexture, bgCellUV).rgb;\n\n // Dithered mode: background image multiplies the beam tint.\n // bgCell * 0.6 + 0.4 maps [0,1] \u2192 [0.4, 1.0], so:\n // bright bg \u2192 tint \xD7 1.0 (same intensity as raw mode)\n // dark bg \u2192 tint \xD7 0.4 (dark areas of image dim the beam)\n // The beam's hue is always preserved; the background shows as luminance texture.\n vec3 bgCell3 = bgCell * 0.6 + 0.4;\n vec3 bgFiltered = tint * bgCell3;\n vec3 bgDotContent = mix(tint, bgFiltered, uHasBackground);\n vec3 dotColor = mix(tint, bgDotContent, uDitherBackground);\n\n // Gap (between dots): raw bg reveal in raw mode, black in dithered mode.\n vec3 gapColor = bgRawColor * (1.0 - uDitherBackground);\n\n fragColor = vec4(mix(gapColor, dotColor, alpha), 1.0);\n}\n";
|
|
5249
|
+
var fragment_default16 = "precision highp float;\n\nin vec2 vTextureCoord;\n\nuniform sampler2D uTexture;\nuniform sampler2D uBackgroundTexture;\nuniform float uHasBackground;\nuniform float uDitherBackground;\nuniform float uBackgroundAspect;\nuniform float uBackgroundScale;\nuniform vec2 uResolution;\n\nout vec4 fragColor;\n\n// Object-cover UV: fills the canvas, cropping the image centered at (0.5, 0.5).\n// scale > 1 zooms in, scale < 1 zooms out.\nvec2 coverUV(vec2 uv, float imageAspect, float canvasAspect, float scale) {\n vec2 offset = uv - 0.5;\n if (imageAspect > canvasAspect) {\n offset.x *= canvasAspect / imageAspect;\n } else {\n offset.y *= imageAspect / canvasAspect;\n }\n return (offset / scale) + 0.5;\n}\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 // Foreground dither\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\n // Background \u2014 sampled with cover UVs\n vec2 bgUV = coverUV(uv, uBackgroundAspect, ar, uBackgroundScale);\n vec2 bgCellUV = coverUV(pixelUv, uBackgroundAspect, ar, uBackgroundScale);\n\n float beamReveal = smoothstep(0.4, 0.75, lum);\n vec3 bgRaw = texture(uBackgroundTexture, bgUV).rgb;\n vec3 bgRawColor = mix(vec3(0.0), bgRaw, uHasBackground * beamReveal);\n\n // Background content at cell-snapped UV (pixelated)\n vec3 bgCell = texture(uBackgroundTexture, bgCellUV).rgb;\n\n // Dithered mode: background image multiplies the beam tint.\n // bgCell * 0.6 + 0.4 maps [0,1] \u2192 [0.4, 1.0], so:\n // bright bg \u2192 tint \xD7 1.0 (same intensity as raw mode)\n // dark bg \u2192 tint \xD7 0.4 (dark areas of image dim the beam)\n // The beam's hue is always preserved; the background shows as luminance texture.\n vec3 bgCell3 = bgCell * 0.6 + 0.4;\n vec3 bgFiltered = tint * bgCell3;\n vec3 bgDotContent = mix(tint, bgFiltered, uHasBackground);\n vec3 dotColor = mix(tint, bgDotContent, uDitherBackground);\n\n // Gap (between dots): raw bg reveal in raw mode, black in dithered mode.\n vec3 gapColor = bgRawColor * (1.0 - uDitherBackground);\n\n fragColor = vec4(mix(gapColor, dotColor, alpha), 1.0);\n}\n";
|
|
5250
5250
|
|
|
5251
5251
|
// src/shaders/dither-godray-dither/vertex.glsl
|
|
5252
5252
|
var vertex_default15 = "out vec2 vTextureCoord;\n\nvoid main() {\n vTextureCoord = uv;\n gl_Position = vec4(position, 1.0);\n}\n";
|
|
@@ -5256,6 +5256,7 @@ import { jsx as jsx25 } from "react/jsx-runtime";
|
|
|
5256
5256
|
function DitherStreamDitherPass({
|
|
5257
5257
|
inputTexture = null,
|
|
5258
5258
|
backgroundImageSrc,
|
|
5259
|
+
backgroundImageScale = 1,
|
|
5259
5260
|
ditherBackground = true,
|
|
5260
5261
|
target = null,
|
|
5261
5262
|
clear = true,
|
|
@@ -5311,6 +5312,7 @@ function DitherStreamDitherPass({
|
|
|
5311
5312
|
uHasBackground: { value: 0 },
|
|
5312
5313
|
uDitherBackground: { value: 1 },
|
|
5313
5314
|
uBackgroundAspect: { value: 1 },
|
|
5315
|
+
uBackgroundScale: { value: 1 },
|
|
5314
5316
|
uResolution: { value: new THREE22.Vector2(1, 1) }
|
|
5315
5317
|
}),
|
|
5316
5318
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -5321,6 +5323,7 @@ function DitherStreamDitherPass({
|
|
|
5321
5323
|
uniforms.uHasBackground.value = backgroundTexture ? 1 : 0;
|
|
5322
5324
|
uniforms.uDitherBackground.value = ditherBackground ? 1 : 0;
|
|
5323
5325
|
uniforms.uBackgroundAspect.value = backgroundAspect;
|
|
5326
|
+
uniforms.uBackgroundScale.value = backgroundImageScale;
|
|
5324
5327
|
return /* @__PURE__ */ jsx25(
|
|
5325
5328
|
ShaderPass,
|
|
5326
5329
|
{
|
|
@@ -5582,6 +5585,7 @@ function DitherStream({
|
|
|
5582
5585
|
children,
|
|
5583
5586
|
imageTextureSrc,
|
|
5584
5587
|
backgroundImageSrc,
|
|
5588
|
+
backgroundImageScale = 1,
|
|
5585
5589
|
backgroundDithered = true,
|
|
5586
5590
|
projectionSpeed = 0.05,
|
|
5587
5591
|
beamSpeed = 0.1,
|
|
@@ -5645,7 +5649,11 @@ function DitherStream({
|
|
|
5645
5649
|
},
|
|
5646
5650
|
{
|
|
5647
5651
|
component: DitherStreamDitherPass,
|
|
5648
|
-
props: {
|
|
5652
|
+
props: {
|
|
5653
|
+
backgroundImageSrc,
|
|
5654
|
+
backgroundImageScale,
|
|
5655
|
+
ditherBackground: backgroundDithered
|
|
5656
|
+
}
|
|
5649
5657
|
},
|
|
5650
5658
|
{
|
|
5651
5659
|
component: DitherStreamGodRaysPass,
|
|
@@ -5719,7 +5727,9 @@ function DitherStreamPathDrawer({
|
|
|
5719
5727
|
enabled,
|
|
5720
5728
|
beamColor = "#aab0f0",
|
|
5721
5729
|
backgroundImageSrc,
|
|
5722
|
-
|
|
5730
|
+
backgroundImageScale = 1,
|
|
5731
|
+
onCommit,
|
|
5732
|
+
onCancel
|
|
5723
5733
|
}) {
|
|
5724
5734
|
const overlayRef = useRef13(null);
|
|
5725
5735
|
const canvasRef = useRef13(null);
|
|
@@ -5865,6 +5875,25 @@ function DitherStreamPathDrawer({
|
|
|
5865
5875
|
},
|
|
5866
5876
|
[updatePoints]
|
|
5867
5877
|
);
|
|
5878
|
+
useEffect21(() => {
|
|
5879
|
+
if (!enabled) return;
|
|
5880
|
+
const handleKeyDown = (event) => {
|
|
5881
|
+
if (event.key !== "Escape") return;
|
|
5882
|
+
drawingRef.current = false;
|
|
5883
|
+
pointerIdRef.current = null;
|
|
5884
|
+
lastPixelPointRef.current = null;
|
|
5885
|
+
if (commitTimeoutRef.current) {
|
|
5886
|
+
clearTimeout(commitTimeoutRef.current);
|
|
5887
|
+
commitTimeoutRef.current = null;
|
|
5888
|
+
}
|
|
5889
|
+
updatePoints([]);
|
|
5890
|
+
clearCanvas();
|
|
5891
|
+
setCursor(null);
|
|
5892
|
+
onCancel?.();
|
|
5893
|
+
};
|
|
5894
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
5895
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
5896
|
+
}, [enabled, clearCanvas, updatePoints, onCancel]);
|
|
5868
5897
|
useEffect21(() => {
|
|
5869
5898
|
if (enabled) return;
|
|
5870
5899
|
drawingRef.current = false;
|
|
@@ -5906,7 +5935,7 @@ function DitherStreamPathDrawer({
|
|
|
5906
5935
|
"div",
|
|
5907
5936
|
{
|
|
5908
5937
|
ref: overlayRef,
|
|
5909
|
-
className: "absolute inset-0 z-20 cursor-crosshair touch-none",
|
|
5938
|
+
className: "absolute inset-0 z-20 cursor-crosshair touch-none overflow-hidden",
|
|
5910
5939
|
style: {
|
|
5911
5940
|
background: backgroundImageSrc ? void 0 : "radial-gradient(circle at center, rgba(102,110,164,0.10), rgba(7,9,17,0.72))",
|
|
5912
5941
|
border: "1px dashed rgba(188,196,246,0.35)"
|
|
@@ -5974,6 +6003,7 @@ function DitherStreamPathDrawer({
|
|
|
5974
6003
|
{
|
|
5975
6004
|
src: backgroundImageSrc,
|
|
5976
6005
|
className: "pointer-events-none absolute inset-0 h-full w-full object-cover",
|
|
6006
|
+
style: { transform: `scale(${backgroundImageScale})` },
|
|
5977
6007
|
alt: "",
|
|
5978
6008
|
"aria-hidden": true
|
|
5979
6009
|
}
|