@react-three/drei 9.74.11 → 9.74.13
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/core/CatmullRomLine.js +2 -0
- package/core/Cloud.js +3 -0
- package/core/CubeCamera.js +1 -0
- package/core/CubicBezierLine.js +2 -0
- package/core/Environment.js +1 -0
- package/core/Example.js +6 -0
- package/core/FaceControls.cjs.js +1 -1
- package/core/FaceControls.js +2 -0
- package/core/FaceLandmarker.cjs.js +1 -1
- package/core/FaceLandmarker.js +3 -2
- package/core/Facemesh.js +2 -0
- package/core/GizmoHelper.js +3 -0
- package/core/GizmoViewcube.js +4 -0
- package/core/GizmoViewport.js +4 -0
- package/core/Gltf.js +4 -0
- package/core/MeshDiscardMaterial.js +2 -0
- package/core/MeshDistortMaterial.js +2 -1
- package/core/MeshReflectorMaterial.js +1 -0
- package/core/MeshRefractionMaterial.js +2 -0
- package/core/MeshTransmissionMaterial.js +1 -0
- package/core/OrthographicCamera.js +1 -0
- package/core/PerspectiveCamera.js +1 -0
- package/core/QuadraticBezierLine.js +2 -0
- package/core/Reflector.js +1 -0
- package/core/SpotLight.js +2 -1
- package/core/Stage.js +7 -0
- package/core/Text3D.js +1 -0
- package/core/Wireframe.js +1 -0
- package/core/index.cjs.js +1 -1
- package/core/index.js +0 -1
- package/core/useKTX2.js +1 -0
- package/core/useMatcapTexture.js +2 -0
- package/core/useNormalTexture.js +1 -0
- package/index.cjs.js +1 -1
- package/materials/DiscardMaterial.js +1 -0
- package/materials/MeshRefractionMaterial.js +1 -1
- package/native/index.cjs.js +1 -1
- package/native/index.js +0 -1
- package/package.json +9 -9
- package/src/core/AccumulativeShadows.js +311 -0
- package/src/core/AdaptiveDpr.js +28 -0
- package/src/core/AdaptiveEvents.js +20 -0
- package/src/core/ArcballControls.js +67 -0
- package/src/core/AsciiRenderer.js +60 -0
- package/src/core/BBAnchor.js +37 -0
- package/src/core/Backdrop.js +36 -0
- package/src/core/BakeShadows.js +16 -0
- package/src/core/Billboard.js +41 -0
- package/src/core/Bounds.js +245 -0
- package/src/core/CameraControls.js +92 -0
- package/src/core/CameraShake.js +61 -0
- package/src/core/CatmullRomLine.js +44 -0
- package/src/core/Caustics.js +375 -0
- package/src/core/Center.js +66 -0
- package/src/core/Clone.js +102 -0
- package/src/core/Cloud.js +59 -0
- package/src/core/ComputedAttribute.js +34 -0
- package/src/core/ContactShadows.js +114 -0
- package/src/core/CubeCamera.js +43 -0
- package/src/core/CubicBezierLine.js +28 -0
- package/src/core/CurveModifier.js +34 -0
- package/src/core/Decal.js +92 -0
- package/src/core/Detailed.js +34 -0
- package/src/core/DeviceOrientationControls.js +51 -0
- package/src/core/Edges.js +36 -0
- package/src/core/Effects.js +93 -0
- package/src/core/Environment.js +132 -0
- package/src/core/Example.js +42 -0
- package/src/core/FaceControls.js +315 -0
- package/src/core/FaceLandmarker.js +43 -0
- package/src/core/Facemesh.js +4545 -0
- package/src/core/FirstPersonControls.js +38 -0
- package/src/core/Float.js +36 -0
- package/src/core/FlyControls.js +55 -0
- package/src/core/GizmoHelper.js +111 -0
- package/src/core/GizmoViewcube.js +152 -0
- package/src/core/GizmoViewport.js +152 -0
- package/src/core/Gltf.js +20 -0
- package/src/core/GradientTexture.js +33 -0
- package/src/core/Grid.js +112 -0
- package/src/core/Hud.js +58 -0
- package/src/core/Image.js +119 -0
- package/src/core/Instances.js +215 -0
- package/src/core/Lightformer.js +51 -0
- package/src/core/Line.js +68 -0
- package/src/core/MapControls.js +64 -0
- package/src/core/MarchingCubes.js +76 -0
- package/src/core/Mask.js +42 -0
- package/src/core/MeshDiscardMaterial.js +15 -0
- package/src/core/MeshDistortMaterial.js +79 -0
- package/src/core/MeshPortalMaterial.js +381 -0
- package/src/core/MeshReflectorMaterial.js +182 -0
- package/src/core/MeshRefractionMaterial.js +79 -0
- package/src/core/MeshTransmissionMaterial.js +395 -0
- package/src/core/MeshWobbleMaterial.js +65 -0
- package/src/core/OrbitControls.js +82 -0
- package/src/core/OrthographicCamera.js +77 -0
- package/src/core/PerformanceMonitor.js +121 -0
- package/src/core/PerspectiveCamera.js +73 -0
- package/src/core/PointMaterial.js +36 -0
- package/src/core/PointerLockControls.js +90 -0
- package/src/core/Points.js +227 -0
- package/src/core/PositionalAudio.js +51 -0
- package/src/core/Preload.js +45 -0
- package/src/core/QuadraticBezierLine.js +44 -0
- package/src/core/Reflector.js +182 -0
- package/src/core/RenderTexture.js +96 -0
- package/src/core/Resize.js +39 -0
- package/src/core/RoundedBox.js +52 -0
- package/src/core/Sampler.js +85 -0
- package/src/core/ScreenQuad.js +24 -0
- package/src/core/ScreenSpace.js +25 -0
- package/src/core/Segments.js +102 -0
- package/src/core/Shadow.js +42 -0
- package/src/core/Sky.js +39 -0
- package/src/core/Sparkles.js +139 -0
- package/src/core/SpotLight.js +231 -0
- package/src/core/SpriteAnimator.js +342 -0
- package/src/core/Stage.js +135 -0
- package/src/core/Stars.js +108 -0
- package/src/core/Stats.js +30 -0
- package/src/core/Svg.js +59 -0
- package/src/core/Text.js +58 -0
- package/src/core/Text3D.js +76 -0
- package/src/core/TrackballControls.js +72 -0
- package/src/core/Trail.js +161 -0
- package/src/core/TransformControls.js +106 -0
- package/src/core/Wireframe.js +185 -0
- package/src/core/meshBounds.js +38 -0
- package/src/core/shaderMaterial.js +39 -0
- package/src/core/shapes.js +68 -0
- package/src/core/softShadows.js +161 -0
- package/src/core/useAnimations.js +56 -0
- package/src/core/useAspect.js +10 -0
- package/src/core/useBVH.js +90 -0
- package/src/core/useBoxProjectedEnv.js +98 -0
- package/src/core/useCamera.js +27 -0
- package/src/core/useContextBridge.js +21 -0
- package/src/core/useCubeCamera.js +49 -0
- package/src/core/useCubeTexture.js +18 -0
- package/src/core/useDepthBuffer.js +38 -0
- package/src/core/useDetectGPU.js +6 -0
- package/src/core/useEnvironment.js +48 -0
- package/src/core/useFBO.js +53 -0
- package/src/core/useFBX.js +12 -0
- package/src/core/useFont.js +20 -0
- package/src/core/useGLTF.js +37 -0
- package/src/core/useHelper.js +31 -0
- package/src/core/useIntersect.js +39 -0
- package/src/core/useKTX2.js +38 -0
- package/src/core/useMatcapTexture.js +45 -0
- package/src/core/useNormalTexture.js +30 -0
- package/src/core/useProgress.js +50 -0
- package/src/core/useTexture.js +35 -0
- package/src/core/useTrailTexture.js +164 -0
- package/src/core/useVideoTexture.js +41 -0
- package/src/helpers/environment-assets.js +14 -0
- package/src/helpers/useEffectfulState.js +18 -0
- package/src/materials/BlurPass.js +75 -0
- package/src/materials/ConvolutionMaterial.js +99 -0
- package/src/materials/DiscardMaterial.js +5 -0
- package/src/materials/MeshReflectorMaterial.js +290 -0
- package/src/materials/MeshRefractionMaterial.js +171 -0
- package/src/materials/SpotLightMaterial.js +111 -0
- package/src/materials/WireframeMaterial.js +235 -0
- package/src/web/CycleRaycast.js +97 -0
- package/src/web/Html.js +417 -0
- package/src/web/KeyboardControls.js +101 -0
- package/src/web/Loader.js +98 -0
- package/src/web/PresentationControls.js +86 -0
- package/src/web/ScrollControls.js +246 -0
- package/src/web/Select.js +175 -0
- package/src/web/View.js +206 -0
- package/src/web/pivotControls/AxisArrow.js +202 -0
- package/src/web/pivotControls/AxisRotator.js +235 -0
- package/src/web/pivotControls/PlaneSlider.js +211 -0
- package/src/web/pivotControls/context.js +5 -0
- package/src/web/pivotControls/index.js +223 -0
- package/src/web/useCursor.js +12 -0
- package/web/Loader.js +2 -0
- package/web/index.cjs.js +1 -1
- package/web/index.js +0 -1
- package/web/pivotControls/AxisArrow.js +3 -0
- package/web/pivotControls/AxisRotator.js +3 -0
- package/web/pivotControls/PlaneSlider.js +3 -0
- package/web/pivotControls/index.js +5 -0
- /package/{helpers → src/helpers}/glsl/DefaultSpotlightShadowShadows.glsl.js +0 -0
- /package/{helpers → src/helpers}/glsl/distort.vert.glsl.js +0 -0
- /package/{index.js → src/index.js} +0 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { applyProps } from '@react-three/fiber';
|
|
4
|
+
|
|
5
|
+
// and @0beqz https://gist.github.com/0beqz/8d51b4ae16d68021a09fb504af708fca
|
|
6
|
+
|
|
7
|
+
const worldposReplace =
|
|
8
|
+
/* glsl */
|
|
9
|
+
`
|
|
10
|
+
#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )
|
|
11
|
+
vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );
|
|
12
|
+
#ifdef BOX_PROJECTED_ENV_MAP
|
|
13
|
+
vWorldPosition = worldPosition.xyz;
|
|
14
|
+
#endif
|
|
15
|
+
#endif
|
|
16
|
+
`;
|
|
17
|
+
const boxProjectDefinitions =
|
|
18
|
+
/*glsl */
|
|
19
|
+
`
|
|
20
|
+
#ifdef BOX_PROJECTED_ENV_MAP
|
|
21
|
+
uniform vec3 envMapSize;
|
|
22
|
+
uniform vec3 envMapPosition;
|
|
23
|
+
varying vec3 vWorldPosition;
|
|
24
|
+
|
|
25
|
+
vec3 parallaxCorrectNormal( vec3 v, vec3 cubeSize, vec3 cubePos ) {
|
|
26
|
+
vec3 nDir = normalize( v );
|
|
27
|
+
vec3 rbmax = ( .5 * cubeSize + cubePos - vWorldPosition ) / nDir;
|
|
28
|
+
vec3 rbmin = ( -.5 * cubeSize + cubePos - vWorldPosition ) / nDir;
|
|
29
|
+
vec3 rbminmax;
|
|
30
|
+
rbminmax.x = ( nDir.x > 0. ) ? rbmax.x : rbmin.x;
|
|
31
|
+
rbminmax.y = ( nDir.y > 0. ) ? rbmax.y : rbmin.y;
|
|
32
|
+
rbminmax.z = ( nDir.z > 0. ) ? rbmax.z : rbmin.z;
|
|
33
|
+
float correction = min( min( rbminmax.x, rbminmax.y ), rbminmax.z );
|
|
34
|
+
vec3 boxIntersection = vWorldPosition + nDir * correction;
|
|
35
|
+
return boxIntersection - cubePos;
|
|
36
|
+
}
|
|
37
|
+
#endif
|
|
38
|
+
`; // will be inserted after "vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );"
|
|
39
|
+
|
|
40
|
+
const getIBLIrradiance_patch =
|
|
41
|
+
/* glsl */
|
|
42
|
+
`
|
|
43
|
+
#ifdef BOX_PROJECTED_ENV_MAP
|
|
44
|
+
worldNormal = parallaxCorrectNormal( worldNormal, envMapSize, envMapPosition );
|
|
45
|
+
#endif
|
|
46
|
+
`; // will be inserted after "reflectVec = inverseTransformDirection( reflectVec, viewMatrix );"
|
|
47
|
+
|
|
48
|
+
const getIBLRadiance_patch =
|
|
49
|
+
/* glsl */
|
|
50
|
+
`
|
|
51
|
+
#ifdef BOX_PROJECTED_ENV_MAP
|
|
52
|
+
reflectVec = parallaxCorrectNormal( reflectVec, envMapSize, envMapPosition );
|
|
53
|
+
#endif
|
|
54
|
+
`;
|
|
55
|
+
|
|
56
|
+
function boxProjectedEnvMap(shader, envMapPosition, envMapSize) {
|
|
57
|
+
shader.defines.BOX_PROJECTED_ENV_MAP = true; // uniforms
|
|
58
|
+
|
|
59
|
+
shader.uniforms.envMapPosition = {
|
|
60
|
+
value: envMapPosition
|
|
61
|
+
};
|
|
62
|
+
shader.uniforms.envMapSize = {
|
|
63
|
+
value: envMapSize
|
|
64
|
+
}; // vertex shader
|
|
65
|
+
|
|
66
|
+
shader.vertexShader = `
|
|
67
|
+
varying vec3 vWorldPosition;
|
|
68
|
+
${shader.vertexShader.replace('#include <worldpos_vertex>', worldposReplace)}`; // fragment shader
|
|
69
|
+
|
|
70
|
+
shader.fragmentShader = `
|
|
71
|
+
${boxProjectDefinitions}
|
|
72
|
+
${shader.fragmentShader.replace('#include <envmap_physical_pars_fragment>', THREE.ShaderChunk.envmap_physical_pars_fragment).replace('vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );', `vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );
|
|
73
|
+
${getIBLIrradiance_patch}
|
|
74
|
+
`).replace('reflectVec = inverseTransformDirection( reflectVec, viewMatrix );', `reflectVec = inverseTransformDirection( reflectVec, viewMatrix );
|
|
75
|
+
${getIBLRadiance_patch}
|
|
76
|
+
`)}`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function useBoxProjectedEnv(position = new THREE.Vector3(), size = new THREE.Vector3()) {
|
|
80
|
+
const [config] = React.useState(() => ({
|
|
81
|
+
position: new THREE.Vector3(),
|
|
82
|
+
size: new THREE.Vector3()
|
|
83
|
+
}));
|
|
84
|
+
applyProps(config, {
|
|
85
|
+
position,
|
|
86
|
+
size
|
|
87
|
+
});
|
|
88
|
+
const ref = React.useRef(null);
|
|
89
|
+
const spread = React.useMemo(() => ({
|
|
90
|
+
ref,
|
|
91
|
+
onBeforeCompile: shader => boxProjectedEnvMap(shader, config.position, config.size),
|
|
92
|
+
customProgramCacheKey: () => JSON.stringify(config.position.toArray()) + JSON.stringify(config.size.toArray())
|
|
93
|
+
}), [...config.position.toArray(), ...config.size.toArray()]);
|
|
94
|
+
React.useLayoutEffect(() => void (ref.current.needsUpdate = true), [config]);
|
|
95
|
+
return spread;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export { useBoxProjectedEnv };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Raycaster, Camera } from 'three';
|
|
3
|
+
import { useThree, applyProps } from '@react-three/fiber';
|
|
4
|
+
|
|
5
|
+
function useCamera(camera, props) {
|
|
6
|
+
const pointer = useThree(state => state.pointer);
|
|
7
|
+
const [raycast] = React.useState(() => {
|
|
8
|
+
const raycaster = new Raycaster();
|
|
9
|
+
/**
|
|
10
|
+
* applyProps is an internal method of r3f and
|
|
11
|
+
* therefore requires its first arg to be an
|
|
12
|
+
* "Instance" a term used with the Reconciler
|
|
13
|
+
* so we have an expect error to mask this
|
|
14
|
+
*/
|
|
15
|
+
// @ts-expect-error
|
|
16
|
+
|
|
17
|
+
if (props) applyProps(raycaster, props, {});
|
|
18
|
+
return function (_, intersects) {
|
|
19
|
+
raycaster.setFromCamera(pointer, camera instanceof Camera ? camera : camera.current);
|
|
20
|
+
const rc = this.constructor.prototype.raycast.bind(this);
|
|
21
|
+
if (rc) rc(raycaster, intersects);
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
return raycast;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { useCamera };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
/* eslint-disable react-hooks/rules-of-hooks */
|
|
4
|
+
function useContextBridge(...contexts) {
|
|
5
|
+
const cRef = React.useRef([]);
|
|
6
|
+
cRef.current = contexts.map(context => React.useContext(context));
|
|
7
|
+
return React.useMemo(() => ({
|
|
8
|
+
children
|
|
9
|
+
}) => contexts.reduceRight((acc, Context, i) => /*#__PURE__*/React.createElement(Context.Provider, {
|
|
10
|
+
value: cRef.current[i],
|
|
11
|
+
children: acc
|
|
12
|
+
}), children
|
|
13
|
+
/*
|
|
14
|
+
* done this way in reference to:
|
|
15
|
+
* https://github.com/DefinitelyTyped/DefinitelyTyped/issues/44572#issuecomment-625878049
|
|
16
|
+
* https://github.com/microsoft/TypeScript/issues/14729
|
|
17
|
+
*/
|
|
18
|
+
), []);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { useContextBridge };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { WebGLCubeRenderTarget, HalfFloatType } from 'three';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { useMemo, useEffect } from 'react';
|
|
5
|
+
import { useThree } from '@react-three/fiber';
|
|
6
|
+
|
|
7
|
+
function useCubeCamera({
|
|
8
|
+
resolution = 256,
|
|
9
|
+
near = 0.1,
|
|
10
|
+
far = 1000,
|
|
11
|
+
envMap,
|
|
12
|
+
fog
|
|
13
|
+
} = {}) {
|
|
14
|
+
const gl = useThree(({
|
|
15
|
+
gl
|
|
16
|
+
}) => gl);
|
|
17
|
+
const scene = useThree(({
|
|
18
|
+
scene
|
|
19
|
+
}) => scene);
|
|
20
|
+
const fbo = useMemo(() => {
|
|
21
|
+
const fbo = new WebGLCubeRenderTarget(resolution);
|
|
22
|
+
fbo.texture.type = HalfFloatType;
|
|
23
|
+
return fbo;
|
|
24
|
+
}, [resolution]);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
return () => {
|
|
27
|
+
fbo.dispose();
|
|
28
|
+
};
|
|
29
|
+
}, [fbo]);
|
|
30
|
+
const camera = useMemo(() => new THREE.CubeCamera(near, far, fbo), [near, far, fbo]);
|
|
31
|
+
let originalFog;
|
|
32
|
+
let originalBackground;
|
|
33
|
+
const update = React.useCallback(() => {
|
|
34
|
+
originalFog = scene.fog;
|
|
35
|
+
originalBackground = scene.background;
|
|
36
|
+
scene.background = envMap || originalBackground;
|
|
37
|
+
scene.fog = fog || originalFog;
|
|
38
|
+
camera.update(gl, scene);
|
|
39
|
+
scene.fog = originalFog;
|
|
40
|
+
scene.background = originalBackground;
|
|
41
|
+
}, [gl, scene, camera]);
|
|
42
|
+
return {
|
|
43
|
+
fbo,
|
|
44
|
+
camera,
|
|
45
|
+
update
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export { useCubeCamera };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CubeTextureLoader } from 'three';
|
|
2
|
+
import { useLoader } from '@react-three/fiber';
|
|
3
|
+
|
|
4
|
+
function useCubeTexture(files, {
|
|
5
|
+
path
|
|
6
|
+
}) {
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
const [cubeTexture] = useLoader( // @ts-ignore
|
|
9
|
+
CubeTextureLoader, [files], loader => loader.setPath(path));
|
|
10
|
+
return cubeTexture;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
useCubeTexture.preload = (files, {
|
|
14
|
+
path
|
|
15
|
+
}) => useLoader.preload( // @ts-ignore
|
|
16
|
+
CubeTextureLoader, [files], loader => loader.setPath(path));
|
|
17
|
+
|
|
18
|
+
export { useCubeTexture };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { DepthTexture, DepthFormat, UnsignedShortType } from 'three';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { useThree, useFrame } from '@react-three/fiber';
|
|
4
|
+
import { useFBO } from './useFBO.js';
|
|
5
|
+
|
|
6
|
+
function useDepthBuffer({
|
|
7
|
+
size = 256,
|
|
8
|
+
frames = Infinity
|
|
9
|
+
} = {}) {
|
|
10
|
+
const dpr = useThree(state => state.viewport.dpr);
|
|
11
|
+
const {
|
|
12
|
+
width,
|
|
13
|
+
height
|
|
14
|
+
} = useThree(state => state.size);
|
|
15
|
+
const w = size || width * dpr;
|
|
16
|
+
const h = size || height * dpr;
|
|
17
|
+
const depthConfig = React.useMemo(() => {
|
|
18
|
+
const depthTexture = new DepthTexture(w, h);
|
|
19
|
+
depthTexture.format = DepthFormat;
|
|
20
|
+
depthTexture.type = UnsignedShortType;
|
|
21
|
+
return {
|
|
22
|
+
depthTexture
|
|
23
|
+
};
|
|
24
|
+
}, [w, h]);
|
|
25
|
+
let count = 0;
|
|
26
|
+
const depthFBO = useFBO(w, h, depthConfig);
|
|
27
|
+
useFrame(state => {
|
|
28
|
+
if (frames === Infinity || count < frames) {
|
|
29
|
+
state.gl.setRenderTarget(depthFBO);
|
|
30
|
+
state.gl.render(state.scene, state.camera);
|
|
31
|
+
state.gl.setRenderTarget(null);
|
|
32
|
+
count++;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
return depthFBO.depthTexture;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { useDepthBuffer };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useLoader } from '@react-three/fiber';
|
|
2
|
+
import { CubeReflectionMapping, EquirectangularReflectionMapping, CubeTextureLoader } from 'three';
|
|
3
|
+
import { RGBELoader, EXRLoader } from 'three-stdlib';
|
|
4
|
+
import { presetsObj } from '../helpers/environment-assets.js';
|
|
5
|
+
|
|
6
|
+
const CUBEMAP_ROOT = 'https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/';
|
|
7
|
+
|
|
8
|
+
const isArray = arr => Array.isArray(arr);
|
|
9
|
+
|
|
10
|
+
function useEnvironment({
|
|
11
|
+
files = ['/px.png', '/nx.png', '/py.png', '/ny.png', '/pz.png', '/nz.png'],
|
|
12
|
+
path = '',
|
|
13
|
+
preset = undefined,
|
|
14
|
+
encoding = undefined,
|
|
15
|
+
extensions
|
|
16
|
+
} = {}) {
|
|
17
|
+
var _files$split$pop;
|
|
18
|
+
|
|
19
|
+
let loader = null;
|
|
20
|
+
let isCubeMap = false;
|
|
21
|
+
let extension;
|
|
22
|
+
|
|
23
|
+
if (preset) {
|
|
24
|
+
if (!(preset in presetsObj)) throw new Error('Preset must be one of: ' + Object.keys(presetsObj).join(', '));
|
|
25
|
+
files = presetsObj[preset];
|
|
26
|
+
path = CUBEMAP_ROOT;
|
|
27
|
+
} // Everything else
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
isCubeMap = isArray(files);
|
|
31
|
+
extension = isArray(files) ? 'cube' : files.startsWith('data:application/exr') ? 'exr' : files.startsWith('data:application/hdr') ? 'hdr' : (_files$split$pop = files.split('.').pop()) == null ? void 0 : _files$split$pop.toLowerCase();
|
|
32
|
+
loader = isCubeMap ? CubeTextureLoader : extension === 'hdr' ? RGBELoader : extension === 'exr' ? EXRLoader : null;
|
|
33
|
+
if (!loader) throw new Error('useEnvironment: Unrecognized file extension: ' + files);
|
|
34
|
+
const loaderResult = useLoader( // @ts-expect-error
|
|
35
|
+
loader, isCubeMap ? [files] : files, loader => {
|
|
36
|
+
loader.setPath == null ? void 0 : loader.setPath(path);
|
|
37
|
+
if (extensions) extensions(loader);
|
|
38
|
+
});
|
|
39
|
+
const texture = isCubeMap ? // @ts-ignore
|
|
40
|
+
loaderResult[0] : loaderResult;
|
|
41
|
+
texture.mapping = isCubeMap ? CubeReflectionMapping : EquirectangularReflectionMapping;
|
|
42
|
+
const sRGBEncoding = 3001;
|
|
43
|
+
const LinearEncoding = 3000;
|
|
44
|
+
if ('colorSpace' in texture) texture.colorSpace = (encoding !== null && encoding !== void 0 ? encoding : isCubeMap) ? 'srgb' : 'srgb-linear';else texture.encoding = (encoding !== null && encoding !== void 0 ? encoding : isCubeMap) ? sRGBEncoding : LinearEncoding;
|
|
45
|
+
return texture;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { useEnvironment };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
import { useThree } from '@react-three/fiber';
|
|
4
|
+
|
|
5
|
+
// 👇 uncomment when TS version supports function overloads
|
|
6
|
+
// export function useFBO(settings?: FBOSettings)
|
|
7
|
+
function useFBO(
|
|
8
|
+
/** Width in pixels, or settings (will render fullscreen by default) */
|
|
9
|
+
width,
|
|
10
|
+
/** Height in pixels */
|
|
11
|
+
height,
|
|
12
|
+
/**Settings */
|
|
13
|
+
settings) {
|
|
14
|
+
const size = useThree(state => state.size);
|
|
15
|
+
const viewport = useThree(state => state.viewport);
|
|
16
|
+
|
|
17
|
+
const _width = typeof width === 'number' ? width : size.width * viewport.dpr;
|
|
18
|
+
|
|
19
|
+
const _height = typeof height === 'number' ? height : size.height * viewport.dpr;
|
|
20
|
+
|
|
21
|
+
const _settings = (typeof width === 'number' ? settings : width) || {};
|
|
22
|
+
|
|
23
|
+
const {
|
|
24
|
+
samples = 0,
|
|
25
|
+
depth,
|
|
26
|
+
...targetSettings
|
|
27
|
+
} = _settings;
|
|
28
|
+
const target = React.useMemo(() => {
|
|
29
|
+
const target = new THREE.WebGLRenderTarget(_width, _height, {
|
|
30
|
+
minFilter: THREE.LinearFilter,
|
|
31
|
+
magFilter: THREE.LinearFilter,
|
|
32
|
+
type: THREE.HalfFloatType,
|
|
33
|
+
...targetSettings
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (depth) {
|
|
37
|
+
target.depthTexture = new THREE.DepthTexture(_width, _height, THREE.FloatType);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
target.samples = samples;
|
|
41
|
+
return target;
|
|
42
|
+
}, []);
|
|
43
|
+
React.useLayoutEffect(() => {
|
|
44
|
+
target.setSize(_width, _height);
|
|
45
|
+
if (samples) target.samples = samples;
|
|
46
|
+
}, [samples, target, _width, _height]);
|
|
47
|
+
React.useEffect(() => {
|
|
48
|
+
return () => target.dispose();
|
|
49
|
+
}, []);
|
|
50
|
+
return target;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { useFBO };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { FBXLoader } from 'three-stdlib';
|
|
2
|
+
import { useLoader } from '@react-three/fiber';
|
|
3
|
+
|
|
4
|
+
function useFBX(path) {
|
|
5
|
+
return useLoader(FBXLoader, path);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
useFBX.preload = path => useLoader.preload(FBXLoader, path);
|
|
9
|
+
|
|
10
|
+
useFBX.clear = input => useLoader.clear(FBXLoader, input);
|
|
11
|
+
|
|
12
|
+
export { useFBX };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { FontLoader } from 'three-stdlib';
|
|
2
|
+
import { suspend, preload, clear } from 'suspend-react';
|
|
3
|
+
|
|
4
|
+
let fontLoader = null;
|
|
5
|
+
|
|
6
|
+
async function loader(font) {
|
|
7
|
+
if (!fontLoader) fontLoader = new FontLoader();
|
|
8
|
+
let data = typeof font === 'string' ? await (await fetch(font)).json() : font;
|
|
9
|
+
return fontLoader.parse(data);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function useFont(font) {
|
|
13
|
+
return suspend(loader, [font]);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
useFont.preload = font => preload(loader, [font]);
|
|
17
|
+
|
|
18
|
+
useFont.clear = font => clear([font]);
|
|
19
|
+
|
|
20
|
+
export { useFont };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { GLTFLoader, DRACOLoader, MeshoptDecoder } from 'three-stdlib';
|
|
2
|
+
import { useLoader } from '@react-three/fiber';
|
|
3
|
+
|
|
4
|
+
// @ts-ignore
|
|
5
|
+
let dracoLoader = null;
|
|
6
|
+
|
|
7
|
+
function extensions(useDraco, useMeshopt, extendLoader) {
|
|
8
|
+
return loader => {
|
|
9
|
+
if (extendLoader) {
|
|
10
|
+
extendLoader(loader);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (useDraco) {
|
|
14
|
+
if (!dracoLoader) {
|
|
15
|
+
dracoLoader = new DRACOLoader();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
dracoLoader.setDecoderPath(typeof useDraco === 'string' ? useDraco : 'https://www.gstatic.com/draco/versioned/decoders/1.5.5/');
|
|
19
|
+
loader.setDRACOLoader(dracoLoader);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (useMeshopt) {
|
|
23
|
+
loader.setMeshoptDecoder(typeof MeshoptDecoder === 'function' ? MeshoptDecoder() : MeshoptDecoder);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function useGLTF(path, useDraco = true, useMeshOpt = true, extendLoader) {
|
|
29
|
+
const gltf = useLoader(GLTFLoader, path, extensions(useDraco, useMeshOpt, extendLoader));
|
|
30
|
+
return gltf;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
useGLTF.preload = (path, useDraco = true, useMeshOpt = true, extendLoader) => useLoader.preload(GLTFLoader, path, extensions(useDraco, useMeshOpt, extendLoader));
|
|
34
|
+
|
|
35
|
+
useGLTF.clear = input => useLoader.clear(GLTFLoader, input);
|
|
36
|
+
|
|
37
|
+
export { useGLTF };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useThree, useFrame } from '@react-three/fiber';
|
|
3
|
+
|
|
4
|
+
function useHelper(object3D, helperConstructor, ...args) {
|
|
5
|
+
const helper = React.useRef();
|
|
6
|
+
const scene = useThree(state => state.scene);
|
|
7
|
+
React.useLayoutEffect(() => {
|
|
8
|
+
let currentHelper = undefined;
|
|
9
|
+
|
|
10
|
+
if (object3D && object3D != null && object3D.current && helperConstructor) {
|
|
11
|
+
helper.current = currentHelper = new helperConstructor(object3D.current, ...args);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (currentHelper) {
|
|
15
|
+
scene.add(currentHelper);
|
|
16
|
+
return () => {
|
|
17
|
+
helper.current = undefined;
|
|
18
|
+
scene.remove(currentHelper);
|
|
19
|
+
currentHelper.dispose == null ? void 0 : currentHelper.dispose();
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
}, [scene, helperConstructor, object3D, ...args]);
|
|
23
|
+
useFrame(() => {
|
|
24
|
+
var _helper$current;
|
|
25
|
+
|
|
26
|
+
return void ((_helper$current = helper.current) == null ? void 0 : _helper$current.update == null ? void 0 : _helper$current.update());
|
|
27
|
+
});
|
|
28
|
+
return helper;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { useHelper };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { addEffect, addAfterEffect } from '@react-three/fiber';
|
|
3
|
+
|
|
4
|
+
function useIntersect(onChange) {
|
|
5
|
+
const ref = React.useRef(null);
|
|
6
|
+
const check = React.useRef(false);
|
|
7
|
+
const temp = React.useRef(false);
|
|
8
|
+
const callback = React.useRef(onChange);
|
|
9
|
+
React.useLayoutEffect(() => void (callback.current = onChange), [onChange]);
|
|
10
|
+
React.useEffect(() => {
|
|
11
|
+
const obj = ref.current;
|
|
12
|
+
|
|
13
|
+
if (obj) {
|
|
14
|
+
// Stamp out frustum check pre-emptively
|
|
15
|
+
const unsub1 = addEffect(() => {
|
|
16
|
+
check.current = false;
|
|
17
|
+
return true;
|
|
18
|
+
}); // If the object is inside the frustum three will call onRender
|
|
19
|
+
|
|
20
|
+
const oldOnRender = obj.onBeforeRender;
|
|
21
|
+
|
|
22
|
+
obj.onBeforeRender = () => check.current = true; // Compare the check value against the temp value, if it differs set state
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
const unsub2 = addAfterEffect(() => {
|
|
26
|
+
if (check.current !== temp.current) callback.current == null ? void 0 : callback.current(temp.current = check.current);
|
|
27
|
+
return true;
|
|
28
|
+
});
|
|
29
|
+
return () => {
|
|
30
|
+
obj.onBeforeRender = oldOnRender;
|
|
31
|
+
unsub1();
|
|
32
|
+
unsub2();
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}, []);
|
|
36
|
+
return ref;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { useIntersect };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useThree, useLoader } from '@react-three/fiber';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
import { KTX2Loader } from 'three-stdlib';
|
|
4
|
+
import { IsObject } from './useTexture.js';
|
|
5
|
+
|
|
6
|
+
const cdn = 'https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master';
|
|
7
|
+
function useKTX2(input, basisPath = `${cdn}/basis/`) {
|
|
8
|
+
const gl = useThree(state => state.gl);
|
|
9
|
+
const textures = useLoader(KTX2Loader, IsObject(input) ? Object.values(input) : input, loader => {
|
|
10
|
+
loader.detectSupport(gl);
|
|
11
|
+
loader.setTranscoderPath(basisPath);
|
|
12
|
+
}); // https://github.com/mrdoob/three.js/issues/22696
|
|
13
|
+
// Upload the texture to the GPU immediately instead of waiting for the first render
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
const array = Array.isArray(textures) ? textures : [textures];
|
|
17
|
+
array.forEach(gl.initTexture);
|
|
18
|
+
}, [gl, textures]);
|
|
19
|
+
|
|
20
|
+
if (IsObject(input)) {
|
|
21
|
+
const keys = Object.keys(input);
|
|
22
|
+
const keyed = {};
|
|
23
|
+
keys.forEach(key => Object.assign(keyed, {
|
|
24
|
+
[key]: textures[keys.indexOf(key)]
|
|
25
|
+
}));
|
|
26
|
+
return keyed;
|
|
27
|
+
} else {
|
|
28
|
+
return textures;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
useKTX2.preload = (url, basisPath = `${cdn}/basis/`) => useLoader.preload(KTX2Loader, url, loader => {
|
|
33
|
+
loader.setTranscoderPath(basisPath);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
useKTX2.clear = input => useLoader.clear(KTX2Loader, input);
|
|
37
|
+
|
|
38
|
+
export { useKTX2 };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useTexture } from './useTexture.js';
|
|
3
|
+
import { suspend } from 'suspend-react';
|
|
4
|
+
|
|
5
|
+
function getFormatString(format) {
|
|
6
|
+
switch (format) {
|
|
7
|
+
case 64:
|
|
8
|
+
return '-64px';
|
|
9
|
+
|
|
10
|
+
case 128:
|
|
11
|
+
return '-128px';
|
|
12
|
+
|
|
13
|
+
case 256:
|
|
14
|
+
return '-256px';
|
|
15
|
+
|
|
16
|
+
case 512:
|
|
17
|
+
return '-512px';
|
|
18
|
+
|
|
19
|
+
default:
|
|
20
|
+
return '';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const LIST_URL = 'https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/matcaps.json';
|
|
25
|
+
const MATCAP_ROOT = 'https://rawcdn.githack.com/emmelleppi/matcaps/9b36ccaaf0a24881a39062d05566c9e92be4aa0d';
|
|
26
|
+
function useMatcapTexture(id = 0, format = 1024, onLoad) {
|
|
27
|
+
const matcapList = suspend(() => fetch(LIST_URL).then(res => res.json()), ['matcapList']);
|
|
28
|
+
const DEFAULT_MATCAP = matcapList[0];
|
|
29
|
+
const numTot = React.useMemo(() => Object.keys(matcapList).length, []);
|
|
30
|
+
const fileHash = React.useMemo(() => {
|
|
31
|
+
if (typeof id === 'string') {
|
|
32
|
+
return id;
|
|
33
|
+
} else if (typeof id === 'number') {
|
|
34
|
+
return matcapList[id];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return null;
|
|
38
|
+
}, [id]);
|
|
39
|
+
const fileName = `${fileHash || DEFAULT_MATCAP}${getFormatString(format)}.png`;
|
|
40
|
+
const url = `${MATCAP_ROOT}/${format}/${fileName}`;
|
|
41
|
+
const matcapTexture = useTexture(url, onLoad);
|
|
42
|
+
return [matcapTexture, url, numTot];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { useMatcapTexture };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useTexture } from './useTexture.js';
|
|
3
|
+
import { RepeatWrapping, Vector2 } from 'three';
|
|
4
|
+
import { suspend } from 'suspend-react';
|
|
5
|
+
|
|
6
|
+
const NORMAL_ROOT = 'https://rawcdn.githack.com/pmndrs/drei-assets/7a3104997e1576f83472829815b00880d88b32fb';
|
|
7
|
+
const LIST_URL = 'https://cdn.jsdelivr.net/gh/pmndrs/drei-assets@master/normals/normals.json';
|
|
8
|
+
function useNormalTexture(id = 0, settings = {}, onLoad) {
|
|
9
|
+
const {
|
|
10
|
+
repeat = [1, 1],
|
|
11
|
+
anisotropy = 1,
|
|
12
|
+
offset = [0, 0]
|
|
13
|
+
} = settings;
|
|
14
|
+
const normalsList = suspend(() => fetch(LIST_URL).then(res => res.json()), ['normalsList']);
|
|
15
|
+
const numTot = React.useMemo(() => Object.keys(normalsList).length, []);
|
|
16
|
+
const DEFAULT_NORMAL = normalsList[0];
|
|
17
|
+
const imageName = normalsList[id] || DEFAULT_NORMAL;
|
|
18
|
+
const url = `${NORMAL_ROOT}/normals/${imageName}`;
|
|
19
|
+
const normalTexture = useTexture(url, onLoad);
|
|
20
|
+
React.useLayoutEffect(() => {
|
|
21
|
+
if (!normalTexture) return;
|
|
22
|
+
normalTexture.wrapS = normalTexture.wrapT = RepeatWrapping;
|
|
23
|
+
normalTexture.repeat = new Vector2(repeat[0], repeat[1]);
|
|
24
|
+
normalTexture.offset = new Vector2(offset[0], offset[1]);
|
|
25
|
+
normalTexture.anisotropy = anisotropy;
|
|
26
|
+
}, [normalTexture, anisotropy, repeat, offset]);
|
|
27
|
+
return [normalTexture, url, numTot];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { useNormalTexture };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { DefaultLoadingManager } from 'three';
|
|
2
|
+
import create from 'zustand';
|
|
3
|
+
|
|
4
|
+
let saveLastTotalLoaded = 0;
|
|
5
|
+
const useProgress = create(set => {
|
|
6
|
+
DefaultLoadingManager.onStart = (item, loaded, total) => {
|
|
7
|
+
set({
|
|
8
|
+
active: true,
|
|
9
|
+
item,
|
|
10
|
+
loaded,
|
|
11
|
+
total,
|
|
12
|
+
progress: (loaded - saveLastTotalLoaded) / (total - saveLastTotalLoaded) * 100
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
DefaultLoadingManager.onLoad = () => {
|
|
17
|
+
set({
|
|
18
|
+
active: false
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
DefaultLoadingManager.onError = item => set(state => ({
|
|
23
|
+
errors: [...state.errors, item]
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
DefaultLoadingManager.onProgress = (item, loaded, total) => {
|
|
27
|
+
if (loaded === total) {
|
|
28
|
+
saveLastTotalLoaded = total;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
set({
|
|
32
|
+
active: true,
|
|
33
|
+
item,
|
|
34
|
+
loaded,
|
|
35
|
+
total,
|
|
36
|
+
progress: (loaded - saveLastTotalLoaded) / (total - saveLastTotalLoaded) * 100 || 100
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
errors: [],
|
|
42
|
+
active: false,
|
|
43
|
+
progress: 0,
|
|
44
|
+
item: '',
|
|
45
|
+
loaded: 0,
|
|
46
|
+
total: 0
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export { useProgress };
|