@react-three/drei 9.17.2 → 9.19.0

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 CHANGED
@@ -179,6 +179,8 @@ The `native` route of the library **does not** export `Html` or `Loader`. The de
179
179
  <li><a href="#spotlight">SpotLight</a></li>
180
180
  <li><a href="#shadow">Shadow</a></li>
181
181
  <li><a href="#contactshadows">ContactShadows</a></li>
182
+ <li><a href="#randomizedlight">RandomizedLight</a></li>
183
+ <li><a href="#accumulativeshadows">AccumulativeShadows</a></li>
182
184
  <li><a href="#sky">Sky</a></li>
183
185
  <li><a href="#stars">Stars</a></li>
184
186
  <li><a href="#sparkles">Sparkles</a></li>
@@ -2143,6 +2145,81 @@ Since this is a rather expensive effect you can limit the amount of frames it re
2143
2145
  <ContactShadows frames={1} />
2144
2146
  ```
2145
2147
 
2148
+ ### RandomizedLight
2149
+
2150
+ A randomized light that internally runs multiple lights and jiggles them. See below, you would normally pair it with `AccumulativeShadows`. This component is context aware, paired with AccumulativeShadows it will take the number of frames from its parent.
2151
+
2152
+ ```tsx
2153
+ type RandomizedLightProps = JSX.IntrinsicElements['group'] & {
2154
+ /** How many frames it will jiggle the lights, 1.
2155
+ * Frames is context aware, if a provider like AccumulativeShadows exists, frames will be taken from there! */
2156
+ frames?: number
2157
+ /** Light position, [0, 0, 0] */
2158
+ position?: [x: number, y: number, z: number]
2159
+ /** Radius of the jiggle, higher values make softer light, 5 */
2160
+ radius?: number
2161
+ /** Amount of lights, 8 */
2162
+ amount?: number
2163
+ /** Light intensity, 1 */
2164
+ intensity?: number
2165
+ /** Ambient occlusion, lower values mean less AO, hight more, you can mix AO and directional light, 0.5 */
2166
+ ambient?: number
2167
+ /** If the lights cast shadows, this is true by default */
2168
+ castShadow?: boolean
2169
+ /** Default shadow bias, 0 */
2170
+ bias?: number
2171
+ /** Default map size, 512 */
2172
+ mapSize?: number
2173
+ /** Default size of the shadow camera, 10 */
2174
+ size?: number
2175
+ /** Default shadow camera near, 0.5 */
2176
+ near?: number
2177
+ /** Default shadow camera far, 500 */
2178
+ far?: number
2179
+ }
2180
+ ```
2181
+
2182
+ ```jsx
2183
+ <RandomizedLight castShadow amount={8} frames={100} position={[5, 5, -10]} />
2184
+ ```
2185
+
2186
+ ###  AccumulativeShadows
2187
+
2188
+ <p>
2189
+ <a href="https://codesandbox.io/s/hxcc1x"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/hxcc1x/screenshot.png" alt="Demo"/></a>
2190
+ </p>
2191
+
2192
+ A planar, Y-up oriented shadow-catcher that can accumulate into soft shadows and has zero performance impact after all frames have accumulated. It can be temporal, it will accumulate over time, or instantaneous, which might expensive depending on how many frames you render.
2193
+
2194
+ You must pair it with lightsources (and scene objects!) that cast shadows, which go into the children slot. Best use it with the `RandomizedLight` component, which jiggles a set of lights around, creating realistic raycast-like shadows and ambient occlusion.
2195
+
2196
+ ```tsx
2197
+ type AccumulativeShadowsProps = JSX.IntrinsicElements['group'] & {
2198
+ /** How many frames it can render, more yields cleaner results but takes more time, 40 */
2199
+ frames?: number
2200
+ /** If frames === Infinity blend controls the refresh ratio, 100 */
2201
+ blend?: number
2202
+ /** Scale of the plane, */
2203
+ scale?: number
2204
+ /** Temporal accumulates shadows over time which is more performant but has a visual regression over instant results, false */
2205
+ temporal?: false
2206
+ /** Opacity of the plane, 1 */
2207
+ opacity?: number
2208
+ /** Discards alpha pixels, 0.65 */
2209
+ alphaTest?: number
2210
+ /** Shadow color, black */
2211
+ color?: string
2212
+ /** Buffer resolution, 1024 */
2213
+ resolution?: number
2214
+ }
2215
+ ```
2216
+
2217
+ ```jsx
2218
+ <AccumulativeShadows temporal frames={100} temporal scale={10}>
2219
+ <RandomizedLight castShadow amount={8} position={[5, 5, -10]} />
2220
+ </AccumulativeShadows>
2221
+ ```
2222
+
2146
2223
  #### SpotLight
2147
2224
 
2148
2225
  <p>
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),r=require("three"),t=require("react"),a=require("@react-three/fiber"),n=require("react-merge-refs");function i(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function s(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var a=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,a.get?a:{enumerable:!0,get:function(){return e[t]}})}})),r.default=e,Object.freeze(r)}var o=i(e),u=s(r),l=s(t),c=i(n);class h{constructor(e,r,t=1024){this.renderer=e,this.res=t,this.scene=r,this.scene.background=null,this.buffer1Active=!1;const a=/(Android|iPad|iPhone|iPod)/g.test(navigator.userAgent)?u.HalfFloatType:u.FloatType;this.progressiveLightMap1=new u.WebGLRenderTarget(this.res,this.res,{type:a}),this.progressiveLightMap2=new u.WebGLRenderTarget(this.res,this.res,{type:a}),this.uvMat=new u.MeshPhongMaterial({shininess:0,specular:new u.Color("black")}),this.uniforms={},this.uvMat.onBeforeCompile=e=>{e.vertexShader="#define USE_LIGHTMAP\n"+e.vertexShader.slice(0,-1)+"\tgl_Position = vec4((uv2 - 0.5) * 2.0, 1.0, 1.0); }";const r=e.fragmentShader.indexOf("void main() {");e.fragmentShader=e.fragmentShader.replace("#include <clipping_planes_pars_fragment>","#include <clipping_planes_pars_fragment>\n#include <shadowmask_pars_fragment>\n"),e.fragmentShader="varying vec2 vUv2;\n"+e.fragmentShader.slice(0,r)+"\tuniform sampler2D previousShadowMap;\n\tuniform float averagingWindow;\n"+e.fragmentShader.slice(r-1,-1)+"\nvec3 texelOld = texture2D(previousShadowMap, vUv2).rgb;\n gl_FragColor.rgb = mix(texelOld, gl_FragColor.rgb, 1.0/averagingWindow);\n }",e.uniforms.previousShadowMap={value:this.progressiveLightMap1.texture},e.uniforms.averagingWindow={value:100},this.uniforms=e.uniforms}}clear(){this.renderer.setRenderTarget(this.progressiveLightMap1),this.renderer.clear(),this.renderer.setRenderTarget(this.progressiveLightMap2),this.renderer.clear()}configureObject(e){const r=e.geometry.getAttribute("uv").clone();e.geometry.setAttribute("uv2",r),e.geometry.getAttribute("uv2").needsUpdate=!0}update(e,r=100){this.uniforms.averagingWindow={value:r},this.scene.overrideMaterial=this.uvMat;const t=this.buffer1Active?this.progressiveLightMap1:this.progressiveLightMap2,a=this.buffer1Active?this.progressiveLightMap2:this.progressiveLightMap1;this.renderer.setRenderTarget(t),this.uniforms.previousShadowMap={value:a.texture},this.buffer1Active=!this.buffer1Active,this.renderer.render(this.scene,e),this.scene.overrideMaterial=null,this.renderer.setRenderTarget(null)}}const f=l.createContext(null),d=l.forwardRef((({children:e,blend:r,frames:t=40,scale:n=10,temporal:i=!1,opacity:s=1,alphaTest:o=.65,color:c="black",resolution:d=1024,...g},p)=>{const m=a.useThree((e=>e.gl)),v=a.useThree((e=>e.scene)),M=a.useThree((e=>e.camera)),b=l.useRef(null),y=l.useRef(null),w=l.useRef(0),[S]=l.useState((()=>new h(m,v,d)));l.useLayoutEffect((()=>{S.configureObject(b.current)}),[]);const _=void 0===r&&t===1/0?100:t,T=l.useMemo((()=>{const e=Object.assign(new u.MeshBasicMaterial({opacity:0,transparent:!0,dithering:!0,depthWrite:!1,map:S.progressiveLightMap2.texture}),{uniforms:{ucolor:{value:new u.Color(c)},alphaTest:{value:0}}});return e.onBeforeCompile=r=>{e.uniforms=r.uniforms={...r.uniforms,...e.uniforms},r.fragmentShader=r.fragmentShader.replace("void main() {","uniform vec3 ucolor;\n uniform float alphaTest;\n void main() {"),r.fragmentShader=r.fragmentShader.replace("#include <dithering_fragment>","#include <dithering_fragment>\n gl_FragColor = vec4(ucolor * gl_FragColor.r * 2.0, max(0.0, (1.0 - gl_FragColor.r / alphaTest)) * opacity);")},e}),[c]);function x(){y.current.visible=!0;const e=[];return v.traverse((r=>{(function(e){return e.isLight})(r)&&(e.push({object:r,intensity:r.intensity}),r.intensity=0)})),e}function L(e){y.current.visible=!1,e.forEach((({object:e,intensity:r})=>e.intensity=r))}function E(){t!==1/0&&(S.clear(),T.opacity=0,T.uniforms.alphaTest.value=0,w.current=0)}l.useEffect((()=>{if(!i){T.opacity=s,T.uniforms.alphaTest.value=o;const e=x();for(let e=0;e<_;e++)S.update(M,_);L(e)}})),a.useFrame((()=>{if(i&&w.current<t){T.opacity=Math.min(s,T.opacity+s/_),T.uniforms.alphaTest.value=Math.min(o,T.uniforms.alphaTest.value+o/_);const e=x();S.update(M,_),L(e),w.current++}}));const R=l.useMemo((()=>({refresh:E,count:w,frames:t})),[t]);return l.useImperativeHandle(p,(()=>R),[R]),l.useLayoutEffect(E),l.createElement("group",g,l.createElement("group",{traverse:()=>null,ref:y},l.createElement(f.Provider,{value:R},e)),l.createElement("mesh",{receiveShadow:!0,ref:b,material:T,scale:n,rotation:[-Math.PI/2,0,0]},l.createElement("planeGeometry",null)))})),g=l.forwardRef((({castShadow:e=!0,bias:r=0,mapSize:t=512,size:n=5,near:i=.5,far:s=500,frames:h=1,position:d=[0,0,0],radius:g=1,amount:p=8,intensity:m=1,ambient:v=.5,...M},b)=>{const y=l.useRef(null),w=new u.Vector3(...d).length(),S=l.useContext(f),_=l.useRef(0),T=S?S.count:_,x=S?S.frames:h;let L;return a.useFrame((()=>{if(T.current<x){for(let e=0;e<y.current.children.length;e++)if(L=y.current.children[e],Math.random()>v)L.position.set(d[0]+u.MathUtils.randFloatSpread(g),d[1]+u.MathUtils.randFloatSpread(g),d[2]+u.MathUtils.randFloatSpread(g));else{let e=Math.acos(2*Math.random()-1)-Math.PI/2,r=2*Math.PI*Math.random();L.position.set(Math.cos(e)*Math.cos(r)*w,Math.abs(Math.cos(e)*Math.sin(r)*w),Math.sin(e)*w)}S||T.current++}})),l.createElement("group",o.default({ref:c.default([y,b])},M),Array.from({length:p},((a,o)=>l.createElement("directionalLight",{key:o,castShadow:e,"shadow-bias":r,"shadow-mapSize":[t,t],intensity:m/p},l.createElement("orthographicCamera",{attach:"shadow-camera",args:[-n,n,n,-n,i,s]})))))}));exports.AccumulativeShadows=d,exports.RandomizedLight=g,exports.accumulativeContext=f;
@@ -0,0 +1,67 @@
1
+ import * as THREE from 'three';
2
+ import * as React from 'react';
3
+ export declare const accumulativeContext: React.Context<{
4
+ refresh: (force?: boolean | undefined) => void;
5
+ count: React.MutableRefObject<number>;
6
+ frames: number;
7
+ }>;
8
+ export declare const AccumulativeShadows: React.ForwardRefExoticComponent<Pick<Omit<import("@react-three/fiber").ExtendedColors<import("@react-three/fiber").Overwrite<Partial<THREE.Group>, import("@react-three/fiber").NodeProps<THREE.Group, typeof THREE.Group>>>, import("@react-three/fiber").NonFunctionKeys<{
9
+ position?: import("@react-three/fiber").Vector3 | undefined;
10
+ up?: import("@react-three/fiber").Vector3 | undefined;
11
+ scale?: import("@react-three/fiber").Vector3 | undefined;
12
+ rotation?: import("@react-three/fiber").Euler | undefined;
13
+ matrix?: import("@react-three/fiber").Matrix4 | undefined;
14
+ quaternion?: import("@react-three/fiber").Quaternion | undefined;
15
+ layers?: import("@react-three/fiber").Layers | undefined;
16
+ dispose?: (() => void) | null | undefined;
17
+ }>> & {
18
+ position?: import("@react-three/fiber").Vector3 | undefined;
19
+ up?: import("@react-three/fiber").Vector3 | undefined;
20
+ scale?: import("@react-three/fiber").Vector3 | undefined;
21
+ rotation?: import("@react-three/fiber").Euler | undefined;
22
+ matrix?: import("@react-three/fiber").Matrix4 | undefined;
23
+ quaternion?: import("@react-three/fiber").Quaternion | undefined;
24
+ layers?: import("@react-three/fiber").Layers | undefined;
25
+ dispose?: (() => void) | null | undefined;
26
+ } & import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers & {
27
+ frames?: number | undefined;
28
+ blend?: number | undefined;
29
+ scale?: number | undefined;
30
+ temporal?: boolean | undefined;
31
+ opacity?: number | undefined;
32
+ alphaTest?: number | undefined;
33
+ color?: string | undefined;
34
+ resolution?: number | undefined;
35
+ }, "visible" | "attach" | "args" | "children" | "key" | "onUpdate" | "position" | "up" | "scale" | "rotation" | "matrix" | "quaternion" | "layers" | "dispose" | "type" | "isGroup" | "id" | "uuid" | "name" | "parent" | "modelViewMatrix" | "normalMatrix" | "matrixWorld" | "matrixAutoUpdate" | "matrixWorldNeedsUpdate" | "castShadow" | "receiveShadow" | "frustumCulled" | "renderOrder" | "animations" | "userData" | "customDepthMaterial" | "customDistanceMaterial" | "isObject3D" | "onBeforeRender" | "onAfterRender" | "applyMatrix4" | "applyQuaternion" | "setRotationFromAxisAngle" | "setRotationFromEuler" | "setRotationFromMatrix" | "setRotationFromQuaternion" | "rotateOnAxis" | "rotateOnWorldAxis" | "rotateX" | "rotateY" | "rotateZ" | "translateOnAxis" | "translateX" | "translateY" | "translateZ" | "localToWorld" | "worldToLocal" | "lookAt" | "add" | "remove" | "removeFromParent" | "clear" | "getObjectById" | "getObjectByName" | "getObjectByProperty" | "getWorldPosition" | "getWorldQuaternion" | "getWorldScale" | "getWorldDirection" | "raycast" | "traverse" | "traverseVisible" | "traverseAncestors" | "updateMatrix" | "updateMatrixWorld" | "updateWorldMatrix" | "toJSON" | "clone" | "copy" | "addEventListener" | "hasEventListener" | "removeEventListener" | "dispatchEvent" | "color" | keyof import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers | "opacity" | "alphaTest" | "resolution" | "frames" | "blend" | "temporal"> & React.RefAttributes<unknown>>;
36
+ export declare const RandomizedLight: React.ForwardRefExoticComponent<Pick<Omit<import("@react-three/fiber").ExtendedColors<import("@react-three/fiber").Overwrite<Partial<THREE.Group>, import("@react-three/fiber").NodeProps<THREE.Group, typeof THREE.Group>>>, import("@react-three/fiber").NonFunctionKeys<{
37
+ position?: import("@react-three/fiber").Vector3 | undefined;
38
+ up?: import("@react-three/fiber").Vector3 | undefined;
39
+ scale?: import("@react-three/fiber").Vector3 | undefined;
40
+ rotation?: import("@react-three/fiber").Euler | undefined;
41
+ matrix?: import("@react-three/fiber").Matrix4 | undefined;
42
+ quaternion?: import("@react-three/fiber").Quaternion | undefined;
43
+ layers?: import("@react-three/fiber").Layers | undefined;
44
+ dispose?: (() => void) | null | undefined;
45
+ }>> & {
46
+ position?: import("@react-three/fiber").Vector3 | undefined;
47
+ up?: import("@react-three/fiber").Vector3 | undefined;
48
+ scale?: import("@react-three/fiber").Vector3 | undefined;
49
+ rotation?: import("@react-three/fiber").Euler | undefined;
50
+ matrix?: import("@react-three/fiber").Matrix4 | undefined;
51
+ quaternion?: import("@react-three/fiber").Quaternion | undefined;
52
+ layers?: import("@react-three/fiber").Layers | undefined;
53
+ dispose?: (() => void) | null | undefined;
54
+ } & import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers & {
55
+ frames?: number | undefined;
56
+ position?: [x: number, y: number, z: number] | undefined;
57
+ radius?: number | undefined;
58
+ amount?: number | undefined;
59
+ intensity?: number | undefined;
60
+ ambient?: number | undefined;
61
+ castShadow?: boolean | undefined;
62
+ bias?: number | undefined;
63
+ mapSize?: number | undefined;
64
+ size?: number | undefined;
65
+ near?: number | undefined;
66
+ far?: number | undefined;
67
+ }, "visible" | "attach" | "args" | "children" | "key" | "onUpdate" | "position" | "up" | "scale" | "rotation" | "matrix" | "quaternion" | "layers" | "dispose" | "type" | "isGroup" | "id" | "uuid" | "name" | "parent" | "modelViewMatrix" | "normalMatrix" | "matrixWorld" | "matrixAutoUpdate" | "matrixWorldNeedsUpdate" | "castShadow" | "receiveShadow" | "frustumCulled" | "renderOrder" | "animations" | "userData" | "customDepthMaterial" | "customDistanceMaterial" | "isObject3D" | "onBeforeRender" | "onAfterRender" | "applyMatrix4" | "applyQuaternion" | "setRotationFromAxisAngle" | "setRotationFromEuler" | "setRotationFromMatrix" | "setRotationFromQuaternion" | "rotateOnAxis" | "rotateOnWorldAxis" | "rotateX" | "rotateY" | "rotateZ" | "translateOnAxis" | "translateX" | "translateY" | "translateZ" | "localToWorld" | "worldToLocal" | "lookAt" | "add" | "remove" | "removeFromParent" | "clear" | "getObjectById" | "getObjectByName" | "getObjectByProperty" | "getWorldPosition" | "getWorldQuaternion" | "getWorldScale" | "getWorldDirection" | "raycast" | "traverse" | "traverseVisible" | "traverseAncestors" | "updateMatrix" | "updateMatrixWorld" | "updateWorldMatrix" | "toJSON" | "clone" | "copy" | "addEventListener" | "hasEventListener" | "removeEventListener" | "dispatchEvent" | keyof import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers | "size" | "near" | "far" | "intensity" | "frames" | "radius" | "bias" | "mapSize" | "amount" | "ambient"> & React.RefAttributes<unknown>>;
@@ -0,0 +1,275 @@
1
+ import _extends from '@babel/runtime/helpers/esm/extends';
2
+ import * as THREE from 'three';
3
+ import * as React from 'react';
4
+ import { useThree, useFrame } from '@react-three/fiber';
5
+ import mergeRefs from 'react-merge-refs';
6
+
7
+ class ProgressiveLightMap {
8
+ constructor(renderer, scene, res = 1024) {
9
+ this.renderer = renderer;
10
+ this.res = res;
11
+ this.scene = scene;
12
+ this.scene.background = null;
13
+ this.buffer1Active = false; // Create the Progressive LightMap Texture
14
+
15
+ const format = /(Android|iPad|iPhone|iPod)/g.test(navigator.userAgent) ? THREE.HalfFloatType : THREE.FloatType;
16
+ this.progressiveLightMap1 = new THREE.WebGLRenderTarget(this.res, this.res, {
17
+ type: format
18
+ });
19
+ this.progressiveLightMap2 = new THREE.WebGLRenderTarget(this.res, this.res, {
20
+ type: format
21
+ }); // Inject some spicy new logic into a standard phong material
22
+
23
+ this.uvMat = new THREE.MeshPhongMaterial({
24
+ shininess: 0,
25
+ specular: new THREE.Color('black')
26
+ });
27
+ this.uniforms = {};
28
+
29
+ this.uvMat.onBeforeCompile = shader => {
30
+ // Vertex Shader: Set Vertex Positions to the Unwrapped UV Positions
31
+ shader.vertexShader = '#define USE_LIGHTMAP\n' + shader.vertexShader.slice(0, -1) + ' gl_Position = vec4((uv2 - 0.5) * 2.0, 1.0, 1.0); }'; // Fragment Shader: Set Pixels to average in the Previous frame's Shadows
32
+
33
+ const bodyStart = shader.fragmentShader.indexOf('void main() {');
34
+ shader.fragmentShader = shader.fragmentShader.replace('#include <clipping_planes_pars_fragment>', '#include <clipping_planes_pars_fragment>\n#include <shadowmask_pars_fragment>\n');
35
+ shader.fragmentShader = 'varying vec2 vUv2;\n' + shader.fragmentShader.slice(0, bodyStart) + ' uniform sampler2D previousShadowMap;\n uniform float averagingWindow;\n' + shader.fragmentShader.slice(bodyStart - 1, -1) + `\nvec3 texelOld = texture2D(previousShadowMap, vUv2).rgb;
36
+ gl_FragColor.rgb = mix(texelOld, gl_FragColor.rgb, 1.0/averagingWindow);
37
+ }`; // Set the Previous Frame's Texture Buffer and Averaging Window
38
+
39
+ shader.uniforms.previousShadowMap = {
40
+ value: this.progressiveLightMap1.texture
41
+ };
42
+ shader.uniforms.averagingWindow = {
43
+ value: 100
44
+ };
45
+ this.uniforms = shader.uniforms;
46
+ };
47
+ }
48
+
49
+ clear() {
50
+ this.renderer.setRenderTarget(this.progressiveLightMap1);
51
+ this.renderer.clear();
52
+ this.renderer.setRenderTarget(this.progressiveLightMap2);
53
+ this.renderer.clear();
54
+ }
55
+
56
+ configureObject(object) {
57
+ const uv2 = object.geometry.getAttribute('uv').clone();
58
+ object.geometry.setAttribute('uv2', uv2);
59
+ object.geometry.getAttribute('uv2').needsUpdate = true;
60
+ }
61
+
62
+ update(camera, blendWindow = 100) {
63
+ // Set each object's material to the UV Unwrapped Surface Mapping Version
64
+ this.uniforms.averagingWindow = {
65
+ value: blendWindow
66
+ };
67
+ this.scene.overrideMaterial = this.uvMat; // Ping-pong two surface buffers for reading/writing
68
+
69
+ const activeMap = this.buffer1Active ? this.progressiveLightMap1 : this.progressiveLightMap2;
70
+ const inactiveMap = this.buffer1Active ? this.progressiveLightMap2 : this.progressiveLightMap1; // Render the object's surface maps
71
+
72
+ this.renderer.setRenderTarget(activeMap);
73
+ this.uniforms.previousShadowMap = {
74
+ value: inactiveMap.texture
75
+ };
76
+ this.buffer1Active = !this.buffer1Active;
77
+ this.renderer.render(this.scene, camera);
78
+ this.scene.overrideMaterial = null;
79
+ this.renderer.setRenderTarget(null);
80
+ }
81
+
82
+ }
83
+
84
+ function isLight(object) {
85
+ return object.isLight;
86
+ }
87
+
88
+ const accumulativeContext = /*#__PURE__*/React.createContext(null);
89
+ const AccumulativeShadows = /*#__PURE__*/React.forwardRef(({
90
+ children,
91
+ blend,
92
+ frames = 40,
93
+ scale = 10,
94
+ temporal = false,
95
+ opacity = 1,
96
+ alphaTest = 0.65,
97
+ color = 'black',
98
+ resolution = 1024,
99
+ ...props
100
+ }, forwardRef) => {
101
+ const gl = useThree(state => state.gl);
102
+ const scene = useThree(state => state.scene);
103
+ const defaultCamera = useThree(state => state.camera);
104
+ const gPlane = React.useRef(null);
105
+ const gLights = React.useRef(null);
106
+ const count = React.useRef(0);
107
+ const [plm] = React.useState(() => new ProgressiveLightMap(gl, scene, resolution));
108
+ React.useLayoutEffect(() => {
109
+ plm.configureObject(gPlane.current);
110
+ }, []);
111
+ const blendFrames = blend === undefined ? frames === Infinity ? 100 : frames : frames;
112
+ const material = React.useMemo(() => {
113
+ const mat = Object.assign(new THREE.MeshBasicMaterial({
114
+ opacity: 0,
115
+ transparent: true,
116
+ dithering: true,
117
+ depthWrite: false,
118
+ map: plm.progressiveLightMap2.texture
119
+ }), {
120
+ uniforms: {
121
+ ucolor: {
122
+ value: new THREE.Color(color)
123
+ },
124
+ alphaTest: {
125
+ value: 0
126
+ }
127
+ }
128
+ });
129
+
130
+ mat.onBeforeCompile = shader => {
131
+ mat.uniforms = shader.uniforms = { ...shader.uniforms,
132
+ ...mat.uniforms
133
+ };
134
+ shader.fragmentShader = shader.fragmentShader.replace(`void main() {`, `uniform vec3 ucolor;
135
+ uniform float alphaTest;
136
+ void main() {`);
137
+ shader.fragmentShader = shader.fragmentShader.replace('#include <dithering_fragment>', `#include <dithering_fragment>
138
+ gl_FragColor = vec4(ucolor * gl_FragColor.r * 2.0, max(0.0, (1.0 - gl_FragColor.r / alphaTest)) * opacity);`);
139
+ };
140
+
141
+ return mat;
142
+ }, [color]);
143
+
144
+ function prepare() {
145
+ gLights.current.visible = true;
146
+ const intensities = [];
147
+ scene.traverse(object => {
148
+ if (isLight(object)) {
149
+ intensities.push({
150
+ object,
151
+ intensity: object.intensity
152
+ });
153
+ object.intensity = 0;
154
+ }
155
+ });
156
+ return intensities;
157
+ }
158
+
159
+ function finish(intensities) {
160
+ gLights.current.visible = false;
161
+ intensities.forEach(({
162
+ object,
163
+ intensity
164
+ }) => object.intensity = intensity);
165
+ }
166
+
167
+ function refresh() {
168
+ if (frames !== Infinity) {
169
+ plm.clear();
170
+ material.opacity = 0;
171
+ material.uniforms.alphaTest.value = 0;
172
+ count.current = 0;
173
+ }
174
+ }
175
+
176
+ React.useEffect(() => {
177
+ if (!temporal) {
178
+ material.opacity = opacity;
179
+ material.uniforms.alphaTest.value = alphaTest;
180
+ const intensities = prepare();
181
+
182
+ for (let i = 0; i < blendFrames; i++) plm.update(defaultCamera, blendFrames);
183
+
184
+ finish(intensities);
185
+ }
186
+ });
187
+ useFrame(() => {
188
+ if (temporal && count.current < frames) {
189
+ material.opacity = Math.min(opacity, material.opacity + opacity / blendFrames);
190
+ material.uniforms.alphaTest.value = Math.min(alphaTest, material.uniforms.alphaTest.value + alphaTest / blendFrames);
191
+ const intensities = prepare();
192
+ plm.update(defaultCamera, blendFrames);
193
+ finish(intensities);
194
+ count.current++;
195
+ }
196
+ }); // Expose refresh api
197
+
198
+ const api = React.useMemo(() => ({
199
+ refresh,
200
+ count,
201
+ frames
202
+ }), [frames]);
203
+ React.useImperativeHandle(forwardRef, () => api, [api]); // Refresh on render
204
+
205
+ React.useLayoutEffect(refresh);
206
+ return /*#__PURE__*/React.createElement("group", props, /*#__PURE__*/React.createElement("group", {
207
+ traverse: () => null,
208
+ ref: gLights
209
+ }, /*#__PURE__*/React.createElement(accumulativeContext.Provider, {
210
+ value: api
211
+ }, children)), /*#__PURE__*/React.createElement("mesh", {
212
+ receiveShadow: true,
213
+ ref: gPlane,
214
+ material: material,
215
+ scale: scale,
216
+ rotation: [-Math.PI / 2, 0, 0]
217
+ }, /*#__PURE__*/React.createElement("planeGeometry", null)));
218
+ });
219
+ const RandomizedLight = /*#__PURE__*/React.forwardRef(({
220
+ castShadow = true,
221
+ bias = 0,
222
+ mapSize = 512,
223
+ size = 5,
224
+ near = 0.5,
225
+ far = 500,
226
+ frames = 1,
227
+ position = [0, 0, 0],
228
+ radius = 1,
229
+ amount = 8,
230
+ intensity = 1,
231
+ ambient = 0.5,
232
+ ...props
233
+ }, forwardRef) => {
234
+ const gLights = React.useRef(null);
235
+ const length = new THREE.Vector3(...position).length();
236
+ const parent = React.useContext(accumulativeContext);
237
+ const count = React.useRef(0);
238
+ const actualCount = parent ? parent.count : count;
239
+ const actualFrames = parent ? parent.frames : frames;
240
+ let light;
241
+ useFrame(() => {
242
+ if (actualCount.current < actualFrames) {
243
+ for (let l = 0; l < gLights.current.children.length; l++) {
244
+ light = gLights.current.children[l];
245
+
246
+ if (Math.random() > ambient) {
247
+ light.position.set(position[0] + THREE.MathUtils.randFloatSpread(radius), position[1] + THREE.MathUtils.randFloatSpread(radius), position[2] + THREE.MathUtils.randFloatSpread(radius));
248
+ } else {
249
+ let lambda = Math.acos(2 * Math.random() - 1) - Math.PI / 2.0;
250
+ let phi = 2 * Math.PI * Math.random();
251
+ light.position.set(Math.cos(lambda) * Math.cos(phi) * length, Math.abs(Math.cos(lambda) * Math.sin(phi) * length), Math.sin(lambda) * length);
252
+ }
253
+ } // Do not count up if a perent exists
254
+
255
+
256
+ if (!parent) actualCount.current++;
257
+ }
258
+ });
259
+ return /*#__PURE__*/React.createElement("group", _extends({
260
+ ref: mergeRefs([gLights, forwardRef])
261
+ }, props), Array.from({
262
+ length: amount
263
+ }, (_, index) => /*#__PURE__*/React.createElement("directionalLight", {
264
+ key: index,
265
+ castShadow: castShadow,
266
+ "shadow-bias": bias,
267
+ "shadow-mapSize": [mapSize, mapSize],
268
+ intensity: intensity / amount
269
+ }, /*#__PURE__*/React.createElement("orthographicCamera", {
270
+ attach: "shadow-camera",
271
+ args: [-size, size, size, -size, near, far]
272
+ }))));
273
+ });
274
+
275
+ export { AccumulativeShadows, RandomizedLight, accumulativeContext };
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),n=require("react"),r=require("@react-three/fiber"),t=require("three"),o=require("three-stdlib"),i=require("../helpers/environment-assets.cjs.js"),c=require("./shapes.cjs.js");function a(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function u(e){if(e&&e.__esModule)return e;var n=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var t=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(n,r,t.get?t:{enumerable:!0,get:function(){return e[r]}})}})),n.default=e,Object.freeze(n)}var s=a(e),l=u(n);const d=e=>{return(n=e).current&&n.current.isScene?e.current:e;var n};function f({scene:e,background:n=!1,map:t}){const o=r.useThree((e=>e.scene));return l.useLayoutEffect((()=>{if(t){const r=d(e||o),i=r.background,c=r.environment;return"only"!==n&&(r.environment=t),n&&(r.background=t),()=>{"only"!==n&&(r.environment=c),n&&(r.background=i)}}}),[o,e,t,n]),null}function m({files:e=["/px.png","/nx.png","/py.png","/ny.png","/pz.png","/nz.png"],path:n="",preset:c,encoding:a,extensions:u}){if(c){if(!(c in i.presetsObj))throw new Error("Preset must be one of: "+Object.keys(i.presetsObj).join(", "));e=i.presetsObj[c],n="https://market-assets.fra1.cdn.digitaloceanspaces.com/market-assets/hdris/"}const s=Array.isArray(e),l=s?t.CubeTextureLoader:o.RGBELoader,d=r.useLoader(l,s?[e]:e,(e=>{e.setPath(n),u&&u(e)})),f=s?d[0]:d;return f.mapping=s?t.CubeReflectionMapping:t.EquirectangularReflectionMapping,f.encoding=(null!=a?a:s)?t.sRGBEncoding:t.LinearEncoding,f}function p({background:e=!1,scene:n,...t}){const o=m(t),i=r.useThree((e=>e.scene));return l.useLayoutEffect((()=>{const r=d(n||i),t=r.background,c=r.environment;return"only"!==e&&(r.environment=o),e&&(r.background=o),()=>{"only"!==e&&(r.environment=c),e&&(r.background=t)}}),[o,e,n,i]),null}function v({children:e,near:n=1,far:o=1e3,resolution:i=256,frames:c=1,map:a,background:u=!1,scene:s,files:m,path:v,preset:g,extensions:b}){const h=r.useThree((e=>e.gl)),E=r.useThree((e=>e.scene)),P=l.useRef(null),[x]=l.useState((()=>new t.Scene)),_=l.useMemo((()=>{const e=new t.WebGLCubeRenderTarget(i);return e.texture.type=t.HalfFloatType,e}),[i]);l.useLayoutEffect((()=>{1===c&&P.current.update(h,x);const e=d(s||E),n=e.background,r=e.environment;return"only"!==u&&(e.environment=_.texture),u&&(e.background=_.texture),()=>{"only"!==u&&(e.environment=r),u&&(e.background=n)}}),[e,x,_.texture,s,E,u,c,h]);let y=1;return r.useFrame((()=>{(c===1/0||y<c)&&(P.current.update(h,x),y++)})),l.createElement(l.Fragment,null,r.createPortal(l.createElement(l.Fragment,null,e,l.createElement("cubeCamera",{ref:P,args:[n,o,_]}),m||g?l.createElement(p,{background:!0,files:m,preset:g,path:v,extensions:b}):a?l.createElement(f,{background:!0,map:a,extensions:b}):null),x))}function g(e){var n,r,o,i;const a=m(e),u=e.map||a,d=(p=u)&&p.isCubeTexture;var p;const v=l.useMemo((()=>{var e,n;const r=(null!==(e=d?null==(n=u.image[0])?void 0:n.width:u.image.width)&&void 0!==e?e:1024)/4,t=Math.floor(Math.log2(r)),o=Math.pow(2,t),i=3*Math.max(o,112);return[d?"#define ENVMAP_TYPE_CUBE":"","#define CUBEUV_TEXEL_WIDTH "+1/i,"#define CUBEUV_TEXEL_HEIGHT "+1/(4*o),`#define CUBEUV_MAX_MIP ${t}.0`,""]}),[]),g=l.useMemo((()=>v.join("\n")+"#define GLSLIFY 1\n#define ENVMAP_TYPE_CUBE_UV\nvarying vec3 vWorldPosition;uniform float radius;uniform float height;\n#ifdef ENVMAP_TYPE_CUBE\nuniform samplerCube cubemap;\n#else\nuniform sampler2D cubemap;\n#endif\nfloat diskIntersectWithBackFaceCulling(in vec3 ro,in vec3 rd,vec3 c,vec3 n,float r){float d=dot(rd,n);if(d>0.0)return 1e6;vec3 o=ro-c;float t=-dot(n,o)/d;vec3 q=o+rd*t;return(dot(q,q)<r*r)? t : 1e6;}float sphereIntersect(in vec3 ro,in vec3 rd,in vec3 ce,float ra){vec3 oc=ro-ce;float b=dot(oc,rd);float c=dot(oc,oc)-ra*ra;float h=b*b-c;if(h<0.0)-1.0;h=sqrt(h);return-b+h;}vec3 project(){vec3 p=normalize(vWorldPosition);vec3 camPos=cameraPosition;camPos.y-=height;float intersection=sphereIntersect(camPos,p,vec3(0.),radius);if(intersection>0.){vec3 h=vec3(0.0,-height,0.0);float intersection2=diskIntersectWithBackFaceCulling(camPos,p,h,vec3(0.0,1.0,0.0),radius);p=(camPos+min(intersection,intersection2)*p)/radius;}else{p=vec3(0.0,1.0,0.0);}return p;}\n#include <common>\n#include <cube_uv_reflection_fragment>\nvoid main(){vec3 projectedWorldPosition=project();\n#ifdef ENVMAP_TYPE_CUBE\nvec3 outcolor=textureCube(cubemap,projectedWorldPosition).rgb;\n#else\nvec3 direction=normalize(projectedWorldPosition);vec2 uv=equirectUv(direction);vec3 outcolor=texture2D(cubemap,uv).rgb;\n#endif\ngl_FragColor=vec4(outcolor,1.0);\n#include <tonemapping_fragment>\n#include <encodings_fragment>\n}"),[v]),b=l.useMemo((()=>({cubemap:{value:null},height:{value:15},radius:{value:60}})),[]),h=l.useRef(null),E=null==(n=e.ground)?void 0:n.height,P=null==(r=e.ground)?void 0:r.radius,x=null!==(o=null==(i=e.ground)?void 0:i.scale)&&void 0!==o?o:1e3;return l.useEffect((()=>{E&&(h.current.uniforms.height.value=E)}),[E]),l.useEffect((()=>{P&&(h.current.uniforms.radius.value=P)}),[P]),l.useEffect((()=>{h.current.uniforms.cubemap.value=u}),[u]),l.createElement(l.Fragment,null,l.createElement(f,s.default({},e,{map:u})),l.createElement(c.Icosahedron,{scale:x,args:[1,16]},l.createElement("shaderMaterial",{ref:h,side:t.BackSide,vertexShader:"#define GLSLIFY 1\nvarying vec3 vWorldPosition;void main(){vec4 worldPosition=modelMatrix*vec4(position,1.0);vWorldPosition=worldPosition.xyz;gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.0);}",fragmentShader:g,uniforms:b})))}exports.Environment=function(e){return e.ground?l.createElement(g,e):e.map?l.createElement(f,e):e.children?l.createElement(v,e):l.createElement(p,e)},exports.EnvironmentCube=p,exports.EnvironmentMap=f,exports.EnvironmentPortal=v,exports.useEnvironment=m;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),n=require("react"),r=require("@react-three/fiber"),t=require("three"),u=require("three-stdlib"),o=require("../helpers/environment-assets.cjs.js");function a(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function c(e){if(e&&e.__esModule)return e;var n=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var t=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(n,r,t.get?t:{enumerable:!0,get:function(){return e[r]}})}})),n.default=e,Object.freeze(n)}var s=a(e),i=c(n);const l=e=>{return(n=e).current&&n.current.isScene?e.current:e;var n};function d({scene:e,background:n=!1,map:t}){const u=r.useThree((e=>e.scene));return i.useLayoutEffect((()=>{if(t){const r=l(e||u),o=r.background,a=r.environment;return"only"!==n&&(r.environment=t),n&&(r.background=t),()=>{"only"!==n&&(r.environment=a),n&&(r.background=o)}}}),[u,e,t,n]),null}function p({files:e=["/px.png","/nx.png","/py.png","/ny.png","/pz.png","/nz.png"],path:n="",preset:a,encoding:c,extensions:s}){if(a){if(!(a in o.presetsObj))throw new Error("Preset must be one of: "+Object.keys(o.presetsObj).join(", "));e=o.presetsObj[a],n="https://market-assets.fra1.cdn.digitaloceanspaces.com/market-assets/hdris/"}const i=Array.isArray(e),l=i?t.CubeTextureLoader:u.RGBELoader,d=r.useLoader(l,i?[e]:e,(e=>{e.setPath(n),s&&s(e)})),p=i?d[0]:d;return p.mapping=i?t.CubeReflectionMapping:t.EquirectangularReflectionMapping,p.encoding=(null!=c?c:i)?t.sRGBEncoding:t.LinearEncoding,p}function m({background:e=!1,scene:n,...t}){const u=p(t),o=r.useThree((e=>e.scene));return i.useLayoutEffect((()=>{const r=l(n||o),t=r.background,a=r.environment;return"only"!==e&&(r.environment=u),e&&(r.background=u),()=>{"only"!==e&&(r.environment=a),e&&(r.background=t)}}),[u,e,n,o]),null}function g({children:e,near:n=1,far:u=1e3,resolution:o=256,frames:a=1,map:c,background:s=!1,scene:p,files:g,path:f,preset:b,extensions:v}){const E=r.useThree((e=>e.gl)),h=r.useThree((e=>e.scene)),y=i.useRef(null),[x]=i.useState((()=>new t.Scene)),k=i.useMemo((()=>{const e=new t.WebGLCubeRenderTarget(o);return e.texture.type=t.HalfFloatType,e}),[o]);i.useLayoutEffect((()=>{1===a&&y.current.update(E,x);const e=l(p||h),n=e.background,r=e.environment;return"only"!==s&&(e.environment=k.texture),s&&(e.background=k.texture),()=>{"only"!==s&&(e.environment=r),s&&(e.background=n)}}),[e,x,k.texture,p,h,s,a,E]);let j=1;return r.useFrame((()=>{(a===1/0||j<a)&&(y.current.update(E,x),j++)})),i.createElement(i.Fragment,null,r.createPortal(i.createElement(i.Fragment,null,e,i.createElement("cubeCamera",{ref:y,args:[n,u,k]}),g||b?i.createElement(m,{background:!0,files:g,preset:b,path:f,extensions:v}):c?i.createElement(d,{background:!0,map:c,extensions:v}):null),x))}function f(e){var n,t,o,a;const c=p(e),l=e.map||c;i.useMemo((()=>{r.extend({GroundProjectedEnvImpl:u.GroundProjectedEnv})}),[]);const m=i.useMemo((()=>[l]),[l]),g=null==(n=e.ground)?void 0:n.height,f=null==(t=e.ground)?void 0:t.radius,b=null!==(o=null==(a=e.ground)?void 0:a.scale)&&void 0!==o?o:1e3;return i.createElement(i.Fragment,null,i.createElement(d,s.default({},e,{map:l})),i.createElement("groundProjectedEnvImpl",{args:m,scale:b,height:g,radius:f}))}exports.Environment=function(e){return e.ground?i.createElement(f,e):e.map?i.createElement(d,e):e.children?i.createElement(g,e):i.createElement(m,e)},exports.EnvironmentCube=m,exports.EnvironmentMap=d,exports.EnvironmentPortal=g,exports.useEnvironment=p;
@@ -1,5 +1,7 @@
1
1
  import * as React from 'react';
2
+ import { Object3DNode } from '@react-three/fiber';
2
3
  import { Texture, Scene, Loader, CubeTexture, TextureEncoding } from 'three';
4
+ import { GroundProjectedEnv as GroundProjectedEnvImpl } from 'three-stdlib';
3
5
  import { PresetsType } from '../helpers/environment-assets';
4
6
  declare type Props = {
5
7
  children?: React.ReactNode;
@@ -25,5 +27,12 @@ export declare function EnvironmentMap({ scene, background, map }: Props): null;
25
27
  export declare function useEnvironment({ files, path, preset, encoding, extensions, }: Partial<Props>): Texture | CubeTexture;
26
28
  export declare function EnvironmentCube({ background, scene, ...rest }: Props): null;
27
29
  export declare function EnvironmentPortal({ children, near, far, resolution, frames, map, background, scene, files, path, preset, extensions, }: Props): JSX.Element;
30
+ declare global {
31
+ namespace JSX {
32
+ interface IntrinsicElements {
33
+ groundProjectedEnvImpl: Object3DNode<GroundProjectedEnvImpl, typeof GroundProjectedEnvImpl>;
34
+ }
35
+ }
36
+ }
28
37
  export declare function Environment(props: Props): JSX.Element;
29
38
  export {};
@@ -1,17 +1,12 @@
1
1
  import _extends from '@babel/runtime/helpers/esm/extends';
2
2
  import * as React from 'react';
3
- import { useThree, useLoader, useFrame, createPortal } from '@react-three/fiber';
4
- import { CubeReflectionMapping, EquirectangularReflectionMapping, sRGBEncoding, LinearEncoding, Scene, WebGLCubeRenderTarget, HalfFloatType, CubeTextureLoader, BackSide } from 'three';
5
- import { RGBELoader } from 'three-stdlib';
3
+ import { useThree, useLoader, useFrame, createPortal, extend } from '@react-three/fiber';
4
+ import { CubeReflectionMapping, EquirectangularReflectionMapping, sRGBEncoding, LinearEncoding, Scene, WebGLCubeRenderTarget, HalfFloatType, CubeTextureLoader } from 'three';
5
+ import { RGBELoader, GroundProjectedEnv } from 'three-stdlib';
6
6
  import { presetsObj } from '../helpers/environment-assets.js';
7
- import vertexShader from '../helpers/glsl/GroundProjection.vert.glsl.js';
8
- import fragmentShader from '../helpers/glsl/GroundProjection.frag.glsl.js';
9
- import { Icosahedron } from './shapes.js';
10
7
 
11
8
  const CUBEMAP_ROOT = 'https://market-assets.fra1.cdn.digitaloceanspaces.com/market-assets/hdris/';
12
9
 
13
- const isCubeTexture = def => def && def.isCubeTexture;
14
-
15
10
  const isRef = obj => obj.current && obj.current.isScene;
16
11
 
17
12
  const resolveScene = scene => isRef(scene) ? scene.current : scene;
@@ -146,52 +141,23 @@ function EnvironmentGround(props) {
146
141
 
147
142
  const textureDefault = useEnvironment(props);
148
143
  const texture = props.map || textureDefault;
149
- const isCubeMap = isCubeTexture(texture);
150
- const defines = React.useMemo(() => {
151
- var _ref, _texture$image$;
152
-
153
- const w = (_ref = isCubeMap ? (_texture$image$ = texture.image[0]) == null ? void 0 : _texture$image$.width : texture.image.width) !== null && _ref !== void 0 ? _ref : 1024;
154
- const cubeSize = w / 4;
155
-
156
- const _lodMax = Math.floor(Math.log2(cubeSize));
157
-
158
- const _cubeSize = Math.pow(2, _lodMax);
159
-
160
- const width = 3 * Math.max(_cubeSize, 16 * 7);
161
- const height = 4 * _cubeSize;
162
- return [isCubeMap ? `#define ENVMAP_TYPE_CUBE` : '', `#define CUBEUV_TEXEL_WIDTH ${1.0 / width}`, `#define CUBEUV_TEXEL_HEIGHT ${1.0 / height}`, `#define CUBEUV_MAX_MIP ${_lodMax}.0`, ``];
144
+ React.useMemo(() => {
145
+ extend({
146
+ GroundProjectedEnvImpl: GroundProjectedEnv
147
+ });
163
148
  }, []);
164
- const fragment = React.useMemo(() => defines.join('\n') + fragmentShader, [defines]);
165
- const uniforms = React.useMemo(() => ({
166
- cubemap: {
167
- value: null
168
- },
169
- height: {
170
- value: 15
171
- },
172
- radius: {
173
- value: 60
174
- }
175
- }), []);
176
- const mat = React.useRef(null);
149
+ const args = React.useMemo(() => [texture], [texture]);
177
150
  const height = (_props$ground = props.ground) == null ? void 0 : _props$ground.height;
178
151
  const radius = (_props$ground2 = props.ground) == null ? void 0 : _props$ground2.radius;
179
152
  const scale = (_scale = (_props$ground3 = props.ground) == null ? void 0 : _props$ground3.scale) !== null && _scale !== void 0 ? _scale : 1000;
180
- React.useEffect(() => void (height && (mat.current.uniforms.height.value = height)), [height]);
181
- React.useEffect(() => void (radius && (mat.current.uniforms.radius.value = radius)), [radius]);
182
- React.useEffect(() => void (mat.current.uniforms.cubemap.value = texture), [texture]);
183
153
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(EnvironmentMap, _extends({}, props, {
184
154
  map: texture
185
- })), /*#__PURE__*/React.createElement(Icosahedron, {
155
+ })), /*#__PURE__*/React.createElement("groundProjectedEnvImpl", {
156
+ args: args,
186
157
  scale: scale,
187
- args: [1, 16]
188
- }, /*#__PURE__*/React.createElement("shaderMaterial", {
189
- ref: mat,
190
- side: BackSide,
191
- vertexShader: vertexShader,
192
- fragmentShader: fragment,
193
- uniforms: uniforms
194
- })));
158
+ height: height,
159
+ radius: radius
160
+ }));
195
161
  }
196
162
 
197
163
  function Environment(props) {
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),r=require("three"),t=require("react"),n=require("@react-three/fiber"),a=require("./useFBO.cjs.js");function u(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function i(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})}})),r.default=e,Object.freeze(r)}var c=u(e),o=i(r),s=i(t);const l=s.forwardRef((({children:e,width:r,height:t,renderPriority:u=0,eventPriority:i=0,frames:l=1/0,...d},m)=>{const{size:p,viewport:b}=n.useThree(),v=a.useFBO((r||p.width)*b.dpr,(t||p.height)*b.dpr,{samples:8}),[y]=s.useState((()=>new o.Scene)),g=s.useCallback(((e,r,t)=>{var n,a;let u=null==(n=v.texture)?void 0:n.__r3f.parent;for(;u&&!(u instanceof o.Object3D);)u=u.__r3f.parent;if(!u)return!1;t.raycaster.camera||t.events.compute(e,t,null==(a=t.previousRoot)?void 0:a.getState());const[i]=t.raycaster.intersectObject(u);if(!i)return!1;const c=i.uv;r.raycaster.setFromCamera(r.pointer.set(2*c.x-1,2*c.y-1),r.camera)}),[]);return s.useImperativeHandle(m,(()=>v.texture),[v]),s.createElement(s.Fragment,null,n.createPortal(s.createElement(f,{renderPriority:u,frames:l,fbo:v},e),y,{events:{compute:g,priority:i}}),s.createElement("primitive",c.default({object:v.texture},d)))}));function f({frames:e,renderPriority:r,children:t,fbo:a}){let u=0;return n.useFrame((r=>{(e===1/0||u<e)&&(r.gl.setRenderTarget(a),r.gl.render(r.scene,r.camera),r.gl.setRenderTarget(null),u++)}),r),s.createElement(s.Fragment,null,t)}exports.RenderTexture=l;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),r=require("three"),t=require("react"),n=require("@react-three/fiber"),a=require("./useFBO.cjs.js");function u(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function i(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})}})),r.default=e,Object.freeze(r)}var c=u(e),s=i(r),o=i(t);const l=o.forwardRef((({children:e,width:r,height:t,samples:u=8,renderPriority:i=0,eventPriority:l=0,frames:d=1/0,...m},p)=>{const{size:b,viewport:v}=n.useThree(),y=a.useFBO((r||b.width)*v.dpr,(t||b.height)*v.dpr,{samples:u}),[g]=o.useState((()=>new s.Scene)),h=o.useCallback(((e,r,t)=>{var n,a;let u=null==(n=y.texture)?void 0:n.__r3f.parent;for(;u&&!(u instanceof s.Object3D);)u=u.__r3f.parent;if(!u)return!1;t.raycaster.camera||t.events.compute(e,t,null==(a=t.previousRoot)?void 0:a.getState());const[i]=t.raycaster.intersectObject(u);if(!i)return!1;const c=i.uv;r.raycaster.setFromCamera(r.pointer.set(2*c.x-1,2*c.y-1),r.camera)}),[]);return o.useImperativeHandle(p,(()=>y.texture),[y]),o.createElement(o.Fragment,null,n.createPortal(o.createElement(f,{renderPriority:i,frames:d,fbo:y},e),g,{events:{compute:h,priority:l}}),o.createElement("primitive",c.default({object:y.texture},m)))}));function f({frames:e,renderPriority:r,children:t,fbo:a}){let u=0;return n.useFrame((r=>{(e===1/0||u<e)&&(r.gl.setRenderTarget(a),r.gl.render(r.scene,r.camera),r.gl.setRenderTarget(null),u++)}),r),o.createElement(o.Fragment,null,t)}exports.RenderTexture=l;
@@ -3,6 +3,7 @@ import * as React from 'react';
3
3
  export declare const RenderTexture: React.ForwardRefExoticComponent<THREE.Texture & {
4
4
  width?: number | undefined;
5
5
  height?: number | undefined;
6
+ samples?: number | undefined;
6
7
  renderPriority?: number | undefined;
7
8
  eventPriority?: number | undefined;
8
9
  frames?: number | undefined;
@@ -8,6 +8,7 @@ const RenderTexture = /*#__PURE__*/React.forwardRef(({
8
8
  children,
9
9
  width,
10
10
  height,
11
+ samples = 8,
11
12
  renderPriority = 0,
12
13
  eventPriority = 0,
13
14
  frames = Infinity,
@@ -18,7 +19,7 @@ const RenderTexture = /*#__PURE__*/React.forwardRef(({
18
19
  viewport
19
20
  } = useThree();
20
21
  const fbo = useFBO((width || size.width) * viewport.dpr, (height || size.height) * viewport.dpr, {
21
- samples: 8
22
+ samples
22
23
  });
23
24
  const [vScene] = React.useState(() => new THREE.Scene());
24
25
  const compute = React.useCallback((event, state, previous) => {
package/core/Stage.cjs.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("react"),r=require("three"),n=require("@react-three/fiber"),i=require("./Environment.cjs.js"),a=require("./ContactShadows.cjs.js");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function o(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}require("three-stdlib"),require("../helpers/environment-assets.cjs.js"),require("./shapes.cjs.js");var u=s(e),c=o(t),l=o(r);const f={rembrandt:{main:[1,2,1],fill:[-2,-.5,-2]},portrait:{main:[-1,2,.5],fill:[-1,.5,-1.5]},upfront:{main:[0,2,1],fill:[-1,.5,-1.5]},soft:{main:[-2,4,4],fill:[-1,.5,-1.5]}};exports.Stage=function({children:e,controls:t,shadows:r=!0,adjustCamera:s=!0,environment:o="city",intensity:d=1,preset:m="rembrandt",shadowBias:h=0,contactShadow:p={blur:2,opacity:.5,position:[0,0,0]},...b}){const g=f[m],j=n.useThree((e=>e.camera)),y=n.useThree((e=>e.controls)),w=c.useRef(null),E=c.useRef(null),[{radius:x,width:v,height:q},O]=c.useState({radius:0,width:0,height:0});return c.useLayoutEffect((()=>{w.current.position.set(0,0,0),w.current.updateWorldMatrix(!0,!0);const e=(new l.Box3).setFromObject(E.current),t=new l.Vector3,r=new l.Sphere,n=e.max.y-e.min.y,i=e.max.x-e.min.x;e.getCenter(t),e.getBoundingSphere(r),O({radius:r.radius,width:i,height:n}),w.current.position.set(-t.x,-t.y+n/2,-t.z)}),[e]),c.useLayoutEffect((()=>{if(s){const e=x/(q>v?1.5:2.5);j.position.set(0,.5*x,2.5*x),j.near=.1,j.far=Math.max(5e3,4*x),j.lookAt(0,e,0);const r=y||(null==t?void 0:t.current);r&&(r.target.set(0,e,0),r.update())}}),[y,x,q,v,s]),c.createElement("group",b,c.createElement("group",{ref:w},c.createElement("group",{ref:E},e)),p&&c.createElement(a.ContactShadows,u.default({scale:2*x,far:x/2},p)),o&&c.createElement(i.Environment,{preset:o}),c.createElement("ambientLight",{intensity:d/3}),c.createElement("spotLight",{penumbra:1,position:[g.main[0]*x,g.main[1]*x,g.main[2]*x],intensity:2*d,castShadow:r,"shadow-bias":h}),c.createElement("pointLight",{position:[g.fill[0]*x,g.fill[1]*x,g.fill[2]*x],intensity:d}))};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("react"),r=require("three"),n=require("@react-three/fiber"),i=require("./Environment.cjs.js"),a=require("./ContactShadows.cjs.js");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function s(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}require("three-stdlib"),require("../helpers/environment-assets.cjs.js");var u=o(e),c=s(t),l=s(r);const f={rembrandt:{main:[1,2,1],fill:[-2,-.5,-2]},portrait:{main:[-1,2,.5],fill:[-1,.5,-1.5]},upfront:{main:[0,2,1],fill:[-1,.5,-1.5]},soft:{main:[-2,4,4],fill:[-1,.5,-1.5]}};exports.Stage=function({children:e,controls:t,shadows:r=!0,adjustCamera:o=!0,environment:s="city",intensity:d=1,preset:m="rembrandt",shadowBias:h=0,contactShadow:p={blur:2,opacity:.5,position:[0,0,0]},...b}){const g=f[m],y=n.useThree((e=>e.camera)),j=n.useThree((e=>e.controls)),w=c.useRef(null),E=c.useRef(null),[{radius:x,width:v,height:q},O]=c.useState({radius:0,width:0,height:0});return c.useLayoutEffect((()=>{w.current.position.set(0,0,0),w.current.updateWorldMatrix(!0,!0);const e=(new l.Box3).setFromObject(E.current),t=new l.Vector3,r=new l.Sphere,n=e.max.y-e.min.y,i=e.max.x-e.min.x;e.getCenter(t),e.getBoundingSphere(r),O({radius:r.radius,width:i,height:n}),w.current.position.set(-t.x,-t.y+n/2,-t.z)}),[e]),c.useLayoutEffect((()=>{if(o){const e=x/(q>v?1.5:2.5);y.position.set(0,.5*x,2.5*x),y.near=.1,y.far=Math.max(5e3,4*x),y.lookAt(0,e,0);const r=j||(null==t?void 0:t.current);r&&(r.target.set(0,e,0),r.update())}}),[j,x,q,v,o]),c.createElement("group",b,c.createElement("group",{ref:w},c.createElement("group",{ref:E},e)),p&&c.createElement(a.ContactShadows,u.default({scale:2*x,far:x/2},p)),s&&c.createElement(i.Environment,{preset:s}),c.createElement("ambientLight",{intensity:d/3}),c.createElement("spotLight",{penumbra:1,position:[g.main[0]*x,g.main[1]*x,g.main[2]*x],intensity:2*d,castShadow:r,"shadow-bias":h}),c.createElement("pointLight",{position:[g.fill[0]*x,g.fill[1]*x,g.fill[2]*x],intensity:d}))};