@react-three/drei 9.22.9 → 9.23.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 +26 -0
- package/core/AccumulativeShadows.cjs.js +1 -1
- package/core/AccumulativeShadows.d.ts +46 -32
- package/core/AccumulativeShadows.js +55 -68
- package/index.cjs.js +1 -1
- package/index.js +1 -0
- package/package.json +1 -1
- package/web/configureEvents.cjs.js +1 -0
- package/web/configureEvents.d.ts +8 -0
- package/web/configureEvents.js +19 -0
- package/web/index.cjs.js +1 -1
- package/web/index.d.ts +1 -0
- package/web/index.js +1 -0
package/README.md
CHANGED
|
@@ -111,6 +111,7 @@ The `native` route of the library **does not** export `Html` or `Loader`. The de
|
|
|
111
111
|
<li><a href="#useTrail">useTrail</a></li>
|
|
112
112
|
<li><a href="#useSurfaceSampler">useSurfaceSampler</a></li>
|
|
113
113
|
<li><a href="#BBAnchor">BBAnchor</a></li>
|
|
114
|
+
<li><a href="#configureevents">configureEvents</a></li>
|
|
114
115
|
</ul>
|
|
115
116
|
<li><a href="#loading">Loaders</a></li>
|
|
116
117
|
<ul>
|
|
@@ -1518,6 +1519,29 @@ For instance, one could want the Html component to be pinned to `positive x`, `p
|
|
|
1518
1519
|
</Box>
|
|
1519
1520
|
```
|
|
1520
1521
|
|
|
1522
|
+
#### configureEvents
|
|
1523
|
+
|
|
1524
|
+

|
|
1525
|
+
|
|
1526
|
+
A small helper that ties events to a different target (the default is the canvas itself). This is useful whenever you combine HTML and the canvas. If both need to receive events they have to share the same parent, and the canvas has to register its events there.
|
|
1527
|
+
|
|
1528
|
+
This function also allows you exchange the event prefix. By default fiber reads from event.offsetX(/Y), but in some situations it may be useful to use "client", especially if hovering HTML content resets your canvas pointer events to the upper/left of the viewport.
|
|
1529
|
+
|
|
1530
|
+
```tsx
|
|
1531
|
+
type EventOptions = {
|
|
1532
|
+
target?: HTMLElement
|
|
1533
|
+
prefix?: 'offset' | 'client' | 'page' | 'layer' | 'screen'
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
export function configureEvents(_options: EventOptions): (state: RootState) => void
|
|
1537
|
+
```
|
|
1538
|
+
|
|
1539
|
+
It is a curried function, you would typically drop this into onCreated.
|
|
1540
|
+
|
|
1541
|
+
```jsx
|
|
1542
|
+
<Canvas onCreated={configureEvents({ target: document.getElementById('root'), prefix: 'client' })}>
|
|
1543
|
+
```
|
|
1544
|
+
|
|
1521
1545
|
# Loading
|
|
1522
1546
|
|
|
1523
1547
|
#### Loader
|
|
@@ -2301,6 +2325,8 @@ type AccumulativeShadowsProps = JSX.IntrinsicElements['group'] & {
|
|
|
2301
2325
|
|
|
2302
2326
|
```tsx
|
|
2303
2327
|
interface AccumulativeContext {
|
|
2328
|
+
/** Returns the plane geometry onto which the shadow is cast */
|
|
2329
|
+
getMesh: () => THREE.Mesh<THREE.PlaneGeometry, SoftShadowMaterialProps & THREE.ShaderMaterial>
|
|
2304
2330
|
/** Resets the buffers, starting from scratch */
|
|
2305
2331
|
reset: () => void
|
|
2306
2332
|
/** Updates the lightmap for a number of frames accumulartively */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("three"),r=require("react"),a=require("@react-three/fiber");function
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("three"),r=require("react"),a=require("@react-three/fiber"),i=require("./shaderMaterial.cjs.js");function n(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 a=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,a.get?a:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var o=n(e),l=s(t),h=s(r);const c=h.createContext(null),u=i.shaderMaterial({color:new l.Color,blend:2,alphaTest:.75,opacity:0,map:null},"varying vec2 vUv;\n void main() {\n gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.);\n vUv = uv;\n }","varying vec2 vUv;\n uniform sampler2D map;\n uniform vec3 color;\n uniform float opacity;\n uniform float alphaTest;\n uniform float blend;\n void main() {\n vec4 sampledDiffuseColor = texture2D(map, vUv);\n gl_FragColor = vec4(color * sampledDiffuseColor.r * blend, max(0.0, (1.0 - (sampledDiffuseColor.r + sampledDiffuseColor.g + sampledDiffuseColor.b) / alphaTest)) * opacity);\n #include <tonemapping_fragment>\n #include <encodings_fragment>\n }"),d=i.shaderMaterial({},"void main() { gl_Position = vec4((uv - 0.5) * 2.0, 1.0, 1.0); }","void main() { discard; }"),p=h.forwardRef((({children:e,temporal:t,frames:r=40,limit:i=1/0,blend:n=20,scale:s=10,opacity:o=1,alphaTest:l=.75,color:d="black",colorBlend:p=2,resolution:g=1024,toneMapped:m=!0,...v},M)=>{a.extend({SoftShadowMaterial:u});const b=a.useThree((e=>e.gl)),y=a.useThree((e=>e.scene)),w=a.useThree((e=>e.camera)),S=h.useRef(null),x=h.useRef(null),[j]=h.useState((()=>new f(b,y,g)));h.useLayoutEffect((()=>{j.configure(S.current)}),[]);const E=h.useMemo((()=>({lights:new Map,temporal:!!t,frames:Math.max(2,r),blend:Math.max(2,r===1/0?n:r),count:0,getMesh:()=>S.current,reset:()=>{j.clear();const e=S.current.material;e.opacity=0,e.alphaTest=0,E.count=0},update:(e=1)=>{const t=S.current.material;E.temporal?(t.opacity=Math.min(o,t.opacity+o/E.blend),t.alphaTest=Math.min(l,t.alphaTest+l/E.blend)):(t.opacity=o,t.alphaTest=l),x.current.visible=!0,j.prepare();for(let t=0;t<e;t++)E.lights.forEach((e=>e.update())),j.update(w,E.blend);x.current.visible=!1,j.finish()}})),[j,w,y,t,r,n,o,l]);return h.useLayoutEffect((()=>{E.reset(),E.temporal||E.frames===1/0||E.update(E.blend)})),h.useImperativeHandle(M,(()=>E),[E]),a.useFrame((()=>{(E.temporal||E.frames===1/0)&&E.count<E.frames&&E.count<i&&(E.update(),E.count++)})),h.createElement("group",v,h.createElement("group",{traverse:()=>null,ref:x},h.createElement(c.Provider,{value:E},e)),h.createElement("mesh",{receiveShadow:!0,ref:S,scale:s,rotation:[-Math.PI/2,0,0]},h.createElement("planeGeometry",null),h.createElement("softShadowMaterial",{transparent:!0,depthWrite:!1,toneMapped:m,color:d,blend:p,map:j.progressiveLightMap2.texture})))})),g=h.forwardRef((({castShadow:e=!0,bias:t=.001,mapSize:r=512,size:a=5,near:i=.5,far:n=500,frames:s=1,position:u=[0,0,0],radius:d=1,amount:p=8,intensity:g=1,ambient:f=.5,...m},v)=>{const M=h.useRef(null),b=new l.Vector3(...u).length(),y=h.useContext(c),w=h.useCallback((()=>{let e;if(M.current)for(let t=0;t<M.current.children.length;t++)if(e=M.current.children[t],Math.random()>f)e.position.set(u[0]+l.MathUtils.randFloatSpread(d),u[1]+l.MathUtils.randFloatSpread(d),u[2]+l.MathUtils.randFloatSpread(d));else{let t=Math.acos(2*Math.random()-1)-Math.PI/2,r=2*Math.PI*Math.random();e.position.set(Math.cos(t)*Math.cos(r)*b,Math.abs(Math.cos(t)*Math.sin(r)*b),Math.sin(t)*b)}}),[d,f,b,...u]),S=h.useMemo((()=>({update:w})),[w]);return h.useImperativeHandle(v,(()=>S),[S]),h.useLayoutEffect((()=>{const e=M.current;return y&&y.lights.set(e.uuid,S),()=>{y.lights.delete(e.uuid)}}),[y,S]),h.createElement("group",o.default({ref:M},m),Array.from({length:p},((s,o)=>h.createElement("directionalLight",{key:o,castShadow:e,"shadow-bias":t,"shadow-mapSize":[r,r],intensity:g/p},h.createElement("orthographicCamera",{attach:"shadow-camera",args:[-a,a,a,-a,i,n]})))))}));class f{constructor(e,t,r=1024){this.renderer=e,this.res=r,this.scene=t,this.scene.background=null,this.buffer1Active=!1,this.lights=[],this.meshes=[],this.object=null;const a=/(Android|iPad|iPhone|iPod)/g.test(navigator.userAgent)?l.HalfFloatType:l.FloatType;this.progressiveLightMap1=new l.WebGLRenderTarget(this.res,this.res,{type:a,encoding:e.outputEncoding}),this.progressiveLightMap2=new l.WebGLRenderTarget(this.res,this.res,{type:a,encoding:e.outputEncoding}),this.discardMat=new d,this.targetMat=new l.MeshPhongMaterial({shininess:0}),this.previousShadowMap={value:this.progressiveLightMap1.texture},this.averagingWindow={value:100},this.targetMat.onBeforeCompile=e=>{e.vertexShader="varying vec2 vUv;\n"+e.vertexShader.slice(0,-1)+"vUv = uv; gl_Position = vec4((uv - 0.5) * 2.0, 1.0, 1.0); }";const t=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 vUv;\n"+e.fragmentShader.slice(0,t)+"\tuniform sampler2D previousShadowMap;\n\tuniform float averagingWindow;\n"+e.fragmentShader.slice(t-1,-1)+"\nvec3 texelOld = texture2D(previousShadowMap, vUv).rgb;\n gl_FragColor.rgb = mix(texelOld, gl_FragColor.rgb, 1.0/averagingWindow);\n }",e.uniforms.previousShadowMap=this.previousShadowMap,e.uniforms.averagingWindow=this.averagingWindow}}clear(){this.renderer.setRenderTarget(this.progressiveLightMap1),this.renderer.clear(),this.renderer.setRenderTarget(this.progressiveLightMap2),this.renderer.clear(),this.lights=[],this.meshes=[],this.scene.traverse((e=>{!function(e){return!!e.geometry}(e)?function(e){return e.isLight}(e)&&this.lights.push({object:e,intensity:e.intensity}):this.meshes.push({object:e,material:e.material})}))}prepare(){this.lights.forEach((e=>e.object.intensity=0)),this.meshes.forEach((e=>e.object.material=this.discardMat))}finish(){this.lights.forEach((e=>e.object.intensity=e.intensity)),this.meshes.forEach((e=>e.object.material=e.material))}configure(e){this.object=e}update(e,t=100){if(!this.object)return;this.averagingWindow.value=t,this.object.material=this.targetMat;const r=this.buffer1Active?this.progressiveLightMap1:this.progressiveLightMap2,a=this.buffer1Active?this.progressiveLightMap2:this.progressiveLightMap1;this.renderer.setRenderTarget(r),this.previousShadowMap.value=a.texture,this.buffer1Active=!this.buffer1Active,this.renderer.render(this.scene,e),this.renderer.setRenderTarget(null)}}exports.AccumulativeShadows=p,exports.RandomizedLight=g,exports.accumulativeContext=c;
|
|
@@ -1,35 +1,50 @@
|
|
|
1
1
|
import * as THREE from 'three';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
+
import { ReactThreeFiber } from '@react-three/fiber';
|
|
3
4
|
interface AccumulativeContext {
|
|
4
5
|
lights: Map<any, any>;
|
|
5
6
|
temporal: boolean;
|
|
6
7
|
frames: number;
|
|
7
8
|
blend: number;
|
|
8
9
|
count: number;
|
|
10
|
+
getMesh: () => THREE.Mesh<THREE.PlaneGeometry, SoftShadowMaterialProps & THREE.ShaderMaterial>;
|
|
9
11
|
reset: () => void;
|
|
10
12
|
update: (frames?: number) => void;
|
|
11
13
|
}
|
|
12
14
|
interface AccumulativeLightContext {
|
|
13
15
|
update: () => void;
|
|
14
16
|
}
|
|
17
|
+
declare type SoftShadowMaterialProps = {
|
|
18
|
+
map: THREE.Texture;
|
|
19
|
+
color?: ReactThreeFiber.Color;
|
|
20
|
+
alphaTest?: number;
|
|
21
|
+
blend?: number;
|
|
22
|
+
};
|
|
23
|
+
declare global {
|
|
24
|
+
namespace JSX {
|
|
25
|
+
interface IntrinsicElements {
|
|
26
|
+
softShadowMaterial: JSX.IntrinsicElements['shaderMaterial'] & SoftShadowMaterialProps;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
15
30
|
export declare const accumulativeContext: React.Context<AccumulativeContext>;
|
|
16
|
-
export declare const AccumulativeShadows: React.ForwardRefExoticComponent<Pick<Omit<
|
|
17
|
-
position?:
|
|
18
|
-
up?:
|
|
19
|
-
scale?:
|
|
20
|
-
rotation?:
|
|
21
|
-
matrix?:
|
|
22
|
-
quaternion?:
|
|
23
|
-
layers?:
|
|
31
|
+
export declare const AccumulativeShadows: React.ForwardRefExoticComponent<Pick<Omit<ReactThreeFiber.ExtendedColors<ReactThreeFiber.Overwrite<Partial<THREE.Group>, ReactThreeFiber.NodeProps<THREE.Group, typeof THREE.Group>>>, ReactThreeFiber.NonFunctionKeys<{
|
|
32
|
+
position?: ReactThreeFiber.Vector3 | undefined;
|
|
33
|
+
up?: ReactThreeFiber.Vector3 | undefined;
|
|
34
|
+
scale?: ReactThreeFiber.Vector3 | undefined;
|
|
35
|
+
rotation?: ReactThreeFiber.Euler | undefined;
|
|
36
|
+
matrix?: ReactThreeFiber.Matrix4 | undefined;
|
|
37
|
+
quaternion?: ReactThreeFiber.Quaternion | undefined;
|
|
38
|
+
layers?: ReactThreeFiber.Layers | undefined;
|
|
24
39
|
dispose?: (() => void) | null | undefined;
|
|
25
40
|
}>> & {
|
|
26
|
-
position?:
|
|
27
|
-
up?:
|
|
28
|
-
scale?:
|
|
29
|
-
rotation?:
|
|
30
|
-
matrix?:
|
|
31
|
-
quaternion?:
|
|
32
|
-
layers?:
|
|
41
|
+
position?: ReactThreeFiber.Vector3 | undefined;
|
|
42
|
+
up?: ReactThreeFiber.Vector3 | undefined;
|
|
43
|
+
scale?: ReactThreeFiber.Vector3 | undefined;
|
|
44
|
+
rotation?: ReactThreeFiber.Euler | undefined;
|
|
45
|
+
matrix?: ReactThreeFiber.Matrix4 | undefined;
|
|
46
|
+
quaternion?: ReactThreeFiber.Quaternion | undefined;
|
|
47
|
+
layers?: ReactThreeFiber.Layers | undefined;
|
|
33
48
|
dispose?: (() => void) | null | undefined;
|
|
34
49
|
} & import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers & {
|
|
35
50
|
frames?: number | undefined;
|
|
@@ -42,26 +57,25 @@ export declare const AccumulativeShadows: React.ForwardRefExoticComponent<Pick<O
|
|
|
42
57
|
color?: string | undefined;
|
|
43
58
|
colorBlend?: number | undefined;
|
|
44
59
|
resolution?: number | undefined;
|
|
45
|
-
encoding?: THREE.TextureEncoding | undefined;
|
|
46
60
|
toneMapped?: boolean | undefined;
|
|
47
|
-
}, "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" | "toneMapped" | "resolution" | "
|
|
48
|
-
export declare const RandomizedLight: React.ForwardRefExoticComponent<Pick<Omit<
|
|
49
|
-
position?:
|
|
50
|
-
up?:
|
|
51
|
-
scale?:
|
|
52
|
-
rotation?:
|
|
53
|
-
matrix?:
|
|
54
|
-
quaternion?:
|
|
55
|
-
layers?:
|
|
61
|
+
}, "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" | "toneMapped" | "resolution" | "frames" | "blend" | "temporal" | "limit" | "colorBlend"> & React.RefAttributes<AccumulativeContext>>;
|
|
62
|
+
export declare const RandomizedLight: React.ForwardRefExoticComponent<Pick<Omit<ReactThreeFiber.ExtendedColors<ReactThreeFiber.Overwrite<Partial<THREE.Group>, ReactThreeFiber.NodeProps<THREE.Group, typeof THREE.Group>>>, ReactThreeFiber.NonFunctionKeys<{
|
|
63
|
+
position?: ReactThreeFiber.Vector3 | undefined;
|
|
64
|
+
up?: ReactThreeFiber.Vector3 | undefined;
|
|
65
|
+
scale?: ReactThreeFiber.Vector3 | undefined;
|
|
66
|
+
rotation?: ReactThreeFiber.Euler | undefined;
|
|
67
|
+
matrix?: ReactThreeFiber.Matrix4 | undefined;
|
|
68
|
+
quaternion?: ReactThreeFiber.Quaternion | undefined;
|
|
69
|
+
layers?: ReactThreeFiber.Layers | undefined;
|
|
56
70
|
dispose?: (() => void) | null | undefined;
|
|
57
71
|
}>> & {
|
|
58
|
-
position?:
|
|
59
|
-
up?:
|
|
60
|
-
scale?:
|
|
61
|
-
rotation?:
|
|
62
|
-
matrix?:
|
|
63
|
-
quaternion?:
|
|
64
|
-
layers?:
|
|
72
|
+
position?: ReactThreeFiber.Vector3 | undefined;
|
|
73
|
+
up?: ReactThreeFiber.Vector3 | undefined;
|
|
74
|
+
scale?: ReactThreeFiber.Vector3 | undefined;
|
|
75
|
+
rotation?: ReactThreeFiber.Euler | undefined;
|
|
76
|
+
matrix?: ReactThreeFiber.Matrix4 | undefined;
|
|
77
|
+
quaternion?: ReactThreeFiber.Quaternion | undefined;
|
|
78
|
+
layers?: ReactThreeFiber.Layers | undefined;
|
|
65
79
|
dispose?: (() => void) | null | undefined;
|
|
66
80
|
} & import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers & {
|
|
67
81
|
frames?: number | undefined;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import _extends from '@babel/runtime/helpers/esm/extends';
|
|
2
2
|
import * as THREE from 'three';
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { useThree, useFrame } from '@react-three/fiber';
|
|
4
|
+
import { extend, useThree, useFrame } from '@react-three/fiber';
|
|
5
|
+
import { shaderMaterial } from './shaderMaterial.js';
|
|
5
6
|
|
|
6
7
|
function isLight(object) {
|
|
7
8
|
return object.isLight;
|
|
@@ -12,6 +13,29 @@ function isGeometry(object) {
|
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
const accumulativeContext = /*#__PURE__*/React.createContext(null);
|
|
16
|
+
const SoftShadowMaterial = shaderMaterial({
|
|
17
|
+
color: new THREE.Color(),
|
|
18
|
+
blend: 2.0,
|
|
19
|
+
alphaTest: 0.75,
|
|
20
|
+
opacity: 0,
|
|
21
|
+
map: null
|
|
22
|
+
}, `varying vec2 vUv;
|
|
23
|
+
void main() {
|
|
24
|
+
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.);
|
|
25
|
+
vUv = uv;
|
|
26
|
+
}`, `varying vec2 vUv;
|
|
27
|
+
uniform sampler2D map;
|
|
28
|
+
uniform vec3 color;
|
|
29
|
+
uniform float opacity;
|
|
30
|
+
uniform float alphaTest;
|
|
31
|
+
uniform float blend;
|
|
32
|
+
void main() {
|
|
33
|
+
vec4 sampledDiffuseColor = texture2D(map, vUv);
|
|
34
|
+
gl_FragColor = vec4(color * sampledDiffuseColor.r * blend, max(0.0, (1.0 - (sampledDiffuseColor.r + sampledDiffuseColor.g + sampledDiffuseColor.b) / alphaTest)) * opacity);
|
|
35
|
+
#include <tonemapping_fragment>
|
|
36
|
+
#include <encodings_fragment>
|
|
37
|
+
}`);
|
|
38
|
+
const DiscardMaterial = shaderMaterial({}, 'void main() { gl_Position = vec4((uv - 0.5) * 2.0, 1.0, 1.0); }', 'void main() { discard; }');
|
|
15
39
|
const AccumulativeShadows = /*#__PURE__*/React.forwardRef(({
|
|
16
40
|
children,
|
|
17
41
|
temporal,
|
|
@@ -20,14 +44,16 @@ const AccumulativeShadows = /*#__PURE__*/React.forwardRef(({
|
|
|
20
44
|
blend = 20,
|
|
21
45
|
scale = 10,
|
|
22
46
|
opacity = 1,
|
|
23
|
-
alphaTest = 0.
|
|
47
|
+
alphaTest = 0.75,
|
|
24
48
|
color = 'black',
|
|
25
49
|
colorBlend = 2,
|
|
26
50
|
resolution = 1024,
|
|
27
|
-
encoding,
|
|
28
51
|
toneMapped = true,
|
|
29
52
|
...props
|
|
30
53
|
}, forwardRef) => {
|
|
54
|
+
extend({
|
|
55
|
+
SoftShadowMaterial
|
|
56
|
+
});
|
|
31
57
|
const gl = useThree(state => state.gl);
|
|
32
58
|
const scene = useThree(state => state.scene);
|
|
33
59
|
const camera = useThree(state => state.camera);
|
|
@@ -36,66 +62,32 @@ const AccumulativeShadows = /*#__PURE__*/React.forwardRef(({
|
|
|
36
62
|
const [plm] = React.useState(() => new ProgressiveLightMap(gl, scene, resolution));
|
|
37
63
|
React.useLayoutEffect(() => {
|
|
38
64
|
plm.configure(gPlane.current);
|
|
39
|
-
}, []);
|
|
40
|
-
|
|
41
|
-
const material = React.useMemo(() => {
|
|
42
|
-
const mat = Object.assign(new THREE.MeshBasicMaterial({
|
|
43
|
-
opacity: 0,
|
|
44
|
-
transparent: true,
|
|
45
|
-
dithering: true,
|
|
46
|
-
depthWrite: false,
|
|
47
|
-
map: plm.progressiveLightMap2.texture
|
|
48
|
-
}), {
|
|
49
|
-
uniforms: {
|
|
50
|
-
ucolor: {
|
|
51
|
-
value: new THREE.Color(color)
|
|
52
|
-
},
|
|
53
|
-
ucolorBlend: {
|
|
54
|
-
value: colorBlend
|
|
55
|
-
},
|
|
56
|
-
alphaTest: {
|
|
57
|
-
value: 0
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
mat.onBeforeCompile = shader => {
|
|
63
|
-
mat.uniforms = shader.uniforms = { ...shader.uniforms,
|
|
64
|
-
...mat.uniforms
|
|
65
|
-
};
|
|
66
|
-
shader.fragmentShader = shader.fragmentShader.replace(`void main() {`, `uniform vec3 ucolor;
|
|
67
|
-
uniform float ucolorBlend;
|
|
68
|
-
uniform float alphaTest;
|
|
69
|
-
void main() {`);
|
|
70
|
-
shader.fragmentShader = shader.fragmentShader.replace('#include <dithering_fragment>', `#include <dithering_fragment>
|
|
71
|
-
gl_FragColor = vec4(ucolor * gl_FragColor.r * ucolorBlend, max(0.0, (1.0 - gl_FragColor.r / alphaTest)) * opacity);
|
|
72
|
-
#include <tonemapping_fragment>
|
|
73
|
-
#include <encodings_fragment>`);
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
return mat;
|
|
77
|
-
}, [color, colorBlend]);
|
|
65
|
+
}, []);
|
|
78
66
|
const api = React.useMemo(() => ({
|
|
79
67
|
lights: new Map(),
|
|
80
68
|
temporal: !!temporal,
|
|
81
69
|
frames: Math.max(2, frames),
|
|
82
70
|
blend: Math.max(2, frames === Infinity ? blend : frames),
|
|
83
71
|
count: 0,
|
|
72
|
+
getMesh: () => gPlane.current,
|
|
84
73
|
reset: () => {
|
|
85
74
|
// Clear buffers, reset opacities, set frame count to 0
|
|
86
75
|
plm.clear();
|
|
76
|
+
const material = gPlane.current.material;
|
|
87
77
|
material.opacity = 0;
|
|
88
|
-
material.
|
|
78
|
+
material.alphaTest = 0;
|
|
89
79
|
api.count = 0;
|
|
90
80
|
},
|
|
91
81
|
update: (frames = 1) => {
|
|
92
82
|
// Adapt the opacity-blend ratio to the number of frames
|
|
83
|
+
const material = gPlane.current.material;
|
|
84
|
+
|
|
93
85
|
if (!api.temporal) {
|
|
94
86
|
material.opacity = opacity;
|
|
95
|
-
material.
|
|
87
|
+
material.alphaTest = alphaTest;
|
|
96
88
|
} else {
|
|
97
89
|
material.opacity = Math.min(opacity, material.opacity + opacity / api.blend);
|
|
98
|
-
material.
|
|
90
|
+
material.alphaTest = Math.min(alphaTest, material.alphaTest + alphaTest / api.blend);
|
|
99
91
|
} // Switch accumulative lights on
|
|
100
92
|
|
|
101
93
|
|
|
@@ -113,7 +105,7 @@ const AccumulativeShadows = /*#__PURE__*/React.forwardRef(({
|
|
|
113
105
|
|
|
114
106
|
plm.finish();
|
|
115
107
|
}
|
|
116
|
-
}), [plm,
|
|
108
|
+
}), [plm, camera, scene, temporal, frames, blend, opacity, alphaTest]);
|
|
117
109
|
React.useLayoutEffect(() => {
|
|
118
110
|
// Reset internals, buffers, ...
|
|
119
111
|
api.reset(); // Update lightmap
|
|
@@ -121,7 +113,7 @@ const AccumulativeShadows = /*#__PURE__*/React.forwardRef(({
|
|
|
121
113
|
if (!api.temporal && api.frames !== Infinity) api.update(api.blend);
|
|
122
114
|
}); // Expose api, allow children to set itself as the main light source
|
|
123
115
|
|
|
124
|
-
React.useImperativeHandle(forwardRef, () => api, []);
|
|
116
|
+
React.useImperativeHandle(forwardRef, () => api, [api]);
|
|
125
117
|
useFrame(() => {
|
|
126
118
|
if ((api.temporal || api.frames === Infinity) && api.count < api.frames && api.count < limit) {
|
|
127
119
|
api.update();
|
|
@@ -136,16 +128,20 @@ const AccumulativeShadows = /*#__PURE__*/React.forwardRef(({
|
|
|
136
128
|
}, children)), /*#__PURE__*/React.createElement("mesh", {
|
|
137
129
|
receiveShadow: true,
|
|
138
130
|
ref: gPlane,
|
|
139
|
-
material: material,
|
|
140
|
-
"material-encoding": encoding || gl.outputEncoding,
|
|
141
|
-
"material-toneMapped": toneMapped,
|
|
142
131
|
scale: scale,
|
|
143
132
|
rotation: [-Math.PI / 2, 0, 0]
|
|
144
|
-
}, /*#__PURE__*/React.createElement("planeGeometry", null)
|
|
133
|
+
}, /*#__PURE__*/React.createElement("planeGeometry", null), /*#__PURE__*/React.createElement("softShadowMaterial", {
|
|
134
|
+
transparent: true,
|
|
135
|
+
depthWrite: false,
|
|
136
|
+
toneMapped: toneMapped,
|
|
137
|
+
color: color,
|
|
138
|
+
blend: colorBlend,
|
|
139
|
+
map: plm.progressiveLightMap2.texture
|
|
140
|
+
})));
|
|
145
141
|
});
|
|
146
142
|
const RandomizedLight = /*#__PURE__*/React.forwardRef(({
|
|
147
143
|
castShadow = true,
|
|
148
|
-
bias = 0,
|
|
144
|
+
bias = 0.001,
|
|
149
145
|
mapSize = 512,
|
|
150
146
|
size = 5,
|
|
151
147
|
near = 0.5,
|
|
@@ -201,18 +197,7 @@ const RandomizedLight = /*#__PURE__*/React.forwardRef(({
|
|
|
201
197
|
attach: "shadow-camera",
|
|
202
198
|
args: [-size, size, size, -size, near, far]
|
|
203
199
|
}))));
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
class UVMaterial extends THREE.ShaderMaterial {
|
|
207
|
-
constructor() {
|
|
208
|
-
super({
|
|
209
|
-
vertexShader: 'void main() { gl_Position = vec4((uv - 0.5) * 2.0, 1.0, 1.0); }',
|
|
210
|
-
fragmentShader: 'void main() { discard; }'
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
} // Based on "Progressive Light Map Accumulator", by [zalo](https://github.com/zalo/)
|
|
215
|
-
|
|
200
|
+
}); // Based on "Progressive Light Map Accumulator", by [zalo](https://github.com/zalo/)
|
|
216
201
|
|
|
217
202
|
class ProgressiveLightMap {
|
|
218
203
|
constructor(renderer, scene, res = 1024) {
|
|
@@ -227,13 +212,15 @@ class ProgressiveLightMap {
|
|
|
227
212
|
|
|
228
213
|
const format = /(Android|iPad|iPhone|iPod)/g.test(navigator.userAgent) ? THREE.HalfFloatType : THREE.FloatType;
|
|
229
214
|
this.progressiveLightMap1 = new THREE.WebGLRenderTarget(this.res, this.res, {
|
|
230
|
-
type: format
|
|
215
|
+
type: format,
|
|
216
|
+
encoding: renderer.outputEncoding
|
|
231
217
|
});
|
|
232
218
|
this.progressiveLightMap2 = new THREE.WebGLRenderTarget(this.res, this.res, {
|
|
233
|
-
type: format
|
|
219
|
+
type: format,
|
|
220
|
+
encoding: renderer.outputEncoding
|
|
234
221
|
}); // Inject some spicy new logic into a standard phong material
|
|
235
222
|
|
|
236
|
-
this.
|
|
223
|
+
this.discardMat = new DiscardMaterial();
|
|
237
224
|
this.targetMat = new THREE.MeshPhongMaterial({
|
|
238
225
|
shininess: 0
|
|
239
226
|
});
|
|
@@ -283,7 +270,7 @@ class ProgressiveLightMap {
|
|
|
283
270
|
|
|
284
271
|
prepare() {
|
|
285
272
|
this.lights.forEach(light => light.object.intensity = 0);
|
|
286
|
-
this.meshes.forEach(mesh => mesh.object.material = this.
|
|
273
|
+
this.meshes.forEach(mesh => mesh.object.material = this.discardMat);
|
|
287
274
|
}
|
|
288
275
|
|
|
289
276
|
finish() {
|