@react-three/postprocessing 3.0.5 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -7
- package/dist/EffectComposer.d.ts +9 -2
- package/dist/EffectGroup.d.ts +9 -0
- package/dist/createEffectComponent.d.ts +30 -0
- package/dist/effects/ASCII.d.ts +28 -7
- package/dist/effects/Autofocus.d.ts +1 -1
- package/dist/effects/Bloom.d.ts +9 -1
- package/dist/effects/BrightnessContrast.d.ts +14 -1
- package/dist/effects/ChromaticAberration.d.ts +26 -3
- package/dist/effects/ColorAverage.d.ts +7 -7
- package/dist/effects/ColorDepth.d.ts +7 -1
- package/dist/effects/Depth.d.ts +12 -1
- package/dist/effects/DotScreen.d.ts +14 -1
- package/dist/effects/FXAA.d.ts +10 -1
- package/dist/effects/Glitch.d.ts +16 -11
- package/dist/effects/GodRays.d.ts +1 -1
- package/dist/effects/Grid.d.ts +7 -6
- package/dist/effects/HueSaturation.d.ts +14 -1
- package/dist/effects/LUT.d.ts +1 -1
- package/dist/effects/LensFlare.d.ts +46 -5
- package/dist/effects/Noise.d.ts +7 -1
- package/dist/effects/Outline.d.ts +6 -3
- package/dist/effects/Pixelation.d.ts +1 -1
- package/dist/effects/Ramp.d.ts +58 -6
- package/dist/effects/SMAA.d.ts +9 -1
- package/dist/effects/SSAO.d.ts +1 -1
- package/dist/effects/ScanlineEffect.d.ts +12 -1
- package/dist/effects/SelectiveBloom.d.ts +1 -1
- package/dist/effects/Sepia.d.ts +12 -1
- package/dist/effects/ShockWave.d.ts +11 -1
- package/dist/effects/Texture.d.ts +4 -4
- package/dist/effects/TiltShift.d.ts +9 -1
- package/dist/effects/TiltShift2.d.ts +44 -4
- package/dist/effects/ToneMapping.d.ts +9 -3
- package/dist/effects/Vignette.d.ts +18 -1
- package/dist/effects/Water.d.ts +17 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +2205 -713
- package/dist/index.js.map +1 -1
- package/dist/passes/DepthPicking.d.ts +11 -0
- package/dist/{effects → passes}/N8AO.d.ts +2 -1
- package/dist/util.d.ts +9 -15
- package/dist/wrapEffect.d.ts +3 -3
- package/package.json +6 -5
- package/src/EffectComposer.tsx +143 -42
- package/src/EffectGroup.tsx +74 -0
- package/src/createEffectComponent.tsx +71 -0
- package/src/effects/ASCII.tsx +75 -28
- package/src/effects/Autofocus.tsx +24 -77
- package/src/effects/Bloom.tsx +32 -4
- package/src/effects/BrightnessContrast.tsx +5 -2
- package/src/effects/ChromaticAberration.tsx +13 -21
- package/src/effects/ColorAverage.tsx +3 -16
- package/src/effects/ColorDepth.tsx +23 -2
- package/src/effects/Depth.tsx +4 -2
- package/src/effects/DepthOfField.tsx +48 -26
- package/src/effects/DotScreen.tsx +5 -2
- package/src/effects/FXAA.tsx +4 -2
- package/src/effects/Glitch.tsx +26 -31
- package/src/effects/GodRays.tsx +90 -6
- package/src/effects/Grid.tsx +17 -18
- package/src/effects/HueSaturation.tsx +5 -2
- package/src/effects/LUT.tsx +9 -11
- package/src/effects/LensFlare.tsx +209 -55
- package/src/effects/Noise.tsx +14 -2
- package/src/effects/Outline.tsx +55 -56
- package/src/effects/Pixelation.tsx +11 -8
- package/src/effects/Ramp.tsx +96 -7
- package/src/effects/SMAA.tsx +18 -2
- package/src/effects/SSAO.tsx +130 -22
- package/src/effects/ScanlineEffect.tsx +6 -6
- package/src/effects/SelectiveBloom.tsx +26 -44
- package/src/effects/Sepia.tsx +4 -2
- package/src/effects/ShockWave.tsx +30 -2
- package/src/effects/Texture.tsx +10 -9
- package/src/effects/TiltShift.tsx +30 -2
- package/src/effects/TiltShift2.tsx +72 -6
- package/src/effects/ToneMapping.tsx +16 -3
- package/src/effects/Vignette.tsx +5 -2
- package/src/effects/Water.tsx +21 -6
- package/src/index.ts +4 -2
- package/src/passes/DepthPicking.tsx +63 -0
- package/src/{effects → passes}/N8AO.tsx +28 -4
- package/src/tests/Autofocus.test.tsx +38 -0
- package/src/tests/Bloom.test.tsx +76 -0
- package/src/tests/ChromaticAberration.test.tsx +50 -0
- package/src/tests/ColorDepth.test.tsx +71 -0
- package/src/tests/DepthOfField.test.tsx +130 -0
- package/src/tests/DepthPicking.test.tsx +250 -0
- package/src/tests/EffectComposer.test.tsx +501 -8
- package/src/tests/EffectGroup.test.tsx +337 -0
- package/src/tests/Glitch.test.tsx +56 -0
- package/src/tests/GodRays.test.tsx +101 -0
- package/src/tests/Grid.test.tsx +34 -0
- package/src/tests/LUT.test.tsx +64 -0
- package/src/tests/N8AO.test.tsx +92 -0
- package/src/tests/Outline.test.tsx +122 -0
- package/src/tests/SSAO.test.tsx +140 -0
- package/src/tests/SelectiveBloom.test.tsx +48 -0
- package/src/tests/ShockWave.test.tsx +95 -0
- package/src/tests/TiltShift.test.tsx +76 -0
- package/src/tests/createEffectComponent.test.tsx +286 -0
- package/src/tests/effects.smoke.test.tsx +46 -42
- package/src/util.tsx +148 -23
- package/src/wrapEffect.tsx +3 -2
- package/dist/tests/test-utils.d.ts +0 -12
package/dist/index.js
CHANGED
|
@@ -1,859 +1,2351 @@
|
|
|
1
|
-
import { applyProps
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { easing
|
|
7
|
-
import { N8AOPostPass
|
|
1
|
+
import { applyProps, createPortal, extend, useFrame, useLoader, useThree } from "@react-three/fiber";
|
|
2
|
+
import { createContext, memo, use, useCallback, useContext, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState } from "react";
|
|
3
|
+
import { CanvasTexture, Color, HalfFloatType, Mesh, NearestFilter, NoToneMapping, RepeatWrapping, SRGBColorSpace, Texture as Texture$1, TextureLoader, Uniform, Vector2, Vector3 } from "three";
|
|
4
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { BloomEffect, BrightnessContrastEffect, ChromaticAberrationEffect, ColorAverageEffect, ColorDepthEffect, CopyPass, DepthDownsamplingPass, DepthEffect, DepthOfFieldEffect, DepthPickingPass, DotScreenEffect, Effect, EffectComposer as EffectComposer$1, EffectPass, FXAAEffect, GlitchEffect, GlitchMode, GodRaysEffect, GridEffect, HueSaturationEffect, LUT3DEffect, MaskFunction, NoiseEffect, NormalPass, OutlineEffect, Pass, PixelationEffect, RenderPass, SMAAEffect, SSAOEffect, ScanlineEffect, SelectiveBloomEffect, SepiaEffect, ShockWaveEffect, TextureEffect, TiltShiftEffect as TiltShiftEffect$1, ToneMappingEffect, VignetteEffect } from "postprocessing";
|
|
6
|
+
import { easing } from "maath";
|
|
7
|
+
import { N8AOPostPass } from "n8ao";
|
|
8
|
+
//#region src/Selection.tsx
|
|
9
|
+
var selectionContext = /* @__PURE__ */ createContext(null);
|
|
10
|
+
function Selection({ children, enabled = true }) {
|
|
11
|
+
const [selected, select] = useState([]);
|
|
12
|
+
const value = useMemo(() => ({
|
|
13
|
+
selected,
|
|
14
|
+
select,
|
|
15
|
+
enabled
|
|
16
|
+
}), [
|
|
17
|
+
selected,
|
|
18
|
+
select,
|
|
19
|
+
enabled
|
|
20
|
+
]);
|
|
21
|
+
return /* @__PURE__ */ jsx(selectionContext.Provider, {
|
|
22
|
+
value,
|
|
23
|
+
children
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function isSelectable(object) {
|
|
27
|
+
const o = object;
|
|
28
|
+
return !!(o.isMesh || o.isLine || o.isPoints);
|
|
29
|
+
}
|
|
30
|
+
function Select({ enabled = false, children, ...props }) {
|
|
31
|
+
const group = useRef(null);
|
|
32
|
+
const select = use(selectionContext)?.select;
|
|
33
|
+
const claimed = useRef([]);
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (!select) return;
|
|
36
|
+
const current = [];
|
|
37
|
+
if (enabled) group.current.traverse((o) => {
|
|
38
|
+
if (isSelectable(o)) current.push(o);
|
|
39
|
+
});
|
|
40
|
+
const previouslyClaimed = claimed.current;
|
|
41
|
+
claimed.current = current;
|
|
42
|
+
select((prev) => {
|
|
43
|
+
const prevSet = new Set(prev);
|
|
44
|
+
const currentSet = new Set(current);
|
|
45
|
+
const toAdd = current.filter((o) => !prevSet.has(o));
|
|
46
|
+
const toRemove = previouslyClaimed.filter((o) => !currentSet.has(o) && prevSet.has(o));
|
|
47
|
+
if (!toAdd.length && !toRemove.length) return prev;
|
|
48
|
+
const toRemoveSet = toRemove.length ? new Set(toRemove) : null;
|
|
49
|
+
const kept = toRemoveSet ? prev.filter((o) => !toRemoveSet.has(o)) : prev;
|
|
50
|
+
return toAdd.length ? [...kept, ...toAdd] : kept;
|
|
51
|
+
});
|
|
52
|
+
}, [
|
|
53
|
+
enabled,
|
|
54
|
+
children,
|
|
55
|
+
select
|
|
56
|
+
]);
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
return () => {
|
|
59
|
+
if (!select || !claimed.current.length) return;
|
|
60
|
+
const stillClaimed = new Set(claimed.current);
|
|
61
|
+
select((prev) => {
|
|
62
|
+
const next = prev.filter((o) => !stillClaimed.has(o));
|
|
63
|
+
return next.length !== prev.length ? next : prev;
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
}, [select]);
|
|
67
|
+
return /* @__PURE__ */ jsx("group", {
|
|
68
|
+
ref: group,
|
|
69
|
+
...props,
|
|
70
|
+
children
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region src/util.tsx
|
|
75
|
+
var EMPTY_ARRAY = [];
|
|
76
|
+
var resolveRef = (ref) => typeof ref === "object" && ref != null && "current" in ref ? ref.current : ref;
|
|
77
|
+
function useMergeRefs(localRef, outerRef) {
|
|
78
|
+
return useCallback((instance) => {
|
|
79
|
+
localRef.current = instance;
|
|
80
|
+
if (typeof outerRef !== "function") {
|
|
81
|
+
if (outerRef) outerRef.current = instance;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const cleanup = outerRef(instance);
|
|
85
|
+
if (typeof cleanup !== "function") return;
|
|
86
|
+
return () => {
|
|
87
|
+
localRef.current = null;
|
|
88
|
+
cleanup();
|
|
89
|
+
};
|
|
90
|
+
}, [localRef, outerRef]);
|
|
91
|
+
}
|
|
92
|
+
function readGroupChildren(group, filter) {
|
|
93
|
+
const groupInstance = group.__r3f;
|
|
94
|
+
return groupInstance ? groupInstance.children.map((child) => child.object).filter(filter) : [];
|
|
95
|
+
}
|
|
96
|
+
function updateIfChanged(ref, next) {
|
|
97
|
+
const previous = ref.current;
|
|
98
|
+
if (next.length === previous.length && next.every((item, i) => item === previous[i])) return false;
|
|
99
|
+
ref.current = next;
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
function useSelectionSync(effect, selection, selectionLayer) {
|
|
103
|
+
const invalidate = useThree((state) => state.invalidate);
|
|
104
|
+
const api = use(selectionContext);
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
effect.selection.layer = selectionLayer;
|
|
107
|
+
invalidate();
|
|
108
|
+
}, [
|
|
109
|
+
effect,
|
|
110
|
+
invalidate,
|
|
111
|
+
selectionLayer
|
|
112
|
+
]);
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
if (api) return;
|
|
115
|
+
const resolved = (Array.isArray(selection) ? selection.map((o) => resolveRef(o)) : [resolveRef(selection)]).filter((o) => o != null);
|
|
116
|
+
if (!resolved.length) return;
|
|
117
|
+
effect.selection.set(resolved);
|
|
118
|
+
invalidate();
|
|
119
|
+
return () => {
|
|
120
|
+
effect.selection.clear();
|
|
121
|
+
invalidate();
|
|
122
|
+
};
|
|
123
|
+
}, [
|
|
124
|
+
effect,
|
|
125
|
+
selection,
|
|
126
|
+
api,
|
|
127
|
+
invalidate
|
|
128
|
+
]);
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
if (api && api.enabled && api.selected?.length) {
|
|
131
|
+
effect.selection.set(api.selected);
|
|
132
|
+
invalidate();
|
|
133
|
+
return () => {
|
|
134
|
+
effect.selection.clear();
|
|
135
|
+
invalidate();
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}, [
|
|
139
|
+
api,
|
|
140
|
+
effect.selection,
|
|
141
|
+
invalidate
|
|
142
|
+
]);
|
|
143
|
+
}
|
|
144
|
+
var useDispose = (instance) => {
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
return () => {
|
|
147
|
+
instance?.dispose?.();
|
|
148
|
+
};
|
|
149
|
+
}, [instance]);
|
|
150
|
+
};
|
|
151
|
+
function readPierced(instance, key) {
|
|
152
|
+
let target = instance;
|
|
153
|
+
for (const part of key.split("-")) {
|
|
154
|
+
if (target == null) return void 0;
|
|
155
|
+
target = target[part];
|
|
156
|
+
}
|
|
157
|
+
return target;
|
|
158
|
+
}
|
|
159
|
+
function applyPierced(instance, key, value) {
|
|
160
|
+
const parts = key.split("-");
|
|
161
|
+
let target = instance;
|
|
162
|
+
for (let idx = 0; idx < parts.length - 1; idx++) {
|
|
163
|
+
if (target == null) return;
|
|
164
|
+
target = target[parts[idx]];
|
|
165
|
+
}
|
|
166
|
+
if (target == null) return;
|
|
167
|
+
target[parts[parts.length - 1]] = value;
|
|
168
|
+
}
|
|
169
|
+
function useLiveDefaults(instance, values, keys, get = readPierced, set = applyPierced) {
|
|
170
|
+
const snapshotRef = useRef(null);
|
|
171
|
+
const invalidate = useThree((state) => state.invalidate);
|
|
172
|
+
useLayoutEffect(() => {
|
|
173
|
+
const resolved = resolveRef(instance);
|
|
174
|
+
if (!resolved) return;
|
|
175
|
+
if (snapshotRef.current?.instance !== resolved) snapshotRef.current = {
|
|
176
|
+
instance: resolved,
|
|
177
|
+
defaults: /* @__PURE__ */ new Map(),
|
|
178
|
+
applied: /* @__PURE__ */ new Map()
|
|
179
|
+
};
|
|
180
|
+
const { defaults, applied } = snapshotRef.current;
|
|
181
|
+
let changed = false;
|
|
182
|
+
for (const key of keys) {
|
|
183
|
+
if (!defaults.has(key)) {
|
|
184
|
+
const current = get(resolved, key);
|
|
185
|
+
defaults.set(key, current);
|
|
186
|
+
applied.set(key, current);
|
|
187
|
+
}
|
|
188
|
+
const next = values[key] !== void 0 ? values[key] : defaults.get(key);
|
|
189
|
+
if (Object.is(applied.get(key), next)) continue;
|
|
190
|
+
set(resolved, key, next);
|
|
191
|
+
applied.set(key, next);
|
|
192
|
+
changed = true;
|
|
193
|
+
}
|
|
194
|
+
if (changed) invalidate();
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
var useVector2 = (props, key) => {
|
|
198
|
+
const value = props[key];
|
|
199
|
+
return useMemo(() => {
|
|
200
|
+
if (typeof value === "number") return new Vector2(value, value);
|
|
201
|
+
if (value instanceof Vector2) return value;
|
|
202
|
+
if (value) return new Vector2(...value);
|
|
203
|
+
return new Vector2();
|
|
204
|
+
}, [value]);
|
|
205
|
+
};
|
|
206
|
+
var useVector3 = (props, key) => {
|
|
207
|
+
const value = props[key];
|
|
208
|
+
return useMemo(() => {
|
|
209
|
+
if (typeof value === "number") return new Vector3(value, value, value);
|
|
210
|
+
if (value instanceof Vector3) return value;
|
|
211
|
+
if (value) return new Vector3(...value);
|
|
212
|
+
return new Vector3();
|
|
213
|
+
}, [value]);
|
|
214
|
+
};
|
|
215
|
+
//#endregion
|
|
216
|
+
//#region src/createEffectComponent.tsx
|
|
217
|
+
var components$1 = /* @__PURE__ */ new WeakMap();
|
|
218
|
+
var i$1 = 0;
|
|
219
|
+
var BLEND_KEYS = ["blendMode-blendFunction", "blendMode-opacity-value"];
|
|
220
|
+
/**
|
|
221
|
+
* Registers `effect` as a JSX intrinsic once per class and returns a
|
|
222
|
+
* component that renders it. Everything else - construction from `args`,
|
|
223
|
+
* live prop application (with the same Color/Vector coercion and reset-
|
|
224
|
+
* to-default on removal any r3f element gets), disposal - is r3f's own
|
|
225
|
+
* reconciler, same rules as `<mesh>`/`<meshStandardMaterial>`. Only fits
|
|
226
|
+
* effects whose constructor works with zero arguments (`new Effect()`) -
|
|
227
|
+
* r3f's own reset-on-removal falls back to `0` otherwise, which is wrong
|
|
228
|
+
* for anything non-numeric. Effects that require e.g. scene/camera stay
|
|
229
|
+
* hand-rolled (see Outline.tsx, SelectiveBloom.tsx, ShockWave.tsx).
|
|
230
|
+
*
|
|
231
|
+
* `blendFunction`/`opacity` are pierced through to `blendMode-*` - every
|
|
232
|
+
* `Effect` has them on a nested `blendMode`, not on the effect itself, so a
|
|
233
|
+
* plain top-level prop would silently land on a stray, unread property.
|
|
234
|
+
* Applied via useLiveDefaults, not as plain JSX props: BlendMode's own
|
|
235
|
+
* constructor requires `blendFunction` (no default), so its constructor
|
|
236
|
+
* length isn't 0 either, and r3f's native reset-on-removal falls back to
|
|
237
|
+
* `changedProps[prop] = 0` - which is 9, not a merely
|
|
238
|
+
* "wrong" blend function but one that hides the effect entirely.
|
|
239
|
+
*/
|
|
240
|
+
function createEffectComponent(effect) {
|
|
241
|
+
return function EffectComponent({ blendFunction, opacity, ref, ...props }) {
|
|
242
|
+
let Component = components$1.get(effect);
|
|
243
|
+
if (!Component) {
|
|
244
|
+
const key = `@react-three/postprocessing/${effect.name}-${i$1++}`;
|
|
245
|
+
extend({ [key]: effect });
|
|
246
|
+
components$1.set(effect, Component = key);
|
|
247
|
+
}
|
|
248
|
+
const camera = useThree((state) => state.camera);
|
|
249
|
+
const localRef = useRef(null);
|
|
250
|
+
const setRef = useMergeRefs(localRef, ref);
|
|
251
|
+
useLiveDefaults(localRef, {
|
|
252
|
+
"blendMode-blendFunction": blendFunction,
|
|
253
|
+
"blendMode-opacity-value": opacity
|
|
254
|
+
}, BLEND_KEYS);
|
|
255
|
+
return /* @__PURE__ */ jsx(Component, {
|
|
256
|
+
ref: setRef,
|
|
257
|
+
camera,
|
|
258
|
+
...props
|
|
259
|
+
});
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
//#endregion
|
|
8
263
|
//#region src/EffectComposer.tsx
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
|
|
264
|
+
var EffectComposerContext = /* @__PURE__ */ createContext(null);
|
|
265
|
+
var isConvolution = (effect) => (effect.getAttributes() & 2) === 2;
|
|
266
|
+
function createRendererPropertyGuard(property) {
|
|
267
|
+
const refs = /* @__PURE__ */ new WeakMap();
|
|
12
268
|
return {
|
|
13
|
-
acquire(
|
|
14
|
-
|
|
15
|
-
|
|
269
|
+
acquire(gl, forcedValue) {
|
|
270
|
+
const existing = refs.get(gl);
|
|
271
|
+
if (existing) {
|
|
272
|
+
existing.count++;
|
|
273
|
+
existing.forcedValue = forcedValue;
|
|
274
|
+
} else refs.set(gl, {
|
|
16
275
|
count: 1,
|
|
17
|
-
original:
|
|
18
|
-
forcedValue
|
|
276
|
+
original: gl[property],
|
|
277
|
+
forcedValue
|
|
19
278
|
});
|
|
20
279
|
},
|
|
21
|
-
release(
|
|
22
|
-
|
|
23
|
-
|
|
280
|
+
release(gl) {
|
|
281
|
+
const entry = refs.get(gl);
|
|
282
|
+
if (!entry) return;
|
|
283
|
+
if (--entry.count <= 0) {
|
|
284
|
+
if (gl[property] === entry.forcedValue) gl[property] = entry.original;
|
|
285
|
+
refs.delete(gl);
|
|
286
|
+
}
|
|
24
287
|
}
|
|
25
288
|
};
|
|
26
289
|
}
|
|
27
|
-
var
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
290
|
+
var autoClearGuard = /* @__PURE__ */ createRendererPropertyGuard("autoClear");
|
|
291
|
+
var toneMappingGuard = /* @__PURE__ */ createRendererPropertyGuard("toneMapping");
|
|
292
|
+
var glSize = /* @__PURE__ */ new Vector2();
|
|
293
|
+
var defaultRenderPass = (scene, camera) => new RenderPass(scene, camera);
|
|
294
|
+
var generatedPasses = /* @__PURE__ */ new WeakSet();
|
|
295
|
+
var groupPasses = /* @__PURE__ */ new WeakSet();
|
|
296
|
+
function disposePassWithoutEffects(pass) {
|
|
297
|
+
if (pass instanceof EffectPass) pass.setEffects([]);
|
|
298
|
+
Pass.prototype.dispose.call(pass);
|
|
299
|
+
}
|
|
300
|
+
function disposeGeneratedPass(pass) {
|
|
301
|
+
if (!generatedPasses.has(pass)) return;
|
|
302
|
+
disposePassWithoutEffects(pass);
|
|
303
|
+
}
|
|
304
|
+
function buildPasses(nodes, camera, mergeMode) {
|
|
305
|
+
const passes = [];
|
|
306
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
307
|
+
const node = nodes[i];
|
|
308
|
+
if (node instanceof Effect) {
|
|
309
|
+
const effects = [node];
|
|
310
|
+
let hasConvolution = isConvolution(node);
|
|
311
|
+
if (mergeMode !== "none") {
|
|
312
|
+
let next;
|
|
313
|
+
while ((next = nodes[i + 1]) instanceof Effect) {
|
|
314
|
+
const nextIsConvolution = isConvolution(next);
|
|
315
|
+
if (mergeMode === "auto" && hasConvolution && nextIsConvolution) break;
|
|
316
|
+
effects.push(next);
|
|
317
|
+
hasConvolution ||= nextIsConvolution;
|
|
318
|
+
i++;
|
|
319
|
+
}
|
|
37
320
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
321
|
+
const pass = new EffectPass(camera, ...effects);
|
|
322
|
+
generatedPasses.add(pass);
|
|
323
|
+
passes.push(pass);
|
|
324
|
+
} else if (node instanceof Pass) passes.push(node);
|
|
325
|
+
}
|
|
326
|
+
return passes;
|
|
327
|
+
}
|
|
328
|
+
var EffectComposer = /* @__PURE__ */ memo(function EffectComposer({ children, camera: _camera, scene: _scene, resolutionScale, enabled = true, renderPriority = 1, autoClear = true, autoRenderToScreen = true, depthBuffer, enableNormalPass, stencilBuffer, multisampling = 8, frameBufferType = HalfFloatType, renderPass = defaultRenderPass, mergeMode = "auto", ref }) {
|
|
329
|
+
const { gl, scene: defaultScene, camera: defaultCamera } = useThree();
|
|
330
|
+
const scene = _scene || defaultScene;
|
|
331
|
+
const camera = _camera || defaultCamera;
|
|
332
|
+
gl.getSize(glSize);
|
|
333
|
+
const [composerState, setComposerState] = useState(null);
|
|
334
|
+
const [, requestRebuild] = useReducer((c) => c + 1, 0);
|
|
335
|
+
useEffect(() => {
|
|
336
|
+
autoClearGuard.acquire(gl, false);
|
|
337
|
+
const effectComposer = new EffectComposer$1(gl, {
|
|
338
|
+
depthBuffer,
|
|
339
|
+
stencilBuffer,
|
|
340
|
+
multisampling,
|
|
341
|
+
frameBufferType
|
|
52
342
|
});
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
normalPass
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
343
|
+
effectComposer.autoRenderToScreen = autoRenderToScreen;
|
|
344
|
+
effectComposer.addPass(renderPass(scene, camera));
|
|
345
|
+
let normalPass = null;
|
|
346
|
+
let downSamplingPass = null;
|
|
347
|
+
if (enableNormalPass) {
|
|
348
|
+
normalPass = new NormalPass(scene, camera);
|
|
349
|
+
normalPass.enabled = false;
|
|
350
|
+
effectComposer.addPass(normalPass);
|
|
351
|
+
if (resolutionScale !== void 0) {
|
|
352
|
+
downSamplingPass = new DepthDownsamplingPass({
|
|
353
|
+
normalBuffer: normalPass.texture,
|
|
354
|
+
resolutionScale
|
|
355
|
+
});
|
|
356
|
+
downSamplingPass.enabled = false;
|
|
357
|
+
effectComposer.addPass(downSamplingPass);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
effectComposer.setSize(glSize.width, glSize.height);
|
|
361
|
+
setComposerState({
|
|
362
|
+
composer: effectComposer,
|
|
363
|
+
normalPass,
|
|
364
|
+
downSamplingPass
|
|
365
|
+
});
|
|
366
|
+
return () => {
|
|
367
|
+
for (const pass of effectComposer.passes) disposeGeneratedPass(pass);
|
|
368
|
+
effectComposer.dispose();
|
|
369
|
+
autoClearGuard.release(gl);
|
|
64
370
|
};
|
|
65
371
|
}, [
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (
|
|
87
|
-
|
|
88
|
-
|
|
372
|
+
camera,
|
|
373
|
+
gl,
|
|
374
|
+
depthBuffer,
|
|
375
|
+
stencilBuffer,
|
|
376
|
+
multisampling,
|
|
377
|
+
frameBufferType,
|
|
378
|
+
autoRenderToScreen,
|
|
379
|
+
renderPass,
|
|
380
|
+
scene,
|
|
381
|
+
enableNormalPass,
|
|
382
|
+
resolutionScale
|
|
383
|
+
]);
|
|
384
|
+
const appliedSizeRef = useRef({
|
|
385
|
+
width: -1,
|
|
386
|
+
height: -1
|
|
387
|
+
});
|
|
388
|
+
useFrame((_, delta) => {
|
|
389
|
+
if (!enabled || !composerState) return;
|
|
390
|
+
const { composer } = composerState;
|
|
391
|
+
gl.getSize(glSize);
|
|
392
|
+
if (glSize.width !== appliedSizeRef.current.width || glSize.height !== appliedSizeRef.current.height) {
|
|
393
|
+
composer.setSize(glSize.width, glSize.height);
|
|
394
|
+
appliedSizeRef.current.width = glSize.width;
|
|
395
|
+
appliedSizeRef.current.height = glSize.height;
|
|
89
396
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
397
|
+
const currentAutoClear = gl.autoClear;
|
|
398
|
+
gl.autoClear = autoClear;
|
|
399
|
+
if (stencilBuffer && !autoClear) gl.clearStencil();
|
|
400
|
+
composer.render(delta);
|
|
401
|
+
gl.autoClear = currentAutoClear;
|
|
402
|
+
}, enabled ? renderPriority : 0);
|
|
403
|
+
const group = useRef(null);
|
|
404
|
+
const nodesRef = useRef([]);
|
|
405
|
+
const [nodesVersion, setNodesVersion] = useState(0);
|
|
406
|
+
useLayoutEffect(() => {
|
|
407
|
+
if (!composerState) return;
|
|
408
|
+
const nodes = readGroupChildren(group.current, (object) => object instanceof Effect || object instanceof Pass);
|
|
409
|
+
if (updateIfChanged(nodesRef, nodes)) setNodesVersion((v) => v + 1);
|
|
410
|
+
});
|
|
411
|
+
useLayoutEffect(() => {
|
|
412
|
+
if (!composerState) return;
|
|
413
|
+
const { composer, normalPass, downSamplingPass } = composerState;
|
|
414
|
+
const passes = buildPasses(nodesRef.current, camera, mergeMode);
|
|
415
|
+
if (passes.some((pass) => groupPasses.has(pass))) {
|
|
416
|
+
const trailingCopyPass = new CopyPass();
|
|
417
|
+
generatedPasses.add(trailingCopyPass);
|
|
418
|
+
passes.push(trailingCopyPass);
|
|
419
|
+
}
|
|
420
|
+
for (const pass of passes) composer.addPass(pass);
|
|
421
|
+
if (passes.length) {
|
|
422
|
+
if (normalPass) normalPass.enabled = true;
|
|
423
|
+
if (downSamplingPass) downSamplingPass.enabled = true;
|
|
424
|
+
}
|
|
425
|
+
return () => {
|
|
426
|
+
for (const pass of passes) {
|
|
427
|
+
composer.removePass(pass);
|
|
428
|
+
disposeGeneratedPass(pass);
|
|
429
|
+
}
|
|
430
|
+
if (normalPass) normalPass.enabled = false;
|
|
431
|
+
if (downSamplingPass) downSamplingPass.enabled = false;
|
|
94
432
|
};
|
|
95
433
|
}, [
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
434
|
+
composerState,
|
|
435
|
+
nodesVersion,
|
|
436
|
+
camera,
|
|
437
|
+
mergeMode
|
|
438
|
+
]);
|
|
439
|
+
useEffect(() => {
|
|
440
|
+
toneMappingGuard.acquire(gl, NoToneMapping);
|
|
441
|
+
gl.toneMapping = NoToneMapping;
|
|
442
|
+
return () => {
|
|
443
|
+
toneMappingGuard.release(gl);
|
|
444
|
+
};
|
|
445
|
+
}, [gl]);
|
|
446
|
+
const state = useMemo(() => composerState ? {
|
|
447
|
+
composer: composerState.composer,
|
|
448
|
+
normalPass: composerState.normalPass,
|
|
449
|
+
downSamplingPass: composerState.downSamplingPass,
|
|
450
|
+
resolutionScale,
|
|
451
|
+
camera,
|
|
452
|
+
scene,
|
|
453
|
+
requestRebuild,
|
|
454
|
+
autoClear
|
|
109
455
|
} : null, [
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
456
|
+
composerState,
|
|
457
|
+
resolutionScale,
|
|
458
|
+
camera,
|
|
459
|
+
scene,
|
|
460
|
+
requestRebuild,
|
|
461
|
+
autoClear
|
|
114
462
|
]);
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
463
|
+
useImperativeHandle(ref, () => composerState?.composer, [composerState]);
|
|
464
|
+
if (!state) return null;
|
|
465
|
+
return /* @__PURE__ */ jsx(EffectComposerContext.Provider, {
|
|
466
|
+
value: state,
|
|
467
|
+
children: /* @__PURE__ */ jsx("group", {
|
|
468
|
+
ref: group,
|
|
469
|
+
children
|
|
120
470
|
})
|
|
121
|
-
}) : null;
|
|
122
|
-
}), K = /* @__PURE__ */ he(null);
|
|
123
|
-
function Pe({ children: e, enabled: t = !0 }) {
|
|
124
|
-
let [n, r] = I([]), i = P(() => ({
|
|
125
|
-
selected: n,
|
|
126
|
-
select: r,
|
|
127
|
-
enabled: t
|
|
128
|
-
}), [
|
|
129
|
-
n,
|
|
130
|
-
r,
|
|
131
|
-
t
|
|
132
|
-
]);
|
|
133
|
-
return /* @__PURE__ */ U(K.Provider, {
|
|
134
|
-
value: i,
|
|
135
|
-
children: e
|
|
136
471
|
});
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
return a.length ? [...c, ...a] : c;
|
|
156
|
-
});
|
|
157
|
-
}, [
|
|
158
|
-
e,
|
|
159
|
-
t,
|
|
160
|
-
i
|
|
161
|
-
]), j(() => () => {
|
|
162
|
-
if (!i || !a.current.length) return;
|
|
163
|
-
let e = new Set(a.current);
|
|
164
|
-
i((t) => {
|
|
165
|
-
let n = t.filter((t) => !e.has(t));
|
|
166
|
-
return n.length === t.length ? t : n;
|
|
167
|
-
});
|
|
168
|
-
}, [i]), /* @__PURE__ */ U("group", {
|
|
169
|
-
ref: r,
|
|
170
|
-
...n,
|
|
171
|
-
children: t
|
|
472
|
+
});
|
|
473
|
+
//#endregion
|
|
474
|
+
//#region src/EffectGroup.tsx
|
|
475
|
+
function EffectGroup({ enabled = true, children, ref }) {
|
|
476
|
+
const { camera, requestRebuild } = use(EffectComposerContext);
|
|
477
|
+
const group = useRef(null);
|
|
478
|
+
const effectsRef = useRef([]);
|
|
479
|
+
const [pass, setPass] = useState(null);
|
|
480
|
+
useLayoutEffect(() => {
|
|
481
|
+
const effects = readGroupChildren(group.current, (object) => object instanceof Effect);
|
|
482
|
+
if (!updateIfChanged(effectsRef, effects)) return;
|
|
483
|
+
if (!effects.length) {
|
|
484
|
+
setPass(null);
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
const newPass = new EffectPass(camera, ...effects);
|
|
488
|
+
groupPasses.add(newPass);
|
|
489
|
+
setPass(newPass);
|
|
172
490
|
});
|
|
491
|
+
useLayoutEffect(() => {
|
|
492
|
+
if (pass) pass.enabled = enabled;
|
|
493
|
+
}, [pass, enabled]);
|
|
494
|
+
useLayoutEffect(() => {
|
|
495
|
+
requestRebuild();
|
|
496
|
+
}, [pass, requestRebuild]);
|
|
497
|
+
useLayoutEffect(() => {
|
|
498
|
+
return () => {
|
|
499
|
+
if (pass) disposePassWithoutEffects(pass);
|
|
500
|
+
};
|
|
501
|
+
}, [pass]);
|
|
502
|
+
useImperativeHandle(ref, () => pass, [pass]);
|
|
503
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("group", {
|
|
504
|
+
ref: group,
|
|
505
|
+
children
|
|
506
|
+
}), pass && /* @__PURE__ */ jsx("primitive", { object: pass })] });
|
|
173
507
|
}
|
|
174
508
|
//#endregion
|
|
175
|
-
//#region src/
|
|
176
|
-
var
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
let n = (Array.isArray(t) ? t.map((e) => J(e)) : [J(t)]).filter((e) => e != null);
|
|
188
|
-
if (n.length) return e.selection.set(n), r(), () => {
|
|
189
|
-
e.selection.clear(), r();
|
|
190
|
-
};
|
|
191
|
-
}, [
|
|
192
|
-
e,
|
|
193
|
-
t,
|
|
194
|
-
i,
|
|
195
|
-
r
|
|
196
|
-
]), j(() => {
|
|
197
|
-
if (i && i.enabled && i.selected?.length) return e.selection.set(i.selected), r(), () => {
|
|
198
|
-
e.selection.clear(), r();
|
|
199
|
-
};
|
|
200
|
-
}, [
|
|
201
|
-
i,
|
|
202
|
-
e.selection,
|
|
203
|
-
r
|
|
204
|
-
]);
|
|
509
|
+
//#region src/wrapEffect.tsx
|
|
510
|
+
var i = 0;
|
|
511
|
+
var components = /* @__PURE__ */ new WeakMap();
|
|
512
|
+
var identityTokens = /* @__PURE__ */ new WeakMap();
|
|
513
|
+
var nextIdentityToken = 0;
|
|
514
|
+
function identityOf(value) {
|
|
515
|
+
let token = identityTokens.get(value);
|
|
516
|
+
if (token === void 0) {
|
|
517
|
+
token = nextIdentityToken++;
|
|
518
|
+
identityTokens.set(value, token);
|
|
519
|
+
}
|
|
520
|
+
return token;
|
|
205
521
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
return
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if (t.add(e), Array.isArray(e)) return e.map((e) => Q(e, t));
|
|
227
|
-
let n = {};
|
|
228
|
-
for (let r of Object.keys(e).sort()) n[r] = Q(e[r], t);
|
|
229
|
-
return n;
|
|
230
|
-
}
|
|
231
|
-
function He(e) {
|
|
232
|
-
return JSON.stringify(Q(e, /* @__PURE__ */ new WeakSet()));
|
|
233
|
-
}
|
|
234
|
-
function $(e, t) {
|
|
235
|
-
return function({ ref: r, blendFunction: i = t?.blendFunction, opacity: o = t?.opacity, ...s }) {
|
|
236
|
-
let c = Re.get(e);
|
|
237
|
-
if (!c) {
|
|
238
|
-
let t = `@react-three/postprocessing/${e.name}-${Le++}`;
|
|
239
|
-
n({ [t]: e }), Re.set(e, c = t);
|
|
522
|
+
function fingerprint(value, seen) {
|
|
523
|
+
if (value === null || typeof value !== "object") return value;
|
|
524
|
+
if (seen.has(value)) return "[Circular]";
|
|
525
|
+
if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) return identityOf(value);
|
|
526
|
+
seen.add(value);
|
|
527
|
+
if (Array.isArray(value)) return value.map((item) => fingerprint(item, seen));
|
|
528
|
+
const out = {};
|
|
529
|
+
for (const key of Object.keys(value).sort()) out[key] = fingerprint(value[key], seen);
|
|
530
|
+
return out;
|
|
531
|
+
}
|
|
532
|
+
function stableStringify(value) {
|
|
533
|
+
return JSON.stringify(fingerprint(value, /* @__PURE__ */ new WeakSet()));
|
|
534
|
+
}
|
|
535
|
+
function wrapEffect(effect, defaults) {
|
|
536
|
+
return function WrappedEffect({ ref, blendFunction = defaults?.blendFunction, opacity = defaults?.opacity, ...props }) {
|
|
537
|
+
let Component = components.get(effect);
|
|
538
|
+
if (!Component) {
|
|
539
|
+
const key = `@react-three/postprocessing/${effect.name}-${i++}`;
|
|
540
|
+
extend({ [key]: effect });
|
|
541
|
+
components.set(effect, Component = key);
|
|
240
542
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
...
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
"blendMode-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
543
|
+
const camera = useThree((state) => state.camera);
|
|
544
|
+
const args = useMemo(() => [...defaults?.args ?? [], ...props.args ?? [{
|
|
545
|
+
...defaults,
|
|
546
|
+
...props
|
|
547
|
+
}]], [stableStringify(props)]);
|
|
548
|
+
return /* @__PURE__ */ jsx(Component, {
|
|
549
|
+
camera,
|
|
550
|
+
"blendMode-blendFunction": blendFunction,
|
|
551
|
+
"blendMode-opacity-value": opacity,
|
|
552
|
+
...props,
|
|
553
|
+
args,
|
|
554
|
+
ref
|
|
252
555
|
});
|
|
253
556
|
};
|
|
254
557
|
}
|
|
255
558
|
//#endregion
|
|
256
559
|
//#region src/effects/ASCII.tsx
|
|
257
|
-
var
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
560
|
+
var fragment = `
|
|
561
|
+
uniform sampler2D uCharacters;
|
|
562
|
+
uniform float uCharactersCount;
|
|
563
|
+
uniform float uCellSize;
|
|
564
|
+
uniform bool uInvert;
|
|
565
|
+
uniform vec3 uColor;
|
|
566
|
+
|
|
567
|
+
const vec2 SIZE = vec2(16.);
|
|
568
|
+
|
|
569
|
+
vec3 greyscale(vec3 color, float strength) {
|
|
570
|
+
float g = dot(color, vec3(0.299, 0.587, 0.114));
|
|
571
|
+
return mix(color, vec3(g), strength);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
vec3 greyscale(vec3 color) {
|
|
575
|
+
return greyscale(color, 1.0);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {
|
|
579
|
+
vec2 cell = resolution / uCellSize;
|
|
580
|
+
vec2 grid = 1.0 / cell;
|
|
581
|
+
vec2 pixelizedUV = grid * (0.5 + floor(uv / grid));
|
|
582
|
+
vec4 pixelized = texture2D(inputBuffer, pixelizedUV);
|
|
583
|
+
float greyscaled = greyscale(pixelized.rgb).r;
|
|
584
|
+
|
|
585
|
+
if (uInvert) {
|
|
586
|
+
greyscaled = 1.0 - greyscaled;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
float characterIndex = floor((uCharactersCount - 1.0) * greyscaled);
|
|
590
|
+
vec2 characterPosition = vec2(mod(characterIndex, SIZE.x), floor(characterIndex / SIZE.y));
|
|
591
|
+
vec2 offset = vec2(characterPosition.x, -characterPosition.y) / SIZE;
|
|
592
|
+
vec2 charUV = mod(uv * (cell / SIZE), 1.0 / SIZE) - vec2(0., 1.0 / SIZE) + offset;
|
|
593
|
+
vec4 asciiCharacter = texture2D(uCharacters, charUV);
|
|
594
|
+
|
|
595
|
+
asciiCharacter.rgb = uColor * asciiCharacter.r;
|
|
596
|
+
asciiCharacter.a = pixelized.a;
|
|
597
|
+
outputColor = asciiCharacter;
|
|
598
|
+
}
|
|
599
|
+
`;
|
|
600
|
+
var ASCIIEffect = class extends Effect {
|
|
601
|
+
constructor({ font = "arial", characters = ` .:,'-^=*+?!|0#X%WM@`, fontSize = 54, cellSize = 16, color = "#ffffff", invert = false } = {}) {
|
|
602
|
+
const uniforms = /* @__PURE__ */ new Map([
|
|
603
|
+
["uCharacters", new Uniform(new Texture$1())],
|
|
604
|
+
["uCellSize", new Uniform(cellSize)],
|
|
605
|
+
["uCharactersCount", new Uniform(characters.length)],
|
|
606
|
+
["uColor", new Uniform(new Color(color))],
|
|
607
|
+
["uInvert", new Uniform(invert)]
|
|
265
608
|
]);
|
|
266
|
-
super("ASCIIEffect",
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
609
|
+
super("ASCIIEffect", fragment, { uniforms });
|
|
610
|
+
this._font = font;
|
|
611
|
+
this._characters = characters;
|
|
612
|
+
this._fontSize = fontSize;
|
|
613
|
+
this.updateCharactersTexture();
|
|
614
|
+
}
|
|
615
|
+
get cellSize() {
|
|
616
|
+
return this.uniforms.get("uCellSize").value;
|
|
617
|
+
}
|
|
618
|
+
set cellSize(value) {
|
|
619
|
+
this.uniforms.get("uCellSize").value = value;
|
|
620
|
+
}
|
|
621
|
+
get invert() {
|
|
622
|
+
return this.uniforms.get("uInvert").value;
|
|
623
|
+
}
|
|
624
|
+
set invert(value) {
|
|
625
|
+
this.uniforms.get("uInvert").value = value;
|
|
626
|
+
}
|
|
627
|
+
get color() {
|
|
628
|
+
return this.uniforms.get("uColor").value;
|
|
629
|
+
}
|
|
630
|
+
set color(value) {
|
|
631
|
+
this.uniforms.get("uColor").value.set(value);
|
|
632
|
+
}
|
|
633
|
+
get font() {
|
|
634
|
+
return this._font;
|
|
635
|
+
}
|
|
636
|
+
set font(value) {
|
|
637
|
+
this._font = value;
|
|
638
|
+
this.updateCharactersTexture();
|
|
639
|
+
}
|
|
640
|
+
get characters() {
|
|
641
|
+
return this._characters;
|
|
642
|
+
}
|
|
643
|
+
set characters(value) {
|
|
644
|
+
this._characters = value;
|
|
645
|
+
this.uniforms.get("uCharactersCount").value = value.length;
|
|
646
|
+
this.updateCharactersTexture();
|
|
647
|
+
}
|
|
648
|
+
get fontSize() {
|
|
649
|
+
return this._fontSize;
|
|
650
|
+
}
|
|
651
|
+
set fontSize(value) {
|
|
652
|
+
this._fontSize = value;
|
|
653
|
+
this.updateCharactersTexture();
|
|
654
|
+
}
|
|
655
|
+
updateCharactersTexture() {
|
|
656
|
+
const uniform = this.uniforms.get("uCharacters");
|
|
657
|
+
const previous = uniform.value;
|
|
658
|
+
uniform.value = this.createCharactersTexture(this._characters, this._font, this._fontSize);
|
|
659
|
+
previous.dispose();
|
|
660
|
+
}
|
|
661
|
+
/** Draws the characters on a Canvas and returns a texture */
|
|
662
|
+
createCharactersTexture(characters, font, fontSize) {
|
|
663
|
+
const canvas = document.createElement("canvas");
|
|
664
|
+
const SIZE = 1024;
|
|
665
|
+
const MAX_PER_ROW = 16;
|
|
666
|
+
const CELL = SIZE / MAX_PER_ROW;
|
|
667
|
+
canvas.width = canvas.height = SIZE;
|
|
668
|
+
const texture = new CanvasTexture(canvas, void 0, RepeatWrapping, RepeatWrapping, NearestFilter, NearestFilter);
|
|
669
|
+
const context = canvas.getContext("2d");
|
|
670
|
+
if (!context) throw new Error("Context not available");
|
|
671
|
+
context.clearRect(0, 0, SIZE, SIZE);
|
|
672
|
+
context.font = `${fontSize}px ${font}`;
|
|
673
|
+
context.textAlign = "center";
|
|
674
|
+
context.textBaseline = "middle";
|
|
675
|
+
context.fillStyle = "#fff";
|
|
676
|
+
for (let i = 0; i < characters.length; i++) {
|
|
677
|
+
const char = characters[i];
|
|
678
|
+
const x = i % MAX_PER_ROW;
|
|
679
|
+
const y = Math.floor(i / MAX_PER_ROW);
|
|
680
|
+
context.fillText(char, x * CELL + CELL / 2, y * CELL + CELL / 2);
|
|
279
681
|
}
|
|
280
|
-
|
|
682
|
+
texture.needsUpdate = true;
|
|
683
|
+
return texture;
|
|
281
684
|
}
|
|
282
685
|
};
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
686
|
+
var ASCII = /* @__PURE__ */ createEffectComponent(ASCIIEffect);
|
|
687
|
+
//#endregion
|
|
688
|
+
//#region src/passes/DepthPicking.tsx
|
|
689
|
+
function DepthPicking({ ref }) {
|
|
690
|
+
const { composer } = use(EffectComposerContext);
|
|
691
|
+
const [depthPickingPass] = useState(() => new DepthPickingPass());
|
|
692
|
+
const [copyPass] = useState(() => new CopyPass());
|
|
693
|
+
useEffect(() => {
|
|
694
|
+
composer.addPass(depthPickingPass);
|
|
695
|
+
composer.addPass(copyPass);
|
|
696
|
+
return () => {
|
|
697
|
+
composer.removePass(depthPickingPass);
|
|
698
|
+
composer.removePass(copyPass);
|
|
699
|
+
};
|
|
700
|
+
}, [
|
|
701
|
+
composer,
|
|
702
|
+
depthPickingPass,
|
|
703
|
+
copyPass
|
|
704
|
+
]);
|
|
705
|
+
useDispose(depthPickingPass);
|
|
706
|
+
useDispose(copyPass);
|
|
707
|
+
useImperativeHandle(ref, () => ({ readDepth: (ndc) => depthPickingPass.readDepth(ndc) }), [depthPickingPass]);
|
|
708
|
+
return null;
|
|
709
|
+
}
|
|
710
|
+
function useDepthPicking(pass, camera) {
|
|
711
|
+
const composerCamera = use(EffectComposerContext)?.camera;
|
|
712
|
+
const defaultCamera = useThree((state) => state.camera);
|
|
713
|
+
const resolvedCamera = camera ?? composerCamera ?? defaultCamera;
|
|
714
|
+
const [ndc] = useState(() => new Vector3());
|
|
715
|
+
return useCallback(async (x, y) => {
|
|
716
|
+
if (!pass.current) return false;
|
|
717
|
+
ndc.x = x;
|
|
718
|
+
ndc.y = y;
|
|
719
|
+
ndc.z = await pass.current.readDepth(ndc);
|
|
720
|
+
ndc.z = ndc.z * 2 - 1;
|
|
721
|
+
return 1 - ndc.z > 1e-7 ? ndc.clone().unproject(resolvedCamera) : false;
|
|
722
|
+
}, [
|
|
723
|
+
pass,
|
|
724
|
+
resolvedCamera,
|
|
725
|
+
ndc
|
|
298
726
|
]);
|
|
299
|
-
return X(s), /* @__PURE__ */ U("primitive", {
|
|
300
|
-
ref: o,
|
|
301
|
-
object: s
|
|
302
|
-
});
|
|
303
727
|
}
|
|
304
728
|
//#endregion
|
|
305
729
|
//#region src/effects/DepthOfField.tsx
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
730
|
+
var LIVE_KEYS$6 = [
|
|
731
|
+
"blendMode-blendFunction",
|
|
732
|
+
"bokehScale",
|
|
733
|
+
"cocMaterial-focusDistance",
|
|
734
|
+
"cocMaterial-focusRange",
|
|
735
|
+
"depthTexture"
|
|
736
|
+
];
|
|
737
|
+
function get$2(effect, key) {
|
|
738
|
+
if (key !== "depthTexture") return readPierced(effect, key);
|
|
739
|
+
const texture = effect.cocMaterial.uniforms.depthBuffer.value;
|
|
740
|
+
return texture ? { texture } : void 0;
|
|
741
|
+
}
|
|
742
|
+
function set$3(effect, key, value) {
|
|
743
|
+
if (key === "depthTexture") {
|
|
744
|
+
const dt = value;
|
|
745
|
+
effect.setDepthTexture(dt?.texture, dt?.packing);
|
|
746
|
+
} else applyPierced(effect, key, value);
|
|
747
|
+
}
|
|
748
|
+
function DepthOfField({ ref, blendFunction, worldFocusDistance, worldFocusRange, focusDistance, focusRange, focalLength, bokehScale, resolutionScale, resolutionX, resolutionY, width, height, target, depthTexture, ...props }) {
|
|
749
|
+
const { camera } = use(EffectComposerContext);
|
|
750
|
+
const autoFocus = target != null;
|
|
751
|
+
const effect = useMemo(() => {
|
|
752
|
+
const effect = new DepthOfFieldEffect(camera, {
|
|
753
|
+
worldFocusDistance,
|
|
754
|
+
worldFocusRange,
|
|
755
|
+
focalLength,
|
|
756
|
+
resolutionScale,
|
|
757
|
+
resolutionX,
|
|
758
|
+
resolutionY,
|
|
759
|
+
width,
|
|
760
|
+
height
|
|
321
761
|
});
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
return
|
|
762
|
+
if (autoFocus) effect.target = new Vector3();
|
|
763
|
+
effect.maskFunction = MaskFunction.MULTIPLY_RGB_SET_ALPHA;
|
|
764
|
+
return effect;
|
|
325
765
|
}, [
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
u,
|
|
337
|
-
d,
|
|
338
|
-
f,
|
|
339
|
-
v,
|
|
340
|
-
h
|
|
766
|
+
camera,
|
|
767
|
+
worldFocusDistance,
|
|
768
|
+
worldFocusRange,
|
|
769
|
+
focalLength,
|
|
770
|
+
resolutionScale,
|
|
771
|
+
resolutionX,
|
|
772
|
+
resolutionY,
|
|
773
|
+
width,
|
|
774
|
+
height,
|
|
775
|
+
autoFocus
|
|
341
776
|
]);
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
777
|
+
useLiveDefaults(effect, {
|
|
778
|
+
"blendMode-blendFunction": blendFunction,
|
|
779
|
+
bokehScale,
|
|
780
|
+
"cocMaterial-focusDistance": focusDistance,
|
|
781
|
+
"cocMaterial-focusRange": focusRange,
|
|
782
|
+
depthTexture
|
|
783
|
+
}, LIVE_KEYS$6, get$2, set$3);
|
|
784
|
+
useDispose(effect);
|
|
785
|
+
return /* @__PURE__ */ jsx("primitive", {
|
|
786
|
+
...props,
|
|
787
|
+
object: effect,
|
|
788
|
+
ref,
|
|
789
|
+
target
|
|
347
790
|
});
|
|
348
791
|
}
|
|
349
792
|
//#endregion
|
|
350
793
|
//#region src/effects/Autofocus.tsx
|
|
351
|
-
function
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
y,
|
|
364
|
-
b
|
|
365
|
-
]), j(() => () => {
|
|
366
|
-
y.dispose(), b.dispose();
|
|
367
|
-
}, [y, b]);
|
|
368
|
-
let [x] = I(() => new H(0, 0, 0)), [S] = I(() => new H(0, 0, 0)), C = _e(async (e, t) => (S.x = e, S.y = t, S.z = await y.readDepth(S), S.z = S.z * 2 - 1, 1 - S.z > 1e-7 && S.unproject(v)), [
|
|
369
|
-
S,
|
|
370
|
-
y,
|
|
371
|
-
v
|
|
372
|
-
]), w = _e(async (t, r = !0) => {
|
|
373
|
-
if (e) x.set(...e);
|
|
794
|
+
function Autofocus({ target = void 0, mouse: followMouse = false, debug = void 0, manual = false, smoothTime = .25, ref, ...props }) {
|
|
795
|
+
const dofRef = useRef(null);
|
|
796
|
+
const pickRef = useRef(null);
|
|
797
|
+
const getHit = useDepthPicking(pickRef);
|
|
798
|
+
const hitpointMarkerRef = useRef(null);
|
|
799
|
+
const dofTargetMarkerRef = useRef(null);
|
|
800
|
+
const scene = useThree(({ scene }) => scene);
|
|
801
|
+
const pointer = useThree(({ pointer }) => pointer);
|
|
802
|
+
const [autoFocusMarker] = useState(() => new Vector3());
|
|
803
|
+
const [hitpoint] = useState(() => new Vector3());
|
|
804
|
+
const update = useCallback(async (delta, updateTarget = true) => {
|
|
805
|
+
if (target) hitpoint.set(...target);
|
|
374
806
|
else {
|
|
375
|
-
|
|
807
|
+
const { x, y } = followMouse ? pointer : {
|
|
376
808
|
x: 0,
|
|
377
809
|
y: 0
|
|
378
|
-
}
|
|
379
|
-
|
|
810
|
+
};
|
|
811
|
+
const hit = await getHit(x, y);
|
|
812
|
+
if (hit) hitpoint.copy(hit);
|
|
813
|
+
}
|
|
814
|
+
if (updateTarget && dofRef.current?.target) {
|
|
815
|
+
if (smoothTime > 0 && delta > 0) easing.damp3(dofRef.current.target, hitpoint, smoothTime, delta);
|
|
816
|
+
else dofRef.current.target.copy(hitpoint);
|
|
380
817
|
}
|
|
381
|
-
r && u.current?.target && (s > 0 && t > 0 ? Ee.damp3(u.current.target, x, s, t) : u.current.target.copy(x));
|
|
382
818
|
}, [
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
819
|
+
target,
|
|
820
|
+
hitpoint,
|
|
821
|
+
followMouse,
|
|
822
|
+
pointer,
|
|
823
|
+
getHit,
|
|
824
|
+
smoothTime
|
|
389
825
|
]);
|
|
390
|
-
|
|
391
|
-
|
|
826
|
+
useFrame((_, delta) => {
|
|
827
|
+
if (!manual) update(delta);
|
|
828
|
+
if (hitpointMarkerRef.current) hitpointMarkerRef.current.position.copy(hitpoint);
|
|
829
|
+
if (dofTargetMarkerRef.current && dofRef.current?.target) dofTargetMarkerRef.current.position.copy(dofRef.current.target);
|
|
392
830
|
});
|
|
393
|
-
|
|
394
|
-
dofRef
|
|
395
|
-
hitpoint
|
|
396
|
-
update
|
|
397
|
-
}), [
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
831
|
+
const api = useMemo(() => ({
|
|
832
|
+
dofRef,
|
|
833
|
+
hitpoint,
|
|
834
|
+
update
|
|
835
|
+
}), [hitpoint, update]);
|
|
836
|
+
useImperativeHandle(ref, () => api, [api]);
|
|
837
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
838
|
+
/* @__PURE__ */ jsx(DepthPicking, { ref: pickRef }),
|
|
839
|
+
debug ? createPortal(/* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("mesh", {
|
|
840
|
+
ref: hitpointMarkerRef,
|
|
841
|
+
children: [/* @__PURE__ */ jsx("sphereGeometry", { args: [
|
|
842
|
+
debug,
|
|
843
|
+
16,
|
|
844
|
+
16
|
|
845
|
+
] }), /* @__PURE__ */ jsx("meshBasicMaterial", {
|
|
846
|
+
color: "#00ff00",
|
|
847
|
+
opacity: 1,
|
|
848
|
+
transparent: true,
|
|
849
|
+
depthWrite: false
|
|
850
|
+
})]
|
|
851
|
+
}), /* @__PURE__ */ jsxs("mesh", {
|
|
852
|
+
ref: dofTargetMarkerRef,
|
|
853
|
+
children: [/* @__PURE__ */ jsx("sphereGeometry", { args: [
|
|
854
|
+
debug / 2,
|
|
855
|
+
16,
|
|
856
|
+
16
|
|
857
|
+
] }), /* @__PURE__ */ jsx("meshBasicMaterial", {
|
|
858
|
+
color: "#00ff00",
|
|
859
|
+
opacity: .5,
|
|
860
|
+
transparent: true,
|
|
861
|
+
depthWrite: false
|
|
862
|
+
})]
|
|
863
|
+
})] }), scene) : null,
|
|
864
|
+
/* @__PURE__ */ jsx(DepthOfField, {
|
|
865
|
+
ref: dofRef,
|
|
866
|
+
...props,
|
|
867
|
+
target: autoFocusMarker
|
|
868
|
+
})
|
|
869
|
+
] });
|
|
427
870
|
}
|
|
428
871
|
//#endregion
|
|
429
872
|
//#region src/effects/Bloom.tsx
|
|
430
|
-
var
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
873
|
+
var BloomImpl = /* @__PURE__ */ createEffectComponent(BloomEffect);
|
|
874
|
+
function Bloom({ blendFunction = 0, luminanceThreshold, luminanceSmoothing, mipmapBlur, radius, levels, resolutionScale, resolutionX, resolutionY, ...liveProps }) {
|
|
875
|
+
const args = useMemo(() => [{
|
|
876
|
+
luminanceThreshold,
|
|
877
|
+
luminanceSmoothing,
|
|
878
|
+
mipmapBlur,
|
|
879
|
+
radius,
|
|
880
|
+
levels,
|
|
881
|
+
resolutionScale,
|
|
882
|
+
resolutionX,
|
|
883
|
+
resolutionY
|
|
884
|
+
}], [
|
|
885
|
+
luminanceThreshold,
|
|
886
|
+
luminanceSmoothing,
|
|
887
|
+
mipmapBlur,
|
|
888
|
+
radius,
|
|
889
|
+
levels,
|
|
890
|
+
resolutionScale,
|
|
891
|
+
resolutionX,
|
|
892
|
+
resolutionY
|
|
893
|
+
]);
|
|
894
|
+
return /* @__PURE__ */ jsx(BloomImpl, {
|
|
895
|
+
blendFunction,
|
|
896
|
+
args,
|
|
897
|
+
...liveProps
|
|
441
898
|
});
|
|
442
899
|
}
|
|
443
900
|
//#endregion
|
|
901
|
+
//#region src/effects/BrightnessContrast.tsx
|
|
902
|
+
var BrightnessContrast = /* @__PURE__ */ createEffectComponent(BrightnessContrastEffect);
|
|
903
|
+
//#endregion
|
|
904
|
+
//#region src/effects/ChromaticAberration.tsx
|
|
905
|
+
var ChromaticAberration = /* @__PURE__ */ createEffectComponent(ChromaticAberrationEffect);
|
|
906
|
+
//#endregion
|
|
444
907
|
//#region src/effects/ColorAverage.tsx
|
|
445
|
-
|
|
446
|
-
let n = P(() => new l(e), [e]);
|
|
447
|
-
return X(n), /* @__PURE__ */ U("primitive", {
|
|
448
|
-
object: n,
|
|
449
|
-
ref: t
|
|
450
|
-
});
|
|
451
|
-
}
|
|
908
|
+
var ColorAverage = /* @__PURE__ */ createEffectComponent(ColorAverageEffect);
|
|
452
909
|
//#endregion
|
|
453
910
|
//#region src/effects/ColorDepth.tsx
|
|
454
|
-
var
|
|
911
|
+
var ColorDepthImpl = /* @__PURE__ */ createEffectComponent(ColorDepthEffect);
|
|
912
|
+
function ColorDepth({ bits, ...props }) {
|
|
913
|
+
if (bits !== void 0) props.bitDepth = bits;
|
|
914
|
+
return /* @__PURE__ */ jsx(ColorDepthImpl, { ...props });
|
|
915
|
+
}
|
|
916
|
+
//#endregion
|
|
917
|
+
//#region src/effects/Depth.tsx
|
|
918
|
+
var Depth = /* @__PURE__ */ createEffectComponent(DepthEffect);
|
|
919
|
+
//#endregion
|
|
920
|
+
//#region src/effects/DotScreen.tsx
|
|
921
|
+
var DotScreen = /* @__PURE__ */ createEffectComponent(DotScreenEffect);
|
|
922
|
+
//#endregion
|
|
923
|
+
//#region src/effects/FXAA.tsx
|
|
924
|
+
var FXAA = /* @__PURE__ */ createEffectComponent(FXAAEffect);
|
|
455
925
|
//#endregion
|
|
456
926
|
//#region src/effects/Glitch.tsx
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
}), [
|
|
465
|
-
i,
|
|
466
|
-
o,
|
|
467
|
-
n,
|
|
468
|
-
s,
|
|
469
|
-
c
|
|
470
|
-
]);
|
|
471
|
-
return N(() => {
|
|
472
|
-
l.mode = e ? n.mode || S.SPORADIC : S.DISABLED, r();
|
|
473
|
-
}, [
|
|
474
|
-
e,
|
|
475
|
-
l,
|
|
476
|
-
r,
|
|
477
|
-
n.mode
|
|
478
|
-
]), X(l), /* @__PURE__ */ U("primitive", {
|
|
479
|
-
ref: t,
|
|
480
|
-
object: l
|
|
927
|
+
var GlitchImpl = /* @__PURE__ */ createEffectComponent(GlitchEffect);
|
|
928
|
+
function Glitch({ active = true, mode = GlitchMode.SPORADIC, dtSize, ...props }) {
|
|
929
|
+
const args = useMemo(() => [{ dtSize }], [dtSize]);
|
|
930
|
+
return /* @__PURE__ */ jsx(GlitchImpl, {
|
|
931
|
+
args,
|
|
932
|
+
mode: active ? mode : GlitchMode.DISABLED,
|
|
933
|
+
...props
|
|
481
934
|
});
|
|
482
935
|
}
|
|
483
936
|
//#endregion
|
|
484
937
|
//#region src/effects/GodRays.tsx
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
938
|
+
var LIVE_KEYS$5 = [
|
|
939
|
+
"blendMode-blendFunction",
|
|
940
|
+
"godRaysMaterial-density",
|
|
941
|
+
"godRaysMaterial-decay",
|
|
942
|
+
"godRaysMaterial-weight",
|
|
943
|
+
"godRaysMaterial-exposure",
|
|
944
|
+
"clampMax",
|
|
945
|
+
"blur",
|
|
946
|
+
"kernelSize",
|
|
947
|
+
"samples",
|
|
948
|
+
"width",
|
|
949
|
+
"height"
|
|
950
|
+
];
|
|
951
|
+
function get$1(effect, key) {
|
|
952
|
+
return key === "clampMax" ? effect.godRaysMaterial.maxIntensity : readPierced(effect, key);
|
|
953
|
+
}
|
|
954
|
+
function set$2(effect, key, value) {
|
|
955
|
+
if (key === "clampMax") effect.godRaysMaterial.maxIntensity = value;
|
|
956
|
+
else applyPierced(effect, key, value);
|
|
957
|
+
}
|
|
958
|
+
function GodRays({ sun, blendFunction, density, decay, weight, exposure, clampMax, blur, kernelSize, samples, width, height, resolutionScale, resolutionX, resolutionY, ref }) {
|
|
959
|
+
const { camera, autoClear } = use(EffectComposerContext);
|
|
960
|
+
const invalidate = useThree((state) => state.invalidate);
|
|
961
|
+
const effect = useMemo(() => new GodRaysEffect(camera, resolveRef(sun), {
|
|
962
|
+
resolutionScale,
|
|
963
|
+
resolutionX,
|
|
964
|
+
resolutionY
|
|
965
|
+
}), [
|
|
966
|
+
camera,
|
|
967
|
+
resolutionScale,
|
|
968
|
+
resolutionX,
|
|
969
|
+
resolutionY
|
|
970
|
+
]);
|
|
971
|
+
useEffect(() => {
|
|
972
|
+
if (autoClear !== false) console.warn("GodRays renders an internal extra pass that needs <EffectComposer autoClear={false}> - without it, occlusion by other objects will look wrong.");
|
|
973
|
+
}, [autoClear]);
|
|
974
|
+
useLayoutEffect(() => {
|
|
975
|
+
effect.lightSource = resolveRef(sun);
|
|
976
|
+
invalidate();
|
|
977
|
+
}, [
|
|
978
|
+
effect,
|
|
979
|
+
sun,
|
|
980
|
+
invalidate
|
|
981
|
+
]);
|
|
982
|
+
useLiveDefaults(effect, {
|
|
983
|
+
"blendMode-blendFunction": blendFunction,
|
|
984
|
+
"godRaysMaterial-density": density,
|
|
985
|
+
"godRaysMaterial-decay": decay,
|
|
986
|
+
"godRaysMaterial-weight": weight,
|
|
987
|
+
"godRaysMaterial-exposure": exposure,
|
|
988
|
+
clampMax,
|
|
989
|
+
blur,
|
|
990
|
+
kernelSize,
|
|
991
|
+
samples,
|
|
992
|
+
width,
|
|
993
|
+
height
|
|
994
|
+
}, LIVE_KEYS$5, get$1, set$2);
|
|
995
|
+
useDispose(effect);
|
|
996
|
+
return /* @__PURE__ */ jsx("primitive", {
|
|
997
|
+
ref,
|
|
998
|
+
object: effect
|
|
490
999
|
});
|
|
491
1000
|
}
|
|
492
1001
|
//#endregion
|
|
493
1002
|
//#region src/effects/Grid.tsx
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
1003
|
+
var GridImpl = /* @__PURE__ */ createEffectComponent(GridEffect);
|
|
1004
|
+
function Grid({ size, ref, ...props }) {
|
|
1005
|
+
const invalidate = useThree((state) => state.invalidate);
|
|
1006
|
+
const localRef = useRef(null);
|
|
1007
|
+
useImperativeHandle(ref, () => localRef.current, []);
|
|
1008
|
+
useLayoutEffect(() => {
|
|
1009
|
+
if (size) {
|
|
1010
|
+
localRef.current?.setSize(size.width, size.height);
|
|
1011
|
+
invalidate();
|
|
1012
|
+
}
|
|
1013
|
+
}, [size, invalidate]);
|
|
1014
|
+
return /* @__PURE__ */ jsx(GridImpl, {
|
|
1015
|
+
ref: localRef,
|
|
1016
|
+
...props
|
|
505
1017
|
});
|
|
506
1018
|
}
|
|
507
1019
|
//#endregion
|
|
508
1020
|
//#region src/effects/HueSaturation.tsx
|
|
509
|
-
var ot = /* @__PURE__ */ $(T), st = { fragmentShader: "\n uniform float time;\n uniform vec2 lensPosition;\n uniform vec2 screenRes;\n uniform vec3 colorGain;\n uniform float starPoints;\n uniform float glareSize;\n uniform float flareSize;\n uniform float flareSpeed;\n uniform float flareShape;\n uniform float haloScale;\n uniform float opacity;\n uniform bool animated;\n uniform bool anamorphic;\n uniform bool enabled;\n uniform bool secondaryGhosts;\n uniform bool starBurst;\n uniform float ghostScale;\n uniform bool aditionalStreaks;\n uniform sampler2D lensDirtTexture;\n vec2 vTexCoord;\n \n float rand(float n){return fract(sin(n) * 43758.5453123);}\n\n float noise(float p){\n float fl = floor(p);\n float fc = fract(p);\n return mix(rand(fl),rand(fl + 1.0), fc);\n }\n\n vec3 hsv2rgb(vec3 c)\n {\n vec4 k = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n vec3 p = abs(fract(c.xxx + k.xyz) * 6.0 - k.www);\n return c.z * mix(k.xxx, clamp(p - k.xxx, 0.0, 1.0), c.y);\n }\n\n float saturate(float x)\n {\n return clamp(x, 0.,1.);\n }\n\n vec2 rotateUV(vec2 uv, float rotation)\n {\n return vec2(\n cos(rotation) * uv.x + sin(rotation) * uv.y,\n cos(rotation) * uv.y - sin(rotation) * uv.x\n );\n }\n\n // Based on https://www.shadertoy.com/view/XtKfRV\n vec3 drawflare(vec2 p, float intensity, float rnd, float speed, int id)\n {\n float flarehueoffset = (1. / 32.) * float(id) * 0.1;\n float lingrad = distance(vec2(0.), p);\n float expgrad = 1. / exp(lingrad * (fract(rnd) * 0.66 + 0.33));\n vec3 colgrad = hsv2rgb(vec3( fract( (expgrad * 8.) + speed * flareSpeed + flarehueoffset), pow(1.-abs(expgrad*2.-1.), 0.45), 20.0 * expgrad * intensity)); //rainbow spectrum effect\n\n float internalStarPoints;\n\n if(anamorphic){\n internalStarPoints = 1.0;\n } else{\n internalStarPoints = starPoints;\n }\n \n float blades = length(p * flareShape * sin(internalStarPoints * atan(p.x, p.y)));\n \n float comp = pow(1.-saturate(blades), ( anamorphic ? 100. : 12.));\n comp += saturate(expgrad-0.9) * 3.;\n comp = pow(comp * expgrad, 8. + (1.-intensity) * 5.);\n \n if(flareSpeed > 0.0){\n return vec3(comp) * colgrad;\n } else{\n return vec3(comp) * flareSize * 15.;\n }\n }\n\n float dist(vec3 a, vec3 b) { return abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z); }\n\n vec3 saturate(vec3 x)\n {\n return clamp(x, vec3(0.0), vec3(1.0));\n }\n\n // Based on https://www.shadertoy.com/view/XtKfRV\n float glare(vec2 uv, vec2 pos, float size)\n {\n vec2 main;\n\n if(animated){\n main = rotateUV(uv-pos, time * 0.1); \n } else{\n main = uv-pos; \n }\n \n float ang = atan(main.y, main.x) * (anamorphic ? 1.0 : starPoints);\n float dist = length(main); \n dist = pow(dist, .9);\n \n float f0 = 1.0/(length(uv-pos)*(1.0/size*16.0)+.2);\n\n return f0+f0*(sin((ang))*.2 +.3);\n }\n\n float sdHex(vec2 p){\n p = abs(p);\n vec2 q = vec2(p.x*2.0*0.5773503, p.y + p.x*0.5773503);\n return dot(step(q.xy,q.yx), 1.0-q.yx);\n }\n\n //Based on https://www.shadertoy.com/view/dllSRX\n float fpow(float x, float k){\n return x > k ? pow((x-k)/(1.0-k),2.0) : 0.0;\n }\n\n vec3 renderhex(vec2 uv, vec2 p, float s, vec3 col){\n uv -= p;\n if (abs(uv.x) < 0.2*s && abs(uv.y) < 0.2*s){\n return mix(vec3(0),mix(vec3(0),col,0.1 + fpow(length(uv/s),0.1)*10.0),smoothstep(0.0,0.1,sdHex(uv*20.0/s)));\n }\n return vec3(0);\n }\n\n // Based on https://www.shadertoy.com/view/4sX3Rs\n vec3 LensFlare(vec2 uv, vec2 pos)\n {\n vec2 main = uv-pos;\n vec2 uvd = uv*(length(uv));\n \n float ang = atan(main.x,main.y);\n \n float f0 = .3/(length(uv-pos)*16.0+1.0);\n \n f0 = f0*(sin(noise(sin(ang*3.9-(animated ? time : 0.0) * 0.3) * starPoints))*.2 );\n \n float f1 = max(0.01-pow(length(uv+1.2*pos),1.9),.0)*7.0;\n\n float f2 = max(.9/(10.0+32.0*pow(length(uvd+0.99*pos),2.0)),.0)*0.35;\n float f22 = max(.9/(11.0+32.0*pow(length(uvd+0.85*pos),2.0)),.0)*0.23;\n float f23 = max(.9/(12.0+32.0*pow(length(uvd+0.95*pos),2.0)),.0)*0.6;\n \n vec2 uvx = mix(uv,uvd, 0.1);\n \n float f4 = max(0.01-pow(length(uvx+0.4*pos),2.9),.0)*4.02;\n float f42 = max(0.0-pow(length(uvx+0.45*pos),2.9),.0)*4.1;\n float f43 = max(0.01-pow(length(uvx+0.5*pos),2.9),.0)*4.6;\n \n uvx = mix(uv,uvd,-.4);\n \n float f5 = max(0.01-pow(length(uvx+0.1*pos),5.5),.0)*2.0;\n float f52 = max(0.01-pow(length(uvx+0.2*pos),5.5),.0)*2.0;\n float f53 = max(0.01-pow(length(uvx+0.1*pos),5.5),.0)*2.0;\n \n uvx = mix(uv,uvd, 2.1);\n \n float f6 = max(0.01-pow(length(uvx-0.3*pos),1.61),.0)*3.159;\n float f62 = max(0.01-pow(length(uvx-0.325*pos),1.614),.0)*3.14;\n float f63 = max(0.01-pow(length(uvx-0.389*pos),1.623),.0)*3.12;\n \n vec3 c = vec3(glare(uv,pos, glareSize));\n\n vec2 prot;\n\n if(animated){\n prot = rotateUV(uv - pos, (time * 0.1)); \n } else if(anamorphic){\n prot = rotateUV(uv - pos, 1.570796); \n } else {\n prot = uv - pos;\n }\n\n c += drawflare(prot, (anamorphic ? flareSize * 10. : flareSize), 0.1, time, 1);\n \n c.r+=f1+f2+f4+f5+f6; c.g+=f1+f22+f42+f52+f62; c.b+=f1+f23+f43+f53+f63;\n c = c*1.3 * vec3(length(uvd)+.09);\n c+=vec3(f0);\n \n return c;\n }\n\n vec3 cc(vec3 color, float factor,float factor2)\n {\n float w = color.x+color.y+color.z;\n return mix(color,vec3(w)*factor,w*factor2);\n } \n\n float rnd(vec2 p)\n {\n float f = fract(sin(dot(p, vec2(12.1234, 72.8392) )*45123.2));\n return f; \n }\n\n float rnd(float w)\n {\n float f = fract(sin(w)*1000.);\n return f; \n }\n\n float regShape(vec2 p, int N)\n {\n float f;\n \n float a=atan(p.x,p.y)+.2;\n float b=6.28319/float(N);\n f=smoothstep(.5,.51, cos(floor(.5+a/b)*b-a)*length(p.xy)* 2.0 -ghostScale);\n \n return f;\n }\n\n // Based on https://www.shadertoy.com/view/Xlc3D2\n vec3 circle(vec2 p, float size, float decay, vec3 color, vec3 color2, float dist, vec2 position)\n {\n float l = length(p + position*(dist*2.))+size/2.;\n float l2 = length(p + position*(dist*4.))+size/3.;\n \n float c = max(0.01-pow(length(p + position*dist), size*ghostScale), 0.0)*10.;\n float c1 = max(0.001-pow(l-0.3, 1./40.)+sin(l*20.), 0.0)*3.;\n float c2 = max(0.09/pow(length(p-position*dist/.5)*1., .95), 0.0)/20.;\n float s = max(0.02-pow(regShape(p*5. + position*dist*5. + decay, 6) , 1.), 0.0)*1.5;\n \n color = cos(vec3(0.44, .24, .2)*16. + dist/8.)*0.5+.5;\n vec3 f = c*color;\n f += c1*color;\n f += c2*color; \n f += s*color;\n return f;\n }\n\n vec4 getLensColor(float x){\n return vec4(vec3(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(vec3(0., 0., 0.),\n vec3(0., 0., 0.), smoothstep(0.0, 0.063, x)),\n vec3(0., 0., 0.), smoothstep(0.063, 0.125, x)),\n vec3(0.0, 0., 0.), smoothstep(0.125, 0.188, x)),\n vec3(0.188, 0.131, 0.116), smoothstep(0.188, 0.227, x)),\n vec3(0.31, 0.204, 0.537), smoothstep(0.227, 0.251, x)),\n vec3(0.192, 0.106, 0.286), smoothstep(0.251, 0.314, x)),\n vec3(0.102, 0.008, 0.341), smoothstep(0.314, 0.392, x)),\n vec3(0.086, 0.0, 0.141), smoothstep(0.392, 0.502, x)),\n vec3(1.0, 0.31, 0.0), smoothstep(0.502, 0.604, x)),\n vec3(.1, 0.1, 0.1), smoothstep(0.604, 0.643, x)),\n vec3(1.0, 0.929, 0.0), smoothstep(0.643, 0.761, x)),\n vec3(1.0, 0.086, 0.424), smoothstep(0.761, 0.847, x)),\n vec3(1.0, 0.49, 0.0), smoothstep(0.847, 0.89, x)),\n vec3(0.945, 0.275, 0.475), smoothstep(0.89, 0.941, x)),\n vec3(0.251, 0.275, 0.796), smoothstep(0.941, 1.0, x))),\n 1.0);\n }\n\n float dirtNoise(vec2 p){\n vec2 f = fract(p);\n f = (f * f) * (3.0 - (2.0 * f)); \n float n = dot(floor(p), vec2(1.0, 157.0));\n vec4 a = fract(sin(vec4(n + 0.0, n + 1.0, n + 157.0, n + 158.0)) * 43758.5453123);\n return mix(mix(a.x, a.y, f.x), mix(a.z, a.w, f.x), f.y);\n } \n\n float fbm(vec2 p){\n const mat2 m = mat2(0.80, -0.60, 0.60, 0.80);\n float f = 0.0;\n f += 0.5000*dirtNoise(p); p = m*p*2.02;\n f += 0.2500*dirtNoise(p); p = m*p*2.03;\n f += 0.1250*dirtNoise(p); p = m*p*2.01;\n f += 0.0625*dirtNoise(p);\n return f/0.9375;\n }\n\n vec4 getLensStar(vec2 p){\n vec2 pp = (p - vec2(0.5)) * 2.0;\n float a = atan(pp.y, pp.x);\n vec4 cp = vec4(sin(a * 1.0), length(pp), sin(a * 13.0), sin(a * 53.0));\n float d = sin(clamp(pow(length(vec2(0.5) - p) * 0.5 + haloScale /2., 5.0), 0.0, 1.0) * 3.14159);\n vec3 c = vec3(d) * vec3(fbm(cp.xy * 16.0) * fbm(cp.zw * 9.0) * max(max(max(max(0.5, sin(a * 1.0)), sin(a * 3.0) * 0.8), sin(a * 7.0) * 0.8), sin(a * 9.0) * 10.6));\n c *= vec3(mix(2.0, (sin(length(pp.xy) * 256.0) * 0.5) + 0.5, sin((clamp((length(pp.xy) - 0.875) / 0.1, 0.0, 1.0) + 0.0) * 2.0 * 3.14159) * 1.5) + 0.5) * 0.3275;\n return vec4(vec3(c * 1.0), d); \n }\n\n vec4 getLensDirt(vec2 p){\n p.xy += vec2(fbm(p.yx * 3.0), fbm(p.yx * 2.0)) * 0.0825;\n vec3 o = vec3(mix(0.125, 0.25, max(max(smoothstep(0.1, 0.0, length(p - vec2(0.25))),\n smoothstep(0.4, 0.0, length(p - vec2(0.75)))),\n smoothstep(0.8, 0.0, length(p - vec2(0.875, 0.125))))));\n o += vec3(max(fbm(p * 1.0) - 0.5, 0.0)) * 0.5;\n o += vec3(max(fbm(p * 2.0) - 0.5, 0.0)) * 0.5;\n o += vec3(max(fbm(p * 4.0) - 0.5, 0.0)) * 0.25;\n o += vec3(max(fbm(p * 8.0) - 0.75, 0.0)) * 1.0;\n o += vec3(max(fbm(p * 16.0) - 0.75, 0.0)) * 0.75;\n o += vec3(max(fbm(p * 64.0) - 0.75, 0.0)) * 0.5;\n return vec4(clamp(o, vec3(0.15), vec3(1.0)), 1.0); \n }\n\n vec4 textureLimited(sampler2D tex, vec2 texCoord){\n if(((texCoord.x < 0.) || (texCoord.y < 0.)) || ((texCoord.x > 1.) || (texCoord.y > 1.))){\n return vec4(0.0);\n }else{\n return texture(tex, texCoord); \n }\n }\n\n vec4 textureDistorted(sampler2D tex, vec2 texCoord, vec2 direction, vec3 distortion) {\n return vec4(textureLimited(tex, (texCoord + (direction * distortion.r))).r,\n textureLimited(tex, (texCoord + (direction * distortion.g))).g,\n textureLimited(tex, (texCoord + (direction * distortion.b))).b,\n 1.0);\n }\n\n // Based on https://www.shadertoy.com/view/4sK3W3\n vec4 getStartBurst(){\n vec2 aspectTexCoord = vec2(1.0) - (((vTexCoord - vec2(0.5)) * vec2(1.0)) + vec2(0.5)); \n vec2 texCoord = vec2(1.0) - vTexCoord; \n vec2 ghostVec = (vec2(0.5) - texCoord) * 0.3 - lensPosition;\n vec2 ghostVecAspectNormalized = normalize(ghostVec * vec2(1.0)) * vec2(1.0);\n vec2 haloVec = normalize(ghostVec) * 0.6;\n vec2 haloVecAspectNormalized = ghostVecAspectNormalized * 0.6;\n vec2 texelSize = vec2(1.0) / vec2(screenRes.xy);\n vec3 distortion = vec3(-(texelSize.x * 1.5), 0.2, texelSize.x * 1.5);\n vec4 c = vec4(0.0);\n for (int i = 0; i < 8; i++) {\n vec2 offset = texCoord + (ghostVec * float(i));\n c += textureDistorted(lensDirtTexture, offset, ghostVecAspectNormalized, distortion) * pow(max(0.0, 1.0 - (length(vec2(0.5) - offset) / length(vec2(0.5)))), 10.0);\n } \n vec2 haloOffset = texCoord + haloVecAspectNormalized; \n return (c * getLensColor((length(vec2(0.5) - aspectTexCoord) / length(vec2(haloScale))))) + \n (textureDistorted(lensDirtTexture, haloOffset, ghostVecAspectNormalized, distortion) * pow(max(0.0, 1.0 - (length(vec2(0.5) - haloOffset) / length(vec2(0.5)))), 10.0));\n } \n\n void mainImage(vec4 inputColor, vec2 uv, out vec4 outputColor)\n {\n vec2 myUV = uv -0.5;\n myUV.y *= screenRes.y/screenRes.x;\n vec2 finalLensPosition = lensPosition * 0.5;\n finalLensPosition.y *= screenRes.y/screenRes.x;\n \n //First Lens flare pass\n vec3 finalColor = LensFlare(myUV, finalLensPosition) * 20.0 * colorGain / 256.;\n\n //Aditional streaks\n if(aditionalStreaks){\n vec3 circColor = vec3(0.9, 0.2, 0.1);\n vec3 circColor2 = vec3(0.3, 0.1, 0.9);\n\n for(float i=0.;i<10.;i++){\n finalColor += circle(myUV, pow(rnd(i*2000.)*2.8, .1)+1.41, 0.0, circColor+i , circColor2+i, rnd(i*20.)*3.+0.2-.5, lensPosition);\n }\n }\n\n //Alternative ghosts\n if(secondaryGhosts){\n vec3 altGhosts = vec3(0);\n altGhosts += renderhex(myUV, -lensPosition*0.25, ghostScale * 1.4, vec3(0.25,0.35,0));\n altGhosts += renderhex(myUV, lensPosition*0.25, ghostScale * 0.5, vec3(1,0.5,0.5));\n altGhosts += renderhex(myUV, lensPosition*0.1, ghostScale * 1.6, vec3(1,1,1));\n altGhosts += renderhex(myUV, lensPosition*1.8, ghostScale * 2.0, vec3(0,0.5,0.75));\n altGhosts += renderhex(myUV, lensPosition*1.25, ghostScale * 0.8, vec3(1,1,0.5));\n altGhosts += renderhex(myUV, -lensPosition*1.25, ghostScale * 5.0, vec3(0.5,0.5,0.25));\n \n //Circular ghosts\n altGhosts += fpow(1.0 - abs(distance(lensPosition*0.8,myUV) - 0.7),0.985)*colorGain / 2100.;\n finalColor += altGhosts;\n }\n \n\n //Starburst \n if(starBurst){\n vTexCoord = myUV + 0.5;\n vec4 lensMod = getLensDirt(myUV);\n float tooBright = 1.0 - (clamp(0.5, 0.0, 0.5) * 2.0); \n float tooDark = clamp(0.5 - 0.5, 0.0, 0.5) * 2.0;\n lensMod += mix(lensMod, pow(lensMod * 2.0, vec4(2.0)) * 0.5, tooBright);\n float lensStarRotationAngle = ((myUV.x + myUV.y)) * (1.0 / 6.0);\n vec2 lensStarTexCoord = (mat2(cos(lensStarRotationAngle), -sin(lensStarRotationAngle), sin(lensStarRotationAngle), cos(lensStarRotationAngle)) * vTexCoord);\n lensMod += getLensStar(lensStarTexCoord) * 2.;\n \n finalColor += clamp((lensMod.rgb * getStartBurst().rgb ), 0.01, 1.0);\n }\n\n //Final composed output\n if(enabled){\n outputColor = vec4(mix(finalColor, vec3(.0), opacity) + inputColor.rgb, inputColor.a);\n } else {\n outputColor = vec4(inputColor);\n }\n }\n " }, ct = class extends _ {
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
1021
|
+
var HueSaturation = /* @__PURE__ */ createEffectComponent(HueSaturationEffect);
|
|
1022
|
+
//#endregion
|
|
1023
|
+
//#region src/effects/LensFlare.tsx
|
|
1024
|
+
var LensFlareShader = { fragmentShader: `
|
|
1025
|
+
uniform float time;
|
|
1026
|
+
uniform vec2 lensPosition;
|
|
1027
|
+
uniform vec2 screenRes;
|
|
1028
|
+
uniform vec3 colorGain;
|
|
1029
|
+
uniform float starPoints;
|
|
1030
|
+
uniform float glareSize;
|
|
1031
|
+
uniform float flareSize;
|
|
1032
|
+
uniform float flareSpeed;
|
|
1033
|
+
uniform float flareShape;
|
|
1034
|
+
uniform float haloScale;
|
|
1035
|
+
uniform float opacity;
|
|
1036
|
+
uniform bool animated;
|
|
1037
|
+
uniform bool anamorphic;
|
|
1038
|
+
uniform bool enabled;
|
|
1039
|
+
uniform bool secondaryGhosts;
|
|
1040
|
+
uniform bool starBurst;
|
|
1041
|
+
uniform float ghostScale;
|
|
1042
|
+
uniform bool aditionalStreaks;
|
|
1043
|
+
uniform sampler2D lensDirtTexture;
|
|
1044
|
+
vec2 vTexCoord;
|
|
1045
|
+
|
|
1046
|
+
float rand(float n){return fract(sin(n) * 43758.5453123);}
|
|
1047
|
+
|
|
1048
|
+
float noise(float p){
|
|
1049
|
+
float fl = floor(p);
|
|
1050
|
+
float fc = fract(p);
|
|
1051
|
+
return mix(rand(fl),rand(fl + 1.0), fc);
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
vec3 hsv2rgb(vec3 c)
|
|
1055
|
+
{
|
|
1056
|
+
vec4 k = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
|
1057
|
+
vec3 p = abs(fract(c.xxx + k.xyz) * 6.0 - k.www);
|
|
1058
|
+
return c.z * mix(k.xxx, clamp(p - k.xxx, 0.0, 1.0), c.y);
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
float saturate(float x)
|
|
1062
|
+
{
|
|
1063
|
+
return clamp(x, 0.,1.);
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
vec2 rotateUV(vec2 uv, float rotation)
|
|
1067
|
+
{
|
|
1068
|
+
return vec2(
|
|
1069
|
+
cos(rotation) * uv.x + sin(rotation) * uv.y,
|
|
1070
|
+
cos(rotation) * uv.y - sin(rotation) * uv.x
|
|
1071
|
+
);
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
// Based on https://www.shadertoy.com/view/XtKfRV
|
|
1075
|
+
vec3 drawflare(vec2 p, float intensity, float rnd, float speed, int id)
|
|
1076
|
+
{
|
|
1077
|
+
float flarehueoffset = (1. / 32.) * float(id) * 0.1;
|
|
1078
|
+
float lingrad = distance(vec2(0.), p);
|
|
1079
|
+
float expgrad = 1. / exp(lingrad * (fract(rnd) * 0.66 + 0.33));
|
|
1080
|
+
vec3 colgrad = hsv2rgb(vec3( fract( (expgrad * 8.) + speed * flareSpeed + flarehueoffset), pow(1.-abs(expgrad*2.-1.), 0.45), 20.0 * expgrad * intensity)); //rainbow spectrum effect
|
|
1081
|
+
|
|
1082
|
+
float internalStarPoints;
|
|
1083
|
+
|
|
1084
|
+
if(anamorphic){
|
|
1085
|
+
internalStarPoints = 1.0;
|
|
1086
|
+
} else{
|
|
1087
|
+
internalStarPoints = starPoints;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
float blades = length(p * flareShape * sin(internalStarPoints * atan(p.x, p.y)));
|
|
1091
|
+
|
|
1092
|
+
float comp = pow(1.-saturate(blades), ( anamorphic ? 100. : 12.));
|
|
1093
|
+
comp += saturate(expgrad-0.9) * 3.;
|
|
1094
|
+
comp = pow(comp * expgrad, 8. + (1.-intensity) * 5.);
|
|
1095
|
+
|
|
1096
|
+
if(flareSpeed > 0.0){
|
|
1097
|
+
return vec3(comp) * colgrad;
|
|
1098
|
+
} else{
|
|
1099
|
+
return vec3(comp) * flareSize * 15.;
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
float dist(vec3 a, vec3 b) { return abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z); }
|
|
1104
|
+
|
|
1105
|
+
vec3 saturate(vec3 x)
|
|
1106
|
+
{
|
|
1107
|
+
return clamp(x, vec3(0.0), vec3(1.0));
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
// Based on https://www.shadertoy.com/view/XtKfRV
|
|
1111
|
+
float glare(vec2 uv, vec2 pos, float size)
|
|
1112
|
+
{
|
|
1113
|
+
vec2 main;
|
|
1114
|
+
|
|
1115
|
+
if(animated){
|
|
1116
|
+
main = rotateUV(uv-pos, time * 0.1);
|
|
1117
|
+
} else{
|
|
1118
|
+
main = uv-pos;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
float ang = atan(main.y, main.x) * (anamorphic ? 1.0 : starPoints);
|
|
1122
|
+
float dist = length(main);
|
|
1123
|
+
dist = pow(dist, .9);
|
|
1124
|
+
|
|
1125
|
+
float f0 = 1.0/(length(uv-pos)*(1.0/size*16.0)+.2);
|
|
1126
|
+
|
|
1127
|
+
return f0+f0*(sin((ang))*.2 +.3);
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
float sdHex(vec2 p){
|
|
1131
|
+
p = abs(p);
|
|
1132
|
+
vec2 q = vec2(p.x*2.0*0.5773503, p.y + p.x*0.5773503);
|
|
1133
|
+
return dot(step(q.xy,q.yx), 1.0-q.yx);
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
//Based on https://www.shadertoy.com/view/dllSRX
|
|
1137
|
+
float fpow(float x, float k){
|
|
1138
|
+
return x > k ? pow((x-k)/(1.0-k),2.0) : 0.0;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
vec3 renderhex(vec2 uv, vec2 p, float s, vec3 col){
|
|
1142
|
+
uv -= p;
|
|
1143
|
+
if (abs(uv.x) < 0.2*s && abs(uv.y) < 0.2*s){
|
|
1144
|
+
return mix(vec3(0),mix(vec3(0),col,0.1 + fpow(length(uv/s),0.1)*10.0),smoothstep(0.0,0.1,sdHex(uv*20.0/s)));
|
|
1145
|
+
}
|
|
1146
|
+
return vec3(0);
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
// Based on https://www.shadertoy.com/view/4sX3Rs
|
|
1150
|
+
vec3 LensFlare(vec2 uv, vec2 pos)
|
|
1151
|
+
{
|
|
1152
|
+
vec2 main = uv-pos;
|
|
1153
|
+
vec2 uvd = uv*(length(uv));
|
|
1154
|
+
|
|
1155
|
+
float ang = atan(main.x,main.y);
|
|
1156
|
+
|
|
1157
|
+
float f0 = .3/(length(uv-pos)*16.0+1.0);
|
|
1158
|
+
|
|
1159
|
+
f0 = f0*(sin(noise(sin(ang*3.9-(animated ? time : 0.0) * 0.3) * starPoints))*.2 );
|
|
1160
|
+
|
|
1161
|
+
float f1 = max(0.01-pow(length(uv+1.2*pos),1.9),.0)*7.0;
|
|
1162
|
+
|
|
1163
|
+
float f2 = max(.9/(10.0+32.0*pow(length(uvd+0.99*pos),2.0)),.0)*0.35;
|
|
1164
|
+
float f22 = max(.9/(11.0+32.0*pow(length(uvd+0.85*pos),2.0)),.0)*0.23;
|
|
1165
|
+
float f23 = max(.9/(12.0+32.0*pow(length(uvd+0.95*pos),2.0)),.0)*0.6;
|
|
1166
|
+
|
|
1167
|
+
vec2 uvx = mix(uv,uvd, 0.1);
|
|
1168
|
+
|
|
1169
|
+
float f4 = max(0.01-pow(length(uvx+0.4*pos),2.9),.0)*4.02;
|
|
1170
|
+
float f42 = max(0.0-pow(length(uvx+0.45*pos),2.9),.0)*4.1;
|
|
1171
|
+
float f43 = max(0.01-pow(length(uvx+0.5*pos),2.9),.0)*4.6;
|
|
1172
|
+
|
|
1173
|
+
uvx = mix(uv,uvd,-.4);
|
|
1174
|
+
|
|
1175
|
+
float f5 = max(0.01-pow(length(uvx+0.1*pos),5.5),.0)*2.0;
|
|
1176
|
+
float f52 = max(0.01-pow(length(uvx+0.2*pos),5.5),.0)*2.0;
|
|
1177
|
+
float f53 = max(0.01-pow(length(uvx+0.1*pos),5.5),.0)*2.0;
|
|
1178
|
+
|
|
1179
|
+
uvx = mix(uv,uvd, 2.1);
|
|
1180
|
+
|
|
1181
|
+
float f6 = max(0.01-pow(length(uvx-0.3*pos),1.61),.0)*3.159;
|
|
1182
|
+
float f62 = max(0.01-pow(length(uvx-0.325*pos),1.614),.0)*3.14;
|
|
1183
|
+
float f63 = max(0.01-pow(length(uvx-0.389*pos),1.623),.0)*3.12;
|
|
1184
|
+
|
|
1185
|
+
vec3 c = vec3(glare(uv,pos, glareSize));
|
|
1186
|
+
|
|
1187
|
+
vec2 prot;
|
|
1188
|
+
|
|
1189
|
+
if(animated){
|
|
1190
|
+
prot = rotateUV(uv - pos, (time * 0.1));
|
|
1191
|
+
} else if(anamorphic){
|
|
1192
|
+
prot = rotateUV(uv - pos, 1.570796);
|
|
1193
|
+
} else {
|
|
1194
|
+
prot = uv - pos;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
c += drawflare(prot, (anamorphic ? flareSize * 10. : flareSize), 0.1, time, 1);
|
|
1198
|
+
|
|
1199
|
+
c.r+=f1+f2+f4+f5+f6; c.g+=f1+f22+f42+f52+f62; c.b+=f1+f23+f43+f53+f63;
|
|
1200
|
+
c = c*1.3 * vec3(length(uvd)+.09);
|
|
1201
|
+
c+=vec3(f0);
|
|
1202
|
+
|
|
1203
|
+
return c;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
vec3 cc(vec3 color, float factor,float factor2)
|
|
1207
|
+
{
|
|
1208
|
+
float w = color.x+color.y+color.z;
|
|
1209
|
+
return mix(color,vec3(w)*factor,w*factor2);
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
float rnd(vec2 p)
|
|
1213
|
+
{
|
|
1214
|
+
float f = fract(sin(dot(p, vec2(12.1234, 72.8392) )*45123.2));
|
|
1215
|
+
return f;
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
float rnd(float w)
|
|
1219
|
+
{
|
|
1220
|
+
float f = fract(sin(w)*1000.);
|
|
1221
|
+
return f;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
float regShape(vec2 p, int N)
|
|
1225
|
+
{
|
|
1226
|
+
float f;
|
|
1227
|
+
|
|
1228
|
+
float a=atan(p.x,p.y)+.2;
|
|
1229
|
+
float b=6.28319/float(N);
|
|
1230
|
+
f=smoothstep(.5,.51, cos(floor(.5+a/b)*b-a)*length(p.xy)* 2.0 -ghostScale);
|
|
1231
|
+
|
|
1232
|
+
return f;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
// Based on https://www.shadertoy.com/view/Xlc3D2
|
|
1236
|
+
vec3 circle(vec2 p, float size, float decay, vec3 color, vec3 color2, float dist, vec2 position)
|
|
1237
|
+
{
|
|
1238
|
+
float l = length(p + position*(dist*2.))+size/2.;
|
|
1239
|
+
float l2 = length(p + position*(dist*4.))+size/3.;
|
|
1240
|
+
|
|
1241
|
+
float c = max(0.01-pow(length(p + position*dist), size*ghostScale), 0.0)*10.;
|
|
1242
|
+
float c1 = max(0.001-pow(l-0.3, 1./40.)+sin(l*20.), 0.0)*3.;
|
|
1243
|
+
float c2 = max(0.09/pow(length(p-position*dist/.5)*1., .95), 0.0)/20.;
|
|
1244
|
+
float s = max(0.02-pow(regShape(p*5. + position*dist*5. + decay, 6) , 1.), 0.0)*1.5;
|
|
1245
|
+
|
|
1246
|
+
color = cos(vec3(0.44, .24, .2)*16. + dist/8.)*0.5+.5;
|
|
1247
|
+
vec3 f = c*color;
|
|
1248
|
+
f += c1*color;
|
|
1249
|
+
f += c2*color;
|
|
1250
|
+
f += s*color;
|
|
1251
|
+
return f;
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
vec4 getLensColor(float x){
|
|
1255
|
+
return vec4(vec3(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(vec3(0., 0., 0.),
|
|
1256
|
+
vec3(0., 0., 0.), smoothstep(0.0, 0.063, x)),
|
|
1257
|
+
vec3(0., 0., 0.), smoothstep(0.063, 0.125, x)),
|
|
1258
|
+
vec3(0.0, 0., 0.), smoothstep(0.125, 0.188, x)),
|
|
1259
|
+
vec3(0.188, 0.131, 0.116), smoothstep(0.188, 0.227, x)),
|
|
1260
|
+
vec3(0.31, 0.204, 0.537), smoothstep(0.227, 0.251, x)),
|
|
1261
|
+
vec3(0.192, 0.106, 0.286), smoothstep(0.251, 0.314, x)),
|
|
1262
|
+
vec3(0.102, 0.008, 0.341), smoothstep(0.314, 0.392, x)),
|
|
1263
|
+
vec3(0.086, 0.0, 0.141), smoothstep(0.392, 0.502, x)),
|
|
1264
|
+
vec3(1.0, 0.31, 0.0), smoothstep(0.502, 0.604, x)),
|
|
1265
|
+
vec3(.1, 0.1, 0.1), smoothstep(0.604, 0.643, x)),
|
|
1266
|
+
vec3(1.0, 0.929, 0.0), smoothstep(0.643, 0.761, x)),
|
|
1267
|
+
vec3(1.0, 0.086, 0.424), smoothstep(0.761, 0.847, x)),
|
|
1268
|
+
vec3(1.0, 0.49, 0.0), smoothstep(0.847, 0.89, x)),
|
|
1269
|
+
vec3(0.945, 0.275, 0.475), smoothstep(0.89, 0.941, x)),
|
|
1270
|
+
vec3(0.251, 0.275, 0.796), smoothstep(0.941, 1.0, x))),
|
|
1271
|
+
1.0);
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
float dirtNoise(vec2 p){
|
|
1275
|
+
vec2 f = fract(p);
|
|
1276
|
+
f = (f * f) * (3.0 - (2.0 * f));
|
|
1277
|
+
float n = dot(floor(p), vec2(1.0, 157.0));
|
|
1278
|
+
vec4 a = fract(sin(vec4(n + 0.0, n + 1.0, n + 157.0, n + 158.0)) * 43758.5453123);
|
|
1279
|
+
return mix(mix(a.x, a.y, f.x), mix(a.z, a.w, f.x), f.y);
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
float fbm(vec2 p){
|
|
1283
|
+
const mat2 m = mat2(0.80, -0.60, 0.60, 0.80);
|
|
1284
|
+
float f = 0.0;
|
|
1285
|
+
f += 0.5000*dirtNoise(p); p = m*p*2.02;
|
|
1286
|
+
f += 0.2500*dirtNoise(p); p = m*p*2.03;
|
|
1287
|
+
f += 0.1250*dirtNoise(p); p = m*p*2.01;
|
|
1288
|
+
f += 0.0625*dirtNoise(p);
|
|
1289
|
+
return f/0.9375;
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
vec4 getLensStar(vec2 p){
|
|
1293
|
+
vec2 pp = (p - vec2(0.5)) * 2.0;
|
|
1294
|
+
float a = atan(pp.y, pp.x);
|
|
1295
|
+
vec4 cp = vec4(sin(a * 1.0), length(pp), sin(a * 13.0), sin(a * 53.0));
|
|
1296
|
+
float d = sin(clamp(pow(length(vec2(0.5) - p) * 0.5 + haloScale /2., 5.0), 0.0, 1.0) * 3.14159);
|
|
1297
|
+
vec3 c = vec3(d) * vec3(fbm(cp.xy * 16.0) * fbm(cp.zw * 9.0) * max(max(max(max(0.5, sin(a * 1.0)), sin(a * 3.0) * 0.8), sin(a * 7.0) * 0.8), sin(a * 9.0) * 10.6));
|
|
1298
|
+
c *= vec3(mix(2.0, (sin(length(pp.xy) * 256.0) * 0.5) + 0.5, sin((clamp((length(pp.xy) - 0.875) / 0.1, 0.0, 1.0) + 0.0) * 2.0 * 3.14159) * 1.5) + 0.5) * 0.3275;
|
|
1299
|
+
return vec4(vec3(c * 1.0), d);
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
vec4 getLensDirt(vec2 p){
|
|
1303
|
+
p.xy += vec2(fbm(p.yx * 3.0), fbm(p.yx * 2.0)) * 0.0825;
|
|
1304
|
+
vec3 o = vec3(mix(0.125, 0.25, max(max(smoothstep(0.1, 0.0, length(p - vec2(0.25))),
|
|
1305
|
+
smoothstep(0.4, 0.0, length(p - vec2(0.75)))),
|
|
1306
|
+
smoothstep(0.8, 0.0, length(p - vec2(0.875, 0.125))))));
|
|
1307
|
+
o += vec3(max(fbm(p * 1.0) - 0.5, 0.0)) * 0.5;
|
|
1308
|
+
o += vec3(max(fbm(p * 2.0) - 0.5, 0.0)) * 0.5;
|
|
1309
|
+
o += vec3(max(fbm(p * 4.0) - 0.5, 0.0)) * 0.25;
|
|
1310
|
+
o += vec3(max(fbm(p * 8.0) - 0.75, 0.0)) * 1.0;
|
|
1311
|
+
o += vec3(max(fbm(p * 16.0) - 0.75, 0.0)) * 0.75;
|
|
1312
|
+
o += vec3(max(fbm(p * 64.0) - 0.75, 0.0)) * 0.5;
|
|
1313
|
+
return vec4(clamp(o, vec3(0.15), vec3(1.0)), 1.0);
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
vec4 textureLimited(sampler2D tex, vec2 texCoord){
|
|
1317
|
+
if(((texCoord.x < 0.) || (texCoord.y < 0.)) || ((texCoord.x > 1.) || (texCoord.y > 1.))){
|
|
1318
|
+
return vec4(0.0);
|
|
1319
|
+
}else{
|
|
1320
|
+
return texture(tex, texCoord);
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
vec4 textureDistorted(sampler2D tex, vec2 texCoord, vec2 direction, vec3 distortion) {
|
|
1325
|
+
return vec4(textureLimited(tex, (texCoord + (direction * distortion.r))).r,
|
|
1326
|
+
textureLimited(tex, (texCoord + (direction * distortion.g))).g,
|
|
1327
|
+
textureLimited(tex, (texCoord + (direction * distortion.b))).b,
|
|
1328
|
+
1.0);
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
// Based on https://www.shadertoy.com/view/4sK3W3
|
|
1332
|
+
vec4 getStartBurst(){
|
|
1333
|
+
vec2 aspectTexCoord = vec2(1.0) - (((vTexCoord - vec2(0.5)) * vec2(1.0)) + vec2(0.5));
|
|
1334
|
+
vec2 texCoord = vec2(1.0) - vTexCoord;
|
|
1335
|
+
vec2 ghostVec = (vec2(0.5) - texCoord) * 0.3 - lensPosition;
|
|
1336
|
+
vec2 ghostVecAspectNormalized = normalize(ghostVec * vec2(1.0)) * vec2(1.0);
|
|
1337
|
+
vec2 haloVec = normalize(ghostVec) * 0.6;
|
|
1338
|
+
vec2 haloVecAspectNormalized = ghostVecAspectNormalized * 0.6;
|
|
1339
|
+
vec2 texelSize = vec2(1.0) / vec2(screenRes.xy);
|
|
1340
|
+
vec3 distortion = vec3(-(texelSize.x * 1.5), 0.2, texelSize.x * 1.5);
|
|
1341
|
+
vec4 c = vec4(0.0);
|
|
1342
|
+
for (int i = 0; i < 8; i++) {
|
|
1343
|
+
vec2 offset = texCoord + (ghostVec * float(i));
|
|
1344
|
+
c += textureDistorted(lensDirtTexture, offset, ghostVecAspectNormalized, distortion) * pow(max(0.0, 1.0 - (length(vec2(0.5) - offset) / length(vec2(0.5)))), 10.0);
|
|
1345
|
+
}
|
|
1346
|
+
vec2 haloOffset = texCoord + haloVecAspectNormalized;
|
|
1347
|
+
return (c * getLensColor((length(vec2(0.5) - aspectTexCoord) / length(vec2(haloScale))))) +
|
|
1348
|
+
(textureDistorted(lensDirtTexture, haloOffset, ghostVecAspectNormalized, distortion) * pow(max(0.0, 1.0 - (length(vec2(0.5) - haloOffset) / length(vec2(0.5)))), 10.0));
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
void mainImage(vec4 inputColor, vec2 uv, out vec4 outputColor)
|
|
1352
|
+
{
|
|
1353
|
+
vec2 myUV = uv -0.5;
|
|
1354
|
+
myUV.y *= screenRes.y/screenRes.x;
|
|
1355
|
+
vec2 finalLensPosition = lensPosition * 0.5;
|
|
1356
|
+
finalLensPosition.y *= screenRes.y/screenRes.x;
|
|
1357
|
+
|
|
1358
|
+
//First Lens flare pass
|
|
1359
|
+
vec3 finalColor = LensFlare(myUV, finalLensPosition) * 20.0 * colorGain / 256.;
|
|
1360
|
+
|
|
1361
|
+
//Aditional streaks
|
|
1362
|
+
if(aditionalStreaks){
|
|
1363
|
+
vec3 circColor = vec3(0.9, 0.2, 0.1);
|
|
1364
|
+
vec3 circColor2 = vec3(0.3, 0.1, 0.9);
|
|
1365
|
+
|
|
1366
|
+
for(float i=0.;i<10.;i++){
|
|
1367
|
+
finalColor += circle(myUV, pow(rnd(i*2000.)*2.8, .1)+1.41, 0.0, circColor+i , circColor2+i, rnd(i*20.)*3.+0.2-.5, lensPosition);
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
//Alternative ghosts
|
|
1372
|
+
if(secondaryGhosts){
|
|
1373
|
+
vec3 altGhosts = vec3(0);
|
|
1374
|
+
altGhosts += renderhex(myUV, -lensPosition*0.25, ghostScale * 1.4, vec3(0.25,0.35,0));
|
|
1375
|
+
altGhosts += renderhex(myUV, lensPosition*0.25, ghostScale * 0.5, vec3(1,0.5,0.5));
|
|
1376
|
+
altGhosts += renderhex(myUV, lensPosition*0.1, ghostScale * 1.6, vec3(1,1,1));
|
|
1377
|
+
altGhosts += renderhex(myUV, lensPosition*1.8, ghostScale * 2.0, vec3(0,0.5,0.75));
|
|
1378
|
+
altGhosts += renderhex(myUV, lensPosition*1.25, ghostScale * 0.8, vec3(1,1,0.5));
|
|
1379
|
+
altGhosts += renderhex(myUV, -lensPosition*1.25, ghostScale * 5.0, vec3(0.5,0.5,0.25));
|
|
1380
|
+
|
|
1381
|
+
//Circular ghosts
|
|
1382
|
+
altGhosts += fpow(1.0 - abs(distance(lensPosition*0.8,myUV) - 0.7),0.985)*colorGain / 2100.;
|
|
1383
|
+
finalColor += altGhosts;
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
|
|
1387
|
+
//Starburst
|
|
1388
|
+
if(starBurst){
|
|
1389
|
+
vTexCoord = myUV + 0.5;
|
|
1390
|
+
vec4 lensMod = getLensDirt(myUV);
|
|
1391
|
+
float tooBright = 1.0 - (clamp(0.5, 0.0, 0.5) * 2.0);
|
|
1392
|
+
float tooDark = clamp(0.5 - 0.5, 0.0, 0.5) * 2.0;
|
|
1393
|
+
lensMod += mix(lensMod, pow(lensMod * 2.0, vec4(2.0)) * 0.5, tooBright);
|
|
1394
|
+
float lensStarRotationAngle = ((myUV.x + myUV.y)) * (1.0 / 6.0);
|
|
1395
|
+
vec2 lensStarTexCoord = (mat2(cos(lensStarRotationAngle), -sin(lensStarRotationAngle), sin(lensStarRotationAngle), cos(lensStarRotationAngle)) * vTexCoord);
|
|
1396
|
+
lensMod += getLensStar(lensStarTexCoord) * 2.;
|
|
1397
|
+
|
|
1398
|
+
finalColor += clamp((lensMod.rgb * getStartBurst().rgb ), 0.01, 1.0);
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
//Final composed output
|
|
1402
|
+
if(enabled){
|
|
1403
|
+
outputColor = vec4(mix(finalColor, vec3(.0), opacity) + inputColor.rgb, inputColor.a);
|
|
1404
|
+
} else {
|
|
1405
|
+
outputColor = vec4(inputColor);
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
` };
|
|
1409
|
+
var LensFlareEffect = class extends Effect {
|
|
1410
|
+
constructor({ blendFunction = 23, enabled = true, glareSize = .2, lensPosition = new Vector3(-25, 6, -60), screenRes = new Vector2(0, 0), starPoints = 6, flareSize = .01, flareSpeed = .01, flareShape = .01, animated = true, anamorphic = false, colorGain = new Color(20, 20, 20), lensDirtTexture = null, haloScale = .5, secondaryGhosts = true, aditionalStreaks = true, ghostScale = 0, opacity = 1, starBurst = false } = {}) {
|
|
1411
|
+
super("LensFlareEffect", LensFlareShader.fragmentShader, {
|
|
1412
|
+
blendFunction,
|
|
513
1413
|
uniforms: /* @__PURE__ */ new Map([
|
|
514
|
-
["enabled", new
|
|
515
|
-
["glareSize", new
|
|
516
|
-
["lensPosition", new
|
|
517
|
-
["time", new
|
|
518
|
-
["screenRes", new
|
|
519
|
-
["starPoints", new
|
|
520
|
-
["flareSize", new
|
|
521
|
-
["flareSpeed", new
|
|
522
|
-
["flareShape", new
|
|
523
|
-
["animated", new
|
|
524
|
-
["anamorphic", new
|
|
525
|
-
["colorGain", new
|
|
526
|
-
["lensDirtTexture", new
|
|
527
|
-
["haloScale", new
|
|
528
|
-
["secondaryGhosts", new
|
|
529
|
-
["aditionalStreaks", new
|
|
530
|
-
["ghostScale", new
|
|
531
|
-
["starBurst", new
|
|
532
|
-
["opacity", new
|
|
1414
|
+
["enabled", new Uniform(enabled)],
|
|
1415
|
+
["glareSize", new Uniform(glareSize)],
|
|
1416
|
+
["lensPosition", new Uniform(lensPosition)],
|
|
1417
|
+
["time", new Uniform(0)],
|
|
1418
|
+
["screenRes", new Uniform(screenRes)],
|
|
1419
|
+
["starPoints", new Uniform(starPoints)],
|
|
1420
|
+
["flareSize", new Uniform(flareSize)],
|
|
1421
|
+
["flareSpeed", new Uniform(flareSpeed)],
|
|
1422
|
+
["flareShape", new Uniform(flareShape)],
|
|
1423
|
+
["animated", new Uniform(animated)],
|
|
1424
|
+
["anamorphic", new Uniform(anamorphic)],
|
|
1425
|
+
["colorGain", new Uniform(colorGain)],
|
|
1426
|
+
["lensDirtTexture", new Uniform(lensDirtTexture)],
|
|
1427
|
+
["haloScale", new Uniform(haloScale)],
|
|
1428
|
+
["secondaryGhosts", new Uniform(secondaryGhosts)],
|
|
1429
|
+
["aditionalStreaks", new Uniform(aditionalStreaks)],
|
|
1430
|
+
["ghostScale", new Uniform(ghostScale)],
|
|
1431
|
+
["starBurst", new Uniform(starBurst)],
|
|
1432
|
+
["opacity", new Uniform(opacity)]
|
|
533
1433
|
])
|
|
534
1434
|
});
|
|
535
1435
|
}
|
|
536
|
-
update(
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
1436
|
+
update(_renderer, _inputBuffer, deltaTime) {
|
|
1437
|
+
const time = this.uniforms.get("time");
|
|
1438
|
+
if (time) time.value += deltaTime;
|
|
1439
|
+
}
|
|
1440
|
+
u(name) {
|
|
1441
|
+
return this.uniforms.get(name).value;
|
|
1442
|
+
}
|
|
1443
|
+
setU(name, value) {
|
|
1444
|
+
this.uniforms.get(name).value = value;
|
|
1445
|
+
}
|
|
1446
|
+
get enabled() {
|
|
1447
|
+
return this.u("enabled");
|
|
1448
|
+
}
|
|
1449
|
+
set enabled(value) {
|
|
1450
|
+
this.setU("enabled", value);
|
|
1451
|
+
}
|
|
1452
|
+
get glareSize() {
|
|
1453
|
+
return this.u("glareSize");
|
|
1454
|
+
}
|
|
1455
|
+
set glareSize(value) {
|
|
1456
|
+
this.setU("glareSize", value);
|
|
1457
|
+
}
|
|
1458
|
+
get lensPosition() {
|
|
1459
|
+
return this.u("lensPosition");
|
|
1460
|
+
}
|
|
1461
|
+
set lensPosition(value) {
|
|
1462
|
+
this.setU("lensPosition", value);
|
|
1463
|
+
}
|
|
1464
|
+
get screenRes() {
|
|
1465
|
+
return this.u("screenRes");
|
|
1466
|
+
}
|
|
1467
|
+
set screenRes(value) {
|
|
1468
|
+
this.setU("screenRes", value);
|
|
1469
|
+
}
|
|
1470
|
+
get starPoints() {
|
|
1471
|
+
return this.u("starPoints");
|
|
1472
|
+
}
|
|
1473
|
+
set starPoints(value) {
|
|
1474
|
+
this.setU("starPoints", value);
|
|
1475
|
+
}
|
|
1476
|
+
get flareSize() {
|
|
1477
|
+
return this.u("flareSize");
|
|
1478
|
+
}
|
|
1479
|
+
set flareSize(value) {
|
|
1480
|
+
this.setU("flareSize", value);
|
|
1481
|
+
}
|
|
1482
|
+
get flareSpeed() {
|
|
1483
|
+
return this.u("flareSpeed");
|
|
1484
|
+
}
|
|
1485
|
+
set flareSpeed(value) {
|
|
1486
|
+
this.setU("flareSpeed", value);
|
|
1487
|
+
}
|
|
1488
|
+
get flareShape() {
|
|
1489
|
+
return this.u("flareShape");
|
|
1490
|
+
}
|
|
1491
|
+
set flareShape(value) {
|
|
1492
|
+
this.setU("flareShape", value);
|
|
1493
|
+
}
|
|
1494
|
+
get animated() {
|
|
1495
|
+
return this.u("animated");
|
|
1496
|
+
}
|
|
1497
|
+
set animated(value) {
|
|
1498
|
+
this.setU("animated", value);
|
|
1499
|
+
}
|
|
1500
|
+
get anamorphic() {
|
|
1501
|
+
return this.u("anamorphic");
|
|
1502
|
+
}
|
|
1503
|
+
set anamorphic(value) {
|
|
1504
|
+
this.setU("anamorphic", value);
|
|
1505
|
+
}
|
|
1506
|
+
get colorGain() {
|
|
1507
|
+
return this.u("colorGain");
|
|
1508
|
+
}
|
|
1509
|
+
set colorGain(value) {
|
|
1510
|
+
this.setU("colorGain", value);
|
|
1511
|
+
}
|
|
1512
|
+
get lensDirtTexture() {
|
|
1513
|
+
return this.u("lensDirtTexture");
|
|
1514
|
+
}
|
|
1515
|
+
set lensDirtTexture(value) {
|
|
1516
|
+
this.setU("lensDirtTexture", value);
|
|
1517
|
+
}
|
|
1518
|
+
get haloScale() {
|
|
1519
|
+
return this.u("haloScale");
|
|
1520
|
+
}
|
|
1521
|
+
set haloScale(value) {
|
|
1522
|
+
this.setU("haloScale", value);
|
|
1523
|
+
}
|
|
1524
|
+
get secondaryGhosts() {
|
|
1525
|
+
return this.u("secondaryGhosts");
|
|
1526
|
+
}
|
|
1527
|
+
set secondaryGhosts(value) {
|
|
1528
|
+
this.setU("secondaryGhosts", value);
|
|
1529
|
+
}
|
|
1530
|
+
get aditionalStreaks() {
|
|
1531
|
+
return this.u("aditionalStreaks");
|
|
1532
|
+
}
|
|
1533
|
+
set aditionalStreaks(value) {
|
|
1534
|
+
this.setU("aditionalStreaks", value);
|
|
1535
|
+
}
|
|
1536
|
+
get ghostScale() {
|
|
1537
|
+
return this.u("ghostScale");
|
|
1538
|
+
}
|
|
1539
|
+
set ghostScale(value) {
|
|
1540
|
+
this.setU("ghostScale", value);
|
|
1541
|
+
}
|
|
1542
|
+
get starBurst() {
|
|
1543
|
+
return this.u("starBurst");
|
|
1544
|
+
}
|
|
1545
|
+
set starBurst(value) {
|
|
1546
|
+
this.setU("starBurst", value);
|
|
1547
|
+
}
|
|
1548
|
+
get opacity() {
|
|
1549
|
+
return this.u("opacity");
|
|
1550
|
+
}
|
|
1551
|
+
set opacity(value) {
|
|
1552
|
+
this.setU("opacity", value);
|
|
1553
|
+
}
|
|
1554
|
+
};
|
|
1555
|
+
var LensFlareWrapped = /* @__PURE__ */ createEffectComponent(LensFlareEffect);
|
|
1556
|
+
var DEFAULT_SCREEN_RES = /* @__PURE__ */ new Vector2(0, 0);
|
|
1557
|
+
var DEFAULT_LENS_POSITION = /* @__PURE__ */ new Vector3(-25, 6, -60);
|
|
1558
|
+
var LensFlare = (props) => {
|
|
1559
|
+
const { ref: forwardedRef, smoothTime = .07, blendFunction = 23, enabled = true, glareSize = .2, screenRes, starPoints = 6, flareSize = .01, flareSpeed = .01, flareShape = .01, animated = true, anamorphic = false, colorGain = new Color(20, 20, 20), lensDirtTexture = null, haloScale = .5, secondaryGhosts = true, aditionalStreaks = true, ghostScale = 0, opacity = 1, starBurst = false } = props;
|
|
1560
|
+
const lensPosition = useVector3({ lensPosition: props.lensPosition ?? DEFAULT_LENS_POSITION }, "lensPosition");
|
|
1561
|
+
const viewport = useThree(({ viewport }) => viewport);
|
|
1562
|
+
const raycaster = useThree(({ raycaster }) => raycaster);
|
|
1563
|
+
const { scene, camera } = useContext(EffectComposerContext);
|
|
1564
|
+
const [raycasterPos] = useState(() => new Vector2());
|
|
1565
|
+
const [projectedPosition] = useState(() => new Vector3());
|
|
1566
|
+
const ref = useRef(null);
|
|
1567
|
+
const setRef = useMergeRefs(ref, forwardedRef);
|
|
1568
|
+
useFrame((_, delta) => {
|
|
1569
|
+
if (!ref?.current) return;
|
|
1570
|
+
const uLensPosition = ref.current.uniforms.get("lensPosition");
|
|
1571
|
+
const uOpacity = ref.current.uniforms.get("opacity");
|
|
1572
|
+
if (!uLensPosition || !uOpacity) return;
|
|
1573
|
+
let target = 0;
|
|
1574
|
+
projectedPosition.copy(lensPosition).project(camera);
|
|
1575
|
+
if (projectedPosition.z > 1) return;
|
|
1576
|
+
uLensPosition.value.x = projectedPosition.x;
|
|
1577
|
+
uLensPosition.value.y = projectedPosition.y;
|
|
1578
|
+
raycasterPos.x = projectedPosition.x;
|
|
1579
|
+
raycasterPos.y = projectedPosition.y;
|
|
1580
|
+
raycaster.setFromCamera(raycasterPos, camera);
|
|
1581
|
+
const { object } = raycaster.intersectObjects(scene.children, true)[0] || {};
|
|
1582
|
+
if (object) {
|
|
1583
|
+
target = 1;
|
|
1584
|
+
if (object.userData?.lensflare === "no-occlusion") target = 0;
|
|
1585
|
+
else if (object instanceof Mesh) {
|
|
1586
|
+
if (object.material.uniforms?._transmission?.value > .2) target = .2;
|
|
1587
|
+
else if (object.material._transmission && object.material._transmission > .2) target = .2;
|
|
1588
|
+
else if (object.material.transparent) target = object.material.opacity;
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
easing.damp(uOpacity, "value", target, smoothTime, delta);
|
|
1592
|
+
});
|
|
1593
|
+
useEffect(() => {
|
|
1594
|
+
if (!ref?.current) return;
|
|
1595
|
+
const screenRes = ref.current.uniforms.get("screenRes");
|
|
1596
|
+
if (screenRes) {
|
|
1597
|
+
screenRes.value.x = viewport.width;
|
|
1598
|
+
screenRes.value.y = viewport.height;
|
|
1599
|
+
}
|
|
1600
|
+
}, [viewport]);
|
|
1601
|
+
return /* @__PURE__ */ jsx(LensFlareWrapped, {
|
|
1602
|
+
ref: setRef,
|
|
1603
|
+
blendFunction,
|
|
1604
|
+
enabled,
|
|
1605
|
+
glareSize,
|
|
1606
|
+
lensPosition,
|
|
1607
|
+
screenRes: screenRes ?? DEFAULT_SCREEN_RES,
|
|
1608
|
+
starPoints,
|
|
1609
|
+
flareSize,
|
|
1610
|
+
flareSpeed,
|
|
1611
|
+
flareShape,
|
|
1612
|
+
animated,
|
|
1613
|
+
anamorphic,
|
|
1614
|
+
colorGain,
|
|
1615
|
+
lensDirtTexture,
|
|
1616
|
+
haloScale,
|
|
1617
|
+
secondaryGhosts,
|
|
1618
|
+
aditionalStreaks,
|
|
1619
|
+
ghostScale,
|
|
1620
|
+
opacity,
|
|
1621
|
+
starBurst
|
|
576
1622
|
});
|
|
577
1623
|
};
|
|
578
1624
|
//#endregion
|
|
579
1625
|
//#region src/effects/LUT.tsx
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
1626
|
+
var LIVE_KEYS$4 = [
|
|
1627
|
+
"blendMode-blendFunction",
|
|
1628
|
+
"lut",
|
|
1629
|
+
"tetrahedralInterpolation"
|
|
1630
|
+
];
|
|
1631
|
+
function LUT({ lut, blendFunction, tetrahedralInterpolation, ref }) {
|
|
1632
|
+
const effect = useMemo(() => new LUT3DEffect(lut), []);
|
|
1633
|
+
useLiveDefaults(effect, {
|
|
1634
|
+
"blendMode-blendFunction": blendFunction,
|
|
1635
|
+
lut,
|
|
1636
|
+
tetrahedralInterpolation
|
|
1637
|
+
}, LIVE_KEYS$4);
|
|
1638
|
+
useDispose(effect);
|
|
1639
|
+
return /* @__PURE__ */ jsx("primitive", {
|
|
1640
|
+
ref,
|
|
1641
|
+
object: effect
|
|
592
1642
|
});
|
|
593
1643
|
}
|
|
594
1644
|
//#endregion
|
|
595
1645
|
//#region src/effects/Noise.tsx
|
|
596
|
-
var
|
|
1646
|
+
var NoiseImpl = /* @__PURE__ */ createEffectComponent(NoiseEffect);
|
|
1647
|
+
function Noise({ blendFunction = 5, ...props }) {
|
|
1648
|
+
return /* @__PURE__ */ jsx(NoiseImpl, {
|
|
1649
|
+
blendFunction,
|
|
1650
|
+
...props
|
|
1651
|
+
});
|
|
1652
|
+
}
|
|
597
1653
|
//#endregion
|
|
598
1654
|
//#region src/effects/Outline.tsx
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
1655
|
+
var LIVE_KEYS$3 = [
|
|
1656
|
+
"patternTexture",
|
|
1657
|
+
"patternScale",
|
|
1658
|
+
"edgeStrength",
|
|
1659
|
+
"pulseSpeed",
|
|
1660
|
+
"visibleEdgeColor",
|
|
1661
|
+
"hiddenEdgeColor",
|
|
1662
|
+
"multisampling",
|
|
1663
|
+
"width",
|
|
1664
|
+
"height",
|
|
1665
|
+
"kernelSize",
|
|
1666
|
+
"blur",
|
|
1667
|
+
"xRay",
|
|
1668
|
+
"dithering",
|
|
1669
|
+
"blendMode-blendFunction"
|
|
1670
|
+
];
|
|
1671
|
+
function set$1(effect, key, value) {
|
|
1672
|
+
if (key === "visibleEdgeColor" || key === "hiddenEdgeColor") applyPierced(effect, key, new Color(value));
|
|
1673
|
+
else applyPierced(effect, key, value);
|
|
1674
|
+
}
|
|
1675
|
+
function Outline({ selection = EMPTY_ARRAY, selectionLayer = 10, blendFunction, resolutionScale, resolutionX, resolutionY, ref, ...liveProps }) {
|
|
1676
|
+
const { scene, camera, autoClear } = use(EffectComposerContext);
|
|
1677
|
+
const effect = useMemo(() => new OutlineEffect(scene, camera, {
|
|
1678
|
+
resolutionScale,
|
|
1679
|
+
resolutionX,
|
|
1680
|
+
resolutionY
|
|
617
1681
|
}), [
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
s,
|
|
624
|
-
c,
|
|
625
|
-
l,
|
|
626
|
-
u,
|
|
627
|
-
d,
|
|
628
|
-
f,
|
|
629
|
-
p,
|
|
630
|
-
m,
|
|
631
|
-
h,
|
|
632
|
-
g,
|
|
633
|
-
_,
|
|
634
|
-
b,
|
|
635
|
-
y
|
|
1682
|
+
scene,
|
|
1683
|
+
camera,
|
|
1684
|
+
resolutionScale,
|
|
1685
|
+
resolutionX,
|
|
1686
|
+
resolutionY
|
|
636
1687
|
]);
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
1688
|
+
useEffect(() => {
|
|
1689
|
+
if (autoClear !== false) console.warn("Outline requires <EffectComposer autoClear={false}> to render correctly.");
|
|
1690
|
+
}, [autoClear]);
|
|
1691
|
+
useLiveDefaults(effect, {
|
|
1692
|
+
...liveProps,
|
|
1693
|
+
"blendMode-blendFunction": blendFunction
|
|
1694
|
+
}, LIVE_KEYS$3, readPierced, set$1);
|
|
1695
|
+
useSelectionSync(effect, selection, selectionLayer);
|
|
1696
|
+
useDispose(effect);
|
|
1697
|
+
return /* @__PURE__ */ jsx("primitive", {
|
|
1698
|
+
ref,
|
|
1699
|
+
object: effect
|
|
640
1700
|
});
|
|
641
1701
|
}
|
|
642
1702
|
//#endregion
|
|
643
1703
|
//#region src/effects/Pixelation.tsx
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
return
|
|
647
|
-
|
|
648
|
-
|
|
1704
|
+
var PixelationImpl = /* @__PURE__ */ createEffectComponent(PixelationEffect);
|
|
1705
|
+
function Pixelation({ granularity = 5, ref }) {
|
|
1706
|
+
return /* @__PURE__ */ jsx(PixelationImpl, {
|
|
1707
|
+
granularity,
|
|
1708
|
+
ref
|
|
649
1709
|
});
|
|
650
1710
|
}
|
|
651
1711
|
//#endregion
|
|
652
1712
|
//#region src/effects/Ramp.tsx
|
|
653
|
-
var
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
1713
|
+
var RampShader = { fragmentShader: `
|
|
1714
|
+
uniform int rampType;
|
|
1715
|
+
|
|
1716
|
+
uniform vec2 rampStart;
|
|
1717
|
+
uniform vec2 rampEnd;
|
|
1718
|
+
|
|
1719
|
+
uniform vec4 startColor;
|
|
1720
|
+
uniform vec4 endColor;
|
|
1721
|
+
|
|
1722
|
+
uniform float rampBias;
|
|
1723
|
+
uniform float rampGain;
|
|
1724
|
+
|
|
1725
|
+
uniform bool rampMask;
|
|
1726
|
+
uniform bool rampInvert;
|
|
1727
|
+
|
|
1728
|
+
float getBias(float time, float bias) {
|
|
1729
|
+
return time / (((1.0 / bias) - 2.0) * (1.0 - time) + 1.0);
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
float getGain(float time, float gain) {
|
|
1733
|
+
if (time < 0.5)
|
|
1734
|
+
return getBias(time * 2.0, gain) / 2.0;
|
|
1735
|
+
else
|
|
1736
|
+
return getBias(time * 2.0 - 1.0, 1.0 - gain) / 2.0 + 0.5;
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1739
|
+
void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {
|
|
1740
|
+
vec2 centerPixel = uv * resolution;
|
|
1741
|
+
vec2 startPixel = rampStart * resolution;
|
|
1742
|
+
vec2 endPixel = rampEnd * resolution;
|
|
1743
|
+
|
|
1744
|
+
float rampAlpha;
|
|
1745
|
+
|
|
1746
|
+
if (rampType == 1) {
|
|
1747
|
+
vec2 fuv = centerPixel / resolution.y;
|
|
1748
|
+
vec2 suv = startPixel / resolution.y;
|
|
1749
|
+
vec2 euv = endPixel / resolution.y;
|
|
1750
|
+
|
|
1751
|
+
float radius = length(suv - euv);
|
|
1752
|
+
float falloff = length(fuv - suv);
|
|
1753
|
+
rampAlpha = smoothstep(0.0, radius, falloff);
|
|
1754
|
+
} else {
|
|
1755
|
+
float radius = length(startPixel - endPixel);
|
|
1756
|
+
vec2 direction = normalize(vec2(endPixel.x - startPixel.x, -(startPixel.y - endPixel.y)));
|
|
1757
|
+
|
|
1758
|
+
float fade = dot(centerPixel - startPixel, direction);
|
|
1759
|
+
if (rampType == 2) fade = abs(fade);
|
|
1760
|
+
|
|
1761
|
+
rampAlpha = smoothstep(0.0, 1.0, fade / radius);
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
rampAlpha = abs((rampInvert ? 1.0 : 0.0) - getBias(rampAlpha, rampBias) * getGain(rampAlpha, rampGain));
|
|
1765
|
+
|
|
1766
|
+
if (rampMask) {
|
|
1767
|
+
vec4 inputBuff = texture2D(inputBuffer, uv);
|
|
1768
|
+
outputColor = mix(inputBuff, inputColor, rampAlpha);
|
|
1769
|
+
} else {
|
|
1770
|
+
outputColor = mix(startColor, endColor, rampAlpha);
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
` };
|
|
1774
|
+
var RampType = /* @__PURE__ */ function(RampType) {
|
|
1775
|
+
RampType[RampType["Linear"] = 0] = "Linear";
|
|
1776
|
+
RampType[RampType["Radial"] = 1] = "Radial";
|
|
1777
|
+
RampType[RampType["MirroredLinear"] = 2] = "MirroredLinear";
|
|
1778
|
+
return RampType;
|
|
1779
|
+
}({});
|
|
1780
|
+
var RampEffect = class extends Effect {
|
|
1781
|
+
constructor({ rampType = 0, rampStart = [.5, .5], rampEnd = [1, 1], startColor = [
|
|
657
1782
|
0,
|
|
658
1783
|
0,
|
|
659
1784
|
0,
|
|
660
1785
|
1
|
|
661
|
-
], endColor
|
|
1786
|
+
], endColor = [
|
|
662
1787
|
1,
|
|
663
1788
|
1,
|
|
664
1789
|
1,
|
|
665
1790
|
1
|
|
666
|
-
], rampBias
|
|
667
|
-
super("RampEffect",
|
|
668
|
-
...
|
|
1791
|
+
], rampBias = .5, rampGain = .5, rampMask = false, rampInvert = false, ...params } = {}) {
|
|
1792
|
+
super("RampEffect", RampShader.fragmentShader, {
|
|
1793
|
+
...params,
|
|
669
1794
|
uniforms: /* @__PURE__ */ new Map([
|
|
670
|
-
["rampType", new
|
|
671
|
-
["rampStart", new
|
|
672
|
-
["rampEnd", new
|
|
673
|
-
["startColor", new
|
|
674
|
-
["endColor", new
|
|
675
|
-
["rampBias", new
|
|
676
|
-
["rampGain", new
|
|
677
|
-
["rampMask", new
|
|
678
|
-
["rampInvert", new
|
|
1795
|
+
["rampType", new Uniform(rampType)],
|
|
1796
|
+
["rampStart", new Uniform(rampStart)],
|
|
1797
|
+
["rampEnd", new Uniform(rampEnd)],
|
|
1798
|
+
["startColor", new Uniform(startColor)],
|
|
1799
|
+
["endColor", new Uniform(endColor)],
|
|
1800
|
+
["rampBias", new Uniform(rampBias)],
|
|
1801
|
+
["rampGain", new Uniform(rampGain)],
|
|
1802
|
+
["rampMask", new Uniform(rampMask)],
|
|
1803
|
+
["rampInvert", new Uniform(rampInvert)]
|
|
679
1804
|
])
|
|
680
1805
|
});
|
|
681
1806
|
}
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
1807
|
+
u(name) {
|
|
1808
|
+
return this.uniforms.get(name).value;
|
|
1809
|
+
}
|
|
1810
|
+
setU(name, value) {
|
|
1811
|
+
this.uniforms.get(name).value = value;
|
|
1812
|
+
}
|
|
1813
|
+
get rampType() {
|
|
1814
|
+
return this.u("rampType");
|
|
1815
|
+
}
|
|
1816
|
+
set rampType(value) {
|
|
1817
|
+
this.setU("rampType", value);
|
|
1818
|
+
}
|
|
1819
|
+
get rampStart() {
|
|
1820
|
+
return this.u("rampStart");
|
|
1821
|
+
}
|
|
1822
|
+
set rampStart(value) {
|
|
1823
|
+
this.setU("rampStart", value);
|
|
1824
|
+
}
|
|
1825
|
+
get rampEnd() {
|
|
1826
|
+
return this.u("rampEnd");
|
|
1827
|
+
}
|
|
1828
|
+
set rampEnd(value) {
|
|
1829
|
+
this.setU("rampEnd", value);
|
|
1830
|
+
}
|
|
1831
|
+
get startColor() {
|
|
1832
|
+
return this.u("startColor");
|
|
1833
|
+
}
|
|
1834
|
+
set startColor(value) {
|
|
1835
|
+
this.setU("startColor", value);
|
|
1836
|
+
}
|
|
1837
|
+
get endColor() {
|
|
1838
|
+
return this.u("endColor");
|
|
1839
|
+
}
|
|
1840
|
+
set endColor(value) {
|
|
1841
|
+
this.setU("endColor", value);
|
|
1842
|
+
}
|
|
1843
|
+
get rampBias() {
|
|
1844
|
+
return this.u("rampBias");
|
|
1845
|
+
}
|
|
1846
|
+
set rampBias(value) {
|
|
1847
|
+
this.setU("rampBias", value);
|
|
1848
|
+
}
|
|
1849
|
+
get rampGain() {
|
|
1850
|
+
return this.u("rampGain");
|
|
1851
|
+
}
|
|
1852
|
+
set rampGain(value) {
|
|
1853
|
+
this.setU("rampGain", value);
|
|
1854
|
+
}
|
|
1855
|
+
get rampMask() {
|
|
1856
|
+
return this.u("rampMask");
|
|
1857
|
+
}
|
|
1858
|
+
set rampMask(value) {
|
|
1859
|
+
this.setU("rampMask", value);
|
|
1860
|
+
}
|
|
1861
|
+
get rampInvert() {
|
|
1862
|
+
return this.u("rampInvert");
|
|
1863
|
+
}
|
|
1864
|
+
set rampInvert(value) {
|
|
1865
|
+
this.setU("rampInvert", value);
|
|
1866
|
+
}
|
|
1867
|
+
};
|
|
1868
|
+
var Ramp = /* @__PURE__ */ createEffectComponent(RampEffect);
|
|
1869
|
+
//#endregion
|
|
1870
|
+
//#region src/effects/ScanlineEffect.tsx
|
|
1871
|
+
var Scanline = /* @__PURE__ */ createEffectComponent(ScanlineEffect);
|
|
1872
|
+
//#endregion
|
|
1873
|
+
//#region src/effects/SelectiveBloom.tsx
|
|
1874
|
+
var addLight = (light, effect) => light.layers.enable(effect.selection.layer);
|
|
1875
|
+
var removeLight = (light, effect) => light.layers.disable(effect.selection.layer);
|
|
1876
|
+
var LIVE_KEYS$2 = [
|
|
1877
|
+
"width",
|
|
1878
|
+
"height",
|
|
1879
|
+
"kernelSize",
|
|
1880
|
+
"intensity",
|
|
1881
|
+
"inverted",
|
|
1882
|
+
"ignoreBackground"
|
|
1883
|
+
];
|
|
1884
|
+
function SelectiveBloom({ selection = EMPTY_ARRAY, selectionLayer = 10, lights = EMPTY_ARRAY, luminanceThreshold, luminanceSmoothing, mipmapBlur, radius, levels, resolutionScale, resolutionX, resolutionY, ref, ...liveProps }) {
|
|
1885
|
+
const { scene, camera } = use(EffectComposerContext);
|
|
1886
|
+
const invalidate = useThree((state) => state.invalidate);
|
|
1887
|
+
const effect = useMemo(() => new SelectiveBloomEffect(scene, camera, {
|
|
1888
|
+
blendFunction: 0,
|
|
1889
|
+
luminanceThreshold,
|
|
1890
|
+
luminanceSmoothing,
|
|
1891
|
+
mipmapBlur,
|
|
1892
|
+
radius,
|
|
1893
|
+
levels,
|
|
1894
|
+
resolutionScale,
|
|
1895
|
+
resolutionX,
|
|
1896
|
+
resolutionY
|
|
1897
|
+
}), [
|
|
1898
|
+
scene,
|
|
1899
|
+
camera,
|
|
1900
|
+
luminanceThreshold,
|
|
1901
|
+
luminanceSmoothing,
|
|
1902
|
+
mipmapBlur,
|
|
1903
|
+
radius,
|
|
1904
|
+
levels,
|
|
1905
|
+
resolutionScale,
|
|
1906
|
+
resolutionX,
|
|
1907
|
+
resolutionY
|
|
721
1908
|
]);
|
|
722
|
-
|
|
723
|
-
|
|
1909
|
+
useLiveDefaults(effect, liveProps, LIVE_KEYS$2);
|
|
1910
|
+
useSelectionSync(effect, selection, selectionLayer);
|
|
1911
|
+
useEffect(() => {
|
|
1912
|
+
if (lights.length === 0) {
|
|
724
1913
|
console.warn("SelectiveBloom requires lights to work.");
|
|
725
1914
|
return;
|
|
726
1915
|
}
|
|
727
|
-
|
|
728
|
-
if (
|
|
729
|
-
|
|
1916
|
+
const resolvedLights = lights.map((light) => resolveRef(light)).filter((light) => light != null);
|
|
1917
|
+
if (resolvedLights.length === 0) return;
|
|
1918
|
+
resolvedLights.forEach((light) => addLight(light, effect));
|
|
1919
|
+
invalidate();
|
|
1920
|
+
return () => {
|
|
1921
|
+
resolvedLights.forEach((light) => removeLight(light, effect));
|
|
1922
|
+
invalidate();
|
|
730
1923
|
};
|
|
731
1924
|
}, [
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
])
|
|
737
|
-
|
|
738
|
-
|
|
1925
|
+
effect,
|
|
1926
|
+
invalidate,
|
|
1927
|
+
lights,
|
|
1928
|
+
selectionLayer
|
|
1929
|
+
]);
|
|
1930
|
+
useDispose(effect);
|
|
1931
|
+
return /* @__PURE__ */ jsx("primitive", {
|
|
1932
|
+
ref,
|
|
1933
|
+
object: effect
|
|
739
1934
|
});
|
|
740
1935
|
}
|
|
741
1936
|
//#endregion
|
|
742
1937
|
//#region src/effects/Sepia.tsx
|
|
743
|
-
var
|
|
1938
|
+
var Sepia = /* @__PURE__ */ createEffectComponent(SepiaEffect);
|
|
1939
|
+
//#endregion
|
|
1940
|
+
//#region src/effects/ShockWave.tsx
|
|
1941
|
+
var LIVE_KEYS$1 = [
|
|
1942
|
+
"position",
|
|
1943
|
+
"speed",
|
|
1944
|
+
"maxRadius",
|
|
1945
|
+
"waveSize",
|
|
1946
|
+
"amplitude"
|
|
1947
|
+
];
|
|
1948
|
+
function ShockWave(props) {
|
|
1949
|
+
const { speed, maxRadius, waveSize, amplitude, ref } = props;
|
|
1950
|
+
const { camera } = use(EffectComposerContext);
|
|
1951
|
+
const effect = useMemo(() => new ShockWaveEffect(camera), [camera]);
|
|
1952
|
+
useLiveDefaults(effect, {
|
|
1953
|
+
position: useVector3(props, "position"),
|
|
1954
|
+
speed,
|
|
1955
|
+
maxRadius,
|
|
1956
|
+
waveSize,
|
|
1957
|
+
amplitude
|
|
1958
|
+
}, LIVE_KEYS$1);
|
|
1959
|
+
useDispose(effect);
|
|
1960
|
+
return /* @__PURE__ */ jsx("primitive", {
|
|
1961
|
+
ref,
|
|
1962
|
+
object: effect
|
|
1963
|
+
});
|
|
1964
|
+
}
|
|
1965
|
+
//#endregion
|
|
1966
|
+
//#region src/effects/SMAA.tsx
|
|
1967
|
+
var SMAAImpl = /* @__PURE__ */ createEffectComponent(SMAAEffect);
|
|
1968
|
+
function SMAA({ preset, edgeDetectionMode, predicationMode, ...liveProps }) {
|
|
1969
|
+
const args = useMemo(() => [{
|
|
1970
|
+
preset,
|
|
1971
|
+
edgeDetectionMode,
|
|
1972
|
+
predicationMode
|
|
1973
|
+
}], [
|
|
1974
|
+
preset,
|
|
1975
|
+
edgeDetectionMode,
|
|
1976
|
+
predicationMode
|
|
1977
|
+
]);
|
|
1978
|
+
return /* @__PURE__ */ jsx(SMAAImpl, {
|
|
1979
|
+
args,
|
|
1980
|
+
...liveProps
|
|
1981
|
+
});
|
|
1982
|
+
}
|
|
744
1983
|
//#endregion
|
|
745
1984
|
//#region src/effects/SSAO.tsx
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
1985
|
+
var LIVE_KEYS = [
|
|
1986
|
+
"blendMode-blendFunction",
|
|
1987
|
+
"normalBuffer",
|
|
1988
|
+
"samples",
|
|
1989
|
+
"rings",
|
|
1990
|
+
"radius",
|
|
1991
|
+
"depthAwareUpsampling",
|
|
1992
|
+
"color",
|
|
1993
|
+
"luminanceInfluence",
|
|
1994
|
+
"intensity",
|
|
1995
|
+
"ssaoMaterial-bias",
|
|
1996
|
+
"ssaoMaterial-fade",
|
|
1997
|
+
"ssaoMaterial-minRadiusScale",
|
|
1998
|
+
"ssaoMaterial-distanceThreshold",
|
|
1999
|
+
"ssaoMaterial-distanceFalloff",
|
|
2000
|
+
"ssaoMaterial-worldDistanceThreshold",
|
|
2001
|
+
"ssaoMaterial-worldDistanceFalloff",
|
|
2002
|
+
"rangeThreshold",
|
|
2003
|
+
"rangeFalloff",
|
|
2004
|
+
"ssaoMaterial-worldProximityThreshold",
|
|
2005
|
+
"ssaoMaterial-worldProximityFalloff"
|
|
2006
|
+
];
|
|
2007
|
+
function get(effect, key) {
|
|
2008
|
+
if (key === "rangeThreshold") return effect.ssaoMaterial.proximityThreshold;
|
|
2009
|
+
if (key === "rangeFalloff") return effect.ssaoMaterial.proximityFalloff;
|
|
2010
|
+
return readPierced(effect, key);
|
|
2011
|
+
}
|
|
2012
|
+
function set(effect, key, value) {
|
|
2013
|
+
if (key === "rangeThreshold") effect.ssaoMaterial.proximityThreshold = value;
|
|
2014
|
+
else if (key === "rangeFalloff") effect.ssaoMaterial.proximityFalloff = value;
|
|
2015
|
+
else applyPierced(effect, key, value);
|
|
2016
|
+
}
|
|
2017
|
+
function SSAO({ blendFunction = 21, samples = 30, rings = 4, distanceThreshold = 1, distanceFalloff = 0, rangeThreshold = .5, rangeFalloff = .1, luminanceInfluence = .9, radius = 20, bias = .5, intensity = 1, color, worldDistanceThreshold, worldDistanceFalloff, worldProximityThreshold, worldProximityFalloff, minRadiusScale, fade, depthAwareUpsampling = true, resolutionScale, resolutionX, resolutionY, width, height, ref }) {
|
|
2018
|
+
const { camera, normalPass, downSamplingPass, resolutionScale: composerResolutionScale } = use(EffectComposerContext);
|
|
2019
|
+
const effect = useMemo(() => {
|
|
2020
|
+
if (normalPass === null && downSamplingPass === null) {
|
|
2021
|
+
console.error("Please enable the NormalPass in the EffectComposer in order to use SSAO.");
|
|
2022
|
+
return {};
|
|
2023
|
+
}
|
|
2024
|
+
return new SSAOEffect(camera, normalPass && !downSamplingPass ? normalPass.texture : null, {
|
|
2025
|
+
blendFunction,
|
|
2026
|
+
samples,
|
|
2027
|
+
rings,
|
|
2028
|
+
distanceThreshold,
|
|
2029
|
+
distanceFalloff,
|
|
2030
|
+
rangeThreshold,
|
|
2031
|
+
rangeFalloff,
|
|
2032
|
+
luminanceInfluence,
|
|
2033
|
+
radius,
|
|
2034
|
+
bias,
|
|
2035
|
+
intensity,
|
|
2036
|
+
normalDepthBuffer: downSamplingPass ? downSamplingPass.texture : null,
|
|
2037
|
+
resolutionScale: resolutionScale ?? composerResolutionScale ?? 1,
|
|
2038
|
+
resolutionX,
|
|
2039
|
+
resolutionY,
|
|
2040
|
+
width,
|
|
2041
|
+
height,
|
|
2042
|
+
depthAwareUpsampling
|
|
2043
|
+
});
|
|
2044
|
+
}, [
|
|
2045
|
+
camera,
|
|
2046
|
+
downSamplingPass,
|
|
2047
|
+
normalPass,
|
|
2048
|
+
resolutionScale,
|
|
2049
|
+
composerResolutionScale,
|
|
2050
|
+
resolutionX,
|
|
2051
|
+
resolutionY,
|
|
2052
|
+
width,
|
|
2053
|
+
height
|
|
769
2054
|
]);
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
2055
|
+
useLiveDefaults(effect instanceof SSAOEffect ? effect : null, {
|
|
2056
|
+
"blendMode-blendFunction": blendFunction,
|
|
2057
|
+
samples,
|
|
2058
|
+
rings,
|
|
2059
|
+
radius,
|
|
2060
|
+
depthAwareUpsampling,
|
|
2061
|
+
color,
|
|
2062
|
+
luminanceInfluence,
|
|
2063
|
+
intensity,
|
|
2064
|
+
"ssaoMaterial-bias": bias,
|
|
2065
|
+
"ssaoMaterial-fade": fade,
|
|
2066
|
+
"ssaoMaterial-minRadiusScale": minRadiusScale,
|
|
2067
|
+
"ssaoMaterial-distanceThreshold": distanceThreshold,
|
|
2068
|
+
"ssaoMaterial-distanceFalloff": distanceFalloff,
|
|
2069
|
+
"ssaoMaterial-worldDistanceThreshold": worldDistanceThreshold,
|
|
2070
|
+
"ssaoMaterial-worldDistanceFalloff": worldDistanceFalloff,
|
|
2071
|
+
rangeThreshold,
|
|
2072
|
+
rangeFalloff,
|
|
2073
|
+
"ssaoMaterial-worldProximityThreshold": worldProximityThreshold,
|
|
2074
|
+
"ssaoMaterial-worldProximityFalloff": worldProximityFalloff
|
|
2075
|
+
}, LIVE_KEYS, get, set);
|
|
2076
|
+
useDispose(effect);
|
|
2077
|
+
return /* @__PURE__ */ jsx("primitive", {
|
|
2078
|
+
ref,
|
|
2079
|
+
object: effect
|
|
773
2080
|
});
|
|
774
2081
|
}
|
|
775
2082
|
//#endregion
|
|
776
2083
|
//#region src/effects/Texture.tsx
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
object: s,
|
|
789
|
-
"blendMode-opacity-value": n
|
|
2084
|
+
var TextureImpl = /* @__PURE__ */ createEffectComponent(TextureEffect);
|
|
2085
|
+
function Texture({ textureSrc, texture, opacity = 1, ...props }) {
|
|
2086
|
+
const t = useLoader(TextureLoader, textureSrc);
|
|
2087
|
+
useLayoutEffect(() => {
|
|
2088
|
+
t.colorSpace = SRGBColorSpace;
|
|
2089
|
+
t.wrapS = t.wrapT = RepeatWrapping;
|
|
2090
|
+
}, [t]);
|
|
2091
|
+
return /* @__PURE__ */ jsx(TextureImpl, {
|
|
2092
|
+
...props,
|
|
2093
|
+
texture: texture ?? t,
|
|
2094
|
+
opacity
|
|
790
2095
|
});
|
|
791
2096
|
}
|
|
792
2097
|
//#endregion
|
|
793
2098
|
//#region src/effects/TiltShift.tsx
|
|
794
|
-
var
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
2099
|
+
var TiltShiftImpl = /* @__PURE__ */ createEffectComponent(TiltShiftEffect$1);
|
|
2100
|
+
function TiltShift({ blendFunction = 0, kernelSize, resolutionScale, resolutionX, resolutionY, ...liveProps }) {
|
|
2101
|
+
const args = useMemo(() => [{
|
|
2102
|
+
kernelSize,
|
|
2103
|
+
resolutionScale,
|
|
2104
|
+
resolutionX,
|
|
2105
|
+
resolutionY
|
|
2106
|
+
}], [
|
|
2107
|
+
kernelSize,
|
|
2108
|
+
resolutionScale,
|
|
2109
|
+
resolutionX,
|
|
2110
|
+
resolutionY
|
|
2111
|
+
]);
|
|
2112
|
+
return /* @__PURE__ */ jsx(TiltShiftImpl, {
|
|
2113
|
+
blendFunction,
|
|
2114
|
+
args,
|
|
2115
|
+
...liveProps
|
|
2116
|
+
});
|
|
2117
|
+
}
|
|
2118
|
+
//#endregion
|
|
2119
|
+
//#region src/effects/TiltShift2.tsx
|
|
2120
|
+
var TiltShiftShader = { fragmentShader: `
|
|
2121
|
+
|
|
2122
|
+
// original shader by Evan Wallace
|
|
2123
|
+
|
|
2124
|
+
#define MAX_ITERATIONS 100
|
|
2125
|
+
|
|
2126
|
+
uniform float blur;
|
|
2127
|
+
uniform float taper;
|
|
2128
|
+
uniform vec2 start;
|
|
2129
|
+
uniform vec2 end;
|
|
2130
|
+
uniform vec2 direction;
|
|
2131
|
+
uniform int samples;
|
|
2132
|
+
|
|
2133
|
+
float random(vec3 scale, float seed) {
|
|
2134
|
+
/* use the fragment position for a different seed per-pixel */
|
|
2135
|
+
return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {
|
|
2139
|
+
vec4 color = vec4(0.0);
|
|
2140
|
+
float total = 0.0;
|
|
2141
|
+
vec2 startPixel = vec2(start.x * resolution.x, start.y * resolution.y);
|
|
2142
|
+
vec2 endPixel = vec2(end.x * resolution.x, end.y * resolution.y);
|
|
2143
|
+
float f_samples = float(samples);
|
|
2144
|
+
float half_samples = f_samples / 2.0;
|
|
2145
|
+
|
|
2146
|
+
// use screen diagonal to normalize blur radii
|
|
2147
|
+
float maxScreenDistance = distance(vec2(0.0), resolution); // diagonal distance
|
|
2148
|
+
float gradientRadius = taper * (maxScreenDistance);
|
|
2149
|
+
float blurRadius = blur * (maxScreenDistance / 16.0);
|
|
2150
|
+
|
|
2151
|
+
/* randomize the lookup values to hide the fixed number of samples */
|
|
2152
|
+
float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);
|
|
2153
|
+
vec2 normal = normalize(vec2(startPixel.y - endPixel.y, endPixel.x - startPixel.x));
|
|
2154
|
+
float radius = smoothstep(0.0, 1.0, abs(dot(uv * resolution - startPixel, normal)) / gradientRadius) * blurRadius;
|
|
2155
|
+
|
|
2156
|
+
#pragma unroll_loop_start
|
|
2157
|
+
for (int i = 0; i <= MAX_ITERATIONS; i++) {
|
|
2158
|
+
if (i >= samples) { break; } // return early if over sample count
|
|
2159
|
+
float f_i = float(i);
|
|
2160
|
+
float s_i = -half_samples + f_i;
|
|
2161
|
+
float percent = (s_i + offset - 0.5) / half_samples;
|
|
2162
|
+
float weight = 1.0 - abs(percent);
|
|
2163
|
+
vec4 sample_i = texture2D(inputBuffer, uv + normalize(direction) / resolution * percent * radius);
|
|
2164
|
+
/* switch to pre-multiplied alpha to correctly blur transparent images */
|
|
2165
|
+
sample_i.rgb *= sample_i.a;
|
|
2166
|
+
color += sample_i * weight;
|
|
2167
|
+
total += weight;
|
|
2168
|
+
}
|
|
2169
|
+
#pragma unroll_loop_end
|
|
2170
|
+
|
|
2171
|
+
outputColor = color / total;
|
|
2172
|
+
|
|
2173
|
+
/* switch back from pre-multiplied alpha */
|
|
2174
|
+
outputColor.rgb /= outputColor.a + 0.00001;
|
|
2175
|
+
}
|
|
2176
|
+
` };
|
|
2177
|
+
var TiltShiftEffect = class extends Effect {
|
|
2178
|
+
constructor({ blendFunction = 23, blur = .15, taper = .5, start = [.5, 0], end = [.5, 1], samples = 10, direction = [1, 1] } = {}) {
|
|
2179
|
+
super("TiltShiftEffect", TiltShiftShader.fragmentShader, {
|
|
2180
|
+
blendFunction,
|
|
798
2181
|
attributes: 2,
|
|
799
2182
|
uniforms: /* @__PURE__ */ new Map([
|
|
800
|
-
["blur", new
|
|
801
|
-
["taper", new
|
|
802
|
-
["start", new
|
|
803
|
-
["end", new
|
|
804
|
-
["samples", new
|
|
805
|
-
["direction", new
|
|
2183
|
+
["blur", new Uniform(blur)],
|
|
2184
|
+
["taper", new Uniform(taper)],
|
|
2185
|
+
["start", new Uniform(start)],
|
|
2186
|
+
["end", new Uniform(end)],
|
|
2187
|
+
["samples", new Uniform(samples)],
|
|
2188
|
+
["direction", new Uniform(direction)]
|
|
806
2189
|
])
|
|
807
2190
|
});
|
|
808
2191
|
}
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
2192
|
+
u(name) {
|
|
2193
|
+
return this.uniforms.get(name).value;
|
|
2194
|
+
}
|
|
2195
|
+
setU(name, value) {
|
|
2196
|
+
this.uniforms.get(name).value = value;
|
|
2197
|
+
}
|
|
2198
|
+
get blur() {
|
|
2199
|
+
return this.u("blur");
|
|
2200
|
+
}
|
|
2201
|
+
set blur(value) {
|
|
2202
|
+
this.setU("blur", value);
|
|
2203
|
+
}
|
|
2204
|
+
get taper() {
|
|
2205
|
+
return this.u("taper");
|
|
2206
|
+
}
|
|
2207
|
+
set taper(value) {
|
|
2208
|
+
this.setU("taper", value);
|
|
2209
|
+
}
|
|
2210
|
+
get start() {
|
|
2211
|
+
return this.u("start");
|
|
2212
|
+
}
|
|
2213
|
+
set start(value) {
|
|
2214
|
+
this.setU("start", value);
|
|
2215
|
+
}
|
|
2216
|
+
get end() {
|
|
2217
|
+
return this.u("end");
|
|
2218
|
+
}
|
|
2219
|
+
set end(value) {
|
|
2220
|
+
this.setU("end", value);
|
|
2221
|
+
}
|
|
2222
|
+
get samples() {
|
|
2223
|
+
return this.u("samples");
|
|
2224
|
+
}
|
|
2225
|
+
set samples(value) {
|
|
2226
|
+
this.setU("samples", value);
|
|
2227
|
+
}
|
|
2228
|
+
get direction() {
|
|
2229
|
+
return this.u("direction");
|
|
2230
|
+
}
|
|
2231
|
+
set direction(value) {
|
|
2232
|
+
this.setU("direction", value);
|
|
2233
|
+
}
|
|
2234
|
+
};
|
|
2235
|
+
var TiltShift2 = /* @__PURE__ */ createEffectComponent(TiltShiftEffect);
|
|
2236
|
+
//#endregion
|
|
2237
|
+
//#region src/effects/ToneMapping.tsx
|
|
2238
|
+
var ToneMappingImpl = /* @__PURE__ */ createEffectComponent(ToneMappingEffect);
|
|
2239
|
+
function ToneMapping({ minLuminance, maxLuminance, ...liveProps }) {
|
|
2240
|
+
const args = useMemo(() => [{
|
|
2241
|
+
minLuminance,
|
|
2242
|
+
maxLuminance
|
|
2243
|
+
}], [minLuminance, maxLuminance]);
|
|
2244
|
+
return /* @__PURE__ */ jsx(ToneMappingImpl, {
|
|
2245
|
+
args,
|
|
2246
|
+
...liveProps
|
|
2247
|
+
});
|
|
2248
|
+
}
|
|
2249
|
+
//#endregion
|
|
2250
|
+
//#region src/effects/Vignette.tsx
|
|
2251
|
+
var Vignette = /* @__PURE__ */ createEffectComponent(VignetteEffect);
|
|
2252
|
+
//#endregion
|
|
2253
|
+
//#region src/effects/Water.tsx
|
|
2254
|
+
var WaterShader = { fragmentShader: `
|
|
2255
|
+
uniform float factor;
|
|
2256
|
+
|
|
2257
|
+
void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {
|
|
2258
|
+
vec2 vUv = uv;
|
|
2259
|
+
float frequency = 6.0 * factor;
|
|
2260
|
+
float amplitude = 0.015 * factor;
|
|
2261
|
+
float x = vUv.y * frequency + time * 0.7;
|
|
2262
|
+
float y = vUv.x * frequency + time * 0.3;
|
|
2263
|
+
vUv.x += cos(x + y) * amplitude * cos(y);
|
|
2264
|
+
vUv.y += sin(x - y) * amplitude * cos(y);
|
|
2265
|
+
vec4 rgba = texture(inputBuffer, vUv);
|
|
2266
|
+
outputColor = rgba;
|
|
2267
|
+
}
|
|
2268
|
+
` };
|
|
2269
|
+
var WaterEffectImpl = class extends Effect {
|
|
2270
|
+
constructor({ blendFunction = 23, factor = 0 } = {}) {
|
|
2271
|
+
super("WaterEffect", WaterShader.fragmentShader, {
|
|
2272
|
+
blendFunction,
|
|
813
2273
|
attributes: 2,
|
|
814
|
-
uniforms: /* @__PURE__ */ new Map([["factor", new
|
|
2274
|
+
uniforms: /* @__PURE__ */ new Map([["factor", new Uniform(factor)]])
|
|
815
2275
|
});
|
|
816
2276
|
}
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
2277
|
+
get factor() {
|
|
2278
|
+
return this.uniforms.get("factor").value;
|
|
2279
|
+
}
|
|
2280
|
+
set factor(value) {
|
|
2281
|
+
this.uniforms.get("factor").value = value;
|
|
2282
|
+
}
|
|
2283
|
+
};
|
|
2284
|
+
var WaterEffect = /* @__PURE__ */ createEffectComponent(WaterEffectImpl);
|
|
2285
|
+
//#endregion
|
|
2286
|
+
//#region src/passes/N8AO.tsx
|
|
2287
|
+
function N8AO({ enabled = true, halfRes, screenSpaceRadius, quality, depthAwareUpsampling = true, aoRadius = 5, aoSamples = 16, denoiseSamples = 4, denoiseRadius = 12, distanceFalloff = 1, intensity = 1, color, renderMode = 0, ref }) {
|
|
2288
|
+
const { camera, scene, invalidate } = useThree();
|
|
2289
|
+
const effect = useMemo(() => {
|
|
2290
|
+
const instance = new N8AOPostPass(scene, camera);
|
|
2291
|
+
groupPasses.add(instance);
|
|
2292
|
+
return instance;
|
|
2293
|
+
}, [camera, scene]);
|
|
2294
|
+
useDispose(effect);
|
|
2295
|
+
useLayoutEffect(() => {
|
|
2296
|
+
effect.enabled = enabled;
|
|
2297
|
+
invalidate();
|
|
2298
|
+
}, [
|
|
2299
|
+
effect,
|
|
2300
|
+
enabled,
|
|
2301
|
+
invalidate
|
|
2302
|
+
]);
|
|
2303
|
+
useLayoutEffect(() => {
|
|
2304
|
+
applyProps(effect.configuration, {
|
|
2305
|
+
color,
|
|
2306
|
+
aoRadius,
|
|
2307
|
+
distanceFalloff,
|
|
2308
|
+
intensity,
|
|
2309
|
+
aoSamples,
|
|
2310
|
+
denoiseSamples,
|
|
2311
|
+
denoiseRadius,
|
|
2312
|
+
screenSpaceRadius,
|
|
2313
|
+
renderMode,
|
|
2314
|
+
halfRes,
|
|
2315
|
+
depthAwareUpsampling
|
|
835
2316
|
});
|
|
2317
|
+
invalidate();
|
|
836
2318
|
}, [
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
2319
|
+
screenSpaceRadius,
|
|
2320
|
+
color,
|
|
2321
|
+
aoRadius,
|
|
2322
|
+
distanceFalloff,
|
|
2323
|
+
intensity,
|
|
2324
|
+
aoSamples,
|
|
2325
|
+
denoiseSamples,
|
|
2326
|
+
denoiseRadius,
|
|
2327
|
+
renderMode,
|
|
2328
|
+
halfRes,
|
|
2329
|
+
depthAwareUpsampling,
|
|
2330
|
+
effect,
|
|
2331
|
+
invalidate
|
|
2332
|
+
]);
|
|
2333
|
+
useLayoutEffect(() => {
|
|
2334
|
+
if (quality) {
|
|
2335
|
+
effect.setQualityMode(quality.charAt(0).toUpperCase() + quality.slice(1));
|
|
2336
|
+
invalidate();
|
|
2337
|
+
}
|
|
2338
|
+
}, [
|
|
2339
|
+
effect,
|
|
2340
|
+
quality,
|
|
2341
|
+
invalidate
|
|
2342
|
+
]);
|
|
2343
|
+
return /* @__PURE__ */ jsx("primitive", {
|
|
2344
|
+
ref,
|
|
2345
|
+
object: effect
|
|
854
2346
|
});
|
|
855
2347
|
}
|
|
856
2348
|
//#endregion
|
|
857
|
-
export {
|
|
2349
|
+
export { ASCII, Autofocus, Bloom, BrightnessContrast, ChromaticAberration, ColorAverage, ColorDepth, Depth, DepthOfField, DepthPicking, DotScreen, EMPTY_ARRAY, EffectComposer, EffectComposerContext, EffectGroup, FXAA, Glitch, GodRays, Grid, HueSaturation, LUT, LensFlare, LensFlareEffect, N8AO, Noise, Outline, Pixelation, Ramp, RampEffect, RampType, SMAA, SSAO, Scanline, Select, Selection, SelectiveBloom, Sepia, ShockWave, Texture, TiltShift, TiltShift2, TiltShiftEffect, ToneMapping, Vignette, WaterEffect, WaterEffectImpl, applyPierced, createEffectComponent, disposePassWithoutEffects, groupPasses, readGroupChildren, readPierced, resolveRef, selectionContext, updateIfChanged, useDepthPicking, useDispose, useLiveDefaults, useMergeRefs, useSelectionSync, useVector2, useVector3, wrapEffect };
|
|
858
2350
|
|
|
859
2351
|
//# sourceMappingURL=index.js.map
|