@babylonjs/core 4.2.0-rc.8 → 4.2.2
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/Engines/thinEngine.js +2 -2
- package/Engines/thinEngine.js.map +1 -1
- package/Shaders/ShadersInclude/shadowsFragmentFunctions.js +1 -1
- package/Shaders/ShadersInclude/shadowsFragmentFunctions.js.map +1 -1
- package/XR/features/WebXRHandTracking.d.ts +3 -2
- package/XR/features/WebXRHandTracking.js +12 -6
- package/XR/features/WebXRHandTracking.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Effect } from "../../Materials/effect";
|
|
2
2
|
var name = 'shadowsFragmentFunctions';
|
|
3
|
-
var shader = "#ifdef SHADOWS\n#ifndef SHADOWFLOAT\n\nfloat unpack(vec4 color)\n{\nconst vec4 bit_shift=vec4(1.0/(255.0*255.0*255.0),1.0/(255.0*255.0),1.0/255.0,1.0);\nreturn dot(color,bit_shift);\n}\n#endif\nfloat computeFallOff(float value,vec2 clipSpace,float frustumEdgeFalloff)\n{\nfloat mask=smoothstep(1.0-frustumEdgeFalloff,1.00000012,clamp(dot(clipSpace,clipSpace),0.,1.));\nreturn mix(value,1.0,mask);\n}\n#define inline\nfloat computeShadowCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\ndepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadow=textureCube(shadowSampler,directionToLight).x;\n#endif\nreturn depth>shadow ? darkness : 1.0;\n}\n#define inline\nfloat computeShadowWithPoissonSamplingCube(vec3 lightPosition,samplerCube shadowSampler,float mapSize,float darkness,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\ndepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\nfloat visibility=1.;\nvec3 poissonDisk[4];\npoissonDisk[0]=vec3(-1.0,1.0,-1.0);\npoissonDisk[1]=vec3(1.0,-1.0,-1.0);\npoissonDisk[2]=vec3(-1.0,-1.0,-1.0);\npoissonDisk[3]=vec3(1.0,-1.0,1.0);\n\n#ifndef SHADOWFLOAT\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[0]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[1]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[2]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[3]*mapSize))<depth) visibility-=0.25;\n#else\nif (textureCube(shadowSampler,directionToLight+poissonDisk[0]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[1]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[2]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[3]*mapSize).x<depth) visibility-=0.25;\n#endif\nreturn min(1.0,visibility+darkness);\n}\n#define inline\nfloat computeShadowWithESMCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,float depthScale,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\nfloat shadowPixelDepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadowMapSample=textureCube(shadowSampler,directionToLight).x;\n#endif\nfloat esm=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness);\nreturn esm;\n}\n#define inline\nfloat computeShadowWithCloseESMCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,float depthScale,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\nfloat shadowPixelDepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadowMapSample=textureCube(shadowSampler,directionToLight).x;\n#endif\nfloat esm=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);\nreturn esm;\n}\n#ifdef WEBGL2\n#define inline\nfloat computeShadowCSM(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nvec3 uvLayer=vec3(uv.x,uv.y,layer);\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(texture2D(shadowSampler,uvLayer));\n#else\nfloat shadow=texture2D(shadowSampler,uvLayer).x;\n#endif\nreturn shadowPixelDepth>shadow ? computeFallOff(darkness,clipSpace.xy,frustumEdgeFalloff) : 1.;\n}\n#endif\n#define inline\nfloat computeShadow(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadow=texture2D(shadowSampler,uv).x;\n#endif\nreturn shadowPixelDepth>shadow ? computeFallOff(darkness,clipSpace.xy,frustumEdgeFalloff) : 1.;\n}\n}\n#define inline\nfloat computeShadowWithPoissonSampling(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float mapSize,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\nfloat visibility=1.;\nvec2 poissonDisk[4];\npoissonDisk[0]=vec2(-0.94201624,-0.39906216);\npoissonDisk[1]=vec2(0.94558609,-0.76890725);\npoissonDisk[2]=vec2(-0.094184101,-0.92938870);\npoissonDisk[3]=vec2(0.34495938,0.29387760);\n\n#ifndef SHADOWFLOAT\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[0]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[1]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[2]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[3]*mapSize))<shadowPixelDepth) visibility-=0.25;\n#else\nif (texture2D(shadowSampler,uv+poissonDisk[0]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[1]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[2]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[3]*mapSize).x<shadowPixelDepth) visibility-=0.25;\n#endif\nreturn computeFallOff(min(1.0,visibility+darkness),clipSpace.xy,frustumEdgeFalloff);\n}\n}\n#define inline\nfloat computeShadowWithESM(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float depthScale,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadowMapSample=texture2D(shadowSampler,uv).x;\n#endif\nfloat esm=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness);\nreturn computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n#define inline\nfloat computeShadowWithCloseESM(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float depthScale,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadowMapSample=texture2D(shadowSampler,uv).x;\n#endif\nfloat esm=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);\nreturn computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n#ifdef WEBGL2\n#define GREATEST_LESS_THAN_ONE 0.99999994\n\n#define inline\nfloat computeShadowWithCSMPCF1(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArrayShadow shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec4 uvDepthLayer=vec4(uvDepth.x,uvDepth.y,layer,uvDepth.z);\nfloat shadow=texture(shadowSampler,uvDepthLayer);\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n\n\n\n#define inline\nfloat computeShadowWithCSMPCF3(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArrayShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\n\n\nvec2 uvw0=3.-2.*st;\nvec2 uvw1=1.+2.*st;\nvec2 u=vec2((2.-st.x)/uvw0.x-1.,st.x/uvw1.x+1.)*shadowMapSizeAndInverse.y;\nvec2 v=vec2((2.-st.y)/uvw0.y-1.,st.y/uvw1.y+1.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[0]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[0]),layer,uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[1]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[1]),layer,uvDepth.z));\nshadow=shadow/16.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n\n\n\n#define inline\nfloat computeShadowWithCSMPCF5(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArrayShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\nvec2 uvw0=4.-3.*st;\nvec2 uvw1=vec2(7.);\nvec2 uvw2=1.+3.*st;\nvec3 u=vec3((3.-2.*st.x)/uvw0.x-2.,(3.+st.x)/uvw1.x,st.x/uvw2.x+2.)*shadowMapSizeAndInverse.y;\nvec3 v=vec3((3.-2.*st.y)/uvw0.y-2.,(3.+st.y)/uvw1.y,st.y/uvw2.y+2.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[0]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[0]),layer,uvDepth.z));\nshadow+=uvw2.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[2],v[0]),layer,uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[1]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[1]),layer,uvDepth.z));\nshadow+=uvw2.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[2],v[1]),layer,uvDepth.z));\nshadow+=uvw0.x*uvw2.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[2]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw2.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[2]),layer,uvDepth.z));\nshadow+=uvw2.x*uvw2.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[2],v[2]),layer,uvDepth.z));\nshadow=shadow/144.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n\n#define inline\nfloat computeShadowWithPCF1(vec4 vPositionFromLight,float depthMetric,sampler2DShadow shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nfloat shadow=texture2D(shadowSampler,uvDepth);\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n\n\n\n#define inline\nfloat computeShadowWithPCF3(vec4 vPositionFromLight,float depthMetric,sampler2DShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\n\n\nvec2 uvw0=3.-2.*st;\nvec2 uvw1=1.+2.*st;\nvec2 u=vec2((2.-st.x)/uvw0.x-1.,st.x/uvw1.x+1.)*shadowMapSizeAndInverse.y;\nvec2 v=vec2((2.-st.y)/uvw0.y-1.,st.y/uvw1.y+1.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[0]),uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[0]),uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[1]),uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[1]),uvDepth.z));\nshadow=shadow/16.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n\n\n\n#define inline\nfloat computeShadowWithPCF5(vec4 vPositionFromLight,float depthMetric,sampler2DShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\nvec2 uvw0=4.-3.*st;\nvec2 uvw1=vec2(7.);\nvec2 uvw2=1.+3.*st;\nvec3 u=vec3((3.-2.*st.x)/uvw0.x-2.,(3.+st.x)/uvw1.x,st.x/uvw2.x+2.)*shadowMapSizeAndInverse.y;\nvec3 v=vec3((3.-2.*st.y)/uvw0.y-2.,(3.+st.y)/uvw1.y,st.y/uvw2.y+2.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[0]),uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[0]),uvDepth.z));\nshadow+=uvw2.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[0]),uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[1]),uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[1]),uvDepth.z));\nshadow+=uvw2.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[1]),uvDepth.z));\nshadow+=uvw0.x*uvw2.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[2]),uvDepth.z));\nshadow+=uvw1.x*uvw2.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[2]),uvDepth.z));\nshadow+=uvw2.x*uvw2.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[2]),uvDepth.z));\nshadow=shadow/144.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\nconst vec3 PoissonSamplers32[64]=vec3[64](\nvec3(0.06407013,0.05409927,0.),\nvec3(0.7366577,0.5789394,0.),\nvec3(-0.6270542,-0.5320278,0.),\nvec3(-0.4096107,0.8411095,0.),\nvec3(0.6849564,-0.4990818,0.),\nvec3(-0.874181,-0.04579735,0.),\nvec3(0.9989998,0.0009880066,0.),\nvec3(-0.004920578,-0.9151649,0.),\nvec3(0.1805763,0.9747483,0.),\nvec3(-0.2138451,0.2635818,0.),\nvec3(0.109845,0.3884785,0.),\nvec3(0.06876755,-0.3581074,0.),\nvec3(0.374073,-0.7661266,0.),\nvec3(0.3079132,-0.1216763,0.),\nvec3(-0.3794335,-0.8271583,0.),\nvec3(-0.203878,-0.07715034,0.),\nvec3(0.5912697,0.1469799,0.),\nvec3(-0.88069,0.3031784,0.),\nvec3(0.5040108,0.8283722,0.),\nvec3(-0.5844124,0.5494877,0.),\nvec3(0.6017799,-0.1726654,0.),\nvec3(-0.5554981,0.1559997,0.),\nvec3(-0.3016369,-0.3900928,0.),\nvec3(-0.5550632,-0.1723762,0.),\nvec3(0.925029,0.2995041,0.),\nvec3(-0.2473137,0.5538505,0.),\nvec3(0.9183037,-0.2862392,0.),\nvec3(0.2469421,0.6718712,0.),\nvec3(0.3916397,-0.4328209,0.),\nvec3(-0.03576927,-0.6220032,0.),\nvec3(-0.04661255,0.7995201,0.),\nvec3(0.4402924,0.3640312,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.)\n);\nconst vec3 PoissonSamplers64[64]=vec3[64](\nvec3(-0.613392,0.617481,0.),\nvec3(0.170019,-0.040254,0.),\nvec3(-0.299417,0.791925,0.),\nvec3(0.645680,0.493210,0.),\nvec3(-0.651784,0.717887,0.),\nvec3(0.421003,0.027070,0.),\nvec3(-0.817194,-0.271096,0.),\nvec3(-0.705374,-0.668203,0.),\nvec3(0.977050,-0.108615,0.),\nvec3(0.063326,0.142369,0.),\nvec3(0.203528,0.214331,0.),\nvec3(-0.667531,0.326090,0.),\nvec3(-0.098422,-0.295755,0.),\nvec3(-0.885922,0.215369,0.),\nvec3(0.566637,0.605213,0.),\nvec3(0.039766,-0.396100,0.),\nvec3(0.751946,0.453352,0.),\nvec3(0.078707,-0.715323,0.),\nvec3(-0.075838,-0.529344,0.),\nvec3(0.724479,-0.580798,0.),\nvec3(0.222999,-0.215125,0.),\nvec3(-0.467574,-0.405438,0.),\nvec3(-0.248268,-0.814753,0.),\nvec3(0.354411,-0.887570,0.),\nvec3(0.175817,0.382366,0.),\nvec3(0.487472,-0.063082,0.),\nvec3(-0.084078,0.898312,0.),\nvec3(0.488876,-0.783441,0.),\nvec3(0.470016,0.217933,0.),\nvec3(-0.696890,-0.549791,0.),\nvec3(-0.149693,0.605762,0.),\nvec3(0.034211,0.979980,0.),\nvec3(0.503098,-0.308878,0.),\nvec3(-0.016205,-0.872921,0.),\nvec3(0.385784,-0.393902,0.),\nvec3(-0.146886,-0.859249,0.),\nvec3(0.643361,0.164098,0.),\nvec3(0.634388,-0.049471,0.),\nvec3(-0.688894,0.007843,0.),\nvec3(0.464034,-0.188818,0.),\nvec3(-0.440840,0.137486,0.),\nvec3(0.364483,0.511704,0.),\nvec3(0.034028,0.325968,0.),\nvec3(0.099094,-0.308023,0.),\nvec3(0.693960,-0.366253,0.),\nvec3(0.678884,-0.204688,0.),\nvec3(0.001801,0.780328,0.),\nvec3(0.145177,-0.898984,0.),\nvec3(0.062655,-0.611866,0.),\nvec3(0.315226,-0.604297,0.),\nvec3(-0.780145,0.486251,0.),\nvec3(-0.371868,0.882138,0.),\nvec3(0.200476,0.494430,0.),\nvec3(-0.494552,-0.711051,0.),\nvec3(0.612476,0.705252,0.),\nvec3(-0.578845,-0.768792,0.),\nvec3(-0.772454,-0.090976,0.),\nvec3(0.504440,0.372295,0.),\nvec3(0.155736,0.065157,0.),\nvec3(0.391522,0.849605,0.),\nvec3(-0.620106,-0.328104,0.),\nvec3(0.789239,-0.419965,0.),\nvec3(-0.545396,0.538133,0.),\nvec3(-0.178564,-0.596057,0.)\n);\n\n\n\n\n\n#define inline\nfloat computeShadowWithCSMPCSS(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,int searchTapCount,int pcfTapCount,vec3[64] poissonSamplers,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec4 uvDepthLayer=vec4(uvDepth.x,uvDepth.y,layer,uvDepth.z);\nfloat blockerDepth=0.0;\nfloat sumBlockerDepth=0.0;\nfloat numBlocker=0.0;\nfor (int i=0; i<searchTapCount; i ++) {\nblockerDepth=texture(depthSampler,vec3(uvDepth.xy+(lightSizeUV*lightSizeUVCorrection*shadowMapSizeInverse*PoissonSamplers32[i].xy),layer)).r;\nif (blockerDepth<depthMetric) {\nsumBlockerDepth+=blockerDepth;\nnumBlocker++;\n}\n}\nif (numBlocker<1.0) {\nreturn 1.0;\n}\nelse\n{\nfloat avgBlockerDepth=sumBlockerDepth/numBlocker;\n\nfloat AAOffset=shadowMapSizeInverse*10.;\n\n\nfloat penumbraRatio=((depthMetric-avgBlockerDepth)*depthCorrection+AAOffset);\nvec4 filterRadius=vec4(penumbraRatio*lightSizeUV*lightSizeUVCorrection*shadowMapSizeInverse,0.,0.);\nfloat random=getRand(vPositionFromLight.xy);\nfloat rotationAngle=random*3.1415926;\nvec2 rotationVector=vec2(cos(rotationAngle),sin(rotationAngle));\nfloat shadow=0.;\nfor (int i=0; i<pcfTapCount; i++) {\nvec4 offset=vec4(poissonSamplers[i],0.);\n\noffset=vec4(offset.x*rotationVector.x-offset.y*rotationVector.y,offset.y*rotationVector.x+offset.x*rotationVector.y,0.,0.);\nshadow+=texture2D(shadowSampler,uvDepthLayer+offset*filterRadius);\n}\nshadow/=float(pcfTapCount);\n\nshadow=mix(shadow,1.,min((depthMetric-avgBlockerDepth)*depthCorrection*penumbraDarkness,1.));\n\nshadow=mix(darkness,1.,shadow);\n\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n\n\n\n\n\n#define inline\nfloat computeShadowWithPCSS(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,int searchTapCount,int pcfTapCount,vec3[64] poissonSamplers)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nfloat blockerDepth=0.0;\nfloat sumBlockerDepth=0.0;\nfloat numBlocker=0.0;\nfor (int i=0; i<searchTapCount; i ++) {\nblockerDepth=texture(depthSampler,uvDepth.xy+(lightSizeUV*shadowMapSizeInverse*PoissonSamplers32[i].xy)).r;\nif (blockerDepth<depthMetric) {\nsumBlockerDepth+=blockerDepth;\nnumBlocker++;\n}\n}\nif (numBlocker<1.0) {\nreturn 1.0;\n}\nelse\n{\nfloat avgBlockerDepth=sumBlockerDepth/numBlocker;\n\nfloat AAOffset=shadowMapSizeInverse*10.;\n\n\nfloat penumbraRatio=((depthMetric-avgBlockerDepth)+AAOffset);\nfloat filterRadius=penumbraRatio*lightSizeUV*shadowMapSizeInverse;\nfloat random=getRand(vPositionFromLight.xy);\nfloat rotationAngle=random*3.1415926;\nvec2 rotationVector=vec2(cos(rotationAngle),sin(rotationAngle));\nfloat shadow=0.;\nfor (int i=0; i<pcfTapCount; i++) {\nvec3 offset=poissonSamplers[i];\n\noffset=vec3(offset.x*rotationVector.x-offset.y*rotationVector.y,offset.y*rotationVector.x+offset.x*rotationVector.y,0.);\nshadow+=texture2D(shadowSampler,uvDepth+offset*filterRadius);\n}\nshadow/=float(pcfTapCount);\n\nshadow=mix(shadow,1.,depthMetric-avgBlockerDepth);\n\nshadow=mix(darkness,1.,shadow);\n\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n}\n#define inline\nfloat computeShadowWithPCSS16(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{\nreturn computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,16,PoissonSamplers32);\n}\n#define inline\nfloat computeShadowWithPCSS32(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{\nreturn computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,32,PoissonSamplers32);\n}\n#define inline\nfloat computeShadowWithPCSS64(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{\nreturn computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,32,64,PoissonSamplers64);\n}\n#define inline\nfloat computeShadowWithCSMPCSS16(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nreturn computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,16,PoissonSamplers32,lightSizeUVCorrection,depthCorrection,penumbraDarkness);\n}\n#define inline\nfloat computeShadowWithCSMPCSS32(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nreturn computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,32,PoissonSamplers32,lightSizeUVCorrection,depthCorrection,penumbraDarkness);\n}\n#define inline\nfloat computeShadowWithCSMPCSS64(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nreturn computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,32,64,PoissonSamplers64,lightSizeUVCorrection,depthCorrection,penumbraDarkness);\n}\n#endif\n#endif\n";
|
|
3
|
+
var shader = "#ifdef SHADOWS\n#ifndef SHADOWFLOAT\n\nfloat unpack(vec4 color)\n{\nconst vec4 bit_shift=vec4(1.0/(255.0*255.0*255.0),1.0/(255.0*255.0),1.0/255.0,1.0);\nreturn dot(color,bit_shift);\n}\n#endif\nfloat computeFallOff(float value,vec2 clipSpace,float frustumEdgeFalloff)\n{\nfloat mask=smoothstep(1.0-frustumEdgeFalloff,1.00000012,clamp(dot(clipSpace,clipSpace),0.,1.));\nreturn mix(value,1.0,mask);\n}\n#define inline\nfloat computeShadowCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\ndepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadow=textureCube(shadowSampler,directionToLight).x;\n#endif\nreturn depth>shadow ? darkness : 1.0;\n}\n#define inline\nfloat computeShadowWithPoissonSamplingCube(vec3 lightPosition,samplerCube shadowSampler,float mapSize,float darkness,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\ndepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\nfloat visibility=1.;\nvec3 poissonDisk[4];\npoissonDisk[0]=vec3(-1.0,1.0,-1.0);\npoissonDisk[1]=vec3(1.0,-1.0,-1.0);\npoissonDisk[2]=vec3(-1.0,-1.0,-1.0);\npoissonDisk[3]=vec3(1.0,-1.0,1.0);\n\n#ifndef SHADOWFLOAT\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[0]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[1]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[2]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[3]*mapSize))<depth) visibility-=0.25;\n#else\nif (textureCube(shadowSampler,directionToLight+poissonDisk[0]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[1]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[2]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[3]*mapSize).x<depth) visibility-=0.25;\n#endif\nreturn min(1.0,visibility+darkness);\n}\n#define inline\nfloat computeShadowWithESMCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,float depthScale,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\nfloat shadowPixelDepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadowMapSample=textureCube(shadowSampler,directionToLight).x;\n#endif\nfloat esm=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness);\nreturn esm;\n}\n#define inline\nfloat computeShadowWithCloseESMCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,float depthScale,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\nfloat shadowPixelDepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadowMapSample=textureCube(shadowSampler,directionToLight).x;\n#endif\nfloat esm=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);\nreturn esm;\n}\n#ifdef WEBGL2\n#define inline\nfloat computeShadowCSM(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nvec3 uvLayer=vec3(uv.x,uv.y,layer);\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(texture2D(shadowSampler,uvLayer));\n#else\nfloat shadow=texture2D(shadowSampler,uvLayer).x;\n#endif\nreturn shadowPixelDepth>shadow ? computeFallOff(darkness,clipSpace.xy,frustumEdgeFalloff) : 1.;\n}\n#endif\n#define inline\nfloat computeShadow(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadow=texture2D(shadowSampler,uv).x;\n#endif\nreturn shadowPixelDepth>shadow ? computeFallOff(darkness,clipSpace.xy,frustumEdgeFalloff) : 1.;\n}\n}\n#define inline\nfloat computeShadowWithPoissonSampling(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float mapSize,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\nfloat visibility=1.;\nvec2 poissonDisk[4];\npoissonDisk[0]=vec2(-0.94201624,-0.39906216);\npoissonDisk[1]=vec2(0.94558609,-0.76890725);\npoissonDisk[2]=vec2(-0.094184101,-0.92938870);\npoissonDisk[3]=vec2(0.34495938,0.29387760);\n\n#ifndef SHADOWFLOAT\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[0]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[1]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[2]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[3]*mapSize))<shadowPixelDepth) visibility-=0.25;\n#else\nif (texture2D(shadowSampler,uv+poissonDisk[0]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[1]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[2]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[3]*mapSize).x<shadowPixelDepth) visibility-=0.25;\n#endif\nreturn computeFallOff(min(1.0,visibility+darkness),clipSpace.xy,frustumEdgeFalloff);\n}\n}\n#define inline\nfloat computeShadowWithESM(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float depthScale,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadowMapSample=texture2D(shadowSampler,uv).x;\n#endif\nfloat esm=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness);\nreturn computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n#define inline\nfloat computeShadowWithCloseESM(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float depthScale,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadowMapSample=texture2D(shadowSampler,uv).x;\n#endif\nfloat esm=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);\nreturn computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n#ifdef WEBGL2\n#define GREATEST_LESS_THAN_ONE 0.99999994\n\n#define inline\nfloat computeShadowWithCSMPCF1(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArrayShadow shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec4 uvDepthLayer=vec4(uvDepth.x,uvDepth.y,layer,uvDepth.z);\nfloat shadow=texture(shadowSampler,uvDepthLayer);\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n\n\n\n#define inline\nfloat computeShadowWithCSMPCF3(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArrayShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\n\n\nvec2 uvw0=3.-2.*st;\nvec2 uvw1=1.+2.*st;\nvec2 u=vec2((2.-st.x)/uvw0.x-1.,st.x/uvw1.x+1.)*shadowMapSizeAndInverse.y;\nvec2 v=vec2((2.-st.y)/uvw0.y-1.,st.y/uvw1.y+1.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[0]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[0]),layer,uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[1]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[1]),layer,uvDepth.z));\nshadow=shadow/16.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n\n\n\n#define inline\nfloat computeShadowWithCSMPCF5(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArrayShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\nvec2 uvw0=4.-3.*st;\nvec2 uvw1=vec2(7.);\nvec2 uvw2=1.+3.*st;\nvec3 u=vec3((3.-2.*st.x)/uvw0.x-2.,(3.+st.x)/uvw1.x,st.x/uvw2.x+2.)*shadowMapSizeAndInverse.y;\nvec3 v=vec3((3.-2.*st.y)/uvw0.y-2.,(3.+st.y)/uvw1.y,st.y/uvw2.y+2.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[0]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[0]),layer,uvDepth.z));\nshadow+=uvw2.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[2],v[0]),layer,uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[1]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[1]),layer,uvDepth.z));\nshadow+=uvw2.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[2],v[1]),layer,uvDepth.z));\nshadow+=uvw0.x*uvw2.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[2]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw2.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[2]),layer,uvDepth.z));\nshadow+=uvw2.x*uvw2.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[2],v[2]),layer,uvDepth.z));\nshadow=shadow/144.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n\n#define inline\nfloat computeShadowWithPCF1(vec4 vPositionFromLight,float depthMetric,highp sampler2DShadow shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nfloat shadow=texture2D(shadowSampler,uvDepth);\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n\n\n\n#define inline\nfloat computeShadowWithPCF3(vec4 vPositionFromLight,float depthMetric,highp sampler2DShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\n\n\nvec2 uvw0=3.-2.*st;\nvec2 uvw1=1.+2.*st;\nvec2 u=vec2((2.-st.x)/uvw0.x-1.,st.x/uvw1.x+1.)*shadowMapSizeAndInverse.y;\nvec2 v=vec2((2.-st.y)/uvw0.y-1.,st.y/uvw1.y+1.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[0]),uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[0]),uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[1]),uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[1]),uvDepth.z));\nshadow=shadow/16.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n\n\n\n#define inline\nfloat computeShadowWithPCF5(vec4 vPositionFromLight,float depthMetric,highp sampler2DShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\nvec2 uvw0=4.-3.*st;\nvec2 uvw1=vec2(7.);\nvec2 uvw2=1.+3.*st;\nvec3 u=vec3((3.-2.*st.x)/uvw0.x-2.,(3.+st.x)/uvw1.x,st.x/uvw2.x+2.)*shadowMapSizeAndInverse.y;\nvec3 v=vec3((3.-2.*st.y)/uvw0.y-2.,(3.+st.y)/uvw1.y,st.y/uvw2.y+2.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[0]),uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[0]),uvDepth.z));\nshadow+=uvw2.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[0]),uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[1]),uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[1]),uvDepth.z));\nshadow+=uvw2.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[1]),uvDepth.z));\nshadow+=uvw0.x*uvw2.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[2]),uvDepth.z));\nshadow+=uvw1.x*uvw2.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[2]),uvDepth.z));\nshadow+=uvw2.x*uvw2.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[2]),uvDepth.z));\nshadow=shadow/144.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\nconst vec3 PoissonSamplers32[64]=vec3[64](\nvec3(0.06407013,0.05409927,0.),\nvec3(0.7366577,0.5789394,0.),\nvec3(-0.6270542,-0.5320278,0.),\nvec3(-0.4096107,0.8411095,0.),\nvec3(0.6849564,-0.4990818,0.),\nvec3(-0.874181,-0.04579735,0.),\nvec3(0.9989998,0.0009880066,0.),\nvec3(-0.004920578,-0.9151649,0.),\nvec3(0.1805763,0.9747483,0.),\nvec3(-0.2138451,0.2635818,0.),\nvec3(0.109845,0.3884785,0.),\nvec3(0.06876755,-0.3581074,0.),\nvec3(0.374073,-0.7661266,0.),\nvec3(0.3079132,-0.1216763,0.),\nvec3(-0.3794335,-0.8271583,0.),\nvec3(-0.203878,-0.07715034,0.),\nvec3(0.5912697,0.1469799,0.),\nvec3(-0.88069,0.3031784,0.),\nvec3(0.5040108,0.8283722,0.),\nvec3(-0.5844124,0.5494877,0.),\nvec3(0.6017799,-0.1726654,0.),\nvec3(-0.5554981,0.1559997,0.),\nvec3(-0.3016369,-0.3900928,0.),\nvec3(-0.5550632,-0.1723762,0.),\nvec3(0.925029,0.2995041,0.),\nvec3(-0.2473137,0.5538505,0.),\nvec3(0.9183037,-0.2862392,0.),\nvec3(0.2469421,0.6718712,0.),\nvec3(0.3916397,-0.4328209,0.),\nvec3(-0.03576927,-0.6220032,0.),\nvec3(-0.04661255,0.7995201,0.),\nvec3(0.4402924,0.3640312,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.)\n);\nconst vec3 PoissonSamplers64[64]=vec3[64](\nvec3(-0.613392,0.617481,0.),\nvec3(0.170019,-0.040254,0.),\nvec3(-0.299417,0.791925,0.),\nvec3(0.645680,0.493210,0.),\nvec3(-0.651784,0.717887,0.),\nvec3(0.421003,0.027070,0.),\nvec3(-0.817194,-0.271096,0.),\nvec3(-0.705374,-0.668203,0.),\nvec3(0.977050,-0.108615,0.),\nvec3(0.063326,0.142369,0.),\nvec3(0.203528,0.214331,0.),\nvec3(-0.667531,0.326090,0.),\nvec3(-0.098422,-0.295755,0.),\nvec3(-0.885922,0.215369,0.),\nvec3(0.566637,0.605213,0.),\nvec3(0.039766,-0.396100,0.),\nvec3(0.751946,0.453352,0.),\nvec3(0.078707,-0.715323,0.),\nvec3(-0.075838,-0.529344,0.),\nvec3(0.724479,-0.580798,0.),\nvec3(0.222999,-0.215125,0.),\nvec3(-0.467574,-0.405438,0.),\nvec3(-0.248268,-0.814753,0.),\nvec3(0.354411,-0.887570,0.),\nvec3(0.175817,0.382366,0.),\nvec3(0.487472,-0.063082,0.),\nvec3(-0.084078,0.898312,0.),\nvec3(0.488876,-0.783441,0.),\nvec3(0.470016,0.217933,0.),\nvec3(-0.696890,-0.549791,0.),\nvec3(-0.149693,0.605762,0.),\nvec3(0.034211,0.979980,0.),\nvec3(0.503098,-0.308878,0.),\nvec3(-0.016205,-0.872921,0.),\nvec3(0.385784,-0.393902,0.),\nvec3(-0.146886,-0.859249,0.),\nvec3(0.643361,0.164098,0.),\nvec3(0.634388,-0.049471,0.),\nvec3(-0.688894,0.007843,0.),\nvec3(0.464034,-0.188818,0.),\nvec3(-0.440840,0.137486,0.),\nvec3(0.364483,0.511704,0.),\nvec3(0.034028,0.325968,0.),\nvec3(0.099094,-0.308023,0.),\nvec3(0.693960,-0.366253,0.),\nvec3(0.678884,-0.204688,0.),\nvec3(0.001801,0.780328,0.),\nvec3(0.145177,-0.898984,0.),\nvec3(0.062655,-0.611866,0.),\nvec3(0.315226,-0.604297,0.),\nvec3(-0.780145,0.486251,0.),\nvec3(-0.371868,0.882138,0.),\nvec3(0.200476,0.494430,0.),\nvec3(-0.494552,-0.711051,0.),\nvec3(0.612476,0.705252,0.),\nvec3(-0.578845,-0.768792,0.),\nvec3(-0.772454,-0.090976,0.),\nvec3(0.504440,0.372295,0.),\nvec3(0.155736,0.065157,0.),\nvec3(0.391522,0.849605,0.),\nvec3(-0.620106,-0.328104,0.),\nvec3(0.789239,-0.419965,0.),\nvec3(-0.545396,0.538133,0.),\nvec3(-0.178564,-0.596057,0.)\n);\n\n\n\n\n\n#define inline\nfloat computeShadowWithCSMPCSS(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,int searchTapCount,int pcfTapCount,vec3[64] poissonSamplers,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec4 uvDepthLayer=vec4(uvDepth.x,uvDepth.y,layer,uvDepth.z);\nfloat blockerDepth=0.0;\nfloat sumBlockerDepth=0.0;\nfloat numBlocker=0.0;\nfor (int i=0; i<searchTapCount; i ++) {\nblockerDepth=texture(depthSampler,vec3(uvDepth.xy+(lightSizeUV*lightSizeUVCorrection*shadowMapSizeInverse*PoissonSamplers32[i].xy),layer)).r;\nif (blockerDepth<depthMetric) {\nsumBlockerDepth+=blockerDepth;\nnumBlocker++;\n}\n}\nif (numBlocker<1.0) {\nreturn 1.0;\n}\nelse\n{\nfloat avgBlockerDepth=sumBlockerDepth/numBlocker;\n\nfloat AAOffset=shadowMapSizeInverse*10.;\n\n\nfloat penumbraRatio=((depthMetric-avgBlockerDepth)*depthCorrection+AAOffset);\nvec4 filterRadius=vec4(penumbraRatio*lightSizeUV*lightSizeUVCorrection*shadowMapSizeInverse,0.,0.);\nfloat random=getRand(vPositionFromLight.xy);\nfloat rotationAngle=random*3.1415926;\nvec2 rotationVector=vec2(cos(rotationAngle),sin(rotationAngle));\nfloat shadow=0.;\nfor (int i=0; i<pcfTapCount; i++) {\nvec4 offset=vec4(poissonSamplers[i],0.);\n\noffset=vec4(offset.x*rotationVector.x-offset.y*rotationVector.y,offset.y*rotationVector.x+offset.x*rotationVector.y,0.,0.);\nshadow+=texture2D(shadowSampler,uvDepthLayer+offset*filterRadius);\n}\nshadow/=float(pcfTapCount);\n\nshadow=mix(shadow,1.,min((depthMetric-avgBlockerDepth)*depthCorrection*penumbraDarkness,1.));\n\nshadow=mix(darkness,1.,shadow);\n\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n\n\n\n\n\n#define inline\nfloat computeShadowWithPCSS(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,highp sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,int searchTapCount,int pcfTapCount,vec3[64] poissonSamplers)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nfloat blockerDepth=0.0;\nfloat sumBlockerDepth=0.0;\nfloat numBlocker=0.0;\nfor (int i=0; i<searchTapCount; i ++) {\nblockerDepth=texture(depthSampler,uvDepth.xy+(lightSizeUV*shadowMapSizeInverse*PoissonSamplers32[i].xy)).r;\nif (blockerDepth<depthMetric) {\nsumBlockerDepth+=blockerDepth;\nnumBlocker++;\n}\n}\nif (numBlocker<1.0) {\nreturn 1.0;\n}\nelse\n{\nfloat avgBlockerDepth=sumBlockerDepth/numBlocker;\n\nfloat AAOffset=shadowMapSizeInverse*10.;\n\n\nfloat penumbraRatio=((depthMetric-avgBlockerDepth)+AAOffset);\nfloat filterRadius=penumbraRatio*lightSizeUV*shadowMapSizeInverse;\nfloat random=getRand(vPositionFromLight.xy);\nfloat rotationAngle=random*3.1415926;\nvec2 rotationVector=vec2(cos(rotationAngle),sin(rotationAngle));\nfloat shadow=0.;\nfor (int i=0; i<pcfTapCount; i++) {\nvec3 offset=poissonSamplers[i];\n\noffset=vec3(offset.x*rotationVector.x-offset.y*rotationVector.y,offset.y*rotationVector.x+offset.x*rotationVector.y,0.);\nshadow+=texture2D(shadowSampler,uvDepth+offset*filterRadius);\n}\nshadow/=float(pcfTapCount);\n\nshadow=mix(shadow,1.,depthMetric-avgBlockerDepth);\n\nshadow=mix(darkness,1.,shadow);\n\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n}\n#define inline\nfloat computeShadowWithPCSS16(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,highp sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{\nreturn computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,16,PoissonSamplers32);\n}\n#define inline\nfloat computeShadowWithPCSS32(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,highp sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{\nreturn computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,32,PoissonSamplers32);\n}\n#define inline\nfloat computeShadowWithPCSS64(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,highp sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{\nreturn computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,32,64,PoissonSamplers64);\n}\n#define inline\nfloat computeShadowWithCSMPCSS16(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nreturn computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,16,PoissonSamplers32,lightSizeUVCorrection,depthCorrection,penumbraDarkness);\n}\n#define inline\nfloat computeShadowWithCSMPCSS32(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nreturn computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,32,PoissonSamplers32,lightSizeUVCorrection,depthCorrection,penumbraDarkness);\n}\n#define inline\nfloat computeShadowWithCSMPCSS64(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nreturn computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,32,64,PoissonSamplers64,lightSizeUVCorrection,depthCorrection,penumbraDarkness);\n}\n#endif\n#endif\n";
|
|
4
4
|
Effect.IncludesShadersStore[name] = shader;
|
|
5
5
|
/** @hidden */
|
|
6
6
|
export var shadowsFragmentFunctions = { name: name, shader: shader };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadowsFragmentFunctions.js","sourceRoot":"","sources":["../../../../sourceES6/core/Shaders/ShadersInclude/shadowsFragmentFunctions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,IAAI,IAAI,GAAG,0BAA0B,CAAC;AACtC,IAAI,MAAM,GAAG,o5xBA0oBZ,CAAC;AAEF,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AAC3C,cAAc;AACd,MAAM,CAAC,IAAI,wBAAwB,GAAG,EAAE,IAAI,MAAA,EAAE,MAAM,QAAA,EAAE,CAAC","sourcesContent":["import { Effect } from \"../../Materials/effect\";\n\nlet name = 'shadowsFragmentFunctions';\nlet shader = `#ifdef SHADOWS\n#ifndef SHADOWFLOAT\n\nfloat unpack(vec4 color)\n{\nconst vec4 bit_shift=vec4(1.0/(255.0*255.0*255.0),1.0/(255.0*255.0),1.0/255.0,1.0);\nreturn dot(color,bit_shift);\n}\n#endif\nfloat computeFallOff(float value,vec2 clipSpace,float frustumEdgeFalloff)\n{\nfloat mask=smoothstep(1.0-frustumEdgeFalloff,1.00000012,clamp(dot(clipSpace,clipSpace),0.,1.));\nreturn mix(value,1.0,mask);\n}\n#define inline\nfloat computeShadowCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\ndepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadow=textureCube(shadowSampler,directionToLight).x;\n#endif\nreturn depth>shadow ? darkness : 1.0;\n}\n#define inline\nfloat computeShadowWithPoissonSamplingCube(vec3 lightPosition,samplerCube shadowSampler,float mapSize,float darkness,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\ndepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\nfloat visibility=1.;\nvec3 poissonDisk[4];\npoissonDisk[0]=vec3(-1.0,1.0,-1.0);\npoissonDisk[1]=vec3(1.0,-1.0,-1.0);\npoissonDisk[2]=vec3(-1.0,-1.0,-1.0);\npoissonDisk[3]=vec3(1.0,-1.0,1.0);\n\n#ifndef SHADOWFLOAT\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[0]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[1]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[2]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[3]*mapSize))<depth) visibility-=0.25;\n#else\nif (textureCube(shadowSampler,directionToLight+poissonDisk[0]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[1]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[2]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[3]*mapSize).x<depth) visibility-=0.25;\n#endif\nreturn min(1.0,visibility+darkness);\n}\n#define inline\nfloat computeShadowWithESMCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,float depthScale,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\nfloat shadowPixelDepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadowMapSample=textureCube(shadowSampler,directionToLight).x;\n#endif\nfloat esm=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness);\nreturn esm;\n}\n#define inline\nfloat computeShadowWithCloseESMCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,float depthScale,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\nfloat shadowPixelDepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadowMapSample=textureCube(shadowSampler,directionToLight).x;\n#endif\nfloat esm=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);\nreturn esm;\n}\n#ifdef WEBGL2\n#define inline\nfloat computeShadowCSM(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nvec3 uvLayer=vec3(uv.x,uv.y,layer);\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(texture2D(shadowSampler,uvLayer));\n#else\nfloat shadow=texture2D(shadowSampler,uvLayer).x;\n#endif\nreturn shadowPixelDepth>shadow ? computeFallOff(darkness,clipSpace.xy,frustumEdgeFalloff) : 1.;\n}\n#endif\n#define inline\nfloat computeShadow(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadow=texture2D(shadowSampler,uv).x;\n#endif\nreturn shadowPixelDepth>shadow ? computeFallOff(darkness,clipSpace.xy,frustumEdgeFalloff) : 1.;\n}\n}\n#define inline\nfloat computeShadowWithPoissonSampling(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float mapSize,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\nfloat visibility=1.;\nvec2 poissonDisk[4];\npoissonDisk[0]=vec2(-0.94201624,-0.39906216);\npoissonDisk[1]=vec2(0.94558609,-0.76890725);\npoissonDisk[2]=vec2(-0.094184101,-0.92938870);\npoissonDisk[3]=vec2(0.34495938,0.29387760);\n\n#ifndef SHADOWFLOAT\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[0]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[1]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[2]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[3]*mapSize))<shadowPixelDepth) visibility-=0.25;\n#else\nif (texture2D(shadowSampler,uv+poissonDisk[0]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[1]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[2]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[3]*mapSize).x<shadowPixelDepth) visibility-=0.25;\n#endif\nreturn computeFallOff(min(1.0,visibility+darkness),clipSpace.xy,frustumEdgeFalloff);\n}\n}\n#define inline\nfloat computeShadowWithESM(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float depthScale,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadowMapSample=texture2D(shadowSampler,uv).x;\n#endif\nfloat esm=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness);\nreturn computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n#define inline\nfloat computeShadowWithCloseESM(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float depthScale,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadowMapSample=texture2D(shadowSampler,uv).x;\n#endif\nfloat esm=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);\nreturn computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n#ifdef WEBGL2\n#define GREATEST_LESS_THAN_ONE 0.99999994\n\n#define inline\nfloat computeShadowWithCSMPCF1(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArrayShadow shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec4 uvDepthLayer=vec4(uvDepth.x,uvDepth.y,layer,uvDepth.z);\nfloat shadow=texture(shadowSampler,uvDepthLayer);\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n\n\n\n#define inline\nfloat computeShadowWithCSMPCF3(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArrayShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\n\n\nvec2 uvw0=3.-2.*st;\nvec2 uvw1=1.+2.*st;\nvec2 u=vec2((2.-st.x)/uvw0.x-1.,st.x/uvw1.x+1.)*shadowMapSizeAndInverse.y;\nvec2 v=vec2((2.-st.y)/uvw0.y-1.,st.y/uvw1.y+1.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[0]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[0]),layer,uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[1]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[1]),layer,uvDepth.z));\nshadow=shadow/16.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n\n\n\n#define inline\nfloat computeShadowWithCSMPCF5(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArrayShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\nvec2 uvw0=4.-3.*st;\nvec2 uvw1=vec2(7.);\nvec2 uvw2=1.+3.*st;\nvec3 u=vec3((3.-2.*st.x)/uvw0.x-2.,(3.+st.x)/uvw1.x,st.x/uvw2.x+2.)*shadowMapSizeAndInverse.y;\nvec3 v=vec3((3.-2.*st.y)/uvw0.y-2.,(3.+st.y)/uvw1.y,st.y/uvw2.y+2.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[0]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[0]),layer,uvDepth.z));\nshadow+=uvw2.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[2],v[0]),layer,uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[1]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[1]),layer,uvDepth.z));\nshadow+=uvw2.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[2],v[1]),layer,uvDepth.z));\nshadow+=uvw0.x*uvw2.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[2]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw2.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[2]),layer,uvDepth.z));\nshadow+=uvw2.x*uvw2.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[2],v[2]),layer,uvDepth.z));\nshadow=shadow/144.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n\n#define inline\nfloat computeShadowWithPCF1(vec4 vPositionFromLight,float depthMetric,sampler2DShadow shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nfloat shadow=texture2D(shadowSampler,uvDepth);\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n\n\n\n#define inline\nfloat computeShadowWithPCF3(vec4 vPositionFromLight,float depthMetric,sampler2DShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\n\n\nvec2 uvw0=3.-2.*st;\nvec2 uvw1=1.+2.*st;\nvec2 u=vec2((2.-st.x)/uvw0.x-1.,st.x/uvw1.x+1.)*shadowMapSizeAndInverse.y;\nvec2 v=vec2((2.-st.y)/uvw0.y-1.,st.y/uvw1.y+1.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[0]),uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[0]),uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[1]),uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[1]),uvDepth.z));\nshadow=shadow/16.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n\n\n\n#define inline\nfloat computeShadowWithPCF5(vec4 vPositionFromLight,float depthMetric,sampler2DShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\nvec2 uvw0=4.-3.*st;\nvec2 uvw1=vec2(7.);\nvec2 uvw2=1.+3.*st;\nvec3 u=vec3((3.-2.*st.x)/uvw0.x-2.,(3.+st.x)/uvw1.x,st.x/uvw2.x+2.)*shadowMapSizeAndInverse.y;\nvec3 v=vec3((3.-2.*st.y)/uvw0.y-2.,(3.+st.y)/uvw1.y,st.y/uvw2.y+2.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[0]),uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[0]),uvDepth.z));\nshadow+=uvw2.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[0]),uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[1]),uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[1]),uvDepth.z));\nshadow+=uvw2.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[1]),uvDepth.z));\nshadow+=uvw0.x*uvw2.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[2]),uvDepth.z));\nshadow+=uvw1.x*uvw2.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[2]),uvDepth.z));\nshadow+=uvw2.x*uvw2.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[2]),uvDepth.z));\nshadow=shadow/144.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\nconst vec3 PoissonSamplers32[64]=vec3[64](\nvec3(0.06407013,0.05409927,0.),\nvec3(0.7366577,0.5789394,0.),\nvec3(-0.6270542,-0.5320278,0.),\nvec3(-0.4096107,0.8411095,0.),\nvec3(0.6849564,-0.4990818,0.),\nvec3(-0.874181,-0.04579735,0.),\nvec3(0.9989998,0.0009880066,0.),\nvec3(-0.004920578,-0.9151649,0.),\nvec3(0.1805763,0.9747483,0.),\nvec3(-0.2138451,0.2635818,0.),\nvec3(0.109845,0.3884785,0.),\nvec3(0.06876755,-0.3581074,0.),\nvec3(0.374073,-0.7661266,0.),\nvec3(0.3079132,-0.1216763,0.),\nvec3(-0.3794335,-0.8271583,0.),\nvec3(-0.203878,-0.07715034,0.),\nvec3(0.5912697,0.1469799,0.),\nvec3(-0.88069,0.3031784,0.),\nvec3(0.5040108,0.8283722,0.),\nvec3(-0.5844124,0.5494877,0.),\nvec3(0.6017799,-0.1726654,0.),\nvec3(-0.5554981,0.1559997,0.),\nvec3(-0.3016369,-0.3900928,0.),\nvec3(-0.5550632,-0.1723762,0.),\nvec3(0.925029,0.2995041,0.),\nvec3(-0.2473137,0.5538505,0.),\nvec3(0.9183037,-0.2862392,0.),\nvec3(0.2469421,0.6718712,0.),\nvec3(0.3916397,-0.4328209,0.),\nvec3(-0.03576927,-0.6220032,0.),\nvec3(-0.04661255,0.7995201,0.),\nvec3(0.4402924,0.3640312,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.)\n);\nconst vec3 PoissonSamplers64[64]=vec3[64](\nvec3(-0.613392,0.617481,0.),\nvec3(0.170019,-0.040254,0.),\nvec3(-0.299417,0.791925,0.),\nvec3(0.645680,0.493210,0.),\nvec3(-0.651784,0.717887,0.),\nvec3(0.421003,0.027070,0.),\nvec3(-0.817194,-0.271096,0.),\nvec3(-0.705374,-0.668203,0.),\nvec3(0.977050,-0.108615,0.),\nvec3(0.063326,0.142369,0.),\nvec3(0.203528,0.214331,0.),\nvec3(-0.667531,0.326090,0.),\nvec3(-0.098422,-0.295755,0.),\nvec3(-0.885922,0.215369,0.),\nvec3(0.566637,0.605213,0.),\nvec3(0.039766,-0.396100,0.),\nvec3(0.751946,0.453352,0.),\nvec3(0.078707,-0.715323,0.),\nvec3(-0.075838,-0.529344,0.),\nvec3(0.724479,-0.580798,0.),\nvec3(0.222999,-0.215125,0.),\nvec3(-0.467574,-0.405438,0.),\nvec3(-0.248268,-0.814753,0.),\nvec3(0.354411,-0.887570,0.),\nvec3(0.175817,0.382366,0.),\nvec3(0.487472,-0.063082,0.),\nvec3(-0.084078,0.898312,0.),\nvec3(0.488876,-0.783441,0.),\nvec3(0.470016,0.217933,0.),\nvec3(-0.696890,-0.549791,0.),\nvec3(-0.149693,0.605762,0.),\nvec3(0.034211,0.979980,0.),\nvec3(0.503098,-0.308878,0.),\nvec3(-0.016205,-0.872921,0.),\nvec3(0.385784,-0.393902,0.),\nvec3(-0.146886,-0.859249,0.),\nvec3(0.643361,0.164098,0.),\nvec3(0.634388,-0.049471,0.),\nvec3(-0.688894,0.007843,0.),\nvec3(0.464034,-0.188818,0.),\nvec3(-0.440840,0.137486,0.),\nvec3(0.364483,0.511704,0.),\nvec3(0.034028,0.325968,0.),\nvec3(0.099094,-0.308023,0.),\nvec3(0.693960,-0.366253,0.),\nvec3(0.678884,-0.204688,0.),\nvec3(0.001801,0.780328,0.),\nvec3(0.145177,-0.898984,0.),\nvec3(0.062655,-0.611866,0.),\nvec3(0.315226,-0.604297,0.),\nvec3(-0.780145,0.486251,0.),\nvec3(-0.371868,0.882138,0.),\nvec3(0.200476,0.494430,0.),\nvec3(-0.494552,-0.711051,0.),\nvec3(0.612476,0.705252,0.),\nvec3(-0.578845,-0.768792,0.),\nvec3(-0.772454,-0.090976,0.),\nvec3(0.504440,0.372295,0.),\nvec3(0.155736,0.065157,0.),\nvec3(0.391522,0.849605,0.),\nvec3(-0.620106,-0.328104,0.),\nvec3(0.789239,-0.419965,0.),\nvec3(-0.545396,0.538133,0.),\nvec3(-0.178564,-0.596057,0.)\n);\n\n\n\n\n\n#define inline\nfloat computeShadowWithCSMPCSS(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,int searchTapCount,int pcfTapCount,vec3[64] poissonSamplers,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec4 uvDepthLayer=vec4(uvDepth.x,uvDepth.y,layer,uvDepth.z);\nfloat blockerDepth=0.0;\nfloat sumBlockerDepth=0.0;\nfloat numBlocker=0.0;\nfor (int i=0; i<searchTapCount; i ++) {\nblockerDepth=texture(depthSampler,vec3(uvDepth.xy+(lightSizeUV*lightSizeUVCorrection*shadowMapSizeInverse*PoissonSamplers32[i].xy),layer)).r;\nif (blockerDepth<depthMetric) {\nsumBlockerDepth+=blockerDepth;\nnumBlocker++;\n}\n}\nif (numBlocker<1.0) {\nreturn 1.0;\n}\nelse\n{\nfloat avgBlockerDepth=sumBlockerDepth/numBlocker;\n\nfloat AAOffset=shadowMapSizeInverse*10.;\n\n\nfloat penumbraRatio=((depthMetric-avgBlockerDepth)*depthCorrection+AAOffset);\nvec4 filterRadius=vec4(penumbraRatio*lightSizeUV*lightSizeUVCorrection*shadowMapSizeInverse,0.,0.);\nfloat random=getRand(vPositionFromLight.xy);\nfloat rotationAngle=random*3.1415926;\nvec2 rotationVector=vec2(cos(rotationAngle),sin(rotationAngle));\nfloat shadow=0.;\nfor (int i=0; i<pcfTapCount; i++) {\nvec4 offset=vec4(poissonSamplers[i],0.);\n\noffset=vec4(offset.x*rotationVector.x-offset.y*rotationVector.y,offset.y*rotationVector.x+offset.x*rotationVector.y,0.,0.);\nshadow+=texture2D(shadowSampler,uvDepthLayer+offset*filterRadius);\n}\nshadow/=float(pcfTapCount);\n\nshadow=mix(shadow,1.,min((depthMetric-avgBlockerDepth)*depthCorrection*penumbraDarkness,1.));\n\nshadow=mix(darkness,1.,shadow);\n\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n\n\n\n\n\n#define inline\nfloat computeShadowWithPCSS(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,int searchTapCount,int pcfTapCount,vec3[64] poissonSamplers)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nfloat blockerDepth=0.0;\nfloat sumBlockerDepth=0.0;\nfloat numBlocker=0.0;\nfor (int i=0; i<searchTapCount; i ++) {\nblockerDepth=texture(depthSampler,uvDepth.xy+(lightSizeUV*shadowMapSizeInverse*PoissonSamplers32[i].xy)).r;\nif (blockerDepth<depthMetric) {\nsumBlockerDepth+=blockerDepth;\nnumBlocker++;\n}\n}\nif (numBlocker<1.0) {\nreturn 1.0;\n}\nelse\n{\nfloat avgBlockerDepth=sumBlockerDepth/numBlocker;\n\nfloat AAOffset=shadowMapSizeInverse*10.;\n\n\nfloat penumbraRatio=((depthMetric-avgBlockerDepth)+AAOffset);\nfloat filterRadius=penumbraRatio*lightSizeUV*shadowMapSizeInverse;\nfloat random=getRand(vPositionFromLight.xy);\nfloat rotationAngle=random*3.1415926;\nvec2 rotationVector=vec2(cos(rotationAngle),sin(rotationAngle));\nfloat shadow=0.;\nfor (int i=0; i<pcfTapCount; i++) {\nvec3 offset=poissonSamplers[i];\n\noffset=vec3(offset.x*rotationVector.x-offset.y*rotationVector.y,offset.y*rotationVector.x+offset.x*rotationVector.y,0.);\nshadow+=texture2D(shadowSampler,uvDepth+offset*filterRadius);\n}\nshadow/=float(pcfTapCount);\n\nshadow=mix(shadow,1.,depthMetric-avgBlockerDepth);\n\nshadow=mix(darkness,1.,shadow);\n\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n}\n#define inline\nfloat computeShadowWithPCSS16(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{\nreturn computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,16,PoissonSamplers32);\n}\n#define inline\nfloat computeShadowWithPCSS32(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{\nreturn computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,32,PoissonSamplers32);\n}\n#define inline\nfloat computeShadowWithPCSS64(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{\nreturn computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,32,64,PoissonSamplers64);\n}\n#define inline\nfloat computeShadowWithCSMPCSS16(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nreturn computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,16,PoissonSamplers32,lightSizeUVCorrection,depthCorrection,penumbraDarkness);\n}\n#define inline\nfloat computeShadowWithCSMPCSS32(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nreturn computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,32,PoissonSamplers32,lightSizeUVCorrection,depthCorrection,penumbraDarkness);\n}\n#define inline\nfloat computeShadowWithCSMPCSS64(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nreturn computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,32,64,PoissonSamplers64,lightSizeUVCorrection,depthCorrection,penumbraDarkness);\n}\n#endif\n#endif\n`;\n\nEffect.IncludesShadersStore[name] = shader;\n/** @hidden */\nexport var shadowsFragmentFunctions = { name, shader };\n"]}
|
|
1
|
+
{"version":3,"file":"shadowsFragmentFunctions.js","sourceRoot":"","sources":["../../../../sourceES6/core/Shaders/ShadersInclude/shadowsFragmentFunctions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,IAAI,IAAI,GAAG,0BAA0B,CAAC;AACtC,IAAI,MAAM,GAAG,87xBA0oBZ,CAAC;AAEF,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;AAC3C,cAAc;AACd,MAAM,CAAC,IAAI,wBAAwB,GAAG,EAAE,IAAI,MAAA,EAAE,MAAM,QAAA,EAAE,CAAC","sourcesContent":["import { Effect } from \"../../Materials/effect\";\n\nlet name = 'shadowsFragmentFunctions';\nlet shader = `#ifdef SHADOWS\n#ifndef SHADOWFLOAT\n\nfloat unpack(vec4 color)\n{\nconst vec4 bit_shift=vec4(1.0/(255.0*255.0*255.0),1.0/(255.0*255.0),1.0/255.0,1.0);\nreturn dot(color,bit_shift);\n}\n#endif\nfloat computeFallOff(float value,vec2 clipSpace,float frustumEdgeFalloff)\n{\nfloat mask=smoothstep(1.0-frustumEdgeFalloff,1.00000012,clamp(dot(clipSpace,clipSpace),0.,1.));\nreturn mix(value,1.0,mask);\n}\n#define inline\nfloat computeShadowCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\ndepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadow=textureCube(shadowSampler,directionToLight).x;\n#endif\nreturn depth>shadow ? darkness : 1.0;\n}\n#define inline\nfloat computeShadowWithPoissonSamplingCube(vec3 lightPosition,samplerCube shadowSampler,float mapSize,float darkness,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\ndepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\nfloat visibility=1.;\nvec3 poissonDisk[4];\npoissonDisk[0]=vec3(-1.0,1.0,-1.0);\npoissonDisk[1]=vec3(1.0,-1.0,-1.0);\npoissonDisk[2]=vec3(-1.0,-1.0,-1.0);\npoissonDisk[3]=vec3(1.0,-1.0,1.0);\n\n#ifndef SHADOWFLOAT\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[0]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[1]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[2]*mapSize))<depth) visibility-=0.25;\nif (unpack(textureCube(shadowSampler,directionToLight+poissonDisk[3]*mapSize))<depth) visibility-=0.25;\n#else\nif (textureCube(shadowSampler,directionToLight+poissonDisk[0]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[1]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[2]*mapSize).x<depth) visibility-=0.25;\nif (textureCube(shadowSampler,directionToLight+poissonDisk[3]*mapSize).x<depth) visibility-=0.25;\n#endif\nreturn min(1.0,visibility+darkness);\n}\n#define inline\nfloat computeShadowWithESMCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,float depthScale,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\nfloat shadowPixelDepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadowMapSample=textureCube(shadowSampler,directionToLight).x;\n#endif\nfloat esm=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness);\nreturn esm;\n}\n#define inline\nfloat computeShadowWithCloseESMCube(vec3 lightPosition,samplerCube shadowSampler,float darkness,float depthScale,vec2 depthValues)\n{\nvec3 directionToLight=vPositionW-lightPosition;\nfloat depth=length(directionToLight);\ndepth=(depth+depthValues.x)/(depthValues.y);\nfloat shadowPixelDepth=clamp(depth,0.,1.0);\ndirectionToLight=normalize(directionToLight);\ndirectionToLight.y=-directionToLight.y;\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(textureCube(shadowSampler,directionToLight));\n#else\nfloat shadowMapSample=textureCube(shadowSampler,directionToLight).x;\n#endif\nfloat esm=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);\nreturn esm;\n}\n#ifdef WEBGL2\n#define inline\nfloat computeShadowCSM(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nvec3 uvLayer=vec3(uv.x,uv.y,layer);\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(texture2D(shadowSampler,uvLayer));\n#else\nfloat shadow=texture2D(shadowSampler,uvLayer).x;\n#endif\nreturn shadowPixelDepth>shadow ? computeFallOff(darkness,clipSpace.xy,frustumEdgeFalloff) : 1.;\n}\n#endif\n#define inline\nfloat computeShadow(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadow=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadow=texture2D(shadowSampler,uv).x;\n#endif\nreturn shadowPixelDepth>shadow ? computeFallOff(darkness,clipSpace.xy,frustumEdgeFalloff) : 1.;\n}\n}\n#define inline\nfloat computeShadowWithPoissonSampling(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float mapSize,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\nfloat visibility=1.;\nvec2 poissonDisk[4];\npoissonDisk[0]=vec2(-0.94201624,-0.39906216);\npoissonDisk[1]=vec2(0.94558609,-0.76890725);\npoissonDisk[2]=vec2(-0.094184101,-0.92938870);\npoissonDisk[3]=vec2(0.34495938,0.29387760);\n\n#ifndef SHADOWFLOAT\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[0]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[1]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[2]*mapSize))<shadowPixelDepth) visibility-=0.25;\nif (unpack(texture2D(shadowSampler,uv+poissonDisk[3]*mapSize))<shadowPixelDepth) visibility-=0.25;\n#else\nif (texture2D(shadowSampler,uv+poissonDisk[0]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[1]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[2]*mapSize).x<shadowPixelDepth) visibility-=0.25;\nif (texture2D(shadowSampler,uv+poissonDisk[3]*mapSize).x<shadowPixelDepth) visibility-=0.25;\n#endif\nreturn computeFallOff(min(1.0,visibility+darkness),clipSpace.xy,frustumEdgeFalloff);\n}\n}\n#define inline\nfloat computeShadowWithESM(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float depthScale,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadowMapSample=texture2D(shadowSampler,uv).x;\n#endif\nfloat esm=1.0-clamp(exp(min(87.,depthScale*shadowPixelDepth))*shadowMapSample,0.,1.-darkness);\nreturn computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n#define inline\nfloat computeShadowWithCloseESM(vec4 vPositionFromLight,float depthMetric,sampler2D shadowSampler,float darkness,float depthScale,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec2 uv=0.5*clipSpace.xy+vec2(0.5);\nif (uv.x<0. || uv.x>1.0 || uv.y<0. || uv.y>1.0)\n{\nreturn 1.0;\n}\nelse\n{\nfloat shadowPixelDepth=clamp(depthMetric,0.,1.0);\n#ifndef SHADOWFLOAT\nfloat shadowMapSample=unpack(texture2D(shadowSampler,uv));\n#else\nfloat shadowMapSample=texture2D(shadowSampler,uv).x;\n#endif\nfloat esm=clamp(exp(min(87.,-depthScale*(shadowPixelDepth-shadowMapSample))),darkness,1.);\nreturn computeFallOff(esm,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n#ifdef WEBGL2\n#define GREATEST_LESS_THAN_ONE 0.99999994\n\n#define inline\nfloat computeShadowWithCSMPCF1(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArrayShadow shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec4 uvDepthLayer=vec4(uvDepth.x,uvDepth.y,layer,uvDepth.z);\nfloat shadow=texture(shadowSampler,uvDepthLayer);\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n\n\n\n#define inline\nfloat computeShadowWithCSMPCF3(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArrayShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\n\n\nvec2 uvw0=3.-2.*st;\nvec2 uvw1=1.+2.*st;\nvec2 u=vec2((2.-st.x)/uvw0.x-1.,st.x/uvw1.x+1.)*shadowMapSizeAndInverse.y;\nvec2 v=vec2((2.-st.y)/uvw0.y-1.,st.y/uvw1.y+1.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[0]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[0]),layer,uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[1]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[1]),layer,uvDepth.z));\nshadow=shadow/16.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n\n\n\n#define inline\nfloat computeShadowWithCSMPCF5(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArrayShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\nvec2 uvw0=4.-3.*st;\nvec2 uvw1=vec2(7.);\nvec2 uvw2=1.+3.*st;\nvec3 u=vec3((3.-2.*st.x)/uvw0.x-2.,(3.+st.x)/uvw1.x,st.x/uvw2.x+2.)*shadowMapSizeAndInverse.y;\nvec3 v=vec3((3.-2.*st.y)/uvw0.y-2.,(3.+st.y)/uvw1.y,st.y/uvw2.y+2.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[0]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[0]),layer,uvDepth.z));\nshadow+=uvw2.x*uvw0.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[2],v[0]),layer,uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[1]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[1]),layer,uvDepth.z));\nshadow+=uvw2.x*uvw1.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[2],v[1]),layer,uvDepth.z));\nshadow+=uvw0.x*uvw2.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[0],v[2]),layer,uvDepth.z));\nshadow+=uvw1.x*uvw2.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[1],v[2]),layer,uvDepth.z));\nshadow+=uvw2.x*uvw2.y*texture2D(shadowSampler,vec4(base_uv.xy+vec2(u[2],v[2]),layer,uvDepth.z));\nshadow=shadow/144.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n\n#define inline\nfloat computeShadowWithPCF1(vec4 vPositionFromLight,float depthMetric,highp sampler2DShadow shadowSampler,float darkness,float frustumEdgeFalloff)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nfloat shadow=texture2D(shadowSampler,uvDepth);\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n\n\n\n#define inline\nfloat computeShadowWithPCF3(vec4 vPositionFromLight,float depthMetric,highp sampler2DShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\n\n\nvec2 uvw0=3.-2.*st;\nvec2 uvw1=1.+2.*st;\nvec2 u=vec2((2.-st.x)/uvw0.x-1.,st.x/uvw1.x+1.)*shadowMapSizeAndInverse.y;\nvec2 v=vec2((2.-st.y)/uvw0.y-1.,st.y/uvw1.y+1.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[0]),uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[0]),uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[1]),uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[1]),uvDepth.z));\nshadow=shadow/16.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n\n\n\n#define inline\nfloat computeShadowWithPCF5(vec4 vPositionFromLight,float depthMetric,highp sampler2DShadow shadowSampler,vec2 shadowMapSizeAndInverse,float darkness,float frustumEdgeFalloff)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nvec2 uv=uvDepth.xy*shadowMapSizeAndInverse.x;\nuv+=0.5;\nvec2 st=fract(uv);\nvec2 base_uv=floor(uv)-0.5;\nbase_uv*=shadowMapSizeAndInverse.y;\n\n\nvec2 uvw0=4.-3.*st;\nvec2 uvw1=vec2(7.);\nvec2 uvw2=1.+3.*st;\nvec3 u=vec3((3.-2.*st.x)/uvw0.x-2.,(3.+st.x)/uvw1.x,st.x/uvw2.x+2.)*shadowMapSizeAndInverse.y;\nvec3 v=vec3((3.-2.*st.y)/uvw0.y-2.,(3.+st.y)/uvw1.y,st.y/uvw2.y+2.)*shadowMapSizeAndInverse.y;\nfloat shadow=0.;\nshadow+=uvw0.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[0]),uvDepth.z));\nshadow+=uvw1.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[0]),uvDepth.z));\nshadow+=uvw2.x*uvw0.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[0]),uvDepth.z));\nshadow+=uvw0.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[1]),uvDepth.z));\nshadow+=uvw1.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[1]),uvDepth.z));\nshadow+=uvw2.x*uvw1.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[1]),uvDepth.z));\nshadow+=uvw0.x*uvw2.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[0],v[2]),uvDepth.z));\nshadow+=uvw1.x*uvw2.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[1],v[2]),uvDepth.z));\nshadow+=uvw2.x*uvw2.y*texture2D(shadowSampler,vec3(base_uv.xy+vec2(u[2],v[2]),uvDepth.z));\nshadow=shadow/144.;\nshadow=mix(darkness,1.,shadow);\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\nconst vec3 PoissonSamplers32[64]=vec3[64](\nvec3(0.06407013,0.05409927,0.),\nvec3(0.7366577,0.5789394,0.),\nvec3(-0.6270542,-0.5320278,0.),\nvec3(-0.4096107,0.8411095,0.),\nvec3(0.6849564,-0.4990818,0.),\nvec3(-0.874181,-0.04579735,0.),\nvec3(0.9989998,0.0009880066,0.),\nvec3(-0.004920578,-0.9151649,0.),\nvec3(0.1805763,0.9747483,0.),\nvec3(-0.2138451,0.2635818,0.),\nvec3(0.109845,0.3884785,0.),\nvec3(0.06876755,-0.3581074,0.),\nvec3(0.374073,-0.7661266,0.),\nvec3(0.3079132,-0.1216763,0.),\nvec3(-0.3794335,-0.8271583,0.),\nvec3(-0.203878,-0.07715034,0.),\nvec3(0.5912697,0.1469799,0.),\nvec3(-0.88069,0.3031784,0.),\nvec3(0.5040108,0.8283722,0.),\nvec3(-0.5844124,0.5494877,0.),\nvec3(0.6017799,-0.1726654,0.),\nvec3(-0.5554981,0.1559997,0.),\nvec3(-0.3016369,-0.3900928,0.),\nvec3(-0.5550632,-0.1723762,0.),\nvec3(0.925029,0.2995041,0.),\nvec3(-0.2473137,0.5538505,0.),\nvec3(0.9183037,-0.2862392,0.),\nvec3(0.2469421,0.6718712,0.),\nvec3(0.3916397,-0.4328209,0.),\nvec3(-0.03576927,-0.6220032,0.),\nvec3(-0.04661255,0.7995201,0.),\nvec3(0.4402924,0.3640312,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.),\nvec3(0.,0.,0.)\n);\nconst vec3 PoissonSamplers64[64]=vec3[64](\nvec3(-0.613392,0.617481,0.),\nvec3(0.170019,-0.040254,0.),\nvec3(-0.299417,0.791925,0.),\nvec3(0.645680,0.493210,0.),\nvec3(-0.651784,0.717887,0.),\nvec3(0.421003,0.027070,0.),\nvec3(-0.817194,-0.271096,0.),\nvec3(-0.705374,-0.668203,0.),\nvec3(0.977050,-0.108615,0.),\nvec3(0.063326,0.142369,0.),\nvec3(0.203528,0.214331,0.),\nvec3(-0.667531,0.326090,0.),\nvec3(-0.098422,-0.295755,0.),\nvec3(-0.885922,0.215369,0.),\nvec3(0.566637,0.605213,0.),\nvec3(0.039766,-0.396100,0.),\nvec3(0.751946,0.453352,0.),\nvec3(0.078707,-0.715323,0.),\nvec3(-0.075838,-0.529344,0.),\nvec3(0.724479,-0.580798,0.),\nvec3(0.222999,-0.215125,0.),\nvec3(-0.467574,-0.405438,0.),\nvec3(-0.248268,-0.814753,0.),\nvec3(0.354411,-0.887570,0.),\nvec3(0.175817,0.382366,0.),\nvec3(0.487472,-0.063082,0.),\nvec3(-0.084078,0.898312,0.),\nvec3(0.488876,-0.783441,0.),\nvec3(0.470016,0.217933,0.),\nvec3(-0.696890,-0.549791,0.),\nvec3(-0.149693,0.605762,0.),\nvec3(0.034211,0.979980,0.),\nvec3(0.503098,-0.308878,0.),\nvec3(-0.016205,-0.872921,0.),\nvec3(0.385784,-0.393902,0.),\nvec3(-0.146886,-0.859249,0.),\nvec3(0.643361,0.164098,0.),\nvec3(0.634388,-0.049471,0.),\nvec3(-0.688894,0.007843,0.),\nvec3(0.464034,-0.188818,0.),\nvec3(-0.440840,0.137486,0.),\nvec3(0.364483,0.511704,0.),\nvec3(0.034028,0.325968,0.),\nvec3(0.099094,-0.308023,0.),\nvec3(0.693960,-0.366253,0.),\nvec3(0.678884,-0.204688,0.),\nvec3(0.001801,0.780328,0.),\nvec3(0.145177,-0.898984,0.),\nvec3(0.062655,-0.611866,0.),\nvec3(0.315226,-0.604297,0.),\nvec3(-0.780145,0.486251,0.),\nvec3(-0.371868,0.882138,0.),\nvec3(0.200476,0.494430,0.),\nvec3(-0.494552,-0.711051,0.),\nvec3(0.612476,0.705252,0.),\nvec3(-0.578845,-0.768792,0.),\nvec3(-0.772454,-0.090976,0.),\nvec3(0.504440,0.372295,0.),\nvec3(0.155736,0.065157,0.),\nvec3(0.391522,0.849605,0.),\nvec3(-0.620106,-0.328104,0.),\nvec3(0.789239,-0.419965,0.),\nvec3(-0.545396,0.538133,0.),\nvec3(-0.178564,-0.596057,0.)\n);\n\n\n\n\n\n#define inline\nfloat computeShadowWithCSMPCSS(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,int searchTapCount,int pcfTapCount,vec3[64] poissonSamplers,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nuvDepth.z=clamp(uvDepth.z,0.,GREATEST_LESS_THAN_ONE);\nvec4 uvDepthLayer=vec4(uvDepth.x,uvDepth.y,layer,uvDepth.z);\nfloat blockerDepth=0.0;\nfloat sumBlockerDepth=0.0;\nfloat numBlocker=0.0;\nfor (int i=0; i<searchTapCount; i ++) {\nblockerDepth=texture(depthSampler,vec3(uvDepth.xy+(lightSizeUV*lightSizeUVCorrection*shadowMapSizeInverse*PoissonSamplers32[i].xy),layer)).r;\nif (blockerDepth<depthMetric) {\nsumBlockerDepth+=blockerDepth;\nnumBlocker++;\n}\n}\nif (numBlocker<1.0) {\nreturn 1.0;\n}\nelse\n{\nfloat avgBlockerDepth=sumBlockerDepth/numBlocker;\n\nfloat AAOffset=shadowMapSizeInverse*10.;\n\n\nfloat penumbraRatio=((depthMetric-avgBlockerDepth)*depthCorrection+AAOffset);\nvec4 filterRadius=vec4(penumbraRatio*lightSizeUV*lightSizeUVCorrection*shadowMapSizeInverse,0.,0.);\nfloat random=getRand(vPositionFromLight.xy);\nfloat rotationAngle=random*3.1415926;\nvec2 rotationVector=vec2(cos(rotationAngle),sin(rotationAngle));\nfloat shadow=0.;\nfor (int i=0; i<pcfTapCount; i++) {\nvec4 offset=vec4(poissonSamplers[i],0.);\n\noffset=vec4(offset.x*rotationVector.x-offset.y*rotationVector.y,offset.y*rotationVector.x+offset.x*rotationVector.y,0.,0.);\nshadow+=texture2D(shadowSampler,uvDepthLayer+offset*filterRadius);\n}\nshadow/=float(pcfTapCount);\n\nshadow=mix(shadow,1.,min((depthMetric-avgBlockerDepth)*depthCorrection*penumbraDarkness,1.));\n\nshadow=mix(darkness,1.,shadow);\n\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n\n\n\n\n\n#define inline\nfloat computeShadowWithPCSS(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,highp sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,int searchTapCount,int pcfTapCount,vec3[64] poissonSamplers)\n{\nif (depthMetric>1.0 || depthMetric<0.0) {\nreturn 1.0;\n}\nelse\n{\nvec3 clipSpace=vPositionFromLight.xyz/vPositionFromLight.w;\nvec3 uvDepth=vec3(0.5*clipSpace.xyz+vec3(0.5));\nfloat blockerDepth=0.0;\nfloat sumBlockerDepth=0.0;\nfloat numBlocker=0.0;\nfor (int i=0; i<searchTapCount; i ++) {\nblockerDepth=texture(depthSampler,uvDepth.xy+(lightSizeUV*shadowMapSizeInverse*PoissonSamplers32[i].xy)).r;\nif (blockerDepth<depthMetric) {\nsumBlockerDepth+=blockerDepth;\nnumBlocker++;\n}\n}\nif (numBlocker<1.0) {\nreturn 1.0;\n}\nelse\n{\nfloat avgBlockerDepth=sumBlockerDepth/numBlocker;\n\nfloat AAOffset=shadowMapSizeInverse*10.;\n\n\nfloat penumbraRatio=((depthMetric-avgBlockerDepth)+AAOffset);\nfloat filterRadius=penumbraRatio*lightSizeUV*shadowMapSizeInverse;\nfloat random=getRand(vPositionFromLight.xy);\nfloat rotationAngle=random*3.1415926;\nvec2 rotationVector=vec2(cos(rotationAngle),sin(rotationAngle));\nfloat shadow=0.;\nfor (int i=0; i<pcfTapCount; i++) {\nvec3 offset=poissonSamplers[i];\n\noffset=vec3(offset.x*rotationVector.x-offset.y*rotationVector.y,offset.y*rotationVector.x+offset.x*rotationVector.y,0.);\nshadow+=texture2D(shadowSampler,uvDepth+offset*filterRadius);\n}\nshadow/=float(pcfTapCount);\n\nshadow=mix(shadow,1.,depthMetric-avgBlockerDepth);\n\nshadow=mix(darkness,1.,shadow);\n\nreturn computeFallOff(shadow,clipSpace.xy,frustumEdgeFalloff);\n}\n}\n}\n#define inline\nfloat computeShadowWithPCSS16(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,highp sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{\nreturn computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,16,PoissonSamplers32);\n}\n#define inline\nfloat computeShadowWithPCSS32(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,highp sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{\nreturn computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,32,PoissonSamplers32);\n}\n#define inline\nfloat computeShadowWithPCSS64(vec4 vPositionFromLight,float depthMetric,sampler2D depthSampler,highp sampler2DShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff)\n{\nreturn computeShadowWithPCSS(vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,32,64,PoissonSamplers64);\n}\n#define inline\nfloat computeShadowWithCSMPCSS16(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nreturn computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,16,PoissonSamplers32,lightSizeUVCorrection,depthCorrection,penumbraDarkness);\n}\n#define inline\nfloat computeShadowWithCSMPCSS32(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nreturn computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,16,32,PoissonSamplers32,lightSizeUVCorrection,depthCorrection,penumbraDarkness);\n}\n#define inline\nfloat computeShadowWithCSMPCSS64(float layer,vec4 vPositionFromLight,float depthMetric,highp sampler2DArray depthSampler,highp sampler2DArrayShadow shadowSampler,float shadowMapSizeInverse,float lightSizeUV,float darkness,float frustumEdgeFalloff,vec2 lightSizeUVCorrection,float depthCorrection,float penumbraDarkness)\n{\nreturn computeShadowWithCSMPCSS(layer,vPositionFromLight,depthMetric,depthSampler,shadowSampler,shadowMapSizeInverse,lightSizeUV,darkness,frustumEdgeFalloff,32,64,PoissonSamplers64,lightSizeUVCorrection,depthCorrection,penumbraDarkness);\n}\n#endif\n#endif\n`;\n\nEffect.IncludesShadersStore[name] = shader;\n/** @hidden */\nexport var shadowsFragmentFunctions = { name, shader };\n"]}
|
|
@@ -57,7 +57,7 @@ export interface IWebXRHandTrackingOptions {
|
|
|
57
57
|
impostorType?: number;
|
|
58
58
|
};
|
|
59
59
|
/**
|
|
60
|
-
* Should the default hand mesh be disabled. In this case, the spheres will be visible.
|
|
60
|
+
* Should the default hand mesh be disabled. In this case, the spheres will be visible (unless set invisible).
|
|
61
61
|
*/
|
|
62
62
|
disableDefaultHandMesh?: boolean;
|
|
63
63
|
/**
|
|
@@ -135,12 +135,13 @@ export declare class WebXRHand implements IDisposable {
|
|
|
135
135
|
* @param trackedMeshes the meshes to be used to track the hand joints
|
|
136
136
|
* @param _handMesh an optional hand mesh. if not provided, ours will be used
|
|
137
137
|
* @param _rigMapping an optional rig mapping for the hand mesh. if not provided, ours will be used
|
|
138
|
+
* @param disableDefaultHandMesh should the default mesh creation be disabled
|
|
138
139
|
*/
|
|
139
140
|
constructor(
|
|
140
141
|
/** the controller to which the hand correlates */
|
|
141
142
|
xrController: WebXRInputSource,
|
|
142
143
|
/** the meshes to be used to track the hand joints */
|
|
143
|
-
trackedMeshes: AbstractMesh[], _handMesh?: AbstractMesh | undefined, _rigMapping?: string[] | undefined);
|
|
144
|
+
trackedMeshes: AbstractMesh[], _handMesh?: AbstractMesh | undefined, _rigMapping?: string[] | undefined, disableDefaultHandMesh?: boolean);
|
|
144
145
|
/**
|
|
145
146
|
* Update this hand from the latest xr frame
|
|
146
147
|
* @param xrFrame xrFrame to update from
|
|
@@ -23,12 +23,13 @@ var WebXRHand = /** @class */ (function () {
|
|
|
23
23
|
* @param trackedMeshes the meshes to be used to track the hand joints
|
|
24
24
|
* @param _handMesh an optional hand mesh. if not provided, ours will be used
|
|
25
25
|
* @param _rigMapping an optional rig mapping for the hand mesh. if not provided, ours will be used
|
|
26
|
+
* @param disableDefaultHandMesh should the default mesh creation be disabled
|
|
26
27
|
*/
|
|
27
28
|
function WebXRHand(
|
|
28
29
|
/** the controller to which the hand correlates */
|
|
29
30
|
xrController,
|
|
30
31
|
/** the meshes to be used to track the hand joints */
|
|
31
|
-
trackedMeshes, _handMesh, _rigMapping) {
|
|
32
|
+
trackedMeshes, _handMesh, _rigMapping, disableDefaultHandMesh) {
|
|
32
33
|
this.xrController = xrController;
|
|
33
34
|
this.trackedMeshes = trackedMeshes;
|
|
34
35
|
this._handMesh = _handMesh;
|
|
@@ -41,7 +42,9 @@ var WebXRHand = /** @class */ (function () {
|
|
|
41
42
|
this._defaultHandMesh = false;
|
|
42
43
|
}
|
|
43
44
|
else {
|
|
44
|
-
|
|
45
|
+
if (!disableDefaultHandMesh) {
|
|
46
|
+
this._generateDefaultHandMesh();
|
|
47
|
+
}
|
|
45
48
|
}
|
|
46
49
|
// hide the motion controller, if available/loaded
|
|
47
50
|
if (this.xrController.motionController) {
|
|
@@ -267,7 +270,7 @@ var WebXRHandTracking = /** @class */ (function (_super) {
|
|
|
267
270
|
_this.onHandRemovedObservable = new Observable();
|
|
268
271
|
_this._hands = {};
|
|
269
272
|
_this._attachHand = function (xrController) {
|
|
270
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
273
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
271
274
|
if (!xrController.inputSource.hand || _this._hands[xrController.uniqueId]) {
|
|
272
275
|
// already attached
|
|
273
276
|
return;
|
|
@@ -294,12 +297,15 @@ var WebXRHandTracking = /** @class */ (function (_super) {
|
|
|
294
297
|
newInstance.physicsImpostor = new PhysicsImpostor(newInstance, type, __assign({ mass: 0 }, props));
|
|
295
298
|
}
|
|
296
299
|
newInstance.rotationQuaternion = new Quaternion();
|
|
300
|
+
if ((_e = _this.options.jointMeshes) === null || _e === void 0 ? void 0 : _e.invisible) {
|
|
301
|
+
newInstance.isVisible = false;
|
|
302
|
+
}
|
|
297
303
|
trackedMeshes.push(newInstance);
|
|
298
304
|
}
|
|
299
305
|
var handedness = xrController.inputSource.handedness === "right" ? "right" : "left";
|
|
300
|
-
var handMesh = ((
|
|
301
|
-
var rigMapping = ((
|
|
302
|
-
var webxrHand = new WebXRHand(xrController, trackedMeshes, handMesh, rigMapping);
|
|
306
|
+
var handMesh = ((_f = _this.options.jointMeshes) === null || _f === void 0 ? void 0 : _f.handMeshes) && ((_g = _this.options.jointMeshes) === null || _g === void 0 ? void 0 : _g.handMeshes[handedness]);
|
|
307
|
+
var rigMapping = ((_h = _this.options.jointMeshes) === null || _h === void 0 ? void 0 : _h.rigMapping) && ((_j = _this.options.jointMeshes) === null || _j === void 0 ? void 0 : _j.rigMapping[handedness]);
|
|
308
|
+
var webxrHand = new WebXRHand(xrController, trackedMeshes, handMesh, rigMapping, (_k = _this.options.jointMeshes) === null || _k === void 0 ? void 0 : _k.disableDefaultHandMesh);
|
|
303
309
|
// get two new meshes
|
|
304
310
|
_this._hands[xrController.uniqueId] = {
|
|
305
311
|
handObject: webxrHand,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebXRHandTracking.js","sourceRoot":"","sources":["../../../../sourceES6/core/XR/features/WebXRHandTracking.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { WebXRFeatureName } from \"../webXRFeaturesManager\";\r\nimport { AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { Mesh } from \"../../Meshes/mesh\";\r\nimport { SphereBuilder } from \"../../Meshes/Builders/sphereBuilder\";\r\nimport { WebXRInput } from \"../webXRInput\";\r\nimport { WebXRInputSource } from \"../webXRInputSource\";\r\nimport { Quaternion } from \"../../Maths/math.vector\";\r\nimport { Nullable } from \"../../types\";\r\nimport { PhysicsImpostor } from \"../../Physics/physicsImpostor\";\r\nimport { WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { IDisposable, Scene } from \"../../scene\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport { InstancedMesh } from \"../../Meshes/instancedMesh\";\r\nimport { SceneLoader } from \"../../Loading/sceneLoader\";\r\nimport { Color3 } from \"../../Maths/math.color\";\r\nimport { NodeMaterial } from \"../../Materials/Node/nodeMaterial\";\r\nimport { InputBlock } from \"../../Materials/Node/Blocks/Input/inputBlock\";\r\nimport { Material } from \"../../Materials/material\";\r\nimport { Engine } from \"../../Engines/engine\";\r\nimport { Tools } from \"../../Misc/tools\";\r\nimport { Axis } from \"../../Maths/math.axis\";\r\nimport { TransformNode } from '../../Meshes/transformNode';\r\n\r\ndeclare const XRHand: XRHand;\r\n\r\n/**\r\n * Configuration interface for the hand tracking feature\r\n */\r\nexport interface IWebXRHandTrackingOptions {\r\n /**\r\n * The xrInput that will be used as source for new hands\r\n */\r\n xrInput: WebXRInput;\r\n\r\n /**\r\n * Configuration object for the joint meshes\r\n */\r\n jointMeshes?: {\r\n /**\r\n * Should the meshes created be invisible (defaults to false)\r\n */\r\n invisible?: boolean;\r\n /**\r\n * A source mesh to be used to create instances. Defaults to a sphere.\r\n * This mesh will be the source for all other (25) meshes.\r\n * It should have the general size of a single unit, as the instances will be scaled according to the provided radius\r\n */\r\n sourceMesh?: Mesh;\r\n\r\n /**\r\n * This function will be called after a mesh was created for a specific joint.\r\n * Using this function you can either manipulate the instance or return a new mesh.\r\n * When returning a new mesh the instance created before will be disposed\r\n */\r\n onHandJointMeshGenerated?: (meshInstance: InstancedMesh, jointId: number, controllerId: string) => Mesh | undefined;\r\n /**\r\n * Should the source mesh stay visible. Defaults to false\r\n */\r\n keepOriginalVisible?: boolean;\r\n /**\r\n * Scale factor for all instances (defaults to 2)\r\n */\r\n scaleFactor?: number;\r\n /**\r\n * Should each instance have its own physics impostor\r\n */\r\n enablePhysics?: boolean;\r\n /**\r\n * If enabled, override default physics properties\r\n */\r\n physicsProps?: { friction?: number; restitution?: number; impostorType?: number };\r\n /**\r\n * Should the default hand mesh be disabled. In this case, the spheres will be visible.\r\n */\r\n disableDefaultHandMesh?: boolean;\r\n /**\r\n * a rigged hand-mesh that will be updated according to the XRHand data provided. This will override the default hand mesh\r\n */\r\n handMeshes?: {\r\n right: AbstractMesh;\r\n left: AbstractMesh;\r\n };\r\n /**\r\n * If a hand mesh was provided, this array will define what axis will update which node. This will override the default hand mesh\r\n */\r\n rigMapping?: {\r\n right: string[];\r\n left: string[];\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * Parts of the hands divided to writs and finger names\r\n */\r\nexport const enum HandPart {\r\n /**\r\n * HandPart - Wrist\r\n */\r\n WRIST = \"wrist\",\r\n /**\r\n * HandPart - The THumb\r\n */\r\n THUMB = \"thumb\",\r\n /**\r\n * HandPart - Index finger\r\n */\r\n INDEX = \"index\",\r\n /**\r\n * HandPart - Middle finger\r\n */\r\n MIDDLE = \"middle\",\r\n /**\r\n * HandPart - Ring finger\r\n */\r\n RING = \"ring\",\r\n /**\r\n * HandPart - Little finger\r\n */\r\n LITTLE = \"little\",\r\n}\r\n\r\n/**\r\n * Representing a single hand (with its corresponding native XRHand object)\r\n */\r\nexport class WebXRHand implements IDisposable {\r\n private _scene: Scene;\r\n private _defaultHandMesh: boolean = false;\r\n private _transformNodeMapping: TransformNode[] = [];\r\n /**\r\n * Hand-parts definition (key is HandPart)\r\n */\r\n public handPartsDefinition: { [key: string]: number[] };\r\n\r\n /**\r\n * Populate the HandPartsDefinition object.\r\n * This is called as a side effect since certain browsers don't have XRHand defined.\r\n */\r\n private generateHandPartsDefinition(hand: XRHand) {\r\n return {\r\n [HandPart.WRIST]: [hand.WRIST],\r\n [HandPart.THUMB]: [hand.THUMB_METACARPAL, hand.THUMB_PHALANX_PROXIMAL, hand.THUMB_PHALANX_DISTAL, hand.THUMB_PHALANX_TIP],\r\n [HandPart.INDEX]: [hand.INDEX_METACARPAL, hand.INDEX_PHALANX_PROXIMAL, hand.INDEX_PHALANX_INTERMEDIATE, hand.INDEX_PHALANX_DISTAL, hand.INDEX_PHALANX_TIP],\r\n [HandPart.MIDDLE]: [hand.MIDDLE_METACARPAL, hand.MIDDLE_PHALANX_PROXIMAL, hand.MIDDLE_PHALANX_INTERMEDIATE, hand.MIDDLE_PHALANX_DISTAL, hand.MIDDLE_PHALANX_TIP],\r\n [HandPart.RING]: [hand.RING_METACARPAL, hand.RING_PHALANX_PROXIMAL, hand.RING_PHALANX_INTERMEDIATE, hand.RING_PHALANX_DISTAL, hand.RING_PHALANX_TIP],\r\n [HandPart.LITTLE]: [hand.LITTLE_METACARPAL, hand.LITTLE_PHALANX_PROXIMAL, hand.LITTLE_PHALANX_INTERMEDIATE, hand.LITTLE_PHALANX_DISTAL, hand.LITTLE_PHALANX_TIP],\r\n };\r\n }\r\n\r\n /**\r\n * Construct a new hand object\r\n * @param xrController the controller to which the hand correlates\r\n * @param trackedMeshes the meshes to be used to track the hand joints\r\n * @param _handMesh an optional hand mesh. if not provided, ours will be used\r\n * @param _rigMapping an optional rig mapping for the hand mesh. if not provided, ours will be used\r\n */\r\n constructor(\r\n /** the controller to which the hand correlates */\r\n public readonly xrController: WebXRInputSource,\r\n /** the meshes to be used to track the hand joints */\r\n public readonly trackedMeshes: AbstractMesh[],\r\n private _handMesh?: AbstractMesh,\r\n private _rigMapping?: string[]\r\n ) {\r\n this.handPartsDefinition = this.generateHandPartsDefinition(xrController.inputSource.hand!);\r\n this._scene = trackedMeshes[0].getScene();\r\n if (this._handMesh && this._rigMapping) {\r\n this._defaultHandMesh = false;\r\n } else {\r\n this._generateDefaultHandMesh();\r\n }\r\n\r\n // hide the motion controller, if available/loaded\r\n if (this.xrController.motionController) {\r\n if (this.xrController.motionController.rootMesh) {\r\n this.xrController.motionController.rootMesh.setEnabled(false);\r\n } else {\r\n this.xrController.motionController.onModelLoadedObservable.add((controller) => {\r\n if (controller.rootMesh) {\r\n controller.rootMesh.setEnabled(false);\r\n }\r\n });\r\n }\r\n }\r\n\r\n this.xrController.onMotionControllerInitObservable.add((motionController) => {\r\n motionController.onModelLoadedObservable.add((controller) => {\r\n if (controller.rootMesh) {\r\n controller.rootMesh.setEnabled(false);\r\n }\r\n });\r\n if (motionController.rootMesh) {\r\n motionController.rootMesh.setEnabled(false);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Update this hand from the latest xr frame\r\n * @param xrFrame xrFrame to update from\r\n * @param referenceSpace The current viewer reference space\r\n * @param scaleFactor optional scale factor for the meshes\r\n */\r\n public updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace, scaleFactor: number = 2) {\r\n const hand = this.xrController.inputSource.hand;\r\n if (!hand) {\r\n return;\r\n }\r\n this.trackedMeshes.forEach((mesh, idx) => {\r\n const xrJoint = hand[idx];\r\n if (xrJoint) {\r\n let pose = xrFrame.getJointPose!(xrJoint, referenceSpace);\r\n if (!pose || !pose.transform) {\r\n return;\r\n }\r\n // get the transformation. can be done with matrix decomposition as well\r\n const pos = pose.transform.position;\r\n const orientation = pose.transform.orientation;\r\n mesh.position.set(pos.x, pos.y, pos.z);\r\n mesh.rotationQuaternion!.set(orientation.x, orientation.y, orientation.z, orientation.w);\r\n // left handed system conversion\r\n // get the radius of the joint. In general it is static, but just in case it does change we update it on each frame.\r\n const radius = (pose.radius || 0.008) * scaleFactor;\r\n mesh.scaling.set(radius, radius, radius);\r\n\r\n // now check for the hand mesh\r\n if (this._handMesh && this._rigMapping) {\r\n if (this._rigMapping[idx]) {\r\n this._transformNodeMapping[idx] = this._transformNodeMapping[idx] || this._scene.getTransformNodeByName(this._rigMapping[idx]);\r\n if (this._transformNodeMapping[idx]) {\r\n this._transformNodeMapping[idx].position.copyFrom(mesh.position);\r\n this._transformNodeMapping[idx].rotationQuaternion!.copyFrom(mesh.rotationQuaternion!);\r\n // no scaling at the moment\r\n // this._transformNodeMapping[idx].scaling.copyFrom(mesh.scaling).scaleInPlace(20);\r\n mesh.isVisible = false;\r\n }\r\n }\r\n }\r\n if (!mesh.getScene().useRightHandedSystem) {\r\n mesh.position.z *= -1;\r\n mesh.rotationQuaternion!.z *= -1;\r\n mesh.rotationQuaternion!.w *= -1;\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Get meshes of part of the hand\r\n * @param part the part of hand to get\r\n * @returns An array of meshes that correlate to the hand part requested\r\n */\r\n public getHandPartMeshes(part: HandPart): AbstractMesh[] {\r\n return this.handPartsDefinition[part].map((idx) => this.trackedMeshes[idx]);\r\n }\r\n\r\n /**\r\n * Dispose this Hand object\r\n */\r\n public dispose() {\r\n this.trackedMeshes.forEach((mesh) => mesh.dispose());\r\n // dispose the hand mesh, if it is the default one\r\n if (this._defaultHandMesh && this._handMesh) {\r\n this._handMesh.dispose();\r\n }\r\n }\r\n\r\n private async _generateDefaultHandMesh() {\r\n try {\r\n const handedness = this.xrController.inputSource.handedness === \"right\" ? \"right\" : \"left\";\r\n const filename = `${handedness === \"right\" ? \"r\" : \"l\"}_hand_${this._scene.useRightHandedSystem ? \"r\" : \"l\"}hs.glb`;\r\n const loaded = await SceneLoader.ImportMeshAsync(\"\", \"https://assets.babylonjs.com/meshes/HandMeshes/\", filename, this._scene);\r\n // shader\r\n const handColors = {\r\n base: Color3.FromInts(116, 63, 203),\r\n fresnel: Color3.FromInts(149, 102, 229),\r\n fingerColor: Color3.FromInts(177, 130, 255),\r\n tipFresnel: Color3.FromInts(220, 200, 255),\r\n };\r\n\r\n const handShader = new NodeMaterial(\"leftHandShader\", this._scene, { emitComments: false });\r\n await handShader.loadAsync(\"https://patrickryanms.github.io/BabylonJStextures/Demos/xrHandMesh/handsShader.json\");\r\n // build node materials\r\n handShader.build(false);\r\n\r\n // depth prepass and alpha mode\r\n handShader.needDepthPrePass = true;\r\n handShader.transparencyMode = Material.MATERIAL_ALPHABLEND;\r\n handShader.alphaMode = Engine.ALPHA_COMBINE;\r\n\r\n const handNodes = {\r\n base: handShader.getBlockByName(\"baseColor\") as InputBlock,\r\n fresnel: handShader.getBlockByName(\"fresnelColor\") as InputBlock,\r\n fingerColor: handShader.getBlockByName(\"fingerColor\") as InputBlock,\r\n tipFresnel: handShader.getBlockByName(\"tipFresnelColor\") as InputBlock,\r\n };\r\n\r\n handNodes.base.value = handColors.base;\r\n handNodes.fresnel.value = handColors.fresnel;\r\n handNodes.fingerColor.value = handColors.fingerColor;\r\n handNodes.tipFresnel.value = handColors.tipFresnel;\r\n\r\n loaded.meshes[1].material = handShader;\r\n\r\n this._defaultHandMesh = true;\r\n this._handMesh = loaded.meshes[0];\r\n this._rigMapping = [\r\n \"wrist_\",\r\n \"thumb_metacarpal_\",\r\n \"thumb_proxPhalanx_\",\r\n \"thumb_distPhalanx_\",\r\n \"thumb_tip_\",\r\n \"index_metacarpal_\",\r\n \"index_proxPhalanx_\",\r\n \"index_intPhalanx_\",\r\n \"index_distPhalanx_\",\r\n \"index_tip_\",\r\n \"middle_metacarpal_\",\r\n \"middle_proxPhalanx_\",\r\n \"middle_intPhalanx_\",\r\n \"middle_distPhalanx_\",\r\n \"middle_tip_\",\r\n \"ring_metacarpal_\",\r\n \"ring_proxPhalanx_\",\r\n \"ring_intPhalanx_\",\r\n \"ring_distPhalanx_\",\r\n \"ring_tip_\",\r\n \"little_metacarpal_\",\r\n \"little_proxPhalanx_\",\r\n \"little_intPhalanx_\",\r\n \"little_distPhalanx_\",\r\n \"little_tip_\",\r\n ].map((joint) => `${joint}${handedness === \"right\" ? \"R\" : \"L\"}`);\r\n // single change for left handed systems\r\n const tm = this._scene.getTransformNodeByName(this._rigMapping[0]);\r\n if (!tm) {\r\n throw new Error(\"could not find the wrist node\");\r\n } else {\r\n tm.parent && (tm.parent as AbstractMesh).rotate(Axis.Y, Math.PI);\r\n }\r\n } catch (e) {\r\n Tools.Error(\"error loading hand mesh\");\r\n console.log(e);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * WebXR Hand Joint tracking feature, available for selected browsers and devices\r\n */\r\nexport class WebXRHandTracking extends WebXRAbstractFeature {\r\n private static _idCounter = 0;\r\n /**\r\n * The module's name\r\n */\r\n public static readonly Name = WebXRFeatureName.HAND_TRACKING;\r\n /**\r\n * The (Babylon) version of this module.\r\n * This is an integer representing the implementation version.\r\n * This number does not correspond to the WebXR specs version\r\n */\r\n public static readonly Version = 1;\r\n\r\n /**\r\n * This observable will notify registered observers when a new hand object was added and initialized\r\n */\r\n public onHandAddedObservable: Observable<WebXRHand> = new Observable();\r\n /**\r\n * This observable will notify its observers right before the hand object is disposed\r\n */\r\n public onHandRemovedObservable: Observable<WebXRHand> = new Observable();\r\n\r\n private _hands: {\r\n [controllerId: string]: {\r\n id: number;\r\n handObject: WebXRHand;\r\n };\r\n } = {};\r\n\r\n /**\r\n * Creates a new instance of the hit test feature\r\n * @param _xrSessionManager an instance of WebXRSessionManager\r\n * @param options options to use when constructing this feature\r\n */\r\n constructor(\r\n _xrSessionManager: WebXRSessionManager,\r\n /**\r\n * options to use when constructing this feature\r\n */\r\n public readonly options: IWebXRHandTrackingOptions\r\n ) {\r\n super(_xrSessionManager);\r\n this.xrNativeFeatureName = \"hand-tracking\";\r\n }\r\n\r\n /**\r\n * Check if the needed objects are defined.\r\n * This does not mean that the feature is enabled, but that the objects needed are well defined.\r\n */\r\n public isCompatible(): boolean {\r\n return typeof XRHand !== \"undefined\";\r\n }\r\n\r\n /**\r\n * attach this feature\r\n * Will usually be called by the features manager\r\n *\r\n * @returns true if successful.\r\n */\r\n public attach(): boolean {\r\n if (!super.attach()) {\r\n return false;\r\n }\r\n this.options.xrInput.controllers.forEach(this._attachHand);\r\n this._addNewAttachObserver(this.options.xrInput.onControllerAddedObservable, this._attachHand);\r\n this._addNewAttachObserver(this.options.xrInput.onControllerRemovedObservable, (controller) => {\r\n // REMOVE the controller\r\n this._detachHand(controller.uniqueId);\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * detach this feature.\r\n * Will usually be called by the features manager\r\n *\r\n * @returns true if successful.\r\n */\r\n public detach(): boolean {\r\n if (!super.detach()) {\r\n return false;\r\n }\r\n\r\n Object.keys(this._hands).forEach((controllerId) => {\r\n this._detachHand(controllerId);\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Dispose this feature and all of the resources attached\r\n */\r\n public dispose(): void {\r\n super.dispose();\r\n this.onHandAddedObservable.clear();\r\n }\r\n\r\n /**\r\n * Get the hand object according to the controller id\r\n * @param controllerId the controller id to which we want to get the hand\r\n * @returns null if not found or the WebXRHand object if found\r\n */\r\n public getHandByControllerId(controllerId: string): Nullable<WebXRHand> {\r\n return this._hands[controllerId]?.handObject || null;\r\n }\r\n\r\n /**\r\n * Get a hand object according to the requested handedness\r\n * @param handedness the handedness to request\r\n * @returns null if not found or the WebXRHand object if found\r\n */\r\n public getHandByHandedness(handedness: XRHandedness): Nullable<WebXRHand> {\r\n const handednesses = Object.keys(this._hands).map((key) => this._hands[key].handObject.xrController.inputSource.handedness);\r\n const found = handednesses.indexOf(handedness);\r\n if (found !== -1) {\r\n return this._hands[found].handObject;\r\n }\r\n return null;\r\n }\r\n\r\n protected _onXRFrame(_xrFrame: XRFrame): void {\r\n // iterate over the hands object\r\n Object.keys(this._hands).forEach((id) => {\r\n this._hands[id].handObject.updateFromXRFrame(_xrFrame, this._xrSessionManager.referenceSpace, this.options.jointMeshes?.scaleFactor);\r\n });\r\n }\r\n\r\n private _attachHand = (xrController: WebXRInputSource) => {\r\n if (!xrController.inputSource.hand || this._hands[xrController.uniqueId]) {\r\n // already attached\r\n return;\r\n }\r\n\r\n const hand = xrController.inputSource.hand;\r\n const trackedMeshes: AbstractMesh[] = [];\r\n const originalMesh = this.options.jointMeshes?.sourceMesh || SphereBuilder.CreateSphere(\"jointParent\", { diameter: 1 });\r\n originalMesh.isVisible = !!this.options.jointMeshes?.keepOriginalVisible;\r\n for (let i = 0; i < hand.length; ++i) {\r\n let newInstance: AbstractMesh = originalMesh.createInstance(`${xrController.uniqueId}-handJoint-${i}`);\r\n if (this.options.jointMeshes?.onHandJointMeshGenerated) {\r\n const returnedMesh = this.options.jointMeshes.onHandJointMeshGenerated(newInstance as InstancedMesh, i, xrController.uniqueId);\r\n if (returnedMesh) {\r\n if (returnedMesh !== newInstance) {\r\n newInstance.dispose();\r\n newInstance = returnedMesh;\r\n }\r\n }\r\n }\r\n newInstance.isPickable = false;\r\n if (this.options.jointMeshes?.enablePhysics) {\r\n const props = this.options.jointMeshes.physicsProps || {};\r\n const type = props.impostorType !== undefined ? props.impostorType : PhysicsImpostor.SphereImpostor;\r\n newInstance.physicsImpostor = new PhysicsImpostor(newInstance, type, { mass: 0, ...props });\r\n }\r\n newInstance.rotationQuaternion = new Quaternion();\r\n trackedMeshes.push(newInstance);\r\n }\r\n\r\n const handedness = xrController.inputSource.handedness === \"right\" ? \"right\" : \"left\";\r\n const handMesh = this.options.jointMeshes?.handMeshes && this.options.jointMeshes?.handMeshes[handedness];\r\n const rigMapping = this.options.jointMeshes?.rigMapping && this.options.jointMeshes?.rigMapping[handedness];\r\n const webxrHand = new WebXRHand(xrController, trackedMeshes, handMesh, rigMapping);\r\n\r\n // get two new meshes\r\n this._hands[xrController.uniqueId] = {\r\n handObject: webxrHand,\r\n id: WebXRHandTracking._idCounter++,\r\n };\r\n\r\n this.onHandAddedObservable.notifyObservers(webxrHand);\r\n };\r\n\r\n private _detachHand(controllerId: string) {\r\n if (this._hands[controllerId]) {\r\n this.onHandRemovedObservable.notifyObservers(this._hands[controllerId].handObject);\r\n this._hands[controllerId].handObject.dispose();\r\n }\r\n }\r\n}\r\n\r\n//register the plugin\r\nWebXRFeaturesManager.AddWebXRFeature(\r\n WebXRHandTracking.Name,\r\n (xrSessionManager, options) => {\r\n return () => new WebXRHandTracking(xrSessionManager, options);\r\n },\r\n WebXRHandTracking.Version,\r\n false\r\n);\r\n"]}
|
|
1
|
+
{"version":3,"file":"WebXRHandTracking.js","sourceRoot":"","sources":["../../../../sourceES6/core/XR/features/WebXRHandTracking.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebXRAbstractFeature } from \"./WebXRAbstractFeature\";\r\nimport { WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { WebXRFeatureName } from \"../webXRFeaturesManager\";\r\nimport { AbstractMesh } from \"../../Meshes/abstractMesh\";\r\nimport { Mesh } from \"../../Meshes/mesh\";\r\nimport { SphereBuilder } from \"../../Meshes/Builders/sphereBuilder\";\r\nimport { WebXRInput } from \"../webXRInput\";\r\nimport { WebXRInputSource } from \"../webXRInputSource\";\r\nimport { Quaternion } from \"../../Maths/math.vector\";\r\nimport { Nullable } from \"../../types\";\r\nimport { PhysicsImpostor } from \"../../Physics/physicsImpostor\";\r\nimport { WebXRFeaturesManager } from \"../webXRFeaturesManager\";\r\nimport { IDisposable, Scene } from \"../../scene\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport { InstancedMesh } from \"../../Meshes/instancedMesh\";\r\nimport { SceneLoader } from \"../../Loading/sceneLoader\";\r\nimport { Color3 } from \"../../Maths/math.color\";\r\nimport { NodeMaterial } from \"../../Materials/Node/nodeMaterial\";\r\nimport { InputBlock } from \"../../Materials/Node/Blocks/Input/inputBlock\";\r\nimport { Material } from \"../../Materials/material\";\r\nimport { Engine } from \"../../Engines/engine\";\r\nimport { Tools } from \"../../Misc/tools\";\r\nimport { Axis } from \"../../Maths/math.axis\";\r\nimport { TransformNode } from \"../../Meshes/transformNode\";\r\n\r\ndeclare const XRHand: XRHand;\r\n\r\n/**\r\n * Configuration interface for the hand tracking feature\r\n */\r\nexport interface IWebXRHandTrackingOptions {\r\n /**\r\n * The xrInput that will be used as source for new hands\r\n */\r\n xrInput: WebXRInput;\r\n\r\n /**\r\n * Configuration object for the joint meshes\r\n */\r\n jointMeshes?: {\r\n /**\r\n * Should the meshes created be invisible (defaults to false)\r\n */\r\n invisible?: boolean;\r\n /**\r\n * A source mesh to be used to create instances. Defaults to a sphere.\r\n * This mesh will be the source for all other (25) meshes.\r\n * It should have the general size of a single unit, as the instances will be scaled according to the provided radius\r\n */\r\n sourceMesh?: Mesh;\r\n\r\n /**\r\n * This function will be called after a mesh was created for a specific joint.\r\n * Using this function you can either manipulate the instance or return a new mesh.\r\n * When returning a new mesh the instance created before will be disposed\r\n */\r\n onHandJointMeshGenerated?: (meshInstance: InstancedMesh, jointId: number, controllerId: string) => Mesh | undefined;\r\n /**\r\n * Should the source mesh stay visible. Defaults to false\r\n */\r\n keepOriginalVisible?: boolean;\r\n /**\r\n * Scale factor for all instances (defaults to 2)\r\n */\r\n scaleFactor?: number;\r\n /**\r\n * Should each instance have its own physics impostor\r\n */\r\n enablePhysics?: boolean;\r\n /**\r\n * If enabled, override default physics properties\r\n */\r\n physicsProps?: { friction?: number; restitution?: number; impostorType?: number };\r\n /**\r\n * Should the default hand mesh be disabled. In this case, the spheres will be visible (unless set invisible).\r\n */\r\n disableDefaultHandMesh?: boolean;\r\n /**\r\n * a rigged hand-mesh that will be updated according to the XRHand data provided. This will override the default hand mesh\r\n */\r\n handMeshes?: {\r\n right: AbstractMesh;\r\n left: AbstractMesh;\r\n };\r\n /**\r\n * If a hand mesh was provided, this array will define what axis will update which node. This will override the default hand mesh\r\n */\r\n rigMapping?: {\r\n right: string[];\r\n left: string[];\r\n };\r\n };\r\n}\r\n\r\n/**\r\n * Parts of the hands divided to writs and finger names\r\n */\r\nexport const enum HandPart {\r\n /**\r\n * HandPart - Wrist\r\n */\r\n WRIST = \"wrist\",\r\n /**\r\n * HandPart - The THumb\r\n */\r\n THUMB = \"thumb\",\r\n /**\r\n * HandPart - Index finger\r\n */\r\n INDEX = \"index\",\r\n /**\r\n * HandPart - Middle finger\r\n */\r\n MIDDLE = \"middle\",\r\n /**\r\n * HandPart - Ring finger\r\n */\r\n RING = \"ring\",\r\n /**\r\n * HandPart - Little finger\r\n */\r\n LITTLE = \"little\",\r\n}\r\n\r\n/**\r\n * Representing a single hand (with its corresponding native XRHand object)\r\n */\r\nexport class WebXRHand implements IDisposable {\r\n private _scene: Scene;\r\n private _defaultHandMesh: boolean = false;\r\n private _transformNodeMapping: TransformNode[] = [];\r\n /**\r\n * Hand-parts definition (key is HandPart)\r\n */\r\n public handPartsDefinition: { [key: string]: number[] };\r\n\r\n /**\r\n * Populate the HandPartsDefinition object.\r\n * This is called as a side effect since certain browsers don't have XRHand defined.\r\n */\r\n private generateHandPartsDefinition(hand: XRHand) {\r\n return {\r\n [HandPart.WRIST]: [hand.WRIST],\r\n [HandPart.THUMB]: [hand.THUMB_METACARPAL, hand.THUMB_PHALANX_PROXIMAL, hand.THUMB_PHALANX_DISTAL, hand.THUMB_PHALANX_TIP],\r\n [HandPart.INDEX]: [hand.INDEX_METACARPAL, hand.INDEX_PHALANX_PROXIMAL, hand.INDEX_PHALANX_INTERMEDIATE, hand.INDEX_PHALANX_DISTAL, hand.INDEX_PHALANX_TIP],\r\n [HandPart.MIDDLE]: [hand.MIDDLE_METACARPAL, hand.MIDDLE_PHALANX_PROXIMAL, hand.MIDDLE_PHALANX_INTERMEDIATE, hand.MIDDLE_PHALANX_DISTAL, hand.MIDDLE_PHALANX_TIP],\r\n [HandPart.RING]: [hand.RING_METACARPAL, hand.RING_PHALANX_PROXIMAL, hand.RING_PHALANX_INTERMEDIATE, hand.RING_PHALANX_DISTAL, hand.RING_PHALANX_TIP],\r\n [HandPart.LITTLE]: [hand.LITTLE_METACARPAL, hand.LITTLE_PHALANX_PROXIMAL, hand.LITTLE_PHALANX_INTERMEDIATE, hand.LITTLE_PHALANX_DISTAL, hand.LITTLE_PHALANX_TIP],\r\n };\r\n }\r\n\r\n /**\r\n * Construct a new hand object\r\n * @param xrController the controller to which the hand correlates\r\n * @param trackedMeshes the meshes to be used to track the hand joints\r\n * @param _handMesh an optional hand mesh. if not provided, ours will be used\r\n * @param _rigMapping an optional rig mapping for the hand mesh. if not provided, ours will be used\r\n * @param disableDefaultHandMesh should the default mesh creation be disabled\r\n */\r\n constructor(\r\n /** the controller to which the hand correlates */\r\n public readonly xrController: WebXRInputSource,\r\n /** the meshes to be used to track the hand joints */\r\n public readonly trackedMeshes: AbstractMesh[],\r\n private _handMesh?: AbstractMesh,\r\n private _rigMapping?: string[],\r\n disableDefaultHandMesh?: boolean\r\n ) {\r\n this.handPartsDefinition = this.generateHandPartsDefinition(xrController.inputSource.hand!);\r\n this._scene = trackedMeshes[0].getScene();\r\n if (this._handMesh && this._rigMapping) {\r\n this._defaultHandMesh = false;\r\n } else {\r\n if (!disableDefaultHandMesh) {\r\n this._generateDefaultHandMesh();\r\n }\r\n }\r\n\r\n // hide the motion controller, if available/loaded\r\n if (this.xrController.motionController) {\r\n if (this.xrController.motionController.rootMesh) {\r\n this.xrController.motionController.rootMesh.setEnabled(false);\r\n } else {\r\n this.xrController.motionController.onModelLoadedObservable.add((controller) => {\r\n if (controller.rootMesh) {\r\n controller.rootMesh.setEnabled(false);\r\n }\r\n });\r\n }\r\n }\r\n\r\n this.xrController.onMotionControllerInitObservable.add((motionController) => {\r\n motionController.onModelLoadedObservable.add((controller) => {\r\n if (controller.rootMesh) {\r\n controller.rootMesh.setEnabled(false);\r\n }\r\n });\r\n if (motionController.rootMesh) {\r\n motionController.rootMesh.setEnabled(false);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Update this hand from the latest xr frame\r\n * @param xrFrame xrFrame to update from\r\n * @param referenceSpace The current viewer reference space\r\n * @param scaleFactor optional scale factor for the meshes\r\n */\r\n public updateFromXRFrame(xrFrame: XRFrame, referenceSpace: XRReferenceSpace, scaleFactor: number = 2) {\r\n const hand = this.xrController.inputSource.hand;\r\n if (!hand) {\r\n return;\r\n }\r\n this.trackedMeshes.forEach((mesh, idx) => {\r\n const xrJoint = hand[idx];\r\n if (xrJoint) {\r\n let pose = xrFrame.getJointPose!(xrJoint, referenceSpace);\r\n if (!pose || !pose.transform) {\r\n return;\r\n }\r\n // get the transformation. can be done with matrix decomposition as well\r\n const pos = pose.transform.position;\r\n const orientation = pose.transform.orientation;\r\n mesh.position.set(pos.x, pos.y, pos.z);\r\n mesh.rotationQuaternion!.set(orientation.x, orientation.y, orientation.z, orientation.w);\r\n // left handed system conversion\r\n // get the radius of the joint. In general it is static, but just in case it does change we update it on each frame.\r\n const radius = (pose.radius || 0.008) * scaleFactor;\r\n mesh.scaling.set(radius, radius, radius);\r\n\r\n // now check for the hand mesh\r\n if (this._handMesh && this._rigMapping) {\r\n if (this._rigMapping[idx]) {\r\n this._transformNodeMapping[idx] = this._transformNodeMapping[idx] || this._scene.getTransformNodeByName(this._rigMapping[idx]);\r\n if (this._transformNodeMapping[idx]) {\r\n this._transformNodeMapping[idx].position.copyFrom(mesh.position);\r\n this._transformNodeMapping[idx].rotationQuaternion!.copyFrom(mesh.rotationQuaternion!);\r\n // no scaling at the moment\r\n // this._transformNodeMapping[idx].scaling.copyFrom(mesh.scaling).scaleInPlace(20);\r\n mesh.isVisible = false;\r\n }\r\n }\r\n }\r\n if (!mesh.getScene().useRightHandedSystem) {\r\n mesh.position.z *= -1;\r\n mesh.rotationQuaternion!.z *= -1;\r\n mesh.rotationQuaternion!.w *= -1;\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Get meshes of part of the hand\r\n * @param part the part of hand to get\r\n * @returns An array of meshes that correlate to the hand part requested\r\n */\r\n public getHandPartMeshes(part: HandPart): AbstractMesh[] {\r\n return this.handPartsDefinition[part].map((idx) => this.trackedMeshes[idx]);\r\n }\r\n\r\n /**\r\n * Dispose this Hand object\r\n */\r\n public dispose() {\r\n this.trackedMeshes.forEach((mesh) => mesh.dispose());\r\n // dispose the hand mesh, if it is the default one\r\n if (this._defaultHandMesh && this._handMesh) {\r\n this._handMesh.dispose();\r\n }\r\n }\r\n\r\n private async _generateDefaultHandMesh() {\r\n try {\r\n const handedness = this.xrController.inputSource.handedness === \"right\" ? \"right\" : \"left\";\r\n const filename = `${handedness === \"right\" ? \"r\" : \"l\"}_hand_${this._scene.useRightHandedSystem ? \"r\" : \"l\"}hs.glb`;\r\n const loaded = await SceneLoader.ImportMeshAsync(\"\", \"https://assets.babylonjs.com/meshes/HandMeshes/\", filename, this._scene);\r\n // shader\r\n const handColors = {\r\n base: Color3.FromInts(116, 63, 203),\r\n fresnel: Color3.FromInts(149, 102, 229),\r\n fingerColor: Color3.FromInts(177, 130, 255),\r\n tipFresnel: Color3.FromInts(220, 200, 255),\r\n };\r\n\r\n const handShader = new NodeMaterial(\"leftHandShader\", this._scene, { emitComments: false });\r\n await handShader.loadAsync(\"https://patrickryanms.github.io/BabylonJStextures/Demos/xrHandMesh/handsShader.json\");\r\n // build node materials\r\n handShader.build(false);\r\n\r\n // depth prepass and alpha mode\r\n handShader.needDepthPrePass = true;\r\n handShader.transparencyMode = Material.MATERIAL_ALPHABLEND;\r\n handShader.alphaMode = Engine.ALPHA_COMBINE;\r\n\r\n const handNodes = {\r\n base: handShader.getBlockByName(\"baseColor\") as InputBlock,\r\n fresnel: handShader.getBlockByName(\"fresnelColor\") as InputBlock,\r\n fingerColor: handShader.getBlockByName(\"fingerColor\") as InputBlock,\r\n tipFresnel: handShader.getBlockByName(\"tipFresnelColor\") as InputBlock,\r\n };\r\n\r\n handNodes.base.value = handColors.base;\r\n handNodes.fresnel.value = handColors.fresnel;\r\n handNodes.fingerColor.value = handColors.fingerColor;\r\n handNodes.tipFresnel.value = handColors.tipFresnel;\r\n\r\n loaded.meshes[1].material = handShader;\r\n\r\n this._defaultHandMesh = true;\r\n this._handMesh = loaded.meshes[0];\r\n this._rigMapping = [\r\n \"wrist_\",\r\n \"thumb_metacarpal_\",\r\n \"thumb_proxPhalanx_\",\r\n \"thumb_distPhalanx_\",\r\n \"thumb_tip_\",\r\n \"index_metacarpal_\",\r\n \"index_proxPhalanx_\",\r\n \"index_intPhalanx_\",\r\n \"index_distPhalanx_\",\r\n \"index_tip_\",\r\n \"middle_metacarpal_\",\r\n \"middle_proxPhalanx_\",\r\n \"middle_intPhalanx_\",\r\n \"middle_distPhalanx_\",\r\n \"middle_tip_\",\r\n \"ring_metacarpal_\",\r\n \"ring_proxPhalanx_\",\r\n \"ring_intPhalanx_\",\r\n \"ring_distPhalanx_\",\r\n \"ring_tip_\",\r\n \"little_metacarpal_\",\r\n \"little_proxPhalanx_\",\r\n \"little_intPhalanx_\",\r\n \"little_distPhalanx_\",\r\n \"little_tip_\",\r\n ].map((joint) => `${joint}${handedness === \"right\" ? \"R\" : \"L\"}`);\r\n // single change for left handed systems\r\n const tm = this._scene.getTransformNodeByName(this._rigMapping[0]);\r\n if (!tm) {\r\n throw new Error(\"could not find the wrist node\");\r\n } else {\r\n tm.parent && (tm.parent as AbstractMesh).rotate(Axis.Y, Math.PI);\r\n }\r\n } catch (e) {\r\n Tools.Error(\"error loading hand mesh\");\r\n console.log(e);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * WebXR Hand Joint tracking feature, available for selected browsers and devices\r\n */\r\nexport class WebXRHandTracking extends WebXRAbstractFeature {\r\n private static _idCounter = 0;\r\n /**\r\n * The module's name\r\n */\r\n public static readonly Name = WebXRFeatureName.HAND_TRACKING;\r\n /**\r\n * The (Babylon) version of this module.\r\n * This is an integer representing the implementation version.\r\n * This number does not correspond to the WebXR specs version\r\n */\r\n public static readonly Version = 1;\r\n\r\n /**\r\n * This observable will notify registered observers when a new hand object was added and initialized\r\n */\r\n public onHandAddedObservable: Observable<WebXRHand> = new Observable();\r\n /**\r\n * This observable will notify its observers right before the hand object is disposed\r\n */\r\n public onHandRemovedObservable: Observable<WebXRHand> = new Observable();\r\n\r\n private _hands: {\r\n [controllerId: string]: {\r\n id: number;\r\n handObject: WebXRHand;\r\n };\r\n } = {};\r\n\r\n /**\r\n * Creates a new instance of the hit test feature\r\n * @param _xrSessionManager an instance of WebXRSessionManager\r\n * @param options options to use when constructing this feature\r\n */\r\n constructor(\r\n _xrSessionManager: WebXRSessionManager,\r\n /**\r\n * options to use when constructing this feature\r\n */\r\n public readonly options: IWebXRHandTrackingOptions\r\n ) {\r\n super(_xrSessionManager);\r\n this.xrNativeFeatureName = \"hand-tracking\";\r\n }\r\n\r\n /**\r\n * Check if the needed objects are defined.\r\n * This does not mean that the feature is enabled, but that the objects needed are well defined.\r\n */\r\n public isCompatible(): boolean {\r\n return typeof XRHand !== \"undefined\";\r\n }\r\n\r\n /**\r\n * attach this feature\r\n * Will usually be called by the features manager\r\n *\r\n * @returns true if successful.\r\n */\r\n public attach(): boolean {\r\n if (!super.attach()) {\r\n return false;\r\n }\r\n this.options.xrInput.controllers.forEach(this._attachHand);\r\n this._addNewAttachObserver(this.options.xrInput.onControllerAddedObservable, this._attachHand);\r\n this._addNewAttachObserver(this.options.xrInput.onControllerRemovedObservable, (controller) => {\r\n // REMOVE the controller\r\n this._detachHand(controller.uniqueId);\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * detach this feature.\r\n * Will usually be called by the features manager\r\n *\r\n * @returns true if successful.\r\n */\r\n public detach(): boolean {\r\n if (!super.detach()) {\r\n return false;\r\n }\r\n\r\n Object.keys(this._hands).forEach((controllerId) => {\r\n this._detachHand(controllerId);\r\n });\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Dispose this feature and all of the resources attached\r\n */\r\n public dispose(): void {\r\n super.dispose();\r\n this.onHandAddedObservable.clear();\r\n }\r\n\r\n /**\r\n * Get the hand object according to the controller id\r\n * @param controllerId the controller id to which we want to get the hand\r\n * @returns null if not found or the WebXRHand object if found\r\n */\r\n public getHandByControllerId(controllerId: string): Nullable<WebXRHand> {\r\n return this._hands[controllerId]?.handObject || null;\r\n }\r\n\r\n /**\r\n * Get a hand object according to the requested handedness\r\n * @param handedness the handedness to request\r\n * @returns null if not found or the WebXRHand object if found\r\n */\r\n public getHandByHandedness(handedness: XRHandedness): Nullable<WebXRHand> {\r\n const handednesses = Object.keys(this._hands).map((key) => this._hands[key].handObject.xrController.inputSource.handedness);\r\n const found = handednesses.indexOf(handedness);\r\n if (found !== -1) {\r\n return this._hands[found].handObject;\r\n }\r\n return null;\r\n }\r\n\r\n protected _onXRFrame(_xrFrame: XRFrame): void {\r\n // iterate over the hands object\r\n Object.keys(this._hands).forEach((id) => {\r\n this._hands[id].handObject.updateFromXRFrame(_xrFrame, this._xrSessionManager.referenceSpace, this.options.jointMeshes?.scaleFactor);\r\n });\r\n }\r\n\r\n private _attachHand = (xrController: WebXRInputSource) => {\r\n if (!xrController.inputSource.hand || this._hands[xrController.uniqueId]) {\r\n // already attached\r\n return;\r\n }\r\n\r\n const hand = xrController.inputSource.hand;\r\n const trackedMeshes: AbstractMesh[] = [];\r\n const originalMesh = this.options.jointMeshes?.sourceMesh || SphereBuilder.CreateSphere(\"jointParent\", { diameter: 1 });\r\n originalMesh.isVisible = !!this.options.jointMeshes?.keepOriginalVisible;\r\n for (let i = 0; i < hand.length; ++i) {\r\n let newInstance: AbstractMesh = originalMesh.createInstance(`${xrController.uniqueId}-handJoint-${i}`);\r\n if (this.options.jointMeshes?.onHandJointMeshGenerated) {\r\n const returnedMesh = this.options.jointMeshes.onHandJointMeshGenerated(newInstance as InstancedMesh, i, xrController.uniqueId);\r\n if (returnedMesh) {\r\n if (returnedMesh !== newInstance) {\r\n newInstance.dispose();\r\n newInstance = returnedMesh;\r\n }\r\n }\r\n }\r\n newInstance.isPickable = false;\r\n if (this.options.jointMeshes?.enablePhysics) {\r\n const props = this.options.jointMeshes.physicsProps || {};\r\n const type = props.impostorType !== undefined ? props.impostorType : PhysicsImpostor.SphereImpostor;\r\n newInstance.physicsImpostor = new PhysicsImpostor(newInstance, type, { mass: 0, ...props });\r\n }\r\n newInstance.rotationQuaternion = new Quaternion();\r\n if (this.options.jointMeshes?.invisible) {\r\n newInstance.isVisible = false;\r\n }\r\n trackedMeshes.push(newInstance);\r\n }\r\n\r\n const handedness = xrController.inputSource.handedness === \"right\" ? \"right\" : \"left\";\r\n const handMesh = this.options.jointMeshes?.handMeshes && this.options.jointMeshes?.handMeshes[handedness];\r\n const rigMapping = this.options.jointMeshes?.rigMapping && this.options.jointMeshes?.rigMapping[handedness];\r\n const webxrHand = new WebXRHand(xrController, trackedMeshes, handMesh, rigMapping, this.options.jointMeshes?.disableDefaultHandMesh);\r\n\r\n // get two new meshes\r\n this._hands[xrController.uniqueId] = {\r\n handObject: webxrHand,\r\n id: WebXRHandTracking._idCounter++,\r\n };\r\n\r\n this.onHandAddedObservable.notifyObservers(webxrHand);\r\n };\r\n\r\n private _detachHand(controllerId: string) {\r\n if (this._hands[controllerId]) {\r\n this.onHandRemovedObservable.notifyObservers(this._hands[controllerId].handObject);\r\n this._hands[controllerId].handObject.dispose();\r\n }\r\n }\r\n}\r\n\r\n//register the plugin\r\nWebXRFeaturesManager.AddWebXRFeature(\r\n WebXRHandTracking.Name,\r\n (xrSessionManager, options) => {\r\n return () => new WebXRHandTracking(xrSessionManager, options);\r\n },\r\n WebXRHandTracking.Version,\r\n false\r\n);\r\n"]}
|
package/package.json
CHANGED