@react-three/drei 9.17.3 → 9.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md 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>
@@ -997,8 +999,6 @@ Antialiased round dots. It takes the same props as regular [THREE.PointsMaterial
997
999
 
998
1000
  #### softShadows
999
1001
 
1000
- [![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.vercel.app/?path=/story/shaders-softshadows--soft-shadows-st)
1001
-
1002
1002
  <p>
1003
1003
  <a href="https://codesandbox.io/s/dh2jc"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/dh2jc/screenshot.png" alt="Demo"/></a>
1004
1004
  </p>
@@ -2143,6 +2143,81 @@ Since this is a rather expensive effect you can limit the amount of frames it re
2143
2143
  <ContactShadows frames={1} />
2144
2144
  ```
2145
2145
 
2146
+ ### RandomizedLight
2147
+
2148
+ 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.
2149
+
2150
+ ```tsx
2151
+ type RandomizedLightProps = JSX.IntrinsicElements['group'] & {
2152
+ /** How many frames it will jiggle the lights, 1.
2153
+ * Frames is context aware, if a provider like AccumulativeShadows exists, frames will be taken from there! */
2154
+ frames?: number
2155
+ /** Light position, [0, 0, 0] */
2156
+ position?: [x: number, y: number, z: number]
2157
+ /** Radius of the jiggle, higher values make softer light, 5 */
2158
+ radius?: number
2159
+ /** Amount of lights, 8 */
2160
+ amount?: number
2161
+ /** Light intensity, 1 */
2162
+ intensity?: number
2163
+ /** Ambient occlusion, lower values mean less AO, hight more, you can mix AO and directional light, 0.5 */
2164
+ ambient?: number
2165
+ /** If the lights cast shadows, this is true by default */
2166
+ castShadow?: boolean
2167
+ /** Default shadow bias, 0 */
2168
+ bias?: number
2169
+ /** Default map size, 512 */
2170
+ mapSize?: number
2171
+ /** Default size of the shadow camera, 10 */
2172
+ size?: number
2173
+ /** Default shadow camera near, 0.5 */
2174
+ near?: number
2175
+ /** Default shadow camera far, 500 */
2176
+ far?: number
2177
+ }
2178
+ ```
2179
+
2180
+ ```jsx
2181
+ <RandomizedLight castShadow amount={8} frames={100} position={[5, 5, -10]} />
2182
+ ```
2183
+
2184
+ ###  AccumulativeShadows
2185
+
2186
+ <p>
2187
+ <a href="https://codesandbox.io/s/hxcc1x"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/hxcc1x/screenshot.png" alt="Demo"/></a>
2188
+ </p>
2189
+
2190
+ 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.
2191
+
2192
+ 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.
2193
+
2194
+ ```tsx
2195
+ type AccumulativeShadowsProps = JSX.IntrinsicElements['group'] & {
2196
+ /** How many frames it can render, more yields cleaner results but takes more time, 40 */
2197
+ frames?: number
2198
+ /** If frames === Infinity blend controls the refresh ratio, 100 */
2199
+ blend?: number
2200
+ /** Scale of the plane, */
2201
+ scale?: number
2202
+ /** Temporal accumulates shadows over time which is more performant but has a visual regression over instant results, false */
2203
+ temporal?: false
2204
+ /** Opacity of the plane, 1 */
2205
+ opacity?: number
2206
+ /** Discards alpha pixels, 0.65 */
2207
+ alphaTest?: number
2208
+ /** Shadow color, black */
2209
+ color?: string
2210
+ /** Buffer resolution, 1024 */
2211
+ resolution?: number
2212
+ }
2213
+ ```
2214
+
2215
+ ```jsx
2216
+ <AccumulativeShadows temporal frames={100} scale={10}>
2217
+ <RandomizedLight castShadow amount={8} position={[5, 5, -10]} />
2218
+ </AccumulativeShadows>
2219
+ ```
2220
+
2146
2221
  #### SpotLight
2147
2222
 
2148
2223
  <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++}})),console.log(n,i,s),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,276 @@
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
+ console.log(size, near, far);
260
+ return /*#__PURE__*/React.createElement("group", _extends({
261
+ ref: mergeRefs([gLights, forwardRef])
262
+ }, props), Array.from({
263
+ length: amount
264
+ }, (_, index) => /*#__PURE__*/React.createElement("directionalLight", {
265
+ key: index,
266
+ castShadow: castShadow,
267
+ "shadow-bias": bias,
268
+ "shadow-mapSize": [mapSize, mapSize],
269
+ intensity: intensity / amount
270
+ }, /*#__PURE__*/React.createElement("orthographicCamera", {
271
+ attach: "shadow-camera",
272
+ args: [-size, size, size, -size, near, far]
273
+ }))));
274
+ });
275
+
276
+ export { AccumulativeShadows, RandomizedLight, accumulativeContext };
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),r=require("react"),t=require("three"),a=require("@react-three/fiber"),n=require("three-stdlib");function o(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 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 u=o(e),c=i(r),l=i(t);const s=c.forwardRef((({scale:e=10,frames:r=1/0,opacity:t=1,width:o=1,height:i=1,blur:s=1,far:d=10,resolution:f=512,smooth:h=!0,color:m="#000000",depthWrite:p=!1,renderOrder:g,...v},b)=>{const M=a.useThree((e=>e.scene)),y=a.useThree((e=>e.gl)),w=c.useRef(null);o*=Array.isArray(e)?e[0]:e||1,i*=Array.isArray(e)?e[1]:e||1;const[T,S,x,O,R,j,P]=c.useMemo((()=>{const e=new l.WebGLRenderTarget(f,f),r=new l.WebGLRenderTarget(f,f);r.texture.generateMipmaps=e.texture.generateMipmaps=!1;const t=new l.PlaneBufferGeometry(o,i).rotateX(Math.PI/2),a=new l.Mesh(t),u=new l.MeshDepthMaterial;u.depthTest=u.depthWrite=!1,u.onBeforeCompile=e=>{e.uniforms={...e.uniforms,ucolor:{value:new l.Color(m).convertSRGBToLinear()}},e.fragmentShader=e.fragmentShader.replace("void main() {","uniform vec3 ucolor;\n void main() {\n "),e.fragmentShader=e.fragmentShader.replace("vec4( vec3( 1.0 - fragCoordZ ), opacity );","vec4( ucolor, ( 1.0 - fragCoordZ ) * 1.0 );")};const c=new l.ShaderMaterial(n.HorizontalBlurShader),s=new l.ShaderMaterial(n.VerticalBlurShader);return s.depthTest=c.depthTest=!1,[e,t,u,a,c,s,r]}),[f,o,i,e,m]),B=e=>{O.visible=!0,O.material=R,R.uniforms.tDiffuse.value=T.texture,R.uniforms.h.value=1*e/256,y.setRenderTarget(P),y.render(O,w.current),O.material=j,j.uniforms.tDiffuse.value=P.texture,j.uniforms.v.value=1*e/256,y.setRenderTarget(T),y.render(O,w.current),O.visible=!1};let C=0;return a.useFrame((()=>{if(w.current&&(r===1/0||C<r)){const e=M.background;M.background=null;const r=M.overrideMaterial;M.overrideMaterial=x,y.setRenderTarget(T),y.render(M,w.current),M.overrideMaterial=r,B(s),h&&B(.4*s),y.setRenderTarget(null),M.background=e,C++}})),c.createElement("group",u.default({"rotation-x":Math.PI/2},v,{ref:b}),c.createElement("mesh",{renderOrder:g,geometry:S,scale:[1,-1,1],rotation:[-Math.PI/2,0,0]},c.createElement("meshBasicMaterial",{map:T.texture,"map-encoding":y.outputEncoding,transparent:!0,opacity:t,depthWrite:p})),c.createElement("orthographicCamera",{ref:w,args:[-o/2,o/2,i/2,-i/2,0,d]}))}));exports.ContactShadows=s;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),r=require("react"),t=require("three"),a=require("@react-three/fiber"),n=require("three-stdlib");function o(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 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 u=o(e),l=i(r),c=i(t);const s=l.forwardRef((({scale:e=10,frames:r=1/0,opacity:t=1,width:o=1,height:i=1,blur:s=1,far:d=10,resolution:f=512,smooth:h=!0,color:m="#000000",depthWrite:g=!1,renderOrder:p,...v},b)=>{const M=a.useThree((e=>e.scene)),y=a.useThree((e=>e.gl)),w=l.useRef(null);o*=Array.isArray(e)?e[0]:e||1,i*=Array.isArray(e)?e[1]:e||1;const[T,S,x,O,R,j,C]=l.useMemo((()=>{const e=new c.WebGLRenderTarget(f,f),r=new c.WebGLRenderTarget(f,f);r.texture.generateMipmaps=e.texture.generateMipmaps=!1;const t=new c.PlaneBufferGeometry(o,i).rotateX(Math.PI/2),a=new c.Mesh(t),u=new c.MeshDepthMaterial;u.depthTest=u.depthWrite=!1,u.onBeforeCompile=e=>{e.uniforms={...e.uniforms,ucolor:{value:new c.Color(m).convertSRGBToLinear()}},e.fragmentShader=e.fragmentShader.replace("void main() {","uniform vec3 ucolor;\n void main() {\n "),e.fragmentShader=e.fragmentShader.replace("vec4( vec3( 1.0 - fragCoordZ ), opacity );","vec4( ucolor * fragCoordZ * 2.0, ( 1.0 - fragCoordZ ) * 1.0 );"),console.log(e.fragmentShader)};const l=new c.ShaderMaterial(n.HorizontalBlurShader),s=new c.ShaderMaterial(n.VerticalBlurShader);return s.depthTest=l.depthTest=!1,[e,t,u,a,l,s,r]}),[f,o,i,e,m]),P=e=>{O.visible=!0,O.material=R,R.uniforms.tDiffuse.value=T.texture,R.uniforms.h.value=1*e/256,y.setRenderTarget(C),y.render(O,w.current),O.material=j,j.uniforms.tDiffuse.value=C.texture,j.uniforms.v.value=1*e/256,y.setRenderTarget(T),y.render(O,w.current),O.visible=!1};let B=0;return a.useFrame((()=>{if(w.current&&(r===1/0||B<r)){const e=M.background;M.background=null;const r=M.overrideMaterial;M.overrideMaterial=x,y.setRenderTarget(T),y.render(M,w.current),M.overrideMaterial=r,P(s),h&&P(.4*s),y.setRenderTarget(null),M.background=e,B++}})),l.createElement("group",u.default({"rotation-x":Math.PI/2},v,{ref:b}),l.createElement("mesh",{renderOrder:p,geometry:S,scale:[1,-1,1],rotation:[-Math.PI/2,0,0]},l.createElement("meshBasicMaterial",{map:T.texture,"map-encoding":y.outputEncoding,transparent:!0,opacity:t,depthWrite:g})),l.createElement("orthographicCamera",{ref:w,args:[-o/2,o/2,i/2,-i/2,0,d]}))}));exports.ContactShadows=s;
@@ -43,7 +43,9 @@ const ContactShadows = /*#__PURE__*/React.forwardRef(({
43
43
  `uniform vec3 ucolor;
44
44
  void main() {
45
45
  `);
46
- shader.fragmentShader = shader.fragmentShader.replace('vec4( vec3( 1.0 - fragCoordZ ), opacity );', 'vec4( ucolor, ( 1.0 - fragCoordZ ) * 1.0 );');
46
+ shader.fragmentShader = shader.fragmentShader.replace('vec4( vec3( 1.0 - fragCoordZ ), opacity );', // Colorize the shadow, multiply by the falloff so that the center can remain darker
47
+ 'vec4( ucolor * fragCoordZ * 2.0, ( 1.0 - fragCoordZ ) * 1.0 );');
48
+ console.log(shader.fragmentShader);
47
49
  };
48
50
 
49
51
  const horizontalBlurMaterial = new THREE.ShaderMaterial(HorizontalBlurShader);
@@ -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;