@react-three/drei 9.52.3 → 9.52.4
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 +9 -4
- package/core/Caustics.cjs.js +1 -1
- package/core/Caustics.d.ts +2 -3
- package/core/Caustics.js +117 -70
- package/core/Center.cjs.js +1 -1
- package/core/Center.d.ts +1 -0
- package/core/Center.js +2 -1
- package/core/useBVH.cjs.js +1 -1
- package/core/useBVH.js +9 -1
- package/index.cjs.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1830,6 +1830,8 @@ Enable shadows using the `castShadow` and `recieveShadow` prop.
|
|
|
1830
1830
|
/>
|
|
1831
1831
|
```
|
|
1832
1832
|
|
|
1833
|
+
> Note: Html 'blending' mode only correctly occludes rectangular HTML elements by default. Use the `geometry` prop to swap the backing geometry to a custom one if your Html has a different shape.
|
|
1834
|
+
|
|
1833
1835
|
#### CycleRaycast
|
|
1834
1836
|
|
|
1835
1837
|

|
|
@@ -2841,6 +2843,8 @@ export type Props = JSX.IntrinsicElements['group'] & {
|
|
|
2841
2843
|
left?: boolean
|
|
2842
2844
|
front?: boolean
|
|
2843
2845
|
back?: boolean
|
|
2846
|
+
/** Disable all axes */
|
|
2847
|
+
disable?: boolean
|
|
2844
2848
|
/** Disable x-axis centering */
|
|
2845
2849
|
disableX?: boolean
|
|
2846
2850
|
/** Disable y-axis centering */
|
|
@@ -3117,13 +3121,16 @@ Caustics are swirls of light that appear when light passes through transmissive
|
|
|
3117
3121
|
|
|
3118
3122
|
```tsx
|
|
3119
3123
|
type CausticsProps = JSX.IntrinsicElements['group'] & {
|
|
3124
|
+
/** How many frames it will render, set it to Infinity for runtime, default: 1 */
|
|
3125
|
+
frames?: number
|
|
3120
3126
|
/** Enables visual cues to help you stage your scene, default: false */
|
|
3121
3127
|
debug?: boolean
|
|
3122
3128
|
/** Will display caustics only and skip the models, default: false */
|
|
3123
3129
|
causticsOnly: boolean
|
|
3124
3130
|
/** Will include back faces and enable the backfaceIor prop, default: false */
|
|
3125
3131
|
backfaces: boolean
|
|
3126
|
-
/** The size of the camera frustum,
|
|
3132
|
+
/** The size of the camera frustum, make sure it fits your model perfectly
|
|
3133
|
+
* (with the debug flag)! The better it fits the more resolution you have. default: 2 */
|
|
3127
3134
|
frustum?: number
|
|
3128
3135
|
/** The IOR refraction index, default: 1.1 */
|
|
3129
3136
|
ior?: number
|
|
@@ -3141,10 +3148,8 @@ type CausticsProps = JSX.IntrinsicElements['group'] & {
|
|
|
3141
3148
|
near?: number
|
|
3142
3149
|
/** Camera far, default: 100 */
|
|
3143
3150
|
far?: number
|
|
3144
|
-
/** Camera position, default: [5, 5, 5] */
|
|
3151
|
+
/** Camera position, it will point towards the contents bounds center, default: [5, 5, 5] */
|
|
3145
3152
|
lightSource?: [x: number, y: number, z: number]
|
|
3146
|
-
/** Camera lookAt, default: [0, 0, 0] */
|
|
3147
|
-
focus?: [x: number, y: number, z: number]
|
|
3148
3153
|
}
|
|
3149
3154
|
```
|
|
3150
3155
|
|
package/core/Caustics.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),r=require("three"),n=require("react"),t=require("@react-three/fiber"),i=require("./useFBO.cjs.js"),o=require("./useHelper.cjs.js"),a=require("./shaderMaterial.cjs.js"),l=require("three-stdlib");function c(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(n){if("default"!==n){var t=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(r,n,t.get?t:{enumerable:!0,get:function(){return e[n]}})}})),r.default=e,Object.freeze(r)}var u=c(e),d=s(r),v=s(n);function f(e=d.FrontSide){const r={value:new d.Matrix4};return Object.assign(new d.MeshNormalMaterial({side:e}),{viewMatrix:r,onBeforeCompile:e=>{e.uniforms.viewMatrix=r,e.fragmentShader="vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n }\n"+e.fragmentShader.replace("#include <normal_fragment_maps>","#include <normal_fragment_maps>\n normal = inverseTransformDirection( normal, viewMatrix );\n")}})}const p=a.shaderMaterial({causticsTexture:null,causticsTextureB:null,color:new d.Color("white"),lightProjMatrix:new d.Matrix4,lightViewMatrix:new d.Matrix4},"varying vec3 vWorldPosition; \n void main() {\n gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.);\n vec4 worldPosition = modelMatrix * vec4(position, 1.);\n vWorldPosition = worldPosition.xyz;\n }","varying vec3 vWorldPosition;\n uniform vec3 color;\n uniform sampler2D causticsTexture; \n uniform sampler2D causticsTextureB; \n uniform mat4 lightProjMatrix;\n uniform mat4 lightViewMatrix;\n void main() {\n // Apply caustics \n vec4 lightSpacePos = lightProjMatrix * lightViewMatrix * vec4(vWorldPosition, 1.0);\n lightSpacePos.xyz /= lightSpacePos.w;\n lightSpacePos.xyz = lightSpacePos.xyz * 0.5 + 0.5; \n vec3 front = texture2D(causticsTexture, lightSpacePos.xy).rgb;\n vec3 back = texture2D(causticsTextureB, lightSpacePos.xy).rgb;\n gl_FragColor = vec4((front + back) * color, 1.0);\n #include <tonemapping_fragment>\n #include <encodings_fragment>\n }"),m=a.shaderMaterial({cameraMatrixWorld:new d.Matrix4,cameraProjectionMatrixInv:new d.Matrix4,normalTexture:null,depthTexture:null,lightDir:new d.Vector3(0,1,0),near:.1,far:100,modelMatrix:new d.Matrix4,worldRadius:1/40,ior:1.1,bounces:0,resolution:1024,size:10,intensity:.5},"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }"," \n uniform mat4 cameraMatrixWorld;\n uniform mat4 cameraProjectionMatrixInv;\n uniform vec3 lightDir;\n uniform float near;\n uniform float far;\n uniform float time;\n uniform float worldRadius;\n uniform float resolution;\n uniform float size;\n uniform float intensity;\n uniform float ior;\n precision highp isampler2D;\n precision highp usampler2D;\n uniform sampler2D normalTexture;\n uniform sampler2D depthTexture;\n uniform float bounces;\n varying vec2 vUv;\n vec3 WorldPosFromDepth(float depth, vec2 coord) {\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = cameraProjectionMatrixInv * clipSpacePosition;\n // Perspective division\n viewSpacePosition /= viewSpacePosition.w;\n vec4 worldSpacePosition = cameraMatrixWorld * viewSpacePosition;\n return worldSpacePosition.xyz;\n } \n float sdPlane( vec3 p, vec3 n, float h ) {\n // n must be normalized\n return dot(p,n) + h;\n }\n float planeIntersect( vec3 ro, vec3 rd, vec4 p ) {\n return -(dot(ro,p.xyz)+p.w)/dot(rd,p.xyz);\n }\n vec3 totalInternalReflection(vec3 ro, vec3 rd, vec3 pos, vec3 normal, float ior, out vec3 rayOrigin, out vec3 rayDirection) {\n rayOrigin = ro;\n rayDirection = rd;\n rayDirection = refract(rayDirection, normal, 1.0 / ior);\n rayOrigin = pos + rayDirection * 0.1;\n return rayDirection;\n }\n void main() {\n // Each sample consists of random offset in the x and y direction\n float caustic = 0.0;\n float causticTexelSize = (1.0 / resolution) * size * 2.0;\n float texelsNeeded = worldRadius / causticTexelSize;\n float sampleRadius = texelsNeeded / resolution;\n float sum = 0.0;\n if (texture2D(depthTexture, vUv).x == 1.0) {\n gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n return;\n }\n vec2 offset1 = vec2(-0.5, -0.5);//vec2(rand() - 0.5, rand() - 0.5);\n vec2 offset2 = vec2(-0.5, 0.5);//vec2(rand() - 0.5, rand() - 0.5);\n vec2 offset3 = vec2(0.5, 0.5);//vec2(rand() - 0.5, rand() - 0.5);\n vec2 offset4 = vec2(0.5, -0.5);//vec2(rand() - 0.5, rand() - 0.5);\n vec2 uv1 = vUv + offset1 * sampleRadius;\n vec2 uv2 = vUv + offset2 * sampleRadius;\n vec2 uv3 = vUv + offset3 * sampleRadius;\n vec2 uv4 = vUv + offset4 * sampleRadius;\n vec3 normal1 = texture2D(normalTexture, uv1, -10.0).rgb * 2.0 - 1.0;\n vec3 normal2 = texture2D(normalTexture, uv2, -10.0).rgb * 2.0 - 1.0;\n vec3 normal3 = texture2D(normalTexture, uv3, -10.0).rgb * 2.0 - 1.0;\n vec3 normal4 = texture2D(normalTexture, uv4, -10.0).rgb * 2.0 - 1.0;\n float depth1 = texture2D(depthTexture, uv1, -10.0).x;\n float depth2 = texture2D(depthTexture, uv2, -10.0).x;\n float depth3 = texture2D(depthTexture, uv3, -10.0).x;\n float depth4 = texture2D(depthTexture, uv4, -10.0).x;\n // Sanity check the depths\n if (depth1 == 1.0 || depth2 == 1.0 || depth3 == 1.0 || depth4 == 1.0) {\n gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n return;\n }\n vec3 pos1 = WorldPosFromDepth(depth1, uv1);\n vec3 pos2 = WorldPosFromDepth(depth2, uv2);\n vec3 pos3 = WorldPosFromDepth(depth3, uv3);\n vec3 pos4 = WorldPosFromDepth(depth4, uv4);\n vec3 originPos1 = WorldPosFromDepth(0.0, uv1);\n vec3 originPos2 = WorldPosFromDepth(0.0, uv2);\n vec3 originPos3 = WorldPosFromDepth(0.0, uv3);\n vec3 originPos4 = WorldPosFromDepth(0.0, uv4);\n vec3 endPos1, endPos2, endPos3, endPos4;\n vec3 endDir1, endDir2, endDir3, endDir4;\n totalInternalReflection(originPos1, lightDir, pos1, normal1, ior, endPos1, endDir1);\n totalInternalReflection(originPos2, lightDir, pos2, normal2, ior, endPos2, endDir2);\n totalInternalReflection(originPos3, lightDir, pos3, normal3, ior, endPos3, endDir3);\n totalInternalReflection(originPos4, lightDir, pos4, normal4, ior, endPos4, endDir4);\n float lightPosArea = length(cross(originPos2 - originPos1, originPos3 - originPos1)) + length(cross(originPos3 - originPos1, originPos4 - originPos1));\n float t1 = planeIntersect(endPos1, endDir1, vec4(0.0, 1.0, 0.0, 0.0));\n float t2 = planeIntersect(endPos2, endDir2, vec4(0.0, 1.0, 0.0, 0.0));\n float t3 = planeIntersect(endPos3, endDir3, vec4(0.0, 1.0, 0.0, 0.0));\n float t4 = planeIntersect(endPos4, endDir4, vec4(0.0, 1.0, 0.0, 0.0));\n vec3 finalPos1 = endPos1 + endDir1 * t1;\n vec3 finalPos2 = endPos2 + endDir2 * t2;\n vec3 finalPos3 = endPos3 + endDir3 * t3;\n vec3 finalPos4 = endPos4 + endDir4 * t4;\n float finalArea = length(cross(finalPos2 - finalPos1, finalPos3 - finalPos1)) + length(cross(finalPos3 - finalPos1, finalPos4 - finalPos1));\n caustic += intensity * (lightPosArea / finalArea);\n // Calculate the area of the triangle in light spaces\n gl_FragColor = vec4(vec3(max(caustic, 0.0)), 1.0);\n }"),x={depth:!0,minFilter:d.LinearFilter,magFilter:d.LinearFilter,encoding:d.LinearEncoding,type:d.UnsignedByteType},g={minFilter:d.LinearMipmapLinearFilter,magFilter:d.LinearFilter,encoding:d.LinearEncoding,format:d.RGBAFormat,type:d.FloatType,generateMipmaps:!0},h=v.forwardRef((({debug:e,children:r,frustum:n=2,ior:a=1.1,color:c="white",causticsOnly:s=!1,backfaces:h=!1,backfaceIor:P=1.1,worldRadius:D=.3125,intensity:M=.05,resolution:y=2024,near:w=.1,far:T=100,lightSource:b=[5,5,5],focus:F=[0,0,0],...S},j)=>{t.extend({CausticsProjectionMaterial:p});const R=v.useRef(null),W=v.useRef(null),z=v.useRef(null),I=v.useRef(null),O=t.useThree((e=>e.gl)),_=o.useHelper(e&&W,d.CameraHelper),B=o.useHelper(e&&I,d.BoxHelper),C=i.useFBO(y,y,x),E=i.useFBO(y,y,x),U=i.useFBO(y,y,g),k=i.useFBO(y,y,g),[q]=v.useState((()=>f())),[A]=v.useState((()=>f(d.BackSide))),[L]=v.useState((()=>new m)),[V]=v.useState((()=>new l.FullScreenQuad(L))),H=new d.Vector3;return v.useLayoutEffect((()=>{var r,t;(R.current.updateWorldMatrix(!1,!0),W.current.position.set(...b),W.current.lookAt(...F),W.current.updateWorldMatrix(!1,!1),W.current.updateProjectionMatrix(),e)&&(null==(r=_.current)||r.update(),null==(t=B.current)||t.update());A.viewMatrix.value=q.viewMatrix.value=W.current.matrixWorldInverse,L.cameraMatrixWorld=W.current.matrixWorld,L.cameraProjectionMatrixInv=W.current.projectionMatrixInverse,L.lightDir=W.current.getWorldPosition(H).normalize().multiplyScalar(-1),L.near=W.current.near,L.far=W.current.far,L.resolution=y,L.size=n,L.intensity=M,L.worldRadius=D,z.current.visible=!0,O.setRenderTarget(C),O.clear(),z.current.overrideMaterial=q,O.render(z.current,W.current),O.setRenderTarget(E),O.clear(),h&&(z.current.overrideMaterial=A,O.render(z.current,W.current)),z.current.overrideMaterial=null,L.ior=a,I.current.material.lightProjMatrix=W.current.projectionMatrix,I.current.material.lightViewMatrix=W.current.matrixWorldInverse,L.normalTexture=C.texture,L.depthTexture=C.depthTexture,O.setRenderTarget(U),O.clear(),V.render(O),L.ior=P,L.normalTexture=E.texture,L.depthTexture=E.depthTexture,O.setRenderTarget(k),O.clear(),h&&V.render(O),O.setRenderTarget(null),s&&(z.current.visible=!1)})),v.createElement("group",u.default({ref:R},S),v.createElement("orthographicCamera",{ref:W,up:[0,1,0],left:-n,right:n,top:n,bottom:-n,near:w,far:T}),v.createElement("scene",{ref:z},r),v.createElement("mesh",{ref:I,"rotation-x":-Math.PI/2,scale:2*n},v.createElement("planeGeometry",null),v.createElement("causticsProjectionMaterial",{transparent:!0,color:c,causticsTexture:U.texture,causticsTextureB:k.texture,blending:d.CustomBlending,blendSrc:d.OneFactor,blendDst:d.SrcAlphaFactor,depthWrite:!1})))}));exports.Caustics=h;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),r=require("three"),n=require("react"),t=require("@react-three/fiber"),o=require("./useFBO.cjs.js"),i=require("./useHelper.cjs.js"),a=require("./shaderMaterial.cjs.js"),l=require("./Edges.cjs.js"),c=require("three-stdlib");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function u(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var t=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(r,n,t.get?t:{enumerable:!0,get:function(){return e[n]}})}})),r.default=e,Object.freeze(r)}var d=s(e),m=u(r),p=u(n);function v(e=m.FrontSide){const r={value:new m.Matrix4};return Object.assign(new m.MeshNormalMaterial({side:e}),{viewMatrix:r,onBeforeCompile:e=>{e.uniforms.viewMatrix=r,e.fragmentShader="vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n }\n"+e.fragmentShader.replace("#include <normal_fragment_maps>","#include <normal_fragment_maps>\n normal = inverseTransformDirection( normal, viewMatrix );\n")}})}const f=a.shaderMaterial({causticsTexture:null,causticsTextureB:null,color:new m.Color,lightProjMatrix:new m.Matrix4,lightViewMatrix:new m.Matrix4},"varying vec3 vWorldPosition; \n void main() {\n gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.);\n vec4 worldPosition = modelMatrix * vec4(position, 1.);\n vWorldPosition = worldPosition.xyz;\n }","varying vec3 vWorldPosition;\n uniform vec3 color;\n uniform sampler2D causticsTexture; \n uniform sampler2D causticsTextureB; \n uniform mat4 lightProjMatrix;\n uniform mat4 lightViewMatrix;\n void main() {\n // Apply caustics \n vec4 lightSpacePos = lightProjMatrix * lightViewMatrix * vec4(vWorldPosition, 1.0);\n lightSpacePos.xyz /= lightSpacePos.w;\n lightSpacePos.xyz = lightSpacePos.xyz * 0.5 + 0.5; \n vec3 front = texture2D(causticsTexture, lightSpacePos.xy).rgb;\n vec3 back = texture2D(causticsTextureB, lightSpacePos.xy).rgb;\n gl_FragColor = vec4((front + back) * color, 1.0);\n #include <tonemapping_fragment>\n #include <encodings_fragment>\n }"),x=a.shaderMaterial({cameraMatrixWorld:new m.Matrix4,cameraProjectionMatrixInv:new m.Matrix4,normalTexture:null,depthTexture:null,lightDir:new m.Vector3(0,1,0),lightPlaneNormal:new m.Vector3(0,1,0),lightPlaneConstant:0,near:.1,far:100,modelMatrix:new m.Matrix4,worldRadius:1/40,ior:1.1,bounces:0,resolution:1024,size:10,intensity:.5},"\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }"," \n uniform mat4 cameraMatrixWorld;\n uniform mat4 cameraProjectionMatrixInv;\n uniform vec3 lightDir;\n uniform vec3 lightPlaneNormal;\n uniform float lightPlaneConstant;\n uniform float near;\n uniform float far;\n uniform float time;\n uniform float worldRadius;\n uniform float resolution;\n uniform float size;\n uniform float intensity;\n uniform float ior;\n precision highp isampler2D;\n precision highp usampler2D;\n uniform sampler2D normalTexture;\n uniform sampler2D depthTexture;\n uniform float bounces;\n varying vec2 vUv;\n vec3 WorldPosFromDepth(float depth, vec2 coord) {\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = cameraProjectionMatrixInv * clipSpacePosition;\n // Perspective division\n viewSpacePosition /= viewSpacePosition.w;\n vec4 worldSpacePosition = cameraMatrixWorld * viewSpacePosition;\n return worldSpacePosition.xyz;\n } \n float sdPlane( vec3 p, vec3 n, float h ) {\n // n must be normalized\n return dot(p,n) + h;\n }\n float planeIntersect( vec3 ro, vec3 rd, vec4 p ) {\n return -(dot(ro,p.xyz)+p.w)/dot(rd,p.xyz);\n }\n vec3 totalInternalReflection(vec3 ro, vec3 rd, vec3 pos, vec3 normal, float ior, out vec3 rayOrigin, out vec3 rayDirection) {\n rayOrigin = ro;\n rayDirection = rd;\n rayDirection = refract(rayDirection, normal, 1.0 / ior);\n rayOrigin = pos + rayDirection * 0.1;\n return rayDirection;\n }\n void main() {\n // Each sample consists of random offset in the x and y direction\n float caustic = 0.0;\n float causticTexelSize = (1.0 / resolution) * size * 2.0;\n float texelsNeeded = worldRadius / causticTexelSize;\n float sampleRadius = texelsNeeded / resolution;\n float sum = 0.0;\n if (texture2D(depthTexture, vUv).x == 1.0) {\n gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n return;\n }\n vec2 offset1 = vec2(-0.5, -0.5);//vec2(rand() - 0.5, rand() - 0.5);\n vec2 offset2 = vec2(-0.5, 0.5);//vec2(rand() - 0.5, rand() - 0.5);\n vec2 offset3 = vec2(0.5, 0.5);//vec2(rand() - 0.5, rand() - 0.5);\n vec2 offset4 = vec2(0.5, -0.5);//vec2(rand() - 0.5, rand() - 0.5);\n vec2 uv1 = vUv + offset1 * sampleRadius;\n vec2 uv2 = vUv + offset2 * sampleRadius;\n vec2 uv3 = vUv + offset3 * sampleRadius;\n vec2 uv4 = vUv + offset4 * sampleRadius;\n vec3 normal1 = texture2D(normalTexture, uv1, -10.0).rgb * 2.0 - 1.0;\n vec3 normal2 = texture2D(normalTexture, uv2, -10.0).rgb * 2.0 - 1.0;\n vec3 normal3 = texture2D(normalTexture, uv3, -10.0).rgb * 2.0 - 1.0;\n vec3 normal4 = texture2D(normalTexture, uv4, -10.0).rgb * 2.0 - 1.0;\n float depth1 = texture2D(depthTexture, uv1, -10.0).x;\n float depth2 = texture2D(depthTexture, uv2, -10.0).x;\n float depth3 = texture2D(depthTexture, uv3, -10.0).x;\n float depth4 = texture2D(depthTexture, uv4, -10.0).x;\n // Sanity check the depths\n if (depth1 == 1.0 || depth2 == 1.0 || depth3 == 1.0 || depth4 == 1.0) {\n gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n return;\n }\n vec3 pos1 = WorldPosFromDepth(depth1, uv1);\n vec3 pos2 = WorldPosFromDepth(depth2, uv2);\n vec3 pos3 = WorldPosFromDepth(depth3, uv3);\n vec3 pos4 = WorldPosFromDepth(depth4, uv4);\n vec3 originPos1 = WorldPosFromDepth(0.0, uv1);\n vec3 originPos2 = WorldPosFromDepth(0.0, uv2);\n vec3 originPos3 = WorldPosFromDepth(0.0, uv3);\n vec3 originPos4 = WorldPosFromDepth(0.0, uv4);\n vec3 endPos1, endPos2, endPos3, endPos4;\n vec3 endDir1, endDir2, endDir3, endDir4;\n totalInternalReflection(originPos1, lightDir, pos1, normal1, ior, endPos1, endDir1);\n totalInternalReflection(originPos2, lightDir, pos2, normal2, ior, endPos2, endDir2);\n totalInternalReflection(originPos3, lightDir, pos3, normal3, ior, endPos3, endDir3);\n totalInternalReflection(originPos4, lightDir, pos4, normal4, ior, endPos4, endDir4);\n float lightPosArea = length(cross(originPos2 - originPos1, originPos3 - originPos1)) + length(cross(originPos3 - originPos1, originPos4 - originPos1));\n float t1 = planeIntersect(endPos1, endDir1, vec4(lightPlaneNormal, lightPlaneConstant));\n float t2 = planeIntersect(endPos2, endDir2, vec4(lightPlaneNormal, lightPlaneConstant));\n float t3 = planeIntersect(endPos3, endDir3, vec4(lightPlaneNormal, lightPlaneConstant));\n float t4 = planeIntersect(endPos4, endDir4, vec4(lightPlaneNormal, lightPlaneConstant));\n vec3 finalPos1 = endPos1 + endDir1 * t1;\n vec3 finalPos2 = endPos2 + endDir2 * t2;\n vec3 finalPos3 = endPos3 + endDir3 * t3;\n vec3 finalPos4 = endPos4 + endDir4 * t4;\n float finalArea = length(cross(finalPos2 - finalPos1, finalPos3 - finalPos1)) + length(cross(finalPos3 - finalPos1, finalPos4 - finalPos1));\n caustic += intensity * (lightPosArea / finalArea);\n // Calculate the area of the triangle in light spaces\n gl_FragColor = vec4(vec3(max(caustic, 0.0)), 1.0);\n }"),h={depth:!0,minFilter:m.LinearFilter,magFilter:m.LinearFilter,encoding:m.LinearEncoding,type:m.UnsignedByteType},g={minFilter:m.LinearMipmapLinearFilter,magFilter:m.LinearFilter,encoding:m.LinearEncoding,format:m.RGBAFormat,type:m.FloatType,generateMipmaps:!0},P=p.forwardRef((({debug:e,children:r,frames:n=1,ior:a=1.1,color:s="white",causticsOnly:u=!1,backfaces:P=!1,backfaceIor:y=1.1,worldRadius:M=.3125,intensity:w=.05,resolution:D=2024,near:T=.1,far:F=100,lightSource:S=[5,5,5],...b},j)=>{t.extend({CausticsProjectionMaterial:f});const z=p.useRef(null),R=p.useRef(null),W=p.useRef(null),C=p.useRef(null),I=t.useThree((e=>e.gl)),V=i.useHelper(e&&R,m.CameraHelper),O=o.useFBO(D,D,h),B=o.useFBO(D,D,h),_=o.useFBO(D,D,g),E=o.useFBO(D,D,g),[A]=p.useState((()=>v())),[N]=p.useState((()=>v(m.BackSide))),[k]=p.useState((()=>new x)),[q]=p.useState((()=>new c.FullScreenQuad(k)));p.useLayoutEffect((()=>{z.current.updateWorldMatrix(!0,!0)}),[]);let U=0;const L=new m.Vector3,H=new m.Frustum,G=new m.Matrix4,Q=new m.Plane,J=new m.Vector3,K=new m.Vector3,X=new m.Box3,Y=new m.Vector3;return t.useFrame(((r,t)=>{if(n===1/0||U++<n){var o,i;J.fromArray(S).normalize(),K.copy(J).multiplyScalar(-1);let r=[];null==(o=W.current.parent)||o.matrixWorld.identity(),X.setFromObject(W.current,!0),r.push(new m.Vector3(X.min.x,X.min.y,X.min.z)),r.push(new m.Vector3(X.min.x,X.min.y,X.max.z)),r.push(new m.Vector3(X.min.x,X.max.y,X.min.z)),r.push(new m.Vector3(X.min.x,X.max.y,X.max.z)),r.push(new m.Vector3(X.max.x,X.min.y,X.min.z)),r.push(new m.Vector3(X.max.x,X.min.y,X.max.z)),r.push(new m.Vector3(X.max.x,X.max.y,X.min.z)),r.push(new m.Vector3(X.max.x,X.max.y,X.max.z));const n=r.map((e=>e.clone()));X.getCenter(Y),r=r.map((e=>e.clone().sub(Y)));const t=Q.set(K,0),l=r.map((e=>t.projectPoint(e,new m.Vector3))),c=l.reduce(((e,r)=>e.add(r)),L.set(0,0,0)).divideScalar(l.length),s=l.map((e=>e.distanceTo(c))).reduce(((e,r)=>Math.max(e,r))),d=r.map((e=>e.dot(J))).reduce(((e,r)=>Math.max(e,r)));R.current.position.copy(J.clone().multiplyScalar(d).add(Y)),R.current.lookAt(W.current.localToWorld(Y.clone()));const p=G.lookAt(R.current.position,Y,L.set(0,1,0));R.current.left=-s,R.current.right=s,R.current.top=s,R.current.bottom=-s;const v=L.set(0,s,0).applyMatrix4(p),f=(R.current.position.y+v.y)/J.y;R.current.near=.1,R.current.far=f,R.current.updateProjectionMatrix(),R.current.updateMatrixWorld();const x=n.map((e=>e.add(J.clone().multiplyScalar(-e.y/J.y)))),h=x.reduce(((e,r)=>e.add(r)),L.set(0,0,0)).divideScalar(x.length),g=2*x.map((e=>Math.hypot(e.x-h.x,e.z-h.z))).reduce(((e,r)=>Math.max(e,r)));C.current.scale.setScalar(g),C.current.position.copy(h),e&&(null==(i=V.current)||i.update());const T=H.setFromProjectionMatrix(G.multiplyMatrices(R.current.projectionMatrix,R.current.matrixWorldInverse)).planes[4];N.viewMatrix.value=A.viewMatrix.value=R.current.matrixWorldInverse,k.cameraMatrixWorld=R.current.matrixWorld,k.cameraProjectionMatrixInv=R.current.projectionMatrixInverse,k.lightDir=K,k.lightPlaneNormal=T.normal,k.lightPlaneConstant=T.constant,k.near=R.current.near,k.far=R.current.far,k.resolution=D,k.size=s,k.intensity=w,k.worldRadius=M,W.current.visible=!0,I.setRenderTarget(O),I.clear(),W.current.overrideMaterial=A,I.render(W.current,R.current),I.setRenderTarget(B),I.clear(),P&&(W.current.overrideMaterial=N,I.render(W.current,R.current)),W.current.overrideMaterial=null,k.ior=a,C.current.material.lightProjMatrix=R.current.projectionMatrix,C.current.material.lightViewMatrix=R.current.matrixWorldInverse,k.normalTexture=O.texture,k.depthTexture=O.depthTexture,I.setRenderTarget(_),I.clear(),q.render(I),k.ior=y,k.normalTexture=B.texture,k.depthTexture=B.depthTexture,I.setRenderTarget(E),I.clear(),P&&q.render(I),I.setRenderTarget(null),u&&(W.current.visible=!1)}})),p.createElement("group",d.default({ref:z},b),p.createElement("orthographicCamera",{ref:R,up:[0,1,0]}),p.createElement("scene",{ref:W},r),p.createElement("mesh",{ref:C,"rotation-x":-Math.PI/2},p.createElement("planeGeometry",null),p.createElement("causticsProjectionMaterial",{transparent:!0,color:s,causticsTexture:_.texture,causticsTextureB:E.texture,blending:m.CustomBlending,blendSrc:m.OneFactor,blendDst:m.SrcAlphaFactor,depthWrite:!1}),e&&p.createElement(l.Edges,null,p.createElement("lineBasicMaterial",{color:"#ffff00",toneMapped:!1}))))}));exports.Caustics=P;
|
package/core/Caustics.d.ts
CHANGED
|
@@ -36,10 +36,10 @@ export declare const Caustics: React.ForwardRefExoticComponent<Pick<Omit<ReactTh
|
|
|
36
36
|
layers?: ReactThreeFiber.Layers | undefined;
|
|
37
37
|
dispose?: (() => void) | null | undefined;
|
|
38
38
|
} & import("@react-three/fiber/dist/declarations/src/core/events").EventHandlers & {
|
|
39
|
+
frames?: number | undefined;
|
|
39
40
|
debug?: boolean | undefined;
|
|
40
41
|
causticsOnly: boolean;
|
|
41
42
|
backfaces: boolean;
|
|
42
|
-
frustum?: number | undefined;
|
|
43
43
|
ior?: number | undefined;
|
|
44
44
|
backfaceIor?: number | undefined;
|
|
45
45
|
worldRadius?: number | undefined;
|
|
@@ -49,5 +49,4 @@ export declare const Caustics: React.ForwardRefExoticComponent<Pick<Omit<ReactTh
|
|
|
49
49
|
near?: number | undefined;
|
|
50
50
|
far?: number | undefined;
|
|
51
51
|
lightSource?: [x: number, y: number, z: number] | undefined;
|
|
52
|
-
|
|
53
|
-
}, "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 | "near" | "far" | "intensity" | "focus" | "ior" | "resolution" | "debug" | "frustum" | "worldRadius" | "causticsOnly" | "backfaces" | "backfaceIor" | "lightSource"> & React.RefAttributes<unknown>>;
|
|
52
|
+
}, "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 | "near" | "far" | "intensity" | "ior" | "resolution" | "debug" | "frames" | "worldRadius" | "causticsOnly" | "backfaces" | "backfaceIor" | "lightSource"> & React.RefAttributes<unknown>>;
|
package/core/Caustics.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
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 { extend, useThree } from '@react-three/fiber';
|
|
4
|
+
import { extend, useThree, useFrame } from '@react-three/fiber';
|
|
5
5
|
import { useFBO } from './useFBO.js';
|
|
6
6
|
import { useHelper } from './useHelper.js';
|
|
7
7
|
import { shaderMaterial } from './shaderMaterial.js';
|
|
8
|
+
import { Edges } from './Edges.js';
|
|
8
9
|
import { FullScreenQuad } from 'three-stdlib';
|
|
9
10
|
|
|
10
11
|
function createNormalMaterial(side = THREE.FrontSide) {
|
|
@@ -28,7 +29,7 @@ function createNormalMaterial(side = THREE.FrontSide) {
|
|
|
28
29
|
const CausticsProjectionMaterial = shaderMaterial({
|
|
29
30
|
causticsTexture: null,
|
|
30
31
|
causticsTextureB: null,
|
|
31
|
-
color: new THREE.Color(
|
|
32
|
+
color: new THREE.Color(),
|
|
32
33
|
lightProjMatrix: new THREE.Matrix4(),
|
|
33
34
|
lightViewMatrix: new THREE.Matrix4()
|
|
34
35
|
}, `varying vec3 vWorldPosition;
|
|
@@ -59,6 +60,8 @@ const CausticsMaterial = shaderMaterial({
|
|
|
59
60
|
normalTexture: null,
|
|
60
61
|
depthTexture: null,
|
|
61
62
|
lightDir: new THREE.Vector3(0, 1, 0),
|
|
63
|
+
lightPlaneNormal: new THREE.Vector3(0, 1, 0),
|
|
64
|
+
lightPlaneConstant: 0,
|
|
62
65
|
near: 0.1,
|
|
63
66
|
far: 100,
|
|
64
67
|
modelMatrix: new THREE.Matrix4(),
|
|
@@ -81,6 +84,8 @@ const CausticsMaterial = shaderMaterial({
|
|
|
81
84
|
uniform mat4 cameraMatrixWorld;
|
|
82
85
|
uniform mat4 cameraProjectionMatrixInv;
|
|
83
86
|
uniform vec3 lightDir;
|
|
87
|
+
uniform vec3 lightPlaneNormal;
|
|
88
|
+
uniform float lightPlaneConstant;
|
|
84
89
|
uniform float near;
|
|
85
90
|
uniform float far;
|
|
86
91
|
uniform float time;
|
|
@@ -165,10 +170,10 @@ const CausticsMaterial = shaderMaterial({
|
|
|
165
170
|
totalInternalReflection(originPos3, lightDir, pos3, normal3, ior, endPos3, endDir3);
|
|
166
171
|
totalInternalReflection(originPos4, lightDir, pos4, normal4, ior, endPos4, endDir4);
|
|
167
172
|
float lightPosArea = length(cross(originPos2 - originPos1, originPos3 - originPos1)) + length(cross(originPos3 - originPos1, originPos4 - originPos1));
|
|
168
|
-
float t1 = planeIntersect(endPos1, endDir1, vec4(
|
|
169
|
-
float t2 = planeIntersect(endPos2, endDir2, vec4(
|
|
170
|
-
float t3 = planeIntersect(endPos3, endDir3, vec4(
|
|
171
|
-
float t4 = planeIntersect(endPos4, endDir4, vec4(
|
|
173
|
+
float t1 = planeIntersect(endPos1, endDir1, vec4(lightPlaneNormal, lightPlaneConstant));
|
|
174
|
+
float t2 = planeIntersect(endPos2, endDir2, vec4(lightPlaneNormal, lightPlaneConstant));
|
|
175
|
+
float t3 = planeIntersect(endPos3, endDir3, vec4(lightPlaneNormal, lightPlaneConstant));
|
|
176
|
+
float t4 = planeIntersect(endPos4, endDir4, vec4(lightPlaneNormal, lightPlaneConstant));
|
|
172
177
|
vec3 finalPos1 = endPos1 + endDir1 * t1;
|
|
173
178
|
vec3 finalPos2 = endPos2 + endDir2 * t2;
|
|
174
179
|
vec3 finalPos3 = endPos3 + endDir3 * t3;
|
|
@@ -196,7 +201,7 @@ const CAUSTICPROPS = {
|
|
|
196
201
|
const Caustics = /*#__PURE__*/React.forwardRef(({
|
|
197
202
|
debug,
|
|
198
203
|
children,
|
|
199
|
-
|
|
204
|
+
frames = 1,
|
|
200
205
|
ior = 1.1,
|
|
201
206
|
color = 'white',
|
|
202
207
|
causticsOnly = false,
|
|
@@ -208,7 +213,6 @@ const Caustics = /*#__PURE__*/React.forwardRef(({
|
|
|
208
213
|
near = 0.1,
|
|
209
214
|
far = 100,
|
|
210
215
|
lightSource = [5, 5, 5],
|
|
211
|
-
focus = [0, 0, 0],
|
|
212
216
|
...props
|
|
213
217
|
}, fref) => {
|
|
214
218
|
extend({
|
|
@@ -219,8 +223,7 @@ const Caustics = /*#__PURE__*/React.forwardRef(({
|
|
|
219
223
|
const scene = React.useRef(null);
|
|
220
224
|
const plane = React.useRef(null);
|
|
221
225
|
const gl = useThree(state => state.gl);
|
|
222
|
-
const helper = useHelper(debug && camera, THREE.CameraHelper);
|
|
223
|
-
const boxHelper = useHelper(debug && plane, THREE.BoxHelper); // Buffers for front and back faces
|
|
226
|
+
const helper = useHelper(debug && camera, THREE.CameraHelper); // Buffers for front and back faces
|
|
224
227
|
|
|
225
228
|
const normalTarget = useFBO(resolution, resolution, NORMALPROPS);
|
|
226
229
|
const normalTargetB = useFBO(resolution, resolution, NORMALPROPS);
|
|
@@ -232,89 +235,130 @@ const Caustics = /*#__PURE__*/React.forwardRef(({
|
|
|
232
235
|
|
|
233
236
|
const [causticsMaterial] = React.useState(() => new CausticsMaterial());
|
|
234
237
|
const [causticsQuad] = React.useState(() => new FullScreenQuad(causticsMaterial));
|
|
235
|
-
const pos = new THREE.Vector3();
|
|
236
238
|
React.useLayoutEffect(() => {
|
|
237
|
-
// Update matrix world and the camera
|
|
238
|
-
ref.current.updateWorldMatrix(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
239
|
+
// Update matrix world and the camera on first mount
|
|
240
|
+
ref.current.updateWorldMatrix(true, true);
|
|
241
|
+
}, []);
|
|
242
|
+
let count = 0;
|
|
243
|
+
const v = new THREE.Vector3();
|
|
244
|
+
const lpF = new THREE.Frustum();
|
|
245
|
+
const lpM = new THREE.Matrix4();
|
|
246
|
+
const lpP = new THREE.Plane();
|
|
247
|
+
const lightDir = new THREE.Vector3();
|
|
248
|
+
const lightDirInv = new THREE.Vector3();
|
|
249
|
+
const bounds = new THREE.Box3();
|
|
250
|
+
const focusPos = new THREE.Vector3();
|
|
251
|
+
useFrame((state, delta) => {
|
|
252
|
+
if (frames === Infinity || count++ < frames) {
|
|
253
|
+
var _scene$current$parent, _helper$current;
|
|
243
254
|
|
|
244
|
-
|
|
245
|
-
|
|
255
|
+
lightDir.fromArray(lightSource).normalize();
|
|
256
|
+
lightDirInv.copy(lightDir).multiplyScalar(-1);
|
|
257
|
+
let boundsVertices = [];
|
|
258
|
+
(_scene$current$parent = scene.current.parent) == null ? void 0 : _scene$current$parent.matrixWorld.identity();
|
|
259
|
+
bounds.setFromObject(scene.current, true);
|
|
260
|
+
boundsVertices.push(new THREE.Vector3(bounds.min.x, bounds.min.y, bounds.min.z));
|
|
261
|
+
boundsVertices.push(new THREE.Vector3(bounds.min.x, bounds.min.y, bounds.max.z));
|
|
262
|
+
boundsVertices.push(new THREE.Vector3(bounds.min.x, bounds.max.y, bounds.min.z));
|
|
263
|
+
boundsVertices.push(new THREE.Vector3(bounds.min.x, bounds.max.y, bounds.max.z));
|
|
264
|
+
boundsVertices.push(new THREE.Vector3(bounds.max.x, bounds.min.y, bounds.min.z));
|
|
265
|
+
boundsVertices.push(new THREE.Vector3(bounds.max.x, bounds.min.y, bounds.max.z));
|
|
266
|
+
boundsVertices.push(new THREE.Vector3(bounds.max.x, bounds.max.y, bounds.min.z));
|
|
267
|
+
boundsVertices.push(new THREE.Vector3(bounds.max.x, bounds.max.y, bounds.max.z));
|
|
268
|
+
const worldVerts = boundsVertices.map(v => v.clone());
|
|
269
|
+
bounds.getCenter(focusPos);
|
|
270
|
+
boundsVertices = boundsVertices.map(v => v.clone().sub(focusPos));
|
|
271
|
+
const lightPlane = lpP.set(lightDirInv, 0);
|
|
272
|
+
const projectedVerts = boundsVertices.map(v => lightPlane.projectPoint(v, new THREE.Vector3()));
|
|
273
|
+
const centralVert = projectedVerts.reduce((a, b) => a.add(b), v.set(0, 0, 0)).divideScalar(projectedVerts.length);
|
|
274
|
+
const radius = projectedVerts.map(v => v.distanceTo(centralVert)).reduce((a, b) => Math.max(a, b));
|
|
275
|
+
const dirLength = boundsVertices.map(x => x.dot(lightDir)).reduce((a, b) => Math.max(a, b)); // Shadows
|
|
246
276
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
277
|
+
camera.current.position.copy(lightDir.clone().multiplyScalar(dirLength).add(focusPos));
|
|
278
|
+
camera.current.lookAt(scene.current.localToWorld(focusPos.clone()));
|
|
279
|
+
const dirMatrix = lpM.lookAt(camera.current.position, focusPos, v.set(0, 1, 0));
|
|
280
|
+
camera.current.left = -radius;
|
|
281
|
+
camera.current.right = radius;
|
|
282
|
+
camera.current.top = radius;
|
|
283
|
+
camera.current.bottom = -radius;
|
|
284
|
+
const yOffset = v.set(0, radius, 0).applyMatrix4(dirMatrix);
|
|
285
|
+
const yTime = (camera.current.position.y + yOffset.y) / lightDir.y;
|
|
286
|
+
camera.current.near = 0.1;
|
|
287
|
+
camera.current.far = yTime;
|
|
288
|
+
camera.current.updateProjectionMatrix();
|
|
289
|
+
camera.current.updateMatrixWorld(); // Now find size of ground plane
|
|
250
290
|
|
|
291
|
+
const groundProjectedCoords = worldVerts.map(v => v.add(lightDir.clone().multiplyScalar(-v.y / lightDir.y)));
|
|
292
|
+
const centerPos = groundProjectedCoords.reduce((a, b) => a.add(b), v.set(0, 0, 0)).divideScalar(groundProjectedCoords.length);
|
|
293
|
+
const maxSize = 2 * groundProjectedCoords.map(v => Math.hypot(v.x - centerPos.x, v.z - centerPos.z)).reduce((a, b) => Math.max(a, b));
|
|
294
|
+
plane.current.scale.setScalar(maxSize);
|
|
295
|
+
plane.current.position.copy(centerPos);
|
|
296
|
+
if (debug) (_helper$current = helper.current) == null ? void 0 : _helper$current.update(); // Inject uniforms
|
|
251
297
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
causticsMaterial.size = frustum;
|
|
260
|
-
causticsMaterial.intensity = intensity;
|
|
261
|
-
causticsMaterial.worldRadius = worldRadius; // Switch the scene on
|
|
298
|
+
const dirLightNearPlane = lpF.setFromProjectionMatrix(lpM.multiplyMatrices(camera.current.projectionMatrix, camera.current.matrixWorldInverse)).planes[4];
|
|
299
|
+
normalMatB.viewMatrix.value = normalMat.viewMatrix.value = camera.current.matrixWorldInverse;
|
|
300
|
+
causticsMaterial.cameraMatrixWorld = camera.current.matrixWorld;
|
|
301
|
+
causticsMaterial.cameraProjectionMatrixInv = camera.current.projectionMatrixInverse;
|
|
302
|
+
causticsMaterial.lightDir = lightDirInv;
|
|
303
|
+
causticsMaterial.lightPlaneNormal = dirLightNearPlane.normal;
|
|
304
|
+
causticsMaterial.lightPlaneConstant = dirLightNearPlane.constant; //console.log(causticsMaterial.lightDir)
|
|
262
305
|
|
|
263
|
-
|
|
306
|
+
causticsMaterial.near = camera.current.near;
|
|
307
|
+
causticsMaterial.far = camera.current.far;
|
|
308
|
+
causticsMaterial.resolution = resolution;
|
|
309
|
+
causticsMaterial.size = radius;
|
|
310
|
+
causticsMaterial.intensity = intensity;
|
|
311
|
+
causticsMaterial.worldRadius = worldRadius; // Switch the scene on
|
|
264
312
|
|
|
265
|
-
|
|
266
|
-
gl.clear();
|
|
267
|
-
scene.current.overrideMaterial = normalMat;
|
|
268
|
-
gl.render(scene.current, camera.current); // Render back face normals, if enabled
|
|
313
|
+
scene.current.visible = true; // Render front face normals
|
|
269
314
|
|
|
270
|
-
|
|
271
|
-
|
|
315
|
+
gl.setRenderTarget(normalTarget);
|
|
316
|
+
gl.clear();
|
|
317
|
+
scene.current.overrideMaterial = normalMat;
|
|
318
|
+
gl.render(scene.current, camera.current); // Render back face normals, if enabled
|
|
272
319
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
gl.render(scene.current, camera.current);
|
|
276
|
-
} // Remove the override material
|
|
320
|
+
gl.setRenderTarget(normalTargetB);
|
|
321
|
+
gl.clear();
|
|
277
322
|
|
|
323
|
+
if (backfaces) {
|
|
324
|
+
scene.current.overrideMaterial = normalMatB;
|
|
325
|
+
gl.render(scene.current, camera.current);
|
|
326
|
+
} // Remove the override material
|
|
278
327
|
|
|
279
|
-
scene.current.overrideMaterial = null; // Render front face caustics
|
|
280
328
|
|
|
281
|
-
|
|
282
|
-
plane.current.material.lightProjMatrix = camera.current.projectionMatrix;
|
|
283
|
-
plane.current.material.lightViewMatrix = camera.current.matrixWorldInverse;
|
|
284
|
-
causticsMaterial.normalTexture = normalTarget.texture;
|
|
285
|
-
causticsMaterial.depthTexture = normalTarget.depthTexture;
|
|
286
|
-
gl.setRenderTarget(causticsTarget);
|
|
287
|
-
gl.clear();
|
|
288
|
-
causticsQuad.render(gl); // Render back face caustics, if enabled
|
|
329
|
+
scene.current.overrideMaterial = null; // Render front face caustics
|
|
289
330
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
331
|
+
causticsMaterial.ior = ior;
|
|
332
|
+
plane.current.material.lightProjMatrix = camera.current.projectionMatrix;
|
|
333
|
+
plane.current.material.lightViewMatrix = camera.current.matrixWorldInverse;
|
|
334
|
+
causticsMaterial.normalTexture = normalTarget.texture;
|
|
335
|
+
causticsMaterial.depthTexture = normalTarget.depthTexture;
|
|
336
|
+
gl.setRenderTarget(causticsTarget);
|
|
337
|
+
gl.clear();
|
|
338
|
+
causticsQuad.render(gl); // Render back face caustics, if enabled
|
|
296
339
|
|
|
297
|
-
|
|
340
|
+
causticsMaterial.ior = backfaceIor;
|
|
341
|
+
causticsMaterial.normalTexture = normalTargetB.texture;
|
|
342
|
+
causticsMaterial.depthTexture = normalTargetB.depthTexture;
|
|
343
|
+
gl.setRenderTarget(causticsTargetB);
|
|
344
|
+
gl.clear();
|
|
345
|
+
if (backfaces) causticsQuad.render(gl); // Reset render target
|
|
298
346
|
|
|
299
|
-
|
|
347
|
+
gl.setRenderTarget(null); // Switch the scene off if caustics is all that's wanted
|
|
348
|
+
|
|
349
|
+
if (causticsOnly) scene.current.visible = false;
|
|
350
|
+
}
|
|
300
351
|
});
|
|
301
352
|
return /*#__PURE__*/React.createElement("group", _extends({
|
|
302
353
|
ref: ref
|
|
303
354
|
}, props), /*#__PURE__*/React.createElement("orthographicCamera", {
|
|
304
355
|
ref: camera,
|
|
305
|
-
up: [0, 1, 0]
|
|
306
|
-
left: -frustum,
|
|
307
|
-
right: frustum,
|
|
308
|
-
top: frustum,
|
|
309
|
-
bottom: -frustum,
|
|
310
|
-
near: near,
|
|
311
|
-
far: far
|
|
356
|
+
up: [0, 1, 0]
|
|
312
357
|
}), /*#__PURE__*/React.createElement("scene", {
|
|
313
358
|
ref: scene
|
|
314
359
|
}, children), /*#__PURE__*/React.createElement("mesh", {
|
|
315
360
|
ref: plane,
|
|
316
|
-
"rotation-x": -Math.PI / 2
|
|
317
|
-
scale: frustum * 2
|
|
361
|
+
"rotation-x": -Math.PI / 2
|
|
318
362
|
}, /*#__PURE__*/React.createElement("planeGeometry", null), /*#__PURE__*/React.createElement("causticsProjectionMaterial", {
|
|
319
363
|
transparent: true,
|
|
320
364
|
color: color,
|
|
@@ -324,7 +368,10 @@ const Caustics = /*#__PURE__*/React.forwardRef(({
|
|
|
324
368
|
blendSrc: THREE.OneFactor,
|
|
325
369
|
blendDst: THREE.SrcAlphaFactor,
|
|
326
370
|
depthWrite: false
|
|
327
|
-
})
|
|
371
|
+
}), debug && /*#__PURE__*/React.createElement(Edges, null, /*#__PURE__*/React.createElement("lineBasicMaterial", {
|
|
372
|
+
color: "#ffff00",
|
|
373
|
+
toneMapped: false
|
|
374
|
+
}))));
|
|
328
375
|
});
|
|
329
376
|
|
|
330
377
|
export { Caustics };
|
package/core/Center.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("three"),r=require("react");function n(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(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),t=require("three"),r=require("react");function n(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(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var i=n(e),o=u(r);const c=o.forwardRef((function({children:e,disable:r,disableX:n,disableY:u,disableZ:c,left:a,right:l,top:f,bottom:d,front:s,back:p,onCentered:b,precise:m=!0,...g},h){const x=o.useRef(null),y=o.useRef(null),j=o.useRef(null);return o.useLayoutEffect((()=>{y.current.matrixWorld.identity();const e=(new t.Box3).setFromObject(j.current,m),i=new t.Vector3,o=new t.Sphere,g=e.max.x-e.min.x,h=e.max.y-e.min.y,v=e.max.z-e.min.z;e.getCenter(i),e.getBoundingSphere(o);const O=f?h/2:d?-h/2:0,w=a?-g/2:l?g/2:0,z=s?v/2:p?-v/2:0;y.current.position.set(r||n?0:-i.x+w,r||u?0:-i.y+O,r||c?0:-i.z+z),void 0!==b&&b({parent:x.current.parent,container:x.current,width:g,height:h,depth:v,boundingBox:e,boundingSphere:o,center:i,verticalAlignment:O,horizontalAlignment:w,depthAlignment:z})}),[e]),o.useImperativeHandle(h,(()=>x.current),[]),o.createElement("group",i.default({ref:x},g),o.createElement("group",{ref:y},o.createElement("group",{ref:j},e)))}));exports.Center=c;
|
package/core/Center.d.ts
CHANGED
package/core/Center.js
CHANGED
|
@@ -4,6 +4,7 @@ import * as React from 'react';
|
|
|
4
4
|
|
|
5
5
|
const Center = /*#__PURE__*/React.forwardRef(function Center({
|
|
6
6
|
children,
|
|
7
|
+
disable,
|
|
7
8
|
disableX,
|
|
8
9
|
disableY,
|
|
9
10
|
disableZ,
|
|
@@ -33,7 +34,7 @@ const Center = /*#__PURE__*/React.forwardRef(function Center({
|
|
|
33
34
|
const vAlign = top ? height / 2 : bottom ? -height / 2 : 0;
|
|
34
35
|
const hAlign = left ? -width / 2 : right ? width / 2 : 0;
|
|
35
36
|
const dAlign = front ? depth / 2 : back ? -depth / 2 : 0;
|
|
36
|
-
outer.current.position.set(disableX ? 0 : -center.x + hAlign, disableY ? 0 : -center.y + vAlign, disableZ ? 0 : -center.z + dAlign);
|
|
37
|
+
outer.current.position.set(disable || disableX ? 0 : -center.x + hAlign, disable || disableY ? 0 : -center.y + vAlign, disable || disableZ ? 0 : -center.z + dAlign);
|
|
37
38
|
|
|
38
39
|
if (typeof onCentered !== 'undefined') {
|
|
39
40
|
onCentered({
|
package/core/useBVH.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),r=require("three-mesh-bvh");function t(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var u=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,u.get?u:{enumerable:!0,get:function(){return e[t]}})}})),r.default=e,Object.freeze(r)}var u=t(e);exports.useBVH=function(e,t){u.useEffect((()=>{if(e.current){e.current.raycast=r.acceleratedRaycast;const u=e.current.geometry;return u.computeBoundsTree=r.computeBoundsTree,u.disposeBoundsTree=r.disposeBoundsTree,u.computeBoundsTree(t),()=>{u.boundsTree&&u.disposeBoundsTree()}}}),[e,t])};
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),r=require("three-mesh-bvh");function t(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var u=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,u.get?u:{enumerable:!0,get:function(){return e[t]}})}})),r.default=e,Object.freeze(r)}var u=t(e);exports.useBVH=function(e,t){t={splitStrategy:"SAH",verbose:!1,setBoundingBox:!0,maxDepth:40,maxLeafTris:10,...t},u.useEffect((()=>{if(e.current){e.current.raycast=r.acceleratedRaycast;const u=e.current.geometry;return u.computeBoundsTree=r.computeBoundsTree,u.disposeBoundsTree=r.disposeBoundsTree,u.computeBoundsTree(t),()=>{u.boundsTree&&u.disposeBoundsTree()}}}),[e,JSON.stringify(t)])};
|
package/core/useBVH.js
CHANGED
|
@@ -2,6 +2,14 @@ import * as React from 'react';
|
|
|
2
2
|
import { acceleratedRaycast, computeBoundsTree, disposeBoundsTree } from 'three-mesh-bvh';
|
|
3
3
|
|
|
4
4
|
function useBVH(mesh, options) {
|
|
5
|
+
options = {
|
|
6
|
+
splitStrategy: 'SAH',
|
|
7
|
+
verbose: false,
|
|
8
|
+
setBoundingBox: true,
|
|
9
|
+
maxDepth: 40,
|
|
10
|
+
maxLeafTris: 10,
|
|
11
|
+
...options
|
|
12
|
+
};
|
|
5
13
|
React.useEffect(() => {
|
|
6
14
|
if (mesh.current) {
|
|
7
15
|
mesh.current.raycast = acceleratedRaycast;
|
|
@@ -15,7 +23,7 @@ function useBVH(mesh, options) {
|
|
|
15
23
|
}
|
|
16
24
|
};
|
|
17
25
|
}
|
|
18
|
-
}, [mesh, options]);
|
|
26
|
+
}, [mesh, JSON.stringify(options)]);
|
|
19
27
|
}
|
|
20
28
|
|
|
21
29
|
export { useBVH };
|