@react-three/drei 9.41.3 → 9.42.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
@@ -2312,7 +2312,13 @@ function Effects() {
2312
2312
 
2313
2313
  Views use gl.scissor to cut the viewport into segments. You tie a view to a tracking div which then controls the position and bounds of the viewport. This allows you to have multiple views with a single, performant canvas. These views will follow their tracking elements, scroll along, resize, etc.
2314
2314
 
2315
- It is advisable to re-connect the event system to a parent that contains both the canvas and the html content. This ensures that both are accessible/selectable and even allows you to mount controls or other deeper integrations into your view.
2315
+ It is advisable to re-connect the event system to a parent that contains both the canvas and the html content.
2316
+ This ensures that both are accessible/selectable and even allows you to mount controls or other deeper
2317
+ integrations into your view.
2318
+
2319
+ > Note that `@react-three/fiber` newer than `^8.1.0` is required for `View` to work correctly if the
2320
+ > canvas/react three fiber root is not fullscreen. A warning will be logged if drei is used with older
2321
+ > versions of `@react-three/fiber`.
2316
2322
 
2317
2323
  ```tsx
2318
2324
  <View
@@ -2558,8 +2564,7 @@ Calculates a boundary box and centers the camera accordingly. If you are using c
2558
2564
  <mesh />
2559
2565
  </Bounds>
2560
2566
  ```
2561
-
2562
- The Bounds component also acts as a context provider, use the `useBounds` hook to refresh the bounds, fit the camera, clip near/far planes or focus objects. `refresh(object?: THREE.Object3D | THREE.Box3)` will recalculate bounds. Since this can be expensive only call it when you know the view has changed. `clip` sets the cameras near/far planes. `fit` zooms and centers the view.
2567
+ The Bounds component also acts as a context provider, use the `useBounds` hook to refresh the bounds, fit the camera, clip near/far planes, go to camera orientations or focus objects. `refresh(object?: THREE.Object3D | THREE.Box3)` will recalculate bounds, since this can be expensive only call it when you know the view has changed. `clip` sets the cameras near/far planes. `to` sets a position and target for the camera. `fit` zooms and centers the view.
2563
2568
 
2564
2569
  ```jsx
2565
2570
  function Foo() {
@@ -2567,10 +2572,13 @@ function Foo() {
2567
2572
  useEffect(() => {
2568
2573
  // Calculate scene bounds
2569
2574
  bounds.refresh().clip().fit()
2575
+
2570
2576
  // Or, focus a specific object or box3
2571
2577
  // bounds.refresh(ref.current).clip().fit()
2572
2578
  // bounds.refresh(new THREE.Box3()).clip().fit()
2573
2579
 
2580
+ // Or, send the camera to a specific orientatin
2581
+ // bounds.to({position: [0, 10, 10], target: {[5, 5, 0]}})
2574
2582
  <Bounds>
2575
2583
  <Foo />
2576
2584
  ```
@@ -2643,25 +2651,33 @@ Creates a "stage" with proper studio lighting, 0/0/0 top-centred, model-shadows,
2643
2651
 
2644
2652
  ```tsx
2645
2653
  type StageShadows = Partial<AccumulativeShadowsProps> &
2654
+ Partial<RandomizedLightProps> &
2646
2655
  Partial<ContactShadowsProps> & {
2647
2656
  type: 'contact' | 'accumulative'
2648
2657
  /** Shadow plane offset, default: 0 */
2649
2658
  offset?: number
2650
2659
  /** Shadow bias, default: -0.0001 */
2651
2660
  bias?: number
2661
+ /** Shadow normal bias, default: 0 */
2662
+ normalBias?: number
2652
2663
  /** Shadow map size, default: 1024 */
2653
2664
  size?: number
2654
2665
  }
2655
2666
 
2656
- type StageProps = JSX.IntrinsicElements['group'] & {
2667
+ type StageProps = {
2657
2668
  /** Lighting setup, default: "rembrandt" */
2658
- preset?: 'rembrandt' | 'portrait' | 'upfront' | 'soft'
2669
+ preset?:
2670
+ | 'rembrandt'
2671
+ | 'portrait'
2672
+ | 'upfront'
2673
+ | 'soft'
2674
+ | { main: [x: number, y: number, z: number]; fill: [x: number, y: number, z: number] }
2659
2675
  /** Controls the ground shadows, default: "contact" */
2660
2676
  shadows?: boolean | 'contact' | 'accumulative' | StageShadows
2661
- /** Optional zoom-to-fit using <Bounds>, can also be a margin, default: true */
2677
+ /** Optionally wraps and thereby centers the models using <Bounds>, can also be a margin, default: true */
2662
2678
  adjustCamera?: boolean | number
2663
2679
  /** The default environment, default: "city" */
2664
- environment?: PresetsType | null
2680
+ environment?: PresetsType | Partial<EnvironmentProps>
2665
2681
  /** The lighting intensity, default: 0.5 */
2666
2682
  intensity?: number
2667
2683
  }
@@ -2670,7 +2686,7 @@ type StageProps = JSX.IntrinsicElements['group'] & {
2670
2686
  By default it gives you contact shadows and auto-centering.
2671
2687
 
2672
2688
  ```jsx
2673
- <Stage>
2689
+ <Stage adjustCamera intensity={0.5} shadows="contact" environment="city">
2674
2690
  <mesh />
2675
2691
  </Stage>
2676
2692
  ```
@@ -60,6 +60,20 @@ export declare const AccumulativeShadows: React.ForwardRefExoticComponent<Pick<O
60
60
  layers?: ReactThreeFiber.Layers | undefined;
61
61
  dispose?: (() => void) | null | undefined;
62
62
  } & import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers & AccumulativeShadowsProps, "visible" | "attach" | "args" | "children" | "key" | "onUpdate" | "position" | "up" | "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 | keyof AccumulativeShadowsProps> & React.RefAttributes<AccumulativeContext>>;
63
+ export declare type RandomizedLightProps = {
64
+ frames?: number;
65
+ position?: [x: number, y: number, z: number];
66
+ radius?: number;
67
+ amount?: number;
68
+ intensity?: number;
69
+ ambient?: number;
70
+ castShadow?: boolean;
71
+ bias?: number;
72
+ mapSize?: number;
73
+ size?: number;
74
+ near?: number;
75
+ far?: number;
76
+ };
63
77
  export declare const RandomizedLight: React.ForwardRefExoticComponent<Pick<Omit<ReactThreeFiber.ExtendedColors<ReactThreeFiber.Overwrite<Partial<THREE.Group>, ReactThreeFiber.NodeProps<THREE.Group, typeof THREE.Group>>>, ReactThreeFiber.NonFunctionKeys<{
64
78
  position?: ReactThreeFiber.Vector3 | undefined;
65
79
  up?: ReactThreeFiber.Vector3 | undefined;
@@ -78,18 +92,5 @@ export declare const RandomizedLight: React.ForwardRefExoticComponent<Pick<Omit<
78
92
  quaternion?: ReactThreeFiber.Quaternion | undefined;
79
93
  layers?: ReactThreeFiber.Layers | undefined;
80
94
  dispose?: (() => void) | null | undefined;
81
- } & import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers & {
82
- frames?: number | undefined;
83
- position?: [x: number, y: number, z: number] | undefined;
84
- radius?: number | undefined;
85
- amount?: number | undefined;
86
- intensity?: number | undefined;
87
- ambient?: number | undefined;
88
- castShadow?: boolean | undefined;
89
- bias?: number | undefined;
90
- mapSize?: number | undefined;
91
- size?: number | undefined;
92
- near?: number | undefined;
93
- far?: number | undefined;
94
- }, "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" | "bias" | "radius" | "mapSize" | "frames" | "amount" | "ambient"> & React.RefAttributes<AccumulativeLightContext>>;
95
+ } & import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers & RandomizedLightProps, "visible" | "attach" | "args" | "children" | "key" | "onUpdate" | "up" | "scale" | "rotation" | "matrix" | "quaternion" | "layers" | "dispose" | "type" | "isGroup" | "id" | "uuid" | "name" | "parent" | "modelViewMatrix" | "normalMatrix" | "matrixWorld" | "matrixAutoUpdate" | "matrixWorldNeedsUpdate" | "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 | keyof RandomizedLightProps> & React.RefAttributes<AccumulativeLightContext>>;
95
96
  export {};
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("three"),r=require("@react-three/fiber");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 o=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,o.get?o:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var a=o(e),n=o(t);const c=e=>e&&e.isOrthographicCamera,i=a.createContext(null);exports.Bounds=function({children:e,damping:t=6,fit:o,clip:s,observe:u,margin:m=1.2,eps:f=.01,onFit:l}){const p=a.useRef(null),{camera:x,invalidate:y,size:z,controls:d}=r.useThree(),h=d,M=a.useRef(l);function g(e,t){return Math.abs(e.x-t.x)<f&&Math.abs(e.y-t.y)<f&&Math.abs(e.z-t.z)<f}function b(e,t,r,o){e.x=n.MathUtils.damp(e.x,t.x,r,o),e.y=n.MathUtils.damp(e.y,t.y,r,o),e.z=n.MathUtils.damp(e.z,t.z,r,o)}M.current=l;const[w]=a.useState((()=>({animating:!1,focus:new n.Vector3,camera:new n.Vector3,zoom:1}))),[v]=a.useState((()=>({focus:new n.Vector3,camera:new n.Vector3,zoom:1}))),[V]=a.useState((()=>new n.Box3)),j=a.useMemo((()=>{function e(){const e=V.getSize(new n.Vector3),t=V.getCenter(new n.Vector3),r=Math.max(e.x,e.y,e.z),o=c(x)?4*r:r/(2*Math.atan(Math.PI*x.fov/360)),a=c(x)?4*r:o/x.aspect,i=m*Math.max(o,a);return{box:V,size:e,center:t,distance:i}}return{getSize:e,refresh(t){if((r=t)&&r.isBox3)V.copy(t);else{const e=t||p.current;e.updateWorldMatrix(!0,!0),V.setFromObject(e)}var r;if(V.isEmpty()){const e=x.position.length()||10;V.setFromCenterAndSize(new n.Vector3,new n.Vector3(e,e,e))}if("OrthographicTrackballControls"===(null==h?void 0:h.constructor.name)){const{distance:t}=e(),r=x.position.clone().sub(h.target).normalize().multiplyScalar(t),o=h.target.clone().add(r);x.position.copy(o)}return this},clip(){const{distance:t}=e();return h&&(h.maxDistance=10*t),x.near=t/100,x.far=100*t,x.updateProjectionMatrix(),h&&h.update(),y(),this},fit(){w.camera.copy(x.position),h&&w.focus.copy(h.target);const{center:r,distance:o}=e(),a=r.clone().sub(x.position).normalize().multiplyScalar(o);if(v.camera.copy(r).sub(a),v.focus.copy(r),c(x)){w.zoom=x.zoom;let e=0,o=0;const a=[new n.Vector3(V.min.x,V.min.y,V.min.z),new n.Vector3(V.min.x,V.max.y,V.min.z),new n.Vector3(V.min.x,V.min.y,V.max.z),new n.Vector3(V.min.x,V.max.y,V.max.z),new n.Vector3(V.max.x,V.max.y,V.max.z),new n.Vector3(V.max.x,V.max.y,V.min.z),new n.Vector3(V.max.x,V.min.y,V.max.z),new n.Vector3(V.max.x,V.min.y,V.min.z)];r.applyMatrix4(x.matrixWorldInverse);for(const t of a)t.applyMatrix4(x.matrixWorldInverse),e=Math.max(e,Math.abs(t.y-r.y)),o=Math.max(o,Math.abs(t.x-r.x));e*=2,o*=2;const c=(x.top-x.bottom)/e,i=(x.right-x.left)/o;v.zoom=Math.min(c,i)/m,t||(x.zoom=v.zoom,x.updateProjectionMatrix())}return t?w.animating=!0:(x.position.copy(v.camera),x.lookAt(v.focus),h&&(h.target.copy(v.focus),h.update())),M.current&&M.current(this.getSize()),y(),this}}}),[V,x,h,m,t,y]);a.useLayoutEffect((()=>{if(h){const e=()=>w.animating=!1;return h.addEventListener("start",e),()=>h.removeEventListener("start",e)}}),[h]);const O=a.useRef(0);return a.useLayoutEffect((()=>{(u||0==O.current++)&&(j.refresh(),o&&j.fit(),s&&j.clip())}),[z,s,o,u,x,h]),r.useFrame(((e,r)=>{if(w.animating){if(b(w.focus,v.focus,t,r),b(w.camera,v.camera,t,r),w.zoom=n.MathUtils.damp(w.zoom,v.zoom,t,r),x.position.copy(w.camera),c(x)&&(x.zoom=w.zoom,x.updateProjectionMatrix()),h?(h.target.copy(w.focus),h.update()):x.lookAt(w.focus),y(),c(x)&&!(Math.abs(w.zoom-v.zoom)<f))return;if(!c(x)&&!g(w.camera,v.camera))return;if(h&&!g(w.focus,v.focus))return;w.animating=!1}})),a.createElement("group",{ref:p},a.createElement(i.Provider,{value:j},e))},exports.useBounds=function(){return a.useContext(i)};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("three"),o=require("@react-three/fiber");function r(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(o){if("default"!==o){var r=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(t,o,r.get?r:{enumerable:!0,get:function(){return e[o]}})}})),t.default=e,Object.freeze(t)}var a=r(e),n=r(t);const i=e=>e&&e.isOrthographicCamera,c=a.createContext(null);exports.Bounds=function({children:e,damping:t=6,fit:r,clip:s,observe:u,margin:m=1.2,eps:f=.01,onFit:p}){const l=a.useRef(null),{camera:x,invalidate:y,size:z,controls:d}=o.useThree(),h=d,g=a.useRef(p);function M(e,t){return Math.abs(e.x-t.x)<f&&Math.abs(e.y-t.y)<f&&Math.abs(e.z-t.z)<f}function b(e,t,o,r){e.x=n.MathUtils.damp(e.x,t.x,o,r),e.y=n.MathUtils.damp(e.y,t.y,o,r),e.z=n.MathUtils.damp(e.z,t.z,o,r)}g.current=p;const[w]=a.useState((()=>({animating:!1,focus:new n.Vector3,camera:new n.Vector3,zoom:1}))),[v]=a.useState((()=>({focus:new n.Vector3,camera:new n.Vector3,zoom:1}))),[V]=a.useState((()=>new n.Box3)),j=a.useMemo((()=>{function e(){const e=V.getSize(new n.Vector3),t=V.getCenter(new n.Vector3),o=Math.max(e.x,e.y,e.z),r=i(x)?4*o:o/(2*Math.atan(Math.PI*x.fov/360)),a=i(x)?4*o:r/x.aspect,c=m*Math.max(r,a);return{box:V,size:e,center:t,distance:c}}return{getSize:e,refresh(t){if((o=t)&&o.isBox3)V.copy(t);else{const e=t||l.current;e.updateWorldMatrix(!0,!0),V.setFromObject(e)}var o;if(V.isEmpty()){const e=x.position.length()||10;V.setFromCenterAndSize(new n.Vector3,new n.Vector3(e,e,e))}if("OrthographicTrackballControls"===(null==h?void 0:h.constructor.name)){const{distance:t}=e(),o=x.position.clone().sub(h.target).normalize().multiplyScalar(t),r=h.target.clone().add(o);x.position.copy(r)}return this},clip(){const{distance:t}=e();return h&&(h.maxDistance=10*t),x.near=t/100,x.far=100*t,x.updateProjectionMatrix(),h&&h.update(),y(),this},to({position:o,target:r}){w.camera.copy(x.position);const{center:a}=e();return v.camera.set(...o),r?v.focus.set(...r):v.focus.copy(a),t?w.animating=!0:x.position.set(...o),this},fit(){w.camera.copy(x.position),h&&w.focus.copy(h.target);const{center:o,distance:r}=e(),a=o.clone().sub(x.position).normalize().multiplyScalar(r);if(v.camera.copy(o).sub(a),v.focus.copy(o),i(x)){w.zoom=x.zoom;let e=0,r=0;const a=[new n.Vector3(V.min.x,V.min.y,V.min.z),new n.Vector3(V.min.x,V.max.y,V.min.z),new n.Vector3(V.min.x,V.min.y,V.max.z),new n.Vector3(V.min.x,V.max.y,V.max.z),new n.Vector3(V.max.x,V.max.y,V.max.z),new n.Vector3(V.max.x,V.max.y,V.min.z),new n.Vector3(V.max.x,V.min.y,V.max.z),new n.Vector3(V.max.x,V.min.y,V.min.z)];o.applyMatrix4(x.matrixWorldInverse);for(const t of a)t.applyMatrix4(x.matrixWorldInverse),e=Math.max(e,Math.abs(t.y-o.y)),r=Math.max(r,Math.abs(t.x-o.x));e*=2,r*=2;const i=(x.top-x.bottom)/e,c=(x.right-x.left)/r;v.zoom=Math.min(i,c)/m,t||(x.zoom=v.zoom,x.updateProjectionMatrix())}return t?w.animating=!0:(x.position.copy(v.camera),x.lookAt(v.focus),h&&(h.target.copy(v.focus),h.update())),g.current&&g.current(this.getSize()),y(),this}}}),[V,x,h,m,t,y]);a.useLayoutEffect((()=>{if(h){const e=()=>w.animating=!1;return h.addEventListener("start",e),()=>h.removeEventListener("start",e)}}),[h]);const O=a.useRef(0);return a.useLayoutEffect((()=>{(u||0==O.current++)&&(j.refresh(),r&&j.fit(),s&&j.clip())}),[z,s,r,u,x,h]),o.useFrame(((e,o)=>{if(w.animating){if(b(w.focus,v.focus,t,o),b(w.camera,v.camera,t,o),w.zoom=n.MathUtils.damp(w.zoom,v.zoom,t,o),x.position.copy(w.camera),i(x)&&(x.zoom=w.zoom,x.updateProjectionMatrix()),h?(h.target.copy(w.focus),h.update()):x.lookAt(w.focus),y(),i(x)&&!(Math.abs(w.zoom-v.zoom)<f))return;if(!i(x)&&!M(w.camera,v.camera))return;if(h&&!M(w.focus,v.focus))return;w.animating=!1}})),a.createElement("group",{ref:l},a.createElement(c.Provider,{value:j},e))},exports.useBounds=function(){return a.useContext(c)};
package/core/Bounds.js CHANGED
@@ -82,7 +82,7 @@ function Bounds({
82
82
  }
83
83
 
84
84
  if ((controls == null ? void 0 : controls.constructor.name) === 'OrthographicTrackballControls') {
85
- // Put camera on a sphere along which it should moves
85
+ // Put camera on a sphere along which it should move
86
86
  const {
87
87
  distance
88
88
  } = getSize();
@@ -107,6 +107,31 @@ function Bounds({
107
107
  return this;
108
108
  },
109
109
 
110
+ to({
111
+ position,
112
+ target
113
+ }) {
114
+ current.camera.copy(camera.position);
115
+ const {
116
+ center
117
+ } = getSize();
118
+ goal.camera.set(...position);
119
+
120
+ if (target) {
121
+ goal.focus.set(...target);
122
+ } else {
123
+ goal.focus.copy(center);
124
+ }
125
+
126
+ if (damping) {
127
+ current.animating = true;
128
+ } else {
129
+ camera.position.set(...position);
130
+ }
131
+
132
+ return this;
133
+ },
134
+
110
135
  fit() {
111
136
  current.camera.copy(camera.position);
112
137
  if (controls) current.focus.copy(controls.target);
@@ -3,7 +3,7 @@ import { Object3DNode } from '@react-three/fiber';
3
3
  import { Texture, Scene, Loader, CubeTexture, TextureEncoding } from 'three';
4
4
  import { GroundProjectedEnv as GroundProjectedEnvImpl } from 'three-stdlib';
5
5
  import { PresetsType } from '../helpers/environment-assets';
6
- declare type Props = {
6
+ export declare type EnvironmentProps = {
7
7
  children?: React.ReactNode;
8
8
  frames?: number;
9
9
  near?: number;
@@ -24,10 +24,10 @@ declare type Props = {
24
24
  };
25
25
  encoding?: TextureEncoding;
26
26
  };
27
- export declare function EnvironmentMap({ scene, background, blur, map }: Props): null;
28
- export declare function useEnvironment({ files, path, preset, encoding, extensions, }: Partial<Props>): Texture | CubeTexture;
29
- export declare function EnvironmentCube({ background, scene, blur, ...rest }: Props): null;
30
- export declare function EnvironmentPortal({ children, near, far, resolution, frames, map, background, blur, scene, files, path, preset, extensions, }: Props): JSX.Element;
27
+ export declare function EnvironmentMap({ scene, background, blur, map }: EnvironmentProps): null;
28
+ export declare function useEnvironment({ files, path, preset, encoding, extensions, }: Partial<EnvironmentProps>): Texture | CubeTexture;
29
+ export declare function EnvironmentCube({ background, scene, blur, ...rest }: EnvironmentProps): null;
30
+ export declare function EnvironmentPortal({ children, near, far, resolution, frames, map, background, blur, scene, files, path, preset, extensions, }: EnvironmentProps): JSX.Element;
31
31
  declare global {
32
32
  namespace JSX {
33
33
  interface IntrinsicElements {
@@ -35,5 +35,4 @@ declare global {
35
35
  }
36
36
  }
37
37
  }
38
- export declare function Environment(props: Props): JSX.Element;
39
- export {};
38
+ export declare function Environment(props: EnvironmentProps): JSX.Element;
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"),i=require("./Environment.cjs.js"),r=require("./ContactShadows.cjs.js"),n=require("./Center.cjs.js"),a=require("./AccumulativeShadows.cjs.js"),s=require("./Bounds.cjs.js");function u(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function l(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(i){if("default"!==i){var r=Object.getOwnPropertyDescriptor(e,i);Object.defineProperty(t,i,r.get?r:{enumerable:!0,get:function(){return e[i]}})}})),t.default=e,Object.freeze(t)}require("@react-three/fiber"),require("three"),require("three-stdlib"),require("../helpers/environment-assets.cjs.js"),require("./shaderMaterial.cjs.js");var o=u(e),c=l(t);const d={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]}};function m({radius:e,adjustCamera:t}){const i=s.useBounds();return c.useEffect((()=>{t&&i.refresh().clip().fit()}),[e,t]),null}exports.Stage=function({children:e,adjustCamera:t=!0,intensity:u=.5,shadows:l="contact",environment:f="city",preset:h="rembrandt",...p}){var b,j,v;const g=d[h],[{radius:E,height:y},q]=c.useState({radius:0,width:0,height:0,depth:0}),w=null!==(b=null==l?void 0:l.bias)&&void 0!==b?b:-1e-4,S=null!==(j=null==l?void 0:l.size)&&void 0!==j?j:1024,C=null!==(v=null==l?void 0:l.offset)&&void 0!==v?v:0,O="contact"===l||"contact"===(null==l?void 0:l.type),z="accumulative"===l||"accumulative"===(null==l?void 0:l.type),L={..."object"==typeof l?l:{}};return c.createElement(c.Fragment,null,c.createElement("ambientLight",{intensity:u/3}),c.createElement("spotLight",{penumbra:1,position:[g.main[0]*E,g.main[1]*E,g.main[2]*E],intensity:2*u,castShadow:!!l,"shadow-bias":w,"shadow-mapSize":S}),c.createElement("pointLight",{position:[g.fill[0]*E,g.fill[1]*E,g.fill[2]*E],intensity:u}),c.createElement(s.Bounds,o.default({fit:!!t,clip:!!t,margin:Number(t),observe:!0},p),c.createElement(m,{radius:E,adjustCamera:t}),c.createElement(n.Center,{position:[0,C/2,0],onCentered:({width:e,height:t,depth:i,boundingSphere:r,...n})=>q({radius:r.radius,width:e,height:t,depth:i})},e)),c.createElement("group",{position:[0,-y/2-C/2,0]},O&&c.createElement(r.ContactShadows,o.default({scale:4*E,far:E,blur:2},L)),z&&c.createElement(a.AccumulativeShadows,o.default({temporal:!0,frames:100,alphaTest:.9,toneMapped:!0,scale:4*E},L),c.createElement(a.RandomizedLight,{amount:8,radius:E,ambient:.5,intensity:1,position:[g.main[0]*E,g.main[1]*E,g.main[2]*E],size:4*E,bias:-w,mapSize:S}))),f&&c.createElement(i.Environment,{preset:f}))};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("react"),i=require("./Environment.cjs.js"),n=require("./ContactShadows.cjs.js"),r=require("./Center.cjs.js"),a=require("./AccumulativeShadows.cjs.js"),l=require("./Bounds.cjs.js");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function u(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(i){if("default"!==i){var n=Object.getOwnPropertyDescriptor(e,i);Object.defineProperty(t,i,n.get?n:{enumerable:!0,get:function(){return e[i]}})}})),t.default=e,Object.freeze(t)}require("@react-three/fiber"),require("three"),require("three-stdlib"),require("../helpers/environment-assets.cjs.js"),require("./shaderMaterial.cjs.js");var o=s(e),c=u(t);const d={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]}};function m({radius:e,adjustCamera:t}){const i=l.useBounds();return c.useEffect((()=>{t&&i.refresh().clip().fit()}),[e,t]),null}exports.Stage=function({children:e,adjustCamera:t=!0,intensity:s=.5,shadows:u="contact",environment:f="city",preset:p="rembrandt",...h}){var v,b,j,g,y,E,w,q;const S="string"==typeof p?d[p]:p,[{radius:C,height:O},z]=c.useState({radius:0,width:0,height:0,depth:0}),B=null!==(v=null==u?void 0:u.bias)&&void 0!==v?v:-1e-4,L=null!==(b=null==u?void 0:u.normalBias)&&void 0!==b?b:0,M=null!==(j=null==u?void 0:u.size)&&void 0!==j?j:1024,_=null!==(g=null==u?void 0:u.offset)&&void 0!==g?g:0,x="contact"===u||"contact"===(null==u?void 0:u.type),P="accumulative"===u||"accumulative"===(null==u?void 0:u.type),A={..."object"==typeof u?u:{}},k=f?"string"==typeof f?{preset:f}:f:null;return c.createElement(c.Fragment,null,c.createElement("ambientLight",{intensity:s/3}),c.createElement("spotLight",{penumbra:1,position:[S.main[0]*C,S.main[1]*C,S.main[2]*C],intensity:2*s,castShadow:!!u,"shadow-bias":B,"shadow-normalBias":L,"shadow-mapSize":M}),c.createElement("pointLight",{position:[S.fill[0]*C,S.fill[1]*C,S.fill[2]*C],intensity:s}),c.createElement(l.Bounds,o.default({fit:!!t,clip:!!t,margin:Number(t),observe:!0},h),c.createElement(m,{radius:C,adjustCamera:t}),c.createElement(r.Center,{position:[0,_/2,0],onCentered:({width:e,height:t,depth:i,boundingSphere:n,...r})=>z({radius:n.radius,width:e,height:t,depth:i})},e)),c.createElement("group",{position:[0,-O/2-_/2,0]},x&&c.createElement(n.ContactShadows,o.default({scale:4*C,far:C,blur:2},A)),P&&c.createElement(a.AccumulativeShadows,o.default({temporal:!0,frames:100,alphaTest:.9,toneMapped:!0,scale:4*C},A),c.createElement(a.RandomizedLight,{amount:null!==(y=A.amount)&&void 0!==y?y:8,radius:null!==(E=A.radius)&&void 0!==E?E:C,ambient:null!==(w=A.ambient)&&void 0!==w?w:.5,intensity:null!==(q=A.intensity)&&void 0!==q?q:1,position:[S.main[0]*C,S.main[1]*C,S.main[2]*C],size:4*C,bias:-B,mapSize:M}))),f&&c.createElement(i.Environment,k))};
package/core/Stage.d.ts CHANGED
@@ -1,19 +1,24 @@
1
1
  /// <reference types="react" />
2
+ import { EnvironmentProps } from './Environment';
2
3
  import { ContactShadowsProps } from './ContactShadows';
3
- import { AccumulativeShadowsProps } from './AccumulativeShadows';
4
+ import { AccumulativeShadowsProps, RandomizedLightProps } from './AccumulativeShadows';
4
5
  import { PresetsType } from '../helpers/environment-assets';
5
- declare type StageShadows = Partial<AccumulativeShadowsProps> & Partial<ContactShadowsProps> & {
6
+ declare type StageShadows = Partial<AccumulativeShadowsProps> & Partial<RandomizedLightProps> & Partial<ContactShadowsProps> & {
6
7
  type: 'contact' | 'accumulative';
7
8
  offset?: number;
8
9
  bias?: number;
10
+ normalBias?: number;
9
11
  size?: number;
10
12
  };
11
- declare type StageProps = JSX.IntrinsicElements['group'] & {
12
- preset?: 'rembrandt' | 'portrait' | 'upfront' | 'soft';
13
+ declare type StageProps = {
14
+ preset?: 'rembrandt' | 'portrait' | 'upfront' | 'soft' | {
15
+ main: [x: number, y: number, z: number];
16
+ fill: [x: number, y: number, z: number];
17
+ };
13
18
  shadows?: boolean | 'contact' | 'accumulative' | StageShadows;
14
19
  adjustCamera?: boolean | number;
15
- environment?: PresetsType | null;
20
+ environment?: PresetsType | Partial<EnvironmentProps>;
16
21
  intensity?: number;
17
22
  };
18
- export declare function Stage({ children, adjustCamera, intensity, shadows, environment, preset, ...props }: StageProps): JSX.Element;
23
+ export declare function Stage({ children, adjustCamera, intensity, shadows, environment, preset, ...props }: JSX.IntrinsicElements['group'] & StageProps): JSX.Element;
19
24
  export {};
package/core/Stage.js CHANGED
@@ -45,9 +45,9 @@ function Stage({
45
45
  preset = 'rembrandt',
46
46
  ...props
47
47
  }) {
48
- var _bias, _size, _offset;
48
+ var _bias, _normalBias, _size, _offset, _amount, _radius, _ambient, _intensity;
49
49
 
50
- const config = presets[preset];
50
+ const config = typeof preset === 'string' ? presets[preset] : preset;
51
51
  const [{
52
52
  radius,
53
53
  height
@@ -58,12 +58,16 @@ function Stage({
58
58
  depth: 0
59
59
  });
60
60
  const shadowBias = (_bias = shadows == null ? void 0 : shadows.bias) !== null && _bias !== void 0 ? _bias : -0.0001;
61
+ const normalBias = (_normalBias = shadows == null ? void 0 : shadows.normalBias) !== null && _normalBias !== void 0 ? _normalBias : 0;
61
62
  const shadowSize = (_size = shadows == null ? void 0 : shadows.size) !== null && _size !== void 0 ? _size : 1024;
62
63
  const shadowOffset = (_offset = shadows == null ? void 0 : shadows.offset) !== null && _offset !== void 0 ? _offset : 0;
63
64
  const contactShadow = shadows === 'contact' || (shadows == null ? void 0 : shadows.type) === 'contact';
64
65
  const accumulativeShadow = shadows === 'accumulative' || (shadows == null ? void 0 : shadows.type) === 'accumulative';
65
66
  const shadowSpread = { ...(typeof shadows === 'object' ? shadows : {})
66
67
  };
68
+ const environmentProps = !environment ? null : typeof environment === 'string' ? {
69
+ preset: environment
70
+ } : environment;
67
71
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("ambientLight", {
68
72
  intensity: intensity / 3
69
73
  }), /*#__PURE__*/React.createElement("spotLight", {
@@ -72,6 +76,7 @@ function Stage({
72
76
  intensity: intensity * 2,
73
77
  castShadow: !!shadows,
74
78
  "shadow-bias": shadowBias,
79
+ "shadow-normalBias": normalBias,
75
80
  "shadow-mapSize": shadowSize
76
81
  }), /*#__PURE__*/React.createElement("pointLight", {
77
82
  position: [config.fill[0] * radius, config.fill[1] * radius, config.fill[2] * radius],
@@ -111,17 +116,15 @@ function Stage({
111
116
  toneMapped: true,
112
117
  scale: radius * 4
113
118
  }, shadowSpread), /*#__PURE__*/React.createElement(RandomizedLight, {
114
- amount: 8,
115
- radius: radius,
116
- ambient: 0.5,
117
- intensity: 1,
119
+ amount: (_amount = shadowSpread.amount) !== null && _amount !== void 0 ? _amount : 8,
120
+ radius: (_radius = shadowSpread.radius) !== null && _radius !== void 0 ? _radius : radius,
121
+ ambient: (_ambient = shadowSpread.ambient) !== null && _ambient !== void 0 ? _ambient : 0.5,
122
+ intensity: (_intensity = shadowSpread.intensity) !== null && _intensity !== void 0 ? _intensity : 1,
118
123
  position: [config.main[0] * radius, config.main[1] * radius, config.main[2] * radius],
119
124
  size: radius * 4,
120
125
  bias: -shadowBias,
121
126
  mapSize: shadowSize
122
- }))), environment && /*#__PURE__*/React.createElement(Environment, {
123
- preset: environment
124
- }));
127
+ }))), environment && /*#__PURE__*/React.createElement(Environment, environmentProps));
125
128
  }
126
129
 
127
130
  export { Stage };