@react-three/drei 11.0.0-alpha.6 → 11.0.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/core/index.d.mts +2 -2
- package/core/index.d.ts +2 -2
- package/index.d.mts +1 -1
- package/index.d.ts +1 -1
- package/native/index.d.mts +147 -307
- package/native/index.d.ts +147 -307
- package/native/index.mjs +771 -1552
- package/package.json +1 -1
- package/webgpu/chunks/inspector-runtime.mjs +112 -0
- package/webgpu/index.d.mts +214 -314
- package/webgpu/index.d.ts +214 -314
- package/webgpu/index.mjs +1052 -1565
package/webgpu/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { forwardRef, useImperativeHandle, useMemo, useEffect, useCallback, useRef, useLayoutEffect, useState, Fragment, createContext, useContext } from 'react';
|
|
3
|
-
import { useThree, useFrame, extend, createPortal, applyProps, useInstanceHandle, context as context$
|
|
3
|
+
import { useThree, useFrame, extend, createPortal, applyProps, useInstanceHandle, context as context$b, useLoader, addEffect, addAfterEffect } from '@react-three/fiber';
|
|
4
4
|
import * as THREE from 'three/webgpu';
|
|
5
5
|
import { MeshBasicNodeMaterial, RenderTarget, MeshPhongNodeMaterial, MeshNormalNodeMaterial, QuadMesh, MeshPhysicalNodeMaterial, Frustum, Matrix4, CubeRenderTarget, Line2NodeMaterial, Vector3, Vector4, Vector2, Color, InstancedInterleavedBuffer, InterleavedBufferAttribute, Object3D, HalfFloatType, CubeCamera as CubeCamera$1, EventDispatcher, Euler, Quaternion, MathUtils, TextureLoader, Texture as Texture$1, MeshLambertMaterial, DynamicDrawUsage, CatmullRomCurve3, CubicBezierCurve3, QuadraticBezierCurve3, Shape as Shape$1, CanvasTexture, PerspectiveCamera as PerspectiveCamera$1, OrthographicCamera as OrthographicCamera$1, REVISION, AudioListener, AudioLoader, AnimationMixer, BufferAttribute, Box3, Sphere as Sphere$1, InstancedBufferAttribute, DoubleSide, DepthTexture, DepthFormat, UnsignedShortType, CubeTextureLoader, DefaultLoadingManager, Ray, Raycaster, Camera, CubeReflectionMapping, EquirectangularReflectionMapping, Scene, RepeatWrapping, SpriteNodeMaterial, AdditiveBlending, ShadowNode, CylinderGeometry } from 'three/webgpu';
|
|
6
6
|
import { ArcballControls as ArcballControls$1 } from 'three/examples/jsm/controls/ArcballControls.js';
|
|
@@ -16,7 +16,7 @@ import { useGesture } from '@use-gesture/react';
|
|
|
16
16
|
import * as ReactDOM from 'react-dom/client';
|
|
17
17
|
import { TrackballControls as TrackballControls$1 } from 'three/examples/jsm/controls/TrackballControls.js';
|
|
18
18
|
import { SimplexNoise } from 'three/examples/jsm/math/SimplexNoise.js';
|
|
19
|
-
import { uniform, Fn, float, vec4, uniformTexture, uv, vec2 as vec2$2,
|
|
19
|
+
import { uniform, Fn, float, vec4, uniformTexture, uv, vec2 as vec2$2, Discard, materialReference, context as context$a, max, materialAlphaTest, sub, mix, output, positionWorld, mul, add, materialColor, negate, dot, refract, div, length, cross, select, vec3, normalize, normalWorld, cameraPosition, screenCoordinate, mx_fractal_noise_vec3, int, thickness, pow, roughness, Loop, ior, screenUV, screenSize, cameraProjectionMatrix, cameraViewMatrix, attenuationColor, attenuationDistance, diffuseColor, transmission, fract, sin, modelWorldMatrix, log, exp, DFGLUT, reflector, clamp, materialIOR, equirectUV, materialOpacity, reflect, smoothstep, round, distance, positionLocal, mx_noise_vec3, cos, mat3, normalLocal, attribute, modelViewMatrix, varying, min, frontFacing, fwidth, texture, abs, saturate, positionView, positionGeometry, reference, renderGroup, interleavedGradientNoise, vogelDiskSample, step } from 'three/tsl';
|
|
20
20
|
import { Line2 } from 'three/examples/jsm/lines/webgpu/Line2.js';
|
|
21
21
|
import { LineSegments2 } from 'three/examples/jsm/lines/webgpu/LineSegments2.js';
|
|
22
22
|
import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js';
|
|
@@ -51,43 +51,150 @@ import { shallow } from 'zustand/shallow';
|
|
|
51
51
|
import { hashBlur } from 'three/examples/jsm/tsl/display/hashBlur.js';
|
|
52
52
|
import PhysicalLightingModel from 'three/src/nodes/functions/PhysicalLightingModel.js';
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
function assignUniform(node, factory, v) {
|
|
55
|
+
const current = node.value;
|
|
56
|
+
if (v === null || v === void 0) {
|
|
57
|
+
if (current && current.isTexture) node.value = factory().value;
|
|
58
|
+
else node.value = v;
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (typeof current === "number") {
|
|
62
|
+
node.value = typeof v === "boolean" ? v ? 1 : 0 : v;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (typeof current === "boolean") {
|
|
66
|
+
node.value = !!v;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (current && typeof current === "object") {
|
|
70
|
+
if (typeof v === "object" && !Array.isArray(v)) {
|
|
71
|
+
node.value = v;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (Array.isArray(v) && typeof current.fromArray === "function") {
|
|
75
|
+
current.fromArray(v);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (current.isColor) {
|
|
79
|
+
current.set(v);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (typeof v === "number" && typeof current.setScalar === "function") {
|
|
83
|
+
current.setScalar(v);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
node.value = v;
|
|
88
|
+
}
|
|
89
|
+
function withUniforms(Base, table) {
|
|
90
|
+
const keys = Object.keys(table);
|
|
91
|
+
const factories = table;
|
|
92
|
+
let installed = false;
|
|
93
|
+
const install = (instance) => {
|
|
94
|
+
for (const key of keys) {
|
|
95
|
+
if (key.startsWith("_") || key in instance) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
`withUniforms: "${key}" is reserved on ${Base.name}. Read three's own node for it (materialOpacity, materialColor, materialReference(...)) instead of declaring a uniform named "${key}".`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
for (const key of keys) {
|
|
102
|
+
Object.defineProperty(Wrapped.prototype, key, {
|
|
103
|
+
get() {
|
|
104
|
+
return this._uniforms?.[key]?.value;
|
|
105
|
+
},
|
|
106
|
+
set(v) {
|
|
107
|
+
const node = this._uniforms?.[key];
|
|
108
|
+
if (node) assignUniform(node, factories[key], v);
|
|
109
|
+
},
|
|
110
|
+
enumerable: false,
|
|
111
|
+
configurable: true
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
installed = true;
|
|
115
|
+
};
|
|
116
|
+
const splitParameters = (args) => {
|
|
117
|
+
const params = args[0];
|
|
118
|
+
if (!params || typeof params !== "object" || Array.isArray(params)) return { args, own: null };
|
|
119
|
+
const own = {};
|
|
120
|
+
const rest = {};
|
|
121
|
+
let hasOwn = false;
|
|
122
|
+
for (const k in params) {
|
|
123
|
+
if (Object.prototype.hasOwnProperty.call(factories, k)) {
|
|
124
|
+
own[k] = params[k];
|
|
125
|
+
hasOwn = true;
|
|
126
|
+
} else rest[k] = params[k];
|
|
127
|
+
}
|
|
128
|
+
return hasOwn ? { args: [rest, ...args.slice(1)], own } : { args, own: null };
|
|
129
|
+
};
|
|
130
|
+
class Wrapped extends Base {
|
|
131
|
+
constructor(...args) {
|
|
132
|
+
const { args: baseArgs, own } = splitParameters(args);
|
|
133
|
+
super(...baseArgs);
|
|
134
|
+
if (!installed) install(this);
|
|
135
|
+
const nodes = {};
|
|
136
|
+
for (const key of keys) nodes[key] = factories[key]();
|
|
137
|
+
Object.defineProperty(this, "_uniforms", { value: nodes, enumerable: false, writable: false });
|
|
138
|
+
if (own) for (const key in own) this[key] = own[key];
|
|
139
|
+
}
|
|
140
|
+
get uniforms() {
|
|
141
|
+
return this._uniforms;
|
|
142
|
+
}
|
|
143
|
+
/** Copies values for inherited accessors that NodeMaterial.copy does not visit. */
|
|
144
|
+
copy(source) {
|
|
145
|
+
super.copy(source);
|
|
146
|
+
const from = source._uniforms;
|
|
147
|
+
if (!from) return this;
|
|
148
|
+
for (const key of keys) {
|
|
149
|
+
const value = from[key]?.value;
|
|
150
|
+
const node = this._uniforms[key];
|
|
151
|
+
const own = node.value;
|
|
152
|
+
if (value && value.isTexture) node.value = value;
|
|
153
|
+
else if (own && typeof own.copy === "function") own.copy(value);
|
|
154
|
+
else node.value = value;
|
|
155
|
+
}
|
|
156
|
+
return this;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return Wrapped;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
class DepthNodeMaterial extends withUniforms(MeshBasicNodeMaterial, {
|
|
163
|
+
/** Shadow strength, 1 = full darkening, 0 = none */
|
|
164
|
+
shadowOpacity: () => uniform(1)
|
|
165
|
+
}) {
|
|
56
166
|
constructor(opacity = 1) {
|
|
57
167
|
super();
|
|
58
|
-
this.
|
|
168
|
+
this.shadowOpacity = opacity;
|
|
59
169
|
this.depthTest = false;
|
|
60
170
|
this.depthWrite = false;
|
|
61
171
|
this._buildShader();
|
|
62
172
|
}
|
|
63
173
|
_buildShader() {
|
|
64
|
-
const
|
|
174
|
+
const { shadowOpacity } = this.uniforms;
|
|
65
175
|
this.colorNode = Fn(() => {
|
|
66
|
-
const shadowStrength =
|
|
176
|
+
const shadowStrength = shadowOpacity.mul(0.7);
|
|
67
177
|
const gray = float(1).sub(shadowStrength);
|
|
68
178
|
return vec4(gray, gray, gray, 1);
|
|
69
179
|
})();
|
|
70
180
|
}
|
|
71
|
-
set shadowOpacity(value) {
|
|
72
|
-
this._opacity.value = value;
|
|
73
|
-
}
|
|
74
181
|
}
|
|
75
|
-
class BlurNodeMaterial extends MeshBasicNodeMaterial {
|
|
76
|
-
|
|
77
|
-
|
|
182
|
+
class BlurNodeMaterial extends withUniforms(MeshBasicNodeMaterial, {
|
|
183
|
+
/** Texture to blur */
|
|
184
|
+
inputTexture: () => uniformTexture(new THREE.Texture()),
|
|
185
|
+
/** Per-tap UV offset */
|
|
186
|
+
blurAmount: () => uniform(0)
|
|
187
|
+
}) {
|
|
78
188
|
_direction;
|
|
79
189
|
constructor(direction = "horizontal") {
|
|
80
190
|
super();
|
|
81
|
-
this._inputTexture = uniformTexture(new THREE.Texture());
|
|
82
|
-
this._blurAmount = uniform(0);
|
|
83
191
|
this._direction = direction;
|
|
84
192
|
this.depthTest = false;
|
|
85
193
|
this.depthWrite = false;
|
|
86
194
|
this._buildShader();
|
|
87
195
|
}
|
|
88
196
|
_buildShader() {
|
|
89
|
-
const inputTex = this.
|
|
90
|
-
const blurAmountUniform = this._blurAmount;
|
|
197
|
+
const { inputTexture: inputTex, blurAmount: blurAmountUniform } = this.uniforms;
|
|
91
198
|
const isHorizontal = this._direction === "horizontal";
|
|
92
199
|
const weights = [0.051, 0.0918, 0.12245, 0.1531, 0.1633, 0.1531, 0.12245, 0.0918, 0.051];
|
|
93
200
|
this.colorNode = Fn(() => {
|
|
@@ -96,18 +203,12 @@ class BlurNodeMaterial extends MeshBasicNodeMaterial {
|
|
|
96
203
|
for (let i = 0; i < 9; i++) {
|
|
97
204
|
const offset = float(i - 4).mul(blurAmountUniform);
|
|
98
205
|
const sampleUV = isHorizontal ? texCoord.add(vec2$2(offset, 0)) : texCoord.add(vec2$2(0, offset));
|
|
99
|
-
const sampledColor =
|
|
206
|
+
const sampledColor = inputTex.sample(sampleUV);
|
|
100
207
|
result.addAssign(sampledColor.mul(weights[i]));
|
|
101
208
|
}
|
|
102
209
|
return result;
|
|
103
210
|
})();
|
|
104
211
|
}
|
|
105
|
-
set inputTexture(value) {
|
|
106
|
-
this._inputTexture.value = value;
|
|
107
|
-
}
|
|
108
|
-
set blurAmount(value) {
|
|
109
|
-
this._blurAmount.value = value;
|
|
110
|
-
}
|
|
111
212
|
}
|
|
112
213
|
const ContactShadows = /* @__PURE__ */ React.forwardRef(
|
|
113
214
|
({
|
|
@@ -242,9 +343,13 @@ const discardFragment = /* @__PURE__ */ Fn(() => {
|
|
|
242
343
|
Discard();
|
|
243
344
|
return vec4(0, 0, 0, 0);
|
|
244
345
|
});
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
346
|
+
class DiscardNodeMaterial extends MeshBasicNodeMaterial {
|
|
347
|
+
constructor() {
|
|
348
|
+
super();
|
|
349
|
+
this.fragmentNode = discardFragment();
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
const DiscardMaterial = /* @__PURE__ */ new DiscardNodeMaterial();
|
|
248
353
|
|
|
249
354
|
function isLight(object) {
|
|
250
355
|
return object.isLight;
|
|
@@ -255,105 +360,51 @@ function isGeometry$1(object) {
|
|
|
255
360
|
const accumulativeContext = /* @__PURE__ */ React.createContext(
|
|
256
361
|
null
|
|
257
362
|
);
|
|
258
|
-
class SoftShadowMaterialImpl extends MeshBasicNodeMaterial {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
363
|
+
class SoftShadowMaterialImpl extends withUniforms(MeshBasicNodeMaterial, {
|
|
364
|
+
/** Shadow color, black */
|
|
365
|
+
shadowColor: () => uniform(new THREE.Color()),
|
|
366
|
+
/** Colorblend, how much colors turn to black, 0 is black */
|
|
367
|
+
blend: () => uniform(2)
|
|
368
|
+
}) {
|
|
264
369
|
constructor() {
|
|
265
370
|
super();
|
|
266
|
-
this._color = uniform(new THREE.Color());
|
|
267
|
-
this._blend = uniform(2);
|
|
268
|
-
this._alphaTest = uniform(0.75);
|
|
269
|
-
this._opacity = uniform(0);
|
|
270
|
-
this._map = uniformTexture(new THREE.Texture());
|
|
271
371
|
this.transparent = true;
|
|
272
372
|
this.depthWrite = false;
|
|
373
|
+
this.opacity = 0;
|
|
374
|
+
this.alphaTest = 0.75;
|
|
375
|
+
this.map = new THREE.Texture();
|
|
376
|
+
this.alphaTestNode = float(0);
|
|
273
377
|
this._buildShader();
|
|
274
378
|
}
|
|
275
379
|
_buildShader() {
|
|
276
|
-
const
|
|
277
|
-
const
|
|
278
|
-
const alphaTestUniform = this._alphaTest;
|
|
279
|
-
const opacityUniform = this._opacity;
|
|
280
|
-
const mapTex = this._map;
|
|
380
|
+
const { shadowColor, blend } = this.uniforms;
|
|
381
|
+
const map = materialReference("map", "texture", this);
|
|
281
382
|
this.colorNode = Fn(() => {
|
|
282
|
-
const
|
|
283
|
-
const
|
|
284
|
-
const rgb = colorUniform.mul(sampled.r).mul(blendUniform);
|
|
383
|
+
const sampled = context$a(map, { getUV: () => uv() });
|
|
384
|
+
const rgb = shadowColor.mul(sampled.r).mul(blend);
|
|
285
385
|
const sum = sampled.r.add(sampled.g).add(sampled.b);
|
|
286
|
-
const alpha = max(float(0), float(1).sub(sum.div(
|
|
386
|
+
const alpha = max(float(0), float(1).sub(sum.div(materialAlphaTest)));
|
|
287
387
|
return vec4(rgb, alpha);
|
|
288
388
|
})();
|
|
289
389
|
}
|
|
290
|
-
get shadowColor() {
|
|
291
|
-
return this._color.value;
|
|
292
|
-
}
|
|
293
|
-
set shadowColor(v) {
|
|
294
|
-
if (v instanceof THREE.Color) {
|
|
295
|
-
this._color.value.copy(v);
|
|
296
|
-
} else {
|
|
297
|
-
this._color.value.set(v);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
get blend() {
|
|
301
|
-
return this._blend.value;
|
|
302
|
-
}
|
|
303
|
-
set blend(v) {
|
|
304
|
-
this._blend.value = v;
|
|
305
|
-
}
|
|
306
|
-
get alphaTest() {
|
|
307
|
-
return this._alphaTest.value;
|
|
308
|
-
}
|
|
309
|
-
set alphaTest(v) {
|
|
310
|
-
this._alphaTest.value = v;
|
|
311
|
-
}
|
|
312
|
-
get opacity() {
|
|
313
|
-
return this._opacity.value;
|
|
314
|
-
}
|
|
315
|
-
set opacity(v) {
|
|
316
|
-
if (!this._opacity) this._opacity = uniform(v);
|
|
317
|
-
else this._opacity.value = v;
|
|
318
|
-
}
|
|
319
|
-
get map() {
|
|
320
|
-
if (!this._map) {
|
|
321
|
-
this._map = uniformTexture(new THREE.Texture());
|
|
322
|
-
}
|
|
323
|
-
return this._map.value;
|
|
324
|
-
}
|
|
325
|
-
set map(v) {
|
|
326
|
-
this._map.value = v;
|
|
327
|
-
}
|
|
328
390
|
}
|
|
329
|
-
class ProgressiveShadowMaterial extends MeshPhongNodeMaterial {
|
|
330
|
-
|
|
331
|
-
|
|
391
|
+
class ProgressiveShadowMaterial extends withUniforms(MeshPhongNodeMaterial, {
|
|
392
|
+
/** Accumulation buffer from the previous frame, blended with the current shading */
|
|
393
|
+
previousShadowMap: () => uniformTexture(new THREE.Texture()),
|
|
394
|
+
/** Mix 1/averagingWindow of the new shading into the accumulated frames */
|
|
395
|
+
averagingWindow: () => uniform(100)
|
|
396
|
+
}) {
|
|
332
397
|
constructor(initialTexture) {
|
|
333
398
|
super();
|
|
334
|
-
this.
|
|
335
|
-
this._averagingWindow = uniform(100);
|
|
399
|
+
this.previousShadowMap = initialTexture;
|
|
336
400
|
this.fog = false;
|
|
337
401
|
this._buildShader();
|
|
338
402
|
}
|
|
339
403
|
_buildShader() {
|
|
340
|
-
const
|
|
341
|
-
const averagingWindowUniform = this._averagingWindow;
|
|
404
|
+
const { previousShadowMap, averagingWindow } = this.uniforms;
|
|
342
405
|
const uvNode = uv();
|
|
343
406
|
this.vertexNode = vec4(sub(uvNode, vec2$2(0.5)).mul(2), 1, 1);
|
|
344
|
-
this.outputNode = vec4(mix(
|
|
345
|
-
}
|
|
346
|
-
get previousShadowMap() {
|
|
347
|
-
return this._previousShadowMap.value;
|
|
348
|
-
}
|
|
349
|
-
set previousShadowMap(v) {
|
|
350
|
-
this._previousShadowMap.value = v;
|
|
351
|
-
}
|
|
352
|
-
get averagingWindow() {
|
|
353
|
-
return this._averagingWindow.value;
|
|
354
|
-
}
|
|
355
|
-
set averagingWindow(v) {
|
|
356
|
-
this._averagingWindow.value = v;
|
|
407
|
+
this.outputNode = vec4(mix(previousShadowMap.sample(uv()), output, float(1).div(averagingWindow)));
|
|
357
408
|
}
|
|
358
409
|
}
|
|
359
410
|
class ProgressiveLightMap {
|
|
@@ -470,7 +521,7 @@ const AccumulativeShadows = /* @__PURE__ */ React.forwardRef(
|
|
|
470
521
|
plm.configure(gPlane.current);
|
|
471
522
|
}, [plm]);
|
|
472
523
|
React.useEffect(() => {
|
|
473
|
-
softShadowMat.shadowColor
|
|
524
|
+
softShadowMat.shadowColor.set(color);
|
|
474
525
|
softShadowMat.blend = colorBlend;
|
|
475
526
|
softShadowMat.map = plm.progressiveLightMap2.texture;
|
|
476
527
|
softShadowMat.toneMapped = toneMapped;
|
|
@@ -683,19 +734,18 @@ const Edges = /* @__PURE__ */ React.forwardRef(
|
|
|
683
734
|
}
|
|
684
735
|
);
|
|
685
736
|
|
|
686
|
-
class CausticsProjectionMaterial extends MeshBasicNodeMaterial {
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
737
|
+
class CausticsProjectionMaterial extends withUniforms(MeshBasicNodeMaterial, {
|
|
738
|
+
/** Front-face caustics, rendered by CausticsMaterial */
|
|
739
|
+
causticsTexture: () => uniformTexture(new THREE.Texture()),
|
|
740
|
+
/** Back-face caustics, rendered by CausticsMaterial when `backside` is enabled */
|
|
741
|
+
causticsTextureB: () => uniformTexture(new THREE.Texture()),
|
|
742
|
+
/** Projection matrix of the light camera */
|
|
743
|
+
lightProjMatrix: () => uniform(new THREE.Matrix4()),
|
|
744
|
+
/** View matrix (matrixWorldInverse) of the light camera */
|
|
745
|
+
lightViewMatrix: () => uniform(new THREE.Matrix4())
|
|
746
|
+
}) {
|
|
692
747
|
constructor() {
|
|
693
748
|
super();
|
|
694
|
-
this._causticsTexture = uniformTexture(new THREE.Texture());
|
|
695
|
-
this._causticsTextureB = uniformTexture(new THREE.Texture());
|
|
696
|
-
this._color = uniform(new THREE.Color(1, 1, 1));
|
|
697
|
-
this._lightProjMatrix = uniform(new THREE.Matrix4());
|
|
698
|
-
this._lightViewMatrix = uniform(new THREE.Matrix4());
|
|
699
749
|
this.transparent = true;
|
|
700
750
|
this.blending = THREE.CustomBlending;
|
|
701
751
|
this.blendSrc = THREE.OneFactor;
|
|
@@ -704,100 +754,68 @@ class CausticsProjectionMaterial extends MeshBasicNodeMaterial {
|
|
|
704
754
|
this._buildShader();
|
|
705
755
|
}
|
|
706
756
|
_buildShader() {
|
|
707
|
-
const causticsTexture = this.
|
|
708
|
-
const causticsTextureB = this._causticsTextureB;
|
|
709
|
-
const colorUniform = this._color;
|
|
710
|
-
const lightProjMatrix = this._lightProjMatrix;
|
|
711
|
-
const lightViewMatrix = this._lightViewMatrix;
|
|
757
|
+
const { causticsTexture, causticsTextureB, lightProjMatrix, lightViewMatrix } = this.uniforms;
|
|
712
758
|
this.colorNode = Fn(() => {
|
|
713
759
|
const worldPos = positionWorld;
|
|
714
760
|
const worldPos4 = vec4(worldPos, 1);
|
|
715
761
|
const lightSpacePos = mul(lightProjMatrix, mul(lightViewMatrix, worldPos4)).toVar();
|
|
716
762
|
const xyz = lightSpacePos.xyz.div(lightSpacePos.w);
|
|
717
763
|
const lightUv = xyz.mul(0.5).add(0.5).xy;
|
|
718
|
-
const front =
|
|
719
|
-
const back =
|
|
720
|
-
return vec4(add(front, back).mul(
|
|
764
|
+
const front = causticsTexture.sample(lightUv).rgb;
|
|
765
|
+
const back = causticsTextureB.sample(lightUv).rgb;
|
|
766
|
+
return vec4(add(front, back).mul(materialColor), 1);
|
|
721
767
|
})();
|
|
722
768
|
}
|
|
723
|
-
//* Uniform Accessors ==============================
|
|
724
|
-
get causticsTexture() {
|
|
725
|
-
return this._causticsTexture.value;
|
|
726
|
-
}
|
|
727
|
-
set causticsTexture(v) {
|
|
728
|
-
this._causticsTexture.value = v;
|
|
729
|
-
}
|
|
730
|
-
get causticsTextureB() {
|
|
731
|
-
return this._causticsTextureB.value;
|
|
732
|
-
}
|
|
733
|
-
set causticsTextureB(v) {
|
|
734
|
-
this._causticsTextureB.value = v;
|
|
735
|
-
}
|
|
736
|
-
get color() {
|
|
737
|
-
return this._color?.value;
|
|
738
|
-
}
|
|
739
|
-
set color(v) {
|
|
740
|
-
if (this._color) this._color.value = v;
|
|
741
|
-
}
|
|
742
|
-
get lightProjMatrix() {
|
|
743
|
-
return this._lightProjMatrix.value;
|
|
744
|
-
}
|
|
745
|
-
set lightProjMatrix(v) {
|
|
746
|
-
this._lightProjMatrix.value = v;
|
|
747
|
-
}
|
|
748
|
-
get lightViewMatrix() {
|
|
749
|
-
return this._lightViewMatrix.value;
|
|
750
|
-
}
|
|
751
|
-
set lightViewMatrix(v) {
|
|
752
|
-
this._lightViewMatrix.value = v;
|
|
753
|
-
}
|
|
754
769
|
}
|
|
755
|
-
class CausticsMaterial extends MeshBasicNodeMaterial {
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
+
class CausticsMaterial extends withUniforms(MeshBasicNodeMaterial, {
|
|
771
|
+
/** World matrix of the light camera */
|
|
772
|
+
cameraMatrixWorld: () => uniform(new THREE.Matrix4()),
|
|
773
|
+
/** Inverse projection matrix of the light camera, for depth reconstruction */
|
|
774
|
+
cameraProjectionMatrixInv: () => uniform(new THREE.Matrix4()),
|
|
775
|
+
/** World-space normals of the refractive geometry, rendered by CausticsNormalMaterial */
|
|
776
|
+
normalTexture: () => uniformTexture(new THREE.Texture()),
|
|
777
|
+
/** Depth of the refractive geometry, from the same render target as `normalTexture` */
|
|
778
|
+
depthTexture: () => uniformTexture(new THREE.Texture()),
|
|
779
|
+
/** Direction light travels in (inverse of the light position direction) */
|
|
780
|
+
lightDir: () => uniform(new THREE.Vector3(0, 1, 0)),
|
|
781
|
+
/** Normal of the receiving plane in light space */
|
|
782
|
+
lightPlaneNormal: () => uniform(new THREE.Vector3(0, 1, 0)),
|
|
783
|
+
/** Plane constant of the receiving plane */
|
|
784
|
+
lightPlaneConstant: () => uniform(0),
|
|
785
|
+
/** Light camera near plane */
|
|
786
|
+
near: () => uniform(0.1),
|
|
787
|
+
/** Light camera far plane */
|
|
788
|
+
far: () => uniform(100),
|
|
789
|
+
/** The texel size in world units */
|
|
790
|
+
worldRadius: () => uniform(1 / 40),
|
|
791
|
+
/** Refraction index of the surface */
|
|
792
|
+
ior: () => uniform(1.1),
|
|
793
|
+
/** Buffer resolution in pixels */
|
|
794
|
+
resolution: () => uniform(1024),
|
|
795
|
+
/** Half-extent of the light camera frustum */
|
|
796
|
+
size: () => uniform(10),
|
|
797
|
+
/** Intensity of the projected caustics */
|
|
798
|
+
intensity: () => uniform(0.5)
|
|
799
|
+
}) {
|
|
770
800
|
constructor() {
|
|
771
801
|
super();
|
|
772
|
-
this._cameraMatrixWorld = uniform(new THREE.Matrix4());
|
|
773
|
-
this._cameraProjectionMatrixInv = uniform(new THREE.Matrix4());
|
|
774
|
-
this._normalTexture = uniformTexture(new THREE.Texture());
|
|
775
|
-
this._depthTexture = uniformTexture(new THREE.Texture());
|
|
776
|
-
this._lightDir = uniform(new THREE.Vector3(0, 1, 0));
|
|
777
|
-
this._lightPlaneNormal = uniform(new THREE.Vector3(0, 1, 0));
|
|
778
|
-
this._lightPlaneConstant = uniform(0);
|
|
779
|
-
this._near = uniform(0.1);
|
|
780
|
-
this._far = uniform(100);
|
|
781
|
-
this._worldRadius = uniform(1 / 40);
|
|
782
|
-
this._ior = uniform(1.1);
|
|
783
|
-
this._resolution = uniform(1024);
|
|
784
|
-
this._size = uniform(10);
|
|
785
|
-
this._intensity = uniform(0.5);
|
|
786
802
|
this._buildShader();
|
|
787
803
|
}
|
|
788
804
|
_buildShader() {
|
|
789
|
-
const
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
805
|
+
const {
|
|
806
|
+
cameraMatrixWorld,
|
|
807
|
+
cameraProjectionMatrixInv,
|
|
808
|
+
normalTexture,
|
|
809
|
+
depthTexture,
|
|
810
|
+
lightDir,
|
|
811
|
+
lightPlaneNormal,
|
|
812
|
+
lightPlaneConstant,
|
|
813
|
+
worldRadius,
|
|
814
|
+
ior,
|
|
815
|
+
resolution,
|
|
816
|
+
size,
|
|
817
|
+
intensity
|
|
818
|
+
} = this.uniforms;
|
|
801
819
|
const worldPosFromDepth = Fn(({ depth, coord }) => {
|
|
802
820
|
const z = depth.mul(2).sub(1);
|
|
803
821
|
const clipSpacePos = vec4(coord.mul(2).sub(1), z, 1);
|
|
@@ -824,7 +842,7 @@ class CausticsMaterial extends MeshBasicNodeMaterial {
|
|
|
824
842
|
);
|
|
825
843
|
this.colorNode = Fn(() => {
|
|
826
844
|
const baseUv = uv();
|
|
827
|
-
const centerDepth =
|
|
845
|
+
const centerDepth = depthTexture.sample(baseUv).x;
|
|
828
846
|
const causticTexelSize = div(float(1), resolution).mul(size).mul(2);
|
|
829
847
|
const texelsNeeded = div(worldRadius, causticTexelSize);
|
|
830
848
|
const sampleRadius = div(texelsNeeded, resolution);
|
|
@@ -836,14 +854,14 @@ class CausticsMaterial extends MeshBasicNodeMaterial {
|
|
|
836
854
|
const uv2 = add(baseUv, mul(offset2, sampleRadius));
|
|
837
855
|
const uv3 = add(baseUv, mul(offset3, sampleRadius));
|
|
838
856
|
const uv4 = add(baseUv, mul(offset4, sampleRadius));
|
|
839
|
-
const normal1 = sub(mul(
|
|
840
|
-
const normal2 = sub(mul(
|
|
841
|
-
const normal3 = sub(mul(
|
|
842
|
-
const normal4 = sub(mul(
|
|
843
|
-
const depth1 =
|
|
844
|
-
const depth2 =
|
|
845
|
-
const depth3 =
|
|
846
|
-
const depth4 =
|
|
857
|
+
const normal1 = sub(mul(normalTexture.sample(uv1).rgb, 2), 1);
|
|
858
|
+
const normal2 = sub(mul(normalTexture.sample(uv2).rgb, 2), 1);
|
|
859
|
+
const normal3 = sub(mul(normalTexture.sample(uv3).rgb, 2), 1);
|
|
860
|
+
const normal4 = sub(mul(normalTexture.sample(uv4).rgb, 2), 1);
|
|
861
|
+
const depth1 = depthTexture.sample(uv1).x;
|
|
862
|
+
const depth2 = depthTexture.sample(uv2).x;
|
|
863
|
+
const depth3 = depthTexture.sample(uv3).x;
|
|
864
|
+
const depth4 = depthTexture.sample(uv4).x;
|
|
847
865
|
const pos1 = worldPosFromDepth({ depth: depth1, coord: uv1 });
|
|
848
866
|
const pos2 = worldPosFromDepth({ depth: depth2, coord: uv2 });
|
|
849
867
|
const pos3 = worldPosFromDepth({ depth: depth3, coord: uv3 });
|
|
@@ -882,91 +900,6 @@ class CausticsMaterial extends MeshBasicNodeMaterial {
|
|
|
882
900
|
return vec4(vec3(finalCaustic), 1);
|
|
883
901
|
})();
|
|
884
902
|
}
|
|
885
|
-
//* Uniform Accessors ==============================
|
|
886
|
-
get cameraMatrixWorld() {
|
|
887
|
-
return this._cameraMatrixWorld.value;
|
|
888
|
-
}
|
|
889
|
-
set cameraMatrixWorld(v) {
|
|
890
|
-
this._cameraMatrixWorld.value = v;
|
|
891
|
-
}
|
|
892
|
-
get cameraProjectionMatrixInv() {
|
|
893
|
-
return this._cameraProjectionMatrixInv.value;
|
|
894
|
-
}
|
|
895
|
-
set cameraProjectionMatrixInv(v) {
|
|
896
|
-
this._cameraProjectionMatrixInv.value = v;
|
|
897
|
-
}
|
|
898
|
-
get normalTexture() {
|
|
899
|
-
return this._normalTexture.value;
|
|
900
|
-
}
|
|
901
|
-
set normalTexture(v) {
|
|
902
|
-
this._normalTexture.value = v ?? new THREE.Texture();
|
|
903
|
-
}
|
|
904
|
-
get depthTexture() {
|
|
905
|
-
return this._depthTexture.value;
|
|
906
|
-
}
|
|
907
|
-
set depthTexture(v) {
|
|
908
|
-
this._depthTexture.value = v ?? new THREE.Texture();
|
|
909
|
-
}
|
|
910
|
-
get lightDir() {
|
|
911
|
-
return this._lightDir.value;
|
|
912
|
-
}
|
|
913
|
-
set lightDir(v) {
|
|
914
|
-
this._lightDir.value = v;
|
|
915
|
-
}
|
|
916
|
-
get lightPlaneNormal() {
|
|
917
|
-
return this._lightPlaneNormal.value;
|
|
918
|
-
}
|
|
919
|
-
set lightPlaneNormal(v) {
|
|
920
|
-
this._lightPlaneNormal.value = v;
|
|
921
|
-
}
|
|
922
|
-
get lightPlaneConstant() {
|
|
923
|
-
return this._lightPlaneConstant.value;
|
|
924
|
-
}
|
|
925
|
-
set lightPlaneConstant(v) {
|
|
926
|
-
this._lightPlaneConstant.value = v;
|
|
927
|
-
}
|
|
928
|
-
get near() {
|
|
929
|
-
return this._near.value;
|
|
930
|
-
}
|
|
931
|
-
set near(v) {
|
|
932
|
-
this._near.value = v;
|
|
933
|
-
}
|
|
934
|
-
get far() {
|
|
935
|
-
return this._far.value;
|
|
936
|
-
}
|
|
937
|
-
set far(v) {
|
|
938
|
-
this._far.value = v;
|
|
939
|
-
}
|
|
940
|
-
get worldRadius() {
|
|
941
|
-
return this._worldRadius.value;
|
|
942
|
-
}
|
|
943
|
-
set worldRadius(v) {
|
|
944
|
-
this._worldRadius.value = v;
|
|
945
|
-
}
|
|
946
|
-
get ior() {
|
|
947
|
-
return this._ior.value;
|
|
948
|
-
}
|
|
949
|
-
set ior(v) {
|
|
950
|
-
this._ior.value = v;
|
|
951
|
-
}
|
|
952
|
-
get resolution() {
|
|
953
|
-
return this._resolution.value;
|
|
954
|
-
}
|
|
955
|
-
set resolution(v) {
|
|
956
|
-
this._resolution.value = v;
|
|
957
|
-
}
|
|
958
|
-
get size() {
|
|
959
|
-
return this._size.value;
|
|
960
|
-
}
|
|
961
|
-
set size(v) {
|
|
962
|
-
this._size.value = v;
|
|
963
|
-
}
|
|
964
|
-
get intensity() {
|
|
965
|
-
return this._intensity.value;
|
|
966
|
-
}
|
|
967
|
-
set intensity(v) {
|
|
968
|
-
this._intensity.value = v;
|
|
969
|
-
}
|
|
970
903
|
}
|
|
971
904
|
class CausticsNormalMaterial extends MeshNormalNodeMaterial {
|
|
972
905
|
constructor(side = THREE.FrontSide) {
|
|
@@ -977,18 +910,6 @@ class CausticsNormalMaterial extends MeshNormalNodeMaterial {
|
|
|
977
910
|
})();
|
|
978
911
|
}
|
|
979
912
|
}
|
|
980
|
-
const NORMAL_FBO_PROPS = {
|
|
981
|
-
depthBuffer: true,
|
|
982
|
-
minFilter: THREE.LinearFilter,
|
|
983
|
-
magFilter: THREE.LinearFilter,
|
|
984
|
-
type: THREE.UnsignedByteType
|
|
985
|
-
};
|
|
986
|
-
const CAUSTIC_FBO_PROPS = {
|
|
987
|
-
minFilter: THREE.LinearMipmapLinearFilter,
|
|
988
|
-
magFilter: THREE.LinearFilter,
|
|
989
|
-
type: THREE.FloatType,
|
|
990
|
-
generateMipmaps: true
|
|
991
|
-
};
|
|
992
913
|
const Caustics = /* @__PURE__ */ React.forwardRef(
|
|
993
914
|
({
|
|
994
915
|
debug,
|
|
@@ -1012,10 +933,30 @@ const Caustics = /* @__PURE__ */ React.forwardRef(
|
|
|
1012
933
|
const plane = React.useRef(null);
|
|
1013
934
|
const gl = useThree((state) => state.gl);
|
|
1014
935
|
const helper = useHelper(debug && camera, THREE.CameraHelper);
|
|
1015
|
-
const normalTarget = useFBO(resolution, resolution,
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
936
|
+
const normalTarget = useFBO(resolution, resolution, {
|
|
937
|
+
depthBuffer: true,
|
|
938
|
+
minFilter: THREE.LinearFilter,
|
|
939
|
+
magFilter: THREE.LinearFilter,
|
|
940
|
+
type: THREE.UnsignedByteType
|
|
941
|
+
});
|
|
942
|
+
const normalTargetB = useFBO(resolution, resolution, {
|
|
943
|
+
depthBuffer: true,
|
|
944
|
+
minFilter: THREE.LinearFilter,
|
|
945
|
+
magFilter: THREE.LinearFilter,
|
|
946
|
+
type: THREE.UnsignedByteType
|
|
947
|
+
});
|
|
948
|
+
const causticsTarget = useFBO(resolution, resolution, {
|
|
949
|
+
minFilter: THREE.LinearMipmapLinearFilter,
|
|
950
|
+
magFilter: THREE.LinearFilter,
|
|
951
|
+
type: THREE.FloatType,
|
|
952
|
+
generateMipmaps: true
|
|
953
|
+
});
|
|
954
|
+
const causticsTargetB = useFBO(resolution, resolution, {
|
|
955
|
+
minFilter: THREE.LinearMipmapLinearFilter,
|
|
956
|
+
magFilter: THREE.LinearFilter,
|
|
957
|
+
type: THREE.FloatType,
|
|
958
|
+
generateMipmaps: true
|
|
959
|
+
});
|
|
1019
960
|
const [normalMat] = React.useState(() => new CausticsNormalMaterial(THREE.FrontSide));
|
|
1020
961
|
const [normalMatB] = React.useState(() => new CausticsNormalMaterial(THREE.BackSide));
|
|
1021
962
|
const [causticsMaterial] = React.useState(() => new CausticsMaterial());
|
|
@@ -1287,9 +1228,9 @@ class TransmissionLightingModel extends PhysicalLightingModel {
|
|
|
1287
1228
|
const uvR = getRefractionUV(sampleNorm, v, iorR, sampleThickness, position);
|
|
1288
1229
|
const uvG = getRefractionUV(sampleNorm, v, iorG, sampleThickness, position);
|
|
1289
1230
|
const uvB = getRefractionUV(sampleNorm, v, iorB, sampleThickness, position);
|
|
1290
|
-
const sampleR =
|
|
1291
|
-
const sampleG =
|
|
1292
|
-
const sampleB =
|
|
1231
|
+
const sampleR = bufferTex.sample(uvR);
|
|
1232
|
+
const sampleG = bufferTex.sample(uvG);
|
|
1233
|
+
const sampleB = bufferTex.sample(uvB);
|
|
1293
1234
|
transmissionAccum.x.addAssign(sampleR.r);
|
|
1294
1235
|
transmissionAccum.y.addAssign(sampleG.g);
|
|
1295
1236
|
transmissionAccum.z.addAssign(sampleB.b);
|
|
@@ -1299,7 +1240,7 @@ class TransmissionLightingModel extends PhysicalLightingModel {
|
|
|
1299
1240
|
const debugNdotV = n.dot(v);
|
|
1300
1241
|
const isNeg = debugNdotV.lessThan(0);
|
|
1301
1242
|
const sampleUVFlipped = vec2$2(screenUV.x, screenUV.y.oneMinus()).clamp(1e-3, 0.999);
|
|
1302
|
-
const directSampleFlipped =
|
|
1243
|
+
const directSampleFlipped = bufferTex.sample(sampleUVFlipped);
|
|
1303
1244
|
const testRay = getVolumeTransmissionRay(n, v, thickness, ior);
|
|
1304
1245
|
const rayLen = length(testRay);
|
|
1305
1246
|
const manualUV = screenCoordinate.xy.div(screenSize);
|
|
@@ -1307,9 +1248,9 @@ class TransmissionLightingModel extends PhysicalLightingModel {
|
|
|
1307
1248
|
const flippedUV = vec2$2(screenUV.x, screenUV.y.oneMinus()).clamp(1e-3, 0.999);
|
|
1308
1249
|
const useFlipped = screenUV.x.greaterThan(0.5);
|
|
1309
1250
|
const splitSampleUV = select(useFlipped, flippedUV, noFlipUV);
|
|
1310
|
-
const splitSample =
|
|
1311
|
-
const directSampleNoFlip =
|
|
1312
|
-
const centerSample =
|
|
1251
|
+
const splitSample = bufferTex.sample(splitSampleUV);
|
|
1252
|
+
const directSampleNoFlip = bufferTex.sample(screenUV.clamp(1e-3, 0.999));
|
|
1253
|
+
const centerSample = bufferTex.sample(vec2$2(0.5, 0.5));
|
|
1313
1254
|
const transmissionRayDbg = getVolumeTransmissionRay(n, v, thickness, ior);
|
|
1314
1255
|
const refractedRayExitDbg = position.add(transmissionRayDbg);
|
|
1315
1256
|
const ndcPosDbg = cameraProjectionMatrix.mul(cameraViewMatrix.mul(vec4(refractedRayExitDbg, 1)));
|
|
@@ -1326,7 +1267,7 @@ class TransmissionLightingModel extends PhysicalLightingModel {
|
|
|
1326
1267
|
projUVDbg.divAssign(2);
|
|
1327
1268
|
projUVDbg.assign(vec2$2(projUVDbg.x, projUVDbg.y.oneMinus()));
|
|
1328
1269
|
projUVDbg.assign(projUVDbg.clamp(1e-3, 0.999));
|
|
1329
|
-
const projectedSample =
|
|
1270
|
+
const projectedSample = bufferTex.sample(projUVDbg);
|
|
1330
1271
|
const wNorm = clipPosDbg.w.div(10).add(0.5).clamp(0, 1);
|
|
1331
1272
|
const isBehind = clipPosDbg.w.lessThan(0);
|
|
1332
1273
|
const rawNdcX = clipPosDbg.x.div(safeWDbg2);
|
|
@@ -1449,18 +1390,29 @@ class TransmissionLightingModel extends PhysicalLightingModel {
|
|
|
1449
1390
|
}
|
|
1450
1391
|
}
|
|
1451
1392
|
}
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1393
|
+
function createPlaceholderTexture() {
|
|
1394
|
+
const placeholder = new THREE.DataTexture(new Uint8Array([255, 255, 255, 255]), 1, 1);
|
|
1395
|
+
placeholder.needsUpdate = true;
|
|
1396
|
+
return placeholder;
|
|
1397
|
+
}
|
|
1398
|
+
class MeshTransmissionMaterialImpl extends withUniforms(MeshPhysicalNodeMaterial, {
|
|
1399
|
+
/** Chromatic aberration, default: 0.05 */
|
|
1400
|
+
chromaticAberration: () => uniform(0.05),
|
|
1401
|
+
/** Anisotropic blur, default: 0.1 */
|
|
1402
|
+
anisotropicBlur: () => uniform(0.1),
|
|
1403
|
+
/** Elapsed time, drives the temporal distortion */
|
|
1404
|
+
time: () => uniform(0),
|
|
1405
|
+
/** Distortion, default: 0 */
|
|
1406
|
+
distortion: () => uniform(0),
|
|
1407
|
+
/** Distortion scale, default: 0.5 */
|
|
1408
|
+
distortionScale: () => uniform(0.5),
|
|
1409
|
+
/** Temporal distortion (speed of movement), default: 0 */
|
|
1410
|
+
temporalDistortion: () => uniform(0),
|
|
1411
|
+
/** The scene rendered into a texture (use it to share a texture between materials) */
|
|
1412
|
+
buffer: () => uniformTexture(createPlaceholderTexture()),
|
|
1413
|
+
/** Debug mode for development (0 = normal, 1-19 = various debug outputs), default: 0 */
|
|
1414
|
+
debugMode: () => uniform(0)
|
|
1415
|
+
}) {
|
|
1464
1416
|
/** Type flag for identification */
|
|
1465
1417
|
isMeshTransmissionMaterial = true;
|
|
1466
1418
|
_samples;
|
|
@@ -1469,27 +1421,26 @@ class MeshTransmissionMaterialImpl extends MeshPhysicalNodeMaterial {
|
|
|
1469
1421
|
super();
|
|
1470
1422
|
this._samples = samples;
|
|
1471
1423
|
this._transmissionSampler = transmissionSampler;
|
|
1472
|
-
this.
|
|
1473
|
-
this._anisotropicBlur = uniform(0.1);
|
|
1474
|
-
this._time = uniform(0);
|
|
1475
|
-
this._distortion = uniform(0);
|
|
1476
|
-
this._distortionScale = uniform(0.5);
|
|
1477
|
-
this._temporalDistortion = uniform(0);
|
|
1478
|
-
this._debugMode = uniform(0);
|
|
1479
|
-
const placeholderTexture = new THREE.DataTexture(new Uint8Array([255, 255, 255, 255]), 1, 1);
|
|
1480
|
-
placeholderTexture.needsUpdate = true;
|
|
1481
|
-
this._buffer = uniformTexture(placeholderTexture);
|
|
1482
|
-
this._transmissionValue = uniform(1);
|
|
1483
|
-
this.transmission = transmissionSampler ? 1 : 1e-3;
|
|
1424
|
+
this.transmission = 1;
|
|
1484
1425
|
this.roughness = 0;
|
|
1485
1426
|
this.thickness = 0;
|
|
1486
1427
|
this.ior = 1.5;
|
|
1487
1428
|
this.transparent = true;
|
|
1488
1429
|
}
|
|
1489
1430
|
setupLightingModel() {
|
|
1490
|
-
if (this._transmissionSampler) {
|
|
1431
|
+
if (this._transmissionSampler || !this.useTransmission) {
|
|
1491
1432
|
return super.setupLightingModel();
|
|
1492
1433
|
}
|
|
1434
|
+
const {
|
|
1435
|
+
buffer,
|
|
1436
|
+
chromaticAberration,
|
|
1437
|
+
anisotropicBlur,
|
|
1438
|
+
time,
|
|
1439
|
+
distortion,
|
|
1440
|
+
distortionScale,
|
|
1441
|
+
temporalDistortion,
|
|
1442
|
+
debugMode
|
|
1443
|
+
} = this.uniforms;
|
|
1493
1444
|
return new TransmissionLightingModel(
|
|
1494
1445
|
{
|
|
1495
1446
|
clearcoat: this.useClearcoat,
|
|
@@ -1499,82 +1450,18 @@ class MeshTransmissionMaterialImpl extends MeshPhysicalNodeMaterial {
|
|
|
1499
1450
|
dispersion: this.useDispersion
|
|
1500
1451
|
},
|
|
1501
1452
|
{
|
|
1502
|
-
bufferTex:
|
|
1503
|
-
chromaticAberration
|
|
1504
|
-
anisotropicBlur
|
|
1505
|
-
timeUniform:
|
|
1506
|
-
distortion
|
|
1507
|
-
distortionScale
|
|
1508
|
-
temporalDistortion
|
|
1453
|
+
bufferTex: buffer,
|
|
1454
|
+
chromaticAberration,
|
|
1455
|
+
anisotropicBlur,
|
|
1456
|
+
timeUniform: time,
|
|
1457
|
+
distortion,
|
|
1458
|
+
distortionScale,
|
|
1459
|
+
temporalDistortion,
|
|
1509
1460
|
samples: this._samples,
|
|
1510
|
-
debugMode
|
|
1461
|
+
debugMode
|
|
1511
1462
|
}
|
|
1512
1463
|
);
|
|
1513
1464
|
}
|
|
1514
|
-
//* Property Accessors ==============================
|
|
1515
|
-
get time() {
|
|
1516
|
-
return this._time.value;
|
|
1517
|
-
}
|
|
1518
|
-
set time(v) {
|
|
1519
|
-
this._time.value = v;
|
|
1520
|
-
}
|
|
1521
|
-
get buffer() {
|
|
1522
|
-
return this._buffer.value;
|
|
1523
|
-
}
|
|
1524
|
-
set buffer(v) {
|
|
1525
|
-
this._buffer.value = v;
|
|
1526
|
-
}
|
|
1527
|
-
get chromaticAberration() {
|
|
1528
|
-
return this._chromaticAberration.value;
|
|
1529
|
-
}
|
|
1530
|
-
set chromaticAberration(v) {
|
|
1531
|
-
this._chromaticAberration.value = v;
|
|
1532
|
-
}
|
|
1533
|
-
get anisotropicBlur() {
|
|
1534
|
-
return this._anisotropicBlur.value;
|
|
1535
|
-
}
|
|
1536
|
-
set anisotropicBlur(v) {
|
|
1537
|
-
this._anisotropicBlur.value = v;
|
|
1538
|
-
}
|
|
1539
|
-
get distortion() {
|
|
1540
|
-
return this._distortion.value;
|
|
1541
|
-
}
|
|
1542
|
-
set distortion(v) {
|
|
1543
|
-
this._distortion.value = v;
|
|
1544
|
-
}
|
|
1545
|
-
get distortionScale() {
|
|
1546
|
-
return this._distortionScale.value;
|
|
1547
|
-
}
|
|
1548
|
-
set distortionScale(v) {
|
|
1549
|
-
this._distortionScale.value = v;
|
|
1550
|
-
}
|
|
1551
|
-
get temporalDistortion() {
|
|
1552
|
-
return this._temporalDistortion.value;
|
|
1553
|
-
}
|
|
1554
|
-
set temporalDistortion(v) {
|
|
1555
|
-
this._temporalDistortion.value = v;
|
|
1556
|
-
}
|
|
1557
|
-
get debugMode() {
|
|
1558
|
-
return this._debugMode.value;
|
|
1559
|
-
}
|
|
1560
|
-
set debugMode(v) {
|
|
1561
|
-
this._debugMode.value = v;
|
|
1562
|
-
}
|
|
1563
|
-
// Expose _transmission for legacy compatibility
|
|
1564
|
-
// This stores the user's intended transmission value, separate from the base class's transmission
|
|
1565
|
-
// which is kept at 0.001 to enable the transmission code path without triggering Three's internal rendering
|
|
1566
|
-
get _transmission() {
|
|
1567
|
-
if (!this._transmissionValue) {
|
|
1568
|
-
this._transmissionValue = uniform(1);
|
|
1569
|
-
}
|
|
1570
|
-
return this._transmissionValue.value;
|
|
1571
|
-
}
|
|
1572
|
-
set _transmission(v) {
|
|
1573
|
-
if (!this._transmissionValue) {
|
|
1574
|
-
this._transmissionValue = uniform(1);
|
|
1575
|
-
}
|
|
1576
|
-
this._transmissionValue.value = v;
|
|
1577
|
-
}
|
|
1578
1465
|
}
|
|
1579
1466
|
const MeshTransmissionMaterial = /* @__PURE__ */ React.forwardRef(
|
|
1580
1467
|
({
|
|
@@ -1707,7 +1594,7 @@ const MeshTransmissionMaterial = /* @__PURE__ */ React.forwardRef(
|
|
|
1707
1594
|
ref,
|
|
1708
1595
|
...props,
|
|
1709
1596
|
buffer: buffer || fboMain.texture,
|
|
1710
|
-
|
|
1597
|
+
transmission: transmission2,
|
|
1711
1598
|
anisotropicBlur: anisotropicBlur ?? anisotropy,
|
|
1712
1599
|
thickness: thickness2,
|
|
1713
1600
|
side,
|
|
@@ -1717,23 +1604,36 @@ const MeshTransmissionMaterial = /* @__PURE__ */ React.forwardRef(
|
|
|
1717
1604
|
}
|
|
1718
1605
|
);
|
|
1719
1606
|
|
|
1720
|
-
let MeshReflectorMaterial$1 = class MeshReflectorMaterial extends THREE.MeshStandardNodeMaterial {
|
|
1607
|
+
let MeshReflectorMaterial$1 = class MeshReflectorMaterial extends withUniforms(THREE.MeshStandardNodeMaterial, {
|
|
1608
|
+
/** Mirror strength, 0 = base material only, 1 = pure reflection */
|
|
1609
|
+
mirror: () => uniform(0),
|
|
1610
|
+
/** Positive values enable the blurred reflection sample */
|
|
1611
|
+
mixBlur: () => uniform(0),
|
|
1612
|
+
/** Strength of the reflection added on top of the base colour */
|
|
1613
|
+
mixStrength: () => uniform(1),
|
|
1614
|
+
/** Lower depth threshold for depth-based blur */
|
|
1615
|
+
minDepthThreshold: () => uniform(0.9),
|
|
1616
|
+
/** Upper depth threshold for depth-based blur */
|
|
1617
|
+
maxDepthThreshold: () => uniform(1),
|
|
1618
|
+
/** Depth scale for depth-based blur, 0 = disabled */
|
|
1619
|
+
depthScale: () => uniform(0),
|
|
1620
|
+
/** Bias added to the depth-to-blur ratio */
|
|
1621
|
+
depthToBlurRatioBias: () => uniform(0.25),
|
|
1622
|
+
/** Distortion strength */
|
|
1623
|
+
distortion: () => uniform(1),
|
|
1624
|
+
/** Contrast applied to the (clamped) reflection colour */
|
|
1625
|
+
mixContrast: () => uniform(1),
|
|
1626
|
+
/** Blur radius in the 0-1 range, scaled to 0.01-0.15 in the shader */
|
|
1627
|
+
blurRadius: () => uniform(0.1)
|
|
1628
|
+
}) {
|
|
1721
1629
|
//* Reflector Node ----------------------------------------
|
|
1722
1630
|
reflection;
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
depthScaleUniform;
|
|
1730
|
-
depthToBlurRatioBiasUniform;
|
|
1731
|
-
distortionUniform;
|
|
1732
|
-
mixContrastUniform;
|
|
1733
|
-
blurRadiusUniform;
|
|
1734
|
-
// Feature flags
|
|
1735
|
-
hasBlurUniform;
|
|
1736
|
-
hasDepthUniform;
|
|
1631
|
+
/**
|
|
1632
|
+
* Add this target to the scene and align it with the reflective surface.
|
|
1633
|
+
*/
|
|
1634
|
+
get reflectorTarget() {
|
|
1635
|
+
return this.reflection?.target;
|
|
1636
|
+
}
|
|
1737
1637
|
constructor(options = {}, parameters = {}) {
|
|
1738
1638
|
super();
|
|
1739
1639
|
const { distortionMap, ...validParams } = parameters;
|
|
@@ -1757,109 +1657,37 @@ let MeshReflectorMaterial$1 = class MeshReflectorMaterial extends THREE.MeshStan
|
|
|
1757
1657
|
resolutionScale,
|
|
1758
1658
|
generateMipmaps: true
|
|
1759
1659
|
});
|
|
1760
|
-
this.
|
|
1761
|
-
this.
|
|
1762
|
-
this.
|
|
1763
|
-
this.
|
|
1764
|
-
this.
|
|
1765
|
-
this.
|
|
1766
|
-
this.
|
|
1767
|
-
this.
|
|
1768
|
-
this.
|
|
1769
|
-
this.blurRadiusUniform = uniform(0.1);
|
|
1770
|
-
this.hasBlurUniform = uniform(mixBlur > 0 ? 1 : 0);
|
|
1771
|
-
this.hasDepthUniform = uniform(depthScale > 0 ? 1 : 0);
|
|
1660
|
+
this.mirror = mirror;
|
|
1661
|
+
this.mixBlur = mixBlur;
|
|
1662
|
+
this.mixStrength = mixStrength;
|
|
1663
|
+
this.minDepthThreshold = minDepthThreshold;
|
|
1664
|
+
this.maxDepthThreshold = maxDepthThreshold;
|
|
1665
|
+
this.depthScale = depthScale;
|
|
1666
|
+
this.depthToBlurRatioBias = depthToBlurRatioBias;
|
|
1667
|
+
this.distortion = distortion;
|
|
1668
|
+
this.mixContrast = mixContrast;
|
|
1772
1669
|
this.setupNodes();
|
|
1773
1670
|
}
|
|
1774
1671
|
setupNodes() {
|
|
1672
|
+
const { mirror, mixBlur, mixStrength, mixContrast, blurRadius } = this.uniforms;
|
|
1775
1673
|
this.colorNode = Fn(() => {
|
|
1776
1674
|
const reflectionSample = this.reflection.sample(this.reflection.uvNode);
|
|
1777
|
-
const
|
|
1778
|
-
const reflectionBlurred = hashBlur(this.reflection,
|
|
1675
|
+
const radius = mix(float(0.01), float(0.15), blurRadius);
|
|
1676
|
+
const reflectionBlurred = hashBlur(this.reflection, radius, {
|
|
1779
1677
|
repeats: float(20),
|
|
1780
1678
|
premultipliedAlpha: false
|
|
1781
1679
|
});
|
|
1782
|
-
const reflectionColor =
|
|
1680
|
+
const reflectionColor = select(mixBlur.greaterThan(0), reflectionBlurred.rgb, reflectionSample.rgb);
|
|
1783
1681
|
const reflectionClamped = clamp(reflectionColor, 0, 1);
|
|
1784
1682
|
const contrastAdjusted = vec3(
|
|
1785
|
-
reflectionClamped.x.sub(0.5).mul(
|
|
1786
|
-
reflectionClamped.y.sub(0.5).mul(
|
|
1787
|
-
reflectionClamped.z.sub(0.5).mul(
|
|
1683
|
+
reflectionClamped.x.sub(0.5).mul(mixContrast).add(0.5),
|
|
1684
|
+
reflectionClamped.y.sub(0.5).mul(mixContrast).add(0.5),
|
|
1685
|
+
reflectionClamped.z.sub(0.5).mul(mixContrast).add(0.5)
|
|
1788
1686
|
);
|
|
1789
|
-
const mirrorClamped = clamp(
|
|
1790
|
-
return vec4(vec3(1).sub(vec3(mirrorClamped)).add(contrastAdjusted.mul(
|
|
1687
|
+
const mirrorClamped = clamp(mirror, 0, 1);
|
|
1688
|
+
return vec4(vec3(1).sub(vec3(mirrorClamped)).add(contrastAdjusted.mul(mixStrength)), 1);
|
|
1791
1689
|
})();
|
|
1792
1690
|
}
|
|
1793
|
-
//* Getters and Setters ----------------------------------------
|
|
1794
|
-
get mirror() {
|
|
1795
|
-
return this.mirrorUniform.value;
|
|
1796
|
-
}
|
|
1797
|
-
set mirror(v) {
|
|
1798
|
-
this.mirrorUniform.value = v;
|
|
1799
|
-
}
|
|
1800
|
-
get mixBlur() {
|
|
1801
|
-
return this.mixBlurUniform.value;
|
|
1802
|
-
}
|
|
1803
|
-
set mixBlur(v) {
|
|
1804
|
-
this.mixBlurUniform.value = v;
|
|
1805
|
-
this.hasBlurUniform.value = v > 0 ? 1 : 0;
|
|
1806
|
-
}
|
|
1807
|
-
get mixStrength() {
|
|
1808
|
-
return this.mixStrengthUniform.value;
|
|
1809
|
-
}
|
|
1810
|
-
set mixStrength(v) {
|
|
1811
|
-
this.mixStrengthUniform.value = v;
|
|
1812
|
-
}
|
|
1813
|
-
get minDepthThreshold() {
|
|
1814
|
-
return this.minDepthThresholdUniform.value;
|
|
1815
|
-
}
|
|
1816
|
-
set minDepthThreshold(v) {
|
|
1817
|
-
this.minDepthThresholdUniform.value = v;
|
|
1818
|
-
}
|
|
1819
|
-
get maxDepthThreshold() {
|
|
1820
|
-
return this.maxDepthThresholdUniform.value;
|
|
1821
|
-
}
|
|
1822
|
-
set maxDepthThreshold(v) {
|
|
1823
|
-
this.maxDepthThresholdUniform.value = v;
|
|
1824
|
-
}
|
|
1825
|
-
get depthScale() {
|
|
1826
|
-
return this.depthScaleUniform.value;
|
|
1827
|
-
}
|
|
1828
|
-
set depthScale(v) {
|
|
1829
|
-
this.depthScaleUniform.value = v;
|
|
1830
|
-
this.hasDepthUniform.value = v > 0 ? 1 : 0;
|
|
1831
|
-
}
|
|
1832
|
-
get depthToBlurRatioBias() {
|
|
1833
|
-
return this.depthToBlurRatioBiasUniform.value;
|
|
1834
|
-
}
|
|
1835
|
-
set depthToBlurRatioBias(v) {
|
|
1836
|
-
this.depthToBlurRatioBiasUniform.value = v;
|
|
1837
|
-
}
|
|
1838
|
-
get distortion() {
|
|
1839
|
-
return this.distortionUniform.value;
|
|
1840
|
-
}
|
|
1841
|
-
set distortion(v) {
|
|
1842
|
-
this.distortionUniform.value = v;
|
|
1843
|
-
}
|
|
1844
|
-
get mixContrast() {
|
|
1845
|
-
return this.mixContrastUniform.value;
|
|
1846
|
-
}
|
|
1847
|
-
set mixContrast(v) {
|
|
1848
|
-
this.mixContrastUniform.value = v;
|
|
1849
|
-
}
|
|
1850
|
-
get blurRadius() {
|
|
1851
|
-
return this.blurRadiusUniform.value;
|
|
1852
|
-
}
|
|
1853
|
-
set blurRadius(v) {
|
|
1854
|
-
this.blurRadiusUniform.value = v;
|
|
1855
|
-
}
|
|
1856
|
-
/**
|
|
1857
|
-
* Get the reflector target mesh that needs to be added to the scene.
|
|
1858
|
-
* The target should be positioned and rotated to match the reflective surface.
|
|
1859
|
-
*/
|
|
1860
|
-
get reflectorTarget() {
|
|
1861
|
-
return this.reflection.target;
|
|
1862
|
-
}
|
|
1863
1691
|
};
|
|
1864
1692
|
|
|
1865
1693
|
const MeshReflectorMaterial = /* @__PURE__ */ React.forwardRef(
|
|
@@ -1981,138 +1809,64 @@ const approximateRefraction = /* @__PURE__ */ Fn(([rayDir, normal, iorValue, bou
|
|
|
1981
1809
|
});
|
|
1982
1810
|
return select(entryValid, currentDir, reflect(rayDir, normal));
|
|
1983
1811
|
});
|
|
1984
|
-
class MeshRefractionMaterialImpl extends MeshPhysicalNodeMaterial {
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1812
|
+
class MeshRefractionMaterialImpl extends withUniforms(MeshPhysicalNodeMaterial, {
|
|
1813
|
+
/** Number of internal bounces, default: 3 */
|
|
1814
|
+
bounces: () => uniform(3),
|
|
1815
|
+
/** Fresnel intensity, default: 0 */
|
|
1816
|
+
fresnel: () => uniform(0),
|
|
1817
|
+
/** Chromatic aberration strength, default: 0.01 */
|
|
1818
|
+
aberrationStrength: () => uniform(0.01),
|
|
1819
|
+
/** Tint applied to the refracted environment, default: white */
|
|
1820
|
+
tintColor: () => uniform(new THREE.Color("white"))
|
|
1821
|
+
}) {
|
|
1993
1822
|
_fastChroma;
|
|
1994
1823
|
/** Type flag for identification */
|
|
1995
1824
|
isMeshRefractionMaterial = true;
|
|
1996
1825
|
constructor(fastChroma = true) {
|
|
1997
1826
|
super();
|
|
1998
1827
|
this._fastChroma = fastChroma;
|
|
1999
|
-
this.
|
|
2000
|
-
this.
|
|
2001
|
-
this.
|
|
2002
|
-
this._fresnel = uniform(0);
|
|
2003
|
-
this._aberrationStrength = uniform(0.01);
|
|
2004
|
-
this._color = uniform(new THREE.Color("white"));
|
|
2005
|
-
this._opacityValue = uniform(1);
|
|
1828
|
+
this.ior = 2.4;
|
|
1829
|
+
this.envMap = new THREE.Texture();
|
|
1830
|
+
this.lights = false;
|
|
2006
1831
|
this.transparent = true;
|
|
2007
1832
|
this.side = THREE.FrontSide;
|
|
2008
1833
|
this._buildRefractionShader();
|
|
2009
1834
|
}
|
|
2010
1835
|
_buildRefractionShader() {
|
|
2011
|
-
const
|
|
2012
|
-
const bouncesUniform = this._bounces;
|
|
2013
|
-
const iorUniform = this._ior;
|
|
2014
|
-
const fresnelUniform = this._fresnel;
|
|
2015
|
-
const aberrationUniform = this._aberrationStrength;
|
|
2016
|
-
const colorUniform = this._color;
|
|
2017
|
-
const opacityUniform = this._opacityValue;
|
|
1836
|
+
const { bounces, fresnel, aberrationStrength, tintColor } = this.uniforms;
|
|
2018
1837
|
const fastChroma = this._fastChroma;
|
|
1838
|
+
const envSample = (uvNode) => context$a(materialReference("envMap", "texture", this), { getUV: () => uvNode });
|
|
2019
1839
|
this.outputNode = Fn(() => {
|
|
2020
1840
|
const worldPos = positionWorld;
|
|
2021
1841
|
const worldNormal = normalize(normalWorld);
|
|
2022
1842
|
const viewDir = normalize(worldPos.sub(cameraPosition));
|
|
2023
|
-
const baseColor =
|
|
2024
|
-
const
|
|
2025
|
-
const
|
|
1843
|
+
const baseColor = tintColor.toVar();
|
|
1844
|
+
const iorValue = max(materialIOR, 1);
|
|
1845
|
+
const refractedDirG = approximateRefraction(viewDir, worldNormal, iorValue, bounces);
|
|
1846
|
+
const aberration = aberrationStrength;
|
|
2026
1847
|
const refractedDirR = vec3(0, 0, 0).toVar();
|
|
2027
1848
|
const refractedDirB = vec3(0, 0, 0).toVar();
|
|
2028
|
-
|
|
2029
|
-
if (useFastChroma) {
|
|
1849
|
+
if (fastChroma) {
|
|
2030
1850
|
refractedDirR.assign(normalize(refractedDirG.add(vec3(aberration.mul(0.5)))));
|
|
2031
1851
|
refractedDirB.assign(normalize(refractedDirG.sub(vec3(aberration.mul(0.5)))));
|
|
2032
1852
|
} else {
|
|
2033
1853
|
refractedDirR.assign(
|
|
2034
|
-
approximateRefraction(
|
|
2035
|
-
viewDir,
|
|
2036
|
-
worldNormal,
|
|
2037
|
-
max(iorUniform.mul(float(1).sub(aberration)), 1),
|
|
2038
|
-
bouncesUniform
|
|
2039
|
-
)
|
|
1854
|
+
approximateRefraction(viewDir, worldNormal, max(materialIOR.mul(float(1).sub(aberration)), 1), bounces)
|
|
2040
1855
|
);
|
|
2041
1856
|
refractedDirB.assign(
|
|
2042
|
-
approximateRefraction(
|
|
2043
|
-
viewDir,
|
|
2044
|
-
worldNormal,
|
|
2045
|
-
max(iorUniform.mul(float(1).add(aberration)), 1),
|
|
2046
|
-
bouncesUniform
|
|
2047
|
-
)
|
|
1857
|
+
approximateRefraction(viewDir, worldNormal, max(materialIOR.mul(float(1).add(aberration)), 1), bounces)
|
|
2048
1858
|
);
|
|
2049
1859
|
}
|
|
2050
|
-
const
|
|
2051
|
-
const
|
|
2052
|
-
const
|
|
2053
|
-
const envColorR = texture(envMapTex, uvR).r;
|
|
2054
|
-
const envColorG = texture(envMapTex, uvG).g;
|
|
2055
|
-
const envColorB = texture(envMapTex, uvB).b;
|
|
1860
|
+
const envColorR = envSample(equirectUV(refractedDirR)).r;
|
|
1861
|
+
const envColorG = envSample(equirectUV(refractedDirG)).g;
|
|
1862
|
+
const envColorB = envSample(equirectUV(refractedDirB)).b;
|
|
2056
1863
|
const envColor = vec3(envColorR, envColorG, envColorB);
|
|
2057
1864
|
const tintedColor = envColor.mul(baseColor);
|
|
2058
|
-
const fresnelValue = fresnelEffect(viewDir, worldNormal, float(10)).mul(
|
|
1865
|
+
const fresnelValue = fresnelEffect(viewDir, worldNormal, float(10)).mul(fresnel);
|
|
2059
1866
|
const finalColor = mix(tintedColor, vec3(1), fresnelValue);
|
|
2060
|
-
return vec4(finalColor,
|
|
1867
|
+
return vec4(finalColor, materialOpacity);
|
|
2061
1868
|
})();
|
|
2062
1869
|
}
|
|
2063
|
-
//* Uniform Accessors ==============================
|
|
2064
|
-
/** Environment map texture */
|
|
2065
|
-
get envMap() {
|
|
2066
|
-
return this._envMap.value;
|
|
2067
|
-
}
|
|
2068
|
-
set envMap(v) {
|
|
2069
|
-
if (v) {
|
|
2070
|
-
this._envMap.value = v;
|
|
2071
|
-
}
|
|
2072
|
-
}
|
|
2073
|
-
/** Number of internal bounces, default: 3 */
|
|
2074
|
-
get bounces() {
|
|
2075
|
-
return this._bounces.value;
|
|
2076
|
-
}
|
|
2077
|
-
set bounces(v) {
|
|
2078
|
-
this._bounces.value = v;
|
|
2079
|
-
}
|
|
2080
|
-
/** Index of refraction, default: 2.4 (diamond) */
|
|
2081
|
-
get ior() {
|
|
2082
|
-
return this._ior.value;
|
|
2083
|
-
}
|
|
2084
|
-
set ior(v) {
|
|
2085
|
-
this._ior.value = v;
|
|
2086
|
-
}
|
|
2087
|
-
/** Fresnel intensity, default: 0 */
|
|
2088
|
-
get fresnel() {
|
|
2089
|
-
return this._fresnel.value;
|
|
2090
|
-
}
|
|
2091
|
-
set fresnel(v) {
|
|
2092
|
-
this._fresnel.value = v;
|
|
2093
|
-
}
|
|
2094
|
-
/** Chromatic aberration strength, default: 0.01 */
|
|
2095
|
-
get aberrationStrength() {
|
|
2096
|
-
return this._aberrationStrength.value;
|
|
2097
|
-
}
|
|
2098
|
-
set aberrationStrength(v) {
|
|
2099
|
-
this._aberrationStrength.value = v;
|
|
2100
|
-
}
|
|
2101
|
-
/** Tint color - use tintColor to avoid base class conflict */
|
|
2102
|
-
get tintColor() {
|
|
2103
|
-
return this._color.value;
|
|
2104
|
-
}
|
|
2105
|
-
set tintColor(v) {
|
|
2106
|
-
if (v instanceof THREE.Color) this._color.value = v;
|
|
2107
|
-
else this._color.value = new THREE.Color(v);
|
|
2108
|
-
}
|
|
2109
|
-
/** Opacity, default: 1 */
|
|
2110
|
-
get opacity() {
|
|
2111
|
-
return this._opacityValue.value;
|
|
2112
|
-
}
|
|
2113
|
-
set opacity(v) {
|
|
2114
|
-
this._opacityValue.value = v;
|
|
2115
|
-
}
|
|
2116
1870
|
}
|
|
2117
1871
|
const MeshRefractionMaterial = /* @__PURE__ */ React.forwardRef(
|
|
2118
1872
|
({
|
|
@@ -2335,175 +2089,88 @@ function Container$2({
|
|
|
2335
2089
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
|
|
2336
2090
|
}
|
|
2337
2091
|
|
|
2338
|
-
class PortalMaterialImpl extends MeshBasicNodeMaterial {
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2092
|
+
class PortalMaterialImpl extends withUniforms(MeshBasicNodeMaterial, {
|
|
2093
|
+
/** Edge fade blur, 0 = no blur */
|
|
2094
|
+
blur: () => uniform(0),
|
|
2095
|
+
/** Signed distance field of the parent geometry, generated on demand */
|
|
2096
|
+
sdf: () => uniformTexture(new THREE.Texture()),
|
|
2097
|
+
/** 0 = world scene, 0.5 = both, 1 = portal scene */
|
|
2098
|
+
blend: () => uniform(0),
|
|
2099
|
+
/** Largest SDF distance, used to normalise the field */
|
|
2100
|
+
size: () => uniform(0),
|
|
2101
|
+
/** Drawing-buffer size in pixels */
|
|
2102
|
+
resolution: () => uniform(new THREE.Vector2())
|
|
2103
|
+
}) {
|
|
2345
2104
|
constructor() {
|
|
2346
2105
|
super();
|
|
2347
|
-
this.
|
|
2348
|
-
this._map = uniformTexture(new THREE.Texture());
|
|
2349
|
-
this._sdf = uniformTexture(new THREE.Texture());
|
|
2350
|
-
this._blend = uniform(0);
|
|
2351
|
-
this._size = uniform(0);
|
|
2352
|
-
this._resolution = uniform(new THREE.Vector2());
|
|
2106
|
+
this.map = new THREE.Texture();
|
|
2353
2107
|
this._buildShader();
|
|
2354
2108
|
}
|
|
2355
2109
|
_buildShader() {
|
|
2356
|
-
const
|
|
2357
|
-
const
|
|
2358
|
-
const sdfTex = this._sdf;
|
|
2359
|
-
const sizeUniform = this._size;
|
|
2360
|
-
const resolutionUniform = this._resolution;
|
|
2110
|
+
const { blur, sdf, size, resolution } = this.uniforms;
|
|
2111
|
+
const map = materialReference("map", "texture", this);
|
|
2361
2112
|
this.colorNode = Fn(() => {
|
|
2362
|
-
const screenUv = screenCoordinate.xy.div(
|
|
2363
|
-
const t =
|
|
2364
|
-
const
|
|
2365
|
-
const
|
|
2366
|
-
const k = blurUniform;
|
|
2367
|
-
const edgeFactor = clamp(d.div(k).add(1), 0, 1);
|
|
2113
|
+
const screenUv = screenCoordinate.xy.div(resolution);
|
|
2114
|
+
const t = context$a(map, { getUV: () => screenUv });
|
|
2115
|
+
const d = sdf.sample(uv()).r.div(size);
|
|
2116
|
+
const edgeFactor = clamp(d.div(blur).add(1), 0, 1);
|
|
2368
2117
|
const alpha = float(1).sub(smoothstep(float(0), float(1), edgeFactor));
|
|
2369
|
-
const
|
|
2370
|
-
const finalAlpha = select(isBlurZero, t.a, t.a.mul(alpha));
|
|
2118
|
+
const finalAlpha = select(blur.equal(0), t.a, t.a.mul(alpha));
|
|
2371
2119
|
return vec4(t.rgb, finalAlpha);
|
|
2372
2120
|
})();
|
|
2373
2121
|
}
|
|
2374
|
-
//* Uniform Accessors --
|
|
2375
|
-
get blur() {
|
|
2376
|
-
return this._blur.value;
|
|
2377
|
-
}
|
|
2378
|
-
set blur(v) {
|
|
2379
|
-
this._blur.value = v;
|
|
2380
|
-
}
|
|
2381
|
-
get map() {
|
|
2382
|
-
return this._map?.value;
|
|
2383
|
-
}
|
|
2384
|
-
set map(v) {
|
|
2385
|
-
if (this._map) this._map.value = v ?? new THREE.Texture();
|
|
2386
|
-
}
|
|
2387
|
-
get sdf() {
|
|
2388
|
-
return this._sdf.value;
|
|
2389
|
-
}
|
|
2390
|
-
set sdf(v) {
|
|
2391
|
-
if (v) this._sdf.value = v;
|
|
2392
|
-
}
|
|
2393
|
-
get blend() {
|
|
2394
|
-
return this._blend.value;
|
|
2395
|
-
}
|
|
2396
|
-
set blend(v) {
|
|
2397
|
-
this._blend.value = v;
|
|
2398
|
-
}
|
|
2399
|
-
get size() {
|
|
2400
|
-
return this._size.value;
|
|
2401
|
-
}
|
|
2402
|
-
set size(v) {
|
|
2403
|
-
this._size.value = v;
|
|
2404
|
-
}
|
|
2405
|
-
get resolution() {
|
|
2406
|
-
return this._resolution.value;
|
|
2407
|
-
}
|
|
2408
|
-
set resolution(v) {
|
|
2409
|
-
if (Array.isArray(v)) this._resolution.value.set(v[0], v[1]);
|
|
2410
|
-
else this._resolution.value.copy(v);
|
|
2411
|
-
}
|
|
2412
2122
|
}
|
|
2413
|
-
class BlendMaterial extends MeshBasicNodeMaterial {
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2123
|
+
class BlendMaterial extends withUniforms(MeshBasicNodeMaterial, {
|
|
2124
|
+
textureA: () => uniformTexture(new THREE.Texture()),
|
|
2125
|
+
textureB: () => uniformTexture(new THREE.Texture()),
|
|
2126
|
+
blend: () => uniform(0)
|
|
2127
|
+
}) {
|
|
2417
2128
|
constructor() {
|
|
2418
2129
|
super();
|
|
2419
|
-
|
|
2420
|
-
this._textureB = uniformTexture(new THREE.Texture());
|
|
2421
|
-
this._blend = uniform(0);
|
|
2422
|
-
this._buildShader();
|
|
2423
|
-
}
|
|
2424
|
-
_buildShader() {
|
|
2425
|
-
const texA = this._textureA;
|
|
2426
|
-
const texB = this._textureB;
|
|
2427
|
-
const blendUniform = this._blend;
|
|
2130
|
+
const { textureA, textureB, blend } = this.uniforms;
|
|
2428
2131
|
this.colorNode = Fn(() => {
|
|
2429
2132
|
const uvCoord = uv();
|
|
2430
|
-
|
|
2431
|
-
const tb = texture(texB, uvCoord);
|
|
2432
|
-
return mix(tb, ta, blendUniform);
|
|
2133
|
+
return mix(textureB.sample(uvCoord), textureA.sample(uvCoord), blend);
|
|
2433
2134
|
})();
|
|
2434
2135
|
}
|
|
2435
|
-
get textureA() {
|
|
2436
|
-
return this._textureA.value;
|
|
2437
|
-
}
|
|
2438
|
-
set textureA(v) {
|
|
2439
|
-
this._textureA.value = v;
|
|
2440
|
-
}
|
|
2441
|
-
get textureB() {
|
|
2442
|
-
return this._textureB.value;
|
|
2443
|
-
}
|
|
2444
|
-
set textureB(v) {
|
|
2445
|
-
this._textureB.value = v;
|
|
2446
|
-
}
|
|
2447
|
-
get blend() {
|
|
2448
|
-
return this._blend.value;
|
|
2449
|
-
}
|
|
2450
|
-
set blend(v) {
|
|
2451
|
-
this._blend.value = v;
|
|
2452
|
-
}
|
|
2453
2136
|
}
|
|
2454
|
-
class UVRenderMaterial extends MeshBasicNodeMaterial {
|
|
2455
|
-
|
|
2456
|
-
|
|
2137
|
+
class UVRenderMaterial extends withUniforms(MeshBasicNodeMaterial, {
|
|
2138
|
+
tex: () => uniformTexture(new THREE.Texture()),
|
|
2139
|
+
/** 1 = pack the inside of the mask, 0 = the outside */
|
|
2140
|
+
inside: () => uniform(0)
|
|
2141
|
+
}) {
|
|
2457
2142
|
constructor(inside = false) {
|
|
2458
|
-
super();
|
|
2459
|
-
this.
|
|
2460
|
-
|
|
2461
|
-
this.
|
|
2462
|
-
}
|
|
2463
|
-
_buildShader() {
|
|
2464
|
-
const tex = this._tex;
|
|
2465
|
-
const insideUniform = this._inside;
|
|
2466
|
-
this.colorNode = Fn(() => {
|
|
2143
|
+
super({ toneMapped: false });
|
|
2144
|
+
this.inside = inside ? 1 : 0;
|
|
2145
|
+
const { tex, inside: insideUniform } = this.uniforms;
|
|
2146
|
+
this.fragmentNode = Fn(() => {
|
|
2467
2147
|
const uvCoord = uv();
|
|
2468
|
-
const
|
|
2469
|
-
const roundedMask = round(mask);
|
|
2148
|
+
const roundedMask = round(tex.sample(uvCoord).x);
|
|
2470
2149
|
const isInside = insideUniform.greaterThan(0.5);
|
|
2471
2150
|
const factor = select(isInside, float(1).sub(roundedMask), roundedMask);
|
|
2472
2151
|
const packedUv = uvCoord.mul(factor);
|
|
2473
2152
|
return vec4(packedUv.x, packedUv.y, 0, 1);
|
|
2474
2153
|
})();
|
|
2475
2154
|
}
|
|
2476
|
-
get tex() {
|
|
2477
|
-
return this._tex.value;
|
|
2478
|
-
}
|
|
2479
|
-
set tex(v) {
|
|
2480
|
-
this._tex.value = v;
|
|
2481
|
-
}
|
|
2482
2155
|
}
|
|
2483
|
-
class JumpFloodMaterial extends MeshBasicNodeMaterial {
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2156
|
+
class JumpFloodMaterial extends withUniforms(MeshBasicNodeMaterial, {
|
|
2157
|
+
tex: () => uniformTexture(new THREE.Texture()),
|
|
2158
|
+
offset: () => uniform(0),
|
|
2159
|
+
texelSize: () => uniform(new THREE.Vector2(1, 1))
|
|
2160
|
+
}) {
|
|
2487
2161
|
constructor(clientWidth, clientHeight) {
|
|
2488
|
-
super();
|
|
2489
|
-
this.
|
|
2490
|
-
|
|
2491
|
-
this.
|
|
2492
|
-
this._buildShader();
|
|
2493
|
-
}
|
|
2494
|
-
_buildShader() {
|
|
2495
|
-
const tex = this._tex;
|
|
2496
|
-
const offsetUniform = this._offset;
|
|
2497
|
-
const texelSizeUniform = this._texelSize;
|
|
2498
|
-
this.colorNode = Fn(() => {
|
|
2162
|
+
super({ toneMapped: false });
|
|
2163
|
+
this.uniforms.texelSize.value.set(1 / clientWidth, 1 / clientHeight);
|
|
2164
|
+
const { tex, offset, texelSize } = this.uniforms;
|
|
2165
|
+
this.fragmentNode = Fn(() => {
|
|
2499
2166
|
const uvCoord = uv();
|
|
2500
2167
|
const closestDist = float(99999999e-1).toVar();
|
|
2501
2168
|
const closestPos = vec2$2(0, 0).toVar();
|
|
2502
2169
|
Loop({ start: int(-1), end: int(2), type: "int", condition: "<" }, ({ i: x }) => {
|
|
2503
2170
|
Loop({ start: int(-1), end: int(2), type: "int", condition: "<" }, ({ i: y }) => {
|
|
2504
|
-
const sampleOffset = vec2$2(float(x), float(y)).mul(
|
|
2171
|
+
const sampleOffset = vec2$2(float(x), float(y)).mul(texelSize).mul(offset);
|
|
2505
2172
|
const sampleUv = uvCoord.add(sampleOffset);
|
|
2506
|
-
const pos =
|
|
2173
|
+
const pos = tex.sample(sampleUv).xy;
|
|
2507
2174
|
const dist = distance(pos, uvCoord);
|
|
2508
2175
|
const isValid = pos.x.notEqual(0).and(pos.y.notEqual(0));
|
|
2509
2176
|
const isCloser = dist.lessThan(closestDist);
|
|
@@ -2515,88 +2182,40 @@ class JumpFloodMaterial extends MeshBasicNodeMaterial {
|
|
|
2515
2182
|
return vec4(closestPos, 0, 1);
|
|
2516
2183
|
})();
|
|
2517
2184
|
}
|
|
2518
|
-
get tex() {
|
|
2519
|
-
return this._tex.value;
|
|
2520
|
-
}
|
|
2521
|
-
set tex(v) {
|
|
2522
|
-
this._tex.value = v;
|
|
2523
|
-
}
|
|
2524
|
-
get offset() {
|
|
2525
|
-
return this._offset.value;
|
|
2526
|
-
}
|
|
2527
|
-
set offset(v) {
|
|
2528
|
-
this._offset.value = v;
|
|
2529
|
-
}
|
|
2530
2185
|
}
|
|
2531
|
-
class DistanceFieldMaterial extends MeshBasicNodeMaterial {
|
|
2532
|
-
|
|
2533
|
-
|
|
2186
|
+
class DistanceFieldMaterial extends withUniforms(MeshBasicNodeMaterial, {
|
|
2187
|
+
tex: () => uniformTexture(new THREE.Texture()),
|
|
2188
|
+
size: () => uniform(new THREE.Vector2(1, 1))
|
|
2189
|
+
}) {
|
|
2534
2190
|
constructor(clientWidth, clientHeight) {
|
|
2535
|
-
super();
|
|
2536
|
-
this.
|
|
2537
|
-
|
|
2538
|
-
this.
|
|
2539
|
-
}
|
|
2540
|
-
_buildShader() {
|
|
2541
|
-
const tex = this._tex;
|
|
2542
|
-
const sizeUniform = this._size;
|
|
2543
|
-
this.colorNode = Fn(() => {
|
|
2191
|
+
super({ toneMapped: false });
|
|
2192
|
+
this.uniforms.size.value.set(clientWidth, clientHeight);
|
|
2193
|
+
const { tex, size } = this.uniforms;
|
|
2194
|
+
this.fragmentNode = Fn(() => {
|
|
2544
2195
|
const uvCoord = uv();
|
|
2545
|
-
const pos =
|
|
2546
|
-
const dist = distance(
|
|
2196
|
+
const pos = tex.sample(uvCoord).xy;
|
|
2197
|
+
const dist = distance(size.mul(pos), size.mul(uvCoord));
|
|
2547
2198
|
return vec4(dist, 0, 0, 1);
|
|
2548
2199
|
})();
|
|
2549
2200
|
}
|
|
2550
|
-
get tex() {
|
|
2551
|
-
return this._tex.value;
|
|
2552
|
-
}
|
|
2553
|
-
set tex(v) {
|
|
2554
|
-
this._tex.value = v;
|
|
2555
|
-
}
|
|
2556
2201
|
}
|
|
2557
|
-
class CompositeMaterial extends MeshBasicNodeMaterial {
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2202
|
+
class CompositeMaterial extends withUniforms(MeshBasicNodeMaterial, {
|
|
2203
|
+
inside: () => uniformTexture(new THREE.Texture()),
|
|
2204
|
+
outside: () => uniformTexture(new THREE.Texture()),
|
|
2205
|
+
mask: () => uniformTexture(new THREE.Texture())
|
|
2206
|
+
}) {
|
|
2561
2207
|
constructor() {
|
|
2562
|
-
super();
|
|
2563
|
-
|
|
2564
|
-
this.
|
|
2565
|
-
this._mask = uniformTexture(new THREE.Texture());
|
|
2566
|
-
this._buildShader();
|
|
2567
|
-
}
|
|
2568
|
-
_buildShader() {
|
|
2569
|
-
const insideTex = this._inside;
|
|
2570
|
-
const outsideTex = this._outside;
|
|
2571
|
-
const maskTex = this._mask;
|
|
2572
|
-
this.colorNode = Fn(() => {
|
|
2208
|
+
super({ toneMapped: false });
|
|
2209
|
+
const { inside, outside, mask } = this.uniforms;
|
|
2210
|
+
this.fragmentNode = Fn(() => {
|
|
2573
2211
|
const uvCoord = uv();
|
|
2574
|
-
const i =
|
|
2575
|
-
const o =
|
|
2576
|
-
const maskVal =
|
|
2577
|
-
const
|
|
2578
|
-
const result = select(isOutside, o, i.negate());
|
|
2212
|
+
const i = inside.sample(uvCoord).x;
|
|
2213
|
+
const o = outside.sample(uvCoord).x;
|
|
2214
|
+
const maskVal = mask.sample(uvCoord).x;
|
|
2215
|
+
const result = select(maskVal.equal(0), o, i.negate());
|
|
2579
2216
|
return vec4(result, 0, 0, 1);
|
|
2580
2217
|
})();
|
|
2581
2218
|
}
|
|
2582
|
-
get inside() {
|
|
2583
|
-
return this._inside.value;
|
|
2584
|
-
}
|
|
2585
|
-
set inside(v) {
|
|
2586
|
-
this._inside.value = v;
|
|
2587
|
-
}
|
|
2588
|
-
get outside() {
|
|
2589
|
-
return this._outside.value;
|
|
2590
|
-
}
|
|
2591
|
-
set outside(v) {
|
|
2592
|
-
this._outside.value = v;
|
|
2593
|
-
}
|
|
2594
|
-
get mask() {
|
|
2595
|
-
return this._mask.value;
|
|
2596
|
-
}
|
|
2597
|
-
set mask(v) {
|
|
2598
|
-
this._mask.value = v;
|
|
2599
|
-
}
|
|
2600
2219
|
}
|
|
2601
2220
|
const makeSDFGenerator = (clientWidth, clientHeight, renderer) => {
|
|
2602
2221
|
const finalTarget = new RenderTarget(clientWidth, clientHeight, {
|
|
@@ -2644,7 +2263,7 @@ const makeSDFGenerator = (clientWidth, clientHeight, renderer) => {
|
|
|
2644
2263
|
const jumpFloodQuad = new QuadMesh(jumpFloodMat);
|
|
2645
2264
|
const distanceFieldQuad = new QuadMesh(distanceFieldMat);
|
|
2646
2265
|
const compositeQuad = new QuadMesh(compositeMat);
|
|
2647
|
-
|
|
2266
|
+
const generate = (image) => {
|
|
2648
2267
|
image.minFilter = THREE.NearestFilter;
|
|
2649
2268
|
image.magFilter = THREE.NearestFilter;
|
|
2650
2269
|
uvRenderMat.tex = image;
|
|
@@ -2686,9 +2305,28 @@ const makeSDFGenerator = (clientWidth, clientHeight, renderer) => {
|
|
|
2686
2305
|
compositeMat.outside = outsideRenderTargetFinal.texture;
|
|
2687
2306
|
compositeMat.mask = image;
|
|
2688
2307
|
compositeQuad.render(renderer);
|
|
2689
|
-
renderer.setRenderTarget(null);
|
|
2690
2308
|
return finalTarget;
|
|
2691
2309
|
};
|
|
2310
|
+
return {
|
|
2311
|
+
generate,
|
|
2312
|
+
dispose() {
|
|
2313
|
+
for (const resource of [
|
|
2314
|
+
finalTarget,
|
|
2315
|
+
outsideRenderTarget,
|
|
2316
|
+
insideRenderTarget,
|
|
2317
|
+
outsideRenderTarget2,
|
|
2318
|
+
insideRenderTarget2,
|
|
2319
|
+
outsideRenderTargetFinal,
|
|
2320
|
+
insideRenderTargetFinal,
|
|
2321
|
+
uvRenderMat,
|
|
2322
|
+
uvRenderInsideMat,
|
|
2323
|
+
jumpFloodMat,
|
|
2324
|
+
distanceFieldMat,
|
|
2325
|
+
compositeMat
|
|
2326
|
+
])
|
|
2327
|
+
resource.dispose();
|
|
2328
|
+
}
|
|
2329
|
+
};
|
|
2692
2330
|
};
|
|
2693
2331
|
const MeshPortalMaterial = /* @__PURE__ */ React.forwardRef(
|
|
2694
2332
|
({
|
|
@@ -2703,7 +2341,7 @@ const MeshPortalMaterial = /* @__PURE__ */ React.forwardRef(
|
|
|
2703
2341
|
}, fref) => {
|
|
2704
2342
|
extend({ PortalMaterialImpl });
|
|
2705
2343
|
const ref = React.useRef(null);
|
|
2706
|
-
const { scene,
|
|
2344
|
+
const { scene, renderer, size, viewport, setEvents, invalidate } = useThree();
|
|
2707
2345
|
const maskRenderTarget = useFBO(resolution, resolution);
|
|
2708
2346
|
const [priority, setPriority] = React.useState(0);
|
|
2709
2347
|
useFrame(() => {
|
|
@@ -2714,43 +2352,69 @@ const MeshPortalMaterial = /* @__PURE__ */ React.forwardRef(
|
|
|
2714
2352
|
if (events !== void 0) setEvents({ enabled: !events });
|
|
2715
2353
|
}, [events]);
|
|
2716
2354
|
const [visible, setVisible] = React.useState(true);
|
|
2355
|
+
const needsSdf = blur !== 0;
|
|
2717
2356
|
const parent = useIntersect(setVisible);
|
|
2718
2357
|
React.useLayoutEffect(() => {
|
|
2719
2358
|
parent.current = ref.current?.__r3f?.parent?.object;
|
|
2720
2359
|
}, []);
|
|
2721
2360
|
React.useLayoutEffect(() => {
|
|
2722
|
-
if (!parent.current) return;
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
)
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2361
|
+
if (!parent.current || !needsSdf) return;
|
|
2362
|
+
const material = ref.current;
|
|
2363
|
+
const previousSdf = material.sdf;
|
|
2364
|
+
const previousSize = material.size;
|
|
2365
|
+
const gpuRenderer = renderer;
|
|
2366
|
+
const tempMesh = new THREE.Mesh(parent.current.geometry, new THREE.MeshBasicMaterial());
|
|
2367
|
+
const boundingBox = new THREE.Box3().setFromBufferAttribute(
|
|
2368
|
+
tempMesh.geometry.attributes.position
|
|
2369
|
+
);
|
|
2370
|
+
const orthoCam = new THREE.OrthographicCamera(
|
|
2371
|
+
boundingBox.min.x * (1 + 2 / resolution),
|
|
2372
|
+
boundingBox.max.x * (1 + 2 / resolution),
|
|
2373
|
+
boundingBox.max.y * (1 + 2 / resolution),
|
|
2374
|
+
boundingBox.min.y * (1 + 2 / resolution),
|
|
2375
|
+
0.1,
|
|
2376
|
+
1e3
|
|
2377
|
+
);
|
|
2378
|
+
orthoCam.position.set(0, 0, 1);
|
|
2379
|
+
orthoCam.lookAt(0, 0, 0);
|
|
2380
|
+
const sg = makeSDFGenerator(resolution, resolution, gpuRenderer);
|
|
2381
|
+
const previousTarget = gpuRenderer.getRenderTarget();
|
|
2382
|
+
const previousClearColor = gpuRenderer.getClearColor(new THREE.Color());
|
|
2383
|
+
const previousClearAlpha = gpuRenderer.getClearAlpha();
|
|
2384
|
+
let sdf;
|
|
2385
|
+
try {
|
|
2386
|
+
gpuRenderer.setClearColor(0, 0);
|
|
2387
|
+
gpuRenderer.setRenderTarget(maskRenderTarget);
|
|
2388
|
+
gpuRenderer.render(tempMesh, orthoCam);
|
|
2389
|
+
sdf = sg.generate(maskRenderTarget.texture);
|
|
2390
|
+
} catch (error) {
|
|
2391
|
+
sg.dispose();
|
|
2392
|
+
throw error;
|
|
2393
|
+
} finally {
|
|
2394
|
+
gpuRenderer.setRenderTarget(previousTarget);
|
|
2395
|
+
gpuRenderer.setClearColor(previousClearColor, previousClearAlpha);
|
|
2396
|
+
tempMesh.material.dispose();
|
|
2397
|
+
}
|
|
2398
|
+
let cancelled = false;
|
|
2399
|
+
gpuRenderer.readRenderTargetPixelsAsync(sdf, 0, 0, resolution, resolution).then((readSdf) => {
|
|
2400
|
+
if (cancelled) return;
|
|
2744
2401
|
let min = Infinity;
|
|
2745
2402
|
for (let i = 0; i < readSdf.length; i++) {
|
|
2746
2403
|
if (readSdf[i] < min) min = readSdf[i];
|
|
2747
2404
|
}
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2405
|
+
material.size = -min;
|
|
2406
|
+
material.sdf = sdf.texture;
|
|
2407
|
+
invalidate();
|
|
2408
|
+
}).catch((error) => {
|
|
2409
|
+
if (!cancelled) console.error("MeshPortalMaterial: SDF readback failed.", error);
|
|
2410
|
+
});
|
|
2411
|
+
return () => {
|
|
2412
|
+
cancelled = true;
|
|
2413
|
+
material.sdf = previousSdf;
|
|
2414
|
+
material.size = previousSize;
|
|
2415
|
+
sg.dispose();
|
|
2416
|
+
};
|
|
2417
|
+
}, [resolution, needsSdf, renderer, maskRenderTarget, invalidate]);
|
|
2754
2418
|
React.useImperativeHandle(fref, () => ref.current);
|
|
2755
2419
|
const compute = React.useCallback(
|
|
2756
2420
|
(event, state, _previous) => {
|
|
@@ -2855,44 +2519,27 @@ function ManagePortalScene({
|
|
|
2855
2519
|
return /* @__PURE__ */ React.createElement(React.Fragment, null);
|
|
2856
2520
|
}
|
|
2857
2521
|
|
|
2858
|
-
class DistortMaterialImplWebGPU extends THREE.MeshPhysicalNodeMaterial {
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2522
|
+
class DistortMaterialImplWebGPU extends withUniforms(THREE.MeshPhysicalNodeMaterial, {
|
|
2523
|
+
/** Animation time, advanced by the component each frame */
|
|
2524
|
+
time: () => uniform(0),
|
|
2525
|
+
/** Distortion intensity */
|
|
2526
|
+
distort: () => uniform(0.4),
|
|
2527
|
+
/** Base scale the distortion is added to */
|
|
2528
|
+
radius: () => uniform(1)
|
|
2529
|
+
}) {
|
|
2862
2530
|
constructor(parameters = {}) {
|
|
2863
2531
|
super(parameters);
|
|
2864
|
-
this.
|
|
2865
|
-
this.timeUniform = uniform(0);
|
|
2866
|
-
this.distortUniform = uniform(0.4);
|
|
2867
|
-
this.radiusUniform = uniform(1);
|
|
2532
|
+
const { time, distort, radius } = this.uniforms;
|
|
2868
2533
|
this.positionNode = Fn(() => {
|
|
2869
2534
|
const pos = positionLocal.toVar();
|
|
2870
|
-
const updateTime =
|
|
2535
|
+
const updateTime = time.div(50);
|
|
2871
2536
|
const noiseInput = pos.div(2).add(updateTime.mul(5));
|
|
2872
2537
|
const noiseVec = mx_noise_vec3(noiseInput);
|
|
2873
2538
|
const noise = noiseVec.x;
|
|
2874
|
-
const distortFactor = noise.mul(pow(
|
|
2539
|
+
const distortFactor = noise.mul(pow(distort, float(2))).add(radius);
|
|
2875
2540
|
return pos.mul(distortFactor);
|
|
2876
2541
|
})();
|
|
2877
2542
|
}
|
|
2878
|
-
get time() {
|
|
2879
|
-
return this.timeUniform.value;
|
|
2880
|
-
}
|
|
2881
|
-
set time(v) {
|
|
2882
|
-
this.timeUniform.value = v;
|
|
2883
|
-
}
|
|
2884
|
-
get distort() {
|
|
2885
|
-
return this.distortUniform.value;
|
|
2886
|
-
}
|
|
2887
|
-
set distort(v) {
|
|
2888
|
-
this.distortUniform.value = v;
|
|
2889
|
-
}
|
|
2890
|
-
get radius() {
|
|
2891
|
-
return this.radiusUniform.value;
|
|
2892
|
-
}
|
|
2893
|
-
set radius(v) {
|
|
2894
|
-
this.radiusUniform.value = v;
|
|
2895
|
-
}
|
|
2896
2543
|
}
|
|
2897
2544
|
const MeshDistortMaterial = /* @__PURE__ */ React.forwardRef(({ speed = 1, ...props }, ref) => {
|
|
2898
2545
|
const [material] = React.useState(() => new DistortMaterialImplWebGPU());
|
|
@@ -2900,17 +2547,18 @@ const MeshDistortMaterial = /* @__PURE__ */ React.forwardRef(({ speed = 1, ...pr
|
|
|
2900
2547
|
return /* @__PURE__ */ React.createElement("primitive", { object: material, ref, attach: "material", ...props });
|
|
2901
2548
|
});
|
|
2902
2549
|
|
|
2903
|
-
class WobbleMaterialImpl extends THREE.MeshStandardNodeMaterial {
|
|
2904
|
-
|
|
2905
|
-
|
|
2550
|
+
class WobbleMaterialImpl extends withUniforms(THREE.MeshStandardNodeMaterial, {
|
|
2551
|
+
/** Animation time, advanced by the component each frame */
|
|
2552
|
+
time: () => uniform(0),
|
|
2553
|
+
/** Wobble strength */
|
|
2554
|
+
factor: () => uniform(1)
|
|
2555
|
+
}) {
|
|
2906
2556
|
constructor(parameters = {}) {
|
|
2907
2557
|
super(parameters);
|
|
2908
|
-
this.
|
|
2909
|
-
this.timeUniform = uniform(0);
|
|
2910
|
-
this.factorUniform = uniform(1);
|
|
2558
|
+
const { time, factor } = this.uniforms;
|
|
2911
2559
|
this.positionNode = Fn(() => {
|
|
2912
2560
|
const pos = positionLocal.toVar();
|
|
2913
|
-
const theta = sin(
|
|
2561
|
+
const theta = sin(time.add(pos.y)).div(2).mul(factor);
|
|
2914
2562
|
const c = cos(theta);
|
|
2915
2563
|
const s = sin(theta);
|
|
2916
2564
|
const rotMatrix = mat3(c, float(0), s, float(0), float(1), float(0), s.negate(), float(0), c);
|
|
@@ -2919,25 +2567,13 @@ class WobbleMaterialImpl extends THREE.MeshStandardNodeMaterial {
|
|
|
2919
2567
|
this.normalNode = Fn(() => {
|
|
2920
2568
|
const pos = positionLocal.toVar();
|
|
2921
2569
|
const norm = normalLocal.toVar();
|
|
2922
|
-
const theta = sin(
|
|
2570
|
+
const theta = sin(time.add(pos.y)).div(2).mul(factor);
|
|
2923
2571
|
const c = cos(theta);
|
|
2924
2572
|
const s = sin(theta);
|
|
2925
2573
|
const rotMatrix = mat3(c, float(0), s, float(0), float(1), float(0), s.negate(), float(0), c);
|
|
2926
2574
|
return norm.mul(rotMatrix);
|
|
2927
2575
|
})();
|
|
2928
2576
|
}
|
|
2929
|
-
get time() {
|
|
2930
|
-
return this.timeUniform.value;
|
|
2931
|
-
}
|
|
2932
|
-
set time(v) {
|
|
2933
|
-
this.timeUniform.value = v;
|
|
2934
|
-
}
|
|
2935
|
-
get factor() {
|
|
2936
|
-
return this.factorUniform.value;
|
|
2937
|
-
}
|
|
2938
|
-
set factor(v) {
|
|
2939
|
-
this.factorUniform.value = v;
|
|
2940
|
-
}
|
|
2941
2577
|
}
|
|
2942
2578
|
const MeshWobbleMaterial = /* @__PURE__ */ React.forwardRef(({ speed = 1, ...props }, ref) => {
|
|
2943
2579
|
const [material] = React.useState(() => new WobbleMaterialImpl());
|
|
@@ -2956,84 +2592,36 @@ function FakeCloudMaterial(BaseMaterial) {
|
|
|
2956
2592
|
return mat;
|
|
2957
2593
|
}
|
|
2958
2594
|
|
|
2959
|
-
class OutlinesMaterial extends MeshBasicNodeMaterial {
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2595
|
+
class OutlinesMaterial extends withUniforms(MeshBasicNodeMaterial, {
|
|
2596
|
+
/** Whether thickness is constant in screen pixels */
|
|
2597
|
+
screenspace: () => uniform(false),
|
|
2598
|
+
/** Outline thickness */
|
|
2599
|
+
thickness: () => uniform(0.05),
|
|
2600
|
+
/** Drawing-buffer size, for screenspace thickness */
|
|
2601
|
+
size: () => uniform(new THREE.Vector2(1, 1))
|
|
2602
|
+
}) {
|
|
2967
2603
|
/** Type flag for identification */
|
|
2968
2604
|
isOutlinesMaterial = true;
|
|
2969
2605
|
constructor() {
|
|
2970
2606
|
super();
|
|
2971
|
-
this.
|
|
2972
|
-
this._color = uniform(new THREE.Color("black"));
|
|
2973
|
-
this._opacityValue = uniform(1);
|
|
2974
|
-
this._thickness = uniform(0.05);
|
|
2975
|
-
this._size = uniform(new THREE.Vector2(1, 1));
|
|
2607
|
+
this.color.set("black");
|
|
2976
2608
|
this.side = THREE.BackSide;
|
|
2977
2609
|
this.transparent = false;
|
|
2978
2610
|
this._buildOutlineShader();
|
|
2979
2611
|
}
|
|
2980
2612
|
_buildOutlineShader() {
|
|
2981
|
-
const
|
|
2982
|
-
const colorUniform = this._color;
|
|
2983
|
-
const opacityUniform = this._opacityValue;
|
|
2984
|
-
const thicknessUniform = this._thickness;
|
|
2985
|
-
const sizeUniform = this._size;
|
|
2613
|
+
const { screenspace, thickness, size } = this.uniforms;
|
|
2986
2614
|
this.positionNode = Fn(() => {
|
|
2987
2615
|
const position = positionLocal.toVar();
|
|
2988
2616
|
const normal = normalLocal.toVar();
|
|
2989
|
-
const
|
|
2990
|
-
const screenspacePos = position.add(normal.mul(thicknessUniform));
|
|
2617
|
+
const screenspacePos = position.add(normal.mul(thickness));
|
|
2991
2618
|
const clipPos = cameraProjectionMatrix.mul(modelViewMatrix.mul(vec4(position, 1)));
|
|
2992
2619
|
const clipNormal = cameraProjectionMatrix.mul(modelViewMatrix.mul(vec4(normal, 0)));
|
|
2993
|
-
normalize(clipNormal.xy).mul(
|
|
2994
|
-
const worldOffset = normal.mul(
|
|
2995
|
-
return select(
|
|
2996
|
-
})();
|
|
2997
|
-
this.outputNode = Fn(() => {
|
|
2998
|
-
return vec4(colorUniform, opacityUniform);
|
|
2620
|
+
normalize(clipNormal.xy).mul(thickness).div(size).mul(clipPos.w).mul(2);
|
|
2621
|
+
const worldOffset = normal.mul(thickness);
|
|
2622
|
+
return select(screenspace, screenspacePos, position.add(worldOffset));
|
|
2999
2623
|
})();
|
|
3000
|
-
|
|
3001
|
-
//* Uniform Accessors ==============================
|
|
3002
|
-
/** Whether to use screenspace thickness */
|
|
3003
|
-
get screenspace() {
|
|
3004
|
-
return this._screenspace.value > 0.5;
|
|
3005
|
-
}
|
|
3006
|
-
set screenspace(v) {
|
|
3007
|
-
this._screenspace.value = v ? 1 : 0;
|
|
3008
|
-
}
|
|
3009
|
-
/** Outline color */
|
|
3010
|
-
get color() {
|
|
3011
|
-
return this._color.value;
|
|
3012
|
-
}
|
|
3013
|
-
set color(v) {
|
|
3014
|
-
if (v instanceof THREE.Color) this._color.value = v;
|
|
3015
|
-
else this._color.value = new THREE.Color(v);
|
|
3016
|
-
}
|
|
3017
|
-
/** Outline opacity */
|
|
3018
|
-
get opacity() {
|
|
3019
|
-
return this._opacityValue.value;
|
|
3020
|
-
}
|
|
3021
|
-
set opacity(v) {
|
|
3022
|
-
this._opacityValue.value = v;
|
|
3023
|
-
}
|
|
3024
|
-
/** Outline thickness */
|
|
3025
|
-
get thickness() {
|
|
3026
|
-
return this._thickness.value;
|
|
3027
|
-
}
|
|
3028
|
-
set thickness(v) {
|
|
3029
|
-
this._thickness.value = v;
|
|
3030
|
-
}
|
|
3031
|
-
/** Screen size for screenspace calculations */
|
|
3032
|
-
get size() {
|
|
3033
|
-
return this._size.value;
|
|
3034
|
-
}
|
|
3035
|
-
set size(v) {
|
|
3036
|
-
this._size.value = v;
|
|
2624
|
+
this.outputNode = Fn(() => vec4(materialColor, materialOpacity))();
|
|
3037
2625
|
}
|
|
3038
2626
|
}
|
|
3039
2627
|
function Outlines({
|
|
@@ -4743,7 +4331,7 @@ const ScrollHtml = React.forwardRef(
|
|
|
4743
4331
|
const group = React.useRef(null);
|
|
4744
4332
|
React.useImperativeHandle(ref, () => group.current, []);
|
|
4745
4333
|
const { width, height } = useThree((state2) => state2.size);
|
|
4746
|
-
const fiberState = React.useContext(context$
|
|
4334
|
+
const fiberState = React.useContext(context$b);
|
|
4747
4335
|
const root = React.useMemo(() => {
|
|
4748
4336
|
let root2 = rootCache.get(state.fixed);
|
|
4749
4337
|
if (!root2) {
|
|
@@ -4771,7 +4359,7 @@ const ScrollHtml = React.forwardRef(
|
|
|
4771
4359
|
style: { ...style, position: "absolute", top: 0, left: 0, willChange: "transform" },
|
|
4772
4360
|
...props
|
|
4773
4361
|
},
|
|
4774
|
-
/* @__PURE__ */ React.createElement(context$7.Provider, { value: state }, /* @__PURE__ */ React.createElement(context$
|
|
4362
|
+
/* @__PURE__ */ React.createElement(context$7.Provider, { value: state }, /* @__PURE__ */ React.createElement(context$b.Provider, { value: fiberState }, children))
|
|
4775
4363
|
)
|
|
4776
4364
|
);
|
|
4777
4365
|
return null;
|
|
@@ -10159,7 +9747,7 @@ const HtmlView = /* @__PURE__ */ React.forwardRef(
|
|
|
10159
9747
|
);
|
|
10160
9748
|
const View = /* @__PURE__ */ (() => {
|
|
10161
9749
|
const _View = React.forwardRef((props, fref) => {
|
|
10162
|
-
const store = React.useContext(context$
|
|
9750
|
+
const store = React.useContext(context$b);
|
|
10163
9751
|
if (!store) return /* @__PURE__ */ React.createElement(HtmlView, { ref: fref, ...props });
|
|
10164
9752
|
else return /* @__PURE__ */ React.createElement(CanvasView, { ref: fref, ...props });
|
|
10165
9753
|
});
|
|
@@ -11321,62 +10909,63 @@ const remap = /* @__PURE__ */ Fn((inputs) => {
|
|
|
11321
10909
|
const [value, min1, max1, min2, max2] = inputs;
|
|
11322
10910
|
return min2.add(value.sub(min1).mul(max2.sub(min2)).div(max1.sub(min1)));
|
|
11323
10911
|
});
|
|
11324
|
-
class WireframeMaterialImpl extends MeshBasicNodeMaterial {
|
|
11325
|
-
|
|
11326
|
-
|
|
11327
|
-
|
|
11328
|
-
|
|
11329
|
-
|
|
11330
|
-
|
|
11331
|
-
|
|
11332
|
-
|
|
11333
|
-
|
|
11334
|
-
|
|
11335
|
-
|
|
11336
|
-
|
|
11337
|
-
|
|
11338
|
-
|
|
11339
|
-
|
|
11340
|
-
|
|
11341
|
-
|
|
10912
|
+
class WireframeMaterialImpl extends withUniforms(MeshBasicNodeMaterial, {
|
|
10913
|
+
/** Stroke (edge) opacity, default: 1 */
|
|
10914
|
+
strokeOpacity: () => uniform(1),
|
|
10915
|
+
/** Fill opacity (background), default: 0.25 */
|
|
10916
|
+
fillOpacity: () => uniform(0.25),
|
|
10917
|
+
/** Mix factor between material color and fill color, default: 0 */
|
|
10918
|
+
fillMix: () => uniform(0),
|
|
10919
|
+
/** Edge thickness 0-1, default: 0.05 */
|
|
10920
|
+
thickness: () => uniform(0.05),
|
|
10921
|
+
/** Use different color for backfaces, default: false */
|
|
10922
|
+
colorBackfaces: () => uniform(false),
|
|
10923
|
+
/** Invert dash pattern, default: true */
|
|
10924
|
+
dashInvert: () => uniform(true),
|
|
10925
|
+
/** Enable dashed lines, default: false */
|
|
10926
|
+
dash: () => uniform(false),
|
|
10927
|
+
/** Number of dash repeats, default: 4 */
|
|
10928
|
+
dashRepeats: () => uniform(4),
|
|
10929
|
+
/** Dash length 0-1, default: 0.5 */
|
|
10930
|
+
dashLength: () => uniform(0.5),
|
|
10931
|
+
/** Squeeze thickness toward line center, default: false */
|
|
10932
|
+
squeeze: () => uniform(false),
|
|
10933
|
+
/** Minimum squeeze factor, default: 0.2 */
|
|
10934
|
+
squeezeMin: () => uniform(0.2),
|
|
10935
|
+
/** Maximum squeeze factor, default: 1 */
|
|
10936
|
+
squeezeMax: () => uniform(1),
|
|
10937
|
+
/** Stroke (edge) color */
|
|
10938
|
+
stroke: () => uniform(new THREE.Color("#ff0000")),
|
|
10939
|
+
/** Backface stroke color */
|
|
10940
|
+
backfaceStroke: () => uniform(new THREE.Color("#0000ff")),
|
|
10941
|
+
/** Fill (background) color */
|
|
10942
|
+
fill: () => uniform(new THREE.Color("#00ff00"))
|
|
10943
|
+
}) {
|
|
11342
10944
|
/** Type flag for identification */
|
|
11343
10945
|
isWireframeMaterial = true;
|
|
11344
10946
|
constructor() {
|
|
11345
10947
|
super();
|
|
11346
|
-
this._strokeOpacity = uniform(1);
|
|
11347
|
-
this._fillOpacity = uniform(0.25);
|
|
11348
|
-
this._fillMix = uniform(0);
|
|
11349
|
-
this._thickness = uniform(0.05);
|
|
11350
|
-
this._colorBackfaces = uniform(0);
|
|
11351
|
-
this._dashInvert = uniform(1);
|
|
11352
|
-
this._dash = uniform(0);
|
|
11353
|
-
this._dashRepeats = uniform(4);
|
|
11354
|
-
this._dashLength = uniform(0.5);
|
|
11355
|
-
this._squeeze = uniform(0);
|
|
11356
|
-
this._squeezeMin = uniform(0.2);
|
|
11357
|
-
this._squeezeMax = uniform(1);
|
|
11358
|
-
this._stroke = uniform(new THREE.Color("#ff0000"));
|
|
11359
|
-
this._backfaceStroke = uniform(new THREE.Color("#0000ff"));
|
|
11360
|
-
this._fill = uniform(new THREE.Color("#00ff00"));
|
|
11361
10948
|
this.transparent = true;
|
|
11362
10949
|
this.side = THREE.DoubleSide;
|
|
11363
10950
|
this._buildWireframeShader();
|
|
11364
10951
|
}
|
|
11365
10952
|
_buildWireframeShader() {
|
|
11366
|
-
const
|
|
11367
|
-
|
|
11368
|
-
|
|
11369
|
-
|
|
11370
|
-
|
|
11371
|
-
|
|
11372
|
-
|
|
11373
|
-
|
|
11374
|
-
|
|
11375
|
-
|
|
11376
|
-
|
|
11377
|
-
|
|
11378
|
-
|
|
11379
|
-
|
|
10953
|
+
const {
|
|
10954
|
+
strokeOpacity: strokeOpacityUniform,
|
|
10955
|
+
fillOpacity: fillOpacityUniform,
|
|
10956
|
+
thickness: thicknessUniform,
|
|
10957
|
+
colorBackfaces: colorBackfacesUniform,
|
|
10958
|
+
dashInvert: dashInvertUniform,
|
|
10959
|
+
dash: dashUniform,
|
|
10960
|
+
dashRepeats: dashRepeatsUniform,
|
|
10961
|
+
dashLength: dashLengthUniform,
|
|
10962
|
+
squeeze: squeezeUniform,
|
|
10963
|
+
squeezeMin: squeezeMinUniform,
|
|
10964
|
+
squeezeMax: squeezeMaxUniform,
|
|
10965
|
+
stroke: strokeUniform,
|
|
10966
|
+
backfaceStroke: backfaceStrokeUniform,
|
|
10967
|
+
fill: fillUniform
|
|
10968
|
+
} = this.uniforms;
|
|
11380
10969
|
const barycentricAttr = attribute("barycentric", "vec3");
|
|
11381
10970
|
const vBarycentric = varying(barycentricAttr, "v_barycentric");
|
|
11382
10971
|
this.outputNode = Fn(() => {
|
|
@@ -11387,136 +10976,23 @@ class WireframeMaterialImpl extends MeshBasicNodeMaterial {
|
|
|
11387
10976
|
const isYSmallest = barycentric.y.lessThan(barycentric.x).and(barycentric.y.lessThan(barycentric.z));
|
|
11388
10977
|
positionAlong.assign(select(isYSmallest, float(1).sub(maxXY), maxXY));
|
|
11389
10978
|
const computedThickness = remap(thicknessUniform, float(0), float(1), float(0), float(0.34)).toVar();
|
|
11390
|
-
const squeezeEnabled = squeezeUniform.greaterThan(0.5);
|
|
11391
10979
|
const squeezeFactor = mix(squeezeMinUniform, squeezeMaxUniform, float(1).sub(sin(positionAlong.mul(Math.PI))));
|
|
11392
|
-
computedThickness.assign(select(
|
|
11393
|
-
const dashEnabled = dashUniform.greaterThan(0.5);
|
|
11394
|
-
const dashInverted = dashInvertUniform.greaterThan(0.5);
|
|
10980
|
+
computedThickness.assign(select(squeezeUniform, computedThickness.mul(squeezeFactor), computedThickness));
|
|
11395
10981
|
const baseOffset = float(1).div(dashRepeatsUniform).mul(dashLengthUniform).mul(0.5);
|
|
11396
10982
|
const additionalOffset = float(1).div(dashRepeatsUniform).mul(0.5);
|
|
11397
|
-
const dashOffset = select(
|
|
10983
|
+
const dashOffset = select(dashInvertUniform, baseOffset, baseOffset.add(additionalOffset));
|
|
11398
10984
|
const pattern = fract(positionAlong.add(dashOffset).mul(dashRepeatsUniform));
|
|
11399
10985
|
const dashMask = float(1).sub(aastep(dashLengthUniform, pattern));
|
|
11400
|
-
computedThickness.assign(select(
|
|
10986
|
+
computedThickness.assign(select(dashUniform, computedThickness.mul(dashMask), computedThickness));
|
|
11401
10987
|
const edge = float(1).sub(aastep(computedThickness, d));
|
|
11402
|
-
const useBackfaceColor = colorBackfacesUniform.greaterThan(0.5);
|
|
11403
10988
|
const isFrontFace = frontFacing;
|
|
11404
|
-
const currentStroke = select(
|
|
10989
|
+
const currentStroke = select(colorBackfacesUniform.and(isFrontFace.not()), backfaceStrokeUniform, strokeUniform);
|
|
11405
10990
|
const colorStroke = vec4(currentStroke, edge);
|
|
11406
10991
|
const colorFill = vec4(fillUniform, fillOpacityUniform);
|
|
11407
10992
|
const outColor = mix(colorFill, colorStroke, edge.mul(strokeOpacityUniform));
|
|
11408
10993
|
return outColor;
|
|
11409
10994
|
})();
|
|
11410
10995
|
}
|
|
11411
|
-
//* Uniform Accessors ==============================
|
|
11412
|
-
/** Stroke (edge) opacity, default: 1 */
|
|
11413
|
-
get strokeOpacity() {
|
|
11414
|
-
return this._strokeOpacity.value;
|
|
11415
|
-
}
|
|
11416
|
-
set strokeOpacity(v) {
|
|
11417
|
-
this._strokeOpacity.value = v;
|
|
11418
|
-
}
|
|
11419
|
-
/** Fill opacity (background), default: 0.25 */
|
|
11420
|
-
get fillOpacity() {
|
|
11421
|
-
return this._fillOpacity.value;
|
|
11422
|
-
}
|
|
11423
|
-
set fillOpacity(v) {
|
|
11424
|
-
this._fillOpacity.value = v;
|
|
11425
|
-
}
|
|
11426
|
-
/** Mix factor between material color and fill color, default: 0 */
|
|
11427
|
-
get fillMix() {
|
|
11428
|
-
return this._fillMix.value;
|
|
11429
|
-
}
|
|
11430
|
-
set fillMix(v) {
|
|
11431
|
-
this._fillMix.value = v;
|
|
11432
|
-
}
|
|
11433
|
-
/** Edge thickness 0-1, default: 0.05 */
|
|
11434
|
-
get thickness() {
|
|
11435
|
-
return this._thickness.value;
|
|
11436
|
-
}
|
|
11437
|
-
set thickness(v) {
|
|
11438
|
-
this._thickness.value = v;
|
|
11439
|
-
}
|
|
11440
|
-
/** Use different color for backfaces */
|
|
11441
|
-
get colorBackfaces() {
|
|
11442
|
-
return this._colorBackfaces.value > 0.5;
|
|
11443
|
-
}
|
|
11444
|
-
set colorBackfaces(v) {
|
|
11445
|
-
this._colorBackfaces.value = v ? 1 : 0;
|
|
11446
|
-
}
|
|
11447
|
-
/** Invert dash pattern */
|
|
11448
|
-
get dashInvert() {
|
|
11449
|
-
return this._dashInvert.value > 0.5;
|
|
11450
|
-
}
|
|
11451
|
-
set dashInvert(v) {
|
|
11452
|
-
this._dashInvert.value = v ? 1 : 0;
|
|
11453
|
-
}
|
|
11454
|
-
/** Enable dashed lines */
|
|
11455
|
-
get dash() {
|
|
11456
|
-
return this._dash.value > 0.5;
|
|
11457
|
-
}
|
|
11458
|
-
set dash(v) {
|
|
11459
|
-
this._dash.value = v ? 1 : 0;
|
|
11460
|
-
}
|
|
11461
|
-
/** Number of dash repeats, default: 4 */
|
|
11462
|
-
get dashRepeats() {
|
|
11463
|
-
return this._dashRepeats.value;
|
|
11464
|
-
}
|
|
11465
|
-
set dashRepeats(v) {
|
|
11466
|
-
this._dashRepeats.value = v;
|
|
11467
|
-
}
|
|
11468
|
-
/** Dash length 0-1, default: 0.5 */
|
|
11469
|
-
get dashLength() {
|
|
11470
|
-
return this._dashLength.value;
|
|
11471
|
-
}
|
|
11472
|
-
set dashLength(v) {
|
|
11473
|
-
this._dashLength.value = v;
|
|
11474
|
-
}
|
|
11475
|
-
/** Squeeze thickness toward line center */
|
|
11476
|
-
get squeeze() {
|
|
11477
|
-
return this._squeeze.value > 0.5;
|
|
11478
|
-
}
|
|
11479
|
-
set squeeze(v) {
|
|
11480
|
-
this._squeeze.value = v ? 1 : 0;
|
|
11481
|
-
}
|
|
11482
|
-
/** Minimum squeeze factor, default: 0.2 */
|
|
11483
|
-
get squeezeMin() {
|
|
11484
|
-
return this._squeezeMin.value;
|
|
11485
|
-
}
|
|
11486
|
-
set squeezeMin(v) {
|
|
11487
|
-
this._squeezeMin.value = v;
|
|
11488
|
-
}
|
|
11489
|
-
/** Maximum squeeze factor, default: 1 */
|
|
11490
|
-
get squeezeMax() {
|
|
11491
|
-
return this._squeezeMax.value;
|
|
11492
|
-
}
|
|
11493
|
-
set squeezeMax(v) {
|
|
11494
|
-
this._squeezeMax.value = v;
|
|
11495
|
-
}
|
|
11496
|
-
/** Stroke (edge) color */
|
|
11497
|
-
get stroke() {
|
|
11498
|
-
return this._stroke.value;
|
|
11499
|
-
}
|
|
11500
|
-
set stroke(v) {
|
|
11501
|
-
if (v instanceof THREE.Color) this._stroke.value = v;
|
|
11502
|
-
else this._stroke.value = new THREE.Color(v);
|
|
11503
|
-
}
|
|
11504
|
-
/** Backface stroke color */
|
|
11505
|
-
get backfaceStroke() {
|
|
11506
|
-
return this._backfaceStroke.value;
|
|
11507
|
-
}
|
|
11508
|
-
set backfaceStroke(v) {
|
|
11509
|
-
if (v instanceof THREE.Color) this._backfaceStroke.value = v;
|
|
11510
|
-
else this._backfaceStroke.value = new THREE.Color(v);
|
|
11511
|
-
}
|
|
11512
|
-
/** Fill (background) color */
|
|
11513
|
-
get fill() {
|
|
11514
|
-
return this._fill.value;
|
|
11515
|
-
}
|
|
11516
|
-
set fill(v) {
|
|
11517
|
-
if (v instanceof THREE.Color) this._fill.value = v;
|
|
11518
|
-
else this._fill.value = new THREE.Color(v);
|
|
11519
|
-
}
|
|
11520
10996
|
}
|
|
11521
10997
|
function setBarycentricCoordinates(geometry) {
|
|
11522
10998
|
const position = geometry.getAttribute("position");
|
|
@@ -11578,9 +11054,9 @@ const WireframeMaterial = /* @__PURE__ */ React.forwardRef(
|
|
|
11578
11054
|
squeeze,
|
|
11579
11055
|
squeezeMin,
|
|
11580
11056
|
squeezeMax,
|
|
11581
|
-
stroke
|
|
11582
|
-
backfaceStroke
|
|
11583
|
-
fill
|
|
11057
|
+
stroke,
|
|
11058
|
+
backfaceStroke,
|
|
11059
|
+
fill
|
|
11584
11060
|
}
|
|
11585
11061
|
);
|
|
11586
11062
|
}
|
|
@@ -11696,52 +11172,74 @@ function Wireframe({ geometry: customGeometry, ...props }) {
|
|
|
11696
11172
|
return /* @__PURE__ */ React.createElement(WireframeWithoutCustomGeo, { ...props });
|
|
11697
11173
|
}
|
|
11698
11174
|
|
|
11175
|
+
function isShadowCastingLight(object) {
|
|
11176
|
+
const light = object;
|
|
11177
|
+
return light.isLight === true && light.castShadow === true && light.shadow != null;
|
|
11178
|
+
}
|
|
11699
11179
|
function BakeShadows() {
|
|
11700
|
-
const
|
|
11701
|
-
|
|
11702
|
-
|
|
11703
|
-
|
|
11180
|
+
const scene = useThree((state) => state.scene);
|
|
11181
|
+
const priorRef = React.useRef(/* @__PURE__ */ new WeakMap());
|
|
11182
|
+
useFrame(() => {
|
|
11183
|
+
const prior = priorRef.current;
|
|
11184
|
+
scene.traverse((object) => {
|
|
11185
|
+
if (!isShadowCastingLight(object)) return;
|
|
11186
|
+
const shadow = object.shadow;
|
|
11187
|
+
if (prior.has(shadow)) return;
|
|
11188
|
+
prior.set(shadow, { autoUpdate: shadow.autoUpdate, needsUpdate: shadow.needsUpdate });
|
|
11189
|
+
shadow.autoUpdate = false;
|
|
11190
|
+
shadow.needsUpdate = true;
|
|
11191
|
+
});
|
|
11192
|
+
});
|
|
11193
|
+
React.useEffect(() => {
|
|
11194
|
+
const prior = priorRef.current;
|
|
11704
11195
|
return () => {
|
|
11705
|
-
|
|
11196
|
+
scene.traverse((object) => {
|
|
11197
|
+
if (!isShadowCastingLight(object)) return;
|
|
11198
|
+
const previous = prior.get(object.shadow);
|
|
11199
|
+
if (previous === void 0) return;
|
|
11200
|
+
object.shadow.autoUpdate = previous.autoUpdate;
|
|
11201
|
+
object.shadow.needsUpdate = previous.needsUpdate;
|
|
11202
|
+
prior.delete(object.shadow);
|
|
11203
|
+
});
|
|
11706
11204
|
};
|
|
11707
|
-
}, [
|
|
11205
|
+
}, [scene]);
|
|
11708
11206
|
return null;
|
|
11709
11207
|
}
|
|
11710
11208
|
|
|
11711
|
-
class ConvolutionMaterial extends MeshBasicNodeMaterial {
|
|
11712
|
-
|
|
11713
|
-
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
|
|
11720
|
-
|
|
11721
|
-
|
|
11722
|
-
|
|
11723
|
-
|
|
11724
|
-
|
|
11725
|
-
|
|
11726
|
-
|
|
11209
|
+
class ConvolutionMaterial extends withUniforms(MeshBasicNodeMaterial, {
|
|
11210
|
+
/** Input color buffer to blur */
|
|
11211
|
+
inputBuffer: () => uniformTexture(new THREE.Texture()),
|
|
11212
|
+
/** Depth buffer for depth-aware blur */
|
|
11213
|
+
depthBuffer: () => uniformTexture(new THREE.Texture()),
|
|
11214
|
+
/** Render resolution */
|
|
11215
|
+
resolution: () => uniform(new THREE.Vector2()),
|
|
11216
|
+
/** Texel size (1/resolution) */
|
|
11217
|
+
texelSize: () => uniform(new THREE.Vector2()),
|
|
11218
|
+
/** Half texel size for offset calculations */
|
|
11219
|
+
halfTexelSize: () => uniform(new THREE.Vector2()),
|
|
11220
|
+
/** Kernel offset multiplier (changes per blur pass) */
|
|
11221
|
+
kernelValue: () => uniform(0),
|
|
11222
|
+
/** Scale factor for blur spread */
|
|
11223
|
+
scale: () => uniform(1),
|
|
11224
|
+
/** Camera near plane for depth calculations */
|
|
11225
|
+
cameraNear: () => uniform(0),
|
|
11226
|
+
/** Camera far plane for depth calculations */
|
|
11227
|
+
cameraFar: () => uniform(1),
|
|
11228
|
+
/** Minimum depth threshold for blur (objects closer than this get less blur) */
|
|
11229
|
+
minDepthThreshold: () => uniform(0),
|
|
11230
|
+
/** Maximum depth threshold for blur (objects farther than this get full blur) */
|
|
11231
|
+
maxDepthThreshold: () => uniform(1),
|
|
11232
|
+
/** Scale factor for depth-based blur adjustment */
|
|
11233
|
+
depthScale: () => uniform(0),
|
|
11234
|
+
/** Bias added to depth-to-blur ratio */
|
|
11235
|
+
depthToBlurRatioBias: () => uniform(0.25),
|
|
11236
|
+
/** Enable depth-based blur */
|
|
11237
|
+
useDepth: () => uniform(false)
|
|
11238
|
+
}) {
|
|
11727
11239
|
/** Kernel weights for multi-pass blur */
|
|
11728
11240
|
kernel;
|
|
11729
11241
|
constructor(texelSize = new THREE.Vector2()) {
|
|
11730
11242
|
super();
|
|
11731
|
-
this._inputBuffer = uniformTexture(new THREE.Texture());
|
|
11732
|
-
this._depthBuffer = uniformTexture(new THREE.Texture());
|
|
11733
|
-
this._resolution = uniform(new THREE.Vector2());
|
|
11734
|
-
this._texelSize = uniform(new THREE.Vector2());
|
|
11735
|
-
this._halfTexelSize = uniform(new THREE.Vector2());
|
|
11736
|
-
this._kernel = uniform(0);
|
|
11737
|
-
this._scale = uniform(1);
|
|
11738
|
-
this._cameraNear = uniform(0);
|
|
11739
|
-
this._cameraFar = uniform(1);
|
|
11740
|
-
this._minDepthThreshold = uniform(0);
|
|
11741
|
-
this._maxDepthThreshold = uniform(1);
|
|
11742
|
-
this._depthScale = uniform(0);
|
|
11743
|
-
this._depthToBlurRatioBias = uniform(0.25);
|
|
11744
|
-
this._useDepth = uniform(0);
|
|
11745
11243
|
this.blending = THREE.NoBlending;
|
|
11746
11244
|
this.depthWrite = false;
|
|
11747
11245
|
this.depthTest = false;
|
|
@@ -11751,16 +11249,19 @@ class ConvolutionMaterial extends MeshBasicNodeMaterial {
|
|
|
11751
11249
|
this._buildShader();
|
|
11752
11250
|
}
|
|
11753
11251
|
_buildShader() {
|
|
11754
|
-
const
|
|
11755
|
-
|
|
11756
|
-
|
|
11757
|
-
|
|
11758
|
-
|
|
11759
|
-
|
|
11760
|
-
|
|
11761
|
-
|
|
11762
|
-
|
|
11763
|
-
|
|
11252
|
+
const {
|
|
11253
|
+
inputBuffer: inputBufferTex,
|
|
11254
|
+
depthBuffer: depthBufferTex,
|
|
11255
|
+
texelSize: texelSizeUniform,
|
|
11256
|
+
halfTexelSize: halfTexelSizeUniform,
|
|
11257
|
+
kernelValue: kernelUniform,
|
|
11258
|
+
scale: scaleUniform,
|
|
11259
|
+
minDepthThreshold: minDepthThresholdUniform,
|
|
11260
|
+
maxDepthThreshold: maxDepthThresholdUniform,
|
|
11261
|
+
depthScale: depthScaleUniform,
|
|
11262
|
+
depthToBlurRatioBias: depthToBlurRatioBiasUniform,
|
|
11263
|
+
useDepth: useDepthUniform
|
|
11264
|
+
} = this.uniforms;
|
|
11764
11265
|
const baseUv = varying(uv(), "vUv");
|
|
11765
11266
|
const dUv = varying(
|
|
11766
11267
|
Fn(() => {
|
|
@@ -11774,17 +11275,16 @@ class ConvolutionMaterial extends MeshBasicNodeMaterial {
|
|
|
11774
11275
|
const vUv3 = varying(Fn(() => vec2$2(baseUv.x.sub(dUv.x), baseUv.y.sub(dUv.y)))(), "vUv3");
|
|
11775
11276
|
this.colorNode = Fn(() => {
|
|
11776
11277
|
const depthFactor = float(0).toVar();
|
|
11777
|
-
const
|
|
11778
|
-
const depthSample = texture(depthBufferTex, baseUv);
|
|
11278
|
+
const depthSample = depthBufferTex.sample(baseUv);
|
|
11779
11279
|
const rawDepth = float(1).sub(depthSample.r.mul(depthSample.a));
|
|
11780
11280
|
const smoothedDepth = smoothstep(minDepthThresholdUniform, maxDepthThresholdUniform, rawDepth);
|
|
11781
11281
|
const scaledDepth = smoothedDepth.mul(depthScaleUniform);
|
|
11782
|
-
const clampedDepth = max(float(0), min(float(1), scaledDepth.add(
|
|
11783
|
-
depthFactor.assign(select(
|
|
11784
|
-
const sample0 =
|
|
11785
|
-
const sample1 =
|
|
11786
|
-
const sample2 =
|
|
11787
|
-
const sample3 =
|
|
11282
|
+
const clampedDepth = max(float(0), min(float(1), scaledDepth.add(depthToBlurRatioBiasUniform)));
|
|
11283
|
+
depthFactor.assign(select(useDepthUniform, clampedDepth, float(0)));
|
|
11284
|
+
const sample0 = inputBufferTex.sample(mix(vUv0, baseUv, depthFactor));
|
|
11285
|
+
const sample1 = inputBufferTex.sample(mix(vUv1, baseUv, depthFactor));
|
|
11286
|
+
const sample2 = inputBufferTex.sample(mix(vUv2, baseUv, depthFactor));
|
|
11287
|
+
const sample3 = inputBufferTex.sample(mix(vUv3, baseUv, depthFactor));
|
|
11788
11288
|
const sum = sample0.add(sample1).add(sample2).add(sample3);
|
|
11789
11289
|
return sum.mul(0.25);
|
|
11790
11290
|
})();
|
|
@@ -11792,111 +11292,90 @@ class ConvolutionMaterial extends MeshBasicNodeMaterial {
|
|
|
11792
11292
|
//* Utility Methods ==============================
|
|
11793
11293
|
/** Set texel size for blur calculations */
|
|
11794
11294
|
setTexelSize(x, y) {
|
|
11795
|
-
this.
|
|
11796
|
-
this.
|
|
11295
|
+
this.uniforms.texelSize.value.set(x, y);
|
|
11296
|
+
this.uniforms.halfTexelSize.value.set(x * 0.5, y * 0.5);
|
|
11797
11297
|
}
|
|
11798
11298
|
/** Set render resolution */
|
|
11799
11299
|
setResolution(resolution) {
|
|
11800
|
-
this.
|
|
11801
|
-
}
|
|
11802
|
-
//* Uniform Accessors ==============================
|
|
11803
|
-
/** Input color buffer to blur */
|
|
11804
|
-
get inputBuffer() {
|
|
11805
|
-
return this._inputBuffer.value;
|
|
11806
|
-
}
|
|
11807
|
-
set inputBuffer(v) {
|
|
11808
|
-
this._inputBuffer.value = v ?? new THREE.Texture();
|
|
11809
|
-
}
|
|
11810
|
-
/** Depth buffer for depth-aware blur */
|
|
11811
|
-
get depthBuffer() {
|
|
11812
|
-
return this._depthBuffer.value;
|
|
11813
|
-
}
|
|
11814
|
-
set depthBuffer(v) {
|
|
11815
|
-
this._depthBuffer.value = v ?? new THREE.Texture();
|
|
11816
|
-
}
|
|
11817
|
-
/** Render resolution */
|
|
11818
|
-
get resolution() {
|
|
11819
|
-
return this._resolution.value;
|
|
11820
|
-
}
|
|
11821
|
-
set resolution(v) {
|
|
11822
|
-
this._resolution.value = v;
|
|
11823
|
-
}
|
|
11824
|
-
/** Texel size (1/resolution) */
|
|
11825
|
-
get texelSize() {
|
|
11826
|
-
return this._texelSize.value;
|
|
11827
|
-
}
|
|
11828
|
-
set texelSize(v) {
|
|
11829
|
-
this._texelSize.value = v;
|
|
11830
|
-
}
|
|
11831
|
-
/** Half texel size for offset calculations */
|
|
11832
|
-
get halfTexelSize() {
|
|
11833
|
-
return this._halfTexelSize.value;
|
|
11834
|
-
}
|
|
11835
|
-
set halfTexelSize(v) {
|
|
11836
|
-
this._halfTexelSize.value = v;
|
|
11837
|
-
}
|
|
11838
|
-
/** Kernel offset multiplier (changes per blur pass) */
|
|
11839
|
-
get kernelValue() {
|
|
11840
|
-
return this._kernel.value;
|
|
11841
|
-
}
|
|
11842
|
-
set kernelValue(v) {
|
|
11843
|
-
this._kernel.value = v;
|
|
11844
|
-
}
|
|
11845
|
-
/** Scale factor for blur spread */
|
|
11846
|
-
get scale() {
|
|
11847
|
-
return this._scale.value;
|
|
11848
|
-
}
|
|
11849
|
-
set scale(v) {
|
|
11850
|
-
this._scale.value = v;
|
|
11851
|
-
}
|
|
11852
|
-
/** Camera near plane for depth calculations */
|
|
11853
|
-
get cameraNear() {
|
|
11854
|
-
return this._cameraNear.value;
|
|
11855
|
-
}
|
|
11856
|
-
set cameraNear(v) {
|
|
11857
|
-
this._cameraNear.value = v;
|
|
11858
|
-
}
|
|
11859
|
-
/** Camera far plane for depth calculations */
|
|
11860
|
-
get cameraFar() {
|
|
11861
|
-
return this._cameraFar.value;
|
|
11862
|
-
}
|
|
11863
|
-
set cameraFar(v) {
|
|
11864
|
-
this._cameraFar.value = v;
|
|
11865
|
-
}
|
|
11866
|
-
/** Minimum depth threshold for blur (objects closer than this get less blur) */
|
|
11867
|
-
get minDepthThreshold() {
|
|
11868
|
-
return this._minDepthThreshold.value;
|
|
11300
|
+
this.uniforms.resolution.value.copy(resolution);
|
|
11869
11301
|
}
|
|
11870
|
-
|
|
11871
|
-
|
|
11872
|
-
|
|
11873
|
-
|
|
11874
|
-
|
|
11875
|
-
|
|
11876
|
-
|
|
11877
|
-
|
|
11878
|
-
|
|
11879
|
-
|
|
11880
|
-
|
|
11881
|
-
|
|
11882
|
-
|
|
11883
|
-
|
|
11884
|
-
|
|
11885
|
-
|
|
11886
|
-
|
|
11887
|
-
|
|
11888
|
-
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
|
|
11892
|
-
|
|
11302
|
+
}
|
|
11303
|
+
|
|
11304
|
+
class BlurPass {
|
|
11305
|
+
renderTargetA;
|
|
11306
|
+
renderTargetB;
|
|
11307
|
+
convolutionMaterial;
|
|
11308
|
+
/** Fullscreen triangle the convolution material is drawn with */
|
|
11309
|
+
screen;
|
|
11310
|
+
renderToScreen = false;
|
|
11311
|
+
constructor({
|
|
11312
|
+
resolution,
|
|
11313
|
+
width = 500,
|
|
11314
|
+
height = 500,
|
|
11315
|
+
minDepthThreshold = 0,
|
|
11316
|
+
maxDepthThreshold = 1,
|
|
11317
|
+
depthScale = 0,
|
|
11318
|
+
depthToBlurRatioBias = 0.25
|
|
11319
|
+
}) {
|
|
11320
|
+
this.renderTargetA = new THREE.RenderTarget(resolution, resolution, {
|
|
11321
|
+
minFilter: THREE.LinearFilter,
|
|
11322
|
+
magFilter: THREE.LinearFilter,
|
|
11323
|
+
stencilBuffer: false,
|
|
11324
|
+
depthBuffer: false,
|
|
11325
|
+
type: THREE.HalfFloatType
|
|
11326
|
+
});
|
|
11327
|
+
this.renderTargetB = this.renderTargetA.clone();
|
|
11328
|
+
const material = new ConvolutionMaterial();
|
|
11329
|
+
material.setTexelSize(1 / width, 1 / height);
|
|
11330
|
+
material.setResolution(new THREE.Vector2(width, height));
|
|
11331
|
+
material.minDepthThreshold = minDepthThreshold;
|
|
11332
|
+
material.maxDepthThreshold = maxDepthThreshold;
|
|
11333
|
+
material.depthScale = depthScale;
|
|
11334
|
+
material.depthToBlurRatioBias = depthToBlurRatioBias;
|
|
11335
|
+
material.useDepth = depthScale > 0;
|
|
11336
|
+
this.convolutionMaterial = material;
|
|
11337
|
+
this.screen = new QuadMesh(material);
|
|
11338
|
+
this.screen.frustumCulled = false;
|
|
11893
11339
|
}
|
|
11894
|
-
/**
|
|
11895
|
-
|
|
11896
|
-
|
|
11340
|
+
/**
|
|
11341
|
+
* Runs the blur.
|
|
11342
|
+
*
|
|
11343
|
+
* Reads `inputBuffer`, ping-pongs through the internal targets, and writes the
|
|
11344
|
+
* final pass into `outputBuffer` (or the canvas when `renderToScreen` is true).
|
|
11345
|
+
* The render target is left bound, matching the legacy pass — restore it with
|
|
11346
|
+
* `renderer.setRenderTarget(null)` when you are done.
|
|
11347
|
+
*/
|
|
11348
|
+
render(renderer, inputBuffer, outputBuffer = null) {
|
|
11349
|
+
const material = this.convolutionMaterial;
|
|
11350
|
+
material.depthBuffer = inputBuffer.depthTexture;
|
|
11351
|
+
const kernel = material.kernel;
|
|
11352
|
+
let lastRT = inputBuffer;
|
|
11353
|
+
let i = 0;
|
|
11354
|
+
const last = kernel.length - 1;
|
|
11355
|
+
for (; i < last; ++i) {
|
|
11356
|
+
const destRT = (i & 1) === 0 ? this.renderTargetA : this.renderTargetB;
|
|
11357
|
+
material.kernelValue = kernel[i];
|
|
11358
|
+
material.inputBuffer = lastRT.texture;
|
|
11359
|
+
renderer.setRenderTarget(destRT);
|
|
11360
|
+
this.screen.render(renderer);
|
|
11361
|
+
lastRT = destRT;
|
|
11362
|
+
}
|
|
11363
|
+
material.kernelValue = kernel[i];
|
|
11364
|
+
material.inputBuffer = lastRT.texture;
|
|
11365
|
+
renderer.setRenderTarget(this.renderToScreen ? null : outputBuffer);
|
|
11366
|
+
this.screen.render(renderer);
|
|
11367
|
+
}
|
|
11368
|
+
/** Resize the intermediate targets and recompute the texel size */
|
|
11369
|
+
setSize(width, height) {
|
|
11370
|
+
this.renderTargetA.setSize(width, height);
|
|
11371
|
+
this.renderTargetB.setSize(width, height);
|
|
11372
|
+
this.convolutionMaterial.setTexelSize(1 / width, 1 / height);
|
|
11373
|
+
this.convolutionMaterial.setResolution(new THREE.Vector2(width, height));
|
|
11897
11374
|
}
|
|
11898
|
-
|
|
11899
|
-
this.
|
|
11375
|
+
dispose() {
|
|
11376
|
+
this.renderTargetA.dispose();
|
|
11377
|
+
this.renderTargetB.dispose();
|
|
11378
|
+
this.convolutionMaterial.dispose();
|
|
11900
11379
|
}
|
|
11901
11380
|
}
|
|
11902
11381
|
|
|
@@ -12094,28 +11573,31 @@ const Image = /* @__PURE__ */ React.forwardRef((props, ref) => {
|
|
|
12094
11573
|
else throw new Error("<Image /> requires a url or texture");
|
|
12095
11574
|
});
|
|
12096
11575
|
|
|
12097
|
-
|
|
12098
|
-
|
|
12099
|
-
|
|
12100
|
-
|
|
12101
|
-
|
|
12102
|
-
|
|
12103
|
-
|
|
12104
|
-
|
|
12105
|
-
|
|
12106
|
-
|
|
12107
|
-
|
|
11576
|
+
const MeshDiscardMaterial = /* @__PURE__ */ React.forwardRef((props, fref) => {
|
|
11577
|
+
const [material] = React.useState(() => new DiscardNodeMaterial());
|
|
11578
|
+
return /* @__PURE__ */ React.createElement("primitive", { object: material, ref: fref, attach: "material", ...props });
|
|
11579
|
+
});
|
|
11580
|
+
|
|
11581
|
+
class SpotLightMaterial extends withUniforms(MeshBasicNodeMaterial, {
|
|
11582
|
+
/** Scene depth (in the R channel) for soft intersection with scene geometry */
|
|
11583
|
+
depth: () => uniformTexture(new THREE.Texture()),
|
|
11584
|
+
/** Distance attenuation factor, default: 5 */
|
|
11585
|
+
attenuation: () => uniform(5),
|
|
11586
|
+
/** Angle falloff power - higher = sharper edges, default: 5 */
|
|
11587
|
+
anglePower: () => uniform(5),
|
|
11588
|
+
/** World position of the cone tip */
|
|
11589
|
+
spotPosition: () => uniform(new THREE.Vector3(0, 0, 0)),
|
|
11590
|
+
/** Light color, default: white */
|
|
11591
|
+
lightColor: () => uniform(new THREE.Color("white")),
|
|
11592
|
+
/** Camera near plane, for depth reconstruction */
|
|
11593
|
+
cameraNear: () => uniform(0.1),
|
|
11594
|
+
/** Camera far plane, for depth reconstruction */
|
|
11595
|
+
cameraFar: () => uniform(100),
|
|
11596
|
+
/** Drawing-buffer size in pixels. Zero disables depth-based soft edges. */
|
|
11597
|
+
resolution: () => uniform(new THREE.Vector2(0, 0))
|
|
11598
|
+
}) {
|
|
12108
11599
|
constructor() {
|
|
12109
11600
|
super();
|
|
12110
|
-
this._depth = uniformTexture(new THREE.Texture());
|
|
12111
|
-
this._opacity = uniform(1);
|
|
12112
|
-
this._attenuation = uniform(5);
|
|
12113
|
-
this._anglePower = uniform(5);
|
|
12114
|
-
this._spotPosition = uniform(new THREE.Vector3(0, 0, 0));
|
|
12115
|
-
this._lightColor = uniform(new THREE.Color("white"));
|
|
12116
|
-
this._cameraNear = uniform(0.1);
|
|
12117
|
-
this._cameraFar = uniform(100);
|
|
12118
|
-
this._resolution = uniform(new THREE.Vector2(0, 0));
|
|
12119
11601
|
this.transparent = true;
|
|
12120
11602
|
this.depthWrite = false;
|
|
12121
11603
|
this.side = THREE.DoubleSide;
|
|
@@ -12123,15 +11605,16 @@ class SpotLightMaterial extends MeshBasicNodeMaterial {
|
|
|
12123
11605
|
}
|
|
12124
11606
|
//* Build TSL Shader ==============================
|
|
12125
11607
|
_buildShader() {
|
|
12126
|
-
const
|
|
12127
|
-
|
|
12128
|
-
|
|
12129
|
-
|
|
12130
|
-
|
|
12131
|
-
|
|
12132
|
-
|
|
12133
|
-
|
|
12134
|
-
|
|
11608
|
+
const {
|
|
11609
|
+
depth: depthTex,
|
|
11610
|
+
attenuation: attenuationUniform,
|
|
11611
|
+
anglePower: anglePowerUniform,
|
|
11612
|
+
spotPosition: spotPositionUniform,
|
|
11613
|
+
lightColor: lightColorUniform,
|
|
11614
|
+
cameraNear: cameraNearUniform,
|
|
11615
|
+
cameraFar: cameraFarUniform,
|
|
11616
|
+
resolution: resolutionUniform
|
|
11617
|
+
} = this.uniforms;
|
|
12135
11618
|
const vNormal = varying(normalize(modelViewMatrix.transformDirection(normalLocal)), "vNormal");
|
|
12136
11619
|
const vIntensity = varying(
|
|
12137
11620
|
saturate(float(1).sub(distance(positionWorld, spotPositionUniform).div(attenuationUniform))),
|
|
@@ -12146,71 +11629,16 @@ class SpotLightMaterial extends MeshBasicNodeMaterial {
|
|
|
12146
11629
|
screenCoordinate.x.div(resolutionUniform.x),
|
|
12147
11630
|
float(1).sub(screenCoordinate.y.div(resolutionUniform.y))
|
|
12148
11631
|
);
|
|
12149
|
-
const sampledDepth =
|
|
11632
|
+
const sampledDepth = depthTex.sample(screenUV).r;
|
|
12150
11633
|
const near = cameraNearUniform;
|
|
12151
11634
|
const far = cameraFarUniform;
|
|
12152
11635
|
const sceneViewZ = near.mul(far).div(far.sub(near).mul(sampledDepth).sub(far));
|
|
12153
11636
|
const depthDiff = vViewZ.sub(sceneViewZ);
|
|
12154
11637
|
const softFactor = smoothstep(float(0), float(1), depthDiff);
|
|
12155
11638
|
intensity.assign(select(hasDepth, intensity.mul(softFactor), intensity));
|
|
12156
|
-
return vec4(lightColorUniform, intensity.mul(
|
|
11639
|
+
return vec4(lightColorUniform, intensity.mul(materialOpacity));
|
|
12157
11640
|
})();
|
|
12158
11641
|
}
|
|
12159
|
-
//* Uniform Accessors ==============================
|
|
12160
|
-
get depth() {
|
|
12161
|
-
return this._depth?.value;
|
|
12162
|
-
}
|
|
12163
|
-
set depth(v) {
|
|
12164
|
-
if (this._depth) this._depth.value = v ?? new THREE.Texture();
|
|
12165
|
-
}
|
|
12166
|
-
get opacity() {
|
|
12167
|
-
return this._opacity?.value;
|
|
12168
|
-
}
|
|
12169
|
-
set opacity(v) {
|
|
12170
|
-
if (this._opacity) this._opacity.value = v;
|
|
12171
|
-
}
|
|
12172
|
-
get attenuation() {
|
|
12173
|
-
return this._attenuation?.value;
|
|
12174
|
-
}
|
|
12175
|
-
set attenuation(v) {
|
|
12176
|
-
if (this._attenuation) this._attenuation.value = v;
|
|
12177
|
-
}
|
|
12178
|
-
get anglePower() {
|
|
12179
|
-
return this._anglePower?.value;
|
|
12180
|
-
}
|
|
12181
|
-
set anglePower(v) {
|
|
12182
|
-
if (this._anglePower) this._anglePower.value = v;
|
|
12183
|
-
}
|
|
12184
|
-
get spotPosition() {
|
|
12185
|
-
return this._spotPosition?.value;
|
|
12186
|
-
}
|
|
12187
|
-
set spotPosition(v) {
|
|
12188
|
-
if (this._spotPosition) this._spotPosition.value = v;
|
|
12189
|
-
}
|
|
12190
|
-
get lightColor() {
|
|
12191
|
-
return this._lightColor?.value;
|
|
12192
|
-
}
|
|
12193
|
-
set lightColor(v) {
|
|
12194
|
-
if (this._lightColor) this._lightColor.value = v;
|
|
12195
|
-
}
|
|
12196
|
-
get cameraNear() {
|
|
12197
|
-
return this._cameraNear?.value;
|
|
12198
|
-
}
|
|
12199
|
-
set cameraNear(v) {
|
|
12200
|
-
if (this._cameraNear) this._cameraNear.value = v;
|
|
12201
|
-
}
|
|
12202
|
-
get cameraFar() {
|
|
12203
|
-
return this._cameraFar?.value;
|
|
12204
|
-
}
|
|
12205
|
-
set cameraFar(v) {
|
|
12206
|
-
if (this._cameraFar) this._cameraFar.value = v;
|
|
12207
|
-
}
|
|
12208
|
-
get resolution() {
|
|
12209
|
-
return this._resolution?.value;
|
|
12210
|
-
}
|
|
12211
|
-
set resolution(v) {
|
|
12212
|
-
if (this._resolution) this._resolution.value = v;
|
|
12213
|
-
}
|
|
12214
11642
|
}
|
|
12215
11643
|
|
|
12216
11644
|
function createHtmlNodeMaterial(transform) {
|
|
@@ -12231,12 +11659,15 @@ const HtmlMaterial = ({ transform }) => {
|
|
|
12231
11659
|
return /* @__PURE__ */ React.createElement("primitive", { object: material, attach: "material" });
|
|
12232
11660
|
};
|
|
12233
11661
|
|
|
12234
|
-
class StarfieldMaterial extends SpriteNodeMaterial {
|
|
12235
|
-
|
|
12236
|
-
|
|
12237
|
-
|
|
11662
|
+
class StarfieldMaterial extends withUniforms(SpriteNodeMaterial, {
|
|
11663
|
+
/** Animation time, advanced by the component each frame */
|
|
11664
|
+
time: () => uniform(0),
|
|
11665
|
+
/** 1 = soft circular fade, 0 = hard-edged circle */
|
|
11666
|
+
fade: () => uniform(1)
|
|
11667
|
+
}) {
|
|
12238
11668
|
constructor() {
|
|
12239
11669
|
super();
|
|
11670
|
+
const { time, fade } = this.uniforms;
|
|
12240
11671
|
this.transparent = true;
|
|
12241
11672
|
this.depthWrite = false;
|
|
12242
11673
|
this.blending = AdditiveBlending;
|
|
@@ -12250,7 +11681,7 @@ class StarfieldMaterial extends SpriteNodeMaterial {
|
|
|
12250
11681
|
const worldPos = modelWorldMatrix.mul(vec4(this.positionNode, 1));
|
|
12251
11682
|
const viewPos = cameraViewMatrix.mul(worldPos);
|
|
12252
11683
|
const distanceAttenuation = float(30).div(viewPos.z.negate());
|
|
12253
|
-
const timeScale = float(3.5).add(sin(
|
|
11684
|
+
const timeScale = float(3.5).add(sin(time.add(100)).mul(0.3));
|
|
12254
11685
|
const size = particleSize.mul(distanceAttenuation).mul(timeScale).mul(0.04);
|
|
12255
11686
|
return vec2$2(size);
|
|
12256
11687
|
})();
|
|
@@ -12259,38 +11690,28 @@ class StarfieldMaterial extends SpriteNodeMaterial {
|
|
|
12259
11690
|
const d = length(quadUV.sub(vec2$2(0.5)));
|
|
12260
11691
|
const softFade = float(1).div(float(1).add(exp(float(16).mul(d.sub(0.25)))));
|
|
12261
11692
|
const hardMask = float(1).sub(d.smoothstep(0.3, 0.5));
|
|
12262
|
-
const circularOpacity = select(
|
|
11693
|
+
const circularOpacity = select(fade.equal(1), softFade, hardMask);
|
|
12263
11694
|
const opacity = circularOpacity.mul(0.7);
|
|
12264
11695
|
return vec4(particleColor, opacity);
|
|
12265
11696
|
})();
|
|
12266
11697
|
}
|
|
12267
|
-
//* Uniform Accessors ==============================
|
|
12268
11698
|
setTime(time) {
|
|
12269
|
-
this.
|
|
11699
|
+
this.time = time;
|
|
12270
11700
|
}
|
|
12271
11701
|
setFade(fade) {
|
|
12272
|
-
this.
|
|
12273
|
-
}
|
|
12274
|
-
get time() {
|
|
12275
|
-
return this._time.value;
|
|
12276
|
-
}
|
|
12277
|
-
set time(value) {
|
|
12278
|
-
this._time.value = value;
|
|
12279
|
-
}
|
|
12280
|
-
get fade() {
|
|
12281
|
-
return this._fade.value;
|
|
12282
|
-
}
|
|
12283
|
-
set fade(value) {
|
|
12284
|
-
this._fade.value = value;
|
|
11702
|
+
this.fade = fade;
|
|
12285
11703
|
}
|
|
12286
11704
|
}
|
|
12287
11705
|
|
|
12288
|
-
class SparklesMaterial extends SpriteNodeMaterial {
|
|
12289
|
-
|
|
12290
|
-
|
|
12291
|
-
|
|
11706
|
+
class SparklesMaterial extends withUniforms(SpriteNodeMaterial, {
|
|
11707
|
+
/** Animation time, advanced by the component each frame */
|
|
11708
|
+
time: () => uniform(0),
|
|
11709
|
+
/** Device pixel ratio, scales the point size */
|
|
11710
|
+
pixelRatio: () => uniform(1)
|
|
11711
|
+
}) {
|
|
12292
11712
|
constructor() {
|
|
12293
11713
|
super();
|
|
11714
|
+
const { time, pixelRatio } = this.uniforms;
|
|
12294
11715
|
this.transparent = true;
|
|
12295
11716
|
this.depthWrite = false;
|
|
12296
11717
|
const particlePosition = attribute("particlePosition", "vec3");
|
|
@@ -12301,13 +11722,13 @@ class SparklesMaterial extends SpriteNodeMaterial {
|
|
|
12301
11722
|
const particleColor = attribute("color", "vec3");
|
|
12302
11723
|
this.positionNode = Fn(() => {
|
|
12303
11724
|
const pos = particlePosition.toVar();
|
|
12304
|
-
pos.y.addAssign(sin(
|
|
12305
|
-
pos.z.addAssign(cos(
|
|
12306
|
-
pos.x.addAssign(cos(
|
|
11725
|
+
pos.y.addAssign(sin(time.mul(particleSpeed).add(pos.x.mul(particleNoise.x).mul(100))).mul(0.2));
|
|
11726
|
+
pos.z.addAssign(cos(time.mul(particleSpeed).add(pos.x.mul(particleNoise.y).mul(100))).mul(0.2));
|
|
11727
|
+
pos.x.addAssign(cos(time.mul(particleSpeed).add(pos.x.mul(particleNoise.z).mul(100))).mul(0.2));
|
|
12307
11728
|
return pos;
|
|
12308
11729
|
})();
|
|
12309
11730
|
this.scaleNode = Fn(() => {
|
|
12310
|
-
const pixelSize = particleSize.mul(25).mul(
|
|
11731
|
+
const pixelSize = particleSize.mul(25).mul(pixelRatio);
|
|
12311
11732
|
const projY = cameraProjectionMatrix.element(1).y;
|
|
12312
11733
|
const viewportH = screenSize.y;
|
|
12313
11734
|
const size = pixelSize.mul(2).div(projY.mul(viewportH));
|
|
@@ -12320,82 +11741,67 @@ class SparklesMaterial extends SpriteNodeMaterial {
|
|
|
12320
11741
|
return vec4(particleColor, strength.mul(particleOpacity));
|
|
12321
11742
|
})();
|
|
12322
11743
|
}
|
|
12323
|
-
|
|
12324
|
-
|
|
12325
|
-
|
|
12326
|
-
|
|
12327
|
-
|
|
12328
|
-
|
|
12329
|
-
|
|
12330
|
-
|
|
12331
|
-
|
|
12332
|
-
|
|
12333
|
-
|
|
12334
|
-
|
|
12335
|
-
|
|
12336
|
-
|
|
12337
|
-
|
|
12338
|
-
|
|
12339
|
-
|
|
12340
|
-
|
|
12341
|
-
|
|
12342
|
-
|
|
12343
|
-
|
|
12344
|
-
|
|
12345
|
-
|
|
12346
|
-
|
|
12347
|
-
|
|
12348
|
-
|
|
12349
|
-
|
|
12350
|
-
|
|
12351
|
-
|
|
12352
|
-
|
|
12353
|
-
_worldCamProjPosition;
|
|
12354
|
-
_worldPlanePosition;
|
|
11744
|
+
}
|
|
11745
|
+
|
|
11746
|
+
class GridMaterialImpl extends withUniforms(MeshBasicNodeMaterial, {
|
|
11747
|
+
/** Cell size, default: 0.5 */
|
|
11748
|
+
cellSize: () => uniform(0.5),
|
|
11749
|
+
/** Section size, default: 1 */
|
|
11750
|
+
sectionSize: () => uniform(1),
|
|
11751
|
+
/** Fade distance, default: 100 */
|
|
11752
|
+
fadeDistance: () => uniform(100),
|
|
11753
|
+
/** Fade strength, default: 1 */
|
|
11754
|
+
fadeStrength: () => uniform(1),
|
|
11755
|
+
/** Fade from camera (1) or origin (0), default: 1 */
|
|
11756
|
+
fadeFrom: () => uniform(1),
|
|
11757
|
+
/** Cell thickness, default: 0.5 */
|
|
11758
|
+
cellThickness: () => uniform(0.5),
|
|
11759
|
+
/** Section thickness, default: 1 */
|
|
11760
|
+
sectionThickness: () => uniform(1),
|
|
11761
|
+
/** Cell color, default: black */
|
|
11762
|
+
cellColor: () => uniform(new THREE.Color("#000000")),
|
|
11763
|
+
/** Section color, default: #2080ff */
|
|
11764
|
+
sectionColor: () => uniform(new THREE.Color("#2080ff")),
|
|
11765
|
+
/** Display the grid infinitely */
|
|
11766
|
+
infiniteGrid: () => uniform(false),
|
|
11767
|
+
/** Follow camera position */
|
|
11768
|
+
followCamera: () => uniform(false),
|
|
11769
|
+
/** Camera projection position on plane (set by component) */
|
|
11770
|
+
worldCamProjPosition: () => uniform(new THREE.Vector3()),
|
|
11771
|
+
/** Plane world position (set by component) */
|
|
11772
|
+
worldPlanePosition: () => uniform(new THREE.Vector3())
|
|
11773
|
+
}) {
|
|
12355
11774
|
/** Type flag for identification */
|
|
12356
11775
|
isGridMaterial = true;
|
|
12357
11776
|
constructor() {
|
|
12358
11777
|
super();
|
|
12359
|
-
this._cellSize = uniform(0.5);
|
|
12360
|
-
this._sectionSize = uniform(1);
|
|
12361
|
-
this._fadeDistance = uniform(100);
|
|
12362
|
-
this._fadeStrength = uniform(1);
|
|
12363
|
-
this._fadeFrom = uniform(1);
|
|
12364
|
-
this._cellThickness = uniform(0.5);
|
|
12365
|
-
this._sectionThickness = uniform(1);
|
|
12366
|
-
this._cellColor = uniform(new THREE.Color("#000000"));
|
|
12367
|
-
this._sectionColor = uniform(new THREE.Color("#2080ff"));
|
|
12368
|
-
this._infiniteGrid = uniform(0);
|
|
12369
|
-
this._followCamera = uniform(0);
|
|
12370
|
-
this._worldCamProjPosition = uniform(new THREE.Vector3());
|
|
12371
|
-
this._worldPlanePosition = uniform(new THREE.Vector3());
|
|
12372
11778
|
this.transparent = true;
|
|
12373
11779
|
this.side = THREE.BackSide;
|
|
12374
11780
|
this._buildGridShader();
|
|
12375
11781
|
}
|
|
12376
11782
|
_buildGridShader() {
|
|
12377
|
-
const
|
|
12378
|
-
|
|
12379
|
-
|
|
12380
|
-
|
|
12381
|
-
|
|
12382
|
-
|
|
12383
|
-
|
|
12384
|
-
|
|
12385
|
-
|
|
12386
|
-
|
|
12387
|
-
|
|
12388
|
-
|
|
12389
|
-
|
|
11783
|
+
const {
|
|
11784
|
+
cellSize: cellSizeUniform,
|
|
11785
|
+
sectionSize: sectionSizeUniform,
|
|
11786
|
+
fadeDistance: fadeDistanceUniform,
|
|
11787
|
+
fadeStrength: fadeStrengthUniform,
|
|
11788
|
+
fadeFrom: fadeFromUniform,
|
|
11789
|
+
cellThickness: cellThicknessUniform,
|
|
11790
|
+
sectionThickness: sectionThicknessUniform,
|
|
11791
|
+
cellColor: cellColorUniform,
|
|
11792
|
+
sectionColor: sectionColorUniform,
|
|
11793
|
+
infiniteGrid: infiniteGridUniform,
|
|
11794
|
+
followCamera: followCameraUniform,
|
|
11795
|
+
worldCamProjPosition: worldCamProjPositionUniform,
|
|
11796
|
+
worldPlanePosition: worldPlanePositionUniform
|
|
11797
|
+
} = this.uniforms;
|
|
12390
11798
|
const computeLocalPosition = Fn(() => {
|
|
12391
11799
|
const pos = positionGeometry;
|
|
12392
11800
|
let localPos = vec3(pos.x, pos.z, pos.y).toVar();
|
|
12393
|
-
const isInfinite = infiniteGridUniform.greaterThan(0.5);
|
|
12394
11801
|
const scaleFactor = float(1).add(fadeDistanceUniform);
|
|
12395
|
-
localPos.assign(select(
|
|
12396
|
-
const isFollowCamera = followCameraUniform.greaterThan(0.5);
|
|
11802
|
+
localPos.assign(select(infiniteGridUniform, localPos.mul(scaleFactor), localPos));
|
|
12397
11803
|
const cameraOffset = worldCamProjPositionUniform.sub(worldPlanePositionUniform);
|
|
12398
|
-
localPos.assign(select(
|
|
11804
|
+
localPos.assign(select(followCameraUniform, localPos.add(cameraOffset), localPos));
|
|
12399
11805
|
return localPos;
|
|
12400
11806
|
});
|
|
12401
11807
|
const vLocalPosition = varying(computeLocalPosition(), "vLocalPosition");
|
|
@@ -12407,12 +11813,10 @@ class GridMaterialImpl extends MeshBasicNodeMaterial {
|
|
|
12407
11813
|
this.positionNode = Fn(() => {
|
|
12408
11814
|
const pos = positionGeometry;
|
|
12409
11815
|
let localPos = vec3(pos.x, pos.z, pos.y).toVar();
|
|
12410
|
-
const isInfinite = infiniteGridUniform.greaterThan(0.5);
|
|
12411
11816
|
const scaleFactor = float(1).add(fadeDistanceUniform);
|
|
12412
|
-
localPos.assign(select(
|
|
12413
|
-
const isFollowCamera = followCameraUniform.greaterThan(0.5);
|
|
11817
|
+
localPos.assign(select(infiniteGridUniform, localPos.mul(scaleFactor), localPos));
|
|
12414
11818
|
const cameraOffset = worldCamProjPositionUniform.sub(worldPlanePositionUniform);
|
|
12415
|
-
localPos.assign(select(
|
|
11819
|
+
localPos.assign(select(followCameraUniform, localPos.add(cameraOffset), localPos));
|
|
12416
11820
|
return localPos;
|
|
12417
11821
|
})();
|
|
12418
11822
|
const getGrid = Fn((inputs) => {
|
|
@@ -12438,100 +11842,6 @@ class GridMaterialImpl extends MeshBasicNodeMaterial {
|
|
|
12438
11842
|
return vec4(gridColor, finalAlpha);
|
|
12439
11843
|
})();
|
|
12440
11844
|
}
|
|
12441
|
-
//* Uniform Accessors ==============================
|
|
12442
|
-
/** Cell size, default: 0.5 */
|
|
12443
|
-
get cellSize() {
|
|
12444
|
-
return this._cellSize.value;
|
|
12445
|
-
}
|
|
12446
|
-
set cellSize(v) {
|
|
12447
|
-
this._cellSize.value = v;
|
|
12448
|
-
}
|
|
12449
|
-
/** Section size, default: 1 */
|
|
12450
|
-
get sectionSize() {
|
|
12451
|
-
return this._sectionSize.value;
|
|
12452
|
-
}
|
|
12453
|
-
set sectionSize(v) {
|
|
12454
|
-
this._sectionSize.value = v;
|
|
12455
|
-
}
|
|
12456
|
-
/** Fade distance, default: 100 */
|
|
12457
|
-
get fadeDistance() {
|
|
12458
|
-
return this._fadeDistance.value;
|
|
12459
|
-
}
|
|
12460
|
-
set fadeDistance(v) {
|
|
12461
|
-
this._fadeDistance.value = v;
|
|
12462
|
-
}
|
|
12463
|
-
/** Fade strength, default: 1 */
|
|
12464
|
-
get fadeStrength() {
|
|
12465
|
-
return this._fadeStrength.value;
|
|
12466
|
-
}
|
|
12467
|
-
set fadeStrength(v) {
|
|
12468
|
-
this._fadeStrength.value = v;
|
|
12469
|
-
}
|
|
12470
|
-
/** Fade from camera (1) or origin (0), default: 1 */
|
|
12471
|
-
get fadeFrom() {
|
|
12472
|
-
return this._fadeFrom.value;
|
|
12473
|
-
}
|
|
12474
|
-
set fadeFrom(v) {
|
|
12475
|
-
this._fadeFrom.value = v;
|
|
12476
|
-
}
|
|
12477
|
-
/** Cell thickness, default: 0.5 */
|
|
12478
|
-
get cellThickness() {
|
|
12479
|
-
return this._cellThickness.value;
|
|
12480
|
-
}
|
|
12481
|
-
set cellThickness(v) {
|
|
12482
|
-
this._cellThickness.value = v;
|
|
12483
|
-
}
|
|
12484
|
-
/** Section thickness, default: 1 */
|
|
12485
|
-
get sectionThickness() {
|
|
12486
|
-
return this._sectionThickness.value;
|
|
12487
|
-
}
|
|
12488
|
-
set sectionThickness(v) {
|
|
12489
|
-
this._sectionThickness.value = v;
|
|
12490
|
-
}
|
|
12491
|
-
/** Cell color */
|
|
12492
|
-
get cellColor() {
|
|
12493
|
-
return this._cellColor.value;
|
|
12494
|
-
}
|
|
12495
|
-
set cellColor(v) {
|
|
12496
|
-
if (v instanceof THREE.Color) this._cellColor.value = v;
|
|
12497
|
-
else this._cellColor.value = new THREE.Color(v);
|
|
12498
|
-
}
|
|
12499
|
-
/** Section color */
|
|
12500
|
-
get sectionColor() {
|
|
12501
|
-
return this._sectionColor.value;
|
|
12502
|
-
}
|
|
12503
|
-
set sectionColor(v) {
|
|
12504
|
-
if (v instanceof THREE.Color) this._sectionColor.value = v;
|
|
12505
|
-
else this._sectionColor.value = new THREE.Color(v);
|
|
12506
|
-
}
|
|
12507
|
-
/** Display the grid infinitely */
|
|
12508
|
-
get infiniteGrid() {
|
|
12509
|
-
return this._infiniteGrid.value > 0.5;
|
|
12510
|
-
}
|
|
12511
|
-
set infiniteGrid(v) {
|
|
12512
|
-
this._infiniteGrid.value = v ? 1 : 0;
|
|
12513
|
-
}
|
|
12514
|
-
/** Follow camera position */
|
|
12515
|
-
get followCamera() {
|
|
12516
|
-
return this._followCamera.value > 0.5;
|
|
12517
|
-
}
|
|
12518
|
-
set followCamera(v) {
|
|
12519
|
-
this._followCamera.value = v ? 1 : 0;
|
|
12520
|
-
}
|
|
12521
|
-
/** Camera projection position on plane (set by component) */
|
|
12522
|
-
get worldCamProjPosition() {
|
|
12523
|
-
return this._worldCamProjPosition.value;
|
|
12524
|
-
}
|
|
12525
|
-
set worldCamProjPosition(v) {
|
|
12526
|
-
this._worldCamProjPosition.value = v;
|
|
12527
|
-
}
|
|
12528
|
-
/** Plane world position (set by component) */
|
|
12529
|
-
get worldPlanePosition() {
|
|
12530
|
-
return this._worldPlanePosition.value;
|
|
12531
|
-
}
|
|
12532
|
-
set worldPlanePosition(v) {
|
|
12533
|
-
this._worldPlanePosition.value = v;
|
|
12534
|
-
}
|
|
12535
11845
|
}
|
|
12536
11846
|
const Grid = /* @__PURE__ */ React.forwardRef(
|
|
12537
11847
|
({
|
|
@@ -12937,4 +12247,181 @@ const Sparkles = /* @__PURE__ */ React.forwardRef(({ noise = 1, count = 100, spe
|
|
|
12937
12247
|
);
|
|
12938
12248
|
});
|
|
12939
12249
|
|
|
12940
|
-
|
|
12250
|
+
if (typeof window !== "undefined") {
|
|
12251
|
+
await import('three/examples/jsm/inspector/tabs/Settings.js');
|
|
12252
|
+
}
|
|
12253
|
+
const InspectorContext = React.createContext(void 0);
|
|
12254
|
+
function useInspectorContext() {
|
|
12255
|
+
const inspector = React.useContext(InspectorContext);
|
|
12256
|
+
if (inspector === void 0) throw new Error("useInspectorControls must be used inside <Inspector>.");
|
|
12257
|
+
return inspector;
|
|
12258
|
+
}
|
|
12259
|
+
function Inspector({ children, hide = false }) {
|
|
12260
|
+
const renderer = useThree((state) => state.renderer);
|
|
12261
|
+
const isLegacy = useThree((state) => state.isLegacy);
|
|
12262
|
+
const frameloop = useThree((state) => state.frameloop);
|
|
12263
|
+
const eventSource = useThree((state) => state.events.connected);
|
|
12264
|
+
const invalidate = useThree((state) => state.invalidate);
|
|
12265
|
+
const [inspector, setInspector] = React.useState(null);
|
|
12266
|
+
const [error, setError] = React.useState(null);
|
|
12267
|
+
const session = React.useRef(null);
|
|
12268
|
+
const hidden = React.useRef(hide);
|
|
12269
|
+
hidden.current = hide;
|
|
12270
|
+
React.useEffect(() => {
|
|
12271
|
+
if (isLegacy) {
|
|
12272
|
+
setError(new Error("Inspector requires an R3F v10 WebGPU renderer. Use <Canvas renderer={true}>."));
|
|
12273
|
+
return;
|
|
12274
|
+
}
|
|
12275
|
+
if (frameloop !== "always") {
|
|
12276
|
+
setError(
|
|
12277
|
+
new Error('Inspector currently requires frameloop="always". Demand and manual rendering are not supported.')
|
|
12278
|
+
);
|
|
12279
|
+
return;
|
|
12280
|
+
}
|
|
12281
|
+
const controller = new AbortController();
|
|
12282
|
+
let current;
|
|
12283
|
+
Promise.all([import('./chunks/inspector-runtime.mjs'), renderer.init()]).then(async ([{ attachInspector }]) => {
|
|
12284
|
+
if (controller.signal.aborted) return;
|
|
12285
|
+
current = await attachInspector(renderer, eventSource, controller.signal);
|
|
12286
|
+
if (controller.signal.aborted) {
|
|
12287
|
+
current.release();
|
|
12288
|
+
return;
|
|
12289
|
+
}
|
|
12290
|
+
current.inspector.domElement.style.display = hidden.current ? "none" : "";
|
|
12291
|
+
session.current = current;
|
|
12292
|
+
setInspector(current.inspector);
|
|
12293
|
+
invalidate();
|
|
12294
|
+
}).catch((reason) => {
|
|
12295
|
+
if (!controller.signal.aborted) setError(reason instanceof Error ? reason : new Error(String(reason)));
|
|
12296
|
+
});
|
|
12297
|
+
return () => {
|
|
12298
|
+
controller.abort();
|
|
12299
|
+
session.current = null;
|
|
12300
|
+
setInspector(null);
|
|
12301
|
+
current?.release();
|
|
12302
|
+
};
|
|
12303
|
+
}, [renderer, isLegacy, frameloop, eventSource, invalidate]);
|
|
12304
|
+
React.useEffect(() => {
|
|
12305
|
+
if (inspector) inspector.domElement.style.display = hide ? "none" : "";
|
|
12306
|
+
}, [inspector, hide]);
|
|
12307
|
+
useFrame(() => session.current?.begin(), { phase: "start", priority: Infinity });
|
|
12308
|
+
useFrame(() => session.current?.finish(), { phase: "finish", priority: -Infinity });
|
|
12309
|
+
if (error) throw error;
|
|
12310
|
+
return /* @__PURE__ */ React.createElement(InspectorContext.Provider, { value: inspector }, children);
|
|
12311
|
+
}
|
|
12312
|
+
|
|
12313
|
+
function isFolder(entry) {
|
|
12314
|
+
return entry.schema !== void 0;
|
|
12315
|
+
}
|
|
12316
|
+
function isColorControl({ color, value }) {
|
|
12317
|
+
return color === true || value?.isColor === true || typeof value === "string" && /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i.test(value);
|
|
12318
|
+
}
|
|
12319
|
+
function readValue(control, value = control.value) {
|
|
12320
|
+
if (isColorControl(control) && typeof control.value === "string") {
|
|
12321
|
+
if (typeof value === "number") return "#" + value.toString(16).padStart(6, "0");
|
|
12322
|
+
if (typeof value === "string") {
|
|
12323
|
+
return value.length === 4 ? "#" + [...value.slice(1)].map((c) => c + c).join("") : value.toLowerCase();
|
|
12324
|
+
}
|
|
12325
|
+
}
|
|
12326
|
+
return value?.isColor ? value.clone() : value;
|
|
12327
|
+
}
|
|
12328
|
+
function buildInitialValues(schema) {
|
|
12329
|
+
return Object.fromEntries(
|
|
12330
|
+
Object.entries(schema).map(([key, entry]) => [
|
|
12331
|
+
key,
|
|
12332
|
+
isFolder(entry) ? buildInitialValues(entry.schema) : readValue(entry)
|
|
12333
|
+
])
|
|
12334
|
+
);
|
|
12335
|
+
}
|
|
12336
|
+
function setIn(obj, path, value) {
|
|
12337
|
+
const [head, ...rest] = path;
|
|
12338
|
+
return {
|
|
12339
|
+
...obj,
|
|
12340
|
+
[head]: rest.length === 0 ? value : setIn(obj[head], rest, value)
|
|
12341
|
+
};
|
|
12342
|
+
}
|
|
12343
|
+
function useInspectorControls(schema, options = {}) {
|
|
12344
|
+
const inspector = useInspectorContext();
|
|
12345
|
+
const invalidate = useThree((state) => state.invalidate);
|
|
12346
|
+
const { title, collapsed } = options;
|
|
12347
|
+
const schemaRef = useRef(schema);
|
|
12348
|
+
schemaRef.current = schema;
|
|
12349
|
+
const [values, setValues] = useState(() => buildInitialValues(schema));
|
|
12350
|
+
const valuesRef = useRef(values);
|
|
12351
|
+
const rootRef = useRef(null);
|
|
12352
|
+
useEffect(() => {
|
|
12353
|
+
if (!inspector) return;
|
|
12354
|
+
const parameters = inspector.parameters;
|
|
12355
|
+
const root = parameters.createGroup(title ?? "Controls");
|
|
12356
|
+
rootRef.current = root;
|
|
12357
|
+
const editors = [];
|
|
12358
|
+
let active = true;
|
|
12359
|
+
function populate(group, currentSchema, currentValues, path) {
|
|
12360
|
+
for (const key of Object.keys(currentSchema)) {
|
|
12361
|
+
const entry = currentSchema[key];
|
|
12362
|
+
if (isFolder(entry)) {
|
|
12363
|
+
const folder = group.addFolder(entry.label ?? key);
|
|
12364
|
+
populate(folder, entry.schema, currentValues[key], [...path, key]);
|
|
12365
|
+
if (entry.collapsed) folder.close();
|
|
12366
|
+
continue;
|
|
12367
|
+
}
|
|
12368
|
+
const control = { ...entry, value: currentValues[key] };
|
|
12369
|
+
const backing = { [key]: readValue(control) };
|
|
12370
|
+
let editor;
|
|
12371
|
+
if (control.options !== void 0) {
|
|
12372
|
+
editor = group.add(backing, key, control.options);
|
|
12373
|
+
} else if (isColorControl(control)) {
|
|
12374
|
+
editor = group.addColor(backing, key);
|
|
12375
|
+
} else if (typeof control.value === "number") {
|
|
12376
|
+
if (control.min !== void 0 && control.max !== void 0) {
|
|
12377
|
+
editor = group.add(backing, key, control.min, control.max, control.step);
|
|
12378
|
+
} else {
|
|
12379
|
+
const number = group.addNumber(backing, key, control.min, control.max);
|
|
12380
|
+
if (control.step !== void 0) number.input.step = String(control.step);
|
|
12381
|
+
editor = number;
|
|
12382
|
+
}
|
|
12383
|
+
} else {
|
|
12384
|
+
editor = group.add(backing, key);
|
|
12385
|
+
}
|
|
12386
|
+
editor.name(control.label ?? key);
|
|
12387
|
+
editors.push(editor);
|
|
12388
|
+
const fullPath = [...path, key];
|
|
12389
|
+
editor.onChange((value) => {
|
|
12390
|
+
if (!active) return;
|
|
12391
|
+
const next = readValue(entry, value);
|
|
12392
|
+
valuesRef.current = setIn(valuesRef.current, fullPath, next);
|
|
12393
|
+
setValues(valuesRef.current);
|
|
12394
|
+
invalidate();
|
|
12395
|
+
let node = schemaRef.current;
|
|
12396
|
+
for (let i = 0; i < fullPath.length - 1 && node; i++) {
|
|
12397
|
+
node = node[fullPath[i]]?.schema;
|
|
12398
|
+
}
|
|
12399
|
+
node?.[key]?.onChange?.(next);
|
|
12400
|
+
});
|
|
12401
|
+
}
|
|
12402
|
+
}
|
|
12403
|
+
populate(root, schemaRef.current, valuesRef.current, []);
|
|
12404
|
+
if (collapsed) root.close();
|
|
12405
|
+
parameters.show();
|
|
12406
|
+
return () => {
|
|
12407
|
+
active = false;
|
|
12408
|
+
rootRef.current = null;
|
|
12409
|
+
for (const editor of editors) editor.onChange(() => {
|
|
12410
|
+
});
|
|
12411
|
+
parameters.paramList.remove(root.paramList);
|
|
12412
|
+
const index = parameters.groups.indexOf(root);
|
|
12413
|
+
if (index !== -1) parameters.groups.splice(index, 1);
|
|
12414
|
+
};
|
|
12415
|
+
}, [inspector, invalidate]);
|
|
12416
|
+
useEffect(() => {
|
|
12417
|
+
rootRef.current?.name(title ?? "Controls");
|
|
12418
|
+
}, [title, inspector]);
|
|
12419
|
+
useEffect(() => {
|
|
12420
|
+
const root = rootRef.current;
|
|
12421
|
+
if (collapsed) root?.close();
|
|
12422
|
+
else if (root && !root.paramList.isOpen) root.paramList.toggle();
|
|
12423
|
+
}, [collapsed, inspector]);
|
|
12424
|
+
return values;
|
|
12425
|
+
}
|
|
12426
|
+
|
|
12427
|
+
export { AccumulativeShadows, AdaptiveDpr, AdaptiveEvents, ArcballControls, BBAnchor, Backdrop, BakeShadows, Billboard, BlurPass, Bounds, Box, CameraShake, Capsule, CatmullRomLine, Caustics, CausticsMaterial, CausticsNormalMaterial, CausticsProjectionMaterial, Center, Circle, Clone, Cloud, CloudInstance, Clouds, ComputedAttribute, Cone, ContactShadows, ConvolutionMaterial, CubeCamera, CubeTexture, CubicBezierLine, CurveModifier, CycleRaycast, Cylinder, Decal, Detailed, DetectGPU, DeviceOrientationControls, DiscardMaterial, DiscardNodeMaterial, Dodecahedron, DragControls, Edges, Environment, EnvironmentCube, EnvironmentMap, EnvironmentPortal, Example, Extrude, FakeCloudMaterial, Fbo, Fbx, FirstPersonControls, Fisheye, Float, FlyControls, GizmoHelper, GizmoViewcube, GizmoViewport, Gltf, GradientTexture, GradientType, Grid, Helper, Html, HtmlMaterial, Hud, Icosahedron, Image, Inspector, Instance, InstancedAttribute, Instances, IsObject, KeyboardControls, Ktx2, Lathe, Lightformer, Line, Loader, MapControls, Mask, MatcapTexture, Merged, MeshDiscardMaterial, MeshDistortMaterial, MeshPortalMaterial, MeshReflectorMaterial, MeshReflectorMaterial$1 as MeshReflectorMaterialImpl, MeshRefractionMaterial, MeshTransmissionMaterial, MeshWobbleMaterial, MotionPathControls, NormalTexture, Octahedron, OrbitControls, OrthographicCamera, Outlines, PCSSShadowNode, PerformanceMonitor, PerspectiveCamera, PivotControls, Plane, Point, PointMaterial, PointMaterialImpl, PointerLockControls, Points, PointsBuffer, Polyhedron, PositionMesh, PositionPoint, PositionalAudio, Preload, PresentationControls, Progress, QuadraticBezierLine, RandomizedLight, RenderCubeTexture, RenderTexture, Resize, Ring, RoundedBox, RoundedBoxGeometry, Sampler, ScreenQuad, ScreenSizer, ScreenSpace, ScreenVideoTexture, Scroll, ScrollControls, Segment, SegmentObject, Segments, Select, Shadow, Shape, Sky, SoftShadows, Sparkles, SparklesMaterial, Sphere, SpotLight, SpotLightMaterial, SpriteAnimator, Stage, StarfieldMaterial, Stars, Stats, StatsGl, Svg, Tetrahedron, Text3D, Texture, Torus, TorusKnot, TrackballControls, Trail, TrailTexture, TransformControls, Tube, VideoTexture, View, WebcamVideoTexture, Wireframe, WireframeMaterial, WireframeMaterialImpl, WireframeMaterialShaders, accumulativeContext, calcPosFromAngles, checkIfFrameIsEmpty, createInstances, getFirstFrame, meshBounds, presetsObj, setBarycentricCoordinates, setWireframeOverride, useAnimations, useAspect, useBounds, useContextBridge, useCubeCamera, useCubeTexture, useCursor, useCustomRaycast, useDepthBuffer, useDetectGPU, useEnvironment, useFBO, useFBX, useFont, useGLTF, useGizmoContext, useHelper, useInspectorControls, useIntersect, useKTX2, useKeyboardControls, useMask, useMatcapTexture, useMotion, useNormalTexture, usePerformanceMonitor, useProgress, useScroll, useSelect, useSpriteAnimator, useSpriteLoader, useSurfaceSampler, useTexture, useTrail, useTrailTexture, useVariants, useVideoTexture, useWireframeUniforms, withUniforms };
|