@react-three/drei 9.74.5 → 9.74.6
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 +4 -0
- package/core/MeshPortalMaterial.cjs.js +1 -1
- package/core/MeshPortalMaterial.js +50 -34
- package/index.cjs.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3327,6 +3327,10 @@ const stencil = useMask(1, true)
|
|
|
3327
3327
|
|
|
3328
3328
|
#### Portal
|
|
3329
3329
|
|
|
3330
|
+
<p>
|
|
3331
|
+
<a href="https://codesandbox.io/s/ik11ln"><img width="20%" src="https://codesandbox.io/api/v1/sandboxes/ik11ln/screenshot.png" alt="Demo"/></a>
|
|
3332
|
+
</p>
|
|
3333
|
+
|
|
3330
3334
|
```tsx
|
|
3331
3335
|
export type PortalProps = JSX.IntrinsicElements['portalMaterialImpl'] & {
|
|
3332
3336
|
/** Edge fade blur, 0 = no blur (default) */
|
|
@@ -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"),i=require("./RenderTexture.cjs.js"),l=require("./shaderMaterial.cjs.js"),o=require("three-stdlib");function u(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 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 v=u(e),m=s(r),d=s(t);const
|
|
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"),i=require("./RenderTexture.cjs.js"),l=require("./shaderMaterial.cjs.js"),o=require("three-stdlib");function u(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 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 v=u(e),m=s(r),d=s(t);const c=l.shaderMaterial({blur:0,map:null,sdf:null,size:0,resolution:new m.Vector2},"varying vec2 vUv;\n void main() {\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n vUv = uv;\n }","uniform sampler2D sdf;\n uniform sampler2D map;\n uniform float blur;\n uniform float size;\n uniform float time;\n uniform vec2 resolution;\n varying vec2 vUv;\n #include <packing>\n void main() {\n vec2 uv = gl_FragCoord.xy / resolution.xy;\n vec4 t = texture2D(map, uv);\n float k = blur;\n float d = texture2D(sdf, vUv).r/size;\n float alpha = 1.0 - smoothstep(0.0, 1.0, clamp(d/k + 1.0, 0.0, 1.0));\n gl_FragColor = vec4(t.rgb, blur == 0.0 ? t.a : t.a * alpha);\n #include <tonemapping_fragment>\n #include <encodings_fragment>\n }"),f=d.forwardRef((({children:e,blur:r,eventPriority:t,renderPriority:l,worldUnits:o=!1,resolution:u=512,...s},f)=>{n.extend({PortalMaterialImpl:c});const p=d.useRef(null),{gl:F,size:h,events:y,viewport:w}=n.useThree(),M=a.useFBO(u,u);return d.useLayoutEffect((()=>{var e;let t=null==(e=p.current)?void 0:e.__r3f.parent;if(t&&r&&null===p.current.sdf){const e=new m.Mesh(t.geometry,new m.MeshBasicMaterial),r=(new m.Box3).setFromBufferAttribute(e.geometry.attributes.position),n=new m.OrthographicCamera(r.min.x*(1+2/u),r.max.x*(1+2/u),r.max.y*(1+2/u),r.min.y*(1+2/u),.1,1e3);n.position.set(0,0,1),n.lookAt(0,0,0),F.setRenderTarget(M),F.render(e,n);const a=g(u,u,F)(M.texture),i=new Float32Array(u*u);F.readRenderTargetPixels(a,0,0,u,u,i);let l=1/0;for(let e=0;e<i.length;e++)i[e]<l&&(l=i[e]);l=-l,p.current.size=l,p.current.sdf=a.texture,F.setRenderTarget(null)}}),[u,r]),d.useImperativeHandle(f,(()=>p.current)),d.createElement("portalMaterialImpl",v.default({ref:p,blur:r,resolution:[h.width*w.dpr,h.height*w.dpr],toneMapped:!1,attach:"material"},s),d.createElement(i.RenderTexture,{attach:"map",eventPriority:t,renderPriority:l,compute:y.compute},e,d.createElement(x,{material:p,worldUnits:o})))}));function x({material:e,worldUnits:r}){const t=n.useThree((e=>e.scene));return d.useLayoutEffect((()=>{t.matrixAutoUpdate=!1}),[]),n.useFrame((()=>{var n;let a=null==e||null==(n=e.current)?void 0:n.__r3f.parent;a&&(r?t.matrixWorld.identity():t.matrixWorld.copy(a.matrixWorld))})),d.createElement(d.Fragment,null)}const g=(e,r,t)=>{let n=new m.WebGLRenderTarget(e,r,{minFilter:m.LinearMipmapLinearFilter,magFilter:m.LinearFilter,type:m.FloatType,format:m.RedFormat,generateMipmaps:!0}),a=new m.WebGLRenderTarget(e,r,{minFilter:m.NearestFilter,magFilter:m.NearestFilter}),i=new m.WebGLRenderTarget(e,r,{minFilter:m.NearestFilter,magFilter:m.NearestFilter}),l=new m.WebGLRenderTarget(e,r,{minFilter:m.NearestFilter,magFilter:m.NearestFilter}),u=new m.WebGLRenderTarget(e,r,{minFilter:m.NearestFilter,magFilter:m.NearestFilter}),s=new m.WebGLRenderTarget(e,r,{minFilter:m.NearestFilter,magFilter:m.NearestFilter,type:m.FloatType,format:m.RedFormat}),v=new m.WebGLRenderTarget(e,r,{minFilter:m.NearestFilter,magFilter:m.NearestFilter,type:m.FloatType,format:m.RedFormat});const d=new o.FullScreenQuad(new m.ShaderMaterial({uniforms:{tex:{value:null}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }",fragmentShader:"\n uniform sampler2D tex;\n varying vec2 vUv;\n #include <packing>\n void main() {\n gl_FragColor = pack2HalfToRGBA(vUv * (round(texture2D(tex, vUv).x)));\n }"})),c=new o.FullScreenQuad(new m.ShaderMaterial({uniforms:{tex:{value:null}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }",fragmentShader:"\n uniform sampler2D tex;\n varying vec2 vUv;\n #include <packing>\n void main() {\n gl_FragColor = pack2HalfToRGBA(vUv * (1.0 - round(texture2D(tex, vUv).x)));\n }"})),f=new o.FullScreenQuad(new m.ShaderMaterial({uniforms:{tex:{value:null},offset:{value:0},level:{value:0},maxSteps:{value:0}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }",fragmentShader:`\n varying vec2 vUv;\n uniform sampler2D tex;\n uniform float offset;\n uniform float level;\n uniform float maxSteps;\n #include <packing>\n void main() {\n float closestDist = 9999999.9;\n vec2 closestPos = vec2(0.0);\n for (float x = -1.0; x <= 1.0; x += 1.0) {\n for (float y = -1.0; y <= 1.0; y += 1.0) {\n vec2 voffset = vUv;\n voffset += vec2(x, y) * vec2(${1/e}, ${1/r}) * offset;\n vec2 pos = unpackRGBATo2Half(texture2D(tex, voffset));\n float dist = distance(pos.xy, vUv);\n if(pos.x != 0.0 && pos.y != 0.0 && dist < closestDist) {\n closestDist = dist;\n closestPos = pos;\n }\n }\n }\n gl_FragColor = pack2HalfToRGBA(closestPos);\n }`})),x=new o.FullScreenQuad(new m.ShaderMaterial({uniforms:{tex:{value:null},size:{value:new m.Vector2(e,r)}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }",fragmentShader:"\n varying vec2 vUv;\n uniform sampler2D tex;\n uniform vec2 size;\n #include <packing>\n void main() {\n gl_FragColor = vec4(distance(size * unpackRGBATo2Half(texture2D(tex, vUv)), size * vUv), 0.0, 0.0, 0.0);\n }"})),g=new o.FullScreenQuad(new m.ShaderMaterial({uniforms:{inside:{value:v.texture},outside:{value:s.texture},tex:{value:null}},vertexShader:"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }",fragmentShader:"\n varying vec2 vUv;\n uniform sampler2D inside;\n uniform sampler2D outside;\n uniform sampler2D tex;\n #include <packing>\n void main() {\n float i = texture2D(inside, vUv).x;\n float o =texture2D(outside, vUv).x;\n if (texture2D(tex, vUv).x == 0.0) {\n gl_FragColor = vec4(o, 0.0, 0.0, 0.0);\n } else {\n gl_FragColor = vec4(-i, 0.0, 0.0, 0.0);\n }\n }"}));return o=>{let p=n;o.minFilter=m.NearestFilter,o.magFilter=m.NearestFilter,d.material.uniforms.tex.value=o,t.setRenderTarget(a),d.render(t);const F=Math.ceil(Math.log(Math.max(e,r))/Math.log(2));let h=a,y=null;for(let e=0;e<F;e++){const r=Math.pow(2,F-e-1);y=h===a?l:a,f.material.uniforms.level.value=e,f.material.uniforms.maxSteps.value=F,f.material.uniforms.offset.value=r,f.material.uniforms.tex.value=h.texture,t.setRenderTarget(y),f.render(t),h=y}t.setRenderTarget(s),x.material.uniforms.tex.value=y.texture,x.render(t),c.material.uniforms.tex.value=o,t.setRenderTarget(i),c.render(t),h=i;for(let e=0;e<F;e++){const r=Math.pow(2,F-e-1);y=h===i?u:i,f.material.uniforms.level.value=e,f.material.uniforms.maxSteps.value=F,f.material.uniforms.offset.value=r,f.material.uniforms.tex.value=h.texture,t.setRenderTarget(y),f.render(t),h=y}return t.setRenderTarget(v),x.material.uniforms.tex.value=y.texture,x.render(t),t.setRenderTarget(p),g.material.uniforms.tex.value=o,g.render(t),t.setRenderTarget(null),p}};exports.MeshPortalMaterial=f;
|
|
@@ -37,6 +37,7 @@ const PortalMaterialImpl = shaderMaterial({
|
|
|
37
37
|
}`);
|
|
38
38
|
const MeshPortalMaterial = /*#__PURE__*/React.forwardRef(({
|
|
39
39
|
children,
|
|
40
|
+
blur,
|
|
40
41
|
eventPriority,
|
|
41
42
|
renderPriority,
|
|
42
43
|
worldUnits = false,
|
|
@@ -47,7 +48,6 @@ const MeshPortalMaterial = /*#__PURE__*/React.forwardRef(({
|
|
|
47
48
|
PortalMaterialImpl
|
|
48
49
|
});
|
|
49
50
|
const ref = React.useRef(null);
|
|
50
|
-
const group = React.useRef(null);
|
|
51
51
|
const {
|
|
52
52
|
gl,
|
|
53
53
|
size,
|
|
@@ -59,55 +59,71 @@ const MeshPortalMaterial = /*#__PURE__*/React.forwardRef(({
|
|
|
59
59
|
var _ref$current;
|
|
60
60
|
|
|
61
61
|
let mask = (_ref$current = ref.current) == null ? void 0 : _ref$current.__r3f.parent;
|
|
62
|
-
if (!mask) return;
|
|
63
|
-
const tempMesh = new THREE.Mesh(mask.geometry, new THREE.MeshBasicMaterial());
|
|
64
|
-
const boundingBox = new THREE.Box3().setFromBufferAttribute(tempMesh.geometry.attributes.position);
|
|
65
|
-
const orthoCam = new THREE.OrthographicCamera(boundingBox.min.x * (1 + 2 / resolution), boundingBox.max.x * (1 + 2 / resolution), boundingBox.max.y * (1 + 2 / resolution), boundingBox.min.y * (1 + 2 / resolution), 0.1, 1000);
|
|
66
|
-
orthoCam.position.set(0, 0, 1);
|
|
67
|
-
orthoCam.lookAt(0, 0, 0);
|
|
68
|
-
gl.setRenderTarget(maskRenderTarget);
|
|
69
|
-
gl.render(tempMesh, orthoCam);
|
|
70
|
-
const sg = makeSDFGenerator(resolution, resolution, gl);
|
|
71
|
-
const sdf = sg(maskRenderTarget.texture);
|
|
72
|
-
const readSdf = new Float32Array(resolution * resolution);
|
|
73
|
-
gl.readRenderTargetPixels(sdf, 0, 0, resolution, resolution, readSdf); // Get smallest value in sdf
|
|
62
|
+
if (!mask) return; // Apply the SDF mask only once
|
|
74
63
|
|
|
75
|
-
|
|
64
|
+
if (blur && ref.current.sdf === null) {
|
|
65
|
+
const tempMesh = new THREE.Mesh(mask.geometry, new THREE.MeshBasicMaterial());
|
|
66
|
+
const boundingBox = new THREE.Box3().setFromBufferAttribute(tempMesh.geometry.attributes.position);
|
|
67
|
+
const orthoCam = new THREE.OrthographicCamera(boundingBox.min.x * (1 + 2 / resolution), boundingBox.max.x * (1 + 2 / resolution), boundingBox.max.y * (1 + 2 / resolution), boundingBox.min.y * (1 + 2 / resolution), 0.1, 1000);
|
|
68
|
+
orthoCam.position.set(0, 0, 1);
|
|
69
|
+
orthoCam.lookAt(0, 0, 0);
|
|
70
|
+
gl.setRenderTarget(maskRenderTarget);
|
|
71
|
+
gl.render(tempMesh, orthoCam);
|
|
72
|
+
const sg = makeSDFGenerator(resolution, resolution, gl);
|
|
73
|
+
const sdf = sg(maskRenderTarget.texture);
|
|
74
|
+
const readSdf = new Float32Array(resolution * resolution);
|
|
75
|
+
gl.readRenderTargetPixels(sdf, 0, 0, resolution, resolution, readSdf); // Get smallest value in sdf
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
if (readSdf[i] < min) min = readSdf[i];
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
min = -min;
|
|
82
|
-
ref.current.size = min;
|
|
83
|
-
ref.current.sdf = sdf.texture;
|
|
84
|
-
gl.setRenderTarget(null);
|
|
85
|
-
}, [resolution]);
|
|
86
|
-
useFrame(() => {
|
|
87
|
-
var _ref$current2;
|
|
77
|
+
let min = Infinity;
|
|
88
78
|
|
|
89
|
-
|
|
79
|
+
for (let i = 0; i < readSdf.length; i++) {
|
|
80
|
+
if (readSdf[i] < min) min = readSdf[i];
|
|
81
|
+
}
|
|
90
82
|
|
|
91
|
-
|
|
92
|
-
|
|
83
|
+
min = -min;
|
|
84
|
+
ref.current.size = min;
|
|
85
|
+
ref.current.sdf = sdf.texture;
|
|
86
|
+
gl.setRenderTarget(null);
|
|
93
87
|
}
|
|
94
|
-
});
|
|
88
|
+
}, [resolution, blur]);
|
|
95
89
|
React.useImperativeHandle(fref, () => ref.current);
|
|
96
90
|
return /*#__PURE__*/React.createElement("portalMaterialImpl", _extends({
|
|
97
91
|
ref: ref,
|
|
92
|
+
blur: blur,
|
|
98
93
|
resolution: [size.width * viewport.dpr, size.height * viewport.dpr],
|
|
99
|
-
toneMapped: false
|
|
94
|
+
toneMapped: false,
|
|
95
|
+
attach: "material"
|
|
100
96
|
}, props), /*#__PURE__*/React.createElement(RenderTexture, {
|
|
101
97
|
attach: "map",
|
|
102
98
|
eventPriority: eventPriority,
|
|
103
99
|
renderPriority: renderPriority,
|
|
104
100
|
compute: events.compute
|
|
105
|
-
}, /*#__PURE__*/React.createElement(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
101
|
+
}, children, /*#__PURE__*/React.createElement(CopyMatrix, {
|
|
102
|
+
material: ref,
|
|
103
|
+
worldUnits: worldUnits
|
|
104
|
+
})));
|
|
109
105
|
});
|
|
110
106
|
|
|
107
|
+
function CopyMatrix({
|
|
108
|
+
material,
|
|
109
|
+
worldUnits
|
|
110
|
+
}) {
|
|
111
|
+
const scene = useThree(state => state.scene);
|
|
112
|
+
React.useLayoutEffect(() => {
|
|
113
|
+
scene.matrixAutoUpdate = false;
|
|
114
|
+
}, []);
|
|
115
|
+
useFrame(() => {
|
|
116
|
+
var _material$current;
|
|
117
|
+
|
|
118
|
+
let parent = material == null ? void 0 : (_material$current = material.current) == null ? void 0 : _material$current.__r3f.parent;
|
|
119
|
+
|
|
120
|
+
if (parent) {
|
|
121
|
+
if (!worldUnits) scene.matrixWorld.copy(parent.matrixWorld);else scene.matrixWorld.identity();
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null);
|
|
125
|
+
}
|
|
126
|
+
|
|
111
127
|
const makeSDFGenerator = (clientWidth, clientHeight, renderer) => {
|
|
112
128
|
let finalTarget = new THREE.WebGLRenderTarget(clientWidth, clientHeight, {
|
|
113
129
|
minFilter: THREE.LinearMipmapLinearFilter,
|