@react-three/postprocessing 2.15.0 → 2.15.2

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.
Files changed (157) hide show
  1. package/dist/EffectComposer.cjs +126 -0
  2. package/dist/EffectComposer.cjs.map +1 -0
  3. package/dist/EffectComposer.js +126 -0
  4. package/dist/EffectComposer.js.map +1 -0
  5. package/dist/Selection.cjs +36 -0
  6. package/dist/Selection.cjs.map +1 -0
  7. package/dist/Selection.js +36 -0
  8. package/dist/Selection.js.map +1 -0
  9. package/dist/effects/ASCII.cjs +105 -0
  10. package/dist/effects/ASCII.cjs.map +1 -0
  11. package/dist/effects/ASCII.js +105 -0
  12. package/dist/effects/ASCII.js.map +1 -0
  13. package/dist/effects/Autofocus.cjs +126 -0
  14. package/dist/effects/Autofocus.cjs.map +1 -0
  15. package/dist/effects/Autofocus.js +109 -0
  16. package/dist/effects/Autofocus.js.map +1 -0
  17. package/dist/effects/Bloom.cjs +9 -0
  18. package/dist/effects/Bloom.cjs.map +1 -0
  19. package/dist/effects/Bloom.js +9 -0
  20. package/dist/effects/Bloom.js.map +1 -0
  21. package/dist/effects/BrightnessContrast.cjs +7 -0
  22. package/dist/effects/BrightnessContrast.cjs.map +1 -0
  23. package/dist/effects/BrightnessContrast.js +7 -0
  24. package/dist/effects/BrightnessContrast.js.map +1 -0
  25. package/dist/effects/ChromaticAberration.cjs +7 -0
  26. package/dist/effects/ChromaticAberration.cjs.map +1 -0
  27. package/dist/effects/ChromaticAberration.js +7 -0
  28. package/dist/effects/ChromaticAberration.js.map +1 -0
  29. package/dist/effects/ColorAverage.cjs +11 -0
  30. package/dist/effects/ColorAverage.cjs.map +1 -0
  31. package/dist/effects/ColorAverage.js +11 -0
  32. package/dist/effects/ColorAverage.js.map +1 -0
  33. package/dist/effects/ColorDepth.cjs +7 -0
  34. package/dist/effects/ColorDepth.cjs.map +1 -0
  35. package/dist/effects/ColorDepth.js +7 -0
  36. package/dist/effects/ColorDepth.js.map +1 -0
  37. package/dist/effects/Depth.cjs +7 -0
  38. package/dist/effects/Depth.cjs.map +1 -0
  39. package/dist/effects/Depth.js +7 -0
  40. package/dist/effects/Depth.js.map +1 -0
  41. package/dist/effects/DepthOfField.cjs +74 -0
  42. package/dist/effects/DepthOfField.cjs.map +1 -0
  43. package/dist/effects/DepthOfField.js +74 -0
  44. package/dist/effects/DepthOfField.js.map +1 -0
  45. package/dist/effects/DotScreen.cjs +7 -0
  46. package/dist/effects/DotScreen.cjs.map +1 -0
  47. package/dist/effects/DotScreen.js +7 -0
  48. package/dist/effects/DotScreen.js.map +1 -0
  49. package/dist/effects/FXAA.cjs +7 -0
  50. package/dist/effects/FXAA.cjs.map +1 -0
  51. package/dist/effects/FXAA.js +7 -0
  52. package/dist/effects/FXAA.js.map +1 -0
  53. package/dist/effects/Glitch.cjs +30 -0
  54. package/dist/effects/Glitch.cjs.map +1 -0
  55. package/dist/effects/Glitch.js +30 -0
  56. package/dist/effects/Glitch.js.map +1 -0
  57. package/dist/effects/GodRays.cjs +15 -0
  58. package/dist/effects/GodRays.cjs.map +1 -0
  59. package/dist/effects/GodRays.js +15 -0
  60. package/dist/effects/GodRays.js.map +1 -0
  61. package/dist/effects/Grid.cjs +18 -0
  62. package/dist/effects/Grid.cjs.map +1 -0
  63. package/dist/effects/Grid.js +18 -0
  64. package/dist/effects/Grid.js.map +1 -0
  65. package/dist/effects/HueSaturation.cjs +7 -0
  66. package/dist/effects/HueSaturation.cjs.map +1 -0
  67. package/dist/effects/HueSaturation.js +7 -0
  68. package/dist/effects/HueSaturation.js.map +1 -0
  69. package/dist/effects/LUT.cjs +20 -0
  70. package/dist/effects/LUT.cjs.map +1 -0
  71. package/dist/effects/LUT.js +20 -0
  72. package/dist/effects/LUT.js.map +1 -0
  73. package/dist/effects/LensFlare.cjs +189 -0
  74. package/dist/effects/LensFlare.cjs.map +1 -0
  75. package/dist/effects/LensFlare.js +172 -0
  76. package/dist/effects/LensFlare.js.map +1 -0
  77. package/dist/effects/N8AO.cjs +59 -0
  78. package/dist/effects/N8AO.cjs.map +1 -0
  79. package/dist/effects/N8AO.js +59 -0
  80. package/dist/effects/N8AO.js.map +1 -0
  81. package/dist/effects/Noise.cjs +7 -0
  82. package/dist/effects/Noise.cjs.map +1 -0
  83. package/dist/effects/Noise.js +7 -0
  84. package/dist/effects/Noise.js.map +1 -0
  85. package/dist/effects/Outline.cjs +93 -0
  86. package/dist/effects/Outline.cjs.map +1 -0
  87. package/dist/effects/Outline.js +93 -0
  88. package/dist/effects/Outline.js.map +1 -0
  89. package/dist/effects/Pixelation.cjs +11 -0
  90. package/dist/effects/Pixelation.cjs.map +1 -0
  91. package/dist/effects/Pixelation.js +11 -0
  92. package/dist/effects/Pixelation.js.map +1 -0
  93. package/dist/effects/SMAA.cjs +7 -0
  94. package/dist/effects/SMAA.cjs.map +1 -0
  95. package/dist/effects/SMAA.js +7 -0
  96. package/dist/effects/SMAA.js.map +1 -0
  97. package/dist/effects/SSAO.cjs +37 -0
  98. package/dist/effects/SSAO.cjs.map +1 -0
  99. package/dist/effects/SSAO.js +37 -0
  100. package/dist/effects/SSAO.js.map +1 -0
  101. package/dist/effects/SSR/index.cjs +33 -0
  102. package/dist/effects/SSR/index.cjs.map +1 -0
  103. package/dist/effects/SSR/index.js +33 -0
  104. package/dist/effects/SSR/index.js.map +1 -0
  105. package/dist/effects/SSR/screen-space-reflections.cjs +1133 -0
  106. package/dist/effects/SSR/screen-space-reflections.cjs.map +1 -0
  107. package/dist/effects/SSR/screen-space-reflections.js +1133 -0
  108. package/dist/effects/SSR/screen-space-reflections.js.map +1 -0
  109. package/dist/effects/ScanlineEffect.cjs +7 -0
  110. package/dist/effects/ScanlineEffect.cjs.map +1 -0
  111. package/dist/effects/ScanlineEffect.js +7 -0
  112. package/dist/effects/ScanlineEffect.js.map +1 -0
  113. package/dist/effects/SelectiveBloom.cjs +87 -0
  114. package/dist/effects/SelectiveBloom.cjs.map +1 -0
  115. package/dist/effects/SelectiveBloom.js +87 -0
  116. package/dist/effects/SelectiveBloom.js.map +1 -0
  117. package/dist/effects/Sepia.cjs +7 -0
  118. package/dist/effects/Sepia.cjs.map +1 -0
  119. package/dist/effects/Sepia.js +7 -0
  120. package/dist/effects/Sepia.js.map +1 -0
  121. package/dist/effects/ShockWave.cjs +7 -0
  122. package/dist/effects/ShockWave.cjs.map +1 -0
  123. package/dist/effects/ShockWave.js +7 -0
  124. package/dist/effects/ShockWave.js.map +1 -0
  125. package/dist/effects/Texture.cjs +18 -0
  126. package/dist/effects/Texture.cjs.map +1 -0
  127. package/dist/effects/Texture.js +18 -0
  128. package/dist/effects/Texture.js.map +1 -0
  129. package/dist/effects/TiltShift.cjs +7 -0
  130. package/dist/effects/TiltShift.cjs.map +1 -0
  131. package/dist/effects/TiltShift.js +7 -0
  132. package/dist/effects/TiltShift.js.map +1 -0
  133. package/dist/effects/TiltShift2.cjs +98 -0
  134. package/dist/effects/TiltShift2.cjs.map +1 -0
  135. package/dist/effects/TiltShift2.js +98 -0
  136. package/dist/effects/TiltShift2.js.map +1 -0
  137. package/dist/effects/ToneMapping.cjs +7 -0
  138. package/dist/effects/ToneMapping.cjs.map +1 -0
  139. package/dist/effects/ToneMapping.js +7 -0
  140. package/dist/effects/ToneMapping.js.map +1 -0
  141. package/dist/effects/Vignette.cjs +7 -0
  142. package/dist/effects/Vignette.cjs.map +1 -0
  143. package/dist/effects/Vignette.js +7 -0
  144. package/dist/effects/Vignette.js.map +1 -0
  145. package/dist/index.cjs +79 -3616
  146. package/dist/index.cjs.map +1 -1
  147. package/dist/index.js +36 -3557
  148. package/dist/index.js.map +1 -1
  149. package/dist/node_modules/n8ao/dist/N8AO.cjs +1439 -0
  150. package/dist/node_modules/n8ao/dist/N8AO.cjs.map +1 -0
  151. package/dist/node_modules/n8ao/dist/N8AO.js +1439 -0
  152. package/dist/node_modules/n8ao/dist/N8AO.js.map +1 -0
  153. package/dist/util.cjs +69 -0
  154. package/dist/util.cjs.map +1 -0
  155. package/dist/util.js +52 -0
  156. package/dist/util.js.map +1 -0
  157. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -1,3619 +1,82 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const jsxRuntime = require("react/jsx-runtime");
4
- const React = require("react");
5
- const THREE = require("three");
6
- const fiber = require("@react-three/fiber");
7
- const postprocessing = require("postprocessing");
8
- const threeStdlib = require("three-stdlib");
9
- const maath = require("maath");
10
- require("three-stdlib");
11
- function _interopNamespaceDefault(e) {
12
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
13
- if (e) {
14
- for (const k in e) {
15
- if (k !== "default") {
16
- const d = Object.getOwnPropertyDescriptor(e, k);
17
- Object.defineProperty(n, k, d.get ? d : {
18
- enumerable: true,
19
- get: () => e[k]
20
- });
21
- }
22
- }
23
- }
24
- n.default = e;
25
- return Object.freeze(n);
26
- }
27
- const THREE__namespace = /* @__PURE__ */ _interopNamespaceDefault(THREE);
28
- const selectionContext = React.createContext(null);
29
- function Selection({ children, enabled = true }) {
30
- const [selected, select] = React.useState([]);
31
- const value = React.useMemo(() => ({ selected, select, enabled }), [selected, select, enabled]);
32
- return /* @__PURE__ */ jsxRuntime.jsx(selectionContext.Provider, { value, children });
33
- }
34
- function Select({ enabled = false, children, ...props }) {
35
- const group = React.useRef(null);
36
- const api = React.useContext(selectionContext);
37
- React.useEffect(() => {
38
- if (api && enabled) {
39
- let changed = false;
40
- const current = [];
41
- group.current.traverse((o) => {
42
- o.type === "Mesh" && current.push(o);
43
- if (api.selected.indexOf(o) === -1)
44
- changed = true;
45
- });
46
- if (changed) {
47
- api.select((state) => [...state, ...current]);
48
- return () => {
49
- api.select((state) => state.filter((selected) => !current.includes(selected)));
50
- };
51
- }
52
- }
53
- }, [enabled, children, api]);
54
- return /* @__PURE__ */ jsxRuntime.jsx("group", { ref: group, ...props, children });
55
- }
56
- const EffectComposerContext = React.createContext(null);
57
- const EffectComposer = React.memo(
58
- React.forwardRef(
59
- ({
60
- children,
61
- camera: _camera,
62
- scene: _scene,
63
- resolutionScale,
64
- enabled = true,
65
- renderPriority = 1,
66
- autoClear = true,
67
- depthBuffer,
68
- disableNormalPass,
69
- stencilBuffer,
70
- multisampling = 8,
71
- frameBufferType = THREE.HalfFloatType
72
- }, ref) => {
73
- const { gl, scene: defaultScene, camera: defaultCamera, size } = fiber.useThree();
74
- const scene = _scene || defaultScene;
75
- const camera = _camera || defaultCamera;
76
- const [composer, normalPass, downSamplingPass] = React.useMemo(() => {
77
- const webGL2Available = threeStdlib.isWebGL2Available();
78
- const effectComposer = new postprocessing.EffectComposer(gl, {
79
- depthBuffer,
80
- stencilBuffer,
81
- multisampling: multisampling > 0 && webGL2Available ? multisampling : 0,
82
- frameBufferType
83
- });
84
- effectComposer.addPass(new postprocessing.RenderPass(scene, camera));
85
- let downSamplingPass2 = null;
86
- let normalPass2 = null;
87
- if (!disableNormalPass) {
88
- normalPass2 = new postprocessing.NormalPass(scene, camera);
89
- normalPass2.enabled = false;
90
- effectComposer.addPass(normalPass2);
91
- if (resolutionScale !== void 0 && webGL2Available) {
92
- downSamplingPass2 = new postprocessing.DepthDownsamplingPass({ normalBuffer: normalPass2.texture, resolutionScale });
93
- downSamplingPass2.enabled = false;
94
- effectComposer.addPass(downSamplingPass2);
95
- }
96
- }
97
- return [effectComposer, normalPass2, downSamplingPass2];
98
- }, [
99
- camera,
100
- gl,
101
- depthBuffer,
102
- stencilBuffer,
103
- multisampling,
104
- frameBufferType,
105
- scene,
106
- disableNormalPass,
107
- resolutionScale
108
- ]);
109
- React.useEffect(() => composer == null ? void 0 : composer.setSize(size.width, size.height), [composer, size]);
110
- fiber.useFrame(
111
- (_, delta) => {
112
- if (enabled) {
113
- const currentAutoClear = gl.autoClear;
114
- gl.autoClear = autoClear;
115
- if (stencilBuffer && !autoClear)
116
- gl.clearStencil();
117
- composer.render(delta);
118
- gl.autoClear = currentAutoClear;
119
- }
120
- },
121
- enabled ? renderPriority : 0
122
- );
123
- const group = React.useRef(null);
124
- const instance = fiber.useInstanceHandle(group);
125
- React.useLayoutEffect(() => {
126
- const passes = [];
127
- if (group.current && instance.current && composer) {
128
- const children2 = instance.current.objects;
129
- for (let i2 = 0; i2 < children2.length; i2++) {
130
- const child = children2[i2];
131
- if (child instanceof postprocessing.Effect) {
132
- const effects = [];
133
- while (children2[i2] instanceof postprocessing.Effect)
134
- effects.push(children2[i2++]);
135
- i2--;
136
- const pass = new postprocessing.EffectPass(camera, ...effects);
137
- passes.push(pass);
138
- } else if (child instanceof postprocessing.Pass) {
139
- passes.push(child);
140
- }
141
- }
142
- for (const pass of passes)
143
- composer == null ? void 0 : composer.addPass(pass);
144
- if (normalPass)
145
- normalPass.enabled = true;
146
- if (downSamplingPass)
147
- downSamplingPass.enabled = true;
148
- }
149
- return () => {
150
- for (const pass of passes)
151
- composer == null ? void 0 : composer.removePass(pass);
152
- if (normalPass)
153
- normalPass.enabled = false;
154
- if (downSamplingPass)
155
- downSamplingPass.enabled = false;
156
- };
157
- }, [composer, children, camera, normalPass, downSamplingPass, instance]);
158
- const state = React.useMemo(
159
- () => ({ composer, normalPass, downSamplingPass, resolutionScale, camera, scene }),
160
- [composer, normalPass, downSamplingPass, resolutionScale, camera, scene]
161
- );
162
- React.useImperativeHandle(ref, () => composer, [composer]);
163
- return /* @__PURE__ */ jsxRuntime.jsx(EffectComposerContext.Provider, { value: state, children: /* @__PURE__ */ jsxRuntime.jsx("group", { ref: group, children }) });
164
- }
165
- )
166
- );
167
- const resolveRef = (ref) => typeof ref === "object" && ref != null && "current" in ref ? ref.current : ref;
168
- let i = 0;
169
- const components = /* @__PURE__ */ new WeakMap();
170
- const wrapEffect = (effect, defaults) => /* @__PURE__ */ React.forwardRef(function Effect({ blendFunction = defaults == null ? void 0 : defaults.blendFunction, opacity = defaults == null ? void 0 : defaults.opacity, ...props }, ref) {
171
- let Component = components.get(effect);
172
- if (!Component) {
173
- const key = `@react-three/postprocessing/${effect.name}-${i++}`;
174
- fiber.extend({ [key]: effect });
175
- components.set(effect, Component = key);
176
- }
177
- const camera = fiber.useThree((state) => state.camera);
178
- const args = React.useMemo(
179
- () => {
180
- var _a, _b;
181
- return [...(_a = defaults == null ? void 0 : defaults.args) != null ? _a : [], ...(_b = props.args) != null ? _b : [{ ...defaults, ...props }]];
182
- },
183
- // eslint-disable-next-line react-hooks/exhaustive-deps
184
- [JSON.stringify(props)]
185
- );
186
- return /* @__PURE__ */ jsxRuntime.jsx(
187
- Component,
188
- {
189
- camera,
190
- "blendMode-blendFunction": blendFunction,
191
- "blendMode-opacity-value": opacity,
192
- ...props,
193
- ref,
194
- args
195
- }
196
- );
197
- });
198
- const useVector2 = (props, key) => {
199
- const value = props[key];
200
- return React.useMemo(() => {
201
- if (typeof value === "number")
202
- return new THREE__namespace.Vector2(value, value);
203
- else if (value)
204
- return new THREE__namespace.Vector2(...value);
205
- else
206
- return new THREE__namespace.Vector2();
207
- }, [value]);
208
- };
209
- const DepthOfField = React.forwardRef(function DepthOfField2({ target, depthTexture, ...props }, ref) {
210
- const invalidate = fiber.useThree((state) => state.invalidate);
211
- const { camera } = React.useContext(EffectComposerContext);
212
- const effect = React.useMemo(() => {
213
- const effect2 = new postprocessing.DepthOfFieldEffect(camera, props);
214
- const maskMaterial = effect2.maskPass.getFullscreenMaterial();
215
- maskMaterial.maskFunction = postprocessing.MaskFunction.MULTIPLY_RGB_SET_ALPHA;
216
- return effect2;
217
- }, [camera, props]);
218
- React.useLayoutEffect(() => {
219
- if (target && typeof target !== "number") {
220
- const vec = target instanceof THREE.Vector3 ? new THREE.Vector3().set(target.x, target.y, target.z) : new THREE.Vector3().set(target[0], target[1], target[2]);
221
- effect.target = vec;
222
- }
223
- if (depthTexture)
224
- effect.setDepthTexture(depthTexture.texture, depthTexture.packing);
225
- invalidate();
226
- }, [target, depthTexture, effect]);
227
- return /* @__PURE__ */ jsxRuntime.jsx("primitive", { ref, object: effect, dispose: null });
228
- });
229
- const Autofocus = React.forwardRef(
230
- ({ target = void 0, mouse: followMouse = false, debug = void 0, manual = false, smoothTime = 0.25, ...props }, fref) => {
231
- const dofRef = React.useRef(null);
232
- const hitpointRef = React.useRef(null);
233
- const targetRef = React.useRef(null);
234
- const scene = fiber.useThree(({ scene: scene2 }) => scene2);
235
- const pointer = fiber.useThree(({ pointer: pointer2 }) => pointer2);
236
- const { composer, camera } = React.useContext(EffectComposerContext);
237
- const [depthPickingPass] = React.useState(() => new postprocessing.DepthPickingPass());
238
- const [copyPass] = React.useState(() => new postprocessing.CopyPass());
239
- React.useEffect(() => {
240
- composer.addPass(depthPickingPass);
241
- composer.addPass(copyPass);
242
- return () => {
243
- composer.removePass(depthPickingPass);
244
- composer.removePass(copyPass);
245
- };
246
- }, [composer, depthPickingPass, copyPass]);
247
- React.useEffect(() => {
248
- return () => {
249
- depthPickingPass.dispose();
250
- copyPass.dispose();
251
- };
252
- }, [depthPickingPass, copyPass]);
253
- const [hitpoint] = React.useState(() => new THREE__namespace.Vector3(0, 0, 0));
254
- const [ndc] = React.useState(() => new THREE__namespace.Vector3(0, 0, 0));
255
- const getHit = React.useCallback(
256
- async (x, y) => {
257
- ndc.x = x;
258
- ndc.y = y;
259
- ndc.z = await depthPickingPass.readDepth(ndc);
260
- ndc.z = ndc.z * 2 - 1;
261
- const hit = 1 - ndc.z > 1e-7;
262
- return hit ? ndc.unproject(camera) : false;
263
- },
264
- [ndc, depthPickingPass, camera]
265
- );
266
- const update = React.useCallback(
267
- async (delta, updateTarget = true) => {
268
- var _a;
269
- if (target) {
270
- hitpoint.set(...target);
271
- } else {
272
- const { x, y } = followMouse ? pointer : { x: 0, y: 0 };
273
- const hit = await getHit(x, y);
274
- if (hit)
275
- hitpoint.copy(hit);
276
- }
277
- if (updateTarget && ((_a = dofRef.current) == null ? void 0 : _a.target)) {
278
- if (smoothTime > 0 && delta > 0) {
279
- maath.easing.damp3(dofRef.current.target, hitpoint, smoothTime, delta);
280
- } else {
281
- dofRef.current.target.copy(hitpoint);
282
- }
283
- }
284
- },
285
- [target, hitpoint, followMouse, getHit, smoothTime, pointer]
286
- );
287
- fiber.useFrame(async (_, delta) => {
288
- var _a;
289
- if (!manual) {
290
- update(delta);
291
- }
292
- if (hitpointRef.current) {
293
- hitpointRef.current.position.copy(hitpoint);
294
- }
295
- if (targetRef.current && ((_a = dofRef.current) == null ? void 0 : _a.target)) {
296
- targetRef.current.position.copy(dofRef.current.target);
297
- }
298
- });
299
- const api = React.useMemo(
300
- () => ({
301
- dofRef,
302
- hitpoint,
303
- update
304
- }),
305
- [hitpoint, update]
306
- );
307
- React.useImperativeHandle(fref, () => api, [api]);
308
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
309
- debug ? fiber.createPortal(
310
- /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
311
- /* @__PURE__ */ jsxRuntime.jsxs("mesh", { ref: hitpointRef, children: [
312
- /* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [debug, 16, 16] }),
313
- /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: "#00ff00", opacity: 1, transparent: true, depthWrite: false })
314
- ] }),
315
- /* @__PURE__ */ jsxRuntime.jsxs("mesh", { ref: targetRef, children: [
316
- /* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [debug / 2, 16, 16] }),
317
- /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: "#00ff00", opacity: 0.5, transparent: true, depthWrite: false })
318
- ] })
319
- ] }),
320
- scene
321
- ) : null,
322
- /* @__PURE__ */ jsxRuntime.jsx(DepthOfField, { ref: dofRef, ...props, target: hitpoint })
323
- ] });
324
- }
325
- );
326
- const LensFlareShader = {
327
- fragmentShader: (
328
- /* glsl */
329
- `
330
-
331
- uniform float iTime;
332
- uniform vec2 lensPosition;
333
- uniform vec2 iResolution;
334
- uniform vec3 colorGain;
335
- uniform float starPoints;
336
- uniform float glareSize;
337
- uniform float flareSize;
338
- uniform float flareSpeed;
339
- uniform float flareShape;
340
- uniform float haloScale;
341
- uniform float opacity;
342
- uniform bool animated;
343
- uniform bool anamorphic;
344
- uniform bool enabled;
345
- uniform bool secondaryGhosts;
346
- uniform bool starBurst;
347
- uniform float ghostScale;
348
- uniform bool aditionalStreaks;
349
- uniform sampler2D lensDirtTexture;
350
- vec2 vxtC;
351
-
352
- float rndf(float n){return fract(sin(n) * 43758.5453123);}float niz(float p){float fl = floor(p);float fc = fract(p);return mix(rndf(fl),rndf(fl + 1.0), fc);}
353
- vec3 hsv2rgb(vec3 c){vec4 k = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);vec3 p = abs(fract(c.xxx + k.xyz) * 6.0 - k.www);return c.z * mix(k.xxx, clamp(p - k.xxx, 0.0, 1.0), c.y);}
354
- float satU(float x){return clamp(x, 0.,1.);}vec2 rtU(vec2 naz, float rtn){return vec2(cos(rtn) * naz.x + sin(rtn) * naz.y,cos(rtn) * naz.y - sin(rtn) * naz.x);}
355
- vec3 drwF(vec2 p, float intensity, float rnd, float speed, int id){float flhos = (1. / 32.) * float(id) * 0.1;float lingrad = distance(vec2(0.), p);float expg = 1. / exp(lingrad * (fract(rnd) * 0.66 + 0.33));vec3 qzTg = hsv2rgb(vec3( fract( (expg * 8.) + speed * flareSpeed + flhos), pow(1.-abs(expg*2.-1.), 0.45), 20.0 * expg * intensity));float internalStarPoints;if(anamorphic){internalStarPoints = 1.0;} else{internalStarPoints = starPoints;}float ams = length(p * flareShape * sin(internalStarPoints * atan(p.x, p.y)));float kJhg = pow(1.-satU(ams), ( anamorphic ? 100. : 12.));kJhg += satU(expg-0.9) * 3.;kJhg = pow(kJhg * expg, 8. + (1.-intensity) * 5.);if(flareSpeed > 0.0){return vec3(kJhg) * qzTg;} else{return vec3(kJhg) * flareSize * 15.;}}
356
- float ams2(vec3 a, vec3 b) { return abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z);}vec3 satU(vec3 x){return clamp(x, vec3(0.0), vec3(1.0));}
357
- float glR(vec2 naz, vec2 pos, float zsi){vec2 mni;if(animated){mni = rtU(naz-pos, iTime * 0.1);} else{mni = naz-pos;}float ang = atan(mni.y, mni.x) * (anamorphic ? 1.0 : starPoints);float ams2 = length(mni);ams2 = pow(ams2, .9);float f0 = 1.0/(length(naz-pos)*(1.0/zsi*16.0)+.2);return f0+f0*(sin((ang))*.2 +.3);}
358
- float sdHex(vec2 p){p = abs(p);vec2 q = vec2(p.x*2.0*0.5773503, p.y + p.x*0.5773503);return dot(step(q.xy,q.yx), 1.0-q.yx);}float fpow(float x, float k){return x > k ? pow((x-k)/(1.0-k),2.0) : 0.0;}
359
- vec3 rHx(vec2 naz, vec2 p, float s, vec3 col){naz -= p;if (abs(naz.x) < 0.2*s && abs(naz.y) < 0.2*s){return mix(vec3(0),mix(vec3(0),col,0.1 + fpow(length(naz/s),0.1)*10.0),smoothstep(0.0,0.1,sdHex(naz*20.0/s)));}return vec3(0);}
360
- vec3 mLs(vec2 naz, vec2 pos){vec2 mni = naz-pos;vec2 zxMp = naz*(length(naz));float ang = atan(mni.x,mni.y);float f0 = .3/(length(naz-pos)*16.0+1.0);f0 = f0*(sin(niz(sin(ang*3.9-(animated ? iTime : 0.0) * 0.3) * starPoints))*.2 );float f1 = max(0.01-pow(length(naz+1.2*pos),1.9),.0)*7.0;float f2 = max(.9/(10.0+32.0*pow(length(zxMp+0.99*pos),2.0)),.0)*0.35;float f22 = max(.9/(11.0+32.0*pow(length(zxMp+0.85*pos),2.0)),.0)*0.23;float f23 = max(.9/(12.0+32.0*pow(length(zxMp+0.95*pos),2.0)),.0)*0.6;vec2 ztX = mix(naz,zxMp, 0.1);float f4 = max(0.01-pow(length(ztX+0.4*pos),2.9),.0)*4.02;float f42 = max(0.0-pow(length(ztX+0.45*pos),2.9),.0)*4.1;float f43 = max(0.01-pow(length(ztX+0.5*pos),2.9),.0)*4.6;ztX = mix(naz,zxMp,-.4);float f5 = max(0.01-pow(length(ztX+0.1*pos),5.5),.0)*2.0;float f52 = max(0.01-pow(length(ztX+0.2*pos),5.5),.0)*2.0;float f53 = max(0.01-pow(length(ztX+0.1*pos),5.5),.0)*2.0;ztX = mix(naz,zxMp, 2.1);float f6 = max(0.01-pow(length(ztX-0.3*pos),1.61),.0)*3.159;float f62 = max(0.01-pow(length(ztX-0.325*pos),1.614),.0)*3.14;float f63 = max(0.01-pow(length(ztX-0.389*pos),1.623),.0)*3.12;vec3 c = vec3(glR(naz,pos, glareSize));vec2 prot;if(animated){prot = rtU(naz - pos, (iTime * 0.1));} else if(anamorphic){prot = rtU(naz - pos, 1.570796);} else {prot = naz - pos;}c += drwF(prot, (anamorphic ? flareSize * 10. : flareSize), 0.1, iTime, 1);c.r+=f1+f2+f4+f5+f6; c.g+=f1+f22+f42+f52+f62; c.b+=f1+f23+f43+f53+f63;c = c*1.3 * vec3(length(zxMp)+.09);c+=vec3(f0);return c;}
361
- vec3 cc(vec3 clr, float fct,float fct2){float w = clr.x+clr.y+clr.z;return mix(clr,vec3(w)*fct,w*fct2);}float rnd(vec2 p){float f = fract(sin(dot(p, vec2(12.1234, 72.8392) )*45123.2));return f;}float rnd(float w){float f = fract(sin(w)*1000.);return f;}
362
- float rShp(vec2 p, int N){float f;float a=atan(p.x,p.y)+.2;float b=6.28319/float(N);f=smoothstep(.5,.51, cos(floor(.5+a/b)*b-a)*length(p.xy)* 2.0 -ghostScale);return f;}
363
- vec3 drC(vec2 p, float zsi, float dCy, vec3 clr, vec3 clr2, float ams2, vec2 esom){float l = length(p + esom*(ams2*2.))+zsi/2.;float l2 = length(p + esom*(ams2*4.))+zsi/3.;float c = max(0.01-pow(length(p + esom*ams2), zsi*ghostScale), 0.0)*10.;float c1 = max(0.001-pow(l-0.3, 1./40.)+sin(l*20.), 0.0)*3.;float c2 = max(0.09/pow(length(p-esom*ams2/.5)*1., .95), 0.0)/20.;float s = max(0.02-pow(rShp(p*5. + esom*ams2*5. + dCy, 6) , 1.), 0.0)*1.5;clr = cos(vec3(0.44, .24, .2)*8. + ams2*4.)*0.5+.5;vec3 f = c*clr;f += c1*clr;f += c2*clr;f += s*clr;return f-0.01;}
364
- vec4 geLC(float x){return vec4(vec3(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(mix(vec3(0., 0., 0.),vec3(0., 0., 0.), smoothstep(0.0, 0.063, x)),vec3(0., 0., 0.), smoothstep(0.063, 0.125, x)),vec3(0.0, 0., 0.), smoothstep(0.125, 0.188, x)),vec3(0.188, 0.131, 0.116), smoothstep(0.188, 0.227, x)),vec3(0.31, 0.204, 0.537), smoothstep(0.227, 0.251, x)),vec3(0.192, 0.106, 0.286), smoothstep(0.251, 0.314, x)),vec3(0.102, 0.008, 0.341), smoothstep(0.314, 0.392, x)),vec3(0.086, 0.0, 0.141), smoothstep(0.392, 0.502, x)),vec3(1.0, 0.31, 0.0), smoothstep(0.502, 0.604, x)),vec3(.1, 0.1, 0.1), smoothstep(0.604, 0.643, x)),vec3(1.0, 0.929, 0.0), smoothstep(0.643, 0.761, x)),vec3(1.0, 0.086, 0.424), smoothstep(0.761, 0.847, x)),vec3(1.0, 0.49, 0.0), smoothstep(0.847, 0.89, x)),vec3(0.945, 0.275, 0.475), smoothstep(0.89, 0.941, x)),vec3(0.251, 0.275, 0.796), smoothstep(0.941, 1.0, x))),1.0);}
365
- float diTN(vec2 p){vec2 f = fract(p);f = (f * f) * (3.0 - (2.0 * f));float n = dot(floor(p), vec2(1.0, 157.0));vec4 a = fract(sin(vec4(n + 0.0, n + 1.0, n + 157.0, n + 158.0)) * 43758.5453123);return mix(mix(a.x, a.y, f.x), mix(a.z, a.w, f.x), f.y);}
366
- float fbm(vec2 p){const mat2 m = mat2(0.80, -0.60, 0.60, 0.80);float f = 0.0;f += 0.5000*diTN(p); p = m*p*2.02;f += 0.2500*diTN(p); p = m*p*2.03;f += 0.1250*diTN(p); p = m*p*2.01;f += 0.0625*diTN(p);return f/0.9375;}
367
- vec4 geLS(vec2 p){vec2 pp = (p - vec2(0.5)) * 2.0;float a = atan(pp.y, pp.x);vec4 cp = vec4(sin(a * 1.0), length(pp), sin(a * 13.0), sin(a * 53.0));float d = sin(clamp(pow(length(vec2(0.5) - p) * 0.5 + haloScale /2., 5.0), 0.0, 1.0) * 3.14159);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));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;return vec4(vec3(c * 1.0), d);}
368
- vec4 geLD(vec2 p){p.xy += vec2(fbm(p.yx * 3.0), fbm(p.yx * 2.0)) * 0.0825;vec3 o = vec3(mix(0.125, 0.25, max(max(smoothstep(0.1, 0.0, length(p - vec2(0.25))),smoothstep(0.4, 0.0, length(p - vec2(0.75)))),smoothstep(0.8, 0.0, length(p - vec2(0.875, 0.125))))));o += vec3(max(fbm(p * 1.0) - 0.5, 0.0)) * 0.5;o += vec3(max(fbm(p * 2.0) - 0.5, 0.0)) * 0.5;o += vec3(max(fbm(p * 4.0) - 0.5, 0.0)) * 0.25;o += vec3(max(fbm(p * 8.0) - 0.75, 0.0)) * 1.0;o += vec3(max(fbm(p * 16.0) - 0.75, 0.0)) * 0.75;o += vec3(max(fbm(p * 64.0) - 0.75, 0.0)) * 0.5;return vec4(clamp(o, vec3(0.15), vec3(1.0)), 1.0);}
369
- vec4 txL(sampler2D tex, vec2 xtC){if(((xtC.x < 0.) || (xtC.y < 0.)) || ((xtC.x > 1.) || (xtC.y > 1.))){return vec4(0.0);}else{return texture(tex, xtC); }}
370
- vec4 txD(sampler2D tex, vec2 xtC, vec2 dir, vec3 ditn) {return vec4(txL(tex, (xtC + (dir * ditn.r))).r,txL(tex, (xtC + (dir * ditn.g))).g,txL(tex, (xtC + (dir * ditn.b))).b,1.0);}
371
- vec4 strB(){vec2 aspXtc = vec2(1.0) - (((vxtC - vec2(0.5)) * vec2(1.0)) + vec2(0.5)); vec2 xtC = vec2(1.0) - vxtC; vec2 ghvc = (vec2(0.5) - xtC) * 0.3 - lensPosition; vec2 ghNm = normalize(ghvc * vec2(1.0)) * vec2(1.0);vec2 haloVec = normalize(ghvc) * 0.6;vec2 hlNm = ghNm * 0.6;vec2 texelSize = vec2(1.0) / vec2(iResolution.xy);vec3 ditn = vec3(-(texelSize.x * 1.5), 0.2, texelSize.x * 1.5);vec4 c = vec4(0.0);for (int i = 0; i < 8; i++) {vec2 offset = xtC + (ghvc * float(i));c += txD(lensDirtTexture, offset, ghNm, ditn) * pow(max(0.0, 1.0 - (length(vec2(0.5) - offset) / length(vec2(0.5)))), 10.0);}vec2 uyTrz = xtC + hlNm; return (c * geLC((length(vec2(0.5) - aspXtc) / length(vec2(haloScale))))) +(txD(lensDirtTexture, uyTrz, ghNm, ditn) * pow(max(0.0, 1.0 - (length(vec2(0.5) - uyTrz) / length(vec2(0.5)))), 10.0));}
372
- void mainImage(vec4 v,vec2 r,out vec4 i){vec2 g=r-.5;g.y*=iResolution.y/iResolution.x;vec2 l=lensPosition*.5;l.y*=iResolution.y/iResolution.x;vec3 f=mLs(g,l)*20.*colorGain/256.;if(aditionalStreaks){vec3 o=vec3(.9,.2,.1),p=vec3(.3,.1,.9);for(float n=0.;n<10.;n++)f+=drC(g,pow(rnd(n*2e3)*2.8,.1)+1.41,0.,o+n,p+n,rnd(n*20.)*3.+.2-.5,lensPosition);}if(secondaryGhosts){vec3 n=vec3(0);n+=rHx(g,-lensPosition*.25,ghostScale*1.4,vec3(.25,.35,0));n+=rHx(g,lensPosition*.25,ghostScale*.5,vec3(1,.5,.5));n+=rHx(g,lensPosition*.1,ghostScale*1.6,vec3(1));n+=rHx(g,lensPosition*1.8,ghostScale*2.,vec3(0,.5,.75));n+=rHx(g,lensPosition*1.25,ghostScale*.8,vec3(1,1,.5));n+=rHx(g,-lensPosition*1.25,ghostScale*5.,vec3(.5,.5,.25));n+=fpow(1.-abs(distance(lensPosition*.8,g)-.7),.985)*colorGain/2100.;f+=n;}if(starBurst){vxtC=g+.5;vec4 n=geLD(g);float o=1.-clamp(0.5,0.,.5)*2.;n+=mix(n,pow(n*2.,vec4(2))*.5,o);float s=(g.x+g.y)*(1./6.);vec2 d=mat2(cos(s),-sin(s),sin(s),cos(s))*vxtC;n+=geLS(d)*2.;f+=clamp(n.xyz*strB().xyz,.01,1.);}i=enabled?vec4(mix(f,vec3(0),opacity)+v.xyz,v.w):vec4(v);}
373
- `
374
- )
375
- };
376
- class LensFlareEffect extends postprocessing.Effect {
377
- constructor({
378
- blendFunction = postprocessing.BlendFunction.NORMAL,
379
- enabled = true,
380
- glareSize = 0.2,
381
- lensPosition = [0.01, 0.01],
382
- iResolution = [0, 0],
383
- starPoints = 6,
384
- flareSize = 0.01,
385
- flareSpeed = 0.01,
386
- flareShape = 0.01,
387
- animated = true,
388
- anamorphic = false,
389
- colorGain = new THREE__namespace.Color(20, 20, 20),
390
- lensDirtTexture = null,
391
- haloScale = 0.5,
392
- secondaryGhosts = true,
393
- aditionalStreaks = true,
394
- ghostScale = 0,
395
- opacity = 1,
396
- starBurst = false
397
- } = {}) {
398
- super("LensFlareEffect", LensFlareShader.fragmentShader, {
399
- blendFunction,
400
- uniforms: /* @__PURE__ */ new Map([
401
- ["enabled", new THREE__namespace.Uniform(enabled)],
402
- ["glareSize", new THREE__namespace.Uniform(glareSize)],
403
- ["lensPosition", new THREE__namespace.Uniform(lensPosition)],
404
- ["iTime", new THREE__namespace.Uniform(0)],
405
- ["iResolution", new THREE__namespace.Uniform(iResolution)],
406
- ["starPoints", new THREE__namespace.Uniform(starPoints)],
407
- ["flareSize", new THREE__namespace.Uniform(flareSize)],
408
- ["flareSpeed", new THREE__namespace.Uniform(flareSpeed)],
409
- ["flareShape", new THREE__namespace.Uniform(flareShape)],
410
- ["animated", new THREE__namespace.Uniform(animated)],
411
- ["anamorphic", new THREE__namespace.Uniform(anamorphic)],
412
- ["colorGain", new THREE__namespace.Uniform(colorGain)],
413
- ["lensDirtTexture", new THREE__namespace.Uniform(lensDirtTexture)],
414
- ["haloScale", new THREE__namespace.Uniform(haloScale)],
415
- ["secondaryGhosts", new THREE__namespace.Uniform(secondaryGhosts)],
416
- ["aditionalStreaks", new THREE__namespace.Uniform(aditionalStreaks)],
417
- ["ghostScale", new THREE__namespace.Uniform(ghostScale)],
418
- ["starBurst", new THREE__namespace.Uniform(starBurst)],
419
- ["opacity", new THREE__namespace.Uniform(opacity)]
420
- ])
421
- });
422
- }
423
- update(_renderer, _inputBuffer, deltaTime) {
424
- const iTime = this.uniforms.get("iTime");
425
- if (iTime) {
426
- iTime.value += deltaTime;
427
- }
428
- }
429
- }
430
- const LensFlare = React.forwardRef(
431
- ({ position = new THREE__namespace.Vector3(-25, 6, -60), followMouse = false, smoothTime = 0.07, ...props }, ref) => {
432
- const viewport = fiber.useThree(({ viewport: viewport2 }) => viewport2);
433
- const raycaster = fiber.useThree(({ raycaster: raycaster2 }) => raycaster2);
434
- const pointer = fiber.useThree(({ pointer: pointer2 }) => pointer2);
435
- const { scene, camera } = React.useContext(EffectComposerContext);
436
- const [projectedPosition] = React.useState(() => new THREE__namespace.Vector3());
437
- const [mouse2d] = React.useState(() => new THREE__namespace.Vector2());
438
- const effect = React.useMemo(() => new LensFlareEffect(props), [props]);
439
- fiber.useFrame((_, delta) => {
440
- var _a, _b, _c;
441
- const uLensPosition = effect.uniforms.get("lensPosition");
442
- const uOpacity = effect.uniforms.get("opacity");
443
- if (!uLensPosition || !uOpacity)
444
- return;
445
- let target = 1;
446
- if (followMouse) {
447
- uLensPosition.value.x = pointer.x;
448
- uLensPosition.value.y = pointer.y;
449
- target = 0;
450
- } else {
451
- projectedPosition.copy(position).project(camera);
452
- if (projectedPosition.z > 1)
453
- return;
454
- uLensPosition.value.x = projectedPosition.x;
455
- uLensPosition.value.y = projectedPosition.y;
456
- mouse2d.set(projectedPosition.x, projectedPosition.y);
457
- raycaster.setFromCamera(mouse2d, camera);
458
- const intersects = raycaster.intersectObjects(scene.children, true);
459
- const { object } = intersects[0];
460
- if (object) {
461
- if (((_a = object.userData) == null ? void 0 : _a.lensflare) === "no-occlusion") {
462
- target = 0;
463
- } else if (object instanceof THREE__namespace.Mesh) {
464
- if (((_c = (_b = object.material.uniforms) == null ? void 0 : _b._transmission) == null ? void 0 : _c.value) > 0.2) {
465
- target = 0.2;
466
- } else if (object.material._transmission && object.material._transmission > 0.2) {
467
- target = 0.2;
468
- } else if (object.material.transparent) {
469
- target = object.material.opacity;
470
- }
471
- }
472
- }
473
- }
474
- maath.easing.damp(uOpacity, "value", target, smoothTime, delta);
475
- });
476
- React.useEffect(() => {
477
- const iResolution = effect.uniforms.get("iResolution");
478
- if (iResolution) {
479
- iResolution.value.x = viewport.width;
480
- iResolution.value.y = viewport.height;
481
- }
482
- }, [effect, viewport]);
483
- return /* @__PURE__ */ jsxRuntime.jsx("primitive", { ref, object: effect, dispose: null });
484
- }
485
- );
486
- const Bloom = wrapEffect(postprocessing.BloomEffect, {
487
- blendFunction: postprocessing.BlendFunction.ADD
488
- });
489
- const BrightnessContrast = wrapEffect(postprocessing.BrightnessContrastEffect);
490
- const ChromaticAberration = wrapEffect(postprocessing.ChromaticAberrationEffect);
491
- const ColorAverage = React.forwardRef(function ColorAverage2({ blendFunction = postprocessing.BlendFunction.NORMAL }, ref) {
492
- const effect = React.useMemo(() => new postprocessing.ColorAverageEffect(blendFunction), [blendFunction]);
493
- return /* @__PURE__ */ jsxRuntime.jsx("primitive", { ref, object: effect, dispose: null });
494
- });
495
- const ColorDepth = wrapEffect(postprocessing.ColorDepthEffect);
496
- const Depth = wrapEffect(postprocessing.DepthEffect);
497
- const DotScreen = wrapEffect(postprocessing.DotScreenEffect);
498
- const Glitch = React.forwardRef(function Glitch2({ active = true, ...props }, ref) {
499
- const invalidate = fiber.useThree((state) => state.invalidate);
500
- const delay = useVector2(props, "delay");
501
- const duration = useVector2(props, "duration");
502
- const strength = useVector2(props, "strength");
503
- const chromaticAberrationOffset = useVector2(props, "chromaticAberrationOffset");
504
- const effect = React.useMemo(
505
- () => new postprocessing.GlitchEffect({ ...props, delay, duration, strength, chromaticAberrationOffset }),
506
- [delay, duration, props, strength, chromaticAberrationOffset]
507
- );
508
- React.useLayoutEffect(() => {
509
- effect.mode = active ? props.mode || postprocessing.GlitchMode.SPORADIC : postprocessing.GlitchMode.DISABLED;
510
- invalidate();
511
- }, [active, effect, invalidate, props.mode]);
512
- React.useEffect(() => {
513
- return () => {
514
- effect.dispose();
515
- };
516
- }, [effect]);
517
- return /* @__PURE__ */ jsxRuntime.jsx("primitive", { ref, object: effect, dispose: null });
518
- });
519
- const GodRays = React.forwardRef(function GodRays2(props, ref) {
520
- const { camera } = React.useContext(EffectComposerContext);
521
- const effect = React.useMemo(() => new postprocessing.GodRaysEffect(camera, resolveRef(props.sun), props), [camera, props]);
522
- React.useLayoutEffect(() => void (effect.lightSource = resolveRef(props.sun)), [effect, props.sun]);
523
- return /* @__PURE__ */ jsxRuntime.jsx("primitive", { ref, object: effect, dispose: null });
524
- });
525
- const Grid = React.forwardRef(function Grid2({ size, ...props }, ref) {
526
- const invalidate = fiber.useThree((state) => state.invalidate);
527
- const effect = React.useMemo(() => new postprocessing.GridEffect(props), [props]);
528
- React.useLayoutEffect(() => {
529
- if (size)
530
- effect.setSize(size.width, size.height);
531
- invalidate();
532
- }, [effect, size]);
533
- return /* @__PURE__ */ jsxRuntime.jsx("primitive", { ref, object: effect, dispose: null });
534
- });
535
- const HueSaturation = wrapEffect(postprocessing.HueSaturationEffect);
536
- const Noise = wrapEffect(postprocessing.NoiseEffect, { blendFunction: postprocessing.BlendFunction.COLOR_DODGE });
537
- const Outline = React.forwardRef(function Outline2({
538
- selection = [],
539
- selectionLayer = 10,
540
- blendFunction,
541
- patternTexture,
542
- edgeStrength,
543
- pulseSpeed,
544
- visibleEdgeColor,
545
- hiddenEdgeColor,
546
- width,
547
- height,
548
- kernelSize,
549
- blur,
550
- xRay,
551
- ...props
552
- }, forwardRef2) {
553
- const invalidate = fiber.useThree((state) => state.invalidate);
554
- const { scene, camera } = React.useContext(EffectComposerContext);
555
- const effect = React.useMemo(
556
- () => new postprocessing.OutlineEffect(scene, camera, {
557
- blendFunction,
558
- patternTexture,
559
- edgeStrength,
560
- pulseSpeed,
561
- visibleEdgeColor,
562
- hiddenEdgeColor,
563
- width,
564
- height,
565
- kernelSize,
566
- blur,
567
- xRay,
568
- ...props
569
- }),
570
- [
571
- blendFunction,
572
- blur,
573
- camera,
574
- edgeStrength,
575
- height,
576
- hiddenEdgeColor,
577
- kernelSize,
578
- patternTexture,
579
- pulseSpeed,
580
- scene,
581
- visibleEdgeColor,
582
- width,
583
- xRay
584
- ]
585
- );
586
- const api = React.useContext(selectionContext);
587
- React.useEffect(() => {
588
- if (!api && selection) {
589
- effect.selection.set(
590
- Array.isArray(selection) ? selection.map(resolveRef) : [resolveRef(selection)]
591
- );
592
- invalidate();
593
- return () => {
594
- effect.selection.clear();
595
- invalidate();
596
- };
597
- }
598
- }, [effect, selection, api, invalidate]);
599
- React.useEffect(() => {
600
- effect.selectionLayer = selectionLayer;
601
- invalidate();
602
- }, [effect, invalidate, selectionLayer]);
603
- React.useRef();
604
- React.useEffect(() => {
605
- var _a;
606
- if (api && api.enabled) {
607
- if ((_a = api.selected) == null ? void 0 : _a.length) {
608
- effect.selection.set(api.selected);
609
- invalidate();
610
- return () => {
611
- effect.selection.clear();
612
- invalidate();
613
- };
614
- }
615
- }
616
- }, [api, effect.selection, invalidate]);
617
- return /* @__PURE__ */ jsxRuntime.jsx("primitive", { ref: forwardRef2, object: effect });
618
- });
619
- const Pixelation = React.forwardRef(function Pixelation2({ granularity = 5 }, ref) {
620
- const effect = React.useMemo(() => new postprocessing.PixelationEffect(granularity), [granularity]);
621
- return /* @__PURE__ */ jsxRuntime.jsx("primitive", { ref, object: effect, dispose: null });
622
- });
623
- const Scanline = wrapEffect(postprocessing.ScanlineEffect, { blendFunction: postprocessing.BlendFunction.OVERLAY, density: 1.25 });
624
- const addLight = (light, effect) => light.layers.enable(effect.selection.layer);
625
- const removeLight = (light, effect) => light.layers.disable(effect.selection.layer);
626
- const SelectiveBloom = React.forwardRef(function SelectiveBloom2({
627
- selection = [],
628
- selectionLayer = 10,
629
- lights = [],
630
- luminanceThreshold,
631
- luminanceSmoothing,
632
- intensity,
633
- width,
634
- height,
635
- kernelSize,
636
- mipmapBlur,
637
- ...props
638
- }, forwardRef2) {
639
- if (lights.length === 0) {
640
- console.warn("SelectiveBloom requires lights to work.");
641
- }
642
- const invalidate = fiber.useThree((state) => state.invalidate);
643
- const { scene, camera } = React.useContext(EffectComposerContext);
644
- const effect = React.useMemo(
645
- () => new postprocessing.SelectiveBloomEffect(scene, camera, {
646
- blendFunction: postprocessing.BlendFunction.ADD,
647
- luminanceThreshold,
648
- luminanceSmoothing,
649
- intensity,
650
- width,
651
- height,
652
- kernelSize,
653
- mipmapBlur,
654
- ...props
655
- }),
656
- [scene, camera, luminanceThreshold, luminanceSmoothing, intensity, width, height, kernelSize, mipmapBlur, props]
657
- );
658
- const api = React.useContext(selectionContext);
659
- React.useEffect(() => {
660
- if (!api && selection) {
661
- effect.selection.set(
662
- Array.isArray(selection) ? selection.map(resolveRef) : [resolveRef(selection)]
663
- );
664
- invalidate();
665
- return () => {
666
- effect.selection.clear();
667
- invalidate();
668
- };
669
- }
670
- }, [effect, selection, api, invalidate]);
671
- React.useEffect(() => {
672
- effect.selection.layer = selectionLayer;
673
- invalidate();
674
- }, [effect, invalidate, selectionLayer]);
675
- React.useEffect(() => {
676
- if (lights && lights.length > 0) {
677
- lights.forEach((light) => addLight(resolveRef(light), effect));
678
- invalidate();
679
- return () => {
680
- lights.forEach((light) => removeLight(resolveRef(light), effect));
681
- invalidate();
682
- };
683
- }
684
- }, [effect, invalidate, lights, selectionLayer]);
685
- React.useEffect(() => {
686
- var _a;
687
- if (api && api.enabled) {
688
- if ((_a = api.selected) == null ? void 0 : _a.length) {
689
- effect.selection.set(api.selected);
690
- invalidate();
691
- return () => {
692
- effect.selection.clear();
693
- invalidate();
694
- };
695
- }
696
- }
697
- }, [api, effect.selection, invalidate]);
698
- return /* @__PURE__ */ jsxRuntime.jsx("primitive", { ref: forwardRef2, object: effect, dispose: null });
699
- });
700
- const Sepia = wrapEffect(postprocessing.SepiaEffect);
701
- const SSAO = React.forwardRef(function SSAO2(props, ref) {
702
- const { camera, normalPass, downSamplingPass, resolutionScale } = React.useContext(EffectComposerContext);
703
- const effect = React.useMemo(() => {
704
- if (normalPass === null && downSamplingPass === null) {
705
- console.error("Please enable the NormalPass in the EffectComposer in order to use SSAO.");
706
- return {};
707
- }
708
- return new postprocessing.SSAOEffect(camera, normalPass && !downSamplingPass ? normalPass.texture : null, {
709
- blendFunction: postprocessing.BlendFunction.MULTIPLY,
710
- samples: 30,
711
- rings: 4,
712
- distanceThreshold: 1,
713
- distanceFalloff: 0,
714
- rangeThreshold: 0.5,
715
- rangeFalloff: 0.1,
716
- luminanceInfluence: 0.9,
717
- radius: 20,
718
- bias: 0.5,
719
- intensity: 1,
720
- color: void 0,
721
- // @ts-ignore
722
- normalDepthBuffer: downSamplingPass ? downSamplingPass.texture : null,
723
- resolutionScale: resolutionScale != null ? resolutionScale : 1,
724
- depthAwareUpsampling: true,
725
- ...props
726
- });
727
- }, [camera, normalPass, props]);
728
- return /* @__PURE__ */ jsxRuntime.jsx("primitive", { ref, object: effect, dispose: null });
729
- });
730
- const SMAA = wrapEffect(postprocessing.SMAAEffect);
731
- const FXAA = wrapEffect(postprocessing.FXAAEffect);
732
- const Texture = React.forwardRef(function Texture2({ textureSrc, texture, ...props }, ref) {
733
- const t = fiber.useLoader(THREE.TextureLoader, textureSrc);
734
- React.useLayoutEffect(() => {
735
- t.encoding = THREE.sRGBEncoding;
736
- t.wrapS = t.wrapT = THREE.RepeatWrapping;
737
- }, [t]);
738
- const effect = React.useMemo(() => new postprocessing.TextureEffect({ ...props, texture: t || texture }), [props, t, texture]);
739
- return /* @__PURE__ */ jsxRuntime.jsx("primitive", { ref, object: effect, dispose: null });
740
- });
741
- const ToneMapping = wrapEffect(postprocessing.ToneMappingEffect);
742
- const Vignette = wrapEffect(postprocessing.VignetteEffect);
743
- const ShockWave = wrapEffect(postprocessing.ShockWaveEffect);
744
- const LUT = React.forwardRef(function LUT2({ lut, tetrahedralInterpolation, ...props }, ref) {
745
- const effect = React.useMemo(() => new postprocessing.LUT3DEffect(lut, props), [lut, props]);
746
- const invalidate = fiber.useThree((state) => state.invalidate);
747
- React.useLayoutEffect(() => {
748
- if (tetrahedralInterpolation)
749
- effect.tetrahedralInterpolation = tetrahedralInterpolation;
750
- if (lut)
751
- effect.lut = lut;
752
- invalidate();
753
- }, [effect, invalidate, lut, tetrahedralInterpolation]);
754
- return /* @__PURE__ */ jsxRuntime.jsx("primitive", { ref, object: effect, dispose: null });
755
- });
756
- const TiltShift = wrapEffect(postprocessing.TiltShiftEffect, { blendFunction: postprocessing.BlendFunction.ADD });
757
- const TiltShiftShader = {
758
- fragmentShader: `
759
-
760
- // original shader by Evan Wallace
761
-
762
- #define MAX_ITERATIONS 100
763
-
764
- uniform float blur;
765
- uniform float taper;
766
- uniform vec2 start;
767
- uniform vec2 end;
768
- uniform vec2 direction;
769
- uniform int samples;
770
-
771
- float random(vec3 scale, float seed) {
772
- /* use the fragment position for a different seed per-pixel */
773
- return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);
774
- }
775
-
776
- void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {
777
- vec4 color = vec4(0.0);
778
- float total = 0.0;
779
- vec2 startPixel = vec2(start.x * resolution.x, start.y * resolution.y);
780
- vec2 endPixel = vec2(end.x * resolution.x, end.y * resolution.y);
781
- float f_samples = float(samples);
782
- float half_samples = f_samples / 2.0;
783
-
784
- // use screen diagonal to normalize blur radii
785
- float maxScreenDistance = distance(vec2(0.0), resolution); // diagonal distance
786
- float gradientRadius = taper * (maxScreenDistance);
787
- float blurRadius = blur * (maxScreenDistance / 16.0);
788
-
789
- /* randomize the lookup values to hide the fixed number of samples */
790
- float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);
791
- vec2 normal = normalize(vec2(startPixel.y - endPixel.y, endPixel.x - startPixel.x));
792
- float radius = smoothstep(0.0, 1.0, abs(dot(uv * resolution - startPixel, normal)) / gradientRadius) * blurRadius;
793
-
794
- #pragma unroll_loop_start
795
- for (int i = 0; i <= MAX_ITERATIONS; i++) {
796
- if (i >= samples) { break; } // return early if over sample count
797
- float f_i = float(i);
798
- float s_i = -half_samples + f_i;
799
- float percent = (s_i + offset - 0.5) / half_samples;
800
- float weight = 1.0 - abs(percent);
801
- vec4 sample_i = texture2D(inputBuffer, uv + normalize(direction) / resolution * percent * radius);
802
- /* switch to pre-multiplied alpha to correctly blur transparent images */
803
- sample_i.rgb *= sample_i.a;
804
- color += sample_i * weight;
805
- total += weight;
806
- }
807
- #pragma unroll_loop_end
808
-
809
- outputColor = color / total;
810
-
811
- /* switch back from pre-multiplied alpha */
812
- outputColor.rgb /= outputColor.a + 0.00001;
813
- }
814
- `
815
- };
816
- class TiltShiftEffect extends postprocessing.Effect {
817
- constructor({
818
- blendFunction = postprocessing.BlendFunction.NORMAL,
819
- blur = 0.15,
820
- // [0, 1], can go beyond 1 for extra
821
- taper = 0.5,
822
- // [0, 1], can go beyond 1 for extra
823
- start = [0.5, 0],
824
- // [0,1] percentage x,y of screenspace
825
- end = [0.5, 1],
826
- // [0,1] percentage x,y of screenspace
827
- samples = 10,
828
- // number of blur samples
829
- direction = [1, 1]
830
- // direction of blur
831
- } = {}) {
832
- super("TiltShiftEffect", TiltShiftShader.fragmentShader, {
833
- blendFunction,
834
- attributes: postprocessing.EffectAttribute.CONVOLUTION,
835
- uniforms: /* @__PURE__ */ new Map([
836
- ["blur", new THREE.Uniform(blur)],
837
- ["taper", new THREE.Uniform(taper)],
838
- ["start", new THREE.Uniform(start)],
839
- ["end", new THREE.Uniform(end)],
840
- ["samples", new THREE.Uniform(samples)],
841
- ["direction", new THREE.Uniform(direction)]
842
- ])
843
- });
844
- }
845
- }
846
- const TiltShift2 = wrapEffect(TiltShiftEffect, { blendFunction: postprocessing.BlendFunction.NORMAL });
847
- const fragment = `
848
- uniform sampler2D uCharacters;
849
- uniform float uCharactersCount;
850
- uniform float uCellSize;
851
- uniform bool uInvert;
852
- uniform vec3 uColor;
853
-
854
- const vec2 SIZE = vec2(16.);
855
-
856
- vec3 greyscale(vec3 color, float strength) {
857
- float g = dot(color, vec3(0.299, 0.587, 0.114));
858
- return mix(color, vec3(g), strength);
859
- }
860
-
861
- vec3 greyscale(vec3 color) {
862
- return greyscale(color, 1.0);
863
- }
864
-
865
- void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {
866
- vec2 cell = resolution / uCellSize;
867
- vec2 grid = 1.0 / cell;
868
- vec2 pixelizedUV = grid * (0.5 + floor(uv / grid));
869
- vec4 pixelized = texture2D(inputBuffer, pixelizedUV);
870
- float greyscaled = greyscale(pixelized.rgb).r;
871
-
872
- if (uInvert) {
873
- greyscaled = 1.0 - greyscaled;
874
- }
875
-
876
- float characterIndex = floor((uCharactersCount - 1.0) * greyscaled);
877
- vec2 characterPosition = vec2(mod(characterIndex, SIZE.x), floor(characterIndex / SIZE.y));
878
- vec2 offset = vec2(characterPosition.x, -characterPosition.y) / SIZE;
879
- vec2 charUV = mod(uv * (cell / SIZE), 1.0 / SIZE) - vec2(0., 1.0 / SIZE) + offset;
880
- vec4 asciiCharacter = texture2D(uCharacters, charUV);
881
-
882
- asciiCharacter.rgb = uColor * asciiCharacter.r;
883
- asciiCharacter.a = pixelized.a;
884
- outputColor = asciiCharacter;
885
- }
886
- `;
887
- class ASCIIEffect extends postprocessing.Effect {
888
- constructor({
889
- characters = ` .:,'-^=*+?!|0#X%WM@`,
890
- fontSize = 54,
891
- cellSize = 16,
892
- color = "#ffffff",
893
- invert = false
894
- } = {}) {
895
- const uniforms = /* @__PURE__ */ new Map([
896
- ["uCharacters", new THREE.Uniform(new THREE.Texture())],
897
- ["uCellSize", new THREE.Uniform(cellSize)],
898
- ["uCharactersCount", new THREE.Uniform(characters.length)],
899
- ["uColor", new THREE.Uniform(new THREE.Color(color))],
900
- ["uInvert", new THREE.Uniform(invert)]
901
- ]);
902
- super("ASCIIEffect", fragment, { uniforms });
903
- const charactersTextureUniform = this.uniforms.get("uCharacters");
904
- if (charactersTextureUniform) {
905
- charactersTextureUniform.value = this.createCharactersTexture(characters, fontSize);
906
- }
907
- }
908
- /** Draws the characters on a Canvas and returns a texture */
909
- createCharactersTexture(characters, fontSize) {
910
- const canvas = document.createElement("canvas");
911
- const SIZE = 1024;
912
- const MAX_PER_ROW = 16;
913
- const CELL = SIZE / MAX_PER_ROW;
914
- canvas.width = canvas.height = SIZE;
915
- const texture = new THREE.CanvasTexture(canvas, void 0, THREE.RepeatWrapping, THREE.RepeatWrapping, THREE.NearestFilter, THREE.NearestFilter);
916
- const context = canvas.getContext("2d");
917
- if (!context) {
918
- throw new Error("Context not available");
919
- }
920
- context.clearRect(0, 0, SIZE, SIZE);
921
- context.font = `${fontSize}px arial`;
922
- context.textAlign = "center";
923
- context.textBaseline = "middle";
924
- context.fillStyle = "#fff";
925
- for (let i2 = 0; i2 < characters.length; i2++) {
926
- const char = characters[i2];
927
- const x = i2 % MAX_PER_ROW;
928
- const y = Math.floor(i2 / MAX_PER_ROW);
929
- context.fillText(char, x * CELL + CELL / 2, y * CELL + CELL / 2);
930
- }
931
- texture.needsUpdate = true;
932
- return texture;
933
- }
934
- }
935
- const ASCII = React.forwardRef(
936
- ({ characters = ` .:,'-^=*+?!|0#X%WM@`, fontSize = 54, cellSize = 16, color = "#ffffff", invert = false }, fref) => {
937
- const effect = React.useMemo(
938
- () => new ASCIIEffect({ characters, fontSize, cellSize, color, invert }),
939
- [characters, fontSize, cellSize, color, invert]
940
- );
941
- return /* @__PURE__ */ jsxRuntime.jsx("primitive", { ref: fref, object: effect });
942
- }
943
- );
944
- var boxBlur = "#define GLSLIFY 1\nuniform float blur;uniform float blurSharpness;uniform int blurKernel;vec3 denoise(vec3 center,sampler2D tex,vec2 uv,vec2 invTexSize,float blur,float blurSharpness,int blurKernel){vec3 color;float total;vec3 col;float weight;for(int x=-blurKernel;x<=blurKernel;x++){for(int y=-blurKernel;y<=blurKernel;y++){col=textureLod(tex,uv+vec2(x,y)*invTexSize,0.).rgb;weight=1.0-abs(dot(col-center,vec3(0.25)));weight=pow(weight,blurSharpness);color+=col*weight;total+=weight;}}return color/total;}";
945
- var finalSSRShader = "#define GLSLIFY 1\n#define MODE_DEFAULT 0\n#define MODE_REFLECTIONS 1\n#define MODE_RAW_REFLECTION 2\n#define MODE_BLURRED_REFLECTIONS 3\n#define MODE_INPUT 4\n#define MODE_BLUR_MIX 5\n#define FLOAT_EPSILON 0.00001\nuniform sampler2D inputTexture;uniform sampler2D reflectionsTexture;uniform float samples;\n#include <boxBlur>\nvoid mainImage(const in vec4 inputColor,const in vec2 uv,out vec4 outputColor){vec4 reflectionsTexel=texture2D(reflectionsTexture,vUv);ivec2 size=textureSize(reflectionsTexture,0);vec2 invTexSize=1./vec2(size.x,size.y);vec3 reflectionClr=reflectionsTexel.xyz;if(blur>FLOAT_EPSILON){vec3 blurredReflectionsColor=denoise(reflectionsTexel.rgb,reflectionsTexture,vUv,invTexSize,blur,blurSharpness,blurKernel);reflectionClr=mix(reflectionClr,blurredReflectionsColor.rgb,blur);}\n#if RENDER_MODE == MODE_DEFAULT\noutputColor=vec4(inputColor.rgb+reflectionClr,1.0);\n#endif\n#if RENDER_MODE == MODE_REFLECTIONS\noutputColor=vec4(reflectionClr,1.0);\n#endif\n#if RENDER_MODE == MODE_RAW_REFLECTION\noutputColor=vec4(reflectionsTexel.xyz,1.0);\n#endif\n#if RENDER_MODE == MODE_BLURRED_REFLECTIONS\noutputColor=vec4(blurredReflectionsTexel.xyz,1.0);\n#endif\n#if RENDER_MODE == MODE_INPUT\noutputColor=vec4(inputColor.xyz,1.0);\n#endif\n#if RENDER_MODE == MODE_BLUR_MIX\noutputColor=vec4(vec3(blur),1.0);\n#endif\n}";
946
- var helperFunctions = "#define GLSLIFY 1\nvec3 getViewPosition(const float depth){float clipW=_projectionMatrix[2][3]*depth+_projectionMatrix[3][3];vec4 clipPosition=vec4((vec3(vUv,depth)-0.5)*2.0,1.0);clipPosition*=clipW;return(_inverseProjectionMatrix*clipPosition).xyz;}float getViewZ(const in float depth){\n#ifdef PERSPECTIVE_CAMERA\nreturn perspectiveDepthToViewZ(depth,cameraNear,cameraFar);\n#else\nreturn orthographicDepthToViewZ(depth,cameraNear,cameraFar);\n#endif\n}vec3 screenSpaceToWorldSpace(const vec2 uv,const float depth){vec4 ndc=vec4((uv.x-0.5)*2.0,(uv.y-0.5)*2.0,(depth-0.5)*2.0,1.0);vec4 clip=_inverseProjectionMatrix*ndc;vec4 view=cameraMatrixWorld*(clip/clip.w);return view.xyz;}\n#define Scale (vec3(0.8, 0.8, 0.8))\n#define K (19.19)\nvec3 hash(vec3 a){a=fract(a*Scale);a+=dot(a,a.yxz+K);return fract((a.xxy+a.yxx)*a.zyx);}float fresnel_dielectric_cos(float cosi,float eta){float c=abs(cosi);float g=eta*eta-1.0+c*c;float result;if(g>0.0){g=sqrt(g);float A=(g-c)/(g+c);float B=(c*(g+c)-1.0)/(c*(g-c)+1.0);result=0.5*A*A*(1.0+B*B);}else{result=1.0;}return result;}float fresnel_dielectric(vec3 Incoming,vec3 Normal,float eta){float cosine=dot(Incoming,Normal);return min(1.0,5.0*fresnel_dielectric_cos(cosine,eta));}";
947
- var trCompose = "#define GLSLIFY 1\n#define INV_EULER 0.36787944117144233\nalpha=velocityDisocclusion<FLOAT_EPSILON ?(alpha+0.0075): 0.0;alpha=clamp(alpha,0.0,1.0);bool needsBlur=!didReproject||velocityDisocclusion>0.5;\n#ifdef boxBlur\nif(needsBlur)inputColor=boxBlurredColor;\n#endif\nif(alpha==1.0){outputColor=accumulatedColor;}else{float m=mix(alpha,1.0,blend);if(needsBlur)m=0.0;outputColor=accumulatedColor*m+inputColor*(1.0-m);}";
948
- class MRTMaterial extends THREE.ShaderMaterial {
949
- constructor() {
950
- super({
951
- type: "MRTMaterial",
952
- defines: {
953
- USE_UV: "",
954
- TEMPORAL_RESOLVE: ""
955
- },
956
- uniforms: {
957
- opacity: new THREE.Uniform(1),
958
- normalMap: new THREE.Uniform(null),
959
- normalScale: new THREE.Uniform(new THREE.Vector2(1, 1)),
960
- uvTransform: new THREE.Uniform(new THREE.Matrix3()),
961
- roughness: new THREE.Uniform(1),
962
- roughnessMap: new THREE.Uniform(null)
963
- },
964
- vertexShader: (
965
- /* glsl */
966
- `
967
- #ifdef USE_MRT
968
- varying vec2 vHighPrecisionZW;
969
- #endif
970
- #define NORMAL
971
- #if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )
972
- varying vec3 vViewPosition;
973
- #endif
974
- #include <common>
975
- #include <uv_pars_vertex>
976
- #include <displacementmap_pars_vertex>
977
- #include <normal_pars_vertex>
978
- #include <morphtarget_pars_vertex>
979
- #include <skinning_pars_vertex>
980
- #include <logdepthbuf_pars_vertex>
981
- #include <clipping_planes_pars_vertex>
982
- #ifdef USE_UV
983
- ${THREE.REVISION.replace(/\D+/g, "") >= 151 ? "uniform mat3 uvTransform;" : ""}
984
- #endif
985
- void main() {
986
- #include <uv_vertex>
987
- #include <beginnormal_vertex>
988
- #include <morphnormal_vertex>
989
- #include <skinbase_vertex>
990
- #include <skinnormal_vertex>
991
- #include <defaultnormal_vertex>
992
- #include <normal_vertex>
993
- #include <begin_vertex>
994
- #include <morphtarget_vertex>
995
- #include <skinning_vertex>
996
- #include <displacementmap_vertex>
997
- #include <project_vertex>
998
- #include <logdepthbuf_vertex>
999
- #include <clipping_planes_vertex>
1000
- #if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )
1001
- vViewPosition = - mvPosition.xyz;
1002
- #endif
1003
- #ifdef USE_MRT
1004
- vHighPrecisionZW = gl_Position.zw;
1005
- #endif
1006
- #ifdef USE_UV
1007
- vUv = ( uvTransform * vec3( uv, 1 ) ).xy;
1008
- #endif
1009
- }
1010
- `
1011
- ),
1012
- fragmentShader: (
1013
- /* glsl */
1014
- `
1015
- #define NORMAL
1016
- #if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )
1017
- varying vec3 vViewPosition;
1018
- #endif
1019
- #include <packing>
1020
- #include <uv_pars_fragment>
1021
- #include <normal_pars_fragment>
1022
- #include <bumpmap_pars_fragment>
1023
- #include <normalmap_pars_fragment>
1024
- #include <logdepthbuf_pars_fragment>
1025
- #include <clipping_planes_pars_fragment>
1026
- #include <roughnessmap_pars_fragment>
1027
-
1028
- #ifdef USE_MRT
1029
- layout(location = 0) out vec4 gNormal;
1030
- layout(location = 1) out vec4 gDepth;
1031
-
1032
- varying vec2 vHighPrecisionZW;
1033
- #endif
1034
- uniform float roughness;
1035
- void main() {
1036
- #include <clipping_planes_fragment>
1037
- #include <logdepthbuf_fragment>
1038
- #include <normal_fragment_begin>
1039
- #include <normal_fragment_maps>
1040
-
1041
- float roughnessFactor = roughness;
1042
-
1043
- if(roughness > 10.0e9){
1044
- roughnessFactor = 1.;
1045
- }else{
1046
- #ifdef useRoughnessMap
1047
- vec4 texelRoughness = texture2D( roughnessMap, vUv );
1048
- // reads channel G, compatible with a combined OcclusionRoughnessMetallic (RGB) texture
1049
- roughnessFactor *= texelRoughness.g;
1050
- #endif
1051
- }
1052
-
1053
- vec3 normalColor = packNormalToRGB( normal );
1054
- #ifdef USE_MRT
1055
- float fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;
1056
- vec4 depthColor = packDepthToRGBA( fragCoordZ );
1057
- gNormal = vec4( normalColor, roughnessFactor );
1058
- gDepth = depthColor;
1059
- #else
1060
- gl_FragColor = vec4(normalColor, roughnessFactor);
1061
- #endif
1062
- }
1063
- `
1064
- ),
1065
- toneMapped: false
1066
- });
1067
- this.normalMapType = THREE.TangentSpaceNormalMap;
1068
- this.normalScale = new THREE.Vector2(1, 1);
1069
- Object.defineProperty(this, "glslVersion", {
1070
- get() {
1071
- return "USE_MRT" in this.defines ? THREE.GLSL3 : null;
1072
- },
1073
- set(_) {
1074
- }
1075
- });
1076
- }
1077
- }
1078
- var vertexShader$1 = "#define GLSLIFY 1\nvarying vec2 vUv;void main(){vUv=position.xy*0.5+0.5;gl_Position=vec4(position.xy,1.0,1.0);}";
1079
- var fragmentShader = "#define GLSLIFY 1\nvarying vec2 vUv;uniform sampler2D inputTexture;uniform sampler2D accumulatedTexture;uniform sampler2D normalTexture;uniform sampler2D depthTexture;uniform sampler2D envMap;uniform mat4 _projectionMatrix;uniform mat4 _inverseProjectionMatrix;uniform mat4 cameraMatrixWorld;uniform float cameraNear;uniform float cameraFar;uniform float rayDistance;uniform float intensity;uniform float maxDepthDifference;uniform float roughnessFade;uniform float maxRoughness;uniform float fade;uniform float thickness;uniform float ior;uniform float samples;uniform float jitter;uniform float jitterRoughness;\n#define INVALID_RAY_COORDS vec2(-1.0);\n#define EARLY_OUT_COLOR vec4(0.0, 0.0, 0.0, 1.0)\n#define FLOAT_EPSILON 0.00001\nfloat nearMinusFar;float nearMulFar;float farMinusNear;\n#include <packing>\n#include <helperFunctions>\nvec2 RayMarch(vec3 dir,inout vec3 hitPos,inout float rayHitDepthDifference);vec2 BinarySearch(in vec3 dir,inout vec3 hitPos,inout float rayHitDepthDifference);float fastGetViewZ(const in float depth);vec3 getIBLRadiance(const in vec3 viewDir,const in vec3 normal,const in float roughness);void main(){vec4 depthTexel=textureLod(depthTexture,vUv,0.0);if(dot(depthTexel.rgb,depthTexel.rgb)<FLOAT_EPSILON){gl_FragColor=EARLY_OUT_COLOR;return;}float unpackedDepth=unpackRGBAToDepth(depthTexel);vec4 normalTexel=textureLod(normalTexture,vUv,0.0);float roughness=normalTexel.a;float specular=1.0-roughness;nearMinusFar=cameraNear-cameraFar;nearMulFar=cameraNear*cameraFar;farMinusNear=cameraFar-cameraNear;normalTexel.rgb=unpackRGBToNormal(normalTexel.rgb);float depth=fastGetViewZ(unpackedDepth);vec3 viewPos=getViewPosition(depth);vec3 viewDir=normalize(viewPos);vec3 viewNormal=normalTexel.xyz;vec3 worldPos=screenSpaceToWorldSpace(vUv,unpackedDepth);vec3 jitt=vec3(0.0);if(jitterRoughness!=0.0||jitter!=0.0){vec3 randomJitter=hash(50.0*samples*worldPos)-0.5;float spread=((2.0-specular)+roughness*jitterRoughness);float jitterMix=jitter*0.25+jitterRoughness*roughness;if(jitterMix>1.0)jitterMix=1.0;jitt=mix(vec3(0.0),randomJitter*spread,jitterMix);}viewNormal+=jitt;float fresnelFactor=fresnel_dielectric(viewDir,viewNormal,ior);vec3 iblRadiance=getIBLRadiance(-viewDir,viewNormal,0.)*fresnelFactor;float lastFrameAlpha=textureLod(accumulatedTexture,vUv,0.0).a;if(roughness>maxRoughness||(roughness>1.0-FLOAT_EPSILON&&roughnessFade>1.0-FLOAT_EPSILON)){gl_FragColor=vec4(iblRadiance,lastFrameAlpha);return;}vec3 reflected=reflect(viewDir,viewNormal);vec3 rayDir=reflected*-viewPos.z;vec3 hitPos=viewPos;float rayHitDepthDifference;vec2 coords=RayMarch(rayDir,hitPos,rayHitDepthDifference);if(coords.x==-1.0){gl_FragColor=vec4(iblRadiance,lastFrameAlpha);return;}vec4 SSRTexel=textureLod(inputTexture,coords.xy,0.0);vec4 SSRTexelReflected=textureLod(accumulatedTexture,coords.xy,0.0);vec3 SSR=SSRTexel.rgb+SSRTexelReflected.rgb;float roughnessFactor=mix(specular,1.0,max(0.0,1.0-roughnessFade));vec2 coordsNDC=(coords.xy*2.0-1.0);float screenFade=0.1;float maxDimension=min(1.0,max(abs(coordsNDC.x),abs(coordsNDC.y)));float reflectionIntensity=1.0-(max(0.0,maxDimension-screenFade)/(1.0-screenFade));reflectionIntensity=max(0.,reflectionIntensity);vec3 finalSSR=mix(iblRadiance,SSR,reflectionIntensity)*roughnessFactor;if(fade!=0.0){vec3 hitWorldPos=screenSpaceToWorldSpace(coords,rayHitDepthDifference);float reflectionDistance=distance(hitWorldPos,worldPos)+1.0;float opacity=1.0/(reflectionDistance*fade*0.1);if(opacity>1.0)opacity=1.0;finalSSR*=opacity;}finalSSR*=fresnelFactor*intensity;finalSSR=min(vec3(1.0),finalSSR);float alpha=hitPos.z==1.0 ? 1.0 : SSRTexelReflected.a;alpha=min(lastFrameAlpha,alpha);gl_FragColor=vec4(finalSSR,alpha);}vec2 RayMarch(vec3 dir,inout vec3 hitPos,inout float rayHitDepthDifference){dir=normalize(dir);dir*=rayDistance/float(steps);float depth;vec4 projectedCoord;vec4 lastProjectedCoord;float unpackedDepth;vec4 depthTexel;for(int i=0;i<steps;i++){hitPos+=dir;projectedCoord=_projectionMatrix*vec4(hitPos,1.0);projectedCoord.xy/=projectedCoord.w;projectedCoord.xy=projectedCoord.xy*0.5+0.5;\n#ifndef missedRays\nif(projectedCoord.x<0.0||projectedCoord.x>1.0||projectedCoord.y<0.0||projectedCoord.y>1.0){return INVALID_RAY_COORDS;}\n#endif\ndepthTexel=textureLod(depthTexture,projectedCoord.xy,0.0);unpackedDepth=unpackRGBAToDepth(depthTexel);depth=fastGetViewZ(unpackedDepth);rayHitDepthDifference=depth-hitPos.z;if(rayHitDepthDifference>=0.0&&rayHitDepthDifference<thickness){\n#if refineSteps == 0\nif(dot(depthTexel.rgb,depthTexel.rgb)<FLOAT_EPSILON)return INVALID_RAY_COORDS;\n#else\nreturn BinarySearch(dir,hitPos,rayHitDepthDifference);\n#endif\n}\n#ifndef missedRays\nif(hitPos.z>0.0){return INVALID_RAY_COORDS;}\n#endif\nlastProjectedCoord=projectedCoord;}hitPos.z=1.0;\n#ifndef missedRays\nreturn INVALID_RAY_COORDS;\n#endif\nrayHitDepthDifference=unpackedDepth;return projectedCoord.xy;}vec2 BinarySearch(in vec3 dir,inout vec3 hitPos,inout float rayHitDepthDifference){float depth;vec4 projectedCoord;vec2 lastMinProjectedCoordXY;float unpackedDepth;vec4 depthTexel;for(int i=0;i<refineSteps;i++){projectedCoord=_projectionMatrix*vec4(hitPos,1.0);projectedCoord.xy/=projectedCoord.w;projectedCoord.xy=projectedCoord.xy*0.5+0.5;depthTexel=textureLod(depthTexture,projectedCoord.xy,0.0);unpackedDepth=unpackRGBAToDepth(depthTexel);depth=fastGetViewZ(unpackedDepth);rayHitDepthDifference=depth-hitPos.z;dir*=0.5;if(rayHitDepthDifference>0.0){hitPos-=dir;}else{hitPos+=dir;}}if(dot(depthTexel.rgb,depthTexel.rgb)<FLOAT_EPSILON)return INVALID_RAY_COORDS;if(abs(rayHitDepthDifference)>maxDepthDifference)return INVALID_RAY_COORDS;projectedCoord=_projectionMatrix*vec4(hitPos,1.0);projectedCoord.xy/=projectedCoord.w;projectedCoord.xy=projectedCoord.xy*0.5+0.5;rayHitDepthDifference=unpackedDepth;return projectedCoord.xy;}float fastGetViewZ(const in float depth){\n#ifdef PERSPECTIVE_CAMERA\nreturn nearMulFar/(farMinusNear*depth-cameraFar);\n#else\nreturn depth*nearMinusFar-cameraNear;\n#endif\n}\n#include <common>\n#include <cube_uv_reflection_fragment>\nvec3 getIBLRadiance(const in vec3 viewDir,const in vec3 normal,const in float roughness){\n#if defined(ENVMAP_TYPE_CUBE_UV)\nvec3 reflectVec=reflect(-viewDir,normal);reflectVec=normalize(mix(reflectVec,normal,roughness*roughness));reflectVec=inverseTransformDirection(reflectVec,viewMatrix);vec4 envMapColor=textureCubeUV(envMap,reflectVec,roughness);return envMapColor.rgb*intensity;\n#else\nreturn vec3(0.0);\n#endif\n}";
1080
- class ReflectionsMaterial extends THREE.ShaderMaterial {
1081
- constructor() {
1082
- super({
1083
- type: "ReflectionsMaterial",
1084
- uniforms: {
1085
- inputTexture: new THREE.Uniform(null),
1086
- accumulatedTexture: new THREE.Uniform(null),
1087
- normalTexture: new THREE.Uniform(null),
1088
- depthTexture: new THREE.Uniform(null),
1089
- _projectionMatrix: new THREE.Uniform(new THREE.Matrix4()),
1090
- _inverseProjectionMatrix: new THREE.Uniform(new THREE.Matrix4()),
1091
- cameraMatrixWorld: new THREE.Uniform(new THREE.Matrix4()),
1092
- cameraNear: new THREE.Uniform(0),
1093
- cameraFar: new THREE.Uniform(0),
1094
- rayDistance: new THREE.Uniform(0),
1095
- intensity: new THREE.Uniform(0),
1096
- roughnessFade: new THREE.Uniform(0),
1097
- fade: new THREE.Uniform(0),
1098
- thickness: new THREE.Uniform(0),
1099
- ior: new THREE.Uniform(0),
1100
- maxDepthDifference: new THREE.Uniform(0),
1101
- jitter: new THREE.Uniform(0),
1102
- jitterRoughness: new THREE.Uniform(0),
1103
- maxRoughness: new THREE.Uniform(0),
1104
- samples: new THREE.Uniform(0),
1105
- envMap: new THREE.Uniform(null),
1106
- envMapPosition: new THREE.Uniform(new THREE.Vector3()),
1107
- envMapSize: new THREE.Uniform(new THREE.Vector3()),
1108
- viewMatrix: new THREE.Uniform(new THREE.Matrix4())
1109
- },
1110
- defines: {
1111
- steps: 20,
1112
- refineSteps: 5,
1113
- CUBEUV_TEXEL_WIDTH: 0,
1114
- CUBEUV_TEXEL_HEIGHT: 0,
1115
- CUBEUV_MAX_MIP: 0,
1116
- vWorldPosition: "worldPos"
1117
- },
1118
- fragmentShader: fragmentShader.replace("#include <helperFunctions>", helperFunctions),
1119
- vertexShader: vertexShader$1,
1120
- toneMapped: false,
1121
- depthWrite: false,
1122
- depthTest: false
1123
- });
1124
- }
1125
- }
1126
- const getVisibleChildren = (object) => {
1127
- const queue = [object];
1128
- const objects = [];
1129
- while (queue.length !== 0) {
1130
- const mesh = queue.shift();
1131
- if (mesh.material)
1132
- objects.push(mesh);
1133
- for (const c of mesh.children) {
1134
- if (c.visible)
1135
- queue.push(c);
1136
- }
1137
- }
1138
- return objects;
1139
- };
1140
- const generateCubeUVSize = (parameters) => {
1141
- const imageHeight = parameters.envMapCubeUVHeight;
1142
- if (imageHeight === null)
1143
- return null;
1144
- const maxMip = Math.log2(imageHeight) - 2;
1145
- const texelHeight = 1 / imageHeight;
1146
- const texelWidth = 1 / (3 * Math.max(Math.pow(2, maxMip), 7 * 16));
1147
- return {
1148
- texelWidth,
1149
- texelHeight,
1150
- maxMip
1151
- };
1152
- };
1153
- const setupEnvMap = (reflectionsMaterial, envMap, envMapCubeUVHeight) => {
1154
- reflectionsMaterial.uniforms.envMap.value = envMap;
1155
- const envMapCubeUVSize = generateCubeUVSize({
1156
- envMapCubeUVHeight
1157
- });
1158
- reflectionsMaterial.defines.ENVMAP_TYPE_CUBE_UV = "";
1159
- reflectionsMaterial.defines.CUBEUV_TEXEL_WIDTH = envMapCubeUVSize.texelWidth;
1160
- reflectionsMaterial.defines.CUBEUV_TEXEL_HEIGHT = envMapCubeUVSize.texelHeight;
1161
- reflectionsMaterial.defines.CUBEUV_MAX_MIP = envMapCubeUVSize.maxMip + ".0";
1162
- reflectionsMaterial.needsUpdate = true;
1163
- };
1164
- const isWebGL2Available = () => {
1165
- try {
1166
- const canvas = document.createElement("canvas");
1167
- return !!(window.WebGL2RenderingContext && canvas.getContext("webgl2"));
1168
- } catch (e) {
1169
- return false;
1170
- }
1171
- };
1172
- class ReflectionsPass extends postprocessing.Pass {
1173
- constructor(ssrEffect, options = {}) {
1174
- super("ReflectionsPass");
1175
- this.ssrEffect = void 0;
1176
- this.cachedMaterials = /* @__PURE__ */ new WeakMap();
1177
- this.USE_MRT = false;
1178
- this.webgl1DepthPass = null;
1179
- this.visibleMeshes = [];
1180
- this.ssrEffect = ssrEffect;
1181
- this._scene = ssrEffect._scene;
1182
- this._camera = ssrEffect._camera;
1183
- this.fullscreenMaterial = new ReflectionsMaterial();
1184
- if (ssrEffect._camera.isPerspectiveCamera)
1185
- this.fullscreenMaterial.defines.PERSPECTIVE_CAMERA = "";
1186
- const width = options.width || typeof window !== "undefined" ? window.innerWidth : 2e3;
1187
- const height = options.height || typeof window !== "undefined" ? window.innerHeight : 1e3;
1188
- this.renderTarget = new THREE.WebGLRenderTarget(width, height, {
1189
- minFilter: THREE.LinearFilter,
1190
- magFilter: THREE.LinearFilter,
1191
- type: THREE.HalfFloatType,
1192
- depthBuffer: false
1193
- });
1194
- this.renderPass = new postprocessing.RenderPass(this._scene, this._camera);
1195
- this.USE_MRT = isWebGL2Available();
1196
- if (this.USE_MRT) {
1197
- this.gBuffersRenderTarget = new THREE.WebGLMultipleRenderTargets(width, height, 2, {
1198
- minFilter: THREE.LinearFilter,
1199
- magFilter: THREE.LinearFilter
1200
- });
1201
- this.normalTexture = this.gBuffersRenderTarget.texture[0];
1202
- this.depthTexture = this.gBuffersRenderTarget.texture[1];
1203
- } else {
1204
- this.webgl1DepthPass = new postprocessing.DepthPass(this._scene, this._camera);
1205
- this.webgl1DepthPass.renderTarget.minFilter = THREE.LinearFilter;
1206
- this.webgl1DepthPass.renderTarget.magFilter = THREE.LinearFilter;
1207
- this.webgl1DepthPass.renderTarget.texture.minFilter = THREE.LinearFilter;
1208
- this.webgl1DepthPass.renderTarget.texture.magFilter = THREE.LinearFilter;
1209
- this.webgl1DepthPass.setSize(
1210
- typeof window !== "undefined" ? window.innerWidth : 2e3,
1211
- typeof window !== "undefined" ? window.innerHeight : 1e3
1212
- );
1213
- this.gBuffersRenderTarget = new THREE.WebGLRenderTarget(width, height, {
1214
- minFilter: THREE.LinearFilter,
1215
- magFilter: THREE.LinearFilter
1216
- });
1217
- this.normalTexture = this.gBuffersRenderTarget.texture;
1218
- this.depthTexture = this.webgl1DepthPass.texture;
1219
- }
1220
- this.fullscreenMaterial.uniforms.normalTexture.value = this.normalTexture;
1221
- this.fullscreenMaterial.uniforms.depthTexture.value = this.depthTexture;
1222
- this.fullscreenMaterial.uniforms.accumulatedTexture.value = this.ssrEffect.temporalResolvePass.accumulatedTexture;
1223
- this.fullscreenMaterial.uniforms.cameraMatrixWorld.value = this._camera.matrixWorld;
1224
- this.fullscreenMaterial.uniforms._projectionMatrix.value = this._camera.projectionMatrix;
1225
- this.fullscreenMaterial.uniforms._inverseProjectionMatrix.value = this._camera.projectionMatrixInverse;
1226
- }
1227
- setSize(width, height) {
1228
- this.renderTarget.setSize(width * this.ssrEffect.resolutionScale, height * this.ssrEffect.resolutionScale);
1229
- this.gBuffersRenderTarget.setSize(width * this.ssrEffect.resolutionScale, height * this.ssrEffect.resolutionScale);
1230
- this.fullscreenMaterial.uniforms.accumulatedTexture.value = this.ssrEffect.temporalResolvePass.accumulatedTexture;
1231
- this.fullscreenMaterial.needsUpdate = true;
1232
- }
1233
- dispose() {
1234
- this.renderTarget.dispose();
1235
- this.gBuffersRenderTarget.dispose();
1236
- this.renderPass.dispose();
1237
- if (!this.USE_MRT)
1238
- this.webgl1DepthPass.dispose();
1239
- this.fullscreenMaterial.dispose();
1240
- this.normalTexture = null;
1241
- this.depthTexture = null;
1242
- this.velocityTexture = null;
1243
- }
1244
- keepMaterialMapUpdated(mrtMaterial, originalMaterial, prop, define) {
1245
- if (this.ssrEffect[define]) {
1246
- if (originalMaterial[prop] !== mrtMaterial[prop]) {
1247
- mrtMaterial[prop] = originalMaterial[prop];
1248
- mrtMaterial.uniforms[prop].value = originalMaterial[prop];
1249
- if (originalMaterial[prop]) {
1250
- mrtMaterial.defines[define] = "";
1251
- } else {
1252
- delete mrtMaterial.defines[define];
1253
- }
1254
- mrtMaterial.needsUpdate = true;
1255
- }
1256
- } else if (mrtMaterial[prop] !== void 0) {
1257
- mrtMaterial[prop] = void 0;
1258
- mrtMaterial.uniforms[prop].value = void 0;
1259
- delete mrtMaterial.defines[define];
1260
- mrtMaterial.needsUpdate = true;
1261
- }
1262
- }
1263
- setMRTMaterialInScene() {
1264
- this.visibleMeshes = getVisibleChildren(this._scene);
1265
- for (const c of this.visibleMeshes) {
1266
- if (c.material) {
1267
- const originalMaterial = c.material;
1268
- let [cachedOriginalMaterial, mrtMaterial] = this.cachedMaterials.get(c) || [];
1269
- if (originalMaterial !== cachedOriginalMaterial) {
1270
- if (mrtMaterial)
1271
- mrtMaterial.dispose();
1272
- mrtMaterial = new MRTMaterial();
1273
- if (this.USE_MRT)
1274
- mrtMaterial.defines.USE_MRT = "";
1275
- mrtMaterial.normalScale = originalMaterial.normalScale;
1276
- mrtMaterial.uniforms.normalScale.value = originalMaterial.normalScale;
1277
- const map = originalMaterial.map || originalMaterial.normalMap || originalMaterial.roughnessMap || originalMaterial.metalnessMap;
1278
- if (map)
1279
- mrtMaterial.uniforms.uvTransform.value = map.matrix;
1280
- this.cachedMaterials.set(c, [originalMaterial, mrtMaterial]);
1281
- }
1282
- this.keepMaterialMapUpdated(mrtMaterial, originalMaterial, "normalMap", "useNormalMap");
1283
- this.keepMaterialMapUpdated(mrtMaterial, originalMaterial, "roughnessMap", "useRoughnessMap");
1284
- mrtMaterial.uniforms.roughness.value = this.ssrEffect.selection.size === 0 || this.ssrEffect.selection.has(c) ? originalMaterial.roughness || 0 : 1e11;
1285
- c.material = mrtMaterial;
1286
- }
1287
- }
1288
- }
1289
- unsetMRTMaterialInScene() {
1290
- for (const c of this.visibleMeshes) {
1291
- var _c$material;
1292
- if (((_c$material = c.material) == null ? void 0 : _c$material.type) === "MRTMaterial") {
1293
- c.visible = true;
1294
- const [originalMaterial] = this.cachedMaterials.get(c);
1295
- c.material = originalMaterial;
1296
- }
1297
- }
1298
- }
1299
- render(renderer, inputBuffer) {
1300
- this.setMRTMaterialInScene();
1301
- renderer.setRenderTarget(this.gBuffersRenderTarget);
1302
- this.renderPass.render(renderer, this.gBuffersRenderTarget);
1303
- this.unsetMRTMaterialInScene();
1304
- if (!this.USE_MRT)
1305
- this.webgl1DepthPass.renderPass.render(renderer, this.webgl1DepthPass.renderTarget);
1306
- this.fullscreenMaterial.uniforms.inputTexture.value = inputBuffer.texture;
1307
- this.fullscreenMaterial.uniforms.samples.value = this.ssrEffect.temporalResolvePass.samples;
1308
- this.fullscreenMaterial.uniforms.cameraNear.value = this._camera.near;
1309
- this.fullscreenMaterial.uniforms.cameraFar.value = this._camera.far;
1310
- this.fullscreenMaterial.uniforms.viewMatrix.value.copy(this._camera.matrixWorldInverse);
1311
- renderer.setRenderTarget(this.renderTarget);
1312
- renderer.render(this.scene, this.camera);
1313
- }
1314
- }
1315
- const defaultSSROptions = {
1316
- intensity: 1,
1317
- exponent: 1,
1318
- distance: 10,
1319
- fade: 0,
1320
- roughnessFade: 1,
1321
- thickness: 10,
1322
- ior: 1.45,
1323
- maxRoughness: 1,
1324
- maxDepthDifference: 10,
1325
- blend: 0.9,
1326
- correction: 1,
1327
- correctionRadius: 1,
1328
- blur: 0.5,
1329
- blurKernel: 1,
1330
- blurSharpness: 10,
1331
- jitter: 0,
1332
- jitterRoughness: 0,
1333
- steps: 20,
1334
- refineSteps: 5,
1335
- missedRays: true,
1336
- useNormalMap: true,
1337
- useRoughnessMap: true,
1338
- resolutionScale: 1,
1339
- velocityResolutionScale: 1
1340
- };
1341
- var vertexShader = "#define GLSLIFY 1\nvarying vec2 vUv;void main(){vUv=position.xy*0.5+0.5;gl_Position=vec4(position.xy,1.0,1.0);}";
1342
- var temporalResolve = "#define GLSLIFY 1\nuniform sampler2D inputTexture;uniform sampler2D accumulatedTexture;uniform sampler2D velocityTexture;uniform sampler2D lastVelocityTexture;uniform float blend;uniform float correction;uniform float exponent;uniform float samples;uniform vec2 invTexSize;uniform mat4 curInverseProjectionMatrix;uniform mat4 curCameraMatrixWorld;uniform mat4 prevInverseProjectionMatrix;uniform mat4 prevCameraMatrixWorld;varying vec2 vUv;\n#define MAX_NEIGHBOR_DEPTH_DIFFERENCE 0.001\n#define FLOAT_EPSILON 0.00001\n#define FLOAT_ONE_MINUS_EPSILON 0.99999\nvec3 transformexponent;vec3 undoColorTransformExponent;vec3 transformColor(vec3 color){if(exponent==1.0)return color;return pow(abs(color),transformexponent);}vec3 undoColorTransform(vec3 color){if(exponent==1.0)return color;return max(pow(abs(color),undoColorTransformExponent),vec3(0.0));}void main(){if(exponent!=1.0){transformexponent=vec3(1.0/exponent);undoColorTransformExponent=vec3(exponent);}vec4 inputTexel=textureLod(inputTexture,vUv,0.0);vec4 accumulatedTexel;vec3 inputColor=transformColor(inputTexel.rgb);vec3 accumulatedColor;float alpha=inputTexel.a;float velocityDisocclusion;bool didReproject=false;\n#ifdef boxBlur\nvec3 boxBlurredColor=inputTexel.rgb;\n#endif\nvec4 velocity=textureLod(velocityTexture,vUv,0.0);bool isMoving=alpha<1.0||dot(velocity.xy,velocity.xy)>0.0;if(isMoving){vec3 minNeighborColor=inputColor;vec3 maxNeighborColor=inputColor;vec3 col;vec2 neighborUv;vec2 reprojectedUv=vUv-velocity.xy;vec4 lastVelocity=textureLod(lastVelocityTexture,reprojectedUv,0.0);float depth=velocity.b;float closestDepth=depth;float lastClosestDepth=lastVelocity.b;float neighborDepth;float lastNeighborDepth;for(int x=-correctionRadius;x<=correctionRadius;x++){for(int y=-correctionRadius;y<=correctionRadius;y++){if(x!=0||y!=0){neighborUv=vUv+vec2(x,y)*invTexSize;vec4 neigborVelocity=textureLod(velocityTexture,neighborUv,0.0);neighborDepth=neigborVelocity.b;col=textureLod(inputTexture,neighborUv,0.0).xyz;int absX=abs(x);int absY=abs(y);\n#ifdef dilation\nif(absX==1&&absY==1){if(neighborDepth>closestDepth){velocity=neigborVelocity;closestDepth=neighborDepth;}vec4 lastNeighborVelocity=textureLod(velocityTexture,vUv+vec2(x,y)*invTexSize,0.0);lastNeighborDepth=lastNeighborVelocity.b;if(neighborDepth>closestDepth){lastVelocity=lastNeighborVelocity;lastClosestDepth=lastNeighborDepth;}}\n#endif\nif(abs(depth-neighborDepth)<MAX_NEIGHBOR_DEPTH_DIFFERENCE){\n#ifdef boxBlur\nif(absX<=2&&absY<=2)boxBlurredColor+=col;\n#endif\ncol=transformColor(col);minNeighborColor=min(col,minNeighborColor);maxNeighborColor=max(col,maxNeighborColor);}}}}float velocityLength=length(lastVelocity.xy-velocity.xy);velocityDisocclusion=(velocityLength-0.000005)*10.0;velocityDisocclusion*=velocityDisocclusion;reprojectedUv=vUv-velocity.xy;\n#ifdef boxBlur\nfloat pxRadius=correctionRadius>5 ? 121.0 : pow(float(correctionRadius*2+1),2.0);boxBlurredColor/=pxRadius;boxBlurredColor=transformColor(boxBlurredColor);\n#endif\nif(reprojectedUv.x>=0.0&&reprojectedUv.x<=1.0&&reprojectedUv.y>=0.0&&reprojectedUv.y<=1.0){accumulatedTexel=textureLod(accumulatedTexture,reprojectedUv,0.0);accumulatedColor=transformColor(accumulatedTexel.rgb);vec3 clampedColor=clamp(accumulatedColor,minNeighborColor,maxNeighborColor);accumulatedColor=mix(accumulatedColor,clampedColor,correction);didReproject=true;}else{\n#ifdef boxBlur\naccumulatedColor=boxBlurredColor;\n#else\naccumulatedColor=inputColor;\n#endif\n}if(velocity.r>FLOAT_ONE_MINUS_EPSILON&&velocity.g>FLOAT_ONE_MINUS_EPSILON){alpha=0.0;velocityDisocclusion=1.0;}}else{accumulatedColor=transformColor(textureLod(accumulatedTexture,vUv,0.0).rgb);}vec3 outputColor=inputColor;\n#include <custom_compose_shader>\ngl_FragColor=vec4(undoColorTransform(outputColor),alpha);}";
1343
- class TemporalResolveMaterial extends THREE.ShaderMaterial {
1344
- constructor(customComposeShader) {
1345
- const fragmentShader2 = temporalResolve.replace("#include <custom_compose_shader>", customComposeShader);
1346
- super({
1347
- type: "TemporalResolveMaterial",
1348
- uniforms: {
1349
- inputTexture: new THREE.Uniform(null),
1350
- accumulatedTexture: new THREE.Uniform(null),
1351
- velocityTexture: new THREE.Uniform(null),
1352
- lastVelocityTexture: new THREE.Uniform(null),
1353
- samples: new THREE.Uniform(1),
1354
- blend: new THREE.Uniform(0.5),
1355
- correction: new THREE.Uniform(1),
1356
- exponent: new THREE.Uniform(1),
1357
- invTexSize: new THREE.Uniform(new THREE.Vector2())
1358
- },
1359
- defines: {
1360
- correctionRadius: 1
1361
- },
1362
- vertexShader,
1363
- fragmentShader: fragmentShader2
1364
- });
1365
- }
1366
- }
1367
- const prev_skinning_pars_vertex = (
1368
- /* glsl */
1369
- `
1370
- #ifdef USE_SKINNING
1371
- #ifdef BONE_TEXTURE
1372
- uniform sampler2D prevBoneTexture;
1373
- mat4 getPrevBoneMatrix( const in float i ) {
1374
- float j = i * 4.0;
1375
- float x = mod( j, float( boneTextureSize ) );
1376
- float y = floor( j / float( boneTextureSize ) );
1377
- float dx = 1.0 / float( boneTextureSize );
1378
- float dy = 1.0 / float( boneTextureSize );
1379
- y = dy * ( y + 0.5 );
1380
- vec4 v1 = texture2D( prevBoneTexture, vec2( dx * ( x + 0.5 ), y ) );
1381
- vec4 v2 = texture2D( prevBoneTexture, vec2( dx * ( x + 1.5 ), y ) );
1382
- vec4 v3 = texture2D( prevBoneTexture, vec2( dx * ( x + 2.5 ), y ) );
1383
- vec4 v4 = texture2D( prevBoneTexture, vec2( dx * ( x + 3.5 ), y ) );
1384
- mat4 bone = mat4( v1, v2, v3, v4 );
1385
- return bone;
1386
- }
1387
- #else
1388
- uniform mat4 prevBoneMatrices[ MAX_BONES ];
1389
- mat4 getPrevBoneMatrix( const in float i ) {
1390
- mat4 bone = prevBoneMatrices[ int(i) ];
1391
- return bone;
1392
- }
1393
- #endif
1394
- #endif
1395
- `
1396
- );
1397
- const velocity_vertex = (
1398
- /* glsl */
1399
- `
1400
- vec3 transformed;
1401
-
1402
- // Get the normal
1403
- ${THREE.ShaderChunk.skinbase_vertex}
1404
- ${THREE.ShaderChunk.beginnormal_vertex}
1405
- ${THREE.ShaderChunk.skinnormal_vertex}
1406
- ${THREE.ShaderChunk.defaultnormal_vertex}
1407
-
1408
- // Get the current vertex position
1409
- transformed = vec3( position );
1410
- ${THREE.ShaderChunk.skinning_vertex}
1411
- newPosition = velocityMatrix * vec4( transformed, 1.0 );
1412
-
1413
- // Get the previous vertex position
1414
- transformed = vec3( position );
1415
- ${THREE.ShaderChunk.skinbase_vertex.replace(/mat4 /g, "").replace(/getBoneMatrix/g, "getPrevBoneMatrix")}
1416
- ${THREE.ShaderChunk.skinning_vertex.replace(/vec4 /g, "")}
1417
- prevPosition = prevVelocityMatrix * vec4( transformed, 1.0 );
1418
-
1419
- gl_Position = newPosition;
1420
- `
1421
- );
1422
- class VelocityMaterial extends THREE.ShaderMaterial {
1423
- constructor() {
1424
- super({
1425
- uniforms: {
1426
- prevVelocityMatrix: {
1427
- value: new THREE.Matrix4()
1428
- },
1429
- velocityMatrix: {
1430
- value: new THREE.Matrix4()
1431
- },
1432
- prevBoneTexture: {
1433
- value: null
1434
- },
1435
- interpolateGeometry: {
1436
- value: 0
1437
- },
1438
- intensity: {
1439
- value: 1
1440
- },
1441
- boneTexture: {
1442
- value: null
1443
- },
1444
- alphaTest: {
1445
- value: 0
1446
- },
1447
- map: {
1448
- value: null
1449
- },
1450
- alphaMap: {
1451
- value: null
1452
- },
1453
- opacity: {
1454
- value: 1
1455
- }
1456
- },
1457
- vertexShader: (
1458
- /* glsl */
1459
- `
1460
- #define MAX_BONES 1024
1461
-
1462
- ${THREE.ShaderChunk.skinning_pars_vertex}
1463
- ${prev_skinning_pars_vertex}
1464
-
1465
- uniform mat4 velocityMatrix;
1466
- uniform mat4 prevVelocityMatrix;
1467
- uniform float interpolateGeometry;
1468
- varying vec4 prevPosition;
1469
- varying vec4 newPosition;
1470
- varying vec2 vHighPrecisionZW;
1471
-
1472
- void main() {
1473
-
1474
- ${velocity_vertex}
1475
-
1476
- vHighPrecisionZW = gl_Position.zw;
1477
-
1478
- }`
1479
- ),
1480
- fragmentShader: (
1481
- /* glsl */
1482
- `
1483
- uniform float intensity;
1484
- varying vec4 prevPosition;
1485
- varying vec4 newPosition;
1486
- varying vec2 vHighPrecisionZW;
1487
-
1488
- void main() {
1489
- #ifdef FULL_MOVEMENT
1490
- gl_FragColor = vec4( 1., 1., 1. - gl_FragCoord.z, 0. );
1491
- return;
1492
- #endif
1493
-
1494
- vec2 pos0 = (prevPosition.xy / prevPosition.w) * 0.5 + 0.5;
1495
- vec2 pos1 = (newPosition.xy / newPosition.w) * 0.5 + 0.5;
1496
-
1497
- vec2 vel = pos1 - pos0;
1498
-
1499
- float fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;
1500
-
1501
- gl_FragColor = vec4( vel, 1. - fragCoordZ, 0. );
1502
-
1503
- }`
1504
- )
1505
- });
1506
- this.isVelocityMaterial = true;
1507
- }
1508
- }
1509
- const backgroundColor = new THREE.Color(0);
1510
- const updateProperties = ["visible", "wireframe", "side"];
1511
- class VelocityPass extends postprocessing.Pass {
1512
- constructor(scene, camera) {
1513
- var _window, _window2;
1514
- super("VelocityPass");
1515
- this.cachedMaterials = /* @__PURE__ */ new WeakMap();
1516
- this.lastCameraTransform = {
1517
- position: new THREE.Vector3(),
1518
- quaternion: new THREE.Quaternion()
1519
- };
1520
- this.visibleMeshes = [];
1521
- this.renderedMeshesThisFrame = 0;
1522
- this.renderedMeshesLastFrame = 0;
1523
- this._scene = scene;
1524
- this._camera = camera;
1525
- this.renderTarget = new THREE.WebGLRenderTarget(
1526
- ((_window = window) == null ? void 0 : _window.innerWidth) || 1e3,
1527
- ((_window2 = window) == null ? void 0 : _window2.innerHeight) || 1e3,
1528
- {
1529
- type: THREE.HalfFloatType
1530
- }
1531
- );
1532
- }
1533
- setVelocityMaterialInScene() {
1534
- this.renderedMeshesThisFrame = 0;
1535
- this.visibleMeshes = getVisibleChildren(this._scene);
1536
- for (const c of this.visibleMeshes) {
1537
- var _c$skeleton2;
1538
- const originalMaterial = c.material;
1539
- let [cachedOriginalMaterial, velocityMaterial] = this.cachedMaterials.get(c) || [];
1540
- if (originalMaterial !== cachedOriginalMaterial) {
1541
- var _c$skeleton;
1542
- velocityMaterial = new VelocityMaterial();
1543
- velocityMaterial.lastMatrixWorld = new THREE.Matrix4();
1544
- c.material = velocityMaterial;
1545
- if ((_c$skeleton = c.skeleton) != null && _c$skeleton.boneTexture)
1546
- this.saveBoneTexture(c);
1547
- this.cachedMaterials.set(c, [originalMaterial, velocityMaterial]);
1548
- }
1549
- velocityMaterial.uniforms.velocityMatrix.value.multiplyMatrices(this._camera.projectionMatrix, c.modelViewMatrix);
1550
- if (c.userData.needsUpdatedReflections || originalMaterial.map instanceof THREE.VideoTexture) {
1551
- if (!("FULL_MOVEMENT" in velocityMaterial.defines))
1552
- velocityMaterial.needsUpdate = true;
1553
- velocityMaterial.defines.FULL_MOVEMENT = "";
1554
- } else {
1555
- if ("FULL_MOVEMENT" in velocityMaterial.defines) {
1556
- delete velocityMaterial.defines.FULL_MOVEMENT;
1557
- velocityMaterial.needsUpdate = true;
1558
- }
1559
- }
1560
- c.visible = this.cameraMovedThisFrame || !c.matrixWorld.equals(velocityMaterial.lastMatrixWorld) || c.skeleton || "FULL_MOVEMENT" in velocityMaterial.defines;
1561
- c.material = velocityMaterial;
1562
- if (!c.visible)
1563
- continue;
1564
- this.renderedMeshesThisFrame++;
1565
- for (const prop of updateProperties)
1566
- velocityMaterial[prop] = originalMaterial[prop];
1567
- if ((_c$skeleton2 = c.skeleton) != null && _c$skeleton2.boneTexture) {
1568
- velocityMaterial.defines.USE_SKINNING = "";
1569
- velocityMaterial.defines.BONE_TEXTURE = "";
1570
- velocityMaterial.uniforms.boneTexture.value = c.skeleton.boneTexture;
1571
- }
1572
- }
1573
- }
1574
- saveBoneTexture(object) {
1575
- let boneTexture = object.material.uniforms.prevBoneTexture.value;
1576
- if (boneTexture && boneTexture.image.width === object.skeleton.boneTexture.width) {
1577
- boneTexture = object.material.uniforms.prevBoneTexture.value;
1578
- boneTexture.image.data.set(object.skeleton.boneTexture.image.data);
1579
- } else {
1580
- var _boneTexture;
1581
- (_boneTexture = boneTexture) == null ? void 0 : _boneTexture.dispose();
1582
- const boneMatrices = object.skeleton.boneTexture.image.data.slice();
1583
- const size = object.skeleton.boneTexture.image.width;
1584
- boneTexture = new THREE.DataTexture(boneMatrices, size, size, THREE.RGBAFormat, THREE.FloatType);
1585
- object.material.uniforms.prevBoneTexture.value = boneTexture;
1586
- boneTexture.needsUpdate = true;
1587
- }
1588
- }
1589
- unsetVelocityMaterialInScene() {
1590
- for (const c of this.visibleMeshes) {
1591
- if (c.material.isVelocityMaterial) {
1592
- var _c$skeleton3;
1593
- c.visible = true;
1594
- c.material.lastMatrixWorld.copy(c.matrixWorld);
1595
- c.material.uniforms.prevVelocityMatrix.value.multiplyMatrices(this._camera.projectionMatrix, c.modelViewMatrix);
1596
- if ((_c$skeleton3 = c.skeleton) != null && _c$skeleton3.boneTexture)
1597
- this.saveBoneTexture(c);
1598
- c.material = this.cachedMaterials.get(c)[0];
1599
- }
1600
- }
1601
- }
1602
- setSize(width, height) {
1603
- this.renderTarget.setSize(width, height);
1604
- }
1605
- renderVelocity(renderer) {
1606
- renderer.setRenderTarget(this.renderTarget);
1607
- if (this.renderedMeshesThisFrame > 0) {
1608
- const { background } = this._scene;
1609
- this._scene.background = backgroundColor;
1610
- renderer.render(this._scene, this._camera);
1611
- this._scene.background = background;
1612
- } else {
1613
- renderer.clearColor();
1614
- }
1615
- }
1616
- checkCameraMoved() {
1617
- const moveDist = this.lastCameraTransform.position.distanceToSquared(this._camera.position);
1618
- const rotateDist = 8 * (1 - this.lastCameraTransform.quaternion.dot(this._camera.quaternion));
1619
- if (moveDist > 1e-6 || rotateDist > 1e-6) {
1620
- this.lastCameraTransform.position.copy(this._camera.position);
1621
- this.lastCameraTransform.quaternion.copy(this._camera.quaternion);
1622
- return true;
1623
- }
1624
- return false;
1625
- }
1626
- render(renderer) {
1627
- this.cameraMovedThisFrame = this.checkCameraMoved();
1628
- this.setVelocityMaterialInScene();
1629
- if (this.renderedMeshesThisFrame > 0 || this.renderedMeshesLastFrame > 0)
1630
- this.renderVelocity(renderer);
1631
- this.unsetVelocityMaterialInScene();
1632
- this.renderedMeshesLastFrame = this.renderedMeshesThisFrame;
1633
- }
1634
- }
1635
- const zeroVec2 = new THREE.Vector2();
1636
- class TemporalResolvePass extends postprocessing.Pass {
1637
- constructor(scene, camera, customComposeShader, options = {}) {
1638
- super("TemporalResolvePass");
1639
- this.velocityPass = null;
1640
- this.velocityResolutionScale = 1;
1641
- this.samples = 1;
1642
- this.lastCameraTransform = {
1643
- position: new THREE.Vector3(),
1644
- quaternion: new THREE.Quaternion()
1645
- };
1646
- this._scene = scene;
1647
- this._camera = camera;
1648
- this.renderTarget = new THREE.WebGLRenderTarget(1, 1, {
1649
- minFilter: THREE.LinearFilter,
1650
- magFilter: THREE.LinearFilter,
1651
- type: THREE.HalfFloatType,
1652
- depthBuffer: false
1653
- });
1654
- this.velocityPass = new VelocityPass(scene, camera);
1655
- this.fullscreenMaterial = new TemporalResolveMaterial(customComposeShader);
1656
- this.fullscreenMaterial.defines.correctionRadius = options.correctionRadius || 1;
1657
- if (options.dilation)
1658
- this.fullscreenMaterial.defines.dilation = "";
1659
- if (options.boxBlur)
1660
- this.fullscreenMaterial.defines.boxBlur = "";
1661
- this.setupFramebuffers(1, 1);
1662
- this.checkCanUseSharedVelocityTexture();
1663
- }
1664
- dispose() {
1665
- if (this._scene.userData.velocityTexture === this.velocityPass.renderTarget.texture) {
1666
- delete this._scene.userData.velocityTexture;
1667
- delete this._scene.userData.lastVelocityTexture;
1668
- }
1669
- this.renderTarget.dispose();
1670
- this.accumulatedTexture.dispose();
1671
- this.fullscreenMaterial.dispose();
1672
- this.velocityPass.dispose();
1673
- }
1674
- setSize(width, height) {
1675
- this.renderTarget.setSize(width, height);
1676
- this.velocityPass.setSize(width * this.velocityResolutionScale, height * this.velocityResolutionScale);
1677
- this.velocityPass.renderTarget.texture.minFilter = this.velocityResolutionScale === 1 ? THREE.NearestFilter : THREE.LinearFilter;
1678
- this.velocityPass.renderTarget.texture.magFilter = this.velocityResolutionScale === 1 ? THREE.NearestFilter : THREE.LinearFilter;
1679
- this.velocityPass.renderTarget.texture.needsUpdate = true;
1680
- this.fullscreenMaterial.uniforms.invTexSize.value.set(1 / width, 1 / height);
1681
- this.setupFramebuffers(width, height);
1682
- }
1683
- setupFramebuffers(width, height) {
1684
- if (this.accumulatedTexture)
1685
- this.accumulatedTexture.dispose();
1686
- if (this.lastVelocityTexture)
1687
- this.lastVelocityTexture.dispose();
1688
- this.accumulatedTexture = new THREE.FramebufferTexture(width, height, THREE.RGBAFormat);
1689
- this.accumulatedTexture.minFilter = THREE.LinearFilter;
1690
- this.accumulatedTexture.magFilter = THREE.LinearFilter;
1691
- this.accumulatedTexture.type = THREE.HalfFloatType;
1692
- this.lastVelocityTexture = new THREE.FramebufferTexture(
1693
- width * this.velocityResolutionScale,
1694
- height * this.velocityResolutionScale,
1695
- THREE.RGBAFormat
1696
- );
1697
- this.lastVelocityTexture.minFilter = this.velocityResolutionScale === 1 ? THREE.NearestFilter : THREE.LinearFilter;
1698
- this.lastVelocityTexture.magFilter = this.velocityResolutionScale === 1 ? THREE.NearestFilter : THREE.LinearFilter;
1699
- this.lastVelocityTexture.type = THREE.HalfFloatType;
1700
- this.fullscreenMaterial.uniforms.accumulatedTexture.value = this.accumulatedTexture;
1701
- this.fullscreenMaterial.uniforms.lastVelocityTexture.value = this.lastVelocityTexture;
1702
- this.fullscreenMaterial.needsUpdate = true;
1703
- }
1704
- checkCanUseSharedVelocityTexture() {
1705
- const canUseSharedVelocityTexture = this._scene.userData.velocityTexture && this.velocityPass.renderTarget.texture !== this._scene.userData.velocityTexture;
1706
- if (canUseSharedVelocityTexture) {
1707
- if (this.velocityPass.renderTarget.texture === this.fullscreenMaterial.uniforms.velocityTexture.value) {
1708
- this.fullscreenMaterial.uniforms.lastVelocityTexture.value = this._scene.userData.lastVelocityTexture;
1709
- this.fullscreenMaterial.uniforms.velocityTexture.value = this._scene.userData.velocityTexture;
1710
- this.fullscreenMaterial.needsUpdate = true;
1711
- }
1712
- } else {
1713
- if (this.velocityPass.renderTarget.texture !== this.fullscreenMaterial.uniforms.velocityTexture.value) {
1714
- this.fullscreenMaterial.uniforms.velocityTexture.value = this.velocityPass.renderTarget.texture;
1715
- this.fullscreenMaterial.uniforms.lastVelocityTexture.value = this.lastVelocityTexture;
1716
- this.fullscreenMaterial.needsUpdate = true;
1717
- if (!this._scene.userData.velocityTexture) {
1718
- this._scene.userData.velocityTexture = this.velocityPass.renderTarget.texture;
1719
- this._scene.userData.lastVelocityTexture = this.lastVelocityTexture;
1720
- }
1721
- }
1722
- }
1723
- return this.velocityPass.renderTarget.texture !== this.fullscreenMaterial.uniforms.velocityTexture.value;
1724
- }
1725
- checkNeedsResample() {
1726
- const moveDist = this.lastCameraTransform.position.distanceToSquared(this._camera.position);
1727
- const rotateDist = 8 * (1 - this.lastCameraTransform.quaternion.dot(this._camera.quaternion));
1728
- if (moveDist > 1e-6 || rotateDist > 1e-6) {
1729
- this.samples = 1;
1730
- this.lastCameraTransform.position.copy(this._camera.position);
1731
- this.lastCameraTransform.quaternion.copy(this._camera.quaternion);
1732
- }
1733
- }
1734
- render(renderer) {
1735
- this.samples++;
1736
- this.checkNeedsResample();
1737
- this.fullscreenMaterial.uniforms.samples.value = this.samples;
1738
- renderer.setRenderTarget(this.renderTarget);
1739
- renderer.render(this.scene, this.camera);
1740
- renderer.copyFramebufferToTexture(zeroVec2, this.accumulatedTexture);
1741
- renderer.setRenderTarget(this.velocityPass.renderTarget);
1742
- renderer.copyFramebufferToTexture(zeroVec2, this.lastVelocityTexture);
1743
- }
1744
- }
1745
- const halton = function halton2(index, base) {
1746
- let fraction = 1;
1747
- let result = 0;
1748
- while (index > 0) {
1749
- fraction /= base;
1750
- result += fraction * (index % base);
1751
- index = ~~(index / base);
1752
- }
1753
- return result;
1754
- };
1755
- const generateHalton23Points = (count) => {
1756
- const data = [];
1757
- let i2 = 1;
1758
- const end = i2 + count;
1759
- for (; i2 < end; i2++) {
1760
- data.push([halton(i2, 2) - 0.5, halton(i2, 3) - 0.5]);
1761
- }
1762
- return data;
1763
- };
1764
- function escapeRegExp(string) {
1765
- return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1766
- }
1767
- const worldposReplace = (
1768
- /* glsl */
1769
- `
1770
- #if defined( USE_ENVMAP ) || defined( ) || defined ( USE_SHADOWMAP )
1771
- vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );
1772
-
1773
- #ifdef BOX_PROJECTED_ENV_MAP
1774
- vWorldPosition = worldPosition.xyz;
1775
- #endif
1776
- #endif
1777
- `
1778
- );
1779
- const boxProjectDefinitions = (
1780
- /* glsl */
1781
- `
1782
- #ifdef BOX_PROJECTED_ENV_MAP
1783
- uniform vec3 envMapSize;
1784
- uniform vec3 envMapPosition;
1785
- varying vec3 vWorldPosition;
1786
-
1787
- vec3 parallaxCorrectNormal( vec3 v, vec3 cubeSize, vec3 cubePos ) {
1788
- vec3 nDir = normalize( v );
1789
-
1790
- vec3 rbmax = ( .5 * cubeSize + cubePos - vWorldPosition ) / nDir;
1791
- vec3 rbmin = ( -.5 * cubeSize + cubePos - vWorldPosition ) / nDir;
1792
-
1793
- vec3 rbminmax;
1794
-
1795
- rbminmax.x = ( nDir.x > 0. ) ? rbmax.x : rbmin.x;
1796
- rbminmax.y = ( nDir.y > 0. ) ? rbmax.y : rbmin.y;
1797
- rbminmax.z = ( nDir.z > 0. ) ? rbmax.z : rbmin.z;
1798
-
1799
- float correction = min( min( rbminmax.x, rbminmax.y ), rbminmax.z );
1800
- vec3 boxIntersection = vWorldPosition + nDir * correction;
1801
-
1802
- return boxIntersection - cubePos;
1803
- }
1804
- #endif
1805
- `
1806
- );
1807
- const getIBLIrradiance_patch = (
1808
- /* glsl */
1809
- `
1810
- #ifdef BOX_PROJECTED_ENV_MAP
1811
- worldNormal = parallaxCorrectNormal( worldNormal, envMapSize, envMapPosition );
1812
- #endif
1813
- `
1814
- );
1815
- const getIBLRadiance_patch = (
1816
- /* glsl */
1817
- `
1818
- #ifdef BOX_PROJECTED_ENV_MAP
1819
- reflectVec = parallaxCorrectNormal( reflectVec, envMapSize, envMapPosition );
1820
- #endif
1821
- `
1822
- );
1823
- function useBoxProjectedEnvMap(shader, envMapPosition, envMapSize) {
1824
- shader.defines.BOX_PROJECTED_ENV_MAP = "";
1825
- shader.uniforms.envMapPosition = {
1826
- value: envMapPosition
1827
- };
1828
- shader.uniforms.envMapSize = {
1829
- value: envMapSize
1830
- };
1831
- const line1 = new RegExp(
1832
- escapeRegExp("vec3 worldNormal = inverseTransformDirection ( normal , viewMatrix ) ;").replaceAll(" ", "\\s*"),
1833
- "g"
1834
- );
1835
- const line2 = new RegExp(
1836
- escapeRegExp("reflectVec = inverseTransformDirection ( reflectVec , viewMatrix ) ;").replaceAll(" ", "\\s*"),
1837
- "g"
1838
- );
1839
- shader.vertexShader = "varying vec3 vWorldPosition;\n" + shader.vertexShader.replace("#include <worldpos_vertex>", worldposReplace);
1840
- shader.fragmentShader = boxProjectDefinitions + "\n" + shader.fragmentShader.replace("#include <envmap_physical_pars_fragment>", THREE.ShaderChunk.envmap_physical_pars_fragment).replace(
1841
- line1,
1842
- `vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );
1843
- ${getIBLIrradiance_patch}`
1844
- ).replace(
1845
- line2,
1846
- `reflectVec = inverseTransformDirection( reflectVec, viewMatrix );
1847
- ${getIBLRadiance_patch}`
1848
- );
1849
- }
1850
- const finalFragmentShader = finalSSRShader.replace("#include <helperFunctions>", helperFunctions).replace("#include <boxBlur>", boxBlur);
1851
- const noResetSamplesProperties = ["blur", "blurSharpness", "blurKernel"];
1852
- const defaultCubeRenderTarget = new THREE.WebGLCubeRenderTarget(1);
1853
- let pmremGenerator;
1854
- class SSREffect extends postprocessing.Effect {
1855
- /**
1856
- * @param {THREE.Scene} scene The scene of the SSR effect
1857
- * @param {THREE.Camera} camera The camera with which SSR is being rendered
1858
- * @param {SSROptions} [options] The optional options for the SSR effect
1859
- */
1860
- constructor(scene, camera, options = defaultSSROptions) {
1861
- super("SSREffect", finalFragmentShader, {
1862
- type: "FinalSSRMaterial",
1863
- uniforms: /* @__PURE__ */ new Map([
1864
- ["reflectionsTexture", new THREE.Uniform(null)],
1865
- ["blur", new THREE.Uniform(0)],
1866
- ["blurSharpness", new THREE.Uniform(0)],
1867
- ["blurKernel", new THREE.Uniform(0)]
1868
- ]),
1869
- defines: /* @__PURE__ */ new Map([["RENDER_MODE", "0"]])
1870
- });
1871
- this.haltonSequence = generateHalton23Points(1024);
1872
- this.haltonIndex = 0;
1873
- this.selection = new postprocessing.Selection();
1874
- this.lastSize = void 0;
1875
- this.cubeCamera = new THREE.CubeCamera(1e-3, 1e3, defaultCubeRenderTarget);
1876
- this.usingBoxProjectedEnvMap = false;
1877
- this._scene = scene;
1878
- this._camera = camera;
1879
- const trOptions = {
1880
- boxBlur: true,
1881
- dilation: true
1882
- };
1883
- options = { ...defaultSSROptions, ...options, ...trOptions };
1884
- this.temporalResolvePass = new TemporalResolvePass(scene, camera, trCompose, options);
1885
- this.uniforms.get("reflectionsTexture").value = this.temporalResolvePass.renderTarget.texture;
1886
- this.reflectionsPass = new ReflectionsPass(this, options);
1887
- this.temporalResolvePass.fullscreenMaterial.uniforms.inputTexture.value = this.reflectionsPass.renderTarget.texture;
1888
- this.lastSize = {
1889
- width: options.width,
1890
- height: options.height,
1891
- resolutionScale: options.resolutionScale,
1892
- velocityResolutionScale: options.velocityResolutionScale
1893
- };
1894
- this.setSize(options.width, options.height);
1895
- this.makeOptionsReactive(options);
1896
- }
1897
- makeOptionsReactive(options) {
1898
- let needsUpdate = false;
1899
- const reflectionPassFullscreenMaterialUniforms = this.reflectionsPass.fullscreenMaterial.uniforms;
1900
- const reflectionPassFullscreenMaterialUniformsKeys = Object.keys(reflectionPassFullscreenMaterialUniforms);
1901
- for (const key of Object.keys(options)) {
1902
- Object.defineProperty(this, key, {
1903
- get() {
1904
- return options[key];
1905
- },
1906
- set(value) {
1907
- if (options[key] === value && needsUpdate)
1908
- return;
1909
- options[key] = value;
1910
- if (!noResetSamplesProperties.includes(key)) {
1911
- this.setSize(this.lastSize.width, this.lastSize.height, true);
1912
- }
1913
- switch (key) {
1914
- case "resolutionScale":
1915
- this.setSize(this.lastSize.width, this.lastSize.height);
1916
- break;
1917
- case "velocityResolutionScale":
1918
- this.temporalResolvePass.velocityResolutionScale = value;
1919
- this.setSize(this.lastSize.width, this.lastSize.height, true);
1920
- break;
1921
- case "blur":
1922
- this.uniforms.get("blur").value = value;
1923
- break;
1924
- case "blurSharpness":
1925
- this.uniforms.get("blurSharpness").value = value;
1926
- break;
1927
- case "blurKernel":
1928
- this.uniforms.get("blurKernel").value = value;
1929
- break;
1930
- case "steps":
1931
- this.reflectionsPass.fullscreenMaterial.defines.steps = parseInt(value);
1932
- this.reflectionsPass.fullscreenMaterial.needsUpdate = needsUpdate;
1933
- break;
1934
- case "refineSteps":
1935
- this.reflectionsPass.fullscreenMaterial.defines.refineSteps = parseInt(value);
1936
- this.reflectionsPass.fullscreenMaterial.needsUpdate = needsUpdate;
1937
- break;
1938
- case "missedRays":
1939
- if (value) {
1940
- this.reflectionsPass.fullscreenMaterial.defines.missedRays = "";
1941
- } else {
1942
- delete this.reflectionsPass.fullscreenMaterial.defines.missedRays;
1943
- }
1944
- this.reflectionsPass.fullscreenMaterial.needsUpdate = needsUpdate;
1945
- break;
1946
- case "correctionRadius":
1947
- this.temporalResolvePass.fullscreenMaterial.defines.correctionRadius = Math.round(value);
1948
- this.temporalResolvePass.fullscreenMaterial.needsUpdate = needsUpdate;
1949
- break;
1950
- case "blend":
1951
- this.temporalResolvePass.fullscreenMaterial.uniforms.blend.value = value;
1952
- break;
1953
- case "correction":
1954
- this.temporalResolvePass.fullscreenMaterial.uniforms.correction.value = value;
1955
- break;
1956
- case "exponent":
1957
- this.temporalResolvePass.fullscreenMaterial.uniforms.exponent.value = value;
1958
- break;
1959
- case "distance":
1960
- reflectionPassFullscreenMaterialUniforms.rayDistance.value = value;
1961
- default:
1962
- if (reflectionPassFullscreenMaterialUniformsKeys.includes(key)) {
1963
- reflectionPassFullscreenMaterialUniforms[key].value = value;
1964
- }
1965
- }
1966
- }
1967
- });
1968
- this[key] = options[key];
1969
- }
1970
- needsUpdate = true;
1971
- }
1972
- setSize(width, height, force = false) {
1973
- if (!force && width === this.lastSize.width && height === this.lastSize.height && this.resolutionScale === this.lastSize.resolutionScale && this.velocityResolutionScale === this.lastSize.velocityResolutionScale)
1974
- return;
1975
- this.temporalResolvePass.setSize(width, height);
1976
- this.reflectionsPass.setSize(width, height);
1977
- this.lastSize = {
1978
- width,
1979
- height,
1980
- resolutionScale: this.resolutionScale,
1981
- velocityResolutionScale: this.velocityResolutionScale
1982
- };
1983
- }
1984
- generateBoxProjectedEnvMapFallback(renderer, position = new THREE.Vector3(), size = new THREE.Vector3(), envMapSize = 512) {
1985
- this.cubeCamera.renderTarget.dispose();
1986
- this.cubeCamera.renderTarget = new THREE.WebGLCubeRenderTarget(envMapSize);
1987
- this.cubeCamera.position.copy(position);
1988
- this.cubeCamera.updateMatrixWorld();
1989
- this.cubeCamera.update(renderer, this._scene);
1990
- if (!pmremGenerator) {
1991
- pmremGenerator = new THREE.PMREMGenerator(renderer);
1992
- pmremGenerator.compileCubemapShader();
1993
- }
1994
- const envMap = pmremGenerator.fromCubemap(this.cubeCamera.renderTarget.texture).texture;
1995
- envMap.minFilter = THREE.LinearFilter;
1996
- envMap.magFilter = THREE.LinearFilter;
1997
- const reflectionsMaterial = this.reflectionsPass.fullscreenMaterial;
1998
- useBoxProjectedEnvMap(reflectionsMaterial, position, size);
1999
- reflectionsMaterial.fragmentShader = reflectionsMaterial.fragmentShader.replace("vec3 worldPos", "worldPos").replace("varying vec3 vWorldPosition;", "vec3 worldPos;");
2000
- reflectionsMaterial.uniforms.envMapPosition.value.copy(position);
2001
- reflectionsMaterial.uniforms.envMapSize.value.copy(size);
2002
- setupEnvMap(reflectionsMaterial, envMap, envMapSize);
2003
- this.usingBoxProjectedEnvMap = true;
2004
- return envMap;
2005
- }
2006
- setIBLRadiance(iblRadiance, renderer) {
2007
- this._scene.traverse((c) => {
2008
- if (c.material) {
2009
- var _renderer$properties$;
2010
- const uniforms = (_renderer$properties$ = renderer.properties.get(c.material)) == null ? void 0 : _renderer$properties$.uniforms;
2011
- if (uniforms && "disableIBLRadiance" in uniforms) {
2012
- uniforms.disableIBLRadiance.value = iblRadiance;
2013
- }
2014
- }
2015
- });
2016
- }
2017
- deleteBoxProjectedEnvMapFallback() {
2018
- const reflectionsMaterial = this.reflectionsPass.fullscreenMaterial;
2019
- reflectionsMaterial.uniforms.envMap.value = null;
2020
- reflectionsMaterial.fragmentShader = reflectionsMaterial.fragmentShader.replace("worldPos = ", "vec3 worldPos = ");
2021
- delete reflectionsMaterial.defines.BOX_PROJECTED_ENV_MAP;
2022
- reflectionsMaterial.needsUpdate = true;
2023
- this.usingBoxProjectedEnvMap = false;
2024
- }
2025
- dispose() {
2026
- super.dispose();
2027
- this.reflectionsPass.dispose();
2028
- this.temporalResolvePass.dispose();
2029
- }
2030
- update(renderer, inputBuffer) {
2031
- if (!this.usingBoxProjectedEnvMap && this._scene.environment) {
2032
- const reflectionsMaterial = this.reflectionsPass.fullscreenMaterial;
2033
- let envMap = null;
2034
- this._scene.traverse((c) => {
2035
- if (!envMap && c.material && !c.material.envMap) {
2036
- const properties = renderer.properties.get(c.material);
2037
- if ("envMap" in properties && properties.envMap instanceof THREE.Texture)
2038
- envMap = properties.envMap;
2039
- }
2040
- });
2041
- if (envMap) {
2042
- const envMapCubeUVHeight = this._scene.environment.image.height;
2043
- setupEnvMap(reflectionsMaterial, envMap, envMapCubeUVHeight);
2044
- }
2045
- }
2046
- this.haltonIndex = (this.haltonIndex + 1) % this.haltonSequence.length;
2047
- const [x, y] = this.haltonSequence[this.haltonIndex];
2048
- const { width, height } = this.lastSize;
2049
- this.temporalResolvePass.velocityPass.render(renderer);
2050
- if (this._camera.setViewOffset)
2051
- this._camera.setViewOffset(width, height, x, y, width, height);
2052
- this.reflectionsPass.render(renderer, inputBuffer);
2053
- this.temporalResolvePass.render(renderer);
2054
- this._camera.clearViewOffset();
2055
- }
2056
- static patchDirectEnvIntensity(envMapIntensity = 0) {
2057
- if (envMapIntensity === 0) {
2058
- THREE.ShaderChunk.envmap_physical_pars_fragment = THREE.ShaderChunk.envmap_physical_pars_fragment.replace(
2059
- "vec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {",
2060
- "vec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) { return vec3(0.0);"
2061
- );
2062
- } else {
2063
- THREE.ShaderChunk.envmap_physical_pars_fragment = THREE.ShaderChunk.envmap_physical_pars_fragment.replace(
2064
- "vec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );",
2065
- "vec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness ) * " + envMapIntensity.toFixed(5) + ";"
2066
- );
2067
- }
2068
- }
2069
- }
2070
- const SSR = React.forwardRef(function SSR2({ ENABLE_BLUR = true, USE_MRT = true, ...props }, ref) {
2071
- const { invalidate } = fiber.useThree();
2072
- const { scene, camera } = React.useContext(EffectComposerContext);
2073
- const effect = React.useMemo(
2074
- () => new SSREffect(scene, camera, { ENABLE_BLUR, USE_MRT, ...props }),
2075
- [scene, camera, ENABLE_BLUR, USE_MRT, props]
2076
- );
2077
- const api = React.useContext(selectionContext);
2078
- React.useEffect(() => {
2079
- var _a;
2080
- if (api && api.enabled) {
2081
- if ((_a = api.selected) == null ? void 0 : _a.length) {
2082
- effect.selection.set(api.selected);
2083
- invalidate();
2084
- return () => {
2085
- effect.selection.clear();
2086
- invalidate();
2087
- };
2088
- }
2089
- }
2090
- }, [api]);
2091
- return /* @__PURE__ */ jsxRuntime.jsx("primitive", { ref, object: effect, ...props });
2092
- });
2093
- const $e4ca8dcb0218f846$var$_geometry = new THREE.BufferGeometry();
2094
- $e4ca8dcb0218f846$var$_geometry.setAttribute("position", new THREE.BufferAttribute(new Float32Array([
2095
- -1,
2096
- -1,
2097
- 3,
2098
- -1,
2099
- -1,
2100
- 3
2101
- ]), 2));
2102
- $e4ca8dcb0218f846$var$_geometry.setAttribute("uv", new THREE.BufferAttribute(new Float32Array([
2103
- 0,
2104
- 0,
2105
- 2,
2106
- 0,
2107
- 0,
2108
- 2
2109
- ]), 2));
2110
- $e4ca8dcb0218f846$var$_geometry.boundingSphere = new THREE.Sphere();
2111
- $e4ca8dcb0218f846$var$_geometry.computeBoundingSphere = function() {
2112
- };
2113
- const $e4ca8dcb0218f846$var$_camera = new THREE.OrthographicCamera();
2114
- class $e4ca8dcb0218f846$export$dcd670d73db751f5 {
2115
- constructor(material) {
2116
- this._mesh = new THREE.Mesh($e4ca8dcb0218f846$var$_geometry, material);
2117
- this._mesh.frustumCulled = false;
2118
- }
2119
- render(renderer) {
2120
- renderer.render(this._mesh, $e4ca8dcb0218f846$var$_camera);
2121
- }
2122
- get material() {
2123
- return this._mesh.material;
2124
- }
2125
- set material(value) {
2126
- this._mesh.material = value;
2127
- }
2128
- dispose() {
2129
- this._mesh.material.dispose();
2130
- this._mesh.geometry.dispose();
2131
- }
2132
- }
2133
- const $1ed45968c1160c3c$export$c9b263b9a17dffd7 = {
2134
- uniforms: {
2135
- "sceneDiffuse": {
2136
- value: null
2137
- },
2138
- "sceneDepth": {
2139
- value: null
2140
- },
2141
- "sceneNormal": {
2142
- value: null
2143
- },
2144
- "projMat": {
2145
- value: new THREE.Matrix4()
2146
- },
2147
- "viewMat": {
2148
- value: new THREE.Matrix4()
2149
- },
2150
- "projViewMat": {
2151
- value: new THREE.Matrix4()
2152
- },
2153
- "projectionMatrixInv": {
2154
- value: new THREE.Matrix4()
2155
- },
2156
- "viewMatrixInv": {
2157
- value: new THREE.Matrix4()
2158
- },
2159
- "cameraPos": {
2160
- value: new THREE.Vector3()
2161
- },
2162
- "resolution": {
2163
- value: new THREE.Vector2()
2164
- },
2165
- "time": {
2166
- value: 0
2167
- },
2168
- "samples": {
2169
- value: []
2170
- },
2171
- "samplesR": {
2172
- value: []
2173
- },
2174
- "bluenoise": {
2175
- value: null
2176
- },
2177
- "distanceFalloff": {
2178
- value: 1
2179
- },
2180
- "radius": {
2181
- value: 5
2182
- },
2183
- "near": {
2184
- value: 0.1
2185
- },
2186
- "far": {
2187
- value: 1e3
2188
- },
2189
- "logDepth": {
2190
- value: false
2191
- },
2192
- "ortho": {
2193
- value: false
2194
- },
2195
- "screenSpaceRadius": {
2196
- value: false
2197
- }
2198
- },
2199
- vertexShader: (
2200
- /* glsl */
2201
- `
2202
- varying vec2 vUv;
2203
- void main() {
2204
- vUv = uv;
2205
- gl_Position = vec4(position, 1);
2206
- }`
2207
- ),
2208
- fragmentShader: (
2209
- /* glsl */
2210
- `
2211
- #define SAMPLES 16
2212
- #define FSAMPLES 16.0
2213
- uniform sampler2D sceneDiffuse;
2214
- uniform highp sampler2D sceneNormal;
2215
- uniform highp sampler2D sceneDepth;
2216
- uniform mat4 projectionMatrixInv;
2217
- uniform mat4 viewMatrixInv;
2218
- uniform mat4 projMat;
2219
- uniform mat4 viewMat;
2220
- uniform mat4 projViewMat;
2221
- uniform vec3 cameraPos;
2222
- uniform vec2 resolution;
2223
- uniform float time;
2224
- uniform vec3[SAMPLES] samples;
2225
- uniform float[SAMPLES] samplesR;
2226
- uniform float radius;
2227
- uniform float distanceFalloff;
2228
- uniform float near;
2229
- uniform float far;
2230
- uniform bool logDepth;
2231
- uniform bool ortho;
2232
- uniform bool screenSpaceRadius;
2233
- uniform sampler2D bluenoise;
2234
- varying vec2 vUv;
2235
- highp float linearize_depth(highp float d, highp float zNear,highp float zFar)
2236
- {
2237
- return (zFar * zNear) / (zFar - d * (zFar - zNear));
2238
- }
2239
- highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {
2240
- return nearZ + (farZ - nearZ) * d;
2241
- }
2242
- highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {
2243
- float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;
2244
- float a = farZ / (farZ - nearZ);
2245
- float b = farZ * nearZ / (nearZ - farZ);
2246
- float linDepth = a + b / depth;
2247
- return ortho ? linearize_depth_ortho(
2248
- linDepth,
2249
- nearZ,
2250
- farZ
2251
- ) :linearize_depth(linDepth, nearZ, farZ);
2252
- }
2253
-
2254
- vec3 getWorldPosLog(vec3 posS) {
2255
- vec2 uv = posS.xy;
2256
- float z = posS.z;
2257
- float nearZ =near;
2258
- float farZ = far;
2259
- float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;
2260
- float a = farZ / (farZ - nearZ);
2261
- float b = farZ * nearZ / (nearZ - farZ);
2262
- float linDepth = a + b / depth;
2263
- vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;
2264
- vec4 wpos = projectionMatrixInv * clipVec;
2265
- return wpos.xyz / wpos.w;
2266
- }
2267
- vec3 getWorldPos(float depth, vec2 coord) {
2268
- #ifdef LOGDEPTH
2269
- return getWorldPosLog(vec3(coord, depth));
2270
- #endif
2271
- float z = depth * 2.0 - 1.0;
2272
- vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);
2273
- vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;
2274
- // Perspective division
2275
- vec4 worldSpacePosition = viewSpacePosition;
2276
- worldSpacePosition.xyz /= worldSpacePosition.w;
2277
- return worldSpacePosition.xyz;
2278
- }
2279
-
2280
- vec3 computeNormal(vec3 worldPos, vec2 vUv) {
2281
- ivec2 p = ivec2(vUv * resolution);
2282
- float c0 = texelFetch(sceneDepth, p, 0).x;
2283
- float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;
2284
- float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;
2285
- float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;
2286
- float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;
2287
- float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;
2288
- float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;
2289
- float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;
2290
- float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;
2291
-
2292
- float dl = abs((2.0 * l1 - l2) - c0);
2293
- float dr = abs((2.0 * r1 - r2) - c0);
2294
- float db = abs((2.0 * b1 - b2) - c0);
2295
- float dt = abs((2.0 * t1 - t2) - c0);
2296
-
2297
- vec3 ce = getWorldPos(c0, vUv).xyz;
2298
-
2299
- vec3 dpdx = (dl < dr) ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz
2300
- : -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz;
2301
- vec3 dpdy = (db < dt) ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz
2302
- : -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz;
2303
-
2304
- return normalize(cross(dpdx, dpdy));
2305
- }
2306
-
2307
- void main() {
2308
- vec4 diffuse = texture2D(sceneDiffuse, vUv);
2309
- float depth = texture2D(sceneDepth, vUv).x;
2310
- if (depth == 1.0) {
2311
- gl_FragColor = vec4(vec3(1.0), 1.0);
2312
- return;
2313
- }
2314
- vec3 worldPos = getWorldPos(depth, vUv);
2315
- // vec3 normal = texture2D(sceneNormal, vUv).rgb;//computeNormal(worldPos, vUv);
2316
- #ifdef HALFRES
2317
- vec3 normal = texture2D(sceneNormal, vUv).rgb;
2318
- #else
2319
- vec3 normal = computeNormal(worldPos, vUv);
2320
- #endif
2321
- vec4 noise = texture2D(bluenoise, gl_FragCoord.xy / 128.0);
2322
- vec3 randomVec = normalize(noise.rgb * 2.0 - 1.0);
2323
- vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
2324
- vec3 bitangent = cross(normal, tangent);
2325
- mat3 tbn = mat3(tangent, bitangent, normal);
2326
- float occluded = 0.0;
2327
- float totalWeight = 0.0;
2328
- /* float radiusScreen = distance(
2329
- worldPos,
2330
- getWorldPos(depth, vUv +
2331
- vec2(48.0, 0.0) / resolution)
2332
- );/*vUv.x < 0.5 ? radius : min(distance(
2333
- worldPos,
2334
- getWorldPos(depth, vUv +
2335
- vec2(100.0, 0.0) / resolution)
2336
- ), radius);
2337
- float distanceFalloffScreen = radiusScreen * 0.2;*/
2338
- float radiusToUse = screenSpaceRadius ? distance(
2339
- worldPos,
2340
- getWorldPos(depth, vUv +
2341
- vec2(radius, 0.0) / resolution)
2342
- ) : radius;
2343
- float distanceFalloffToUse =screenSpaceRadius ?
2344
- radiusToUse * distanceFalloff
2345
- : distanceFalloff;
2346
- float bias = (0.1 / near) * fwidth(distance(worldPos, cameraPos)) / radiusToUse;
2347
- for(float i = 0.0; i < FSAMPLES; i++) {
2348
- vec3 sampleDirection =
2349
- tbn *
2350
- samples[int(i)];
2351
- ;
2352
- float moveAmt = samplesR[int(mod(i + noise.a * FSAMPLES, FSAMPLES))];
2353
- vec3 samplePos = worldPos + radiusToUse * moveAmt * sampleDirection;
2354
- vec4 offset = projMat * vec4(samplePos, 1.0);
2355
- offset.xyz /= offset.w;
2356
- offset.xyz = offset.xyz * 0.5 + 0.5;
2357
- float sampleDepth = textureLod(sceneDepth, offset.xy, 0.0).x;
2358
- /*float distSample = logDepth ? linearize_depth_log(sampleDepth, near, far)
2359
- (ortho ? linearize_depth_ortho(sampleDepth, near, far) : linearize_depth(sampleDepth, near, far));*/
2360
- #ifdef LOGDEPTH
2361
- float distSample = linearize_depth_log(sampleDepth, near, far);
2362
- #else
2363
- float distSample = ortho ? linearize_depth_ortho(sampleDepth, near, far) : linearize_depth(sampleDepth, near, far);
2364
- #endif
2365
- float distWorld = ortho ? linearize_depth_ortho(offset.z, near, far) : linearize_depth(offset.z, near, far);
2366
- float rangeCheck = smoothstep(0.0, 1.0, distanceFalloffToUse / (abs(distSample - distWorld)));
2367
- vec2 diff = gl_FragCoord.xy - ( offset.xy * resolution);
2368
- float weight = dot(sampleDirection, normal);
2369
- occluded += rangeCheck * weight *
2370
- (distSample + bias
2371
- < distWorld ? 1.0 : 0.0) * (
2372
- (dot(
2373
- diff,
2374
- diff
2375
-
2376
- ) < 1.0 || (sampleDepth == depth) || (
2377
- offset.x < 0.0 || offset.x > 1.0 || offset.y < 0.0 || offset.y > 1.0
2378
- ) ? 0.0 : 1.0)
2379
- );
2380
- totalWeight += weight;
2381
- }
2382
- float occ = clamp(1.0 - occluded / totalWeight, 0.0, 1.0);
2383
- gl_FragColor = vec4(0.5 + 0.5 * normal, occ);
2384
- }`
2385
- )
2386
- };
2387
- const $12b21d24d1192a04$export$a815acccbd2c9a49 = {
2388
- uniforms: {
2389
- "sceneDiffuse": {
2390
- value: null
2391
- },
2392
- "sceneDepth": {
2393
- value: null
2394
- },
2395
- "tDiffuse": {
2396
- value: null
2397
- },
2398
- "projMat": {
2399
- value: new THREE.Matrix4()
2400
- },
2401
- "viewMat": {
2402
- value: new THREE.Matrix4()
2403
- },
2404
- "projectionMatrixInv": {
2405
- value: new THREE.Matrix4()
2406
- },
2407
- "viewMatrixInv": {
2408
- value: new THREE.Matrix4()
2409
- },
2410
- "cameraPos": {
2411
- value: new THREE.Vector3()
2412
- },
2413
- "resolution": {
2414
- value: new THREE.Vector2()
2415
- },
2416
- "color": {
2417
- value: new THREE.Vector3(0, 0, 0)
2418
- },
2419
- "blueNoise": {
2420
- value: null
2421
- },
2422
- "downsampledDepth": {
2423
- value: null
2424
- },
2425
- "time": {
2426
- value: 0
2427
- },
2428
- "intensity": {
2429
- value: 10
2430
- },
2431
- "renderMode": {
2432
- value: 0
2433
- },
2434
- "gammaCorrection": {
2435
- value: false
2436
- },
2437
- "logDepth": {
2438
- value: false
2439
- },
2440
- "ortho": {
2441
- value: false
2442
- },
2443
- "near": {
2444
- value: 0.1
2445
- },
2446
- "far": {
2447
- value: 1e3
2448
- },
2449
- "screenSpaceRadius": {
2450
- value: false
2451
- },
2452
- "radius": {
2453
- value: 0
2454
- },
2455
- "distanceFalloff": {
2456
- value: 1
2457
- },
2458
- "fog": {
2459
- value: false
2460
- },
2461
- "fogExp": {
2462
- value: false
2463
- },
2464
- "fogDensity": {
2465
- value: 0
2466
- },
2467
- "fogNear": {
2468
- value: Infinity
2469
- },
2470
- "fogFar": {
2471
- value: Infinity
2472
- },
2473
- "colorMultiply": {
2474
- value: true
2475
- }
2476
- },
2477
- vertexShader: (
2478
- /* glsl */
2479
- `
2480
- varying vec2 vUv;
2481
- void main() {
2482
- vUv = uv;
2483
- gl_Position = vec4(position, 1);
2484
- }`
2485
- ),
2486
- fragmentShader: (
2487
- /* glsl */
2488
- `
2489
- uniform sampler2D sceneDiffuse;
2490
- uniform highp sampler2D sceneDepth;
2491
- uniform highp sampler2D downsampledDepth;
2492
- uniform sampler2D tDiffuse;
2493
- uniform sampler2D blueNoise;
2494
- uniform vec2 resolution;
2495
- uniform vec3 color;
2496
- uniform mat4 projectionMatrixInv;
2497
- uniform mat4 viewMatrixInv;
2498
- uniform float intensity;
2499
- uniform float renderMode;
2500
- uniform float near;
2501
- uniform float far;
2502
- uniform bool gammaCorrection;
2503
- uniform bool logDepth;
2504
- uniform bool ortho;
2505
- uniform bool screenSpaceRadius;
2506
- uniform bool fog;
2507
- uniform bool fogExp;
2508
- uniform bool colorMultiply;
2509
- uniform float fogDensity;
2510
- uniform float fogNear;
2511
- uniform float fogFar;
2512
- uniform float radius;
2513
- uniform float distanceFalloff;
2514
- uniform vec3 cameraPos;
2515
- varying vec2 vUv;
2516
- highp float linearize_depth(highp float d, highp float zNear,highp float zFar)
2517
- {
2518
- return (zFar * zNear) / (zFar - d * (zFar - zNear));
2519
- }
2520
- highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {
2521
- return nearZ + (farZ - nearZ) * d;
2522
- }
2523
- highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {
2524
- float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;
2525
- float a = farZ / (farZ - nearZ);
2526
- float b = farZ * nearZ / (nearZ - farZ);
2527
- float linDepth = a + b / depth;
2528
- return ortho ? linearize_depth_ortho(
2529
- linDepth,
2530
- nearZ,
2531
- farZ
2532
- ) :linearize_depth(linDepth, nearZ, farZ);
2533
- }
2534
- vec3 getWorldPosLog(vec3 posS) {
2535
- vec2 uv = posS.xy;
2536
- float z = posS.z;
2537
- float nearZ =near;
2538
- float farZ = far;
2539
- float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;
2540
- float a = farZ / (farZ - nearZ);
2541
- float b = farZ * nearZ / (nearZ - farZ);
2542
- float linDepth = a + b / depth;
2543
- vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;
2544
- vec4 wpos = projectionMatrixInv * clipVec;
2545
- return wpos.xyz / wpos.w;
2546
- }
2547
- vec3 getWorldPos(float depth, vec2 coord) {
2548
- // if (logDepth) {
2549
- #ifdef LOGDEPTH
2550
- return getWorldPosLog(vec3(coord, depth));
2551
- #endif
2552
- // }
2553
- float z = depth * 2.0 - 1.0;
2554
- vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);
2555
- vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;
2556
- // Perspective division
2557
- vec4 worldSpacePosition = viewSpacePosition;
2558
- worldSpacePosition.xyz /= worldSpacePosition.w;
2559
- return worldSpacePosition.xyz;
2560
- }
2561
-
2562
- vec3 computeNormal(vec3 worldPos, vec2 vUv) {
2563
- ivec2 p = ivec2(vUv * resolution);
2564
- float c0 = texelFetch(sceneDepth, p, 0).x;
2565
- float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;
2566
- float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;
2567
- float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;
2568
- float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;
2569
- float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;
2570
- float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;
2571
- float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;
2572
- float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;
2573
-
2574
- float dl = abs((2.0 * l1 - l2) - c0);
2575
- float dr = abs((2.0 * r1 - r2) - c0);
2576
- float db = abs((2.0 * b1 - b2) - c0);
2577
- float dt = abs((2.0 * t1 - t2) - c0);
2578
-
2579
- vec3 ce = getWorldPos(c0, vUv).xyz;
2580
-
2581
- vec3 dpdx = (dl < dr) ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz
2582
- : -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz;
2583
- vec3 dpdy = (db < dt) ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz
2584
- : -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz;
2585
-
2586
- return normalize(cross(dpdx, dpdy));
2587
- }
2588
-
2589
- #include <common>
2590
- #include <dithering_pars_fragment>
2591
- void main() {
2592
- //vec4 texel = texture2D(tDiffuse, vUv);//vec3(0.0);
2593
- vec4 sceneTexel = texture2D(sceneDiffuse, vUv);
2594
- float depth = texture2D(
2595
- sceneDepth,
2596
- vUv
2597
- ).x;
2598
- #ifdef HALFRES
2599
- vec4 texel;
2600
- if (depth == 1.0) {
2601
- texel = vec4(0.0, 0.0, 0.0, 1.0);
2602
- } else {
2603
- vec3 worldPos = getWorldPos(depth, vUv);
2604
- vec3 normal = computeNormal(getWorldPos(depth, vUv), vUv);
2605
- // vec4 texel = texture2D(tDiffuse, vUv);
2606
- // Find closest depth;
2607
- float totalWeight = 0.0;
2608
- float radiusToUse = screenSpaceRadius ? distance(
2609
- worldPos,
2610
- getWorldPos(depth, vUv +
2611
- vec2(radius, 0.0) / resolution)
2612
- ) : radius;
2613
- float distanceFalloffToUse =screenSpaceRadius ?
2614
- radiusToUse * distanceFalloff
2615
- : distanceFalloff;
2616
- for(float x = -1.0; x <= 1.0; x++) {
2617
- for(float y = -1.0; y <= 1.0; y++) {
2618
- vec2 offset = vec2(x, y);
2619
- ivec2 p = ivec2(
2620
- (vUv * resolution * 0.5) + offset
2621
- );
2622
- vec2 pUv = vec2(p) / (resolution * 0.5);
2623
- float sampleDepth = texelFetch(downsampledDepth,p, 0).x;
2624
- vec4 sampleInfo = texelFetch(tDiffuse, p, 0);
2625
- vec3 normalSample = sampleInfo.xyz * 2.0 - 1.0;
2626
- vec3 worldPosSample = getWorldPos(sampleDepth, pUv);
2627
- float tangentPlaneDist = abs(dot(worldPos - worldPosSample, normal));
2628
- float rangeCheck = exp(-1.0 * tangentPlaneDist * (1.0 / distanceFalloffToUse)) * max(dot(normal, normalSample), 0.0);
2629
- float weight = rangeCheck;
2630
- totalWeight += weight;
2631
- texel += sampleInfo * weight;
2632
- }
2633
- }
2634
- if (totalWeight == 0.0) {
2635
- texel = texture2D(tDiffuse, vUv);
2636
- } else {
2637
- texel /= totalWeight;
2638
- }
2639
- }
2640
- #else
2641
- vec4 texel = texture2D(tDiffuse, vUv);
2642
- #endif
2643
-
2644
-
2645
- float finalAo = pow(texel.a, intensity);
2646
- float fogFactor;
2647
- float fogDepth = distance(
2648
- cameraPos,
2649
- getWorldPos(depth, vUv)
2650
- );
2651
- if (fog) {
2652
- if (fogExp) {
2653
- fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );
2654
- } else {
2655
- fogFactor = smoothstep( fogNear, fogFar, fogDepth );
2656
- }
2657
- }
2658
- finalAo = mix(finalAo, 1.0, fogFactor);
2659
- vec3 aoApplied = color * mix(vec3(1.0), sceneTexel.rgb, float(colorMultiply));
2660
- if (renderMode == 0.0) {
2661
- gl_FragColor = vec4( mix(sceneTexel.rgb, aoApplied, 1.0 - finalAo), sceneTexel.a);
2662
- } else if (renderMode == 1.0) {
2663
- gl_FragColor = vec4( mix(vec3(1.0), aoApplied, 1.0 - finalAo), sceneTexel.a);
2664
- } else if (renderMode == 2.0) {
2665
- gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);
2666
- } else if (renderMode == 3.0) {
2667
- if (vUv.x < 0.5) {
2668
- gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);
2669
- } else if (abs(vUv.x - 0.5) < 1.0 / resolution.x) {
2670
- gl_FragColor = vec4(1.0);
2671
- } else {
2672
- gl_FragColor = vec4( mix(sceneTexel.rgb, aoApplied, 1.0 - finalAo), sceneTexel.a);
2673
- }
2674
- } else if (renderMode == 4.0) {
2675
- if (vUv.x < 0.5) {
2676
- gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);
2677
- } else if (abs(vUv.x - 0.5) < 1.0 / resolution.x) {
2678
- gl_FragColor = vec4(1.0);
2679
- } else {
2680
- gl_FragColor = vec4( mix(vec3(1.0), aoApplied, 1.0 - finalAo), sceneTexel.a);
2681
- }
2682
- }
2683
- #include <dithering_fragment>
2684
- if (gammaCorrection) {
2685
- gl_FragColor = LinearTosRGB(gl_FragColor);
2686
- }
2687
- }
2688
- `
2689
- )
2690
- };
2691
- const $e52378cd0f5a973d$export$57856b59f317262e = {
2692
- uniforms: {
2693
- "sceneDiffuse": {
2694
- value: null
2695
- },
2696
- "sceneDepth": {
2697
- value: null
2698
- },
2699
- "tDiffuse": {
2700
- value: null
2701
- },
2702
- "projMat": {
2703
- value: new THREE.Matrix4()
2704
- },
2705
- "viewMat": {
2706
- value: new THREE.Matrix4()
2707
- },
2708
- "projectionMatrixInv": {
2709
- value: new THREE.Matrix4()
2710
- },
2711
- "viewMatrixInv": {
2712
- value: new THREE.Matrix4()
2713
- },
2714
- "cameraPos": {
2715
- value: new THREE.Vector3()
2716
- },
2717
- "resolution": {
2718
- value: new THREE.Vector2()
2719
- },
2720
- "time": {
2721
- value: 0
2722
- },
2723
- "r": {
2724
- value: 5
2725
- },
2726
- "blueNoise": {
2727
- value: null
2728
- },
2729
- "radius": {
2730
- value: 12
2731
- },
2732
- "worldRadius": {
2733
- value: 5
2734
- },
2735
- "index": {
2736
- value: 0
2737
- },
2738
- "poissonDisk": {
2739
- value: []
2740
- },
2741
- "distanceFalloff": {
2742
- value: 1
2743
- },
2744
- "near": {
2745
- value: 0.1
2746
- },
2747
- "far": {
2748
- value: 1e3
2749
- },
2750
- "logDepth": {
2751
- value: false
2752
- },
2753
- "screenSpaceRadius": {
2754
- value: false
2755
- }
2756
- },
2757
- vertexShader: (
2758
- /* glsl */
2759
- `
2760
- varying vec2 vUv;
2761
- void main() {
2762
- vUv = uv;
2763
- gl_Position = vec4(position, 1.0);
2764
- }`
2765
- ),
2766
- fragmentShader: (
2767
- /* glsl */
2768
- `
2769
- uniform sampler2D sceneDiffuse;
2770
- uniform highp sampler2D sceneDepth;
2771
- uniform sampler2D tDiffuse;
2772
- uniform sampler2D blueNoise;
2773
- uniform mat4 projectionMatrixInv;
2774
- uniform mat4 viewMatrixInv;
2775
- uniform vec2 resolution;
2776
- uniform float r;
2777
- uniform float radius;
2778
- uniform float worldRadius;
2779
- uniform float index;
2780
- uniform float near;
2781
- uniform float far;
2782
- uniform float distanceFalloff;
2783
- uniform bool logDepth;
2784
- uniform bool screenSpaceRadius;
2785
- varying vec2 vUv;
2786
-
2787
- highp float linearize_depth(highp float d, highp float zNear,highp float zFar)
2788
- {
2789
- highp float z_n = 2.0 * d - 1.0;
2790
- return 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear));
2791
- }
2792
- highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {
2793
- float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;
2794
- float a = farZ / (farZ - nearZ);
2795
- float b = farZ * nearZ / (nearZ - farZ);
2796
- float linDepth = a + b / depth;
2797
- return linearize_depth(linDepth, nearZ, farZ);
2798
- }
2799
- highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {
2800
- return nearZ + (farZ - nearZ) * d;
2801
- }
2802
- vec3 getWorldPosLog(vec3 posS) {
2803
- vec2 uv = posS.xy;
2804
- float z = posS.z;
2805
- float nearZ =near;
2806
- float farZ = far;
2807
- float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;
2808
- float a = farZ / (farZ - nearZ);
2809
- float b = farZ * nearZ / (nearZ - farZ);
2810
- float linDepth = a + b / depth;
2811
- vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;
2812
- vec4 wpos = projectionMatrixInv * clipVec;
2813
- return wpos.xyz / wpos.w;
2814
- }
2815
- vec3 getWorldPos(float depth, vec2 coord) {
2816
- #ifdef LOGDEPTH
2817
- return getWorldPosLog(vec3(coord, depth));
2818
- #endif
2819
-
2820
- float z = depth * 2.0 - 1.0;
2821
- vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);
2822
- vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;
2823
- // Perspective division
2824
- vec4 worldSpacePosition = viewSpacePosition;
2825
- worldSpacePosition.xyz /= worldSpacePosition.w;
2826
- return worldSpacePosition.xyz;
2827
- }
2828
- #include <common>
2829
- #define NUM_SAMPLES 16
2830
- uniform vec2 poissonDisk[NUM_SAMPLES];
2831
- void main() {
2832
- const float pi = 3.14159;
2833
- vec2 texelSize = vec2(1.0 / resolution.x, 1.0 / resolution.y);
2834
- vec2 uv = vUv;
2835
- vec4 data = texture2D(tDiffuse, vUv);
2836
- float occlusion = data.a;
2837
- float baseOcc = data.a;
2838
- vec3 normal = data.rgb * 2.0 - 1.0;
2839
- float count = 1.0;
2840
- float d = texture2D(sceneDepth, vUv).x;
2841
- if (d == 1.0) {
2842
- gl_FragColor = data;
2843
- return;
2844
- }
2845
- vec3 worldPos = getWorldPos(d, vUv);
2846
- float size = radius;
2847
- float angle;
2848
- if (index == 0.0) {
2849
- angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).x * PI2;
2850
- } else if (index == 1.0) {
2851
- angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).y * PI2;
2852
- } else if (index == 2.0) {
2853
- angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).z * PI2;
2854
- } else {
2855
- angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).w * PI2;
2856
- }
2857
-
2858
- mat2 rotationMatrix = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));
2859
- float radiusToUse = screenSpaceRadius ? distance(
2860
- worldPos,
2861
- getWorldPos(d, vUv +
2862
- vec2(worldRadius, 0.0) / resolution)
2863
- ) : worldRadius;
2864
- float distanceFalloffToUse =screenSpaceRadius ?
2865
- radiusToUse * distanceFalloff
2866
- : distanceFalloff;
2867
-
2868
-
2869
- for(int i = 0; i < NUM_SAMPLES; i++) {
2870
- vec2 offset = (rotationMatrix * poissonDisk[i]) * texelSize * size;
2871
- vec4 dataSample = texture2D(tDiffuse, uv + offset);
2872
- float occSample = dataSample.a;
2873
- vec3 normalSample = dataSample.rgb * 2.0 - 1.0;
2874
- float dSample = texture2D(sceneDepth, uv + offset).x;
2875
- vec3 worldPosSample = getWorldPos(dSample, uv + offset);
2876
- float tangentPlaneDist = abs(dot(worldPos - worldPosSample, normal));
2877
- float rangeCheck = dSample == 1.0 ? 0.0 :exp(-1.0 * tangentPlaneDist * (1.0 / distanceFalloffToUse)) * max(dot(normal, normalSample), 0.0) * (1.0 - abs(occSample - baseOcc));
2878
- occlusion += occSample * rangeCheck;
2879
- count += rangeCheck;
2880
- }
2881
- occlusion /= count;
2882
- gl_FragColor = vec4(0.5 + 0.5 * normal, occlusion);
2883
- }
2884
- `
2885
- )
2886
- };
2887
- const $26aca173e0984d99$export$1efdf491687cd442 = {
2888
- uniforms: {
2889
- "sceneDepth": {
2890
- value: null
2891
- },
2892
- "resolution": {
2893
- value: new THREE.Vector2()
2894
- },
2895
- "near": {
2896
- value: 0.1
2897
- },
2898
- "far": {
2899
- value: 1e3
2900
- },
2901
- "viewMatrixInv": {
2902
- value: new THREE.Matrix4()
2903
- },
2904
- "projectionMatrixInv": {
2905
- value: new THREE.Matrix4()
2906
- },
2907
- "logDepth": {
2908
- value: false
2909
- }
2910
- },
2911
- vertexShader: (
2912
- /* glsl */
2913
- `
2914
- varying vec2 vUv;
2915
- void main() {
2916
- vUv = uv;
2917
- gl_Position = vec4(position, 1);
2918
- }`
2919
- ),
2920
- fragmentShader: (
2921
- /* glsl */
2922
- `
2923
- uniform highp sampler2D sceneDepth;
2924
- uniform vec2 resolution;
2925
- uniform float near;
2926
- uniform float far;
2927
- uniform bool logDepth;
2928
- uniform mat4 viewMatrixInv;
2929
- uniform mat4 projectionMatrixInv;
2930
- varying vec2 vUv;
2931
- layout(location = 1) out vec4 gNormal;
2932
- vec3 getWorldPosLog(vec3 posS) {
2933
- vec2 uv = posS.xy;
2934
- float z = posS.z;
2935
- float nearZ =near;
2936
- float farZ = far;
2937
- float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;
2938
- float a = farZ / (farZ - nearZ);
2939
- float b = farZ * nearZ / (nearZ - farZ);
2940
- float linDepth = a + b / depth;
2941
- vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;
2942
- vec4 wpos = projectionMatrixInv * clipVec;
2943
- return wpos.xyz / wpos.w;
2944
- }
2945
- vec3 getWorldPos(float depth, vec2 coord) {
2946
- if (logDepth) {
2947
- return getWorldPosLog(vec3(coord, depth));
2948
- }
2949
- float z = depth * 2.0 - 1.0;
2950
- vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);
2951
- vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;
2952
- // Perspective division
2953
- vec4 worldSpacePosition = viewSpacePosition;
2954
- worldSpacePosition.xyz /= worldSpacePosition.w;
2955
- return worldSpacePosition.xyz;
2956
- }
2957
-
2958
- vec3 computeNormal(vec3 worldPos, vec2 vUv) {
2959
- ivec2 p = ivec2(vUv * resolution);
2960
- float c0 = texelFetch(sceneDepth, p, 0).x;
2961
- float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;
2962
- float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;
2963
- float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;
2964
- float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;
2965
- float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;
2966
- float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;
2967
- float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;
2968
- float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;
2969
-
2970
- float dl = abs((2.0 * l1 - l2) - c0);
2971
- float dr = abs((2.0 * r1 - r2) - c0);
2972
- float db = abs((2.0 * b1 - b2) - c0);
2973
- float dt = abs((2.0 * t1 - t2) - c0);
2974
-
2975
- vec3 ce = getWorldPos(c0, vUv).xyz;
2976
-
2977
- vec3 dpdx = (dl < dr) ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz
2978
- : -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz;
2979
- vec3 dpdy = (db < dt) ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz
2980
- : -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz;
2981
-
2982
- return normalize(cross(dpdx, dpdy));
2983
- }
2984
- void main() {
2985
- vec2 uv = vUv - vec2(0.5) / resolution;
2986
- vec2 pixelSize = vec2(1.0) / resolution;
2987
- vec2[] uvSamples = vec2[4](
2988
- uv,
2989
- uv + vec2(pixelSize.x, 0.0),
2990
- uv + vec2(0.0, pixelSize.y),
2991
- uv + pixelSize
2992
- );
2993
- float depth00 = texture2D(sceneDepth, uvSamples[0]).r;
2994
- float depth10 = texture2D(sceneDepth, uvSamples[1]).r;
2995
- float depth01 = texture2D(sceneDepth, uvSamples[2]).r;
2996
- float depth11 = texture2D(sceneDepth, uvSamples[3]).r;
2997
- float minDepth = min(min(depth00, depth10), min(depth01, depth11));
2998
- float maxDepth = max(max(depth00, depth10), max(depth01, depth11));
2999
- float targetDepth = minDepth;
3000
- // Checkerboard pattern to avoid artifacts
3001
- if (mod(gl_FragCoord.x + gl_FragCoord.y, 2.0) > 0.5) {
3002
- targetDepth = maxDepth;
3003
- }
3004
- int chosenIndex = 0;
3005
- float[] samples = float[4](depth00, depth10, depth01, depth11);
3006
- for(int i = 0; i < 4; ++i) {
3007
- if (samples[i] == targetDepth) {
3008
- chosenIndex = i;
3009
- break;
3010
- }
3011
- }
3012
- gl_FragColor = vec4(samples[chosenIndex], 0.0, 0.0, 1.0);
3013
- gNormal = vec4(computeNormal(
3014
- getWorldPos(samples[chosenIndex], uvSamples[chosenIndex]), uvSamples[chosenIndex]
3015
- ), 0.0);
3016
- /* float[] samples = float[4](depth00, depth10, depth01, depth11);
3017
- float c = 0.25 * (depth00 + depth10 + depth01 + depth11);
3018
- float[] distances = float[4](depth00, depth10, depth01, depth11);
3019
- float maxDistance = max(max(distances[0], distances[1]), max(distances[2], distances[3]));
3020
-
3021
- int remaining[3];
3022
- int rejected[3];
3023
- int i, j, k;
3024
-
3025
- for(i = 0, j = 0, k = 0; i < 4; ++i) {
3026
- if (distances[i] < maxDistance) {
3027
- remaining[j++] = i;
3028
- } else {
3029
- rejected[k++] = i;
3030
- }
3031
- }
3032
- for(;j < 3;++j) {
3033
- remaining[j] = rejected[--k];
3034
- }
3035
- vec3 s = vec3(
3036
- samples[remaining[0]],
3037
- samples[remaining[1]],
3038
- samples[remaining[2]]
3039
- );
3040
- c = (s.x + s.y + s.z) / 3.0;
3041
-
3042
- distances[0] = abs(c - s.x);
3043
- distances[1] = abs(c - s.y);
3044
- distances[2] = abs(c - s.z);
3045
-
3046
- float minDistance = min(min(distances[0], distances[1]), distances[2]);
3047
-
3048
- for(i = 0; i < 3; ++i) {
3049
- if (distances[i] == minDistance) {
3050
- break;
3051
- }
3052
- }*/
3053
- /* gl_FragColor = vec4(samples[remaining[i]], 0.0, 0.0, 0.0);
3054
- gNormal = vec4(computeNormal(
3055
- getWorldPos(samples[remaining[i]], uvSamples[remaining[i]]), uvSamples[remaining[i]]
3056
- ), 0.0);*/
3057
- }`
3058
- )
3059
- };
3060
- var $06269ad78f3c5fdf$export$2e2bcd8739ae039 = `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`;
3061
- const $87431ee93b037844$var$bluenoiseBits = Uint8Array.from(atob($06269ad78f3c5fdf$export$2e2bcd8739ae039), (c) => c.charCodeAt(0));
3062
- function $87431ee93b037844$var$checkTimerQuery(timerQuery, gl, pass) {
3063
- const available = gl.getQueryParameter(timerQuery, gl.QUERY_RESULT_AVAILABLE);
3064
- if (available) {
3065
- const elapsedTimeInNs = gl.getQueryParameter(timerQuery, gl.QUERY_RESULT);
3066
- const elapsedTimeInMs = elapsedTimeInNs / 1e6;
3067
- pass.lastTime = elapsedTimeInMs;
3068
- } else
3069
- setTimeout(() => {
3070
- $87431ee93b037844$var$checkTimerQuery(timerQuery, gl, pass);
3071
- }, 1);
3072
- }
3073
- class $87431ee93b037844$export$2489f9981ab0fa82 extends postprocessing.Pass {
3074
- /**
3075
- *
3076
- * @param {THREE.Scene} scene
3077
- * @param {THREE.Camera} camera
3078
- * @param {number} width
3079
- * @param {number} height
3080
- *
3081
- * @property {THREE.Scene} scene
3082
- * @property {THREE.Camera} camera
3083
- * @property {number} width
3084
- * @property {number} height
3085
- */
3086
- constructor(scene, camera, width = 512, height = 512) {
3087
- super();
3088
- this.width = width;
3089
- this.height = height;
3090
- this.clear = true;
3091
- this.camera = camera;
3092
- this.scene = scene;
3093
- this.autosetGamma = true;
3094
- this.configuration = new Proxy({
3095
- aoSamples: 16,
3096
- aoRadius: 5,
3097
- denoiseSamples: 8,
3098
- denoiseRadius: 12,
3099
- distanceFalloff: 1,
3100
- intensity: 5,
3101
- denoiseIterations: 2,
3102
- renderMode: 0,
3103
- color: new THREE.Color(0, 0, 0),
3104
- gammaCorrection: true,
3105
- logarithmicDepthBuffer: false,
3106
- screenSpaceRadius: false,
3107
- halfRes: false,
3108
- depthAwareUpsampling: true,
3109
- colorMultiply: true
3110
- }, {
3111
- set: (target, propName, value) => {
3112
- const oldProp = target[propName];
3113
- target[propName] = value;
3114
- if (propName === "aoSamples" && oldProp !== value)
3115
- this.configureAOPass(this.configuration.logarithmicDepthBuffer);
3116
- if (propName === "denoiseSamples" && oldProp !== value)
3117
- this.configureDenoisePass(this.configuration.logarithmicDepthBuffer);
3118
- if (propName === "halfRes" && oldProp !== value) {
3119
- this.configureAOPass(this.configuration.logarithmicDepthBuffer);
3120
- this.configureHalfResTargets();
3121
- this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);
3122
- this.setSize(this.width, this.height);
3123
- }
3124
- if (propName === "depthAwareUpsampling" && oldProp !== value)
3125
- this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);
3126
- if (propName === "gammaCorrection")
3127
- this.autosetGamma = false;
3128
- return true;
3129
- }
3130
- });
3131
- this.samples = [];
3132
- this.samplesR = [];
3133
- this.samplesDenoise = [];
3134
- this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);
3135
- this.configureSampleDependentPasses();
3136
- this.configureHalfResTargets();
3137
- this.copyQuad = new $e4ca8dcb0218f846$export$dcd670d73db751f5(new THREE.ShaderMaterial({
3138
- uniforms: {
3139
- tDiffuse: {
3140
- value: null
3141
- }
3142
- },
3143
- depthWrite: false,
3144
- vertexShader: `
3145
- varying vec2 vUv;
3146
- void main() {
3147
- vUv = uv;
3148
- gl_Position = vec4(position, 1);
3149
- }
3150
- `,
3151
- fragmentShader: `
3152
- uniform sampler2D tDiffuse;
3153
- varying vec2 vUv;
3154
- void main() {
3155
- gl_FragColor = texture2D(tDiffuse, vUv);
3156
- }
3157
- `
3158
- }));
3159
- this.writeTargetInternal = new THREE.WebGLRenderTarget(this.width, this.height, {
3160
- minFilter: THREE.LinearFilter,
3161
- magFilter: THREE.LinearFilter,
3162
- depthBuffer: false
3163
- });
3164
- this.readTargetInternal = new THREE.WebGLRenderTarget(this.width, this.height, {
3165
- minFilter: THREE.LinearFilter,
3166
- magFilter: THREE.LinearFilter,
3167
- depthBuffer: false
3168
- });
3169
- this.outputTargetInternal = new THREE.WebGLRenderTarget(this.width, this.height, {
3170
- minFilter: THREE.LinearFilter,
3171
- magFilter: THREE.LinearFilter,
3172
- depthBuffer: false
3173
- });
3174
- this.bluenoise = new THREE.DataTexture($87431ee93b037844$var$bluenoiseBits, 128, 128);
3175
- this.bluenoise.colorSpace = THREE.NoColorSpace;
3176
- this.bluenoise.wrapS = THREE.RepeatWrapping;
3177
- this.bluenoise.wrapT = THREE.RepeatWrapping;
3178
- this.bluenoise.minFilter = THREE.NearestFilter;
3179
- this.bluenoise.magFilter = THREE.NearestFilter;
3180
- this.bluenoise.needsUpdate = true;
3181
- this.lastTime = 0;
3182
- this.needsDepthTexture = true;
3183
- this.needsSwap = true;
3184
- this._r = new THREE.Vector2();
3185
- this._c = new THREE.Color();
3186
- }
3187
- configureHalfResTargets() {
3188
- if (this.configuration.halfRes) {
3189
- this.depthDownsampleTarget = /*new THREE.WebGLRenderTarget(this.width / 2, this.height / 2, {
3190
- minFilter: THREE.NearestFilter,
3191
- magFilter: THREE.NearestFilter,
3192
- depthBuffer: false,
3193
- format: THREE.RedFormat,
3194
- type: THREE.FloatType
3195
- });*/
3196
- new THREE.WebGLMultipleRenderTargets(this.width / 2, this.height / 2, 2);
3197
- this.depthDownsampleTarget.texture[0].format = THREE.RedFormat;
3198
- this.depthDownsampleTarget.texture[0].type = THREE.FloatType;
3199
- this.depthDownsampleTarget.texture[0].minFilter = THREE.NearestFilter;
3200
- this.depthDownsampleTarget.texture[0].magFilter = THREE.NearestFilter;
3201
- this.depthDownsampleTarget.texture[0].depthBuffer = false;
3202
- this.depthDownsampleTarget.texture[1].format = THREE.RGBAFormat;
3203
- this.depthDownsampleTarget.texture[1].type = THREE.HalfFloatType;
3204
- this.depthDownsampleTarget.texture[1].minFilter = THREE.NearestFilter;
3205
- this.depthDownsampleTarget.texture[1].magFilter = THREE.NearestFilter;
3206
- this.depthDownsampleTarget.texture[1].depthBuffer = false;
3207
- this.depthDownsampleQuad = new $e4ca8dcb0218f846$export$dcd670d73db751f5(new THREE.ShaderMaterial($26aca173e0984d99$export$1efdf491687cd442));
3208
- } else {
3209
- if (this.depthDownsampleTarget) {
3210
- this.depthDownsampleTarget.dispose();
3211
- this.depthDownsampleTarget = null;
3212
- }
3213
- if (this.depthDownsampleQuad) {
3214
- this.depthDownsampleQuad.dispose();
3215
- this.depthDownsampleQuad = null;
3216
- }
3217
- }
3218
- }
3219
- configureSampleDependentPasses() {
3220
- this.configureAOPass(this.configuration.logarithmicDepthBuffer);
3221
- this.configureDenoisePass(this.configuration.logarithmicDepthBuffer);
3222
- }
3223
- configureAOPass(logarithmicDepthBuffer = false) {
3224
- this.samples = this.generateHemisphereSamples(this.configuration.aoSamples);
3225
- this.samplesR = this.generateHemisphereSamplesR(this.configuration.aoSamples);
3226
- const e = {
3227
- ...$1ed45968c1160c3c$export$c9b263b9a17dffd7
3228
- };
3229
- e.fragmentShader = e.fragmentShader.replace("16", this.configuration.aoSamples).replace("16.0", this.configuration.aoSamples + ".0");
3230
- if (logarithmicDepthBuffer)
3231
- e.fragmentShader = "#define LOGDEPTH\n" + e.fragmentShader;
3232
- if (this.configuration.halfRes)
3233
- e.fragmentShader = "#define HALFRES\n" + e.fragmentShader;
3234
- if (this.effectShaderQuad) {
3235
- this.effectShaderQuad.material.dispose();
3236
- this.effectShaderQuad.material = new THREE.ShaderMaterial(e);
3237
- } else
3238
- this.effectShaderQuad = new $e4ca8dcb0218f846$export$dcd670d73db751f5(new THREE.ShaderMaterial(e));
3239
- }
3240
- configureDenoisePass(logarithmicDepthBuffer = false) {
3241
- this.samplesDenoise = this.generateDenoiseSamples(this.configuration.denoiseSamples, 11);
3242
- const p = {
3243
- ...$e52378cd0f5a973d$export$57856b59f317262e
3244
- };
3245
- p.fragmentShader = p.fragmentShader.replace("16", this.configuration.denoiseSamples);
3246
- if (logarithmicDepthBuffer)
3247
- p.fragmentShader = "#define LOGDEPTH\n" + p.fragmentShader;
3248
- if (this.poissonBlurQuad) {
3249
- this.poissonBlurQuad.material.dispose();
3250
- this.poissonBlurQuad.material = new THREE.ShaderMaterial(p);
3251
- } else
3252
- this.poissonBlurQuad = new $e4ca8dcb0218f846$export$dcd670d73db751f5(new THREE.ShaderMaterial(p));
3253
- }
3254
- configureEffectCompositer(logarithmicDepthBuffer = false) {
3255
- const e = {
3256
- ...$12b21d24d1192a04$export$a815acccbd2c9a49
3257
- };
3258
- if (logarithmicDepthBuffer)
3259
- e.fragmentShader = "#define LOGDEPTH\n" + e.fragmentShader;
3260
- if (this.configuration.halfRes && this.configuration.depthAwareUpsampling)
3261
- e.fragmentShader = "#define HALFRES\n" + e.fragmentShader;
3262
- if (this.effectCompositerQuad) {
3263
- this.effectCompositerQuad.material.dispose();
3264
- this.effectCompositerQuad.material = new THREE.ShaderMaterial(e);
3265
- } else
3266
- this.effectCompositerQuad = new $e4ca8dcb0218f846$export$dcd670d73db751f5(new THREE.ShaderMaterial(e));
3267
- }
3268
- /**
3269
- *
3270
- * @param {Number} n
3271
- * @returns {THREE.Vector3[]}
3272
- */
3273
- generateHemisphereSamples(n) {
3274
- const points = [];
3275
- for (let k = 0; k < n; k++) {
3276
- const theta = 2.399963 * k;
3277
- const r = Math.sqrt(k + 0.5) / Math.sqrt(n);
3278
- const x = r * Math.cos(theta);
3279
- const y = r * Math.sin(theta);
3280
- const z = Math.sqrt(1 - (x * x + y * y));
3281
- points.push(new THREE.Vector3(x, y, z));
3282
- }
3283
- return points;
3284
- }
3285
- /**
3286
- *
3287
- * @param {number} n
3288
- * @returns {number[]}
3289
- */
3290
- generateHemisphereSamplesR(n) {
3291
- let samplesR = [];
3292
- for (let i2 = 0; i2 < n; i2++)
3293
- samplesR.push((i2 + 1) / n);
3294
- return samplesR;
3295
- }
3296
- /**
3297
- *
3298
- * @param {number} numSamples
3299
- * @param {number} numRings
3300
- * @returns {THREE.Vector2[]}
3301
- */
3302
- generateDenoiseSamples(numSamples, numRings) {
3303
- const angleStep = 2 * Math.PI * numRings / numSamples;
3304
- const invNumSamples = 1 / numSamples;
3305
- const radiusStep = invNumSamples;
3306
- const samples = [];
3307
- let radius = invNumSamples;
3308
- let angle = 0;
3309
- for (let i2 = 0; i2 < numSamples; i2++) {
3310
- samples.push(new THREE.Vector2(Math.cos(angle), Math.sin(angle)).multiplyScalar(Math.pow(radius, 0.75)));
3311
- radius += radiusStep;
3312
- angle += angleStep;
3313
- }
3314
- return samples;
3315
- }
3316
- setSize(width, height) {
3317
- this.width = width;
3318
- this.height = height;
3319
- const c = this.configuration.halfRes ? 0.5 : 1;
3320
- this.writeTargetInternal.setSize(width * c, height * c);
3321
- this.readTargetInternal.setSize(width * c, height * c);
3322
- if (this.configuration.halfRes)
3323
- this.depthDownsampleTarget.setSize(width * c, height * c);
3324
- this.outputTargetInternal.setSize(width, height);
3325
- }
3326
- setDepthTexture(depthTexture) {
3327
- this.depthTexture = depthTexture;
3328
- }
3329
- render(renderer, inputBuffer, outputBuffer) {
3330
- const xrEnabled = renderer.xr.enabled;
3331
- renderer.xr.enabled = false;
3332
- if (renderer.capabilities.logarithmicDepthBuffer !== this.configuration.logarithmicDepthBuffer) {
3333
- this.configuration.logarithmicDepthBuffer = renderer.capabilities.logarithmicDepthBuffer;
3334
- this.configureAOPass(this.configuration.logarithmicDepthBuffer);
3335
- this.configureDenoisePass(this.configuration.logarithmicDepthBuffer);
3336
- this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);
3337
- }
3338
- if (inputBuffer.texture.type !== this.outputTargetInternal.texture.type) {
3339
- this.outputTargetInternal.texture.type = inputBuffer.texture.type;
3340
- this.outputTargetInternal.texture.needsUpdate = true;
3341
- }
3342
- let gl;
3343
- let ext;
3344
- let timerQuery;
3345
- if (this.debugMode) {
3346
- gl = renderer.getContext();
3347
- ext = gl.getExtension("EXT_disjoint_timer_query_webgl2");
3348
- if (ext === null) {
3349
- console.error("EXT_disjoint_timer_query_webgl2 not available, disabling debug mode.");
3350
- this.debugMode = false;
3351
- }
3352
- }
3353
- if (this.debugMode) {
3354
- timerQuery = gl.createQuery();
3355
- gl.beginQuery(ext.TIME_ELAPSED_EXT, timerQuery);
3356
- }
3357
- this.camera.updateMatrixWorld();
3358
- this._r.set(this.width, this.height);
3359
- let trueRadius = this.configuration.aoRadius;
3360
- if (this.configuration.halfRes && this.configuration.screenSpaceRadius)
3361
- trueRadius *= 0.5;
3362
- if (this.configuration.halfRes) {
3363
- renderer.setRenderTarget(this.depthDownsampleTarget);
3364
- this.depthDownsampleQuad.material.uniforms.sceneDepth.value = this.depthTexture;
3365
- this.depthDownsampleQuad.material.uniforms.resolution.value = this._r;
3366
- this.depthDownsampleQuad.material.uniforms["near"].value = this.camera.near;
3367
- this.depthDownsampleQuad.material.uniforms["far"].value = this.camera.far;
3368
- this.depthDownsampleQuad.material.uniforms["projectionMatrixInv"].value = this.camera.projectionMatrixInverse;
3369
- this.depthDownsampleQuad.material.uniforms["viewMatrixInv"].value = this.camera.matrixWorld;
3370
- this.depthDownsampleQuad.material.uniforms["logDepth"].value = this.configuration.logarithmicDepthBuffer;
3371
- this.depthDownsampleQuad.render(renderer);
3372
- }
3373
- this.effectShaderQuad.material.uniforms["sceneDiffuse"].value = inputBuffer.texture;
3374
- this.effectShaderQuad.material.uniforms["sceneDepth"].value = this.configuration.halfRes ? this.depthDownsampleTarget.texture[0] : this.depthTexture;
3375
- this.effectShaderQuad.material.uniforms["sceneNormal"].value = this.configuration.halfRes ? this.depthDownsampleTarget.texture[1] : null;
3376
- this.effectShaderQuad.material.uniforms["projMat"].value = this.camera.projectionMatrix;
3377
- this.effectShaderQuad.material.uniforms["viewMat"].value = this.camera.matrixWorldInverse;
3378
- this.effectShaderQuad.material.uniforms["projViewMat"].value = this.camera.projectionMatrix.clone().multiply(this.camera.matrixWorldInverse.clone());
3379
- this.effectShaderQuad.material.uniforms["projectionMatrixInv"].value = this.camera.projectionMatrixInverse;
3380
- this.effectShaderQuad.material.uniforms["viewMatrixInv"].value = this.camera.matrixWorld;
3381
- this.effectShaderQuad.material.uniforms["cameraPos"].value = this.camera.getWorldPosition(new THREE.Vector3());
3382
- this.effectShaderQuad.material.uniforms["resolution"].value = this.configuration.halfRes ? this._r.clone().multiplyScalar(0.5).floor() : this._r;
3383
- this.effectShaderQuad.material.uniforms["time"].value = performance.now() / 1e3;
3384
- this.effectShaderQuad.material.uniforms["samples"].value = this.samples;
3385
- this.effectShaderQuad.material.uniforms["samplesR"].value = this.samplesR;
3386
- this.effectShaderQuad.material.uniforms["bluenoise"].value = this.bluenoise;
3387
- this.effectShaderQuad.material.uniforms["radius"].value = trueRadius;
3388
- this.effectShaderQuad.material.uniforms["distanceFalloff"].value = this.configuration.distanceFalloff;
3389
- this.effectShaderQuad.material.uniforms["near"].value = this.camera.near;
3390
- this.effectShaderQuad.material.uniforms["far"].value = this.camera.far;
3391
- this.effectShaderQuad.material.uniforms["logDepth"].value = renderer.capabilities.logarithmicDepthBuffer;
3392
- this.effectShaderQuad.material.uniforms["ortho"].value = this.camera.isOrthographicCamera;
3393
- this.effectShaderQuad.material.uniforms["screenSpaceRadius"].value = this.configuration.screenSpaceRadius;
3394
- renderer.setRenderTarget(this.writeTargetInternal);
3395
- this.effectShaderQuad.render(renderer);
3396
- for (let i2 = 0; i2 < this.configuration.denoiseIterations; i2++) {
3397
- [this.writeTargetInternal, this.readTargetInternal] = [
3398
- this.readTargetInternal,
3399
- this.writeTargetInternal
3400
- ];
3401
- this.poissonBlurQuad.material.uniforms["tDiffuse"].value = this.readTargetInternal.texture;
3402
- this.poissonBlurQuad.material.uniforms["sceneDepth"].value = this.configuration.halfRes ? this.depthDownsampleTarget.texture[0] : this.depthTexture;
3403
- this.poissonBlurQuad.material.uniforms["projMat"].value = this.camera.projectionMatrix;
3404
- this.poissonBlurQuad.material.uniforms["viewMat"].value = this.camera.matrixWorldInverse;
3405
- this.poissonBlurQuad.material.uniforms["projectionMatrixInv"].value = this.camera.projectionMatrixInverse;
3406
- this.poissonBlurQuad.material.uniforms["viewMatrixInv"].value = this.camera.matrixWorld;
3407
- this.poissonBlurQuad.material.uniforms["cameraPos"].value = this.camera.getWorldPosition(new THREE.Vector3());
3408
- this.poissonBlurQuad.material.uniforms["resolution"].value = this.configuration.halfRes ? this._r.clone().multiplyScalar(0.5).floor() : this._r;
3409
- this.poissonBlurQuad.material.uniforms["time"].value = performance.now() / 1e3;
3410
- this.poissonBlurQuad.material.uniforms["blueNoise"].value = this.bluenoise;
3411
- this.poissonBlurQuad.material.uniforms["radius"].value = this.configuration.denoiseRadius * (this.configuration.halfRes ? 0.5 : 1);
3412
- this.poissonBlurQuad.material.uniforms["worldRadius"].value = trueRadius;
3413
- this.poissonBlurQuad.material.uniforms["distanceFalloff"].value = this.configuration.distanceFalloff;
3414
- this.poissonBlurQuad.material.uniforms["index"].value = i2;
3415
- this.poissonBlurQuad.material.uniforms["poissonDisk"].value = this.samplesDenoise;
3416
- this.poissonBlurQuad.material.uniforms["near"].value = this.camera.near;
3417
- this.poissonBlurQuad.material.uniforms["far"].value = this.camera.far;
3418
- this.poissonBlurQuad.material.uniforms["logDepth"].value = renderer.capabilities.logarithmicDepthBuffer;
3419
- this.poissonBlurQuad.material.uniforms["screenSpaceRadius"].value = this.configuration.screenSpaceRadius;
3420
- renderer.setRenderTarget(this.writeTargetInternal);
3421
- this.poissonBlurQuad.render(renderer);
3422
- }
3423
- this.effectCompositerQuad.material.uniforms["sceneDiffuse"].value = inputBuffer.texture;
3424
- this.effectCompositerQuad.material.uniforms["sceneDepth"].value = this.depthTexture;
3425
- this.effectCompositerQuad.material.uniforms["near"].value = this.camera.near;
3426
- this.effectCompositerQuad.material.uniforms["far"].value = this.camera.far;
3427
- this.effectCompositerQuad.material.uniforms["projectionMatrixInv"].value = this.camera.projectionMatrixInverse;
3428
- this.effectCompositerQuad.material.uniforms["viewMatrixInv"].value = this.camera.matrixWorld;
3429
- this.effectCompositerQuad.material.uniforms["logDepth"].value = renderer.capabilities.logarithmicDepthBuffer;
3430
- this.effectCompositerQuad.material.uniforms["ortho"].value = this.camera.isOrthographicCamera;
3431
- this.effectCompositerQuad.material.uniforms["downsampledDepth"].value = this.configuration.halfRes ? this.depthDownsampleTarget.texture[0] : this.depthTexture;
3432
- this.effectCompositerQuad.material.uniforms["resolution"].value = this._r;
3433
- this.effectCompositerQuad.material.uniforms["blueNoise"].value = this.bluenoise;
3434
- this.effectCompositerQuad.material.uniforms["intensity"].value = this.configuration.intensity;
3435
- this.effectCompositerQuad.material.uniforms["renderMode"].value = this.configuration.renderMode;
3436
- this.effectCompositerQuad.material.uniforms["screenSpaceRadius"].value = this.configuration.screenSpaceRadius;
3437
- this.effectCompositerQuad.material.uniforms["radius"].value = trueRadius;
3438
- this.effectCompositerQuad.material.uniforms["distanceFalloff"].value = this.configuration.distanceFalloff;
3439
- this.effectCompositerQuad.material.uniforms["gammaCorrection"].value = this.autosetGamma ? this.renderToScreen : this.configuration.gammaCorrection;
3440
- this.effectCompositerQuad.material.uniforms["tDiffuse"].value = this.writeTargetInternal.texture;
3441
- this.effectCompositerQuad.material.uniforms["color"].value = this._c.copy(this.configuration.color).convertSRGBToLinear();
3442
- this.effectCompositerQuad.material.uniforms["colorMultiply"].value = this.configuration.colorMultiply;
3443
- this.effectCompositerQuad.material.uniforms["cameraPos"].value = this.camera.getWorldPosition(new THREE.Vector3());
3444
- this.effectCompositerQuad.material.uniforms["fog"].value = !!this.scene.fog;
3445
- if (this.scene.fog) {
3446
- if (this.scene.fog.isFog) {
3447
- this.effectCompositerQuad.material.uniforms["fogExp"].value = false;
3448
- this.effectCompositerQuad.material.uniforms["fogNear"].value = this.scene.fog.near;
3449
- this.effectCompositerQuad.material.uniforms["fogFar"].value = this.scene.fog.far;
3450
- } else if (this.scene.fog.isFogExp2) {
3451
- this.effectCompositerQuad.material.uniforms["fogExp"].value = true;
3452
- this.effectCompositerQuad.material.uniforms["fogDensity"].value = this.scene.fog.density;
3453
- } else
3454
- console.error(`Unsupported fog type ${this.scene.fog.constructor.name} in SSAOPass.`);
3455
- }
3456
- renderer.setRenderTarget(
3457
- /* this.renderToScreen ? null :
3458
- outputBuffer*/
3459
- this.outputTargetInternal
3460
- );
3461
- this.effectCompositerQuad.render(renderer);
3462
- renderer.setRenderTarget(this.renderToScreen ? null : outputBuffer);
3463
- this.copyQuad.material.uniforms["tDiffuse"].value = this.outputTargetInternal.texture;
3464
- this.copyQuad.render(renderer);
3465
- if (this.debugMode) {
3466
- gl.endQuery(ext.TIME_ELAPSED_EXT);
3467
- $87431ee93b037844$var$checkTimerQuery(timerQuery, gl, this);
3468
- }
3469
- renderer.xr.enabled = xrEnabled;
3470
- }
3471
- /**
3472
- * Enables the debug mode of the AO, meaning the lastTime value will be updated.
3473
- */
3474
- enableDebugMode() {
3475
- this.debugMode = true;
3476
- }
3477
- /**
3478
- * Disables the debug mode of the AO, meaning the lastTime value will not be updated.
3479
- */
3480
- disableDebugMode() {
3481
- this.debugMode = false;
3482
- }
3483
- /**
3484
- * Sets the display mode of the AO
3485
- * @param {"Combined" | "AO" | "No AO" | "Split" | "Split AO"} mode - The display mode.
3486
- */
3487
- setDisplayMode(mode) {
3488
- this.configuration.renderMode = [
3489
- "Combined",
3490
- "AO",
3491
- "No AO",
3492
- "Split",
3493
- "Split AO"
3494
- ].indexOf(mode);
3495
- }
3496
- /**
3497
- *
3498
- * @param {"Performance" | "Low" | "Medium" | "High" | "Ultra"} mode
3499
- */
3500
- setQualityMode(mode) {
3501
- if (mode === "Performance") {
3502
- this.configuration.aoSamples = 8;
3503
- this.configuration.denoiseSamples = 4;
3504
- this.configuration.denoiseRadius = 12;
3505
- } else if (mode === "Low") {
3506
- this.configuration.aoSamples = 16;
3507
- this.configuration.denoiseSamples = 4;
3508
- this.configuration.denoiseRadius = 12;
3509
- } else if (mode === "Medium") {
3510
- this.configuration.aoSamples = 16;
3511
- this.configuration.denoiseSamples = 8;
3512
- this.configuration.denoiseRadius = 12;
3513
- } else if (mode === "High") {
3514
- this.configuration.aoSamples = 64;
3515
- this.configuration.denoiseSamples = 8;
3516
- this.configuration.denoiseRadius = 6;
3517
- } else if (mode === "Ultra") {
3518
- this.configuration.aoSamples = 64;
3519
- this.configuration.denoiseSamples = 16;
3520
- this.configuration.denoiseRadius = 6;
3521
- }
3522
- }
3523
- }
3524
- Uint8Array.from(atob($06269ad78f3c5fdf$export$2e2bcd8739ae039), (c) => c.charCodeAt(0));
3525
- const N8AO = React.forwardRef(
3526
- ({
3527
- halfRes,
3528
- screenSpaceRadius,
3529
- quality,
3530
- depthAwareUpsampling = true,
3531
- aoRadius = 5,
3532
- aoSamples = 16,
3533
- denoiseSamples = 4,
3534
- denoiseRadius = 12,
3535
- distanceFalloff = 1,
3536
- intensity = 1,
3537
- color,
3538
- renderMode = 0
3539
- }, ref) => {
3540
- const { camera, scene } = fiber.useThree();
3541
- const effect = React.useMemo(() => new $87431ee93b037844$export$2489f9981ab0fa82(scene, camera), []);
3542
- React.useLayoutEffect(() => {
3543
- fiber.applyProps(effect.configuration, {
3544
- color,
3545
- aoRadius,
3546
- distanceFalloff,
3547
- intensity,
3548
- aoSamples,
3549
- denoiseSamples,
3550
- denoiseRadius,
3551
- screenSpaceRadius,
3552
- renderMode,
3553
- halfRes,
3554
- depthAwareUpsampling
3555
- });
3556
- }, [
3557
- screenSpaceRadius,
3558
- color,
3559
- aoRadius,
3560
- distanceFalloff,
3561
- intensity,
3562
- aoSamples,
3563
- denoiseSamples,
3564
- denoiseRadius,
3565
- renderMode,
3566
- halfRes,
3567
- depthAwareUpsampling
3568
- ]);
3569
- React.useLayoutEffect(() => {
3570
- if (quality)
3571
- effect.setQualityMode(quality.charAt(0).toUpperCase() + quality.slice(1));
3572
- }, [quality]);
3573
- return /* @__PURE__ */ jsxRuntime.jsx("primitive", { ref, object: effect });
3574
- }
3575
- );
3576
- exports.ASCII = ASCII;
3577
- exports.Autofocus = Autofocus;
3578
- exports.Bloom = Bloom;
3579
- exports.BrightnessContrast = BrightnessContrast;
3580
- exports.ChromaticAberration = ChromaticAberration;
3581
- exports.ColorAverage = ColorAverage;
3582
- exports.ColorDepth = ColorDepth;
3583
- exports.Depth = Depth;
3584
- exports.DepthOfField = DepthOfField;
3585
- exports.DotScreen = DotScreen;
3586
- exports.EffectComposer = EffectComposer;
3587
- exports.EffectComposerContext = EffectComposerContext;
3588
- exports.FXAA = FXAA;
3589
- exports.Glitch = Glitch;
3590
- exports.GodRays = GodRays;
3591
- exports.Grid = Grid;
3592
- exports.HueSaturation = HueSaturation;
3593
- exports.LUT = LUT;
3594
- exports.LensFlare = LensFlare;
3595
- exports.LensFlareEffect = LensFlareEffect;
3596
- exports.N8AO = N8AO;
3597
- exports.Noise = Noise;
3598
- exports.Outline = Outline;
3599
- exports.Pixelation = Pixelation;
3600
- exports.SMAA = SMAA;
3601
- exports.SSAO = SSAO;
3602
- exports.SSR = SSR;
3603
- exports.Scanline = Scanline;
3604
- exports.Select = Select;
3605
- exports.Selection = Selection;
3606
- exports.SelectiveBloom = SelectiveBloom;
3607
- exports.Sepia = Sepia;
3608
- exports.ShockWave = ShockWave;
3609
- exports.Texture = Texture;
3610
- exports.TiltShift = TiltShift;
3611
- exports.TiltShift2 = TiltShift2;
3612
- exports.TiltShiftEffect = TiltShiftEffect;
3613
- exports.ToneMapping = ToneMapping;
3614
- exports.Vignette = Vignette;
3615
- exports.resolveRef = resolveRef;
3616
- exports.selectionContext = selectionContext;
3617
- exports.useVector2 = useVector2;
3618
- exports.wrapEffect = wrapEffect;
3
+ const Selection = require("./Selection.cjs");
4
+ const EffectComposer = require("./EffectComposer.cjs");
5
+ const util = require("./util.cjs");
6
+ const Autofocus = require("./effects/Autofocus.cjs");
7
+ const LensFlare = require("./effects/LensFlare.cjs");
8
+ const Bloom = require("./effects/Bloom.cjs");
9
+ const BrightnessContrast = require("./effects/BrightnessContrast.cjs");
10
+ const ChromaticAberration = require("./effects/ChromaticAberration.cjs");
11
+ const ColorAverage = require("./effects/ColorAverage.cjs");
12
+ const ColorDepth = require("./effects/ColorDepth.cjs");
13
+ const Depth = require("./effects/Depth.cjs");
14
+ const DepthOfField = require("./effects/DepthOfField.cjs");
15
+ const DotScreen = require("./effects/DotScreen.cjs");
16
+ const Glitch = require("./effects/Glitch.cjs");
17
+ const GodRays = require("./effects/GodRays.cjs");
18
+ const Grid = require("./effects/Grid.cjs");
19
+ const HueSaturation = require("./effects/HueSaturation.cjs");
20
+ const Noise = require("./effects/Noise.cjs");
21
+ const Outline = require("./effects/Outline.cjs");
22
+ const Pixelation = require("./effects/Pixelation.cjs");
23
+ const ScanlineEffect = require("./effects/ScanlineEffect.cjs");
24
+ const SelectiveBloom = require("./effects/SelectiveBloom.cjs");
25
+ const Sepia = require("./effects/Sepia.cjs");
26
+ const SSAO = require("./effects/SSAO.cjs");
27
+ const SMAA = require("./effects/SMAA.cjs");
28
+ const FXAA = require("./effects/FXAA.cjs");
29
+ const Texture = require("./effects/Texture.cjs");
30
+ const ToneMapping = require("./effects/ToneMapping.cjs");
31
+ const Vignette = require("./effects/Vignette.cjs");
32
+ const ShockWave = require("./effects/ShockWave.cjs");
33
+ const LUT = require("./effects/LUT.cjs");
34
+ const TiltShift = require("./effects/TiltShift.cjs");
35
+ const TiltShift2 = require("./effects/TiltShift2.cjs");
36
+ const ASCII = require("./effects/ASCII.cjs");
37
+ const index = require("./effects/SSR/index.cjs");
38
+ const N8AO = require("./effects/N8AO.cjs");
39
+ exports.Select = Selection.Select;
40
+ exports.Selection = Selection.Selection;
41
+ exports.selectionContext = Selection.selectionContext;
42
+ exports.EffectComposer = EffectComposer.EffectComposer;
43
+ exports.EffectComposerContext = EffectComposer.EffectComposerContext;
44
+ exports.resolveRef = util.resolveRef;
45
+ exports.useVector2 = util.useVector2;
46
+ exports.wrapEffect = util.wrapEffect;
47
+ exports.Autofocus = Autofocus.Autofocus;
48
+ exports.LensFlare = LensFlare.LensFlare;
49
+ exports.LensFlareEffect = LensFlare.LensFlareEffect;
50
+ exports.Bloom = Bloom.Bloom;
51
+ exports.BrightnessContrast = BrightnessContrast.BrightnessContrast;
52
+ exports.ChromaticAberration = ChromaticAberration.ChromaticAberration;
53
+ exports.ColorAverage = ColorAverage.ColorAverage;
54
+ exports.ColorDepth = ColorDepth.ColorDepth;
55
+ exports.Depth = Depth.Depth;
56
+ exports.DepthOfField = DepthOfField.DepthOfField;
57
+ exports.DotScreen = DotScreen.DotScreen;
58
+ exports.Glitch = Glitch.Glitch;
59
+ exports.GodRays = GodRays.GodRays;
60
+ exports.Grid = Grid.Grid;
61
+ exports.HueSaturation = HueSaturation.HueSaturation;
62
+ exports.Noise = Noise.Noise;
63
+ exports.Outline = Outline.Outline;
64
+ exports.Pixelation = Pixelation.Pixelation;
65
+ exports.Scanline = ScanlineEffect.Scanline;
66
+ exports.SelectiveBloom = SelectiveBloom.SelectiveBloom;
67
+ exports.Sepia = Sepia.Sepia;
68
+ exports.SSAO = SSAO.SSAO;
69
+ exports.SMAA = SMAA.SMAA;
70
+ exports.FXAA = FXAA.FXAA;
71
+ exports.Texture = Texture.Texture;
72
+ exports.ToneMapping = ToneMapping.ToneMapping;
73
+ exports.Vignette = Vignette.Vignette;
74
+ exports.ShockWave = ShockWave.ShockWave;
75
+ exports.LUT = LUT.LUT;
76
+ exports.TiltShift = TiltShift.TiltShift;
77
+ exports.TiltShift2 = TiltShift2.TiltShift2;
78
+ exports.TiltShiftEffect = TiltShift2.TiltShiftEffect;
79
+ exports.ASCII = ASCII.ASCII;
80
+ exports.SSR = index.SSR;
81
+ exports.N8AO = N8AO.N8AO;
3619
82
  //# sourceMappingURL=index.cjs.map