diff --git a/dist/claygl.es.js b/dist/claygl.es.js index 17696fcb7..ce2257200 100644 --- a/dist/claygl.es.js +++ b/dist/claygl.es.js @@ -6165,6 +6165,8 @@ if (typeof window !== 'undefined') { else if (typeof global !== 'undefined') { g = global; } + + vendor.requestAnimationFrame = g.requestAnimationFrame || g.msRequestAnimationFrame || g.mozRequestAnimationFrame @@ -6183,6 +6185,14 @@ vendor.request = { get: request.get }; +vendor.addEventListener = function (dom, type, func, useCapture) { + dom.addEventListener(type, func, useCapture); +}; + +vendor.removeEventListener = function (dom, type, func) { + dom.removeEventListener(type, func); +}; + /** * Animation is global timeline that schedule all clips. each frame animation will set the time of clips to current and update the states of clips * @constructor clay.Timeline @@ -11214,7 +11224,9 @@ var Renderer = Base.extend(function () { var currentVAO; var materialTakesTextureSlot; - var vaoExt = this.getGLExtension('OES_vertex_array_object'); + // var vaoExt = this.getGLExtension('OES_vertex_array_object'); + // not use vaoExt, some platforms may mess it up. + var vaoExt = null; for (var i = 0; i < list.length; i++) { var renderable = list[i]; @@ -19176,11 +19188,9 @@ var Texture2D = Texture.extend(function () { image.onload = function () { self.dirty(); self.trigger('success', self); - image.onload = null; }; image.onerror = function () { self.trigger('error', self); - image.onerror = null; }; image.src = src; @@ -19437,11 +19447,9 @@ var TextureCube = Texture.extend(function () { self.dirty(); self.trigger('success', self); } - image.onload = null; }; image.onerror = function () { loading --; - image.onerror = null; }; loading++; @@ -20681,9 +20689,9 @@ var Skeleton = Base.extend(function () { var utilGlsl = "\n@export clay.util.rand\nhighp float rand(vec2 uv) {\n const highp float a = 12.9898, b = 78.233, c = 43758.5453;\n highp float dt = dot(uv.xy, vec2(a,b)), sn = mod(dt, 3.141592653589793);\n return fract(sin(sn) * c);\n}\n@end\n@export clay.util.calculate_attenuation\nuniform float attenuationFactor : 5.0;\nfloat lightAttenuation(float dist, float range)\n{\n float attenuation = 1.0;\n attenuation = dist*dist/(range*range+1.0);\n float att_s = attenuationFactor;\n attenuation = 1.0/(attenuation*att_s+1.0);\n att_s = 1.0/(att_s+1.0);\n attenuation = attenuation - att_s;\n attenuation /= 1.0 - att_s;\n return clamp(attenuation, 0.0, 1.0);\n}\n@end\n@export clay.util.edge_factor\n#ifdef SUPPORT_STANDARD_DERIVATIVES\nfloat edgeFactor(float width)\n{\n vec3 d = fwidth(v_Barycentric);\n vec3 a3 = smoothstep(vec3(0.0), d * width, v_Barycentric);\n return min(min(a3.x, a3.y), a3.z);\n}\n#else\nfloat edgeFactor(float width)\n{\n return 1.0;\n}\n#endif\n@end\n@export clay.util.encode_float\nvec4 encodeFloat(const in float depth)\n{\n const vec4 bitShifts = vec4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0);\n vec4 res = fract(depth * bitShifts);\n res -= res.xxyz * bit_mask;\n return res;\n}\n@end\n@export clay.util.decode_float\nfloat decodeFloat(const in vec4 color)\n{\n const vec4 bitShifts = vec4(1.0/(256.0*256.0*256.0), 1.0/(256.0*256.0), 1.0/256.0, 1.0);\n return dot(color, bitShifts);\n}\n@end\n@export clay.util.float\n@import clay.util.encode_float\n@import clay.util.decode_float\n@end\n@export clay.util.rgbm_decode\nvec3 RGBMDecode(vec4 rgbm, float range) {\n return range * rgbm.rgb * rgbm.a;\n}\n@end\n@export clay.util.rgbm_encode\nvec4 RGBMEncode(vec3 color, float range) {\n if (dot(color, color) == 0.0) {\n return vec4(0.0);\n }\n vec4 rgbm;\n color /= range;\n rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 1e-6)), 0.0, 1.0);\n rgbm.a = ceil(rgbm.a * 255.0) / 255.0;\n rgbm.rgb = color / rgbm.a;\n return rgbm;\n}\n@end\n@export clay.util.rgbm\n@import clay.util.rgbm_decode\n@import clay.util.rgbm_encode\nvec4 decodeHDR(vec4 color)\n{\n#if defined(RGBM_DECODE) || defined(RGBM)\n return vec4(RGBMDecode(color, 8.12), 1.0);\n#else\n return color;\n#endif\n}\nvec4 encodeHDR(vec4 color)\n{\n#if defined(RGBM_ENCODE) || defined(RGBM)\n return RGBMEncode(color.xyz, 8.12);\n#else\n return color;\n#endif\n}\n@end\n@export clay.util.srgb\nvec4 sRGBToLinear(in vec4 value) {\n return vec4(mix(pow(value.rgb * 0.9478672986 + vec3(0.0521327014), vec3(2.4)), value.rgb * 0.0773993808, vec3(lessThanEqual(value.rgb, vec3(0.04045)))), value.w);\n}\nvec4 linearTosRGB(in vec4 value) {\n return vec4(mix(pow(value.rgb, vec3(0.41666)) * 1.055 - vec3(0.055), value.rgb * 12.92, vec3(lessThanEqual(value.rgb, vec3(0.0031308)))), value.w);\n}\n@end\n@export clay.chunk.skinning_header\n#ifdef SKINNING\nattribute vec3 weight : WEIGHT;\nattribute vec4 joint : JOINT;\n#ifdef USE_SKIN_MATRICES_TEXTURE\nuniform sampler2D skinMatricesTexture : ignore;\nuniform float skinMatricesTextureSize: ignore;\nmat4 getSkinMatrix(sampler2D tex, float idx) {\n float j = idx * 4.0;\n float x = mod(j, skinMatricesTextureSize);\n float y = floor(j / skinMatricesTextureSize) + 0.5;\n vec2 scale = vec2(skinMatricesTextureSize);\n return mat4(\n texture2D(tex, vec2(x + 0.5, y) / scale),\n texture2D(tex, vec2(x + 1.5, y) / scale),\n texture2D(tex, vec2(x + 2.5, y) / scale),\n texture2D(tex, vec2(x + 3.5, y) / scale)\n );\n}\nmat4 getSkinMatrix(float idx) {\n return getSkinMatrix(skinMatricesTexture, idx);\n}\n#else\nuniform mat4 skinMatrix[JOINT_COUNT] : SKIN_MATRIX;\nmat4 getSkinMatrix(float idx) {\n return skinMatrix[int(idx)];\n}\n#endif\n#endif\n@end\n@export clay.chunk.skin_matrix\nmat4 skinMatrixWS = getSkinMatrix(joint.x) * weight.x;\nif (weight.y > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.y) * weight.y;\n}\nif (weight.z > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.z) * weight.z;\n}\nfloat weightW = 1.0-weight.x-weight.y-weight.z;\nif (weightW > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.w) * weightW;\n}\n@end\n@export clay.util.parallax_correct\nvec3 parallaxCorrect(in vec3 dir, in vec3 pos, in vec3 boxMin, in vec3 boxMax) {\n vec3 first = (boxMax - pos) / dir;\n vec3 second = (boxMin - pos) / dir;\n vec3 further = max(first, second);\n float dist = min(further.x, min(further.y, further.z));\n vec3 fixedPos = pos + dir * dist;\n vec3 boxCenter = (boxMax + boxMin) * 0.5;\n return normalize(fixedPos - boxCenter);\n}\n@end\n@export clay.util.clamp_sample\nvec4 clampSample(const in sampler2D texture, const in vec2 coord)\n{\n#ifdef STEREO\n float eye = step(0.5, coord.x) * 0.5;\n vec2 coordClamped = clamp(coord, vec2(eye, 0.0), vec2(0.5 + eye, 1.0));\n#else\n vec2 coordClamped = clamp(coord, vec2(0.0), vec2(1.0));\n#endif\n return texture2D(texture, coordClamped);\n}\n@end\n@export clay.util.ACES\nvec3 ACESToneMapping(vec3 color)\n{\n const float A = 2.51;\n const float B = 0.03;\n const float C = 2.43;\n const float D = 0.59;\n const float E = 0.14;\n return (color * (A * color + B)) / (color * (C * color + D) + E);\n}\n@end"; -var basicEssl = "@export clay.basic.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 position : POSITION;\nattribute vec3 barycentric;\n@import clay.chunk.skinning_header\nvarying vec2 v_Texcoord;\nvarying vec3 v_Barycentric;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\nvoid main()\n{\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n v_Barycentric = barycentric;\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0);\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n}\n@end\n@export clay.basic.fragment\nvarying vec2 v_Texcoord;\nuniform sampler2D diffuseMap;\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform vec3 emission : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\n#ifdef ALPHA_TEST\nuniform float alphaCutoff: 0.9;\n#endif\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\nuniform float lineWidth : 0.0;\nuniform vec4 lineColor : [0.0, 0.0, 0.0, 0.6];\nvarying vec3 v_Barycentric;\n@import clay.util.edge_factor\n@import clay.util.rgbm\n@import clay.util.srgb\n@import clay.util.ACES\nvoid main()\n{\n gl_FragColor = vec4(color, alpha);\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(gl_FragColor);\n#endif\n#ifdef DIFFUSEMAP_ENABLED\n vec4 texel = decodeHDR(texture2D(diffuseMap, v_Texcoord));\n#ifdef SRGB_DECODE\n texel = sRGBToLinear(texel);\n#endif\n#if defined(DIFFUSEMAP_ALPHA_ALPHA)\n gl_FragColor.a = texel.a;\n#endif\n gl_FragColor.rgb *= texel.rgb;\n#endif\n gl_FragColor.rgb += emission;\n if( lineWidth > 0.)\n {\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (gl_FragColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n gl_FragColor.rgb = ACESToneMapping(gl_FragColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n}\n@end"; +var basicEssl = "@export clay.basic.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 position : POSITION;\nattribute vec3 barycentric;\n@import clay.chunk.skinning_header\nvarying vec2 v_Texcoord;\nvarying vec3 v_Barycentric;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\nvoid main()\n{\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n v_Barycentric = barycentric;\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0);\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n}\n@end\n@export clay.basic.fragment\n#define DIFFUSEMAP_ALPHA_ALPHA\nvarying vec2 v_Texcoord;\nuniform sampler2D diffuseMap;\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform vec3 emission : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\n#ifdef ALPHA_TEST\nuniform float alphaCutoff: 0.9;\n#endif\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\nuniform float lineWidth : 0.0;\nuniform vec4 lineColor : [0.0, 0.0, 0.0, 0.6];\nvarying vec3 v_Barycentric;\n@import clay.util.edge_factor\n@import clay.util.rgbm\n@import clay.util.srgb\n@import clay.util.ACES\nvoid main()\n{\n gl_FragColor = vec4(color, alpha);\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(gl_FragColor);\n#endif\n#ifdef DIFFUSEMAP_ENABLED\n vec4 texel = decodeHDR(texture2D(diffuseMap, v_Texcoord));\n#ifdef SRGB_DECODE\n texel = sRGBToLinear(texel);\n#endif\n#if defined(DIFFUSEMAP_ALPHA_ALPHA)\n gl_FragColor.a = texel.a;\n#endif\n gl_FragColor.rgb *= texel.rgb;\n#endif\n gl_FragColor.rgb += emission;\n if( lineWidth > 0.)\n {\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (gl_FragColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n gl_FragColor.rgb = ACESToneMapping(gl_FragColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n}\n@end"; -var lambertEssl = "\n@export clay.lambert.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 normal : NORMAL;\nattribute vec3 barycentric;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n@import clay.chunk.skinning_header\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nvarying vec3 v_Barycentric;\nvoid main()\n{\n vec3 skinnedPosition = position;\n vec3 skinnedNormal = normal;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n skinnedNormal = (skinMatrixWS * vec4(normal, 0.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4( skinnedPosition, 1.0 );\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n v_Normal = normalize( ( worldInverseTranspose * vec4(skinnedNormal, 0.0) ).xyz );\n v_WorldPosition = ( world * vec4( skinnedPosition, 1.0) ).xyz;\n v_Barycentric = barycentric;\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n}\n@end\n@export clay.lambert.fragment\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nuniform sampler2D diffuseMap;\nuniform sampler2D alphaMap;\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform vec3 emission : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\n#ifdef ALPHA_TEST\nuniform float alphaCutoff: 0.9;\n#endif\nuniform float lineWidth : 0.0;\nuniform vec4 lineColor : [0.0, 0.0, 0.0, 0.6];\nvarying vec3 v_Barycentric;\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n#ifdef POINT_LIGHT_COUNT\n@import clay.header.point_light\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n#ifdef SPOT_LIGHT_COUNT\n@import clay.header.spot_light\n#endif\n@import clay.util.calculate_attenuation\n@import clay.util.edge_factor\n@import clay.util.rgbm\n@import clay.plugin.compute_shadow_map\n@import clay.util.ACES\nvoid main()\n{\n gl_FragColor = vec4(color, alpha);\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(gl_FragColor);\n#endif\n#ifdef DIFFUSEMAP_ENABLED\n vec4 tex = texture2D( diffuseMap, v_Texcoord );\n#ifdef SRGB_DECODE\n tex.rgb = pow(tex.rgb, vec3(2.2));\n#endif\n gl_FragColor.rgb *= tex.rgb;\n#ifdef DIFFUSEMAP_ALPHA_ALPHA\n gl_FragColor.a *= tex.a;\n#endif\n#endif\n vec3 diffuseColor = vec3(0.0, 0.0, 0.0);\n#ifdef AMBIENT_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_LIGHT_COUNT; _idx_++)\n {\n diffuseColor += ambientLightColor[_idx_];\n }\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseColor += calcAmbientSHLight(_idx_, v_Normal) * ambientSHLightColor[_idx_];\n }}\n#endif\n#ifdef POINT_LIGHT_COUNT\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsPoint[POINT_LIGHT_COUNT];\n if( shadowEnabled )\n {\n computeShadowOfPointLights(v_WorldPosition, shadowContribsPoint);\n }\n#endif\n for(int i = 0; i < POINT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = pointLightPosition[i];\n vec3 lightColor = pointLightColor[i];\n float range = pointLightRange[i];\n vec3 lightDirection = lightPosition - v_WorldPosition;\n float dist = length(lightDirection);\n float attenuation = lightAttenuation(dist, range);\n lightDirection /= dist;\n float ndl = dot( v_Normal, lightDirection );\n float shadowContrib = 1.0;\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsPoint[i];\n }\n#endif\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0) * attenuation * shadowContrib;\n }\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++)\n {\n vec3 lightDirection = -directionalLightDirection[i];\n vec3 lightColor = directionalLightColor[i];\n float ndl = dot(v_Normal, normalize(lightDirection));\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsDir[i];\n }\n#endif\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0) * shadowContrib;\n }\n#endif\n#ifdef SPOT_LIGHT_COUNT\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsSpot[SPOT_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfSpotLights(v_WorldPosition, shadowContribsSpot);\n }\n#endif\n for(int i = 0; i < SPOT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = -spotLightPosition[i];\n vec3 spotLightDirection = -normalize( spotLightDirection[i] );\n vec3 lightColor = spotLightColor[i];\n float range = spotLightRange[i];\n float a = spotLightUmbraAngleCosine[i];\n float b = spotLightPenumbraAngleCosine[i];\n float falloffFactor = spotLightFalloffFactor[i];\n vec3 lightDirection = lightPosition - v_WorldPosition;\n float dist = length(lightDirection);\n float attenuation = lightAttenuation(dist, range);\n lightDirection /= dist;\n float c = dot(spotLightDirection, lightDirection);\n float falloff;\n falloff = clamp((c - a) /( b - a), 0.0, 1.0);\n falloff = pow(falloff, falloffFactor);\n float ndl = dot(v_Normal, lightDirection);\n ndl = clamp(ndl, 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsSpot[i];\n }\n#endif\n diffuseColor += lightColor * ndl * attenuation * (1.0-falloff) * shadowContrib;\n }\n#endif\n gl_FragColor.rgb *= diffuseColor;\n gl_FragColor.rgb += emission;\n if(lineWidth > 0.)\n {\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (gl_FragColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n gl_FragColor.rgb = ACESToneMapping(gl_FragColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n}\n@end"; +var lambertEssl = "\n@export clay.lambert.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 normal : NORMAL;\nattribute vec3 barycentric;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n@import clay.chunk.skinning_header\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nvarying vec3 v_Barycentric;\nvoid main()\n{\n vec3 skinnedPosition = position;\n vec3 skinnedNormal = normal;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n skinnedNormal = (skinMatrixWS * vec4(normal, 0.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4( skinnedPosition, 1.0 );\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n v_Normal = normalize( ( worldInverseTranspose * vec4(skinnedNormal, 0.0) ).xyz );\n v_WorldPosition = ( world * vec4( skinnedPosition, 1.0) ).xyz;\n v_Barycentric = barycentric;\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n}\n@end\n@export clay.lambert.fragment\n#define DIFFUSEMAP_ALPHA_ALPHA\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nuniform sampler2D diffuseMap;\nuniform sampler2D alphaMap;\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform vec3 emission : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\n#ifdef ALPHA_TEST\nuniform float alphaCutoff: 0.9;\n#endif\nuniform float lineWidth : 0.0;\nuniform vec4 lineColor : [0.0, 0.0, 0.0, 0.6];\nvarying vec3 v_Barycentric;\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n#ifdef POINT_LIGHT_COUNT\n@import clay.header.point_light\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n#ifdef SPOT_LIGHT_COUNT\n@import clay.header.spot_light\n#endif\n@import clay.util.calculate_attenuation\n@import clay.util.edge_factor\n@import clay.util.rgbm\n@import clay.plugin.compute_shadow_map\n@import clay.util.ACES\nvoid main()\n{\n gl_FragColor = vec4(color, alpha);\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(gl_FragColor);\n#endif\n#ifdef DIFFUSEMAP_ENABLED\n vec4 tex = texture2D( diffuseMap, v_Texcoord );\n#ifdef SRGB_DECODE\n tex.rgb = pow(tex.rgb, vec3(2.2));\n#endif\n gl_FragColor.rgb *= tex.rgb;\n#ifdef DIFFUSEMAP_ALPHA_ALPHA\n gl_FragColor.a *= tex.a;\n#endif\n#endif\n vec3 diffuseColor = vec3(0.0, 0.0, 0.0);\n#ifdef AMBIENT_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_LIGHT_COUNT; _idx_++)\n {\n diffuseColor += ambientLightColor[_idx_];\n }\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseColor += calcAmbientSHLight(_idx_, v_Normal) * ambientSHLightColor[_idx_];\n }}\n#endif\n#ifdef POINT_LIGHT_COUNT\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsPoint[POINT_LIGHT_COUNT];\n if( shadowEnabled )\n {\n computeShadowOfPointLights(v_WorldPosition, shadowContribsPoint);\n }\n#endif\n for(int i = 0; i < POINT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = pointLightPosition[i];\n vec3 lightColor = pointLightColor[i];\n float range = pointLightRange[i];\n vec3 lightDirection = lightPosition - v_WorldPosition;\n float dist = length(lightDirection);\n float attenuation = lightAttenuation(dist, range);\n lightDirection /= dist;\n float ndl = dot( v_Normal, lightDirection );\n float shadowContrib = 1.0;\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsPoint[i];\n }\n#endif\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0) * attenuation * shadowContrib;\n }\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++)\n {\n vec3 lightDirection = -directionalLightDirection[i];\n vec3 lightColor = directionalLightColor[i];\n float ndl = dot(v_Normal, normalize(lightDirection));\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsDir[i];\n }\n#endif\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0) * shadowContrib;\n }\n#endif\n#ifdef SPOT_LIGHT_COUNT\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsSpot[SPOT_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfSpotLights(v_WorldPosition, shadowContribsSpot);\n }\n#endif\n for(int i = 0; i < SPOT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = -spotLightPosition[i];\n vec3 spotLightDirection = -normalize( spotLightDirection[i] );\n vec3 lightColor = spotLightColor[i];\n float range = spotLightRange[i];\n float a = spotLightUmbraAngleCosine[i];\n float b = spotLightPenumbraAngleCosine[i];\n float falloffFactor = spotLightFalloffFactor[i];\n vec3 lightDirection = lightPosition - v_WorldPosition;\n float dist = length(lightDirection);\n float attenuation = lightAttenuation(dist, range);\n lightDirection /= dist;\n float c = dot(spotLightDirection, lightDirection);\n float falloff;\n falloff = clamp((c - a) /( b - a), 0.0, 1.0);\n falloff = pow(falloff, falloffFactor);\n float ndl = dot(v_Normal, lightDirection);\n ndl = clamp(ndl, 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsSpot[i];\n }\n#endif\n diffuseColor += lightColor * ndl * attenuation * (1.0-falloff) * shadowContrib;\n }\n#endif\n gl_FragColor.rgb *= diffuseColor;\n gl_FragColor.rgb += emission;\n if(lineWidth > 0.)\n {\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (gl_FragColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n gl_FragColor.rgb = ACESToneMapping(gl_FragColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n}\n@end"; var wireframeEssl = "@export clay.wireframe.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 world : WORLD;\nattribute vec3 position : POSITION;\nattribute vec3 barycentric;\n@import clay.chunk.skinning_header\nvarying vec3 v_Barycentric;\nvoid main()\n{\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0 );\n v_Barycentric = barycentric;\n}\n@end\n@export clay.wireframe.fragment\nuniform vec3 color : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\nuniform float lineWidth : 1.0;\nvarying vec3 v_Barycentric;\n@import clay.util.edge_factor\nvoid main()\n{\n gl_FragColor.rgb = color;\n gl_FragColor.a = (1.0-edgeFactor(lineWidth)) * alpha;\n}\n@end"; @@ -25638,7 +25646,7 @@ function App3D(dom, appNS) { dom.innerHTML = ''; EVE_NAMES.forEach(function (eveType) { - this[makeHandlerName(eveType)] && dom.removeEventListener(makeHandlerName(eveType)); + this[makeHandlerName(eveType)] && vendor.removeEventListener(dom, makeHandlerName(eveType)); }, this); }; @@ -25729,11 +25737,11 @@ App3D.prototype._initMouseEvents = function (rayPicking) { var oldTarget = null; EVE_NAMES.forEach(function (_eveType) { - dom.addEventListener(_eveType, this[makeHandlerName(_eveType)] = function (e) { + vendor.addEventListener(dom, _eveType, this[makeHandlerName(_eveType)] = function (e) { if (!rayPicking.camera) { // Not have camera yet. return; } - e.preventDefault(); + e.preventDefault && e.preventDefault(); var box = dom.getBoundingClientRect(); var offsetX, offsetY; @@ -26403,6 +26411,9 @@ App3D.prototype.createCamera = function (position, target, type, extent) { camera.near = 0; camera.far = extent[2]; } + else { + camera.aspect = this.renderer.getViewportAspect(); + } this.scene.add(camera); @@ -27840,13 +27851,13 @@ var FilterNode$1 = CompositorNode.extend(function () { } } var width, height; - if (parameters.width instanceof Function) { + if (typeof parameters.width === 'function') { width = parameters.width.call(this, renderer); } else { width = parameters.width; } - if (parameters.height instanceof Function) { + if (typeof parameters.height === 'function') { height = parameters.height.call(this, renderer); } else { @@ -28119,7 +28130,7 @@ function createNode(nodeInfo, lib, opts) { if (nodeInfo.parameters) { for (var name in nodeInfo.parameters) { var val = nodeInfo.parameters[name]; - if (typeof(val) === 'string') { + if (typeof val === 'string') { val = val.trim(); if (val.charAt(0) === '#') { val = lib.textures[val.substr(1)]; @@ -28132,6 +28143,9 @@ function createNode(nodeInfo, lib, opts) { ); } } + else if (typeof val === 'function') { + node.on('beforerender', val); + } node.setParameter(name, val); } } @@ -32934,6 +32948,8 @@ function unpackID(r, g, b){ return (r << 16) + (g<<8) + b; } +var doc = typeof document === 'undefined' ? {} : document; + /** * @constructor clay.plugin.FreeControl * @example @@ -33020,14 +33036,14 @@ var FreeControl = Base.extend(function() { //Must request pointer lock after click event, can't not do it directly //Why ? ? - el.addEventListener('click', this._requestPointerLock); + vendor.addEventListener(el, 'click', this._requestPointerLock); - document.addEventListener('pointerlockchange', this._lockChange); - document.addEventListener('mozpointerlockchange', this._lockChange); - document.addEventListener('webkitpointerlockchange', this._lockChange); + vendor.addEventListener(doc, 'pointerlockchange', this._lockChange); + vendor.addEventListener(doc, 'mozpointerlockchange', this._lockChange); + vendor.addEventListener(doc, 'webkitpointerlockchange', this._lockChange); - document.addEventListener('keydown', this._keyDown); - document.addEventListener('keyup', this._keyUp); + vendor.addEventListener(doc, 'keydown', this._keyDown); + vendor.addEventListener(doc, 'keyup', this._keyUp); if (this.timeline) { this.timeline.on('frame', this._detectMovementChange, this); @@ -33049,14 +33065,14 @@ var FreeControl = Base.extend(function() { el.exitPointerLock(); } - this.domElement.removeEventListener('click', this._requestPointerLock); + vendor.removeEventListener(el, 'click', this._requestPointerLock); - document.removeEventListener('pointerlockchange', this._lockChange); - document.removeEventListener('mozpointerlockchange', this._lockChange); - document.removeEventListener('webkitpointerlockchange', this._lockChange); + vendor.removeEventListener(doc, 'pointerlockchange', this._lockChange); + vendor.removeEventListener(doc, 'mozpointerlockchange', this._lockChange); + vendor.removeEventListener(doc, 'webkitpointerlockchange', this._lockChange); - document.removeEventListener('keydown', this._keyDown); - document.removeEventListener('keyup', this._keyUp); + vendor.removeEventListener(doc, 'keydown', this._keyDown); + vendor.removeEventListener(doc, 'keyup', this._keyUp); if (this.timeline) { this.timeline.off('frame', this._detectMovementChange); @@ -33113,14 +33129,14 @@ var FreeControl = Base.extend(function() { _lockChange: function() { if ( - document.pointerLockElement === this.domElement - || document.mozPointerLockElement === this.domElement - || document.webkitPointerLockElement === this.domElement + doc.pointerLockElement === this.domElement + || doc.mozPointerLockElement === this.domElement + || doc.webkitPointerLockElement === this.domElement ) { - document.addEventListener('mousemove', this._mouseMove, false); + vendor.addEventListener(doc, 'mousemove', this._mouseMove, false); } else { - document.removeEventListener('mousemove', this._mouseMove); + vendor.removeEventListener(doc, 'mousemove', this._mouseMove); } }, @@ -33280,6 +33296,8 @@ var GamepadControl = Base.extend(function() { this._scanPressedGamepadButtons = this._scanPressedGamepadButtons.bind(this); this._scanInclinedGamepadAxes = this._scanInclinedGamepadAxes.bind(this); + this.update = this.update.bind(this); + // If browser supports Gamepad API: if (typeof navigator.getGamepads === 'function') { this.init(); @@ -33298,13 +33316,13 @@ var GamepadControl = Base.extend(function() { * * @see https://w3c.github.io/gamepad/#dom-gamepadevent */ - window.addEventListener('gamepadconnected', this._checkGamepadCompatibility); + vendor.addEventListener(window, 'gamepadconnected', this._checkGamepadCompatibility); if (this.timeline) { this.timeline.on('frame', this.update); } - window.addEventListener('gamepaddisconnected', this._disconnectGamepad); + vendor.addEventListener(window, 'gamepaddisconnected', this._disconnectGamepad); }, @@ -33313,13 +33331,13 @@ var GamepadControl = Base.extend(function() { */ dispose: function() { - window.removeEventListener('gamepadconnected', this._checkGamepadCompatibility); + vendor.removeEventListener(window, 'gamepadconnected', this._checkGamepadCompatibility); if (this.timeline) { this.timeline.off('frame', this.update); } - window.removeEventListener('gamepaddisconnected', this._disconnectGamepad); + vendor.removeEventListener(window, 'gamepaddisconnected', this._disconnectGamepad); }, @@ -33365,8 +33383,18 @@ var GamepadControl = Base.extend(function() { var xAxis = target.localTransform.x; target.rotateAround(target.position, xAxis, -this._offsetRoll * frameTime * Math.PI / 360); + /* + * If necessary: trigger `update` event. + * XXX This can economize rendering OPs. + */ + if (this._moveForward === true || this._moveBackward === true || this._moveLeft === true + || this._moveRight === true || this._offsetPitch !== 0 || this._offsetRoll !== 0) + { + this.trigger('update'); + } + // Reset values to avoid lost of control. - + this._moveForward = this._moveBackward = this._moveLeft = this._moveRight = false; this._offsetPitch = this._offsetRoll = 0; @@ -33439,9 +33467,9 @@ var GamepadControl = Base.extend(function() { case 15: this._moveRight = true; break; - + } - + } } @@ -33868,8 +33896,6 @@ var OrbitControl = Base.extend(function () { this._mouseUpHandler = this._mouseUpHandler.bind(this); this._pinchHandler = this._pinchHandler.bind(this); - this.update = this.update.bind(this); - this.init(); }, /** @lends clay.plugin.OrbitControl# */ { /** @@ -33879,13 +33905,13 @@ var OrbitControl = Base.extend(function () { init: function () { var dom = this.domElement; - dom.addEventListener('touchstart', this._mouseDownHandler); + vendor.addEventListener(dom, 'touchstart', this._mouseDownHandler); - dom.addEventListener('mousedown', this._mouseDownHandler); - dom.addEventListener('wheel', this._mouseWheelHandler); + vendor.addEventListener(dom, 'mousedown', this._mouseDownHandler); + vendor.addEventListener(dom, 'wheel', this._mouseWheelHandler); if (this.timeline) { - this.timeline.on('frame', this.update); + this.timeline.on('frame', this.update, this); } }, @@ -33896,15 +33922,15 @@ var OrbitControl = Base.extend(function () { dispose: function () { var dom = this.domElement; - dom.removeEventListener('touchstart', this._mouseDownHandler); - dom.removeEventListener('touchmove', this._mouseMoveHandler); - dom.removeEventListener('touchend', this._mouseUpHandler); + vendor.removeEventListener(dom, 'touchstart', this._mouseDownHandler); + vendor.removeEventListener(dom, 'touchmove', this._mouseMoveHandler); + vendor.removeEventListener(dom, 'touchend', this._mouseUpHandler); - dom.removeEventListener('mousedown', this._mouseDownHandler); - dom.removeEventListener('mousemove', this._mouseMoveHandler); - dom.removeEventListener('mouseup', this._mouseUpHandler); - dom.removeEventListener('wheel', this._mouseWheelHandler); - dom.removeEventListener('mouseout', this._mouseUpHandler); + vendor.removeEventListener(dom, 'mousedown', this._mouseDownHandler); + vendor.removeEventListener(dom, 'mousemove', this._mouseMoveHandler); + vendor.removeEventListener(dom, 'mouseup', this._mouseUpHandler); + vendor.removeEventListener(dom, 'wheel', this._mouseWheelHandler); + vendor.removeEventListener(dom, 'mouseout', this._mouseUpHandler); if (this.timeline) { this.timeline.off('frame', this.update); @@ -34139,8 +34165,6 @@ var OrbitControl = Base.extend(function () { this.setBeta(this.getBeta()); this._vectorDamping(velocity, this.damping); - - velocity.x = velocity.y = 0; }, _updateDistance: function (deltaTime) { @@ -34256,11 +34280,21 @@ var OrbitControl = Base.extend(function () { this._processGesture(e, 'start'); } else { + // Left button. if (e.button === 0) { this._mode = 'rotate'; } + // Middle button. else if (e.button === 1) { this._mode = 'pan'; + + /** + * Vendors like Mozilla provide a mouse-driven panning feature + * that is activated when the middle mouse button is pressed. + * + * @see https://w3c.github.io/uievents/#event-type-mousedown + */ + e.preventDefault(); } else { this._mode = null; @@ -34268,12 +34302,12 @@ var OrbitControl = Base.extend(function () { } var dom = this.domElement; - dom.addEventListener('touchmove', this._mouseMoveHandler); - dom.addEventListener('touchend', this._mouseUpHandler); + vendor.addEventListener(dom, 'touchmove', this._mouseMoveHandler); + vendor.addEventListener(dom, 'touchend', this._mouseUpHandler); - dom.addEventListener('mousemove', this._mouseMoveHandler); - dom.addEventListener('mouseup', this._mouseUpHandler); - dom.addEventListener('mouseout', this._mouseUpHandler); + vendor.addEventListener(dom, 'mousemove', this._mouseMoveHandler); + vendor.addEventListener(dom, 'mouseup', this._mouseUpHandler); + vendor.addEventListener(dom, 'mouseout', this._mouseUpHandler); // Reset rotate velocity this._rotateVelocity.set(0, 0); @@ -34320,7 +34354,7 @@ var OrbitControl = Base.extend(function () { this._mouseX = x; this._mouseY = y; - e.preventDefault(); + e.preventDefault && e.preventDefault(); }, _mouseWheelHandler: function (e) { @@ -34355,16 +34389,16 @@ var OrbitControl = Base.extend(function () { this._startCountingStill(); } - e.preventDefault(); + e.preventDefault && e.preventDefault(); }, _mouseUpHandler: function (event) { var dom = this.domElement; - dom.removeEventListener('touchmove', this._mouseMoveHandler); - dom.removeEventListener('touchend', this._mouseUpHandler); - dom.removeEventListener('mousemove', this._mouseMoveHandler); - dom.removeEventListener('mouseup', this._mouseUpHandler); - dom.removeEventListener('mouseout', this._mouseUpHandler); + vendor.removeEventListener(dom, 'touchmove', this._mouseMoveHandler); + vendor.removeEventListener(dom, 'touchend', this._mouseUpHandler); + vendor.removeEventListener(dom, 'mousemove', this._mouseMoveHandler); + vendor.removeEventListener(dom, 'mouseup', this._mouseUpHandler); + vendor.removeEventListener(dom, 'mouseout', this._mouseUpHandler); this._processGesture(event, 'end'); }, @@ -34905,7 +34939,7 @@ function copyIfNecessary(arr, shallow) { /** * @name clay.version */ -var version = '1.2.1'; +var version = '1.2.2'; var outputEssl$1 = "@export clay.vr.disorter.output.vertex\nattribute vec2 texcoord: TEXCOORD_0;\nattribute vec3 position: POSITION;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n v_Texcoord = texcoord;\n gl_Position = vec4(position.xy, 0.5, 1.0);\n}\n@end\n@export clay.vr.disorter.output.fragment\nuniform sampler2D texture;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n gl_FragColor = texture2D(texture, v_Texcoord);\n}\n@end"; diff --git a/dist/claygl.js b/dist/claygl.js index 3e1dc15ac..b6284d9f7 100644 --- a/dist/claygl.js +++ b/dist/claygl.js @@ -6171,6 +6171,8 @@ if (typeof window !== 'undefined') { else if (typeof global !== 'undefined') { g = global; } + + vendor.requestAnimationFrame = g.requestAnimationFrame || g.msRequestAnimationFrame || g.mozRequestAnimationFrame @@ -6189,6 +6191,14 @@ vendor.request = { get: request.get }; +vendor.addEventListener = function (dom, type, func, useCapture) { + dom.addEventListener(type, func, useCapture); +}; + +vendor.removeEventListener = function (dom, type, func) { + dom.removeEventListener(type, func); +}; + /** * Animation is global timeline that schedule all clips. each frame animation will set the time of clips to current and update the states of clips * @constructor clay.Timeline @@ -11220,7 +11230,9 @@ var Renderer = Base.extend(function () { var currentVAO; var materialTakesTextureSlot; - var vaoExt = this.getGLExtension('OES_vertex_array_object'); + // var vaoExt = this.getGLExtension('OES_vertex_array_object'); + // not use vaoExt, some platforms may mess it up. + var vaoExt = null; for (var i = 0; i < list.length; i++) { var renderable = list[i]; @@ -19182,11 +19194,9 @@ var Texture2D = Texture.extend(function () { image.onload = function () { self.dirty(); self.trigger('success', self); - image.onload = null; }; image.onerror = function () { self.trigger('error', self); - image.onerror = null; }; image.src = src; @@ -19443,11 +19453,9 @@ var TextureCube = Texture.extend(function () { self.dirty(); self.trigger('success', self); } - image.onload = null; }; image.onerror = function () { loading --; - image.onerror = null; }; loading++; @@ -20687,9 +20695,9 @@ var Skeleton = Base.extend(function () { var utilGlsl = "\n@export clay.util.rand\nhighp float rand(vec2 uv) {\n const highp float a = 12.9898, b = 78.233, c = 43758.5453;\n highp float dt = dot(uv.xy, vec2(a,b)), sn = mod(dt, 3.141592653589793);\n return fract(sin(sn) * c);\n}\n@end\n@export clay.util.calculate_attenuation\nuniform float attenuationFactor : 5.0;\nfloat lightAttenuation(float dist, float range)\n{\n float attenuation = 1.0;\n attenuation = dist*dist/(range*range+1.0);\n float att_s = attenuationFactor;\n attenuation = 1.0/(attenuation*att_s+1.0);\n att_s = 1.0/(att_s+1.0);\n attenuation = attenuation - att_s;\n attenuation /= 1.0 - att_s;\n return clamp(attenuation, 0.0, 1.0);\n}\n@end\n@export clay.util.edge_factor\n#ifdef SUPPORT_STANDARD_DERIVATIVES\nfloat edgeFactor(float width)\n{\n vec3 d = fwidth(v_Barycentric);\n vec3 a3 = smoothstep(vec3(0.0), d * width, v_Barycentric);\n return min(min(a3.x, a3.y), a3.z);\n}\n#else\nfloat edgeFactor(float width)\n{\n return 1.0;\n}\n#endif\n@end\n@export clay.util.encode_float\nvec4 encodeFloat(const in float depth)\n{\n const vec4 bitShifts = vec4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0);\n const vec4 bit_mask = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0);\n vec4 res = fract(depth * bitShifts);\n res -= res.xxyz * bit_mask;\n return res;\n}\n@end\n@export clay.util.decode_float\nfloat decodeFloat(const in vec4 color)\n{\n const vec4 bitShifts = vec4(1.0/(256.0*256.0*256.0), 1.0/(256.0*256.0), 1.0/256.0, 1.0);\n return dot(color, bitShifts);\n}\n@end\n@export clay.util.float\n@import clay.util.encode_float\n@import clay.util.decode_float\n@end\n@export clay.util.rgbm_decode\nvec3 RGBMDecode(vec4 rgbm, float range) {\n return range * rgbm.rgb * rgbm.a;\n}\n@end\n@export clay.util.rgbm_encode\nvec4 RGBMEncode(vec3 color, float range) {\n if (dot(color, color) == 0.0) {\n return vec4(0.0);\n }\n vec4 rgbm;\n color /= range;\n rgbm.a = clamp(max(max(color.r, color.g), max(color.b, 1e-6)), 0.0, 1.0);\n rgbm.a = ceil(rgbm.a * 255.0) / 255.0;\n rgbm.rgb = color / rgbm.a;\n return rgbm;\n}\n@end\n@export clay.util.rgbm\n@import clay.util.rgbm_decode\n@import clay.util.rgbm_encode\nvec4 decodeHDR(vec4 color)\n{\n#if defined(RGBM_DECODE) || defined(RGBM)\n return vec4(RGBMDecode(color, 8.12), 1.0);\n#else\n return color;\n#endif\n}\nvec4 encodeHDR(vec4 color)\n{\n#if defined(RGBM_ENCODE) || defined(RGBM)\n return RGBMEncode(color.xyz, 8.12);\n#else\n return color;\n#endif\n}\n@end\n@export clay.util.srgb\nvec4 sRGBToLinear(in vec4 value) {\n return vec4(mix(pow(value.rgb * 0.9478672986 + vec3(0.0521327014), vec3(2.4)), value.rgb * 0.0773993808, vec3(lessThanEqual(value.rgb, vec3(0.04045)))), value.w);\n}\nvec4 linearTosRGB(in vec4 value) {\n return vec4(mix(pow(value.rgb, vec3(0.41666)) * 1.055 - vec3(0.055), value.rgb * 12.92, vec3(lessThanEqual(value.rgb, vec3(0.0031308)))), value.w);\n}\n@end\n@export clay.chunk.skinning_header\n#ifdef SKINNING\nattribute vec3 weight : WEIGHT;\nattribute vec4 joint : JOINT;\n#ifdef USE_SKIN_MATRICES_TEXTURE\nuniform sampler2D skinMatricesTexture : ignore;\nuniform float skinMatricesTextureSize: ignore;\nmat4 getSkinMatrix(sampler2D tex, float idx) {\n float j = idx * 4.0;\n float x = mod(j, skinMatricesTextureSize);\n float y = floor(j / skinMatricesTextureSize) + 0.5;\n vec2 scale = vec2(skinMatricesTextureSize);\n return mat4(\n texture2D(tex, vec2(x + 0.5, y) / scale),\n texture2D(tex, vec2(x + 1.5, y) / scale),\n texture2D(tex, vec2(x + 2.5, y) / scale),\n texture2D(tex, vec2(x + 3.5, y) / scale)\n );\n}\nmat4 getSkinMatrix(float idx) {\n return getSkinMatrix(skinMatricesTexture, idx);\n}\n#else\nuniform mat4 skinMatrix[JOINT_COUNT] : SKIN_MATRIX;\nmat4 getSkinMatrix(float idx) {\n return skinMatrix[int(idx)];\n}\n#endif\n#endif\n@end\n@export clay.chunk.skin_matrix\nmat4 skinMatrixWS = getSkinMatrix(joint.x) * weight.x;\nif (weight.y > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.y) * weight.y;\n}\nif (weight.z > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.z) * weight.z;\n}\nfloat weightW = 1.0-weight.x-weight.y-weight.z;\nif (weightW > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.w) * weightW;\n}\n@end\n@export clay.util.parallax_correct\nvec3 parallaxCorrect(in vec3 dir, in vec3 pos, in vec3 boxMin, in vec3 boxMax) {\n vec3 first = (boxMax - pos) / dir;\n vec3 second = (boxMin - pos) / dir;\n vec3 further = max(first, second);\n float dist = min(further.x, min(further.y, further.z));\n vec3 fixedPos = pos + dir * dist;\n vec3 boxCenter = (boxMax + boxMin) * 0.5;\n return normalize(fixedPos - boxCenter);\n}\n@end\n@export clay.util.clamp_sample\nvec4 clampSample(const in sampler2D texture, const in vec2 coord)\n{\n#ifdef STEREO\n float eye = step(0.5, coord.x) * 0.5;\n vec2 coordClamped = clamp(coord, vec2(eye, 0.0), vec2(0.5 + eye, 1.0));\n#else\n vec2 coordClamped = clamp(coord, vec2(0.0), vec2(1.0));\n#endif\n return texture2D(texture, coordClamped);\n}\n@end\n@export clay.util.ACES\nvec3 ACESToneMapping(vec3 color)\n{\n const float A = 2.51;\n const float B = 0.03;\n const float C = 2.43;\n const float D = 0.59;\n const float E = 0.14;\n return (color * (A * color + B)) / (color * (C * color + D) + E);\n}\n@end"; -var basicEssl = "@export clay.basic.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 position : POSITION;\nattribute vec3 barycentric;\n@import clay.chunk.skinning_header\nvarying vec2 v_Texcoord;\nvarying vec3 v_Barycentric;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\nvoid main()\n{\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n v_Barycentric = barycentric;\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0);\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n}\n@end\n@export clay.basic.fragment\nvarying vec2 v_Texcoord;\nuniform sampler2D diffuseMap;\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform vec3 emission : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\n#ifdef ALPHA_TEST\nuniform float alphaCutoff: 0.9;\n#endif\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\nuniform float lineWidth : 0.0;\nuniform vec4 lineColor : [0.0, 0.0, 0.0, 0.6];\nvarying vec3 v_Barycentric;\n@import clay.util.edge_factor\n@import clay.util.rgbm\n@import clay.util.srgb\n@import clay.util.ACES\nvoid main()\n{\n gl_FragColor = vec4(color, alpha);\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(gl_FragColor);\n#endif\n#ifdef DIFFUSEMAP_ENABLED\n vec4 texel = decodeHDR(texture2D(diffuseMap, v_Texcoord));\n#ifdef SRGB_DECODE\n texel = sRGBToLinear(texel);\n#endif\n#if defined(DIFFUSEMAP_ALPHA_ALPHA)\n gl_FragColor.a = texel.a;\n#endif\n gl_FragColor.rgb *= texel.rgb;\n#endif\n gl_FragColor.rgb += emission;\n if( lineWidth > 0.)\n {\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (gl_FragColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n gl_FragColor.rgb = ACESToneMapping(gl_FragColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n}\n@end"; +var basicEssl = "@export clay.basic.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 position : POSITION;\nattribute vec3 barycentric;\n@import clay.chunk.skinning_header\nvarying vec2 v_Texcoord;\nvarying vec3 v_Barycentric;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\nvoid main()\n{\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n v_Barycentric = barycentric;\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0);\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n}\n@end\n@export clay.basic.fragment\n#define DIFFUSEMAP_ALPHA_ALPHA\nvarying vec2 v_Texcoord;\nuniform sampler2D diffuseMap;\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform vec3 emission : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\n#ifdef ALPHA_TEST\nuniform float alphaCutoff: 0.9;\n#endif\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\nuniform float lineWidth : 0.0;\nuniform vec4 lineColor : [0.0, 0.0, 0.0, 0.6];\nvarying vec3 v_Barycentric;\n@import clay.util.edge_factor\n@import clay.util.rgbm\n@import clay.util.srgb\n@import clay.util.ACES\nvoid main()\n{\n gl_FragColor = vec4(color, alpha);\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(gl_FragColor);\n#endif\n#ifdef DIFFUSEMAP_ENABLED\n vec4 texel = decodeHDR(texture2D(diffuseMap, v_Texcoord));\n#ifdef SRGB_DECODE\n texel = sRGBToLinear(texel);\n#endif\n#if defined(DIFFUSEMAP_ALPHA_ALPHA)\n gl_FragColor.a = texel.a;\n#endif\n gl_FragColor.rgb *= texel.rgb;\n#endif\n gl_FragColor.rgb += emission;\n if( lineWidth > 0.)\n {\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (gl_FragColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n gl_FragColor.rgb = ACESToneMapping(gl_FragColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n}\n@end"; -var lambertEssl = "\n@export clay.lambert.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 normal : NORMAL;\nattribute vec3 barycentric;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n@import clay.chunk.skinning_header\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nvarying vec3 v_Barycentric;\nvoid main()\n{\n vec3 skinnedPosition = position;\n vec3 skinnedNormal = normal;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n skinnedNormal = (skinMatrixWS * vec4(normal, 0.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4( skinnedPosition, 1.0 );\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n v_Normal = normalize( ( worldInverseTranspose * vec4(skinnedNormal, 0.0) ).xyz );\n v_WorldPosition = ( world * vec4( skinnedPosition, 1.0) ).xyz;\n v_Barycentric = barycentric;\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n}\n@end\n@export clay.lambert.fragment\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nuniform sampler2D diffuseMap;\nuniform sampler2D alphaMap;\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform vec3 emission : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\n#ifdef ALPHA_TEST\nuniform float alphaCutoff: 0.9;\n#endif\nuniform float lineWidth : 0.0;\nuniform vec4 lineColor : [0.0, 0.0, 0.0, 0.6];\nvarying vec3 v_Barycentric;\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n#ifdef POINT_LIGHT_COUNT\n@import clay.header.point_light\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n#ifdef SPOT_LIGHT_COUNT\n@import clay.header.spot_light\n#endif\n@import clay.util.calculate_attenuation\n@import clay.util.edge_factor\n@import clay.util.rgbm\n@import clay.plugin.compute_shadow_map\n@import clay.util.ACES\nvoid main()\n{\n gl_FragColor = vec4(color, alpha);\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(gl_FragColor);\n#endif\n#ifdef DIFFUSEMAP_ENABLED\n vec4 tex = texture2D( diffuseMap, v_Texcoord );\n#ifdef SRGB_DECODE\n tex.rgb = pow(tex.rgb, vec3(2.2));\n#endif\n gl_FragColor.rgb *= tex.rgb;\n#ifdef DIFFUSEMAP_ALPHA_ALPHA\n gl_FragColor.a *= tex.a;\n#endif\n#endif\n vec3 diffuseColor = vec3(0.0, 0.0, 0.0);\n#ifdef AMBIENT_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_LIGHT_COUNT; _idx_++)\n {\n diffuseColor += ambientLightColor[_idx_];\n }\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseColor += calcAmbientSHLight(_idx_, v_Normal) * ambientSHLightColor[_idx_];\n }}\n#endif\n#ifdef POINT_LIGHT_COUNT\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsPoint[POINT_LIGHT_COUNT];\n if( shadowEnabled )\n {\n computeShadowOfPointLights(v_WorldPosition, shadowContribsPoint);\n }\n#endif\n for(int i = 0; i < POINT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = pointLightPosition[i];\n vec3 lightColor = pointLightColor[i];\n float range = pointLightRange[i];\n vec3 lightDirection = lightPosition - v_WorldPosition;\n float dist = length(lightDirection);\n float attenuation = lightAttenuation(dist, range);\n lightDirection /= dist;\n float ndl = dot( v_Normal, lightDirection );\n float shadowContrib = 1.0;\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsPoint[i];\n }\n#endif\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0) * attenuation * shadowContrib;\n }\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++)\n {\n vec3 lightDirection = -directionalLightDirection[i];\n vec3 lightColor = directionalLightColor[i];\n float ndl = dot(v_Normal, normalize(lightDirection));\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsDir[i];\n }\n#endif\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0) * shadowContrib;\n }\n#endif\n#ifdef SPOT_LIGHT_COUNT\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsSpot[SPOT_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfSpotLights(v_WorldPosition, shadowContribsSpot);\n }\n#endif\n for(int i = 0; i < SPOT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = -spotLightPosition[i];\n vec3 spotLightDirection = -normalize( spotLightDirection[i] );\n vec3 lightColor = spotLightColor[i];\n float range = spotLightRange[i];\n float a = spotLightUmbraAngleCosine[i];\n float b = spotLightPenumbraAngleCosine[i];\n float falloffFactor = spotLightFalloffFactor[i];\n vec3 lightDirection = lightPosition - v_WorldPosition;\n float dist = length(lightDirection);\n float attenuation = lightAttenuation(dist, range);\n lightDirection /= dist;\n float c = dot(spotLightDirection, lightDirection);\n float falloff;\n falloff = clamp((c - a) /( b - a), 0.0, 1.0);\n falloff = pow(falloff, falloffFactor);\n float ndl = dot(v_Normal, lightDirection);\n ndl = clamp(ndl, 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsSpot[i];\n }\n#endif\n diffuseColor += lightColor * ndl * attenuation * (1.0-falloff) * shadowContrib;\n }\n#endif\n gl_FragColor.rgb *= diffuseColor;\n gl_FragColor.rgb += emission;\n if(lineWidth > 0.)\n {\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (gl_FragColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n gl_FragColor.rgb = ACESToneMapping(gl_FragColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n}\n@end"; +var lambertEssl = "\n@export clay.lambert.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 normal : NORMAL;\nattribute vec3 barycentric;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n@import clay.chunk.skinning_header\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nvarying vec3 v_Barycentric;\nvoid main()\n{\n vec3 skinnedPosition = position;\n vec3 skinnedNormal = normal;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n skinnedNormal = (skinMatrixWS * vec4(normal, 0.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4( skinnedPosition, 1.0 );\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n v_Normal = normalize( ( worldInverseTranspose * vec4(skinnedNormal, 0.0) ).xyz );\n v_WorldPosition = ( world * vec4( skinnedPosition, 1.0) ).xyz;\n v_Barycentric = barycentric;\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n}\n@end\n@export clay.lambert.fragment\n#define DIFFUSEMAP_ALPHA_ALPHA\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nuniform sampler2D diffuseMap;\nuniform sampler2D alphaMap;\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform vec3 emission : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\n#ifdef ALPHA_TEST\nuniform float alphaCutoff: 0.9;\n#endif\nuniform float lineWidth : 0.0;\nuniform vec4 lineColor : [0.0, 0.0, 0.0, 0.6];\nvarying vec3 v_Barycentric;\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n#ifdef POINT_LIGHT_COUNT\n@import clay.header.point_light\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n#ifdef SPOT_LIGHT_COUNT\n@import clay.header.spot_light\n#endif\n@import clay.util.calculate_attenuation\n@import clay.util.edge_factor\n@import clay.util.rgbm\n@import clay.plugin.compute_shadow_map\n@import clay.util.ACES\nvoid main()\n{\n gl_FragColor = vec4(color, alpha);\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(gl_FragColor);\n#endif\n#ifdef DIFFUSEMAP_ENABLED\n vec4 tex = texture2D( diffuseMap, v_Texcoord );\n#ifdef SRGB_DECODE\n tex.rgb = pow(tex.rgb, vec3(2.2));\n#endif\n gl_FragColor.rgb *= tex.rgb;\n#ifdef DIFFUSEMAP_ALPHA_ALPHA\n gl_FragColor.a *= tex.a;\n#endif\n#endif\n vec3 diffuseColor = vec3(0.0, 0.0, 0.0);\n#ifdef AMBIENT_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_LIGHT_COUNT; _idx_++)\n {\n diffuseColor += ambientLightColor[_idx_];\n }\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseColor += calcAmbientSHLight(_idx_, v_Normal) * ambientSHLightColor[_idx_];\n }}\n#endif\n#ifdef POINT_LIGHT_COUNT\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsPoint[POINT_LIGHT_COUNT];\n if( shadowEnabled )\n {\n computeShadowOfPointLights(v_WorldPosition, shadowContribsPoint);\n }\n#endif\n for(int i = 0; i < POINT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = pointLightPosition[i];\n vec3 lightColor = pointLightColor[i];\n float range = pointLightRange[i];\n vec3 lightDirection = lightPosition - v_WorldPosition;\n float dist = length(lightDirection);\n float attenuation = lightAttenuation(dist, range);\n lightDirection /= dist;\n float ndl = dot( v_Normal, lightDirection );\n float shadowContrib = 1.0;\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsPoint[i];\n }\n#endif\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0) * attenuation * shadowContrib;\n }\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++)\n {\n vec3 lightDirection = -directionalLightDirection[i];\n vec3 lightColor = directionalLightColor[i];\n float ndl = dot(v_Normal, normalize(lightDirection));\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsDir[i];\n }\n#endif\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0) * shadowContrib;\n }\n#endif\n#ifdef SPOT_LIGHT_COUNT\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsSpot[SPOT_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfSpotLights(v_WorldPosition, shadowContribsSpot);\n }\n#endif\n for(int i = 0; i < SPOT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = -spotLightPosition[i];\n vec3 spotLightDirection = -normalize( spotLightDirection[i] );\n vec3 lightColor = spotLightColor[i];\n float range = spotLightRange[i];\n float a = spotLightUmbraAngleCosine[i];\n float b = spotLightPenumbraAngleCosine[i];\n float falloffFactor = spotLightFalloffFactor[i];\n vec3 lightDirection = lightPosition - v_WorldPosition;\n float dist = length(lightDirection);\n float attenuation = lightAttenuation(dist, range);\n lightDirection /= dist;\n float c = dot(spotLightDirection, lightDirection);\n float falloff;\n falloff = clamp((c - a) /( b - a), 0.0, 1.0);\n falloff = pow(falloff, falloffFactor);\n float ndl = dot(v_Normal, lightDirection);\n ndl = clamp(ndl, 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsSpot[i];\n }\n#endif\n diffuseColor += lightColor * ndl * attenuation * (1.0-falloff) * shadowContrib;\n }\n#endif\n gl_FragColor.rgb *= diffuseColor;\n gl_FragColor.rgb += emission;\n if(lineWidth > 0.)\n {\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (gl_FragColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n gl_FragColor.rgb = ACESToneMapping(gl_FragColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n}\n@end"; var wireframeEssl = "@export clay.wireframe.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 world : WORLD;\nattribute vec3 position : POSITION;\nattribute vec3 barycentric;\n@import clay.chunk.skinning_header\nvarying vec3 v_Barycentric;\nvoid main()\n{\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0 );\n v_Barycentric = barycentric;\n}\n@end\n@export clay.wireframe.fragment\nuniform vec3 color : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\nuniform float lineWidth : 1.0;\nvarying vec3 v_Barycentric;\n@import clay.util.edge_factor\nvoid main()\n{\n gl_FragColor.rgb = color;\n gl_FragColor.a = (1.0-edgeFactor(lineWidth)) * alpha;\n}\n@end"; @@ -25644,7 +25652,7 @@ function App3D(dom, appNS) { dom.innerHTML = ''; EVE_NAMES.forEach(function (eveType) { - this[makeHandlerName(eveType)] && dom.removeEventListener(makeHandlerName(eveType)); + this[makeHandlerName(eveType)] && vendor.removeEventListener(dom, makeHandlerName(eveType)); }, this); }; @@ -25735,11 +25743,11 @@ App3D.prototype._initMouseEvents = function (rayPicking) { var oldTarget = null; EVE_NAMES.forEach(function (_eveType) { - dom.addEventListener(_eveType, this[makeHandlerName(_eveType)] = function (e) { + vendor.addEventListener(dom, _eveType, this[makeHandlerName(_eveType)] = function (e) { if (!rayPicking.camera) { // Not have camera yet. return; } - e.preventDefault(); + e.preventDefault && e.preventDefault(); var box = dom.getBoundingClientRect(); var offsetX, offsetY; @@ -26409,6 +26417,9 @@ App3D.prototype.createCamera = function (position, target, type, extent) { camera.near = 0; camera.far = extent[2]; } + else { + camera.aspect = this.renderer.getViewportAspect(); + } this.scene.add(camera); @@ -27846,13 +27857,13 @@ var FilterNode$1 = CompositorNode.extend(function () { } } var width, height; - if (parameters.width instanceof Function) { + if (typeof parameters.width === 'function') { width = parameters.width.call(this, renderer); } else { width = parameters.width; } - if (parameters.height instanceof Function) { + if (typeof parameters.height === 'function') { height = parameters.height.call(this, renderer); } else { @@ -28125,7 +28136,7 @@ function createNode(nodeInfo, lib, opts) { if (nodeInfo.parameters) { for (var name in nodeInfo.parameters) { var val = nodeInfo.parameters[name]; - if (typeof(val) === 'string') { + if (typeof val === 'string') { val = val.trim(); if (val.charAt(0) === '#') { val = lib.textures[val.substr(1)]; @@ -28138,6 +28149,9 @@ function createNode(nodeInfo, lib, opts) { ); } } + else if (typeof val === 'function') { + node.on('beforerender', val); + } node.setParameter(name, val); } } @@ -32940,6 +32954,8 @@ function unpackID(r, g, b){ return (r << 16) + (g<<8) + b; } +var doc = typeof document === 'undefined' ? {} : document; + /** * @constructor clay.plugin.FreeControl * @example @@ -33026,14 +33042,14 @@ var FreeControl = Base.extend(function() { //Must request pointer lock after click event, can't not do it directly //Why ? ? - el.addEventListener('click', this._requestPointerLock); + vendor.addEventListener(el, 'click', this._requestPointerLock); - document.addEventListener('pointerlockchange', this._lockChange); - document.addEventListener('mozpointerlockchange', this._lockChange); - document.addEventListener('webkitpointerlockchange', this._lockChange); + vendor.addEventListener(doc, 'pointerlockchange', this._lockChange); + vendor.addEventListener(doc, 'mozpointerlockchange', this._lockChange); + vendor.addEventListener(doc, 'webkitpointerlockchange', this._lockChange); - document.addEventListener('keydown', this._keyDown); - document.addEventListener('keyup', this._keyUp); + vendor.addEventListener(doc, 'keydown', this._keyDown); + vendor.addEventListener(doc, 'keyup', this._keyUp); if (this.timeline) { this.timeline.on('frame', this._detectMovementChange, this); @@ -33055,14 +33071,14 @@ var FreeControl = Base.extend(function() { el.exitPointerLock(); } - this.domElement.removeEventListener('click', this._requestPointerLock); + vendor.removeEventListener(el, 'click', this._requestPointerLock); - document.removeEventListener('pointerlockchange', this._lockChange); - document.removeEventListener('mozpointerlockchange', this._lockChange); - document.removeEventListener('webkitpointerlockchange', this._lockChange); + vendor.removeEventListener(doc, 'pointerlockchange', this._lockChange); + vendor.removeEventListener(doc, 'mozpointerlockchange', this._lockChange); + vendor.removeEventListener(doc, 'webkitpointerlockchange', this._lockChange); - document.removeEventListener('keydown', this._keyDown); - document.removeEventListener('keyup', this._keyUp); + vendor.removeEventListener(doc, 'keydown', this._keyDown); + vendor.removeEventListener(doc, 'keyup', this._keyUp); if (this.timeline) { this.timeline.off('frame', this._detectMovementChange); @@ -33119,14 +33135,14 @@ var FreeControl = Base.extend(function() { _lockChange: function() { if ( - document.pointerLockElement === this.domElement - || document.mozPointerLockElement === this.domElement - || document.webkitPointerLockElement === this.domElement + doc.pointerLockElement === this.domElement + || doc.mozPointerLockElement === this.domElement + || doc.webkitPointerLockElement === this.domElement ) { - document.addEventListener('mousemove', this._mouseMove, false); + vendor.addEventListener(doc, 'mousemove', this._mouseMove, false); } else { - document.removeEventListener('mousemove', this._mouseMove); + vendor.removeEventListener(doc, 'mousemove', this._mouseMove); } }, @@ -33286,6 +33302,8 @@ var GamepadControl = Base.extend(function() { this._scanPressedGamepadButtons = this._scanPressedGamepadButtons.bind(this); this._scanInclinedGamepadAxes = this._scanInclinedGamepadAxes.bind(this); + this.update = this.update.bind(this); + // If browser supports Gamepad API: if (typeof navigator.getGamepads === 'function') { this.init(); @@ -33304,13 +33322,13 @@ var GamepadControl = Base.extend(function() { * * @see https://w3c.github.io/gamepad/#dom-gamepadevent */ - window.addEventListener('gamepadconnected', this._checkGamepadCompatibility); + vendor.addEventListener(window, 'gamepadconnected', this._checkGamepadCompatibility); if (this.timeline) { this.timeline.on('frame', this.update); } - window.addEventListener('gamepaddisconnected', this._disconnectGamepad); + vendor.addEventListener(window, 'gamepaddisconnected', this._disconnectGamepad); }, @@ -33319,13 +33337,13 @@ var GamepadControl = Base.extend(function() { */ dispose: function() { - window.removeEventListener('gamepadconnected', this._checkGamepadCompatibility); + vendor.removeEventListener(window, 'gamepadconnected', this._checkGamepadCompatibility); if (this.timeline) { this.timeline.off('frame', this.update); } - window.removeEventListener('gamepaddisconnected', this._disconnectGamepad); + vendor.removeEventListener(window, 'gamepaddisconnected', this._disconnectGamepad); }, @@ -33371,8 +33389,18 @@ var GamepadControl = Base.extend(function() { var xAxis = target.localTransform.x; target.rotateAround(target.position, xAxis, -this._offsetRoll * frameTime * Math.PI / 360); + /* + * If necessary: trigger `update` event. + * XXX This can economize rendering OPs. + */ + if (this._moveForward === true || this._moveBackward === true || this._moveLeft === true + || this._moveRight === true || this._offsetPitch !== 0 || this._offsetRoll !== 0) + { + this.trigger('update'); + } + // Reset values to avoid lost of control. - + this._moveForward = this._moveBackward = this._moveLeft = this._moveRight = false; this._offsetPitch = this._offsetRoll = 0; @@ -33445,9 +33473,9 @@ var GamepadControl = Base.extend(function() { case 15: this._moveRight = true; break; - + } - + } } @@ -33874,8 +33902,6 @@ var OrbitControl = Base.extend(function () { this._mouseUpHandler = this._mouseUpHandler.bind(this); this._pinchHandler = this._pinchHandler.bind(this); - this.update = this.update.bind(this); - this.init(); }, /** @lends clay.plugin.OrbitControl# */ { /** @@ -33885,13 +33911,13 @@ var OrbitControl = Base.extend(function () { init: function () { var dom = this.domElement; - dom.addEventListener('touchstart', this._mouseDownHandler); + vendor.addEventListener(dom, 'touchstart', this._mouseDownHandler); - dom.addEventListener('mousedown', this._mouseDownHandler); - dom.addEventListener('wheel', this._mouseWheelHandler); + vendor.addEventListener(dom, 'mousedown', this._mouseDownHandler); + vendor.addEventListener(dom, 'wheel', this._mouseWheelHandler); if (this.timeline) { - this.timeline.on('frame', this.update); + this.timeline.on('frame', this.update, this); } }, @@ -33902,15 +33928,15 @@ var OrbitControl = Base.extend(function () { dispose: function () { var dom = this.domElement; - dom.removeEventListener('touchstart', this._mouseDownHandler); - dom.removeEventListener('touchmove', this._mouseMoveHandler); - dom.removeEventListener('touchend', this._mouseUpHandler); + vendor.removeEventListener(dom, 'touchstart', this._mouseDownHandler); + vendor.removeEventListener(dom, 'touchmove', this._mouseMoveHandler); + vendor.removeEventListener(dom, 'touchend', this._mouseUpHandler); - dom.removeEventListener('mousedown', this._mouseDownHandler); - dom.removeEventListener('mousemove', this._mouseMoveHandler); - dom.removeEventListener('mouseup', this._mouseUpHandler); - dom.removeEventListener('wheel', this._mouseWheelHandler); - dom.removeEventListener('mouseout', this._mouseUpHandler); + vendor.removeEventListener(dom, 'mousedown', this._mouseDownHandler); + vendor.removeEventListener(dom, 'mousemove', this._mouseMoveHandler); + vendor.removeEventListener(dom, 'mouseup', this._mouseUpHandler); + vendor.removeEventListener(dom, 'wheel', this._mouseWheelHandler); + vendor.removeEventListener(dom, 'mouseout', this._mouseUpHandler); if (this.timeline) { this.timeline.off('frame', this.update); @@ -34145,8 +34171,6 @@ var OrbitControl = Base.extend(function () { this.setBeta(this.getBeta()); this._vectorDamping(velocity, this.damping); - - velocity.x = velocity.y = 0; }, _updateDistance: function (deltaTime) { @@ -34262,11 +34286,21 @@ var OrbitControl = Base.extend(function () { this._processGesture(e, 'start'); } else { + // Left button. if (e.button === 0) { this._mode = 'rotate'; } + // Middle button. else if (e.button === 1) { this._mode = 'pan'; + + /** + * Vendors like Mozilla provide a mouse-driven panning feature + * that is activated when the middle mouse button is pressed. + * + * @see https://w3c.github.io/uievents/#event-type-mousedown + */ + e.preventDefault(); } else { this._mode = null; @@ -34274,12 +34308,12 @@ var OrbitControl = Base.extend(function () { } var dom = this.domElement; - dom.addEventListener('touchmove', this._mouseMoveHandler); - dom.addEventListener('touchend', this._mouseUpHandler); + vendor.addEventListener(dom, 'touchmove', this._mouseMoveHandler); + vendor.addEventListener(dom, 'touchend', this._mouseUpHandler); - dom.addEventListener('mousemove', this._mouseMoveHandler); - dom.addEventListener('mouseup', this._mouseUpHandler); - dom.addEventListener('mouseout', this._mouseUpHandler); + vendor.addEventListener(dom, 'mousemove', this._mouseMoveHandler); + vendor.addEventListener(dom, 'mouseup', this._mouseUpHandler); + vendor.addEventListener(dom, 'mouseout', this._mouseUpHandler); // Reset rotate velocity this._rotateVelocity.set(0, 0); @@ -34326,7 +34360,7 @@ var OrbitControl = Base.extend(function () { this._mouseX = x; this._mouseY = y; - e.preventDefault(); + e.preventDefault && e.preventDefault(); }, _mouseWheelHandler: function (e) { @@ -34361,16 +34395,16 @@ var OrbitControl = Base.extend(function () { this._startCountingStill(); } - e.preventDefault(); + e.preventDefault && e.preventDefault(); }, _mouseUpHandler: function (event) { var dom = this.domElement; - dom.removeEventListener('touchmove', this._mouseMoveHandler); - dom.removeEventListener('touchend', this._mouseUpHandler); - dom.removeEventListener('mousemove', this._mouseMoveHandler); - dom.removeEventListener('mouseup', this._mouseUpHandler); - dom.removeEventListener('mouseout', this._mouseUpHandler); + vendor.removeEventListener(dom, 'touchmove', this._mouseMoveHandler); + vendor.removeEventListener(dom, 'touchend', this._mouseUpHandler); + vendor.removeEventListener(dom, 'mousemove', this._mouseMoveHandler); + vendor.removeEventListener(dom, 'mouseup', this._mouseUpHandler); + vendor.removeEventListener(dom, 'mouseout', this._mouseUpHandler); this._processGesture(event, 'end'); }, @@ -34911,7 +34945,7 @@ function copyIfNecessary(arr, shallow) { /** * @name clay.version */ -var version = '1.2.1'; +var version = '1.2.2'; var outputEssl$1 = "@export clay.vr.disorter.output.vertex\nattribute vec2 texcoord: TEXCOORD_0;\nattribute vec3 position: POSITION;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n v_Texcoord = texcoord;\n gl_Position = vec4(position.xy, 0.5, 1.0);\n}\n@end\n@export clay.vr.disorter.output.fragment\nuniform sampler2D texture;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n gl_FragColor = texture2D(texture, v_Texcoord);\n}\n@end"; diff --git a/dist/claygl.min.js b/dist/claygl.min.js index 0c6d3ed7c..8240e7f56 100644 --- a/dist/claygl.min.js +++ b/dist/claygl.min.js @@ -1,14 +1,14 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e(t.clay={})}(this,function(t){"use strict";function e(){}function r(t,e){return t[e]}function n(t,e,r){t[e]=r}function i(t,e,r){return(e-t)*r+t}function a(t,e,r,n,a){var o=t.length;if(1==a)for(var s=0;si)t.length=i;else for(var a=n;a=0&&!(x[M]<=e);M--);M=Math.min(M,g-2)}else{for(M=D;Me);M++);M=Math.min(M-1,g-2)}D=M,B=e;var r=x[M+1]-x[M];0!==r&&(L=(e-x[M])/r,L=Math.max(Math.min(1,L),0),L=A[M+1](L),_?(P=E[M],N=E[0===M?M:M-1],I=E[M>g-2?g-1:M+1],O=E[M>g-3?g-1:M+2],f?m(t,s,f(p(t,s),N,P,I,O,L)):y?u(N,P,I,O,L,L*L,L*L*L,p(t,s),T):m(t,s,l(N,P,I,O,L,L*L,L*L*L))):f?m(t,s,f(p(t,s),E[M],E[M+1],L)):y?a(E[M],E[M+1],L,p(t,s),T):m(t,s,i(E[M],E[M+1],L)))},F=new me({target:t._target,life:d,loop:t._loop,delay:t._delay,onframe:U,onfinish:r});return e&&"spline"!==e&&F.setEasing(e),F}}}function d(t,e,i,a,o){this._tracks={},this._target=t,this._loop=e||!1,this._getter=i||r,this._setter=a||n,this._interpolater=o||null,this._delay=0,this._doneList=[],this._onframeList=[],this._clipList=[],this._maxTime=0,this._lastKFTime=0}function p(t){return t}function m(t){var e,r,n,i,a,o,s=Number.POSITIVE_INFINITY,u=Number.POSITIVE_INFINITY,l=Number.NEGATIVE_INFINITY,c=Number.NEGATIVE_INFINITY;for(e=t.length;e--;)t[e][0]l&&(l=t[e][0]),t[e][1]c&&(c=t[e][1]);return r=l-s,n=c-u,i=Math.max(r,n),a=s+.5*r,o=u+.5*n,[[a-20*i,o-i],[a,o+20*i],[a+20*i,o-i]]}function _(t,e,r,n){var i,a,o,s,u,l,c,h,f,d,p=t[e][0],m=t[e][1],_=t[r][0],g=t[r][1],v=t[n][0],y=t[n][1],T=Math.abs(m-g),x=Math.abs(g-y);if(Tx?o*(i-u)+c:s*(i-l)+h),f=_-i,d=g-a,{i:e,j:r,k:n,x:i,y:a,r:f*f+d*d}}function g(t){var e,r,n,i,a,o;for(r=t.length;r;)for(i=t[--r],n=t[--r],e=r;e;)if(o=t[--e],a=t[--e],n===a&&i===o||n===o&&i===a){t.splice(r,2),t.splice(e,2);break}}function v(t,e,r,n,i,a){var o=e[i],s=e[i+1],u=e[i+2];return t[0]=o+n*(r[a]-o),t[1]=s+n*(r[a+1]-s),t[2]=u+n*(r[a+2]-u),t}function y(t,e,r,n,i,a){var o,s,u,l,c,h=e[0+i],f=e[1+i],d=e[2+i],p=e[3+i],m=r[0+a],_=r[1+a],g=r[2+a],v=r[3+a];return s=h*m+f*_+d*g+p*v,s<0&&(s=-s,m=-m,_=-_,g=-g,v=-v),1-s>1e-6?(o=Math.acos(s),u=Math.sin(o),l=Math.sin((1-n)*o)/u,c=Math.sin(n*o)/u):(l=1-n,c=n),t[0]=l*h+c*m,t[1]=l*f+c*_,t[2]=l*d+c*g,t[3]=l*p+c*v,t}function T(t,e,r){"object"==typeof e&&(r=e,e=null);var n,i=this;if(!(t instanceof Function)){n=[];for(var a in t)t.hasOwnProperty(a)&&n.push(a)}var o=function(e){if(i.apply(this,arguments),t instanceof Function?x(this,t.call(this,e)):E(this,t,n),this.constructor===o)for(var r=o.__initializers__,a=0;a=400?t.onerror&&t.onerror():t.onload&&t.onload(e.response)},t.onerror&&(e.onerror=t.onerror),e.send(null)}function S(t){function e(e){var n=t.getExtension(e);n||(n=t.getExtension("MOZ_"+e)),n||(n=t.getExtension("WEBKIT_"+e)),r[e]=n}for(var r={},n={},i=0;i255?255:t}function w(t){return t=Math.round(t),t<0?0:t>360?360:t}function C(t){return t<0?0:t>1?1:t}function R(t){return M(t.length&&"%"===t.charAt(t.length-1)?parseFloat(t)/100*255:parseInt(t,10))}function L(t){return C(t.length&&"%"===t.charAt(t.length-1)?parseFloat(t)/100:parseFloat(t))}function N(t,e,r){return r<0?r+=1:r>1&&(r-=1),6*r<1?t+(e-t)*r*6:2*r<1?e:3*r<2?t+(e-t)*(2/3-r)*6:t}function P(t,e,r){return t+(e-t)*r}function I(t,e,r,n,i){return t[0]=e,t[1]=r,t[2]=n,t[3]=i,t}function O(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t}function D(t,e){$e&&O($e,e),$e=Qe.put(t,$e||e.slice())}function B(t,e){var r=(parseFloat(t[0])%360+360)%360/360,n=L(t[1]),i=L(t[2]),a=i<=.5?i*(n+1):i+n-i*n,o=2*i-a;return e=e||[],I(e,M(255*N(o,a,r+1/3)),M(255*N(o,a,r)),M(255*N(o,a,r-1/3)),1),4===t.length&&(e[3]=t[3]),e}function U(t){if(t){var e,r,n=t[0]/255,i=t[1]/255,a=t[2]/255,o=Math.min(n,i,a),s=Math.max(n,i,a),u=s-o,l=(s+o)/2;if(0===u)e=0,r=0;else{r=l<.5?u/(s+o):u/(2-s-o);var c=((s-n)/6+u/2)/u,h=((s-i)/6+u/2)/u,f=((s-a)/6+u/2)/u;n===s?e=f-h:i===s?e=1/3+c-f:a===s&&(e=2/3+h-c),e<0&&(e+=1),e>1&&(e-=1)}var d=[360*e,r,l];return null!=t[3]&&d.push(t[3]),d}}function F(t){var e=Object.keys(t);e.sort();for(var r=[],n=0;n0&&n.push("#define "+i.toUpperCase()+"_COUNT "+a)}if(r)for(var o=0;o=0){if(1!==u&&4!==u){Z();break}u=2,c=[]}else if(1!==u)if(4!==u)r(h),u=0;else{var f=h;fr.indexOf(f)>=0||dr.indexOf(f)>=0||pr.indexOf(f)>=0?l[s].semantic=f:"ignore"===f||"unconfigurable"===f?l[s].ignore=!0:l[s].value="bool"===t?"true"===f:parseFloat(f)}else l[s].value="bool"===t?"true"===h:parseFloat(h),c=null;else{if(2!==u){Z();break}if(!(c instanceof Array)){Z();break}c.push(+i[++o])}else l[s].value=new Ge.Float32Array(c),c=null,u=5;else if(2===u){if(!(c instanceof Array)){Z();break}c.push(+i[++o])}else u=5;else u=4;else{if(0!==u&&3!==u){Z();break}u=1}}return l}function Q(t,e){"object"==typeof t&&(e=t.fragment,t=t.vertex),t=K(t),e=K(e),this._shaderID=Y(t,e),this._vertexCode=Q.parseImport(t),this._fragmentCode=Q.parseImport(e),this.attributeSemantics={},this.matrixSemantics={},this.uniformSemantics={},this.matrixSemanticKeys=[],this.uniformTemplates={},this.attributes={},this.textures={},this.vertexDefines={},this.fragmentDefines={},this._parseAttributes(),this._parseUniforms(),this._parseDefines()}function $(t){return t.material}function tt(t,e,r){return e.uniforms[r].value}function et(t,e,r,n){return r!==n}function rt(t){return!0}function nt(){}function it(t,e,r){this.availableAttributes=t,this.availableAttributeSymbols=e,this.indicesBuffer=r,this.vao=null}function at(t){var e,r;this.bind=function(t){e||(e=Ge.createCanvas(),e.width=e.height=1,e.getContext("2d"));var n=t.gl,i=!r;i&&(r=n.createTexture()),n.bindTexture(n.TEXTURE_2D,r),i&&n.texImage2D(n.TEXTURE_2D,0,n.RGBA,n.RGBA,n.UNSIGNED_BYTE,e)},this.unbind=function(t){t.gl.bindTexture(t.gl.TEXTURE_2D,null)},this.isRenderable=function(){return!0}}function ot(t,e,r){return tr?r:t}function st(t){var e=[],r=Object.keys(t);r.sort();for(var n=0;n0){var i=Math.pow(2,t[3]-128-8+n);e[r+0]=t[0]*i,e[r+1]=t[1]*i,e[r+2]=t[2]*i}else e[r+0]=0,e[r+1]=0,e[r+2]=0;return e[r+3]=1,e}function bt(t,e,r){for(var n="",i=e;i0;)if(t[a][0]=e[r++],t[a][1]=e[r++],t[a][2]=e[r++],t[a][3]=e[r++],1===t[a][0]&&1===t[a][1]&&1===t[a][2]){for(var s=t[a][3]<>>0;s>0;s--)St(t[a-1],t[a]),a++,o--;i+=8}else a++,o--,i=0;return r}function wt(t,e,r,n){if(nyi)return Mt(t,e,r,n);var i=e[r++];if(2!=i)return Mt(t,e,r-1,n);if(t[0][1]=e[r++],t[0][2]=e[r++],i=e[r++],(t[0][2]<<8>>>0|i)>>>0!==n)return null;for(var i=0;i<4;i++)for(var a=0;a128){o=(127&o)>>>0;for(var s=e[r++];o--;)t[a++][i]=s}else for(;o--;)t[a++][i]=e[r++]}return r}function Ct(t){Ue.defaultsWithPropList(t,wi,Ci),Rt(t);for(var e="",r=0;r>16,r=t-(e<<8)>>8;return[e,r,t-(e<<16)-(r<<8)]}function se(t,e,r){return(t<<16)+(e<<8)+r}function ue(t){var e=t[1][0]-t[0][0],r=t[1][1]-t[0][1];return Math.sqrt(e*e+r*r)}function le(t){return[(t[0][0]+t[1][0])/2,(t[0][1]+t[1][1])/2]}function ce(t){return Array.isArray(t)||(t=[t,t]),t}function he(t,e){return{name:t.name,type:t.type,size:t.size,semantic:t.semantic,value:fe(t.value,e)}}function fe(t,e){return e?t:new t.constructor(t)}function de(t,e,r){return t*(1-r)+e*r}var pe={linear:function(t){return t},quadraticIn:function(t){return t*t},quadraticOut:function(t){return t*(2-t)},quadraticInOut:function(t){return(t*=2)<1?.5*t*t:-.5*(--t*(t-2)-1)},cubicIn:function(t){return t*t*t},cubicOut:function(t){return--t*t*t+1},cubicInOut:function(t){return(t*=2)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},quarticIn:function(t){return t*t*t*t},quarticOut:function(t){return 1- --t*t*t*t},quarticInOut:function(t){return(t*=2)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},quinticIn:function(t){return t*t*t*t*t},quinticOut:function(t){return--t*t*t*t*t+1},quinticInOut:function(t){return(t*=2)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},sinusoidalIn:function(t){return 1-Math.cos(t*Math.PI/2)},sinusoidalOut:function(t){return Math.sin(t*Math.PI/2)},sinusoidalInOut:function(t){return.5*(1-Math.cos(Math.PI*t))},exponentialIn:function(t){return 0===t?0:Math.pow(1024,t-1)},exponentialOut:function(t){return 1===t?1:1-Math.pow(2,-10*t)},exponentialInOut:function(t){return 0===t?0:1===t?1:(t*=2)<1?.5*Math.pow(1024,t-1):.5*(2-Math.pow(2,-10*(t-1)))},circularIn:function(t){return 1-Math.sqrt(1-t*t)},circularOut:function(t){return Math.sqrt(1- --t*t)},circularInOut:function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},elasticIn:function(t){var e,r=.1;return 0===t?0:1===t?1:(!r||r<1?(r=1,e=.1):e=.4*Math.asin(1/r)/(2*Math.PI),-r*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4))},elasticOut:function(t){var e,r=.1;return 0===t?0:1===t?1:(!r||r<1?(r=1,e=.1):e=.4*Math.asin(1/r)/(2*Math.PI),r*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/.4)+1)},elasticInOut:function(t){var e,r=.1;return 0===t?0:1===t?1:(!r||r<1?(r=1,e=.1):e=.4*Math.asin(1/r)/(2*Math.PI),(t*=2)<1?r*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4)*-.5:r*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4)*.5+1)},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){var e=1.70158;return--t*t*((e+1)*t+e)+1},backInOut:function(t){var e=2.5949095;return(t*=2)<1?t*t*((e+1)*t-e)*.5:.5*((t-=2)*t*((e+1)*t+e)+2)},bounceIn:function(t){return 1-pe.bounceOut(1-t)},bounceOut:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},bounceInOut:function(t){return t<.5?.5*pe.bounceIn(2*t):.5*pe.bounceOut(2*t-1)+.5}},me=function(t){t=t||{},this.name=t.name||"",this.target=t.target,this.life=t.life||1e3,this.delay=t.delay||0,this.gap=t.gap||0,this.playbackRate=t.playbackRate||1,this._initialized=!1,this._elapsedTime=0,this._loop=null!=t.loop&&t.loop,this.setLoop(this._loop),null!=t.easing&&this.setEasing(t.easing),this.onframe=t.onframe||e,this.onfinish=t.onfinish||e,this.onrestart=t.onrestart||e,this._paused=!1};me.prototype={gap:0,life:0,delay:0,setLoop:function(t){this._loop=t,t&&(this._loopRemained="number"==typeof t?t:1/0)},setEasing:function(t){"string"==typeof t&&(t=pe[t]),this.easing=t},step:function(t,e,r){if(this._initialized||(this._startTime=t+this.delay,this._initialized=!0),null!=this._currentTime&&(e=t-this._currentTime),this._currentTime=t,this._paused)return"paused";if(!(t0?(this._restartInLoop(t),this._loopRemained--,"restart"):(this._needsRemove=!0,"finish"):null}}},setTime:function(t){return this.step(t+this._startTime)},restart:function(t){var e=0;t&&(this._elapse(t),e=this._elapsedTime%this.life),t=t||Date.now(),this._startTime=t-e+this.delay,this._elapsedTime=0,this._needsRemove=!1,this._paused=!1},getElapsedTime:function(){return this._elapsedTime},_restartInLoop:function(t){this._startTime=t+this.gap,this._elapsedTime=0},_elapse:function(t,e){this._elapsedTime+=e*this.playbackRate},fire:function(t,e){var r="on"+t;this[r]&&this[r](this.target,e)},clone:function(){var t=new this.constructor;return t.name=this.name,t._loop=this._loop,t._loopRemained=this._loopRemained,t.life=this.life,t.gap=this.gap,t.delay=this.delay,t},pause:function(){this._paused=!0},resume:function(){this._paused=!1}},me.prototype.constructor=me;var _e=Array.prototype.slice;d.prototype={constructor:d,when:function(t,e,r){this._maxTime=Math.max(t,this._maxTime),r=("function"==typeof r?r:pe[r])||p;for(var n in e)this._tracks[n]||(this._tracks[n]=[],0!==t&&this._tracks[n].push({time:0,value:s(this._getter(this._target,n)),easing:r})),this._tracks[n].push({time:parseInt(t),value:e[n],easing:r});return this},then:function(t,e,r){return this.when(t+this._lastKFTime,e,r),this._lastKFTime+=t,this},during:function(t){return this._onframeList.push(t),this},_doneCallback:function(){this._tracks={},this._clipList.length=0;for(var t=this._doneList,e=t.length,r=0;rt)this.inputs.unshift(n);else if(this.inputs[i-1].position<=t)this.inputs.push(n);else{var a=this._findKey(t);this.inputs.splice(a,n)}return n},ve.prototype.step=function(t,e,r){var n=me.prototype.step.call(this,t);return"finish"!==n&&this.setTime(this.getElapsedTime()),r||"paused"===n||this.fire("frame"),n},ve.prototype.setTime=function(t){var e=this.position,r=this.inputs,n=r.length,i=r[0].position,a=r[n-1].position;if(e<=i||e>=a){var o=e<=i?r[0]:r[n-1],s=o.clip,u=o.offset;s.setTime((t+u)%s.life),s.output instanceof me?this.output.copy(s.output):this.output.copy(s)}else{var l=this._findKey(e),c=r[l],h=r[l+1],f=c.clip,d=h.clip;f.setTime((t+c.offset)%f.life),d.setTime((t+h.offset)%d.life);var p=(this.position-c.position)/(h.position-c.position),m=f.output instanceof me?f.output:f,_=d.output instanceof me?d.output:d;this.output.blend1D(m,_,p)}},ve.prototype.clone=function(t){var e=me.prototype.clone.call(this);e.output=this.output.clone();for(var r=0;r=r[i].position&&t=0;i--)t>=r[i].position&&t=0&&(this._cacheKey=e,this._cachePosition=t),e};var ye=1/1048576,Te={triangulate:function(t,e){var r,n,i,a,o,s,u,l,c,h,f,d,p=t.length;if(p<3)return[];if(t=t.slice(0),e)for(r=p;r--;)t[r]=t[r][e];for(i=new Array(p),r=p;r--;)i[r]=r;for(i.sort(function(e,r){var n=t[r][0]-t[e][0];return 0!==n?n:e-r}),a=m(t),t.push(a[0],a[1],a[2]),o=[_(t,p+0,p+1,p+2)],s=[],u=[],r=i.length;r--;u.length=0){for(d=i[r],n=o.length;n--;)l=t[d][0]-o[n].x,l>0&&l*l>o[n].r?(s.push(o[n]),o.splice(n,1)):(c=t[d][1]-o[n].y,l*l+c*c-o[n].r>ye||(u.push(o[n].i,o[n].j,o[n].j,o[n].k,o[n].k,o[n].i),o.splice(n,1)));for(g(u),n=u.length;n;)f=u[--n],h=u[--n],o.push(_(t,h,f,d))}for(r=o.length;r--;)s.push(o[r]);for(o.length=0,r=s.length;r--;)s[r].it[0][0]&&e[0]>t[1][0]&&e[0]>t[2][0]||e[1]t[0][1]&&e[1]>t[1][1]&&e[1]>t[2][1])return null;var r=t[1][0]-t[0][0],n=t[2][0]-t[0][0],i=t[1][1]-t[0][1],a=t[2][1]-t[0][1],o=r*a-n*i;if(0===o)return null;var s=(a*(e[0]-t[0][0])-n*(e[1]-t[0][1]))/o,u=(r*(e[1]-t[0][1])-i*(e[0]-t[0][0]))/o;return s<0||u<0||s+u>1?null:[s,u]}},xe=Array,Ee=Math.random,Ae={};Ae.create=function(){var t=new xe(2);return t[0]=0,t[1]=0,t},Ae.clone=function(t){var e=new xe(2);return e[0]=t[0],e[1]=t[1],e},Ae.fromValues=function(t,e){var r=new xe(2);return r[0]=t,r[1]=e,r},Ae.copy=function(t,e){return t[0]=e[0],t[1]=e[1],t},Ae.set=function(t,e,r){return t[0]=e,t[1]=r,t},Ae.add=function(t,e,r){return t[0]=e[0]+r[0],t[1]=e[1]+r[1],t},Ae.subtract=function(t,e,r){return t[0]=e[0]-r[0],t[1]=e[1]-r[1],t},Ae.sub=Ae.subtract,Ae.multiply=function(t,e,r){return t[0]=e[0]*r[0],t[1]=e[1]*r[1],t},Ae.mul=Ae.multiply,Ae.divide=function(t,e,r){return t[0]=e[0]/r[0],t[1]=e[1]/r[1],t},Ae.div=Ae.divide,Ae.min=function(t,e,r){return t[0]=Math.min(e[0],r[0]),t[1]=Math.min(e[1],r[1]),t},Ae.max=function(t,e,r){return t[0]=Math.max(e[0],r[0]),t[1]=Math.max(e[1],r[1]),t},Ae.scale=function(t,e,r){return t[0]=e[0]*r,t[1]=e[1]*r,t},Ae.scaleAndAdd=function(t,e,r,n){return t[0]=e[0]+r[0]*n,t[1]=e[1]+r[1]*n,t},Ae.distance=function(t,e){var r=e[0]-t[0],n=e[1]-t[1];return Math.sqrt(r*r+n*n)},Ae.dist=Ae.distance,Ae.squaredDistance=function(t,e){var r=e[0]-t[0],n=e[1]-t[1];return r*r+n*n},Ae.sqrDist=Ae.squaredDistance,Ae.length=function(t){var e=t[0],r=t[1];return Math.sqrt(e*e+r*r)},Ae.len=Ae.length,Ae.squaredLength=function(t){var e=t[0],r=t[1];return e*e+r*r},Ae.sqrLen=Ae.squaredLength,Ae.negate=function(t,e){return t[0]=-e[0],t[1]=-e[1],t},Ae.inverse=function(t,e){return t[0]=1/e[0],t[1]=1/e[1],t},Ae.normalize=function(t,e){var r=e[0],n=e[1],i=r*r+n*n;return i>0&&(i=1/Math.sqrt(i),t[0]=e[0]*i,t[1]=e[1]*i),t},Ae.dot=function(t,e){return t[0]*e[0]+t[1]*e[1]},Ae.cross=function(t,e,r){var n=e[0]*r[1]-e[1]*r[0];return t[0]=t[1]=0,t[2]=n,t},Ae.lerp=function(t,e,r,n){var i=e[0],a=e[1];return t[0]=i+n*(r[0]-i),t[1]=a+n*(r[1]-a),t},Ae.random=function(t,e){e=e||1;var r=2*GLMAT_RANDOM()*Math.PI;return t[0]=Math.cos(r)*e,t[1]=Math.sin(r)*e,t},Ae.transformMat2=function(t,e,r){var n=e[0],i=e[1];return t[0]=r[0]*n+r[2]*i,t[1]=r[1]*n+r[3]*i,t},Ae.transformMat2d=function(t,e,r){var n=e[0],i=e[1];return t[0]=r[0]*n+r[2]*i+r[4],t[1]=r[1]*n+r[3]*i+r[5],t},Ae.transformMat3=function(t,e,r){var n=e[0],i=e[1];return t[0]=r[0]*n+r[3]*i+r[6],t[1]=r[1]*n+r[4]*i+r[7],t},Ae.transformMat4=function(t,e,r){var n=e[0],i=e[1];return t[0]=r[0]*n+r[4]*i+r[12],t[1]=r[1]*n+r[5]*i+r[13],t},Ae.forEach=function(){var t=Ae.create();return function(e,r,n,i,a,o){var s,u;for(r||(r=2),n||(n=0),u=i?Math.min(i*r+n,e.length):e.length,s=n;s0&&(a=1/Math.sqrt(a),t[0]=e[0]*a,t[1]=e[1]*a,t[2]=e[2]*a),t},we.dot=function(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]},we.cross=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=r[0],s=r[1],u=r[2];return t[0]=i*u-a*s,t[1]=a*o-n*u,t[2]=n*s-i*o,t},we.lerp=function(t,e,r,n){var i=e[0],a=e[1],o=e[2];return t[0]=i+n*(r[0]-i),t[1]=a+n*(r[1]-a),t[2]=o+n*(r[2]-o),t},we.random=function(t,e){e=e||1;var r=2*Ee()*Math.PI,n=2*Ee()-1,i=Math.sqrt(1-n*n)*e;return t[0]=Math.cos(r)*i,t[1]=Math.sin(r)*i,t[2]=n*e,t},we.transformMat4=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=r[3]*n+r[7]*i+r[11]*a+r[15];return o=o||1,t[0]=(r[0]*n+r[4]*i+r[8]*a+r[12])/o,t[1]=(r[1]*n+r[5]*i+r[9]*a+r[13])/o,t[2]=(r[2]*n+r[6]*i+r[10]*a+r[14])/o,t},we.transformMat3=function(t,e,r){var n=e[0],i=e[1],a=e[2];return t[0]=n*r[0]+i*r[3]+a*r[6],t[1]=n*r[1]+i*r[4]+a*r[7],t[2]=n*r[2]+i*r[5]+a*r[8],t},we.transformQuat=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=r[0],s=r[1],u=r[2],l=r[3],c=l*n+s*a-u*i,h=l*i+u*n-o*a,f=l*a+o*i-s*n,d=-o*n-s*i-u*a;return t[0]=c*l+d*-o+h*-u-f*-s,t[1]=h*l+d*-s+f*-o-c*-u,t[2]=f*l+d*-u+c*-s-h*-o,t},we.rotateX=function(t,e,r,n){var i=[],a=[];return i[0]=e[0]-r[0],i[1]=e[1]-r[1],i[2]=e[2]-r[2],a[0]=i[0],a[1]=i[1]*Math.cos(n)-i[2]*Math.sin(n),a[2]=i[1]*Math.sin(n)+i[2]*Math.cos(n),t[0]=a[0]+r[0],t[1]=a[1]+r[1],t[2]=a[2]+r[2],t},we.rotateY=function(t,e,r,n){var i=[],a=[];return i[0]=e[0]-r[0],i[1]=e[1]-r[1],i[2]=e[2]-r[2],a[0]=i[2]*Math.sin(n)+i[0]*Math.cos(n),a[1]=i[1],a[2]=i[2]*Math.cos(n)-i[0]*Math.sin(n),t[0]=a[0]+r[0],t[1]=a[1]+r[1],t[2]=a[2]+r[2],t},we.rotateZ=function(t,e,r,n){var i=[],a=[];return i[0]=e[0]-r[0],i[1]=e[1]-r[1],i[2]=e[2]-r[2],a[0]=i[0]*Math.cos(n)-i[1]*Math.sin(n),a[1]=i[0]*Math.sin(n)+i[1]*Math.cos(n),a[2]=i[2],t[0]=a[0]+r[0],t[1]=a[1]+r[1],t[2]=a[2]+r[2],t},we.forEach=function(){var t=we.create();return function(e,r,n,i,a,o){var s,u;for(r||(r=3),n||(n=0),u=i?Math.min(i*r+n,e.length):e.length,s=n;s1?0:Math.acos(i)};var Ce={};Ce.create=function(){var t=new xe(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},Ce.clone=function(t){var e=new xe(4);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e},Ce.fromValues=function(t,e,r,n){var i=new xe(4);return i[0]=t,i[1]=e,i[2]=r,i[3]=n,i},Ce.copy=function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t},Ce.set=function(t,e,r,n,i){return t[0]=e,t[1]=r,t[2]=n,t[3]=i,t},Ce.add=function(t,e,r){return t[0]=e[0]+r[0],t[1]=e[1]+r[1],t[2]=e[2]+r[2],t[3]=e[3]+r[3],t},Ce.subtract=function(t,e,r){return t[0]=e[0]-r[0],t[1]=e[1]-r[1],t[2]=e[2]-r[2],t[3]=e[3]-r[3],t},Ce.sub=Ce.subtract,Ce.multiply=function(t,e,r){return t[0]=e[0]*r[0],t[1]=e[1]*r[1],t[2]=e[2]*r[2],t[3]=e[3]*r[3],t},Ce.mul=Ce.multiply,Ce.divide=function(t,e,r){return t[0]=e[0]/r[0],t[1]=e[1]/r[1],t[2]=e[2]/r[2],t[3]=e[3]/r[3],t},Ce.div=Ce.divide,Ce.min=function(t,e,r){return t[0]=Math.min(e[0],r[0]),t[1]=Math.min(e[1],r[1]),t[2]=Math.min(e[2],r[2]),t[3]=Math.min(e[3],r[3]),t},Ce.max=function(t,e,r){return t[0]=Math.max(e[0],r[0]),t[1]=Math.max(e[1],r[1]),t[2]=Math.max(e[2],r[2]),t[3]=Math.max(e[3],r[3]),t},Ce.scale=function(t,e,r){return t[0]=e[0]*r,t[1]=e[1]*r,t[2]=e[2]*r,t[3]=e[3]*r,t},Ce.scaleAndAdd=function(t,e,r,n){return t[0]=e[0]+r[0]*n,t[1]=e[1]+r[1]*n,t[2]=e[2]+r[2]*n,t[3]=e[3]+r[3]*n,t},Ce.distance=function(t,e){var r=e[0]-t[0],n=e[1]-t[1],i=e[2]-t[2],a=e[3]-t[3];return Math.sqrt(r*r+n*n+i*i+a*a)},Ce.dist=Ce.distance,Ce.squaredDistance=function(t,e){var r=e[0]-t[0],n=e[1]-t[1],i=e[2]-t[2],a=e[3]-t[3];return r*r+n*n+i*i+a*a},Ce.sqrDist=Ce.squaredDistance,Ce.length=function(t){var e=t[0],r=t[1],n=t[2],i=t[3];return Math.sqrt(e*e+r*r+n*n+i*i)},Ce.len=Ce.length,Ce.squaredLength=function(t){var e=t[0],r=t[1],n=t[2],i=t[3];return e*e+r*r+n*n+i*i},Ce.sqrLen=Ce.squaredLength,Ce.negate=function(t,e){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t},Ce.inverse=function(t,e){return t[0]=1/e[0],t[1]=1/e[1],t[2]=1/e[2],t[3]=1/e[3],t},Ce.normalize=function(t,e){var r=e[0],n=e[1],i=e[2],a=e[3],o=r*r+n*n+i*i+a*a;return o>0&&(o=1/Math.sqrt(o),t[0]=e[0]*o,t[1]=e[1]*o,t[2]=e[2]*o,t[3]=e[3]*o),t},Ce.dot=function(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]+t[3]*e[3]},Ce.lerp=function(t,e,r,n){var i=e[0],a=e[1],o=e[2],s=e[3];return t[0]=i+n*(r[0]-i),t[1]=a+n*(r[1]-a),t[2]=o+n*(r[2]-o),t[3]=s+n*(r[3]-s),t},Ce.random=function(t,e){return e=e||1,t[0]=Ee(),t[1]=Ee(),t[2]=Ee(),t[3]=Ee(),Ce.normalize(t,t),Ce.scale(t,t,e),t},Ce.transformMat4=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=e[3];return t[0]=r[0]*n+r[4]*i+r[8]*a+r[12]*o,t[1]=r[1]*n+r[5]*i+r[9]*a+r[13]*o,t[2]=r[2]*n+r[6]*i+r[10]*a+r[14]*o,t[3]=r[3]*n+r[7]*i+r[11]*a+r[15]*o,t},Ce.transformQuat=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=r[0],s=r[1],u=r[2],l=r[3],c=l*n+s*a-u*i,h=l*i+u*n-o*a,f=l*a+o*i-s*n,d=-o*n-s*i-u*a;return t[0]=c*l+d*-o+h*-u-f*-s,t[1]=h*l+d*-s+f*-o-c*-u,t[2]=f*l+d*-u+c*-s-h*-o,t},Ce.forEach=function(){var t=Ce.create();return function(e,r,n,i,a,o){var s,u;for(r||(r=4),n||(n=0),u=i?Math.min(i*r+n,e.length):e.length,s=n;s.999999?(n[0]=0,n[1]=0,n[2]=0,n[3]=1,n):(we.cross(t,i,a),n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=1+o,Le.normalize(n,n))}}(),Le.setAxes=function(){var t=Re.create();return function(e,r,n,i){return t[0]=n[0],t[3]=n[1],t[6]=n[2],t[1]=i[0],t[4]=i[1],t[7]=i[2],t[2]=-r[0],t[5]=-r[1],t[8]=-r[2],Le.normalize(e,Le.fromMat3(e,t))}}(),Le.clone=Ce.clone,Le.fromValues=Ce.fromValues,Le.copy=Ce.copy,Le.set=Ce.set,Le.identity=function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},Le.setAxisAngle=function(t,e,r){r*=.5;var n=Math.sin(r);return t[0]=n*e[0],t[1]=n*e[1],t[2]=n*e[2],t[3]=Math.cos(r),t},Le.add=Ce.add,Le.multiply=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=e[3],s=r[0],u=r[1],l=r[2],c=r[3];return t[0]=n*c+o*s+i*l-a*u,t[1]=i*c+o*u+a*s-n*l,t[2]=a*c+o*l+n*u-i*s,t[3]=o*c-n*s-i*u-a*l,t},Le.mul=Le.multiply,Le.scale=Ce.scale,Le.rotateX=function(t,e,r){r*=.5;var n=e[0],i=e[1],a=e[2],o=e[3],s=Math.sin(r),u=Math.cos(r);return t[0]=n*u+o*s,t[1]=i*u+a*s,t[2]=a*u-i*s,t[3]=o*u-n*s,t},Le.rotateY=function(t,e,r){r*=.5;var n=e[0],i=e[1],a=e[2],o=e[3],s=Math.sin(r),u=Math.cos(r);return t[0]=n*u-a*s,t[1]=i*u+o*s,t[2]=a*u+n*s,t[3]=o*u-i*s,t},Le.rotateZ=function(t,e,r){r*=.5;var n=e[0],i=e[1],a=e[2],o=e[3],s=Math.sin(r),u=Math.cos(r);return t[0]=n*u+i*s,t[1]=i*u-n*s,t[2]=a*u+o*s,t[3]=o*u-a*s,t},Le.calculateW=function(t,e){var r=e[0],n=e[1],i=e[2];return t[0]=r,t[1]=n,t[2]=i,t[3]=Math.sqrt(Math.abs(1-r*r-n*n-i*i)),t},Le.dot=Ce.dot,Le.lerp=Ce.lerp,Le.slerp=function(t,e,r,n){var i,a,o,s,u,l=e[0],c=e[1],h=e[2],f=e[3],d=r[0],p=r[1],m=r[2],_=r[3];return a=l*d+c*p+h*m+f*_,a<0&&(a=-a,d=-d,p=-p,m=-m,_=-_),1-a>1e-6?(i=Math.acos(a),o=Math.sin(i),s=Math.sin((1-n)*i)/o,u=Math.sin(n*i)/o):(s=1-n,u=n),t[0]=s*l+u*d,t[1]=s*c+u*p,t[2]=s*h+u*m,t[3]=s*f+u*_,t},Le.invert=function(t,e){var r=e[0],n=e[1],i=e[2],a=e[3],o=r*r+n*n+i*i+a*a,s=o?1/o:0;return t[0]=-r*s,t[1]=-n*s,t[2]=-i*s,t[3]=a*s,t},Le.conjugate=function(t,e){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=e[3],t},Le.length=Ce.length,Le.len=Le.length,Le.squaredLength=Ce.squaredLength,Le.sqrLen=Le.squaredLength,Le.normalize=Ce.normalize,Le.fromMat3=function(t,e){var r,n=e[0]+e[4]+e[8];if(n>0)r=Math.sqrt(n+1),t[3]=.5*r,r=.5/r,t[0]=(e[5]-e[7])*r,t[1]=(e[6]-e[2])*r,t[2]=(e[1]-e[3])*r;else{var i=0;e[4]>e[0]&&(i=1),e[8]>e[3*i+i]&&(i=2);var a=(i+1)%3,o=(i+2)%3;r=Math.sqrt(e[3*i+i]-e[3*a+a]-e[3*o+o]+1),t[i]=.5*r,r=.5/r,t[3]=(e[3*a+o]-e[3*o+a])*r,t[a]=(e[3*a+i]+e[3*i+a])*r,t[o]=(e[3*o+i]+e[3*i+o])*r}return t};var Ne=function(t){t=t||{},this.name=t.name||"",this.target=t.target||null,this.position=we.create(),this.rotation=Le.create(),this.scale=we.fromValues(1,1,1),this.channels={time:null,position:null,rotation:null,scale:null},this._cacheKey=0,this._cacheTime=0};Ne.prototype.setTime=function(t){if(this.channels.time){var e=this.channels,r=e.time.length,n=-1;if(1===r)return e.rotation&&Le.copy(this.rotation,e.rotation),e.position&&we.copy(this.position,e.position),void(e.scale&&we.copy(this.scale,e.scale));if(t<=e.time[0])t=e.time[0],n=0;else if(t>=e.time[r-1])t=e.time[r-1],n=r-2;else if(t=0;a--)if(e.time[a-1]<=t&&e.time[a]>t){n=a-1;break}}else for(var a=this._cacheKey;at){n=a;break}if(n>-1){this._cacheKey=n,this._cacheTime=t;var o=n,s=n+1,u=e.time[o],l=e.time[s],c=l-u,h=0===c?0:(t-u)/c;e.rotation&&y(this.rotation,e.rotation,e.rotation,h,4*o,4*s),e.position&&v(this.position,e.position,e.position,h,3*o,3*s),e.scale&&v(this.scale,e.scale,e.scale,h,3*o,3*s)}n===r-2&&(this._cacheKey=0,this._cacheTime=0),this.updateTarget()}},Ne.prototype.updateTarget=function(){var t=this.channels;this.target&&(t.position&&this.target.position.setArray(this.position),t.rotation&&this.target.rotation.setArray(this.rotation),t.scale&&this.target.scale.setArray(this.scale))},Ne.prototype.getMaxTime=function(){return this.channels.time[this.channels.time.length-1]},Ne.prototype.getSubTrack=function(t,e){var r=new Ne({name:this.name}),n=this.channels.time[0];t=Math.min(Math.max(t,n),this.life),e=Math.min(Math.max(e,n),this.life);var i=this._findRange(t),a=this._findRange(e),o=a[0]-i[0]+1;0===i[1]&&0===a[1]&&(o-=1),this.channels.rotation&&(r.channels.rotation=new Float32Array(4*o)),this.channels.position&&(r.channels.position=new Float32Array(3*o)),this.channels.scale&&(r.channels.scale=new Float32Array(3*o)),this.channels.time&&(r.channels.time=new Float32Array(o)),this.setTime(t);for(var s=0;s<3;s++)r.channels.rotation[s]=this.rotation[s],r.channels.position[s]=this.position[s],r.channels.scale[s]=this.scale[s];r.channels.time[0]=0,r.channels.rotation[3]=this.rotation[3];for(var s=1;st&&(n=i);var a=0;if(n>=0)var o=e.time[n],s=e.time[n+1],a=(t-o)/(s-o);return[n,a]},Ne.prototype.blend1D=function(t,e,r){we.lerp(this.position,t.position,e.position,r),we.lerp(this.scale,t.scale,e.scale,r),Le.slerp(this.rotation,t.rotation,e.rotation,r)},Ne.prototype.blend2D=function(){var t=Le.create(),e=Le.create();return function(r,n,i,a,o){var s=1-a-o;this.position[0]=r.position[0]*s+n.position[0]*a+i.position[0]*o,this.position[1]=r.position[1]*s+n.position[1]*a+i.position[1]*o,this.position[2]=r.position[2]*s+n.position[2]*a+i.position[2]*o,this.scale[0]=r.scale[0]*s+n.scale[0]*a+i.scale[0]*o,this.scale[1]=r.scale[1]*s+n.scale[1]*a+i.scale[1]*o,this.scale[2]=r.scale[2]*s+n.scale[2]*a+i.scale[2]*o;var u=a+o;0===u?Le.copy(this.rotation,r.rotation):(Le.slerp(t,r.rotation,n.rotation,u),Le.slerp(e,r.rotation,i.rotation,u),Le.slerp(this.rotation,t,e,o/u))}}(),Ne.prototype.additiveBlend=function(t,e){we.add(this.position,t.position,e.position),we.add(this.scale,t.scale,e.scale),Le.multiply(this.rotation,e.rotation,t.rotation)},Ne.prototype.subtractiveBlend=function(t,e){we.sub(this.position,t.position,e.position),we.sub(this.scale,t.scale,e.scale),Le.invert(this.rotation,e.rotation),Le.multiply(this.rotation,this.rotation,t.rotation)},Ne.prototype.clone=function(){var t=Ne.prototype.clone.call(this);return t.channels={time:this.channels.time||null,position:this.channels.position||null,rotation:this.channels.rotation||null,scale:this.channels.scale||null},we.copy(t.position,this.position),Le.copy(t.rotation,this.rotation),we.copy(t.scale,this.scale),t.target=this.target,t.updateTarget(),t};var Pe={extend:T,derive:T},Ie={trigger:function(t){if(this.hasOwnProperty("__handlers__")&&this.__handlers__.hasOwnProperty(t)){var e=this.__handlers__[t],r=e.length,n=-1,i=arguments;switch(i.length){case 1:for(;++n=0&&this._clips.splice(e,1)},removeAnimator:function(t){for(var e=t.getClips(),r=0;r=0&&this.tracks.splice(e,1)},ze.prototype.getSubClip=function(t,e,r){for(var n=new ze({name:this.name}),i=0;i=this._maxSize&&r>0){var n=this._list.head;this._list.remove(n),delete this._map[n.key]}var i=this._list.insert(e);i.key=t,this._map[t]=i}},Ke.prototype.get=function(t){var e=this._map[t];if(this._map.hasOwnProperty(t))return e!==this._list.tail&&(this._list.remove(e),this._list.insertEntry(e)),e.value},Ke.prototype.remove=function(t){var e=this._map[t];void 0!==e&&(delete this._map[t],this._list.remove(e))},Ke.prototype.clear=function(){this._list.clear(),this._map={}};var Ze={},Je={transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]},Qe=new Ke(20),$e=null;Ze.parse=function(t,e){if(t){e=e||[];var r=Qe.get(t);if(r)return O(e,r);t+="";var n=t.replace(/ /g,"").toLowerCase();if(n in Je)return O(e,Je[n]),D(t,e),e;if("#"!==n.charAt(0)){var i=n.indexOf("("),a=n.indexOf(")");if(-1!==i&&a+1===n.length){var o=n.substr(0,i),s=n.substr(i+1,a-(i+1)).split(","),u=1;switch(o){case"rgba":if(4!==s.length)return void I(e,0,0,0,1);u=L(s.pop());case"rgb":return 3!==s.length?void I(e,0,0,0,1):(I(e,R(s[0]),R(s[1]),R(s[2]),u),D(t,e),e);case"hsla":return 4!==s.length?void I(e,0,0,0,1):(s[3]=L(s[3]),B(s,e),D(t,e),e);case"hsl":return 3!==s.length?void I(e,0,0,0,1):(B(s,e),D(t,e),e);default:return}}I(e,0,0,0,1)}else{if(4===n.length){var l=parseInt(n.substr(1),16);return l>=0&&l<=4095?(I(e,(3840&l)>>4|(3840&l)>>8,240&l|(240&l)>>4,15&l|(15&l)<<4,1),D(t,e),e):void I(e,0,0,0,1)}if(7===n.length){var l=parseInt(n.substr(1),16);return l>=0&&l<=16777215?(I(e,(16711680&l)>>16,(65280&l)>>8,255&l,1),D(t,e),e):void I(e,0,0,0,1)}}}},Ze.parseToFloat=function(t,e){if(e=Ze.parse(t,e))return e[0]/=255,e[1]/=255,e[2]/=255,e},Ze.lift=function(t,e){var r=Ze.parse(t);if(r){for(var n=0;n<3;n++)r[n]=e<0?r[n]*(1-e)|0:(255-r[n])*e+r[n]|0;return Ze.stringify(r,4===r.length?"rgba":"rgb")}},Ze.toHex=function(t){var e=Ze.parse(t);if(e)return((1<<24)+(e[0]<<16)+(e[1]<<8)+ +e[2]).toString(16).slice(1)},Ze.fastLerp=function(t,e,r){if(e&&e.length&&t>=0&&t<=1){r=r||[];var n=t*(e.length-1),i=Math.floor(n),a=Math.ceil(n),o=e[i],s=e[a],u=n-i;return r[0]=M(P(o[0],s[0],u)),r[1]=M(P(o[1],s[1],u)),r[2]=M(P(o[2],s[2],u)),r[3]=C(P(o[3],s[3],u)),r}},Ze.fastMapToColor=Ze.fastLerp,Ze.lerp=function(t,e,r){if(e&&e.length&&t>=0&&t<=1){var n=t*(e.length-1),i=Math.floor(n),a=Math.ceil(n),o=Ze.parse(e[i]),s=Ze.parse(e[a]),u=n-i,l=Ze.stringify([M(P(o[0],s[0],u)),M(P(o[1],s[1],u)),M(P(o[2],s[2],u)),C(P(o[3],s[3],u))],"rgba");return r?{color:l,leftIndex:i,rightIndex:a,value:n}:l}},Ze.mapToColor=Ze.lerp,Ze.modifyHSL=function(t,e,r,n){if(t=Ze.parse(t))return t=U(t),null!=e&&(t[0]=w(e)),null!=r&&(t[1]=L(r)),null!=n&&(t[2]=L(n)),Ze.stringify(B(t),"rgba")},Ze.modifyAlpha=function(t,e){if((t=Ze.parse(t))&&null!=e)return t[3]=C(e),Ze.stringify(t,"rgba")},Ze.stringify=function(t,e){if(t&&t.length){var r=t[0]+","+t[1]+","+t[2];return"rgba"!==e&&"hsva"!==e&&"hsla"!==e||(r+=","+t[3]),e+"("+r+")"}};var tr=Ze.parseToFloat,er={},rr=Fe.extend(function(){return{name:"",depthTest:!0,depthMask:!0,transparent:!1,blend:null,autoUpdateTextureStatus:!0,uniforms:{},vertexDefines:{},fragmentDefines:{},_textureStatus:{},_enabledUniforms:null}},function(){this.name||(this.name="MATERIAL_"+this.__uid__),this.shader&&this.attachShader(this.shader,!0)},{precision:"highp",setUniform:function(t,e){void 0===e&&console.warn('Uniform value "'+t+'" is undefined');var r=this.uniforms[t];r&&("string"==typeof e&&(e=tr(e)||e),r.value=e,this.autoUpdateTextureStatus&&"t"===r.type&&(e?this.enableTexture(t):this.disableTexture(t)))},setUniforms:function(t){for(var e in t){var r=t[e];this.setUniform(e,r)}},isUniformEnabled:function(t){return this._enabledUniforms.indexOf(t)>=0},getEnabledUniforms:function(){return this._enabledUniforms},getTextureUniforms:function(){return this._textureUniforms},set:function(t,e){if("object"==typeof t)for(var r in t){var n=t[r];this.setUniform(r,n)}else this.setUniform(t,e)},get:function(t){var e=this.uniforms[t];if(e)return e.value},attachShader:function(t,e){var r=this.uniforms;this.uniforms=t.createUniforms(),this.shader=t;var n=this.uniforms;this._enabledUniforms=Object.keys(n),this._enabledUniforms.sort(),this._textureUniforms=this._enabledUniforms.filter(function(t){var e=this.uniforms[t].type;return"t"===e||"tv"===e},this);var i=this.vertexDefines,a=this.fragmentDefines;if(this.vertexDefines=Ue.clone(t.vertexDefines),this.fragmentDefines=Ue.clone(t.fragmentDefines),e){for(var o in r)n[o]&&(n[o].value=r[o].value);Ue.defaults(this.vertexDefines,i),Ue.defaults(this.fragmentDefines,a)}var s={};for(var u in t.textures)s[u]={shaderType:t.textures[u].shaderType,type:t.textures[u].type,enabled:!(!e||!this._textureStatus[u])&&this._textureStatus[u].enabled};this._textureStatus=s,this._programKey=""},clone:function(){var t=new this.constructor({name:this.name,shader:this.shader});for(var e in this.uniforms)t.uniforms[e].value=this.uniforms[e].value;return t.depthTest=this.depthTest,t.depthMask=this.depthMask,t.transparent=this.transparent,t.blend=this.blend,t.vertexDefines=Ue.clone(this.vertexDefines),t.fragmentDefines=Ue.clone(this.fragmentDefines),t.enableTexture(this.getEnabledTextures()),t.precision=this.precision,t},define:function(t,e,r){var n=this.vertexDefines,i=this.fragmentDefines;"vertex"!==t&&"fragment"!==t&&"both"!==t&&arguments.length<3&&(r=e,e=t,t="both"),r=null!=r?r:null,"vertex"!==t&&"both"!==t||n[e]!==r&&(n[e]=r,this._programKey=""),"fragment"!==t&&"both"!==t||i[e]!==r&&(i[e]=r,"both"!==t&&(this._programKey=""))},undefine:function(t,e){"vertex"!==t&&"fragment"!==t&&"both"!==t&&arguments.length<2&&(e=t,t="both"),"vertex"!==t&&"both"!==t||this.isDefined("vertex",e)&&(delete this.vertexDefines[e],this._programKey=""),"fragment"!==t&&"both"!==t||this.isDefined("fragment",e)&&(delete this.fragmentDefines[e],"both"!==t&&(this._programKey=""))},isDefined:function(t,e){switch(t){case"vertex":return void 0!==this.vertexDefines[e];case"fragment":return void 0!==this.fragmentDefines[e]}},getDefine:function(t,e){switch(t){case"vertex":return this.vertexDefines[e];case"fragment":return this.fragmentDefines[e]}},enableTexture:function(t){if(Array.isArray(t))for(var e=0;eu.getMaxJointNumber()&&(f.USE_SKIN_MATRICES_TEXTURE=null),h="\n"+W(f)+"\n"}var d=h+W(e.vertexDefines,s,c),p=h+W(e.fragmentDefines,s,c),m=d+"\n"+e.shader.vertex,_=["OES_standard_derivatives","EXT_shader_texture_lod"].filter(function(t){return null!=u.getGLExtension(t)});_.indexOf("EXT_shader_texture_lod")>=0&&(p+="\n#define SUPPORT_TEXTURE_LOD"),_.indexOf("OES_standard_derivatives")>=0&&(p+="\n#define SUPPORT_STANDARD_DERIVATIVES");var g=z(_)+"\n"+X(e.precision)+"\n"+p+"\n"+e.shader.fragment,v=V(m,e.vertexDefines,s),y=V(g,e.fragmentDefines,s),o=new ar;o.uniformSemantics=e.shader.uniformSemantics,o.attributes=e.shader.attributes;var T=o.buildProgram(l,e.shader,v,y);return o.__error=T,n[a]=o,o};var sr=/uniform\s+(bool|float|int|vec2|vec3|vec4|ivec2|ivec3|ivec4|mat2|mat3|mat4|sampler2D|samplerCube)\s+([\s\S]*?);/g,ur=/attribute\s+(float|int|vec2|vec3|vec4)\s+([\s\S]*?);/g,lr=/#define\s+(\w+)?(\s+[\d-.]+)?\s*;?\s*\n/g,cr={bool:"1i",int:"1i",sampler2D:"t",samplerCube:"t",float:"1f",vec2:"2f",vec3:"3f",vec4:"4f",ivec2:"2i",ivec3:"3i",ivec4:"4i",mat2:"m2",mat3:"m3",mat4:"m4"},hr={bool:function(){return!0},int:function(){return 0},float:function(){return 0},sampler2D:function(){return null},samplerCube:function(){return null},vec2:function(){return q(2)},vec3:function(){return q(3)},vec4:function(){return q(4)},ivec2:function(){return q(2)},ivec3:function(){return q(3)},ivec4:function(){return q(4)},mat2:function(){return q(4)},mat3:function(){return q(9)},mat4:function(){return q(16)},array:function(){return[]}},fr=["POSITION","NORMAL","BINORMAL","TANGENT","TEXCOORD","TEXCOORD_0","TEXCOORD_1","COLOR","JOINT","WEIGHT"],dr=["SKIN_MATRIX","VIEWPORT_SIZE","VIEWPORT","DEVICEPIXELRATIO","WINDOW_SIZE","NEAR","FAR","TIME"],pr=["WORLD","VIEW","PROJECTION","WORLDVIEW","VIEWPROJECTION","WORLDVIEWPROJECTION","WORLDINVERSE","VIEWINVERSE","PROJECTIONINVERSE","WORLDVIEWINVERSE","VIEWPROJECTIONINVERSE","WORLDVIEWPROJECTIONINVERSE","WORLDTRANSPOSE","VIEWTRANSPOSE","PROJECTIONTRANSPOSE","WORLDVIEWTRANSPOSE","VIEWPROJECTIONTRANSPOSE","WORLDVIEWPROJECTIONTRANSPOSE","WORLDINVERSETRANSPOSE","VIEWINVERSETRANSPOSE","PROJECTIONINVERSETRANSPOSE","WORLDVIEWINVERSETRANSPOSE","VIEWPROJECTIONINVERSETRANSPOSE","WORLDVIEWPROJECTIONINVERSETRANSPOSE"],mr={vec4:4,vec3:3,vec2:2,float:1},_r={},gr={};Q.prototype={constructor:Q,createUniforms:function(){var t={};for(var e in this.uniformTemplates){var r=this.uniformTemplates[e];t[e]={type:r.type,value:r.value()}}return t},_parseImport:function(){this._vertexCode=Q.parseImport(this.vertex),this._fragmentCode=Q.parseImport(this.fragment)},_addSemanticUniform:function(t,e,r){if(fr.indexOf(r)>=0)this.attributeSemantics[r]={symbol:t,type:e};else if(pr.indexOf(r)>=0){var n=!1,i=r;r.match(/TRANSPOSE$/)&&(n=!0,i=r.slice(0,-9)),this.matrixSemantics[r]={symbol:t,type:e,isTranspose:n,semanticNoTranspose:i}}else dr.indexOf(r)>=0&&(this.uniformSemantics[r]={symbol:t,type:e})},_addMaterialUniform:function(t,e,r,n,i,a){a[t]={type:r,value:i?hr.array:n||hr[e],semantic:null}},_parseUniforms:function(){function t(t){return null!=t?function(){return t}:null}function e(e,a,o){var s=J(a,o),u=[];for(var l in s){var c=s[l],h=c.semantic,f=l,d=cr[a],p=t(s[l].value);s[l].isArray&&(f+="["+s[l].arraySize+"]",d+="v"),u.push(f),n._uniformList.push(l),c.ignore||("sampler2D"!==a&&"samplerCube"!==a||(n.textures[l]={shaderType:i,type:a}),h?n._addSemanticUniform(l,d,h):n._addMaterialUniform(l,a,d,p,s[l].isArray,r))}return u.length>0?"uniform "+a+" "+u.join(",")+";\n":""}var r={},n=this,i="vertex";this._uniformList=[],this._vertexCode=this._vertexCode.replace(sr,e),i="fragment",this._fragmentCode=this._fragmentCode.replace(sr,e),n.matrixSemanticKeys=Object.keys(this.matrixSemantics),this.uniformTemplates=r},_parseAttributes:function(){function t(t,n,i){var a=J(n,i),o=mr[n]||1,s=[];for(var u in a){var l=a[u].semantic;if(e[u]={type:"float",size:o,semantic:l||null},l){if(fr.indexOf(l)<0)throw new Error('Unkown semantic "'+l+'"');r.attributeSemantics[l]={symbol:u,type:n}}s.push(u)}return"attribute "+n+" "+s.join(",")+";\n"}var e={},r=this;this._vertexCode=this._vertexCode.replace(ur,t),this.attributes=e},_parseDefines:function(){function t(t,n,i){var a="vertex"===r?e.vertexDefines:e.fragmentDefines;return a[n]||(a[n]="false"!==i&&("true"===i||(i?isNaN(parseFloat(i))?i.trim():parseFloat(i):null))),""}var e=this,r="vertex";this._vertexCode=this._vertexCode.replace(lr,t),r="fragment",this._fragmentCode=this._fragmentCode.replace(lr,t)},clone:function(){var t=gr[this._shaderID];return new Q(t.vertex,t.fragment)}},Object.defineProperty&&(Object.defineProperty(Q.prototype,"shaderID",{get:function(){return this._shaderID}}),Object.defineProperty(Q.prototype,"vertex",{get:function(){return this._vertexCode}}),Object.defineProperty(Q.prototype,"fragment",{get:function(){return this._fragmentCode}}),Object.defineProperty(Q.prototype,"uniforms",{get:function(){return this._uniformList}}));var vr=/(@import)\s*([0-9a-zA-Z_\-\.]*)/g;Q.parseImport=function(t){return t=t.replace(vr,function(t,e,r){var t=Q.source(r);return t?Q.parseImport(t):(console.error('Shader chunk "'+r+'" not existed in library'),"")})} -;var yr=/(@export)\s*([0-9a-zA-Z_\-\.]*)\s*\n([\s\S]*?)@end/g;Q.import=function(t){t.replace(yr,function(t,e,r,n){var n=n.replace(/(^[\s\t\xa0\u3000]+)|([\u3000\xa0\s\t]+\x24)/g,"");if(n){for(var i,a=r.split("."),o=Q.codes,s=0;s0&&this.setViewport(this._viewportStack.pop())},saveClear:function(){this._clearStack.push({clearBit:this.clearBit,clearColor:this.clearColor})},restoreClear:function(){if(this._clearStack.length>0){var t=this._clearStack.pop();this.clearColor=t.clearColor,this.clearBit=t.clearBit}},bindSceneRendering:function(t){this._sceneRendering=t},render:function(t,e,r,n){var i=this.gl,a=this.clearColor;if(this.clearBit){i.colorMask(!0,!0,!0,!0),i.depthMask(!0);var o=this.viewport,s=!1,u=o.devicePixelRatio;(o.width!==this._width||o.height!==this._height||u&&u!==this.devicePixelRatio||o.x||o.y)&&(s=!0,i.enable(i.SCISSOR_TEST),i.scissor(o.x*u,o.y*u,o.width*u,o.height*u)),i.clearColor(a[0],a[1],a[2],a[3]),i.clear(this.clearBit),s&&i.disable(i.SCISSOR_TEST)}if(r||t.update(!1),t.updateLights(),!(e=e||t.getMainCamera()))return void console.error("Can't find camera in the scene.");e.update();var l=t.updateRenderList(e,!0);this._sceneRendering=t;var c=l.opaque,h=l.transparent,f=t.material;t.trigger("beforerender",this,t,e,l),n?(this.renderPreZ(c,t,e),i.depthFunc(i.LEQUAL)):i.depthFunc(i.LESS);for(var d=Er(),p=we.create(),m=0;m0){var s=t[i-1],u=s.joints?s.joints.length:0;if((a.joints?a.joints.length:0)===u&&a.material===s.material&&a.lightGroup===s.lightGroup){a.__program=s.__program;continue}}var l=this._programMgr.getProgram(a,o,e);this.validateProgram(l),a.__program=l}},renderPass:function(t,e,r){this.trigger("beforerenderpass",this,t,e,r),r=r||{},r.getMaterial=r.getMaterial||$,r.getUniform=r.getUniform||tt,r.isMaterialChanged=r.isMaterialChanged||et,r.beforeRender=r.beforeRender||nt,r.afterRender=r.afterRender||nt;var n=r.ifRender||rt;this.updatePrograms(t,this._sceneRendering,r),r.sortCompare&&t.sort(r.sortCompare);var i=this.viewport,a=i.devicePixelRatio,o=[i.x*a,i.y*a,i.width*a,i.height*a],s=this.devicePixelRatio,u=this.__currentFrameBuffer?[this.__currentFrameBuffer.getTextureWidth(),this.__currentFrameBuffer.getTextureHeight()]:[this._width*s,this._height*s],l=[o[2],o[3]],c=Date.now();e?(xr.copy(Mr.VIEW,e.viewMatrix.array),xr.copy(Mr.PROJECTION,e.projectionMatrix.array),xr.copy(Mr.VIEWINVERSE,e.worldTransform.array)):(xr.identity(Mr.VIEW),xr.identity(Mr.PROJECTION),xr.identity(Mr.VIEWINVERSE)),xr.multiply(Mr.VIEWPROJECTION,Mr.PROJECTION,Mr.VIEW),xr.invert(Mr.PROJECTIONINVERSE,Mr.PROJECTION),xr.invert(Mr.VIEWPROJECTIONINVERSE,Mr.VIEWPROJECTION);for(var h,f,d,p,m,_,g,v,y,T,x,E,A=this.gl,b=this._sceneRendering,S=this.getGLExtension("OES_vertex_array_object"),M=0;Mthis._glinfo.getMaxJointNumber()){var a=i.getSubSkinMatricesTexture(t.__uid__,t.joints);e.useTextureSlot(this,a,r),e.setUniform(n,"1i","skinMatricesTexture",r),e.setUniform(n,"1f","skinMatricesTextureSize",a.width)}else{var o=i.getSubSkinMatrices(t.__uid__,t.joints);e.setUniformOfSemantic(n,"SKIN_MATRIX",o)}},_renderObject:function(t,e){var r=this.gl,n=t.geometry,i=t.mode;if(null==i&&(i=4),e.indicesBuffer){var a=this.getGLExtension("OES_element_index_uint"),o=a&&n.indices instanceof Uint32Array,s=o?r.UNSIGNED_INT:r.UNSIGNED_SHORT;r.drawElements(i,e.indicesBuffer.count,s,0)}else r.drawArrays(i,0,n.vertexCount)},_bindMaterial:function(t,e,r,n,i,a,o){for(var s=this.gl,u=a===r,l=r.currentTextureSlot(),c=e.getEnabledUniforms(),h=e.getTextureUniforms(),f=this._placeholderTexture,d=0;d0){var e=this.min,r=this.max,n=e.array,i=r.array;Hr(n,t[0]),Hr(i,t[0]);for(var a=1;ai[0]&&(i[0]=o[0]),o[1]>i[1]&&(i[1]=o[1]),o[2]>i[2]&&(i[2]=o[2])}e._dirty=!0,r._dirty=!0}},union:function(t){var e=this.min,r=this.max;return we.min(e.array,e.array,t.min.array),we.max(r.array,r.array,t.max.array),e._dirty=!0,r._dirty=!0,this},intersection:function(t){var e=this.min,r=this.max;return we.max(e.array,e.array,t.min.array),we.min(r.array,r.array,t.max.array),e._dirty=!0,r._dirty=!0,this},intersectBoundingBox:function(t){var e=this.min.array,r=this.max.array,n=t.min.array,i=t.max.array;return!(e[0]>i[0]||e[1]>i[1]||e[2]>i[2]||r[0]=i[0]&&r[1]>=i[1]&&r[2]>=i[2]},containPoint:function(t){var e=this.min.array,r=this.max.array,n=t.array;return e[0]<=n[0]&&e[1]<=n[1]&&e[2]<=n[2]&&r[0]>=n[0]&&r[1]>=n[1]&&r[2]>=n[2]},isFinite:function(){var t=this.min.array,e=this.max.array;return isFinite(t[0])&&isFinite(t[1])&&isFinite(t[2])&&isFinite(e[0])&&isFinite(e[1])&&isFinite(e[2])},applyTransform:function(t){this.transformFrom(this,t)},transformFrom:function(){var t=we.create(),e=we.create(),r=we.create(),n=we.create(),i=we.create(),a=we.create();return function(o,s){var u=o.min.array,l=o.max.array,c=s.array;return t[0]=c[0]*u[0],t[1]=c[1]*u[0],t[2]=c[2]*u[0],e[0]=c[0]*l[0],e[1]=c[1]*l[0],e[2]=c[2]*l[0],r[0]=c[4]*u[1],r[1]=c[5]*u[1],r[2]=c[6]*u[1],n[0]=c[4]*l[1],n[1]=c[5]*l[1],n[2]=c[6]*l[1],i[0]=c[8]*u[2],i[1]=c[9]*u[2],i[2]=c[10]*u[2],a[0]=c[8]*l[2],a[1]=c[9]*l[2],a[2]=c[10]*l[2],u=this.min.array,l=this.max.array,u[0]=Math.min(t[0],e[0])+Math.min(r[0],n[0])+Math.min(i[0],a[0])+c[12],u[1]=Math.min(t[1],e[1])+Math.min(r[1],n[1])+Math.min(i[1],a[1])+c[13],u[2]=Math.min(t[2],e[2])+Math.min(r[2],n[2])+Math.min(i[2],a[2])+c[14],l[0]=Math.max(t[0],e[0])+Math.max(r[0],n[0])+Math.max(i[0],a[0])+c[12],l[1]=Math.max(t[1],e[1])+Math.max(r[1],n[1])+Math.max(i[1],a[1])+c[13],l[2]=Math.max(t[2],e[2])+Math.max(r[2],n[2])+Math.max(i[2],a[2])+c[14],this.min._dirty=!0,this.max._dirty=!0,this}}(),applyProjection:function(t){var e=this.min.array,r=this.max.array,n=t.array,i=e[0],a=e[1],o=e[2],s=r[0],u=r[1],l=e[2],c=r[0],h=r[1],f=r[2];if(1===n[15])e[0]=n[0]*i+n[12],e[1]=n[5]*a+n[13],r[2]=n[10]*o+n[14],r[0]=n[0]*c+n[12],r[1]=n[5]*h+n[13],e[2]=n[10]*f+n[14];else{var d=-1/o;e[0]=n[0]*i*d,e[1]=n[5]*a*d,r[2]=(n[10]*o+n[14])*d,d=-1/l,r[0]=n[0]*s*d,r[1]=n[5]*u*d,d=-1/f,e[2]=(n[10]*f+n[14])*d}return this.min._dirty=!0,this.max._dirty=!0,this},updateVertices:function(){var t=this.vertices;if(!t){t=[];for(var e=0;e<8;e++)t[e]=we.fromValues(0,0,0);this.vertices=t}var r=this.min.array,n=this.max.array;return kr(t[0],r[0],r[1],r[2]),kr(t[1],r[0],n[1],r[2]),kr(t[2],n[0],r[1],r[2]),kr(t[3],n[0],n[1],r[2]),kr(t[4],r[0],r[1],n[2]),kr(t[5],r[0],n[1],n[2]),kr(t[6],n[0],r[1],n[2]),kr(t[7],n[0],n[1],n[2]),this},copy:function(t){var e=this.min,r=this.max;return Hr(e.array,t.min.array),Hr(r.array,t.max.array),e._dirty=!0,r._dirty=!0,this},clone:function(){var t=new Gr;return t.copy(this),t}};var Vr=0,Wr=Fe.extend({name:"",position:null,rotation:null,scale:null,worldTransform:null,localTransform:null,autoUpdateLocalTransform:!0,_parent:null,_scene:null,_needsUpdateWorldTransform:!0,_inIterating:!1,__depth:0},function(){this.name||(this.name=(this.type||"NODE")+"_"+Vr++),this.position||(this.position=new wr),this.rotation||(this.rotation=new Ir),this.scale||(this.scale=new wr(1,1,1)),this.worldTransform=new Br,this.localTransform=new Br,this._children=[]},{target:null,invisible:!1,isSkinnedMesh:function(){return!1},isRenderable:function(){return!1},setName:function(t){var e=this._scene;if(e){var r=e._nodeRepository;delete r[this.name],r[t]=this}this.name=t},add:function(t){var e=t._parent;if(e!==this){e&&e.remove(t),t._parent=this,this._children.push(t);var r=this._scene;r&&r!==t.scene&&t.traverse(this._addSelfToScene,this),t._needsUpdateWorldTransform=!0}},remove:function(t){var e=this._children,r=e.indexOf(t);r<0||(e.splice(r,1),t._parent=null,this._scene&&t.traverse(this._removeSelfFromScene,this))},removeAll:function(){for(var t=this._children,e=0;ethis.distance,i=1;i<8;i++)if(we.dot(e[i].array,r)>this.distance!=n)return!0},intersectLine:function(){var t=we.create();return function(e,r,n){var i=this.distanceToPoint(e),a=this.distanceToPoint(r);if(i>0&&a>0||i<0&&a<0)return null;var o=this.normal.array,s=this.distance,u=e.array;we.sub(t,r.array,e.array),we.normalize(t,t);var l=we.dot(o,t);if(0===l)return null;n||(n=new wr);var c=(we.dot(o,u)-s)/l;return we.scaleAndAdd(n.array,u,t,-c),n._dirty=!0,n}}(),applyTransform:function(){var t=xr.create(),e=Ce.create(),r=Ce.create();return r[3]=1,function(n){n=n.array,we.scale(r,this.normal.array,this.distance),Ce.transformMat4(r,r,n),this.distance=we.dot(r,this.normal.array),xr.invert(t,n),xr.transpose(t,t),e[3]=0,we.copy(e,this.normal.array),Ce.transformMat4(e,e,t),we.copy(this.normal.array,e)}}(),copy:function(t){we.copy(this.normal.array,t.normal.array),this.normal._dirty=!0,this.distance=t.distance},clone:function(){var t=new qr;return t.copy(this),t}};var Yr=we.set,Kr=we.copy,Zr=we.transformMat4,Jr=Math.min,Qr=Math.max,$r=function(){this.planes=[];for(var t=0;t<6;t++)this.planes.push(new qr);this.boundingBox=new Gr,this.vertices=[];for(var t=0;t<8;t++)this.vertices[t]=we.fromValues(0,0,0)};$r.prototype={setFromProjection:function(t){var e=this.planes,r=t.array,n=r[0],i=r[1],a=r[2],o=r[3],s=r[4],u=r[5],l=r[6],c=r[7],h=r[8],f=r[9],d=r[10],p=r[11],m=r[12],_=r[13],g=r[14],v=r[15];Yr(e[0].normal.array,o-n,c-s,p-h),e[0].distance=-(v-m),e[0].normalize(),Yr(e[1].normal.array,o+n,c+s,p+h),e[1].distance=-(v+m),e[1].normalize(),Yr(e[2].normal.array,o+i,c+u,p+f),e[2].distance=-(v+_),e[2].normalize(),Yr(e[3].normal.array,o-i,c-u,p-f),e[3].distance=-(v-_),e[3].normalize(),Yr(e[4].normal.array,o-a,c-l,p-d),e[4].distance=-(v-g),e[4].normalize(),Yr(e[5].normal.array,o+a,c+l,p+d),e[5].distance=-(v+g),e[5].normalize();var y=this.boundingBox,T=this.vertices;if(0===v){var x=u/n,E=-g/(d-1),A=-g/(d+1),b=-A/u,S=-E/u;y.min.set(-b*x,-b,A),y.max.set(b*x,b,E),Yr(T[0],-b*x,-b,A),Yr(T[1],-b*x,b,A),Yr(T[2],b*x,-b,A),Yr(T[3],b*x,b,A),Yr(T[4],-S*x,-S,E),Yr(T[5],-S*x,S,E),Yr(T[6],S*x,-S,E),Yr(T[7],S*x,S,E)}else{var M=(-1-m)/n,w=(1-m)/n,C=(1-_)/u,R=(-1-_)/u,L=(-1-g)/d,N=(1-g)/d;y.min.set(Math.min(M,w),Math.min(R,C),Math.min(N,L)),y.max.set(Math.max(w,M),Math.max(C,R),Math.max(L,N));var P=y.min.array,I=y.max.array;Yr(T[0],P[0],P[1],P[2]),Yr(T[1],P[0],I[1],P[2]),Yr(T[2],I[0],P[1],P[2]),Yr(T[3],I[0],I[1],P[2]),Yr(T[4],P[0],P[1],I[2]),Yr(T[5],P[0],I[1],I[2]),Yr(T[6],I[0],P[1],I[2]),Yr(T[7],I[0],I[1],I[2])}},getTransformedBoundingBox:function(){var t=we.create();return function(e,r){var n=this.vertices,i=r.array,a=e.min,o=e.max,s=a.array,u=o.array,l=n[0];Zr(t,l,i),Kr(s,t),Kr(u,t);for(var c=1;c<8;c++)l=n[c],Zr(t,l,i),s[0]=Jr(t[0],s[0]),s[1]=Jr(t[1],s[1]),s[2]=Jr(t[2],s[2]),u[0]=Qr(t[0],u[0]),u[1]=Qr(t[1],u[1]),u[2]=Qr(t[2],u[2]);return a._dirty=!0,o._dirty=!0,e}}()};var tn=function(t,e){this.origin=t||new wr,this.direction=e||new wr};tn.prototype={constructor:tn,intersectPlane:function(t,e){var r=t.normal.array,n=t.distance,i=this.origin.array,a=this.direction.array,o=we.dot(r,a);if(0===o)return null;e||(e=new wr);var s=(we.dot(r,i)-n)/o;return we.scaleAndAdd(e.array,i,a,-s),e._dirty=!0,e},mirrorAgainstPlane:function(t){var e=we.dot(t.normal.array,this.direction.array);we.scaleAndAdd(this.direction.array,this.direction.array,t.normal.array,2*-e),this.direction._dirty=!0},distanceToPoint:function(){var t=we.create();return function(e){we.sub(t,e,this.origin.array);var r=we.dot(t,this.direction.array);if(r<0)return we.distance(this.origin.array,e);var n=we.lenSquared(t);return Math.sqrt(n-r*r)}}(),intersectSphere:function(){var t=we.create();return function(e,r,n){var i=this.origin.array,a=this.direction.array;e=e.array,we.sub(t,e,i);var o=we.dot(t,a),s=we.squaredLength(t),u=s-o*o,l=r*r;if(!(u>l)){var c=Math.sqrt(l-u),h=o-c,f=o+c;return n||(n=new wr),h<0?f<0?null:(we.scaleAndAdd(n.array,i,a,f),n):(we.scaleAndAdd(n.array,i,a,h),n)}}}(),intersectBoundingBox:function(t,e){var r,n,i,a,o,s,u=this.direction.array,l=this.origin.array,c=t.min.array,h=t.max.array,f=1/u[0],d=1/u[1],p=1/u[2];if(f>=0?(r=(c[0]-l[0])*f,n=(h[0]-l[0])*f):(n=(c[0]-l[0])*f,r=(h[0]-l[0])*f),d>=0?(i=(c[1]-l[1])*d,a=(h[1]-l[1])*d):(a=(c[1]-l[1])*d,i=(h[1]-l[1])*d),r>a||i>n)return null;if((i>r||r!==r)&&(r=i),(a=0?(o=(c[2]-l[2])*p,s=(h[2]-l[2])*p):(s=(c[2]-l[2])*p,o=(h[2]-l[2])*p),r>s||o>n)return null;if((o>r||r!==r)&&(r=o),(s=0?r:n;return e||(e=new wr),we.scaleAndAdd(e.array,l,u,m),e},intersectTriangle:function(){var t=we.create(),e=we.create(),r=we.create(),n=we.create();return function(i,a,o,s,u,l){var c=this.direction.array,h=this.origin.array;i=i.array,a=a.array,o=o.array,we.sub(t,a,i),we.sub(e,o,i),we.cross(n,e,c);var f=we.dot(t,n);if(s){if(f>-1e-5)return null}else if(f>-1e-5&&f<1e-5)return null;we.sub(r,h,i);var d=we.dot(n,r)/f;if(d<0||d>1)return null;we.cross(n,t,r);var p=we.dot(c,n)/f;if(p<0||p>1||d+p>1)return null;we.cross(n,t,e);var m=-we.dot(r,n)/f;return m<0?null:(u||(u=new wr),l&&wr.set(l,1-d-p,d,p),we.scaleAndAdd(u.array,h,c,m),u)}}(),applyTransform:function(t){wr.add(this.direction,this.direction,this.origin),wr.transformMat4(this.origin,this.origin,t),wr.transformMat4(this.direction,this.direction,t),wr.sub(this.direction,this.direction,this.origin),wr.normalize(this.direction,this.direction)},copy:function(t){wr.copy(this.origin,t.origin),wr.copy(this.direction,t.direction)},clone:function(){var t=new tn;return t.copy(this),t}};var en=Wr.extend(function(){return{projectionMatrix:new Br,invProjectionMatrix:new Br,viewMatrix:new Br,frustum:new $r}},function(){this.update(!0)},{update:function(t){Wr.prototype.update.call(this,t),Br.invert(this.viewMatrix,this.worldTransform),this.updateProjectionMatrix(),Br.invert(this.invProjectionMatrix,this.projectionMatrix),this.frustum.setFromProjection(this.projectionMatrix)},setViewMatrix:function(t){Br.copy(this.viewMatrix,t),Br.invert(this.worldTransform,t),this.decomposeWorldTransform()},decomposeProjectionMatrix:function(){},setProjectionMatrix:function(t){Br.copy(this.projectionMatrix,t),Br.invert(this.invProjectionMatrix,t),this.decomposeProjectionMatrix()},updateProjectionMatrix:function(){},castRay:function(){var t=Ce.create();return function(e,r){var n=void 0!==r?r:new tn,i=e.array[0],a=e.array[1];return Ce.set(t,i,a,-1,1),Ce.transformMat4(t,t,this.invProjectionMatrix.array),Ce.transformMat4(t,t,this.worldTransform.array),we.scale(n.origin.array,t,1/t[3]),Ce.set(t,i,a,1,1),Ce.transformMat4(t,t,this.invProjectionMatrix.array),Ce.transformMat4(t,t,this.worldTransform.array),we.scale(t,t,1/t[3]),we.sub(n.direction.array,t,n.origin.array),we.normalize(n.direction.array,n.direction.array),n.direction._dirty=!0,n.origin._dirty=!0,n}}()}),rn=xr.create(),nn=xr.create(),an={};ut.prototype.startCount=function(){this._opaqueCount=0,this._transparentCount=0},ut.prototype.add=function(t,e){e?this.transparent[this._transparentCount++]=t:this.opaque[this._opaqueCount++]=t},ut.prototype.endCount=function(){this.transparent.length=this._transparentCount,this.opaque.length=this._opaqueCount};var on=Wr.extend(function(){return{material:null,lights:[],viewBoundingBoxLastFrame:new Gr,shadowUniforms:{},_cameraList:[],_lightUniforms:{},_previousLightNumber:{},_lightNumber:{},_lightProgramKeys:{},_nodeRepository:{},_renderLists:new Ke(20)}},function(){this._scene=this},{addToScene:function(t){t instanceof en?(this._cameraList.length>0&&console.warn("Found multiple camera in one scene. Use the fist one."),this._cameraList.push(t)):t instanceof jr&&this.lights.push(t),t.name&&(this._nodeRepository[t.name]=t)},removeFromScene:function(t){var e;t instanceof en?(e=this._cameraList.indexOf(t))>=0&&this._cameraList.splice(e,1):t instanceof jr&&(e=this.lights.indexOf(t))>=0&&this.lights.splice(e,1),t.name&&delete this._nodeRepository[t.name]},getNode:function(t){return this._nodeRepository[t]},setMainCamera:function(t){var e=this._cameraList.indexOf(t);e>=0&&this._cameraList.splice(e,1),this._cameraList.unshift(t)},getMainCamera:function(){return this._cameraList[0]},getLights:function(){return this.lights},updateLights:function(){var t=this.lights;this._previousLightNumber=this._lightNumber;for(var e={},r=0;r0&&this._doUpdateRenderList(o,e,r,n,i)}},isFrustumCulled:function(){var t=new Gr,e=new Br;return function(r,n,i){var a=r.boundingBox;if(a||(a=r.skeleton&&r.skeleton.boundingBox?r.skeleton.boundingBox:r.geometry.boundingBox),!a)return!1;if(e.array=i,t.transformFrom(a,e),r.castShadow&&this.viewBoundingBoxLastFrame.union(t),r.frustumCulling){if(!t.intersectBoundingBox(n.frustum.boundingBox))return!0;e.array=n.projectionMatrix.array,t.max.array[2]>0&&t.min.array[2]<0&&(t.max.array[2]=-1e-20),t.applyProjection(e);var o=t.min.array,s=t.max.array;if(s[0]<-1||o[0]>1||s[1]<-1||o[1]>1||s[2]<-1||o[2]>1)return!0}return!1}}(),_updateLightUniforms:function(){var t=this.lights;t.sort(lt);var e=this._lightUniforms;for(var r in e)for(var n in e[r])e[r][n].value.length=0;for(var i=0;i=0){e||(e=[]);var r=this.indices;return e[0]=r[3*t],e[1]=r[3*t+1],e[2]=r[3*t+2],e}},setTriangleIndices:function(t,e){var r=this.indices;r[3*t]=e[0],r[3*t+1]=e[1],r[3*t+2]=e[2]},isUseIndices:function(){return!!this.indices},initIndicesFromArray:function(t){var e,r=this.vertexCount>65535?Ge.Uint32Array:Ge.Uint16Array;if(t[0]&&t[0].length){var n=0;e=new r(3*t.length);for(var i=0;i=0&&(e.splice(r,1),delete this.attributes[t],!0)},getAttribute:function(t){return this.attributes[t]},getEnabledAttributes:function(){var t=this._enabledAttributes,e=this._attributeList;if(t)return t;for(var r=[],n=this.vertexCount,i=0;ia[0]&&(a[0]=s),u>a[1]&&(a[1]=u),l>a[2]&&(a[2]=l)}r._dirty=!0,n._dirty=!0}},generateVertexNormals:function(){if(this.vertexCount){var t=this.indices,e=this.attributes,r=e.position.value,n=e.normal.value;if(n&&n.length===r.length)for(var i=0;i65535&&(this.indices=new Ge.Uint32Array(this.indices));for(var t=this.attributes,e=this.indices,r=this.getEnabledAttributes(),n={},i=0;i65535?Uint32Array:Uint16Array,p=this.indices=new d(e*t*6),m=this.radius,_=this.phiStart,g=this.phiLength,v=this.thetaStart,y=this.thetaLength,m=this.radius,T=[],x=[],E=0,A=1/m;for(f=0;f<=t;f++)for(h=0;h<=e;h++)l=h/e,c=f/t,o=-m*Math.cos(_+l*g)*Math.sin(v+c*y),s=m*Math.cos(v+c*y),u=m*Math.sin(_+l*g)*Math.sin(v+c*y),T[0]=o,T[1]=s,T[2]=u,x[0]=l,x[1]=c,r.set(E,T),n.set(E,x),T[0]*=A,T[1]*=A,T[2]*=A,i.set(E,T),E++;var b,S,M,w,C=e+1,R=0;for(f=0;f65535?Uint32Array:Uint16Array,g=(o-1)*(s-1)*6,v=this.indices=new _(g),y=0,f=0;f>e;return t+1},dispose:function(t){var e=this._cache;e.use(t.__uid__);var r=e.get("webgl_texture");r&&t.gl.deleteTexture(r),e.deleteContext(t.__uid__)},isRenderable:function(){},isPowerOfTwo:function(){}});Object.defineProperty(yn.prototype,"width",{get:function(){return this._width},set:function(t){this._width=t}}),Object.defineProperty(yn.prototype,"height",{get:function(){return this._height},set:function(t){this._height=t}}),yn.BYTE=qe.BYTE,yn.UNSIGNED_BYTE=qe.UNSIGNED_BYTE,yn.SHORT=qe.SHORT,yn.UNSIGNED_SHORT=qe.UNSIGNED_SHORT,yn.INT=qe.INT,yn.UNSIGNED_INT=qe.UNSIGNED_INT,yn.FLOAT=qe.FLOAT,yn.HALF_FLOAT=36193,yn.UNSIGNED_INT_24_8_WEBGL=34042,yn.DEPTH_COMPONENT=qe.DEPTH_COMPONENT,yn.DEPTH_STENCIL=qe.DEPTH_STENCIL,yn.ALPHA=qe.ALPHA,yn.RGB=qe.RGB,yn.RGBA=qe.RGBA,yn.LUMINANCE=qe.LUMINANCE,yn.LUMINANCE_ALPHA=qe.LUMINANCE_ALPHA,yn.SRGB=35904,yn.SRGB_ALPHA=35906,yn.COMPRESSED_RGB_S3TC_DXT1_EXT=33776,yn.COMPRESSED_RGBA_S3TC_DXT1_EXT=33777,yn.COMPRESSED_RGBA_S3TC_DXT3_EXT=33778,yn.COMPRESSED_RGBA_S3TC_DXT5_EXT=33779,yn.NEAREST=qe.NEAREST,yn.LINEAR=qe.LINEAR,yn.NEAREST_MIPMAP_NEAREST=qe.NEAREST_MIPMAP_NEAREST,yn.LINEAR_MIPMAP_NEAREST=qe.LINEAR_MIPMAP_NEAREST,yn.NEAREST_MIPMAP_LINEAR=qe.NEAREST_MIPMAP_LINEAR,yn.LINEAR_MIPMAP_LINEAR=qe.LINEAR_MIPMAP_LINEAR,yn.REPEAT=qe.REPEAT,yn.CLAMP_TO_EDGE=qe.CLAMP_TO_EDGE,yn.MIRRORED_REPEAT=qe.MIRRORED_REPEAT;var Tn={};Tn.isPowerOfTwo=function(t){return 0==(t&t-1)},Tn.nextPowerOfTwo=function(t){return t--,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},Tn.nearestPowerOfTwo=function(t){return Math.pow(2,Math.round(Math.log(t)/Math.LN2))};var xn=Tn.isPowerOfTwo,En=yn.extend(function(){return{image:null,pixels:null,mipmaps:[],convertToPOT:!1}},{textureType:"texture2D",update:function(t){var e=t.gl;e.bindTexture(e.TEXTURE_2D,this._cache.get("webgl_texture")),this.updateCommon(t);var r=this.format,n=this.type,i=!(!this.convertToPOT||this.mipmaps.length||!this.image||this.wrapS!==yn.REPEAT&&this.wrapT!==yn.REPEAT||!this.NPOT);e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,i?this.wrapS:this.getAvailableWrapS()),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,i?this.wrapT:this.getAvailableWrapT()),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,i?this.magFilter:this.getAvailableMagFilter()),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,i?this.minFilter:this.getAvailableMinFilter());var a=t.getGLExtension("EXT_texture_filter_anisotropic");if(a&&this.anisotropic>1&&e.texParameterf(e.TEXTURE_2D,a.TEXTURE_MAX_ANISOTROPY_EXT,this.anisotropic),36193===n){t.getGLExtension("OES_texture_half_float")||(n=qe.FLOAT)}if(this.mipmaps.length)for(var o=this.width,s=this.height,u=0;u=yn.COMPRESSED_RGB_S3TC_DXT1_EXT?t.compressedTexImage2D(t.TEXTURE_2D,r,a,n,i,0,e.pixels):t.texImage2D(t.TEXTURE_2D,r,a,n,i,0,a,o,e.pixels)},generateMipmap:function(t){var e=t.gl;this.useMipmap&&!this.NPOT&&(e.bindTexture(e.TEXTURE_2D,this._cache.get("webgl_texture")),e.generateMipmap(e.TEXTURE_2D))},isPowerOfTwo:function(){return xn(this.width)&&xn(this.height)},isRenderable:function(){return this.image?"CANVAS"===this.image.nodeName||"VIDEO"===this.image.nodeName||this.image.complete:!(!this.width||!this.height)},bind:function(t){t.gl.bindTexture(t.gl.TEXTURE_2D,this.getWebGLTexture(t))},unbind:function(t){t.gl.bindTexture(t.gl.TEXTURE_2D,null)},load:function(t,e){var r=Ge.createImage();e&&(r.crossOrigin=e);var n=this;return r.onload=function(){n.dirty(),n.trigger("success",n),r.onload=null},r.onerror=function(){n.trigger("error",n),r.onerror=null},r.src=t,this.image=r,this}});Object.defineProperty(En.prototype,"width",{get:function(){return this.image?this.image.width:this._width},set:function(t){this.image?console.warn("Texture from image can't set width"):(this._width!==t&&this.dirty(),this._width=t)}}),Object.defineProperty(En.prototype,"height",{get:function(){return this.image?this.image.height:this._height},set:function(t){this.image?console.warn("Texture from image can't set height"):(this._height!==t&&this.dirty(),this._height=t)}});var An=Tn.isPowerOfTwo,bn=["px","nx","py","ny","pz","nz"],Sn=yn.extend(function(){return{image:{px:null,nx:null,py:null,ny:null,pz:null,nz:null},pixels:{px:null,nx:null,py:null,ny:null,pz:null,nz:null},mipmaps:[]}},{textureType:"textureCube",update:function(t){var e=t.gl;e.bindTexture(e.TEXTURE_CUBE_MAP,this._cache.get("webgl_texture")),this.updateCommon(t);var r=this.format,n=this.type;e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_WRAP_S,this.getAvailableWrapS()),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_WRAP_T,this.getAvailableWrapT()),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_MAG_FILTER,this.getAvailableMagFilter()),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_MIN_FILTER,this.getAvailableMinFilter());var i=t.getGLExtension("EXT_texture_filter_anisotropic");if(i&&this.anisotropic>1&&e.texParameterf(e.TEXTURE_CUBE_MAP,i.TEXTURE_MAX_ANISOTROPY_EXT,this.anisotropic),36193===n){t.getGLExtension("OES_texture_half_float")||(n=qe.FLOAT)}if(this.mipmaps.length)for(var a=this.width,o=this.height,s=0;s0},beforeRender:function(t){},afterRender:function(t,e){},getBoundingBox:function(t,e){return e=Wr.prototype.getBoundingBox.call(this,t,e),this.geometry&&this.geometry.boundingBox&&e.union(this.geometry.boundingBox),e},clone:function(){var t=["castShadow","receiveShadow","mode","culling","cullFace","frontFace","frustumCulling","renderOrder","lineWidth","ignorePicking","ignorePreZ","ignoreGBuffer"];return function(){var e=Wr.prototype.clone.call(this);e.geometry=this.geometry,e.material=this.material;for(var r=0;r0)},clone:function(){var t=Mn.prototype.clone.call(this);return t.skeleton=this.skeleton,this.joints&&(t.joints=this.joints.slice()),t}});wn.POINTS=qe.POINTS,wn.LINES=qe.LINES,wn.LINE_LOOP=qe.LINE_LOOP,wn.LINE_STRIP=qe.LINE_STRIP,wn.TRIANGLES=qe.TRIANGLES,wn.TRIANGLE_STRIP=qe.TRIANGLE_STRIP,wn.TRIANGLE_FAN=qe.TRIANGLE_FAN,wn.BACK=qe.BACK,wn.FRONT=qe.FRONT,wn.FRONT_AND_BACK=qe.FRONT_AND_BACK,wn.CW=qe.CW,wn.CCW=qe.CCW;var Cn=en.extend({fov:50,aspect:1,near:.1,far:2e3},{updateProjectionMatrix:function(){var t=this.fov/180*Math.PI;this.projectionMatrix.perspective(t,this.aspect,this.near,this.far)},decomposeProjectionMatrix:function(){var t=this.projectionMatrix.array,e=2*Math.atan(1/t[5]);this.fov=e/Math.PI*180,this.aspect=t[5]/t[0],this.near=t[14]/(t[10]-1),this.far=t[14]/(t[10]+1)},clone:function(){var t=en.prototype.clone.call(this);return t.fov=this.fov,t.aspect=this.aspect,t.near=this.near,t.far=this.far,t}}),Rn=en.extend({left:-1,right:1,near:-1,far:1,top:1,bottom:-1},{updateProjectionMatrix:function(){this.projectionMatrix.ortho(this.left,this.right,this.bottom,this.top,this.near,this.far)},decomposeProjectionMatrix:function(){var t=this.projectionMatrix.array;this.left=(-1-t[12])/t[0],this.right=(1-t[12])/t[0],this.top=(1-t[13])/t[5],this.bottom=(-1-t[13])/t[5],this.near=-(-1-t[14])/t[10],this.far=-(1-t[14])/t[10]},clone:function(){var t=en.prototype.clone.call(this);return t.left=this.left,t.right=this.right,t.near=this.near,t.far=this.far,t.top=this.top,t.bottom=this.bottom,t} -}),Ln="\n@export clay.standard.chunk.varying\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nvarying vec3 v_Barycentric;\n#if defined(PARALLAXOCCLUSIONMAP_ENABLED) || defined(NORMALMAP_ENABLED)\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\n#endif\n#if defined(AOMAP_ENABLED)\nvarying vec2 v_Texcoord2;\n#endif\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n@end\n@export clay.standard.chunk.light_header\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n#ifdef AMBIENT_CUBEMAP_LIGHT_COUNT\n@import clay.header.ambient_cubemap_light\n#endif\n#ifdef POINT_LIGHT_COUNT\n@import clay.header.point_light\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n#ifdef SPOT_LIGHT_COUNT\n@import clay.header.spot_light\n#endif\n@end\n@export clay.standard.vertex\n#define SHADER_NAME standard\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\n#if defined(AOMAP_ENABLED)\nattribute vec2 texcoord2 : TEXCOORD_1;\n#endif\nattribute vec3 normal : NORMAL;\nattribute vec4 tangent : TANGENT;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\n#endif\nattribute vec3 barycentric;\n@import clay.standard.chunk.varying\n@import clay.chunk.skinning_header\nvoid main()\n{\n vec3 skinnedPosition = position;\n vec3 skinnedNormal = normal;\n vec3 skinnedTangent = tangent.xyz;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n skinnedNormal = (skinMatrixWS * vec4(normal, 0.0)).xyz;\n skinnedTangent = (skinMatrixWS * vec4(tangent.xyz, 0.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0);\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n v_WorldPosition = (world * vec4(skinnedPosition, 1.0)).xyz;\n v_Barycentric = barycentric;\n v_Normal = normalize((worldInverseTranspose * vec4(skinnedNormal, 0.0)).xyz);\n#if defined(PARALLAXOCCLUSIONMAP_ENABLED) || defined(NORMALMAP_ENABLED)\n v_Tangent = normalize((worldInverseTranspose * vec4(skinnedTangent, 0.0)).xyz);\n v_Bitangent = normalize(cross(v_Normal, v_Tangent) * tangent.w);\n#endif\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n#if defined(AOMAP_ENABLED)\n v_Texcoord2 = texcoord2;\n#endif\n}\n@end\n@export clay.standard.fragment\n#define PI 3.14159265358979\n#define GLOSSINESS_CHANNEL 0\n#define ROUGHNESS_CHANNEL 0\n#define METALNESS_CHANNEL 1\n#define DIFFUSEMAP_ALPHA_ALPHA\n@import clay.standard.chunk.varying\nuniform mat4 viewInverse : VIEWINVERSE;\n#ifdef NORMALMAP_ENABLED\nuniform sampler2D normalMap;\n#endif\nuniform float normalScale: 1.0;\n#ifdef DIFFUSEMAP_ENABLED\nuniform sampler2D diffuseMap;\n#endif\n#ifdef SPECULARMAP_ENABLED\nuniform sampler2D specularMap;\n#endif\n#ifdef USE_ROUGHNESS\nuniform float roughness : 0.5;\n #ifdef ROUGHNESSMAP_ENABLED\nuniform sampler2D roughnessMap;\n #endif\n#else\nuniform float glossiness: 0.5;\n #ifdef GLOSSINESSMAP_ENABLED\nuniform sampler2D glossinessMap;\n #endif\n#endif\n#ifdef METALNESSMAP_ENABLED\nuniform sampler2D metalnessMap;\n#endif\n#ifdef OCCLUSIONMAP_ENABLED\nuniform sampler2D occlusionMap;\n#endif\n#ifdef ENVIRONMENTMAP_ENABLED\nuniform samplerCube environmentMap;\n #ifdef PARALLAX_CORRECTED\nuniform vec3 environmentBoxMin;\nuniform vec3 environmentBoxMax;\n #endif\n#endif\n#ifdef BRDFLOOKUP_ENABLED\nuniform sampler2D brdfLookup;\n#endif\n#ifdef EMISSIVEMAP_ENABLED\nuniform sampler2D emissiveMap;\n#endif\n#ifdef SSAOMAP_ENABLED\nuniform sampler2D ssaoMap;\nuniform vec4 viewport : VIEWPORT;\n#endif\n#ifdef AOMAP_ENABLED\nuniform sampler2D aoMap;\nuniform float aoIntensity;\n#endif\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform float alpha : 1.0;\n#ifdef ALPHA_TEST\nuniform float alphaCutoff: 0.9;\n#endif\n#ifdef USE_METALNESS\nuniform float metalness : 0.0;\n#else\nuniform vec3 specularColor : [0.1, 0.1, 0.1];\n#endif\nuniform vec3 emission : [0.0, 0.0, 0.0];\nuniform float emissionIntensity: 1;\nuniform float lineWidth : 0.0;\nuniform vec4 lineColor : [0.0, 0.0, 0.0, 0.6];\n#ifdef ENVIRONMENTMAP_PREFILTER\nuniform float maxMipmapLevel: 5;\n#endif\n@import clay.standard.chunk.light_header\n@import clay.util.calculate_attenuation\n@import clay.util.edge_factor\n@import clay.util.rgbm\n@import clay.util.srgb\n@import clay.plugin.compute_shadow_map\n@import clay.util.parallax_correct\n@import clay.util.ACES\nfloat G_Smith(float g, float ndv, float ndl)\n{\n float roughness = 1.0 - g;\n float k = roughness * roughness / 2.0;\n float G1V = ndv / (ndv * (1.0 - k) + k);\n float G1L = ndl / (ndl * (1.0 - k) + k);\n return G1L * G1V;\n}\nvec3 F_Schlick(float ndv, vec3 spec) {\n return spec + (1.0 - spec) * pow(1.0 - ndv, 5.0);\n}\nfloat D_Phong(float g, float ndh) {\n float a = pow(8192.0, g);\n return (a + 2.0) / 8.0 * pow(ndh, a);\n}\nfloat D_GGX(float g, float ndh) {\n float r = 1.0 - g;\n float a = r * r;\n float tmp = ndh * ndh * (a - 1.0) + 1.0;\n return a / (PI * tmp * tmp);\n}\n#ifdef PARALLAXOCCLUSIONMAP_ENABLED\nuniform float parallaxOcclusionScale : 0.02;\nuniform float parallaxMaxLayers : 20;\nuniform float parallaxMinLayers : 5;\nuniform sampler2D parallaxOcclusionMap;\nmat3 transpose(in mat3 inMat)\n{\n vec3 i0 = inMat[0];\n vec3 i1 = inMat[1];\n vec3 i2 = inMat[2];\n return mat3(\n vec3(i0.x, i1.x, i2.x),\n vec3(i0.y, i1.y, i2.y),\n vec3(i0.z, i1.z, i2.z)\n );\n}\nvec2 parallaxUv(vec2 uv, vec3 viewDir)\n{\n float numLayers = mix(parallaxMaxLayers, parallaxMinLayers, abs(dot(vec3(0.0, 0.0, 1.0), viewDir)));\n float layerHeight = 1.0 / numLayers;\n float curLayerHeight = 0.0;\n vec2 deltaUv = viewDir.xy * parallaxOcclusionScale / (viewDir.z * numLayers);\n vec2 curUv = uv;\n float height = 1.0 - texture2D(parallaxOcclusionMap, curUv).r;\n for (int i = 0; i < 30; i++) {\n curLayerHeight += layerHeight;\n curUv -= deltaUv;\n height = 1.0 - texture2D(parallaxOcclusionMap, curUv).r;\n if (height < curLayerHeight) {\n break;\n }\n }\n vec2 prevUv = curUv + deltaUv;\n float next = height - curLayerHeight;\n float prev = 1.0 - texture2D(parallaxOcclusionMap, prevUv).r - curLayerHeight + layerHeight;\n return mix(curUv, prevUv, next / (next - prev));\n}\n#endif\nvoid main() {\n vec4 albedoColor = vec4(color, alpha);\n#ifdef VERTEX_COLOR\n albedoColor *= v_Color;\n#endif\n#ifdef SRGB_DECODE\n albedoColor = sRGBToLinear(albedoColor);\n#endif\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(eyePos - v_WorldPosition);\n vec2 uv = v_Texcoord;\n#if defined(PARALLAXOCCLUSIONMAP_ENABLED) || defined(NORMALMAP_ENABLED)\n mat3 tbn = mat3(v_Tangent, v_Bitangent, v_Normal);\n#endif\n#ifdef PARALLAXOCCLUSIONMAP_ENABLED\n uv = parallaxUv(v_Texcoord, normalize(transpose(tbn) * -V));\n#endif\n#ifdef DIFFUSEMAP_ENABLED\n vec4 texel = texture2D(diffuseMap, uv);\n #ifdef SRGB_DECODE\n texel = sRGBToLinear(texel);\n #endif\n albedoColor.rgb *= texel.rgb;\n #ifdef DIFFUSEMAP_ALPHA_ALPHA\n albedoColor.a *= texel.a;\n #endif\n#endif\n#ifdef USE_METALNESS\n float m = metalness;\n #ifdef METALNESSMAP_ENABLED\n float m2 = texture2D(metalnessMap, uv)[METALNESS_CHANNEL];\n m = clamp(m2 + (m - 0.5) * 2.0, 0.0, 1.0);\n #endif\n vec3 baseColor = albedoColor.rgb;\n albedoColor.rgb = baseColor * (1.0 - m);\n vec3 spec = mix(vec3(0.04), baseColor, m);\n#else\n vec3 spec = specularColor;\n#endif\n#ifdef USE_ROUGHNESS\n float g = clamp(1.0 - roughness, 0.0, 1.0);\n #ifdef ROUGHNESSMAP_ENABLED\n float g2 = 1.0 - texture2D(roughnessMap, uv)[ROUGHNESS_CHANNEL];\n g = clamp(g2 + (g - 0.5) * 2.0, 0.0, 1.0);\n #endif\n#else\n float g = glossiness;\n #ifdef GLOSSINESSMAP_ENABLED\n float g2 = texture2D(glossinessMap, uv)[GLOSSINESS_CHANNEL];\n g = clamp(g2 + (g - 0.5) * 2.0, 0.0, 1.0);\n #endif\n#endif\n#ifdef SPECULARMAP_ENABLED\n spec *= sRGBToLinear(texture2D(specularMap, uv)).rgb;\n#endif\n vec3 N = v_Normal;\n#ifdef DOUBLE_SIDED\n if (dot(N, V) < 0.0) {\n N = -N;\n }\n#endif\n#ifdef NORMALMAP_ENABLED\n if (dot(v_Tangent, v_Tangent) > 0.0) {\n vec3 normalTexel = texture2D(normalMap, uv).xyz;\n if (dot(normalTexel, normalTexel) > 0.0) { N = (normalTexel * 2.0 - 1.0);\n N = normalize(N * vec3(normalScale, normalScale, 1.0));\n tbn[1] = -tbn[1];\n N = normalize(tbn * N);\n }\n }\n#endif\n vec3 diffuseTerm = vec3(0.0, 0.0, 0.0);\n vec3 specularTerm = vec3(0.0, 0.0, 0.0);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n vec3 fresnelTerm = F_Schlick(ndv, spec);\n#ifdef AMBIENT_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_LIGHT_COUNT; _idx_++)\n {{\n diffuseTerm += ambientLightColor[_idx_];\n }}\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseTerm += calcAmbientSHLight(_idx_, N) * ambientSHLightColor[_idx_];\n }}\n#endif\n#ifdef POINT_LIGHT_COUNT\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsPoint[POINT_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfPointLights(v_WorldPosition, shadowContribsPoint);\n }\n#endif\n for(int _idx_ = 0; _idx_ < POINT_LIGHT_COUNT; _idx_++)\n {{\n vec3 lightPosition = pointLightPosition[_idx_];\n vec3 lc = pointLightColor[_idx_];\n float range = pointLightRange[_idx_];\n vec3 L = lightPosition - v_WorldPosition;\n float dist = length(L);\n float attenuation = lightAttenuation(dist, range);\n L /= dist;\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n if(shadowEnabled)\n {\n shadowContrib = shadowContribsPoint[_idx_];\n }\n#endif\n vec3 li = lc * ndl * attenuation * shadowContrib;\n diffuseTerm += li;\n specularTerm += li * fresnelTerm * D_Phong(g, ndh);\n }}\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int _idx_ = 0; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++)\n {{\n vec3 L = -normalize(directionalLightDirection[_idx_]);\n vec3 lc = directionalLightColor[_idx_];\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if(shadowEnabled)\n {\n shadowContrib = shadowContribsDir[_idx_];\n }\n#endif\n vec3 li = lc * ndl * shadowContrib;\n diffuseTerm += li;\n specularTerm += li * fresnelTerm * D_Phong(g, ndh);\n }}\n#endif\n#ifdef SPOT_LIGHT_COUNT\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsSpot[SPOT_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfSpotLights(v_WorldPosition, shadowContribsSpot);\n }\n#endif\n for(int i = 0; i < SPOT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = spotLightPosition[i];\n vec3 spotLightDirection = -normalize(spotLightDirection[i]);\n vec3 lc = spotLightColor[i];\n float range = spotLightRange[i];\n float a = spotLightUmbraAngleCosine[i];\n float b = spotLightPenumbraAngleCosine[i];\n float falloffFactor = spotLightFalloffFactor[i];\n vec3 L = lightPosition - v_WorldPosition;\n float dist = length(L);\n float attenuation = lightAttenuation(dist, range);\n L /= dist;\n float c = dot(spotLightDirection, L);\n float falloff;\n falloff = clamp((c - a) /(b - a), 0.0, 1.0);\n falloff = pow(falloff, falloffFactor);\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n if (shadowEnabled)\n {\n shadowContrib = shadowContribsSpot[i];\n }\n#endif\n vec3 li = lc * attenuation * (1.0 - falloff) * shadowContrib * ndl;\n diffuseTerm += li;\n specularTerm += li * fresnelTerm * D_Phong(g, ndh);\n }\n#endif\n vec4 outColor = albedoColor;\n outColor.rgb *= max(diffuseTerm, vec3(0.0));\n outColor.rgb += max(specularTerm, vec3(0.0));\n#ifdef AMBIENT_CUBEMAP_LIGHT_COUNT\n vec3 L = reflect(-V, N);\n float rough2 = clamp(1.0 - g, 0.0, 1.0);\n float bias2 = rough2 * 5.0;\n vec2 brdfParam2 = texture2D(ambientCubemapLightBRDFLookup[0], vec2(rough2, ndv)).xy;\n vec3 envWeight2 = spec * brdfParam2.x + brdfParam2.y;\n vec3 envTexel2;\n for(int _idx_ = 0; _idx_ < AMBIENT_CUBEMAP_LIGHT_COUNT; _idx_++)\n {{\n #ifdef SUPPORT_TEXTURE_LOD\n envTexel2 = RGBMDecode(textureCubeLodEXT(ambientCubemapLightCubemap[_idx_], L, bias2), 8.12);\n #else\n envTexel2 = RGBMDecode(textureCube(ambientCubemapLightCubemap[_idx_], L), 8.12);\n #endif\n outColor.rgb += ambientCubemapLightColor[_idx_] * envTexel2 * envWeight2;\n }}\n#endif\n#ifdef ENVIRONMENTMAP_ENABLED\n vec3 envWeight = g * fresnelTerm;\n vec3 L = reflect(-V, N);\n #ifdef PARALLAX_CORRECTED\n L = parallaxCorrect(L, v_WorldPosition, environmentBoxMin, environmentBoxMax);\n#endif\n #ifdef ENVIRONMENTMAP_PREFILTER\n float rough = clamp(1.0 - g, 0.0, 1.0);\n float bias = rough * maxMipmapLevel;\n #ifdef SUPPORT_TEXTURE_LOD\n vec3 envTexel = decodeHDR(textureCubeLodEXT(environmentMap, L, bias)).rgb;\n #else\n vec3 envTexel = decodeHDR(textureCube(environmentMap, L)).rgb;\n #endif\n #ifdef BRDFLOOKUP_ENABLED\n vec2 brdfParam = texture2D(brdfLookup, vec2(rough, ndv)).xy;\n envWeight = spec * brdfParam.x + brdfParam.y;\n #endif\n #else\n vec3 envTexel = textureCube(environmentMap, L).xyz;\n #endif\n outColor.rgb += envTexel * envWeight;\n#endif\n float aoFactor = 1.0;\n#ifdef SSAOMAP_ENABLED\n aoFactor = min(texture2D(ssaoMap, (gl_FragCoord.xy - viewport.xy) / viewport.zw).r, aoFactor);\n#endif\n#ifdef AOMAP_ENABLED\n aoFactor = min(1.0 - clamp((1.0 - texture2D(aoMap, v_Texcoord2).r) * aoIntensity, 0.0, 1.0), aoFactor);\n#endif\n#ifdef OCCLUSIONMAP_ENABLED\n aoFactor = min(1.0 - clamp((1.0 - texture2D(occlusionMap, v_Texcoord).r), 0.0, 1.0), aoFactor);\n#endif\n outColor.rgb *= aoFactor;\n vec3 lEmission = emission;\n#ifdef EMISSIVEMAP_ENABLED\n lEmission *= texture2D(emissiveMap, uv).rgb;\n#endif\n outColor.rgb += lEmission * emissionIntensity;\n if(lineWidth > 0.)\n {\n outColor.rgb = mix(outColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (outColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n outColor.rgb = ACESToneMapping(outColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n outColor = linearTosRGB(outColor);\n#endif\n gl_FragColor = encodeHDR(outColor);\n}\n@end\n@export clay.standardMR.vertex\n@import clay.standard.vertex\n@end\n@export clay.standardMR.fragment\n#define USE_METALNESS\n#define USE_ROUGHNESS\n@import clay.standard.fragment\n@end";Q.import(Ln);var Nn,Pn=["diffuseMap","normalMap","roughnessMap","metalnessMap","emissiveMap","environmentMap","brdfLookup","ssaoMap","aoMap"],In=["color","emission","emissionIntensity","alpha","roughness","metalness","uvRepeat","uvOffset","aoIntensity","alphaCutoff","normalScale"],On=["linear","encodeRGBM","decodeRGBM","doubleSided","alphaTest","roughnessChannel","metalnessChannel","environmentMapPrefiltered"],Dn={roughnessChannel:"ROUGHNESS_CHANNEL",metalnessChannel:"METALNESS_CHANNEL"},Bn={linear:"SRGB_DECODE",encodeRGBM:"RGBM_ENCODE",decodeRGBM:"RGBM_DECODE",doubleSided:"DOUBLE_SIDED",alphaTest:"ALPHA_TEST",environmentMapPrefiltered:"ENVIRONMENTMAP_PREFILTER"},Un=rr.extend(function(){return Nn||(Nn=new Q(Q.source("clay.standardMR.vertex"),Q.source("clay.standardMR.fragment"))),{shader:Nn}},function(t){Ue.extend(this,t),Ue.defaults(this,{color:[1,1,1],emission:[0,0,0],emissionIntensity:0,roughness:.5,metalness:0,alpha:1,alphaTest:!1,alphaCutoff:.9,normalScale:1,doubleSided:!1,diffuseMap:null,normalMap:null,roughnessMap:null,metalnessMap:null,emissiveMap:null,environmentMap:null,environmentBox:null,brdfLookup:null,ssaoMap:null,aoMap:null,uvRepeat:[1,1],uvOffset:[0,0],aoIntensity:1,environmentMapPrefiltered:!1,linear:!1,encodeRGBM:!1,decodeRGBM:!1,roughnessChannel:0,metalnessChannel:1})},{clone:function(){var t=new Un({name:this.name});return Pn.forEach(function(e){this[e]&&(t[e]=this[e])},this),In.concat(On).forEach(function(e){t[e]=this[e]},this),t}});In.forEach(function(t){Object.defineProperty(Un.prototype,t,{get:function(){return this.get(t)},set:function(e){this.setUniform(t,e)}})}),Pn.forEach(function(t){Object.defineProperty(Un.prototype,t,{get:function(){return this.get(t)},set:function(e){this.setUniform(t,e)}})}),On.forEach(function(t){var e="_"+t;Object.defineProperty(Un.prototype,t,{get:function(){return this[e]},set:function(r){if(this[e]=r,t in Dn){var n=Dn[t];this.define("fragment",n,r)}else{var n=Bn[t];r?this.define("fragment",n):this.undefine("fragment",n)}}})}),Object.defineProperty(Un.prototype,"environmentBox",{get:function(){var t=this._environmentBox;return t&&(t.min.setArray(this.get("environmentBoxMin")),t.max.setArray(this.get("environmentBoxMax"))),t},set:function(t){this._environmentBox=t;var e=this.uniforms=this.uniforms||{};e.environmentBoxMin=e.environmentBoxMin||{value:null},e.environmentBoxMax=e.environmentBoxMax||{value:null},t&&(this.setUniform("environmentBoxMin",t.min.array),this.setUniform("environmentBoxMax",t.max.array)),t?this.define("fragment","PARALLAX_CORRECTED"):this.undefine("fragment","PARALLAX_CORRECTED")}});var Fn={};yt.prototype.get=function(t){var e=t;if(this._pool[e])return this._pool[e];var r=Fn[t];if(!r)return void console.error('Shader "'+t+'" is not in the library');var n=new Q(r.vertex,r.fragment);return this._pool[e]=n,n},yt.prototype.clear=function(){this._pool={}};var kn=new yt,Hn={createLibrary:function(){return new yt},get:function(){return kn.get.apply(kn,arguments)},template:Tt,clear:function(){return kn.clear()}},Gn=Fe.extend({name:"",index:-1,node:null}),Vn=new Gr,Wn=new Br,zn=Fe.extend(function(){return{relativeRootNode:null,name:"",joints:[],boundingBox:null,_clips:[],_invBindPoseMatricesArray:null,_jointMatricesSubArrays:[],_skinMatricesArray:null,_skinMatricesSubArrays:[],_subSkinMatricesArray:{}}},{addClip:function(t,e){for(var r=0;r0&&this._clips.splice(e,1)},removeClipsAll:function(){this._clips=[]},getClip:function(t){if(this._clips[t])return this._clips[t].clip},getClipNumber:function(){return this._clips.length},updateJointMatrices:function(){var t=xr.create();return function(){this._invBindPoseMatricesArray=new Float32Array(16*this.joints.length),this._skinMatricesArray=new Float32Array(16*this.joints.length);for(var e=0;e.01){var f=s[h];c=Math.max(c,f);var d=a[f].min.array,p=a[f].max.array;a[f].__updated=!0,d=we.min(d,d,u),p=we.max(p,p,u)}}this._jointsBoundingBoxes=a,this.boundingBox=new Gr,c256?64:i>64?32:i>16?16:8;var a=this._skinMatricesTexture=this._skinMatricesTexture||new En({type:yn.FLOAT,minFilter:yn.NEAREST,magFilter:yn.NEAREST,useMipmap:!1,flipY:!1});return a.width=r,a.height=r,a.pixels&&a.pixels.length===r*r*4||(a.pixels=new Float32Array(r*r*4)),a.pixels.set(n),a.dirty(),a},getSkinMatricesTexture:function(){return this._skinMatricesTexture},_setPose:function(){if(this._clips[0])for(var t=this._clips[0].clip,e=this._clips[0].maps,r=0;r 0.)\n {\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (gl_FragColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n gl_FragColor.rgb = ACESToneMapping(gl_FragColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n}\n@end"), -Q.import("\n@export clay.lambert.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 normal : NORMAL;\nattribute vec3 barycentric;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n@import clay.chunk.skinning_header\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nvarying vec3 v_Barycentric;\nvoid main()\n{\n vec3 skinnedPosition = position;\n vec3 skinnedNormal = normal;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n skinnedNormal = (skinMatrixWS * vec4(normal, 0.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4( skinnedPosition, 1.0 );\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n v_Normal = normalize( ( worldInverseTranspose * vec4(skinnedNormal, 0.0) ).xyz );\n v_WorldPosition = ( world * vec4( skinnedPosition, 1.0) ).xyz;\n v_Barycentric = barycentric;\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n}\n@end\n@export clay.lambert.fragment\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nuniform sampler2D diffuseMap;\nuniform sampler2D alphaMap;\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform vec3 emission : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\n#ifdef ALPHA_TEST\nuniform float alphaCutoff: 0.9;\n#endif\nuniform float lineWidth : 0.0;\nuniform vec4 lineColor : [0.0, 0.0, 0.0, 0.6];\nvarying vec3 v_Barycentric;\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n#ifdef POINT_LIGHT_COUNT\n@import clay.header.point_light\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n#ifdef SPOT_LIGHT_COUNT\n@import clay.header.spot_light\n#endif\n@import clay.util.calculate_attenuation\n@import clay.util.edge_factor\n@import clay.util.rgbm\n@import clay.plugin.compute_shadow_map\n@import clay.util.ACES\nvoid main()\n{\n gl_FragColor = vec4(color, alpha);\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(gl_FragColor);\n#endif\n#ifdef DIFFUSEMAP_ENABLED\n vec4 tex = texture2D( diffuseMap, v_Texcoord );\n#ifdef SRGB_DECODE\n tex.rgb = pow(tex.rgb, vec3(2.2));\n#endif\n gl_FragColor.rgb *= tex.rgb;\n#ifdef DIFFUSEMAP_ALPHA_ALPHA\n gl_FragColor.a *= tex.a;\n#endif\n#endif\n vec3 diffuseColor = vec3(0.0, 0.0, 0.0);\n#ifdef AMBIENT_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_LIGHT_COUNT; _idx_++)\n {\n diffuseColor += ambientLightColor[_idx_];\n }\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseColor += calcAmbientSHLight(_idx_, v_Normal) * ambientSHLightColor[_idx_];\n }}\n#endif\n#ifdef POINT_LIGHT_COUNT\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsPoint[POINT_LIGHT_COUNT];\n if( shadowEnabled )\n {\n computeShadowOfPointLights(v_WorldPosition, shadowContribsPoint);\n }\n#endif\n for(int i = 0; i < POINT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = pointLightPosition[i];\n vec3 lightColor = pointLightColor[i];\n float range = pointLightRange[i];\n vec3 lightDirection = lightPosition - v_WorldPosition;\n float dist = length(lightDirection);\n float attenuation = lightAttenuation(dist, range);\n lightDirection /= dist;\n float ndl = dot( v_Normal, lightDirection );\n float shadowContrib = 1.0;\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsPoint[i];\n }\n#endif\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0) * attenuation * shadowContrib;\n }\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++)\n {\n vec3 lightDirection = -directionalLightDirection[i];\n vec3 lightColor = directionalLightColor[i];\n float ndl = dot(v_Normal, normalize(lightDirection));\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsDir[i];\n }\n#endif\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0) * shadowContrib;\n }\n#endif\n#ifdef SPOT_LIGHT_COUNT\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsSpot[SPOT_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfSpotLights(v_WorldPosition, shadowContribsSpot);\n }\n#endif\n for(int i = 0; i < SPOT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = -spotLightPosition[i];\n vec3 spotLightDirection = -normalize( spotLightDirection[i] );\n vec3 lightColor = spotLightColor[i];\n float range = spotLightRange[i];\n float a = spotLightUmbraAngleCosine[i];\n float b = spotLightPenumbraAngleCosine[i];\n float falloffFactor = spotLightFalloffFactor[i];\n vec3 lightDirection = lightPosition - v_WorldPosition;\n float dist = length(lightDirection);\n float attenuation = lightAttenuation(dist, range);\n lightDirection /= dist;\n float c = dot(spotLightDirection, lightDirection);\n float falloff;\n falloff = clamp((c - a) /( b - a), 0.0, 1.0);\n falloff = pow(falloff, falloffFactor);\n float ndl = dot(v_Normal, lightDirection);\n ndl = clamp(ndl, 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsSpot[i];\n }\n#endif\n diffuseColor += lightColor * ndl * attenuation * (1.0-falloff) * shadowContrib;\n }\n#endif\n gl_FragColor.rgb *= diffuseColor;\n gl_FragColor.rgb += emission;\n if(lineWidth > 0.)\n {\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (gl_FragColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n gl_FragColor.rgb = ACESToneMapping(gl_FragColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n}\n@end"),Q.import(Ln),Q.import("@export clay.wireframe.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 world : WORLD;\nattribute vec3 position : POSITION;\nattribute vec3 barycentric;\n@import clay.chunk.skinning_header\nvarying vec3 v_Barycentric;\nvoid main()\n{\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0 );\n v_Barycentric = barycentric;\n}\n@end\n@export clay.wireframe.fragment\nuniform vec3 color : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\nuniform float lineWidth : 1.0;\nvarying vec3 v_Barycentric;\n@import clay.util.edge_factor\nvoid main()\n{\n gl_FragColor.rgb = color;\n gl_FragColor.a = (1.0-edgeFactor(lineWidth)) * alpha;\n}\n@end"),Q.import(jn),Q.import(Tr),Hn.template("clay.basic",Q.source("clay.basic.vertex"),Q.source("clay.basic.fragment")),Hn.template("clay.lambert",Q.source("clay.lambert.vertex"),Q.source("clay.lambert.fragment")),Hn.template("clay.wireframe",Q.source("clay.wireframe.vertex"),Q.source("clay.wireframe.fragment")),Hn.template("clay.skybox",Q.source("clay.skybox.vertex"),Q.source("clay.skybox.fragment")),Hn.template("clay.prez",Q.source("clay.prez.vertex"),Q.source("clay.prez.fragment")),Hn.template("clay.standard",Q.source("clay.standard.vertex"),Q.source("clay.standard.fragment")),Hn.template("clay.standardMR",Q.source("clay.standardMR.vertex"),Q.source("clay.standardMR.fragment"));var qn={NORMAL:"normal",POSITION:"position",TEXCOORD_0:"texcoord0",TEXCOORD_1:"texcoord1",WEIGHTS_0:"weight",JOINTS_0:"joint",COLOR_0:"color"},Yn={5120:Ge.Int8Array,5121:Ge.Uint8Array,5122:Ge.Int16Array,5123:Ge.Uint16Array,5125:Ge.Uint32Array,5126:Ge.Float32Array},Kn={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},Zn=Fe.extend({rootNode:null,rootPath:null,textureRootPath:null,bufferRootPath:null,shader:"clay.standard",useStandardMaterial:!1,includeCamera:!0,includeAnimation:!0,includeMesh:!0,includeTexture:!0,crossOrigin:"",textureFlipY:!1,textureConvertToPOT:!1,shaderLibrary:null},function(){this.shaderLibrary||(this.shaderLibrary=Hn.createLibrary())},{load:function(t){var e=this,r=t.endsWith(".glb");null==this.rootPath&&(this.rootPath=t.slice(0,t.lastIndexOf("/"))),Ge.request.get({url:t,onprogress:function(t,r,n){e.trigger("progress",t,r,n)},onerror:function(t){e.trigger("error",t)},responseType:r?"arraybuffer":"text",onload:function(t){r?e.parseBinary(t):("string"==typeof t&&(t=JSON.parse(t)),e.parse(t))}})},parseBinary:function(t){var e=new Uint32Array(t,0,4);if(1179937895!==e[0])return void this.trigger("error","Invalid glTF binary format: Invalid header");if(e[0]<2)return void this.trigger("error","Only glTF2.0 is supported.");for(var r,n=new DataView(t,12),i=[],a=0;a=r.COLOR_ATTACHMENT0&&a<=r.COLOR_ATTACHMENT0+8&&i.push(a);n.drawBuffersEXT(i)}}this.trigger("beforerender",this,t);var o=this.clearDepth?r.DEPTH_BUFFER_BIT:0;if(r.depthMask(!0),this.clearColor){o|=r.COLOR_BUFFER_BIT,r.colorMask(!0,!0,!0,!0);var s=this.clearColor;Array.isArray(s)&&r.clearColor(s[0],s[1],s[2],s[3])}r.clear(o),this.blendWithPrevious?(r.enable(r.BLEND),this.material.transparent=!0):(r.disable(r.BLEND),this.material.transparent=!1),this.renderQuad(t),this.trigger("afterrender",this,t),e&&this.unbind(t,e)},renderQuad:function(t){si.material=this.material,t.renderPass([si],ui)},dispose:function(t){}});Q.import(jn);var ci=wn.extend(function(){var t=new Q({vertex:Q.source("clay.skybox.vertex"),fragment:Q.source("clay.skybox.fragment")}),e=new rr({shader:t,depthMask:!1});return{scene:null,geometry:new _n,material:e,environmentMap:null,culling:!1}},function(){var t=this.scene;t&&this.attachScene(t),this.environmentMap&&this.setEnvironmentMap(this.environmentMap)},{attachScene:function(t){this.scene&&this.detachScene(),t.skybox=this,this.scene=t,t.on("beforerender",this._beforeRenderScene,this)},detachScene:function(){this.scene&&(this.scene.off("beforerender",this._beforeRenderScene),this.scene.skybox=null),this.scene=null},dispose:function(t){this.detachScene(),this.geometry.dispose(t)},setEnvironmentMap:function(t){"texture2D"===t.textureType?(this.material.define("EQUIRECTANGULAR"),t.minFilter=yn.LINEAR):this.material.undefine("EQUIRECTANGULAR"),this.material.set("environmentMap",t)},getEnvironmentMap:function(){return this.material.get("environmentMap")},_beforeRenderScene:function(t,e,r){this.renderSkybox(t,r)},renderSkybox:function(t,e){this.position.copy(e.getWorldPosition()),this.update(),t.gl.disable(t.gl.BLEND),this.material.get("lod")>0?this.material.define("fragment","LOD"):this.material.undefine("fragment","LOD"), -t.renderPass([this],e)}}),hi=["px","nx","py","ny","pz","nz"],fi=Fe.extend(function(){var t={position:new wr,far:1e3,near:.1,texture:null,shadowMapPass:null},e=t._cameras={px:new Cn({fov:90}),nx:new Cn({fov:90}),py:new Cn({fov:90}),ny:new Cn({fov:90}),pz:new Cn({fov:90}),nz:new Cn({fov:90})};return e.px.lookAt(wr.POSITIVE_X,wr.NEGATIVE_Y),e.nx.lookAt(wr.NEGATIVE_X,wr.NEGATIVE_Y),e.py.lookAt(wr.POSITIVE_Y,wr.POSITIVE_Z),e.ny.lookAt(wr.NEGATIVE_Y,wr.NEGATIVE_Z),e.pz.lookAt(wr.POSITIVE_Z,wr.NEGATIVE_Y),e.nz.lookAt(wr.NEGATIVE_Z,wr.NEGATIVE_Y),t._frameBuffer=new ai,t},{getCamera:function(t){return this._cameras[t]},render:function(t,e,r){var n=t.gl;r||e.update();for(var i=this.texture.width,a=2*Math.atan(i/(i-.5))/Math.PI*180,o=0;o<6;o++){var s=hi[o],u=this._cameras[s];if(wr.copy(u.position,this.position),u.far=this.far,u.near=this.near,u.fov=a,this.shadowMapPass){u.update();var l=e.getBoundingBox();l.applyTransform(u.viewMatrix),e.viewBoundingBoxLastFrame.copy(l),this.shadowMapPass.render(t,e,u,!0)}this._frameBuffer.attach(this.texture,n.COLOR_ATTACHMENT0,n.TEXTURE_CUBE_MAP_POSITIVE_X+o),this._frameBuffer.bind(t),t.render(e,u,!0),this._frameBuffer.unbind(t)}},dispose:function(t){this._frameBuffer.dispose(t)}}),di=Et("DXT1"),pi=Et("DXT3"),mi=Et("DXT5"),_i={parse:function(t,e){var r=new Int32Array(t,0,31);if(542327876!==r[0])return null;if(4&!r(20))return null;var n,i,a=r(21),o=r[4],s=r[3],u=512&r[28],l=131072&r[2];switch(a){case di:n=8,i=yn.COMPRESSED_RGB_S3TC_DXT1_EXT;break;case pi:n=16,i=yn.COMPRESSED_RGBA_S3TC_DXT3_EXT;break;case mi:n=16,i=yn.COMPRESSED_RGBA_S3TC_DXT5_EXT;break;default:return null}var c=r[1]+4,h=u?6:1,f=1;l&&(f=Math.max(1,r[7]));for(var d=[],p=0;p=i)){a+=2;for(var o="";a20)return console.warn("Given image is not a height map"),t}var f,d,p,m;u%(4*n)==0?(f=o.data[u],p=o.data[u+4]):u%(4*n)==4*(n-1)?(f=o.data[u-4],p=o.data[u]):(f=o.data[u-4],p=o.data[u+4]),u<4*n?(d=o.data[u],m=o.data[u+4*n]):u>n*(i-1)*4?(d=o.data[u-4*n],m=o.data[u]):(d=o.data[u-4*n],m=o.data[u+4*n]),s.data[u]=f-p+127,s.data[u+1]=d-m+127,s.data[u+2]=255,s.data[u+3]=255}return a.putImageData(s,0,0),r},isHeightImage:function(t,e,r){if(!t||!t.width||!t.height)return!1;var n=document.createElement("canvas"),i=n.getContext("2d"),a=e||32;r=r||20,n.width=n.height=a,i.drawImage(t,0,0,a,a);for(var o=i.getImageData(0,0,a,a),s=0;sr)return!1}return!0},_fetchTexture:function(t,e,r){Ge.request.get({url:t,responseType:"arraybuffer",onload:e,onerror:r})},createChessboard:function(t,e,r,n){t=t||512,e=e||64,r=r||"black",n=n||"white";var i=Math.ceil(t/e),a=document.createElement("canvas");a.width=t,a.height=t;var o=a.getContext("2d");o.fillStyle=n,o.fillRect(0,0,t,t),o.fillStyle=r;for(var s=0;s 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nvoid main() {\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(v_WorldPosition - eyePos);\n vec3 N = V;\n vec3 prefilteredColor = vec3(0.0);\n float totalWeight = 0.0;\n float fMaxSampleNumber = float(SAMPLE_NUMBER);\n for (int i = 0; i < SAMPLE_NUMBER; i++) {\n vec3 H = importanceSampleNormal(float(i) / fMaxSampleNumber, roughness, N);\n vec3 L = reflect(-V, H);\n float NoL = clamp(dot(N, L), 0.0, 1.0);\n if (NoL > 0.0) {\n prefilteredColor += decodeHDR(textureCube(environmentMap, L)).rgb * NoL;\n totalWeight += NoL;\n }\n }\n gl_FragColor = encodeHDR(vec4(prefilteredColor / totalWeight, 1.0));\n}\n"})});h.set("normalDistribution",n),r.encodeRGBM&&h.define("fragment","RGBM_ENCODE"),r.decodeRGBM&&h.define("fragment","RGBM_DECODE");var f,d=new on;if("texture2D"===e.textureType){var p=new Sn({width:a,height:o,type:s===yn.FLOAT?yn.HALF_FLOAT:s});xi.panoramaToCubeMap(t,e,p,{encodeRGBM:r.decodeRGBM}),e=p}f=new ci({scene:d,material:h}),f.material.set("environmentMap",e);var m=new fi({texture:u});r.encodeRGBM&&(s=u.type=yn.UNSIGNED_BYTE);for(var _=new En({width:a,height:o,type:s}),g=new ai({depthBuffer:!1}),v=Ge[s===yn.UNSIGNED_BYTE?"Uint8Array":"Float32Array"],y=0;y 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nfloat G_Smith(float roughness, float NoV, float NoL) {\n float k = roughness * roughness / 2.0;\n float G1V = NoV / (NoV * (1.0 - k) + k);\n float G1L = NoL / (NoL * (1.0 - k) + k);\n return G1L * G1V;\n}\nvoid main() {\n vec2 uv = gl_FragCoord.xy / viewportSize;\n float NoV = uv.x;\n float roughness = uv.y;\n vec3 V;\n V.x = sqrt(1.0 - NoV * NoV);\n V.y = 0.0;\n V.z = NoV;\n float A = 0.0;\n float B = 0.0;\n for (int i = 0; i < SAMPLE_NUMBER; i++) {\n vec3 H = importanceSampleNormal(float(i) / fSampleNumber, roughness, N);\n vec3 L = reflect(-V, H);\n float NoL = clamp(L.z, 0.0, 1.0);\n float NoH = clamp(H.z, 0.0, 1.0);\n float VoH = clamp(dot(V, H), 0.0, 1.0);\n if (NoL > 0.0) {\n float G = G_Smith(roughness, NoV, NoL);\n float G_Vis = G * VoH / (NoH * NoV);\n float Fc = pow(1.0 - VoH, 5.0);\n A += (1.0 - Fc) * G_Vis;\n B += Fc * G_Vis;\n }\n }\n gl_FragColor = vec4(vec2(A, B) / fSampleNumber, 0.0, 1.0);\n}\n"}),i=new En({width:512,height:256,type:yn.HALF_FLOAT,wrapS:yn.CLAMP_TO_EDGE,wrapT:yn.CLAMP_TO_EDGE,minFilter:yn.NEAREST,magFilter:yn.NEAREST,useMipmap:!1});return n.setUniform("normalDistribution",e),n.setUniform("viewportSize",[512,256]),n.attachOutput(i),n.render(t,r),r.dispose(t),i},Ei.generateNormalDistribution=function(t,e){for(var t=t||256,e=e||1024,r=new En({width:t,height:e,type:yn.FLOAT,minFilter:yn.NEAREST,magFilter:yn.NEAREST,wrapS:yn.CLAMP_TO_EDGE,wrapT:yn.CLAMP_TO_EDGE,useMipmap:!1}),n=new Float32Array(e*t*4),i=[],a=0;a>>16)>>>0;l=((1431655765&l)<<1|(2863311530&l)>>>1)>>>0,l=((858993459&l)<<2|(3435973836&l)>>>2)>>>0,l=((252645135&l)<<4|(4042322160&l)>>>4)>>>0,l=(((16711935&l)<<8|(4278255360&l)>>>8)>>>0)/4294967296;var c=Math.sqrt((1-l)/(1+(s*s-1)*l));i[u]=c}for(var u=0;u 0.0) {\n if (texture2D(alphaMap, v_Texcoord).a <= alphaCutoff) {\n discard;\n }\n }\n#ifdef USE_VSM\n depth = depth * 0.5 + 0.5;\n float moment1 = depth;\n float moment2 = depth * depth;\n float dx = dFdx(depth);\n float dy = dFdy(depth);\n moment2 += 0.25*(dx*dx+dy*dy);\n gl_FragColor = vec4(moment1, moment2, 0.0, 1.0);\n#else\n float dx = dFdx(depth);\n float dy = dFdy(depth);\n depth += sqrt(dx*dx + dy*dy) * slopeScale + bias;\n gl_FragColor = encodeFloat(depth * 0.5 + 0.5);\n#endif\n}\n@end\n@export clay.sm.debug_depth\nuniform sampler2D depthMap;\nvarying vec2 v_Texcoord;\n@import clay.util.decode_float\nvoid main() {\n vec4 tex = texture2D(depthMap, v_Texcoord);\n#ifdef USE_VSM\n gl_FragColor = vec4(tex.rgb, 1.0);\n#else\n float depth = decodeFloat(tex);\n gl_FragColor = vec4(depth, depth, depth, 1.0);\n#endif\n}\n@end\n@export clay.sm.distance.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 world : WORLD;\nattribute vec3 position : POSITION;\n@import clay.chunk.skinning_header\nvarying vec3 v_WorldPosition;\nvoid main (){\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition , 1.0);\n v_WorldPosition = (world * vec4(skinnedPosition, 1.0)).xyz;\n}\n@end\n@export clay.sm.distance.fragment\nuniform vec3 lightPosition;\nuniform float range : 100;\nvarying vec3 v_WorldPosition;\n@import clay.util.encode_float\nvoid main(){\n float dist = distance(lightPosition, v_WorldPosition);\n#ifdef USE_VSM\n gl_FragColor = vec4(dist, dist * dist, 0.0, 0.0);\n#else\n dist = dist / range;\n gl_FragColor = encodeFloat(dist);\n#endif\n}\n@end\n@export clay.plugin.shadow_map_common\n@import clay.util.decode_float\nfloat tapShadowMap(sampler2D map, vec2 uv, float z){\n vec4 tex = texture2D(map, uv);\n return step(z, decodeFloat(tex) * 2.0 - 1.0);\n}\nfloat pcf(sampler2D map, vec2 uv, float z, float textureSize, vec2 scale) {\n float shadowContrib = tapShadowMap(map, uv, z);\n vec2 offset = vec2(1.0 / textureSize) * scale;\n#ifdef PCF_KERNEL_SIZE\n for (int _idx_ = 0; _idx_ < PCF_KERNEL_SIZE; _idx_++) {{\n shadowContrib += tapShadowMap(map, uv + offset * pcfKernel[_idx_], z);\n }}\n return shadowContrib / float(PCF_KERNEL_SIZE + 1);\n#else\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, 0.0), z);\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(0.0, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, 0.0), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, -offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, -offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(0.0, -offset.y), z);\n return shadowContrib / 9.0;\n#endif\n}\nfloat pcf(sampler2D map, vec2 uv, float z, float textureSize) {\n return pcf(map, uv, z, textureSize, vec2(1.0));\n}\nfloat chebyshevUpperBound(vec2 moments, float z){\n float p = 0.0;\n z = z * 0.5 + 0.5;\n if (z <= moments.x) {\n p = 1.0;\n }\n float variance = moments.y - moments.x * moments.x;\n variance = max(variance, 0.0000001);\n float mD = moments.x - z;\n float pMax = variance / (variance + mD * mD);\n pMax = clamp((pMax-0.4)/(1.0-0.4), 0.0, 1.0);\n return max(p, pMax);\n}\nfloat computeShadowContrib(\n sampler2D map, mat4 lightVPM, vec3 position, float textureSize, vec2 scale, vec2 offset\n) {\n vec4 posInLightSpace = lightVPM * vec4(position, 1.0);\n posInLightSpace.xyz /= posInLightSpace.w;\n float z = posInLightSpace.z;\n if(all(greaterThan(posInLightSpace.xyz, vec3(-0.99, -0.99, -1.0))) &&\n all(lessThan(posInLightSpace.xyz, vec3(0.99, 0.99, 1.0)))){\n vec2 uv = (posInLightSpace.xy+1.0) / 2.0;\n #ifdef USE_VSM\n vec2 moments = texture2D(map, uv * scale + offset).xy;\n return chebyshevUpperBound(moments, z);\n #else\n return pcf(map, uv * scale + offset, z, textureSize, scale);\n #endif\n }\n return 1.0;\n}\nfloat computeShadowContrib(sampler2D map, mat4 lightVPM, vec3 position, float textureSize) {\n return computeShadowContrib(map, lightVPM, position, textureSize, vec2(1.0), vec2(0.0));\n}\nfloat computeShadowContribOmni(samplerCube map, vec3 direction, float range)\n{\n float dist = length(direction);\n vec4 shadowTex = textureCube(map, direction);\n#ifdef USE_VSM\n vec2 moments = shadowTex.xy;\n float variance = moments.y - moments.x * moments.x;\n float mD = moments.x - dist;\n float p = variance / (variance + mD * mD);\n if(moments.x + 0.001 < dist){\n return clamp(p, 0.0, 1.0);\n }else{\n return 1.0;\n }\n#else\n return step(dist, (decodeFloat(shadowTex) + 0.0002) * range);\n#endif\n}\n@end\n@export clay.plugin.compute_shadow_map\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT) || defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT) || defined(POINT_LIGHT_SHADOWMAP_COUNT)\n#ifdef SPOT_LIGHT_SHADOWMAP_COUNT\nuniform sampler2D spotLightShadowMaps[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform mat4 spotLightMatrices[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform float spotLightShadowMapSizes[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\n#ifdef DIRECTIONAL_LIGHT_SHADOWMAP_COUNT\n#if defined(SHADOW_CASCADE)\nuniform sampler2D directionalLightShadowMaps[1]:unconfigurable;\nuniform mat4 directionalLightMatrices[SHADOW_CASCADE]:unconfigurable;\nuniform float directionalLightShadowMapSizes[1]:unconfigurable;\nuniform float shadowCascadeClipsNear[SHADOW_CASCADE]:unconfigurable;\nuniform float shadowCascadeClipsFar[SHADOW_CASCADE]:unconfigurable;\n#else\nuniform sampler2D directionalLightShadowMaps[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform mat4 directionalLightMatrices[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform float directionalLightShadowMapSizes[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\n#endif\n#ifdef POINT_LIGHT_SHADOWMAP_COUNT\nuniform samplerCube pointLightShadowMaps[POINT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\nuniform bool shadowEnabled : true;\n#ifdef PCF_KERNEL_SIZE\nuniform vec2 pcfKernel[PCF_KERNEL_SIZE];\n#endif\n@import clay.plugin.shadow_map_common\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\nvoid computeShadowOfSpotLights(vec3 position, inout float shadowContribs[SPOT_LIGHT_COUNT] ) {\n float shadowContrib;\n for(int _idx_ = 0; _idx_ < SPOT_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n shadowContrib = computeShadowContrib(\n spotLightShadowMaps[_idx_], spotLightMatrices[_idx_], position,\n spotLightShadowMapSizes[_idx_]\n );\n shadowContribs[_idx_] = shadowContrib;\n }}\n for(int _idx_ = SPOT_LIGHT_SHADOWMAP_COUNT; _idx_ < SPOT_LIGHT_COUNT; _idx_++){{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n#ifdef SHADOW_CASCADE\nvoid computeShadowOfDirectionalLights(vec3 position, inout float shadowContribs[DIRECTIONAL_LIGHT_COUNT]){\n float depth = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far)\n / (gl_DepthRange.far - gl_DepthRange.near);\n float shadowContrib;\n shadowContribs[0] = 1.0;\n for (int _idx_ = 0; _idx_ < SHADOW_CASCADE; _idx_++) {{\n if (\n depth >= shadowCascadeClipsNear[_idx_] &&\n depth <= shadowCascadeClipsFar[_idx_]\n ) {\n shadowContrib = computeShadowContrib(\n directionalLightShadowMaps[0], directionalLightMatrices[_idx_], position,\n directionalLightShadowMapSizes[0],\n vec2(1.0 / float(SHADOW_CASCADE), 1.0),\n vec2(float(_idx_) / float(SHADOW_CASCADE), 0.0)\n );\n shadowContribs[0] = shadowContrib;\n }\n }}\n for(int _idx_ = DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#else\nvoid computeShadowOfDirectionalLights(vec3 position, inout float shadowContribs[DIRECTIONAL_LIGHT_COUNT]){\n float shadowContrib;\n for(int _idx_ = 0; _idx_ < DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n shadowContrib = computeShadowContrib(\n directionalLightShadowMaps[_idx_], directionalLightMatrices[_idx_], position,\n directionalLightShadowMapSizes[_idx_]\n );\n shadowContribs[_idx_] = shadowContrib;\n }}\n for(int _idx_ = DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#endif\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\nvoid computeShadowOfPointLights(vec3 position, inout float shadowContribs[POINT_LIGHT_COUNT] ){\n vec3 lightPosition;\n vec3 direction;\n for(int _idx_ = 0; _idx_ < POINT_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n lightPosition = pointLightPosition[_idx_];\n direction = position - lightPosition;\n shadowContribs[_idx_] = computeShadowContribOmni(pointLightShadowMaps[_idx_], direction, pointLightRange[_idx_]);\n }}\n for(int _idx_ = POINT_LIGHT_SHADOWMAP_COUNT; _idx_ < POINT_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#endif\n@end");var Li=Fe.extend(function(){return{softShadow:Li.PCF,shadowBlur:1,lightFrustumBias:"auto",kernelPCF:new Float32Array([1,0,1,1,-1,1,0,1,-1,0,-1,-1,1,-1,0,-1]),precision:"highp",_lastRenderNotCastShadow:!1,_frameBuffer:new ai,_textures:{},_shadowMapNumber:{POINT_LIGHT:0,DIRECTIONAL_LIGHT:0,SPOT_LIGHT:0},_depthMaterials:{},_distanceMaterials:{},_receivers:[],_lightsCastShadow:[],_lightCameras:{},_lightMaterials:{},_texturePool:new Mi}},function(){this._gaussianPassH=new li({fragment:Q.source("clay.compositor.gaussian_blur")}),this._gaussianPassV=new li({fragment:Q.source("clay.compositor.gaussian_blur")}),this._gaussianPassH.setUniform("blurSize",this.shadowBlur),this._gaussianPassH.setUniform("blurDir",0),this._gaussianPassV.setUniform("blurSize",this.shadowBlur),this._gaussianPassV.setUniform("blurDir",1),this._outputDepthPass=new li({fragment:Q.source("clay.sm.debug_depth")})},{render:function(t,e,r,n){r||(r=e.getMainCamera()),this.trigger("beforerender",this,t,e,r),this._renderShadowPass(t,e,r,n),this.trigger("afterrender",this,t,e,r)},renderDebug:function(t,e){t.saveClear();var r=t.viewport,n=0,i=e||r.width/4,a=i;this.softShadow===Li.VSM?this._outputDepthPass.material.define("fragment","USE_VSM"):this._outputDepthPass.material.undefine("fragment","USE_VSM");for(var o in this._textures){var s=this._textures[o];t.setViewport(n,0,i*s.width/s.height,a),this._outputDepthPass.setUniform("depthMap",s),this._outputDepthPass.render(t),n+=i*s.width/s.height}t.setViewport(r),t.restoreClear()},_updateReceivers:function(t,e){if(e.receiveShadow?(this._receivers.push(e),e.material.set("shadowEnabled",1),e.material.set("pcfKernel",this.kernelPCF)):e.material.set("shadowEnabled",0),this.softShadow===Li.VSM)e.material.define("fragment","USE_VSM"),e.material.undefine("fragment","PCF_KERNEL_SIZE");else{e.material.undefine("fragment","USE_VSM");var r=this.kernelPCF;r&&r.length?e.material.define("fragment","PCF_KERNEL_SIZE",r.length/2):e.material.undefine("fragment","PCF_KERNEL_SIZE")}},_update:function(t,e){var r=this;e.traverse(function(e){e.isRenderable()&&r._updateReceivers(t,e)});for(var n=0;n4){console.warn("Support at most 4 cascade");continue}m.shadowCascade>1&&(s=m),this.renderDirectionalLightShadow(t,e,r,m,f,h,c)}else"SPOT_LIGHT"===m.type?this.renderSpotLightShadow(t,e,m,l,u):"POINT_LIGHT"===m.type&&this.renderPointLightShadow(t,e,m,d);this._shadowMapNumber[m.type]++}for(var _ in this._shadowMapNumber)for(var g=this._shadowMapNumber[_],v=_+"_SHADOWMAP_COUNT",p=0;p0?T.define("fragment",v,g):T.isDefined("fragment",v)&&T.undefine("fragment",v))}for(var p=0;p0){var E=c.map(i);if(x.directionalLightShadowMaps={value:c,type:"tv"},x.directionalLightMatrices={value:h,type:"m4v"},x.directionalLightShadowMapSizes={value:E,type:"1fv"},s){var A=f.slice(),b=f.slice();A.pop(),b.shift(),A.reverse(),b.reverse(),h.reverse(),x.shadowCascadeClipsNear={value:A,type:"1fv"},x.shadowCascadeClipsFar={value:b,type:"1fv"}}}if(u.length>0){var S=u.map(i),x=e.shadowUniforms;x.spotLightShadowMaps={value:u,type:"tv"},x.spotLightMatrices={value:l,type:"m4v"},x.spotLightShadowMapSizes={value:S,type:"1fv"}}d.length>0&&(x.pointLightShadowMaps={value:d,type:"tv"})}},renderDirectionalLightShadow:function(){var t=new $r,e=new Br,r=new Gr,n=new Br,i=new Br,a=new Br,o=new Br;return function(s,u,l,c,h,f,d){var p=this._getDepthMaterial(c),m={getMaterial:function(t){return t.shadowDepthMaterial||p},isMaterialChanged:Pt,getUniform:Nt,ifRender:function(t){return t.castShadow},sortCompare:Sr.opaqueSortCompare};if(!u.viewBoundingBoxLastFrame.isFinite()){var _=u.getBoundingBox();u.viewBoundingBoxLastFrame.copy(_).applyTransform(l.viewMatrix)}var g=Math.min(-u.viewBoundingBoxLastFrame.min.z,l.far),v=Math.max(-u.viewBoundingBoxLastFrame.max.z,l.near),y=this._getDirectionalLightCamera(c,u,l),T=a.array;o.copy(y.projectionMatrix),xr.invert(i.array,y.worldTransform.array),xr.multiply(i.array,i.array,l.worldTransform.array),xr.multiply(T,o.array,i.array);for(var x=[],E=l instanceof Cn,A=(l.near+l.far)/(l.near-l.far),b=2*l.near*l.far/(l.near-l.far),S=0;S<=c.shadowCascade;S++){var M=v*Math.pow(g/v,S/c.shadowCascade),w=v+(g-v)*S/c.shadowCascade,C=M*c.cascadeSplitLogFactor+w*(1-c.cascadeSplitLogFactor);x.push(C),h.push(-(-C*A+b)/-C)}var R=this._getTexture(c,c.shadowCascade);d.push(R);var L=s.viewport,N=s.gl;this._frameBuffer.attach(R),this._frameBuffer.bind(s),N.clear(N.COLOR_BUFFER_BIT|N.DEPTH_BUFFER_BIT);for(var S=0;Sf?s>d?p[i>0?"px":"nx"]=!0:p[o>0?"pz":"nz"]=!0:f>d?p[a>0?"py":"ny"]=!0:p[o>0?"pz":"nz"]=!0}for(var r=0;r=0&&x[y]>1e-4&&(we.transformMat4(b,T,g[E[y]]),we.scaleAndAdd(A,A,b,x[y]));S.set(v,A)}}for(var v=0;v=0){var l="touchend"!==u?i.targetTouches[0]:i.changedTouches[0];"touchstart"===u?u="mousedown":"touchend"===u?u="mouseup":"touchmove"===u&&(u="mousemove"),a=l.clientX-s.left,o=l.clientY-s.top}else a=i.clientX-s.left,o=i.clientY-s.top;var c,h=t.pick(a,o);if("DOMMouseScroll"!==u&&"mousewheel"!==u||(c=i.wheelDelta?i.wheelDelta/120:-(i.detail||0)/3),h){if(h.target.silent)return;if("mousemove"===u){var f=h.target!==r;f&&r&&Ht(r,kt("mouseout",{target:r},a,o)),Ht(h.target,kt("mousemove",h,a,o)),f&&Ht(h.target,kt("mouseover",h,a,o))}else Ht(h.target,kt(u,h,a,o,c));r=h.target}else r&&(Ht(r,kt("mouseout",{target:r},a,o)),r=null)}})},this)},Dt.prototype._updateGraphicOptions=function(t,e,r){for(var n,i=!!t.tonemapping,a=!!t.linear,o=0;o0){var e=this.outputs[t];e.keepLastFrame?(this._prevOutputTextures[t]&&this._compositor.releaseTexture(this._prevOutputTextures[t]),this._prevOutputTextures[t]=this._outputTextures[t]):this._compositor.releaseTexture(this._outputTextures[t])}}}),Gi=Fe.extend(function(){return{nodes:[]}},{dirty:function(){this._dirty=!0},addNode:function(t){this.nodes.indexOf(t)>=0||(this.nodes.push(t),this._dirty=!0)},removeNode:function(t){"string"==typeof t&&(t=this.getNodeByName(t));var e=this.nodes.indexOf(t);e>=0&&(this.nodes.splice(e,1),this._dirty=!0)},getNodeByName:function(t){for(var e=0;e=e.COLOR_ATTACHMENT0&&u<=e.COLOR_ATTACHMENT0+8&&c.push(u);l.drawBuffersEXT(c)}t.saveClear(),t.clearBit=qe.DEPTH_BUFFER_BIT|qe.COLOR_BUFFER_BIT,r=t.render(this.scene,this.camera,!this.autoUpdateScene,this.preZ),t.restoreClear(),n.unbind(t)}else r=t.render(this.scene,this.camera,!this.autoUpdateScene,this.preZ);this.trigger("afterrender",r),this._rendering=!1,this._rendered=!0}}),zi=Hi.extend(function(){return{texture:null,outputs:{color:{}}}},function(){},{getOutput:function(t,e){return this.texture},beforeFrame:function(){},afterFrame:function(){}}),Xi=Hi.extend(function(){return{name:"",inputs:{},outputs:null,shader:"",inputLinks:{},outputLinks:{},pass:null,_prevOutputTextures:{},_outputTextures:{},_outputReferences:{},_rendering:!1,_rendered:!1,_compositor:null}},function(){var t=new li({fragment:this.shader});this.pass=t},{render:function(t,e){this.trigger("beforerender",t),this._rendering=!0;var r=t.gl;for(var n in this.inputLinks){var i=this.inputLinks[n],a=i.node.getOutput(t,i.pin);this.pass.setUniform(n,a)}if(this.outputs){this.pass.outputs={};var o={};for(var s in this.outputs){var u=this.updateParameter(s,t);isNaN(u.width)&&this.updateParameter(s,t);var l=this.outputs[s],c=this._compositor.allocateTexture(u);this._outputTextures[s]=c;var h=l.attachment||r.COLOR_ATTACHMENT0;"string"==typeof h&&(h=r[h]),o[h]=c}this._compositor.getFrameBuffer().bind(t);for(var h in o)this._compositor.getFrameBuffer().attach(o[h],h);this.pass.render(t),this._compositor.getFrameBuffer().updateMipmap(t)}else this.pass.outputs=null,this._compositor.getFrameBuffer().unbind(t),this.pass.render(t,e);for(var n in this.inputLinks){var i=this.inputLinks[n];i.node.removeReference(i.pin)}this._rendering=!1,this._rendered=!0,this.trigger("afterrender",t)},updateParameter:function(t,e){var r=this.outputs[t],n=r.parameters,i=r._parametersCopy;if(i||(i=r._parametersCopy={}),n)for(var a in n)"width"!==a&&"height"!==a&&(i[a]=n[a]);var o,s;return o=n.width instanceof Function?n.width.call(this,e):n.width,s=n.height instanceof Function?n.height.call(this,e):n.height,o=Math.ceil(o),s=Math.ceil(s),i.width===o&&i.height===s||this._outputTextures[t]&&this._outputTextures[t].dispose(e),i.width=o,i.height=s,i},setParameter:function(t,e){this.pass.setUniform(t,e)},getParameter:function(t){return this.pass.getUniform(t)},setParameters:function(t){for(var e in t)this.setParameter(e,t[e])},define:function(t,e){this.pass.material.define("fragment",t,e)},undefine:function(t){this.pass.material.undefine("fragment",t)},removeReference:function(t){if(0===--this._outputReferences[t]){this.outputs[t].keepLastFrame?(this._prevOutputTextures[t]&&this._compositor.releaseTexture(this._prevOutputTextures[t]),this._prevOutputTextures[t]=this._outputTextures[t]):this._compositor.releaseTexture(this._outputTextures[t])}},clear:function(){Hi.prototype.clear.call(this),this.pass.material.disableTexturesAll()} -}),ji="@export clay.compositor.coloradjust\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float brightness : 0.0;\nuniform float contrast : 1.0;\nuniform float exposure : 0.0;\nuniform float gamma : 1.0;\nuniform float saturation : 1.0;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = clamp(tex.rgb + vec3(brightness), 0.0, 1.0);\n color = clamp( (color-vec3(0.5))*contrast+vec3(0.5), 0.0, 1.0);\n color = clamp( color * pow(2.0, exposure), 0.0, 1.0);\n color = clamp( pow(color, vec3(gamma)), 0.0, 1.0);\n float luminance = dot( color, w );\n color = mix(vec3(luminance), color, saturation);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.brightness\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float brightness : 0.0;\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = tex.rgb + vec3(brightness);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.contrast\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float contrast : 1.0;\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = (tex.rgb-vec3(0.5))*contrast+vec3(0.5);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.exposure\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float exposure : 0.0;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = tex.rgb * pow(2.0, exposure);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.gamma\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float gamma : 1.0;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = pow(tex.rgb, vec3(gamma));\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.saturation\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float saturation : 1.0;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = tex.rgb;\n float luminance = dot(color, w);\n color = mix(vec3(luminance), color, saturation);\n gl_FragColor = vec4(color, tex.a);\n}\n@end",qi="@export clay.compositor.kernel.gaussian_9\nfloat gaussianKernel[9];\ngaussianKernel[0] = 0.07;\ngaussianKernel[1] = 0.09;\ngaussianKernel[2] = 0.12;\ngaussianKernel[3] = 0.14;\ngaussianKernel[4] = 0.16;\ngaussianKernel[5] = 0.14;\ngaussianKernel[6] = 0.12;\ngaussianKernel[7] = 0.09;\ngaussianKernel[8] = 0.07;\n@end\n@export clay.compositor.kernel.gaussian_13\nfloat gaussianKernel[13];\ngaussianKernel[0] = 0.02;\ngaussianKernel[1] = 0.03;\ngaussianKernel[2] = 0.06;\ngaussianKernel[3] = 0.08;\ngaussianKernel[4] = 0.11;\ngaussianKernel[5] = 0.13;\ngaussianKernel[6] = 0.14;\ngaussianKernel[7] = 0.13;\ngaussianKernel[8] = 0.11;\ngaussianKernel[9] = 0.08;\ngaussianKernel[10] = 0.06;\ngaussianKernel[11] = 0.03;\ngaussianKernel[12] = 0.02;\n@end\n@export clay.compositor.gaussian_blur\n#define SHADER_NAME gaussian_blur\nuniform sampler2D texture;varying vec2 v_Texcoord;\nuniform float blurSize : 2.0;\nuniform vec2 textureSize : [512.0, 512.0];\nuniform float blurDir : 0.0;\n@import clay.util.rgbm\n@import clay.util.clamp_sample\nvoid main (void)\n{\n @import clay.compositor.kernel.gaussian_9\n vec2 off = blurSize / textureSize;\n off *= vec2(1.0 - blurDir, blurDir);\n vec4 sum = vec4(0.0);\n float weightAll = 0.0;\n for (int i = 0; i < 9; i++) {\n float w = gaussianKernel[i];\n vec4 texel = decodeHDR(clampSample(texture, v_Texcoord + float(i - 4) * off));\n sum += texel * w;\n weightAll += w;\n }\n gl_FragColor = encodeHDR(sum / max(weightAll, 0.01));\n}\n@end\n",Yi="@export clay.compositor.hdr.log_lum\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = decodeHDR(texture2D(texture, v_Texcoord));\n float luminance = dot(tex.rgb, w);\n luminance = log(luminance + 0.001);\n gl_FragColor = encodeHDR(vec4(vec3(luminance), 1.0));\n}\n@end\n@export clay.compositor.hdr.lum_adaption\nvarying vec2 v_Texcoord;\nuniform sampler2D adaptedLum;\nuniform sampler2D currentLum;\nuniform float frameTime : 0.02;\n@import clay.util.rgbm\nvoid main()\n{\n float fAdaptedLum = decodeHDR(texture2D(adaptedLum, vec2(0.5, 0.5))).r;\n float fCurrentLum = exp(encodeHDR(texture2D(currentLum, vec2(0.5, 0.5))).r);\n fAdaptedLum += (fCurrentLum - fAdaptedLum) * (1.0 - pow(0.98, 30.0 * frameTime));\n gl_FragColor = encodeHDR(vec4(vec3(fAdaptedLum), 1.0));\n}\n@end\n@export clay.compositor.lum\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord );\n float luminance = dot(tex.rgb, w);\n gl_FragColor = vec4(vec3(luminance), 1.0);\n}\n@end",Ki="\n@export clay.compositor.lut\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform sampler2D lookup;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n float blueColor = tex.b * 63.0;\n vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.g);\n vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.g);\n vec4 newColor1 = texture2D(lookup, texPos1);\n vec4 newColor2 = texture2D(lookup, texPos2);\n vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n gl_FragColor = vec4(newColor.rgb, tex.w);\n}\n@end",Zi="@export clay.compositor.vignette\n#define OUTPUT_ALPHA\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float darkness: 1;\nuniform float offset: 1;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 texel = decodeHDR(texture2D(texture, v_Texcoord));\n gl_FragColor.rgb = texel.rgb;\n vec2 uv = (v_Texcoord - vec2(0.5)) * vec2(offset);\n gl_FragColor = encodeHDR(vec4(mix(texel.rgb, vec3(1.0 - darkness), dot(uv, uv)), texel.a));\n}\n@end",Ji="@export clay.compositor.output\n#define OUTPUT_ALPHA\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = decodeHDR(texture2D(texture, v_Texcoord));\n gl_FragColor.rgb = tex.rgb;\n#ifdef OUTPUT_ALPHA\n gl_FragColor.a = tex.a;\n#else\n gl_FragColor.a = 1.0;\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n#ifdef PREMULTIPLY_ALPHA\n gl_FragColor.rgb *= gl_FragColor.a;\n#endif\n}\n@end",Qi="@export clay.compositor.bright\nuniform sampler2D texture;\nuniform float threshold : 1;\nuniform float scale : 1.0;\nuniform vec2 textureSize: [512, 512];\nvarying vec2 v_Texcoord;\nconst vec3 lumWeight = vec3(0.2125, 0.7154, 0.0721);\n@import clay.util.rgbm\nvec4 median(vec4 a, vec4 b, vec4 c)\n{\n return a + b + c - min(min(a, b), c) - max(max(a, b), c);\n}\nvoid main()\n{\n vec4 texel = decodeHDR(texture2D(texture, v_Texcoord));\n#ifdef ANTI_FLICKER\n vec3 d = 1.0 / textureSize.xyx * vec3(1.0, 1.0, 0.0);\n vec4 s1 = decodeHDR(texture2D(texture, v_Texcoord - d.xz));\n vec4 s2 = decodeHDR(texture2D(texture, v_Texcoord + d.xz));\n vec4 s3 = decodeHDR(texture2D(texture, v_Texcoord - d.zy));\n vec4 s4 = decodeHDR(texture2D(texture, v_Texcoord + d.zy));\n texel = median(median(texel, s1, s2), s3, s4);\n#endif\n float lum = dot(texel.rgb , lumWeight);\n vec4 color;\n if (lum > threshold && texel.a > 0.0)\n {\n color = vec4(texel.rgb * scale, texel.a * scale);\n }\n else\n {\n color = vec4(0.0);\n }\n gl_FragColor = encodeHDR(color);\n}\n@end\n",$i="@export clay.compositor.downsample\nuniform sampler2D texture;\nuniform vec2 textureSize : [512, 512];\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nfloat brightness(vec3 c)\n{\n return max(max(c.r, c.g), c.b);\n}\n@import clay.util.clamp_sample\nvoid main()\n{\n vec4 d = vec4(-1.0, -1.0, 1.0, 1.0) / textureSize.xyxy;\n#ifdef ANTI_FLICKER\n vec3 s1 = decodeHDR(clampSample(texture, v_Texcoord + d.xy)).rgb;\n vec3 s2 = decodeHDR(clampSample(texture, v_Texcoord + d.zy)).rgb;\n vec3 s3 = decodeHDR(clampSample(texture, v_Texcoord + d.xw)).rgb;\n vec3 s4 = decodeHDR(clampSample(texture, v_Texcoord + d.zw)).rgb;\n float s1w = 1.0 / (brightness(s1) + 1.0);\n float s2w = 1.0 / (brightness(s2) + 1.0);\n float s3w = 1.0 / (brightness(s3) + 1.0);\n float s4w = 1.0 / (brightness(s4) + 1.0);\n float oneDivideSum = 1.0 / (s1w + s2w + s3w + s4w);\n vec4 color = vec4(\n (s1 * s1w + s2 * s2w + s3 * s3w + s4 * s4w) * oneDivideSum,\n 1.0\n );\n#else\n vec4 color = decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.xw));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.zw));\n color *= 0.25;\n#endif\n gl_FragColor = encodeHDR(color);\n}\n@end",ta="\n@export clay.compositor.upsample\n#define HIGH_QUALITY\nuniform sampler2D texture;\nuniform vec2 textureSize : [512, 512];\nuniform float sampleScale: 0.5;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\n@import clay.util.clamp_sample\nvoid main()\n{\n#ifdef HIGH_QUALITY\n vec4 d = vec4(1.0, 1.0, -1.0, 0.0) / textureSize.xyxy * sampleScale;\n vec4 s;\n s = decodeHDR(clampSample(texture, v_Texcoord - d.xy));\n s += decodeHDR(clampSample(texture, v_Texcoord - d.wy)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord - d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zw)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord )) * 4.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xw)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.wy)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n gl_FragColor = encodeHDR(s / 16.0);\n#else\n vec4 d = vec4(-1.0, -1.0, +1.0, +1.0) / textureSize.xyxy;\n vec4 s;\n s = decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xw));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zw));\n gl_FragColor = encodeHDR(s / 4.0);\n#endif\n}\n@end",ea="@export clay.compositor.hdr.composite\n#define TONEMAPPING\nuniform sampler2D texture;\n#ifdef BLOOM_ENABLED\nuniform sampler2D bloom;\n#endif\n#ifdef LENSFLARE_ENABLED\nuniform sampler2D lensflare;\nuniform sampler2D lensdirt;\n#endif\n#ifdef LUM_ENABLED\nuniform sampler2D lum;\n#endif\n#ifdef LUT_ENABLED\nuniform sampler2D lut;\n#endif\n#ifdef COLOR_CORRECTION\nuniform float brightness : 0.0;\nuniform float contrast : 1.0;\nuniform float saturation : 1.0;\n#endif\n#ifdef VIGNETTE\nuniform float vignetteDarkness: 1.0;\nuniform float vignetteOffset: 1.0;\n#endif\nuniform float exposure : 1.0;\nuniform float bloomIntensity : 0.25;\nuniform float lensflareIntensity : 1;\nvarying vec2 v_Texcoord;\n@import clay.util.srgb\nvec3 ACESToneMapping(vec3 color)\n{\n const float A = 2.51;\n const float B = 0.03;\n const float C = 2.43;\n const float D = 0.59;\n const float E = 0.14;\n return (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nfloat eyeAdaption(float fLum)\n{\n return mix(0.2, fLum, 0.5);\n}\n#ifdef LUT_ENABLED\nvec3 lutTransform(vec3 color) {\n float blueColor = color.b * 63.0;\n vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);\n vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);\n vec4 newColor1 = texture2D(lut, texPos1);\n vec4 newColor2 = texture2D(lut, texPos2);\n vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n return newColor.rgb;\n}\n#endif\n@import clay.util.rgbm\nvoid main()\n{\n vec4 texel = vec4(0.0);\n vec4 originalTexel = vec4(0.0);\n#ifdef TEXTURE_ENABLED\n texel = decodeHDR(texture2D(texture, v_Texcoord));\n originalTexel = texel;\n#endif\n#ifdef BLOOM_ENABLED\n vec4 bloomTexel = decodeHDR(texture2D(bloom, v_Texcoord));\n texel.rgb += bloomTexel.rgb * bloomIntensity;\n texel.a += bloomTexel.a * bloomIntensity;\n#endif\n#ifdef LENSFLARE_ENABLED\n texel += decodeHDR(texture2D(lensflare, v_Texcoord)) * texture2D(lensdirt, v_Texcoord) * lensflareIntensity;\n#endif\n texel.a = min(texel.a, 1.0);\n#ifdef LUM_ENABLED\n float fLum = texture2D(lum, vec2(0.5, 0.5)).r;\n float adaptedLumDest = 3.0 / (max(0.1, 1.0 + 10.0*eyeAdaption(fLum)));\n float exposureBias = adaptedLumDest * exposure;\n#else\n float exposureBias = exposure;\n#endif\n#ifdef TONEMAPPING\n texel.rgb *= exposureBias;\n texel.rgb = ACESToneMapping(texel.rgb);\n#endif\n texel = linearTosRGB(texel);\n#ifdef LUT_ENABLED\n texel.rgb = lutTransform(clamp(texel.rgb,vec3(0.0),vec3(1.0)));\n#endif\n#ifdef COLOR_CORRECTION\n texel.rgb = clamp(texel.rgb + vec3(brightness), 0.0, 1.0);\n texel.rgb = clamp((texel.rgb - vec3(0.5))*contrast+vec3(0.5), 0.0, 1.0);\n float lum = dot(texel.rgb, vec3(0.2125, 0.7154, 0.0721));\n texel.rgb = mix(vec3(lum), texel.rgb, saturation);\n#endif\n#ifdef VIGNETTE\n vec2 uv = (v_Texcoord - vec2(0.5)) * vec2(vignetteOffset);\n texel.rgb = mix(texel.rgb, vec3(1.0 - vignetteDarkness), dot(uv, uv));\n#endif\n gl_FragColor = encodeHDR(texel);\n#ifdef DEBUG\n #if DEBUG == 1\n gl_FragColor = encodeHDR(decodeHDR(texture2D(texture, v_Texcoord)));\n #elif DEBUG == 2\n gl_FragColor = encodeHDR(decodeHDR(texture2D(bloom, v_Texcoord)) * bloomIntensity);\n #elif DEBUG == 3\n gl_FragColor = encodeHDR(decodeHDR(texture2D(lensflare, v_Texcoord) * lensflareIntensity));\n #endif\n#endif\n if (originalTexel.a <= 0.01 && gl_FragColor.a > 1e-5) {\n gl_FragColor.a = dot(gl_FragColor.rgb, vec3(0.2125, 0.7154, 0.0721));\n }\n#ifdef PREMULTIPLY_ALPHA\n gl_FragColor.rgb *= gl_FragColor.a;\n#endif\n}\n@end",ra="@export clay.compositor.lensflare\n#define SAMPLE_NUMBER 8\nuniform sampler2D texture;\nuniform sampler2D lenscolor;\nuniform vec2 textureSize : [512, 512];\nuniform float dispersal : 0.3;\nuniform float haloWidth : 0.4;\nuniform float distortion : 1.0;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nvec4 textureDistorted(\n in vec2 texcoord,\n in vec2 direction,\n in vec3 distortion\n) {\n return vec4(\n decodeHDR(texture2D(texture, texcoord + direction * distortion.r)).r,\n decodeHDR(texture2D(texture, texcoord + direction * distortion.g)).g,\n decodeHDR(texture2D(texture, texcoord + direction * distortion.b)).b,\n 1.0\n );\n}\nvoid main()\n{\n vec2 texcoord = -v_Texcoord + vec2(1.0); vec2 textureOffset = 1.0 / textureSize;\n vec2 ghostVec = (vec2(0.5) - texcoord) * dispersal;\n vec2 haloVec = normalize(ghostVec) * haloWidth;\n vec3 distortion = vec3(-textureOffset.x * distortion, 0.0, textureOffset.x * distortion);\n vec4 result = vec4(0.0);\n for (int i = 0; i < SAMPLE_NUMBER; i++)\n {\n vec2 offset = fract(texcoord + ghostVec * float(i));\n float weight = length(vec2(0.5) - offset) / length(vec2(0.5));\n weight = pow(1.0 - weight, 10.0);\n result += textureDistorted(offset, normalize(ghostVec), distortion) * weight;\n }\n result *= texture2D(lenscolor, vec2(length(vec2(0.5) - texcoord)) / length(vec2(0.5)));\n float weight = length(vec2(0.5) - fract(texcoord + haloVec)) / length(vec2(0.5));\n weight = pow(1.0 - weight, 10.0);\n vec2 offset = fract(texcoord + haloVec);\n result += textureDistorted(offset, normalize(ghostVec), distortion) * weight;\n gl_FragColor = result;\n}\n@end",na="@export clay.compositor.blend\n#define SHADER_NAME blend\n#ifdef TEXTURE1_ENABLED\nuniform sampler2D texture1;\nuniform float weight1 : 1.0;\n#endif\n#ifdef TEXTURE2_ENABLED\nuniform sampler2D texture2;\nuniform float weight2 : 1.0;\n#endif\n#ifdef TEXTURE3_ENABLED\nuniform sampler2D texture3;\nuniform float weight3 : 1.0;\n#endif\n#ifdef TEXTURE4_ENABLED\nuniform sampler2D texture4;\nuniform float weight4 : 1.0;\n#endif\n#ifdef TEXTURE5_ENABLED\nuniform sampler2D texture5;\nuniform float weight5 : 1.0;\n#endif\n#ifdef TEXTURE6_ENABLED\nuniform sampler2D texture6;\nuniform float weight6 : 1.0;\n#endif\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = vec4(0.0);\n#ifdef TEXTURE1_ENABLED\n tex += decodeHDR(texture2D(texture1, v_Texcoord)) * weight1;\n#endif\n#ifdef TEXTURE2_ENABLED\n tex += decodeHDR(texture2D(texture2, v_Texcoord)) * weight2;\n#endif\n#ifdef TEXTURE3_ENABLED\n tex += decodeHDR(texture2D(texture3, v_Texcoord)) * weight3;\n#endif\n#ifdef TEXTURE4_ENABLED\n tex += decodeHDR(texture2D(texture4, v_Texcoord)) * weight4;\n#endif\n#ifdef TEXTURE5_ENABLED\n tex += decodeHDR(texture2D(texture5, v_Texcoord)) * weight5;\n#endif\n#ifdef TEXTURE6_ENABLED\n tex += decodeHDR(texture2D(texture6, v_Texcoord)) * weight6;\n#endif\n gl_FragColor = encodeHDR(tex);\n}\n@end",ia="@export clay.compositor.fxaa\nuniform sampler2D texture;\nuniform vec4 viewport : VIEWPORT;\nvarying vec2 v_Texcoord;\n#define FXAA_REDUCE_MIN (1.0/128.0)\n#define FXAA_REDUCE_MUL (1.0/8.0)\n#define FXAA_SPAN_MAX 8.0\n@import clay.util.rgbm\nvoid main()\n{\n vec2 resolution = 1.0 / viewport.zw;\n vec3 rgbNW = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ) ).xyz;\n vec3 rgbNE = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ) ).xyz;\n vec3 rgbSW = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ) ).xyz;\n vec3 rgbSE = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ) ).xyz;\n vec4 rgbaM = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution ) );\n vec3 rgbM = rgbaM.xyz;\n float opacity = rgbaM.w;\n vec3 luma = vec3( 0.299, 0.587, 0.114 );\n float lumaNW = dot( rgbNW, luma );\n float lumaNE = dot( rgbNE, luma );\n float lumaSW = dot( rgbSW, luma );\n float lumaSE = dot( rgbSE, luma );\n float lumaM = dot( rgbM, luma );\n float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );\n float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );\n vec2 dir;\n dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\n dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\n float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );\n float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );\n dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),\n max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\n dir * rcpDirMin)) * resolution;\n vec3 rgbA = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * ( 1.0 / 3.0 - 0.5 ) ) ).xyz;\n rgbA += decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * ( 2.0 / 3.0 - 0.5 ) ) ).xyz;\n rgbA *= 0.5;\n vec3 rgbB = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * -0.5 ) ).xyz;\n rgbB += decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * 0.5 ) ).xyz;\n rgbB *= 0.25;\n rgbB += rgbA * 0.5;\n float lumaB = dot( rgbB, luma );\n if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) )\n {\n gl_FragColor = vec4( rgbA, opacity );\n }\n else {\n gl_FragColor = vec4( rgbB, opacity );\n }\n}\n@end";qt(Q);var aa=/^#source\((.*?)\)/;Q.import("@export clay.deferred.gbuffer.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\n#if defined(SECOND_PASS) || defined(FIRST_PASS)\nattribute vec2 texcoord : TEXCOORD_0;\nuniform vec2 uvRepeat;\nuniform vec2 uvOffset;\nvarying vec2 v_Texcoord;\n#endif\n#ifdef FIRST_PASS\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\nvarying vec3 v_Normal;\nattribute vec3 normal : NORMAL;\nattribute vec4 tangent : TANGENT;\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\nvarying vec3 v_WorldPosition;\n#endif\n@import clay.chunk.skinning_header\n#ifdef THIRD_PASS\nuniform mat4 prevWorldViewProjection;\nvarying vec4 v_ViewPosition;\nvarying vec4 v_PrevViewPosition;\n#ifdef SKINNING\n#ifdef USE_SKIN_MATRICES_TEXTURE\nuniform sampler2D prevSkinMatricesTexture;\nmat4 getPrevSkinMatrix(float idx) {\n return getSkinMatrix(prevSkinMatricesTexture, idx);\n}\n#else\nuniform mat4 prevSkinMatrix[JOINT_COUNT];\nmat4 getPrevSkinMatrix(float idx) {\n return prevSkinMatrix[int(idx)];\n}\n#endif\n#endif\n#endif\nvoid main()\n{\n vec3 skinnedPosition = position;\n vec3 prevSkinnedPosition = position;\n#ifdef FIRST_PASS\n vec3 skinnedNormal = normal;\n vec3 skinnedTangent = tangent.xyz;\n bool hasTangent = dot(tangent, tangent) > 0.0;\n#endif\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n #ifdef FIRST_PASS\n skinnedNormal = (skinMatrixWS * vec4(normal, 0.0)).xyz;\n if (hasTangent) {\n skinnedTangent = (skinMatrixWS * vec4(tangent.xyz, 0.0)).xyz;\n }\n #endif\n #ifdef THIRD_PASS\n {\n mat4 prevSkinMatrixWS = getPrevSkinMatrix(joint.x) * weight.x;\n if (weight.y > 1e-4) { prevSkinMatrixWS += getPrevSkinMatrix(joint.y) * weight.y; }\n if (weight.z > 1e-4) { prevSkinMatrixWS += getPrevSkinMatrix(joint.z) * weight.z; }\n float weightW = 1.0-weight.x-weight.y-weight.z;\n if (weightW > 1e-4) { prevSkinMatrixWS += getPrevSkinMatrix(joint.w) * weightW; }\n prevSkinnedPosition = (prevSkinMatrixWS * vec4(position, 1.0)).xyz;\n }\n #endif\n#endif\n#if defined(SECOND_PASS) || defined(FIRST_PASS)\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n#endif\n#ifdef FIRST_PASS\n v_Normal = normalize((worldInverseTranspose * vec4(skinnedNormal, 0.0)).xyz);\n if (hasTangent) {\n v_Tangent = normalize((worldInverseTranspose * vec4(skinnedTangent, 0.0)).xyz);\n v_Bitangent = normalize(cross(v_Normal, v_Tangent) * tangent.w);\n }\n v_WorldPosition = (world * vec4(skinnedPosition, 1.0)).xyz;\n#endif\n#ifdef THIRD_PASS\n v_ViewPosition = worldViewProjection * vec4(skinnedPosition, 1.0);\n v_PrevViewPosition = prevWorldViewProjection * vec4(prevSkinnedPosition, 1.0);\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0);\n}\n@end\n@export clay.deferred.gbuffer1.fragment\nuniform mat4 viewInverse : VIEWINVERSE;\nuniform float glossiness;\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nuniform sampler2D normalMap;\nuniform sampler2D diffuseMap;\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\nuniform sampler2D roughGlossMap;\nuniform bool useRoughGlossMap;\nuniform bool useRoughness;\nuniform bool doubleSided;\nuniform float alphaCutoff: 0.0;\nuniform float alpha: 1.0;\nuniform int roughGlossChannel: 0;\nfloat indexingTexel(in vec4 texel, in int idx) {\n if (idx == 3) return texel.a;\n else if (idx == 1) return texel.g;\n else if (idx == 2) return texel.b;\n else return texel.r;\n}\nvoid main()\n{\n vec3 N = v_Normal;\n if (doubleSided) {\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = eyePos - v_WorldPosition;\n if (dot(N, V) < 0.0) {\n N = -N;\n }\n }\n if (alphaCutoff > 0.0) {\n float a = texture2D(diffuseMap, v_Texcoord).a * alpha;\n if (a < alphaCutoff) {\n discard;\n }\n }\n if (dot(v_Tangent, v_Tangent) > 0.0) {\n vec3 normalTexel = texture2D(normalMap, v_Texcoord).xyz;\n if (dot(normalTexel, normalTexel) > 0.0) { N = normalTexel * 2.0 - 1.0;\n mat3 tbn = mat3(v_Tangent, v_Bitangent, v_Normal);\n N = normalize(tbn * N);\n }\n }\n gl_FragColor.rgb = (N + 1.0) * 0.5;\n float g = glossiness;\n if (useRoughGlossMap) {\n float g2 = indexingTexel(texture2D(roughGlossMap, v_Texcoord), roughGlossChannel);\n if (useRoughness) {\n g2 = 1.0 - g2;\n }\n g = clamp(g2 + (g - 0.5) * 2.0, 0.0, 1.0);\n }\n gl_FragColor.a = g + 0.005;\n}\n@end\n@export clay.deferred.gbuffer2.fragment\nuniform sampler2D diffuseMap;\nuniform sampler2D metalnessMap;\nuniform vec3 color;\nuniform float metalness;\nuniform bool useMetalnessMap;\nuniform bool linear;\nuniform float alphaCutoff: 0.0;\nuniform float alpha: 1.0;\nvarying vec2 v_Texcoord;\n@import clay.util.srgb\nvoid main()\n{\n float m = metalness;\n if (useMetalnessMap) {\n vec4 metalnessTexel = texture2D(metalnessMap, v_Texcoord);\n m = clamp(metalnessTexel.r + (m * 2.0 - 1.0), 0.0, 1.0);\n }\n vec4 texel = texture2D(diffuseMap, v_Texcoord);\n if (linear) {\n texel = sRGBToLinear(texel);\n }\n if (alphaCutoff > 0.0) {\n float a = texel.a * alpha;\n if (a < alphaCutoff) {\n discard;\n }\n }\n gl_FragColor.rgb = texel.rgb * color;\n gl_FragColor.a = m + 0.005;\n}\n@end\n@export clay.deferred.gbuffer3.fragment\nuniform bool firstRender;\nvarying vec4 v_ViewPosition;\nvarying vec4 v_PrevViewPosition;\nvoid main()\n{\n vec2 a = v_ViewPosition.xy / v_ViewPosition.w;\n vec2 b = v_PrevViewPosition.xy / v_PrevViewPosition.w;\n if (firstRender) {\n gl_FragColor = vec4(0.0);\n }\n else {\n gl_FragColor = vec4((a - b) * 0.5 + 0.5, 0.0, 1.0);\n }\n}\n@end\n@export clay.deferred.gbuffer.debug\n@import clay.deferred.chunk.light_head\nuniform sampler2D gBufferTexture4;\nuniform int debug: 0;\nvoid main ()\n{\n @import clay.deferred.chunk.gbuffer_read\n if (debug == 0) {\n gl_FragColor = vec4(N, 1.0);\n }\n else if (debug == 1) {\n gl_FragColor = vec4(vec3(z), 1.0);\n }\n else if (debug == 2) {\n gl_FragColor = vec4(position, 1.0);\n }\n else if (debug == 3) {\n gl_FragColor = vec4(vec3(glossiness), 1.0);\n }\n else if (debug == 4) {\n gl_FragColor = vec4(vec3(metalness), 1.0);\n }\n else if (debug == 5) {\n gl_FragColor = vec4(albedo, 1.0);\n }\n else {\n vec4 color = texture2D(gBufferTexture4, uv);\n color.rg -= 0.5;\n color.rg *= 2.0;\n gl_FragColor = color;\n }\n}\n@end"),Q.import("@export clay.deferred.chunk.light_head\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture2;\nuniform sampler2D gBufferTexture3;\nuniform vec2 windowSize: WINDOW_SIZE;\nuniform vec4 viewport: VIEWPORT;\nuniform mat4 viewProjectionInv;\n#ifdef DEPTH_ENCODED\n@import clay.util.decode_float\n#endif\n@end\n@export clay.deferred.chunk.gbuffer_read\n vec2 uv = gl_FragCoord.xy / windowSize;\n vec2 uv2 = (gl_FragCoord.xy - viewport.xy) / viewport.zw;\n vec4 texel1 = texture2D(gBufferTexture1, uv);\n vec4 texel3 = texture2D(gBufferTexture3, uv);\n if (dot(texel1.rgb, vec3(1.0)) == 0.0) {\n discard;\n }\n float glossiness = texel1.a;\n float metalness = texel3.a;\n vec3 N = texel1.rgb * 2.0 - 1.0;\n float z = texture2D(gBufferTexture2, uv).r * 2.0 - 1.0;\n vec2 xy = uv2 * 2.0 - 1.0;\n vec4 projectedPos = vec4(xy, z, 1.0);\n vec4 p4 = viewProjectionInv * projectedPos;\n vec3 position = p4.xyz / p4.w;\n vec3 albedo = texel3.rgb;\n vec3 diffuseColor = albedo * (1.0 - metalness);\n vec3 specularColor = mix(vec3(0.04), albedo, metalness);\n@end\n@export clay.deferred.chunk.light_equation\nfloat D_Phong(in float g, in float ndh) {\n float a = pow(8192.0, g);\n return (a + 2.0) / 8.0 * pow(ndh, a);\n}\nfloat D_GGX(in float g, in float ndh) {\n float r = 1.0 - g;\n float a = r * r;\n float tmp = ndh * ndh * (a - 1.0) + 1.0;\n return a / (3.1415926 * tmp * tmp);\n}\nvec3 F_Schlick(in float ndv, vec3 spec) {\n return spec + (1.0 - spec) * pow(1.0 - ndv, 5.0);\n}\nvec3 lightEquation(\n in vec3 lightColor, in vec3 diffuseColor, in vec3 specularColor,\n in float ndl, in float ndh, in float ndv, in float g\n)\n{\n return ndl * lightColor\n * (diffuseColor + D_Phong(g, ndh) * F_Schlick(ndv, specularColor));\n}\n@end");var oa=Fe.extend(function(){var t={minFilter:yn.NEAREST,magFilter:yn.NEAREST,wrapS:yn.CLAMP_TO_EDGE,wrapT:yn.CLAMP_TO_EDGE};return{enableTargetTexture1:!0,enableTargetTexture2:!0,enableTargetTexture3:!0,enableTargetTexture4:!1,renderTransparent:!1,_gBufferRenderList:[],_gBufferTex1:new En(Object.assign({type:yn.HALF_FLOAT},t)),_gBufferTex2:new En(Object.assign({format:yn.DEPTH_STENCIL,type:yn.UNSIGNED_INT_24_8_WEBGL},t)),_gBufferTex3:new En(t),_gBufferTex4:new En(Object.assign({type:yn.HALF_FLOAT},t)),_defaultNormalMap:new En({image:ne("#000")}),_defaultRoughnessMap:new En({image:ne("#fff")}),_defaultMetalnessMap:new En({image:ne("#fff")}),_defaultDiffuseMap:new En({image:ne("#fff")}),_frameBuffer:new ai,_gBufferMaterial1:new rr({shader:new Q(Q.source("clay.deferred.gbuffer.vertex"),Q.source("clay.deferred.gbuffer1.fragment")),vertexDefines:{FIRST_PASS:null},fragmentDefines:{FIRST_PASS:null}}),_gBufferMaterial2:new rr({shader:new Q(Q.source("clay.deferred.gbuffer.vertex"),Q.source("clay.deferred.gbuffer2.fragment")),vertexDefines:{SECOND_PASS:null},fragmentDefines:{SECOND_PASS:null}}),_gBufferMaterial3:new rr({shader:new Q(Q.source("clay.deferred.gbuffer.vertex"),Q.source("clay.deferred.gbuffer3.fragment")),vertexDefines:{THIRD_PASS:null},fragmentDefines:{THIRD_PASS:null}}),_debugPass:new li({fragment:Q.source("clay.deferred.gbuffer.debug")})}},{resize:function(t,e){this._gBufferTex1.width===t&&this._gBufferTex1.height===e||(this._gBufferTex1.width=t,this._gBufferTex1.height=e,this._gBufferTex2.width=t,this._gBufferTex2.height=e,this._gBufferTex3.width=t,this._gBufferTex3.height=e,this._gBufferTex4.width=t,this._gBufferTex4.height=e)},setViewport:function(t,e,r,n,i){var a;a="object"==typeof t?t:{x:t,y:e,width:r,height:n,devicePixelRatio:i||1},this._frameBuffer.viewport=a},getViewport:function(){return this._frameBuffer.viewport?this._frameBuffer.viewport:{x:0,y:0,width:this._gBufferTex1.width,height:this._gBufferTex1.height,devicePixelRatio:1}},update:function(t,e,r,n){function i(){if(u){var t=u.devicePixelRatio;o.enable(o.SCISSOR_TEST),o.scissor(u.x*t,u.y*t,u.width*t,u.height*t)}o.clear(o.COLOR_BUFFER_BIT|o.DEPTH_BUFFER_BIT),u&&o.disable(o.SCISSOR_TEST)}function a(t,e){return t.material!==e.material}n=n||{};for(var o=t.gl,s=this._frameBuffer,u=s.viewport,l=e.updateRenderList(r,!0),c=l.opaque,h=l.transparent,f=0,d=this._gBufferRenderList,p=0;pt.getMaxJointNumber()){var a=n.getSubSkinMatricesTexture(e.__uid__,i),o=e.__prevSkinMatricesTexture;if(o||(o=e.__prevSkinMatricesTexture=new En({type:yn.FLOAT,minFilter:yn.NEAREST,magFilter:yn.NEAREST,useMipmap:!1,flipY:!1})),o.pixels&&o.pixels.length===a.pixels.length)for(var s=0;s= shadowCascadeClipsNear[_idx_] &&\n z <= shadowCascadeClipsFar[_idx_]\n ) {\n shadowContrib = computeShadowContrib(\n lightShadowMap, lightMatrices[_idx_], position, lightShadowMapSize,\n vec2(1.0 / float(SHADOW_CASCADE), 1.0),\n vec2(float(_idx_) / float(SHADOW_CASCADE), 0.0)\n );\n }\n }}\n gl_FragColor.rgb *= shadowContrib;\n#endif\n gl_FragColor.a = 1.0;\n}\n@end\n"),Q.import("@export clay.deferred.ambient_light\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture3;\nuniform vec3 lightColor;\nuniform vec2 windowSize: WINDOW_SIZE;\nvoid main()\n{\n vec2 uv = gl_FragCoord.xy / windowSize;\n vec4 texel1 = texture2D(gBufferTexture1, uv);\n if (dot(texel1.rgb, vec3(1.0)) == 0.0) {\n discard;\n }\n vec3 albedo = texture2D(gBufferTexture3, uv).rgb;\n gl_FragColor.rgb = lightColor * albedo;\n gl_FragColor.a = 1.0;\n}\n@end"),Q.import("@export clay.deferred.ambient_sh_light\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture3;\nuniform vec3 lightColor;\nuniform vec3 lightCoefficients[9];\nuniform vec2 windowSize: WINDOW_SIZE;\nvec3 calcAmbientSHLight(vec3 N) {\n return lightCoefficients[0]\n + lightCoefficients[1] * N.x\n + lightCoefficients[2] * N.y\n + lightCoefficients[3] * N.z\n + lightCoefficients[4] * N.x * N.z\n + lightCoefficients[5] * N.z * N.y\n + lightCoefficients[6] * N.y * N.x\n + lightCoefficients[7] * (3.0 * N.z * N.z - 1.0)\n + lightCoefficients[8] * (N.x * N.x - N.y * N.y);\n}\nvoid main()\n{\n vec2 uv = gl_FragCoord.xy / windowSize;\n vec4 texel1 = texture2D(gBufferTexture1, uv);\n if (dot(texel1.rgb, vec3(1.0)) == 0.0) {\n discard;\n }\n vec3 N = texel1.rgb * 2.0 - 1.0;\n vec3 albedo = texture2D(gBufferTexture3, uv).rgb;\n gl_FragColor.rgb = lightColor * albedo * calcAmbientSHLight(N);\n gl_FragColor.a = 1.0;\n}\n@end"),Q.import("@export clay.deferred.ambient_cubemap_light\n@import clay.deferred.chunk.light_head\nuniform vec3 lightColor;\nuniform samplerCube lightCubemap;\nuniform sampler2D brdfLookup;\nuniform vec3 eyePosition;\n@import clay.util.rgbm\nvoid main()\n{\n @import clay.deferred.chunk.gbuffer_read\n vec3 V = normalize(eyePosition - position);\n vec3 L = reflect(-V, N);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n float rough = clamp(1.0 - glossiness, 0.0, 1.0);\n float bias = rough * 5.0;\n vec2 brdfParam = texture2D(brdfLookup, vec2(rough, ndv)).xy;\n vec3 envWeight = specularColor * brdfParam.x + brdfParam.y;\n vec3 envTexel = RGBMDecode(textureCubeLodEXT(lightCubemap, L, bias), 8.12);\n gl_FragColor.rgb = lightColor * envTexel * envWeight;\n gl_FragColor.a = 1.0;\n}\n@end"),Q.import("@export clay.deferred.point_light\n@import clay.deferred.chunk.light_head\n@import clay.util.calculate_attenuation\n@import clay.deferred.chunk.light_equation\nuniform vec3 lightPosition;\nuniform vec3 lightColor;\nuniform float lightRange;\nuniform vec3 eyePosition;\n#ifdef SHADOWMAP_ENABLED\nuniform samplerCube lightShadowMap;\nuniform float lightShadowMapSize;\n#endif\nvarying vec3 v_Position;\n@import clay.plugin.shadow_map_common\nvoid main()\n{\n @import clay.deferred.chunk.gbuffer_read\n vec3 L = lightPosition - position;\n vec3 V = normalize(eyePosition - position);\n float dist = length(L);\n L /= dist;\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n float attenuation = lightAttenuation(dist, lightRange);\n gl_FragColor.rgb = attenuation * lightEquation(\n lightColor, diffuseColor, specularColor, ndl, ndh, ndv, glossiness\n );\n#ifdef SHADOWMAP_ENABLED\n float shadowContrib = computeShadowContribOmni(\n lightShadowMap, -L * dist, lightRange\n );\n gl_FragColor.rgb *= clamp(shadowContrib, 0.0, 1.0);\n#endif\n gl_FragColor.a = 1.0;\n}\n@end"),Q.import("@export clay.deferred.sphere_light\n@import clay.deferred.chunk.light_head\n@import clay.util.calculate_attenuation\n@import clay.deferred.chunk.light_equation\nuniform vec3 lightPosition;\nuniform vec3 lightColor;\nuniform float lightRange;\nuniform float lightRadius;\nuniform vec3 eyePosition;\nvarying vec3 v_Position;\nvoid main()\n{\n @import clay.deferred.chunk.gbuffer_read\n vec3 L = lightPosition - position;\n vec3 V = normalize(eyePosition - position);\n float dist = length(L);\n vec3 R = reflect(V, N);\n float tmp = dot(L, R);\n vec3 cToR = tmp * R - L;\n float d = length(cToR);\n L = L + cToR * clamp(lightRadius / d, 0.0, 1.0);\n L = normalize(L);\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n float attenuation = lightAttenuation(dist, lightRange);\n gl_FragColor.rgb = lightColor * ndl * attenuation;\n glossiness = clamp(glossiness - lightRadius / 2.0 / dist, 0.0, 1.0);\n gl_FragColor.rgb = attenuation * lightEquation(\n lightColor, diffuseColor, specularColor, ndl, ndh, ndv, glossiness\n );\n gl_FragColor.a = 1.0;\n}\n@end"),Q.import("@export clay.deferred.tube_light\n@import clay.deferred.chunk.light_head\n@import clay.util.calculate_attenuation\n@import clay.deferred.chunk.light_equation\nuniform vec3 lightPosition;\nuniform vec3 lightColor;\nuniform float lightRange;\nuniform vec3 lightExtend;\nuniform vec3 eyePosition;\nvarying vec3 v_Position;\nvoid main()\n{\n @import clay.deferred.chunk.gbuffer_read\n vec3 L = lightPosition - position;\n vec3 V = normalize(eyePosition - position);\n vec3 R = reflect(V, N);\n vec3 L0 = lightPosition - lightExtend - position;\n vec3 L1 = lightPosition + lightExtend - position;\n vec3 LD = L1 - L0;\n float len0 = length(L0);\n float len1 = length(L1);\n float irra = 2.0 * clamp(dot(N, L0) / (2.0 * len0) + dot(N, L1) / (2.0 * len1), 0.0, 1.0);\n float LDDotR = dot(R, LD);\n float t = (LDDotR * dot(R, L0) - dot(L0, LD)) / (dot(LD, LD) - LDDotR * LDDotR);\n t = clamp(t, 0.0, 1.0);\n L = L0 + t * LD;\n float dist = length(L);\n L /= dist;\n vec3 H = normalize(L + V);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n glossiness = clamp(glossiness - 0.0 / 2.0 / dist, 0.0, 1.0);\n gl_FragColor.rgb = lightColor * irra * lightAttenuation(dist, lightRange)\n * (diffuseColor + D_Phong(glossiness, ndh) * F_Schlick(ndv, specularColor));\n gl_FragColor.a = 1.0;\n}\n@end"),Q.import(Tr);var la=Fe.extend(function(){var t=Q.source("clay.compositor.vertex"),e=Q.source("clay.deferred.light_volume.vertex"),r=new Q(t,Q.source("clay.deferred.directional_light")),n=function(t){t.blendEquation(t.FUNC_ADD),t.blendFuncSeparate(t.ONE,t.ONE,t.ONE,t.ONE)},i=function(t){return new rr({shader:t,blend:n,transparent:!0,depthMask:!1})},a=function(t){return new Q(e,Q.source("clay.deferred."+t))},o=new sa({capSegments:10}),s=new Br;s.rotateX(Math.PI/2).translate(new wr(0,-1,0)),o.applyTransform(s);var u=new ua({capSegments:10});return s.identity().rotateZ(Math.PI/2),u.applyTransform(s),{shadowMapPass:null,autoResize:!0,_createLightPassMat:i,_gBuffer:new oa,_lightAccumFrameBuffer:new ai,_lightAccumTex:new En({type:yn.HALF_FLOAT,minFilter:yn.NEAREST,magFilter:yn.NEAREST}),_fullQuadPass:new li({blendWithPrevious:!0}),_directionalLightMat:i(r),_ambientMat:i(new Q(t,Q.source("clay.deferred.ambient_light"))),_ambientSHMat:i(new Q(t,Q.source("clay.deferred.ambient_sh_light"))),_ambientCubemapMat:i(new Q(t,Q.source("clay.deferred.ambient_cubemap_light"))),_spotLightShader:a("spot_light"),_pointLightShader:a("point_light"),_sphereLightShader:a("sphere_light"),_tubeLightShader:a("tube_light"),_lightSphereGeo:new gn({widthSegments:10,heightSegements:10}),_lightConeGeo:o,_lightCylinderGeo:u,_outputPass:new li({fragment:Q.source("clay.compositor.output")})}},{render:function(t,e,r,n){n=n||{},n.renderToTarget=n.renderToTarget||!1,n.notUpdateShadow=n.notUpdateShadow||!1,n.notUpdateScene=n.notUpdateScene||!1,n.notUpdateScene||e.update(!1,!0),e.updateLights(),r.update(!0);var i=t.getDevicePixelRatio();!this.autoResize||t.getWidth()*i===this._lightAccumTex.width&&t.getHeight()*i===this._lightAccumTex.height||this.resize(t.getWidth()*i,t.getHeight()*i),this._gBuffer.update(t,e,r),this._accumulateLightBuffer(t,e,r,!n.notUpdateShadow),n.renderToTarget||(this._outputPass.setUniform("texture",this._lightAccumTex),this._outputPass.render(t))},getTargetTexture:function(){return this._lightAccumTex},getTargetFrameBuffer:function(){return this._lightAccumFrameBuffer},getGBuffer:function(){return this._gBuffer},setViewport:function(t,e,r,n,i){this._gBuffer.setViewport(t,e,r,n,i),this._lightAccumFrameBuffer.viewport=this._gBuffer.getViewport()},resize:function(t,e){this._lightAccumTex.width=t,this._lightAccumTex.height=e,this._gBuffer.resize(t,e)},_accumulateLightBuffer:function(t,e,r,n){for(var i=t.gl,a=this._lightAccumTex,o=this._lightAccumFrameBuffer,s=r.getWorldPosition().array,u=0;u0&&we.scaleAndAdd(t.array,t.array,this.force.array,n/r)}});Q.import("@export clay.particle.vertex\nuniform mat4 worldView : WORLDVIEW;\nuniform mat4 projection : PROJECTION;\nattribute vec3 position : POSITION;\nattribute vec3 normal : NORMAL;\n#ifdef UV_ANIMATION\nattribute vec2 texcoord0 : TEXCOORD_0;\nattribute vec2 texcoord1 : TEXCOORD_1;\nvarying vec2 v_Uv0;\nvarying vec2 v_Uv1;\n#endif\nvarying float v_Age;\nvoid main() {\n v_Age = normal.x;\n float rotation = normal.y;\n vec4 worldViewPosition = worldView * vec4(position, 1.0);\n gl_Position = projection * worldViewPosition;\n float w = gl_Position.w;\n gl_PointSize = normal.z * projection[0].x / w;\n #ifdef UV_ANIMATION\n v_Uv0 = texcoord0;\n v_Uv1 = texcoord1;\n #endif\n}\n@end\n@export clay.particle.fragment\nuniform sampler2D sprite;\nuniform sampler2D gradient;\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform float alpha : 1.0;\nvarying float v_Age;\n#ifdef UV_ANIMATION\nvarying vec2 v_Uv0;\nvarying vec2 v_Uv1;\n#endif\nvoid main() {\n vec4 color = vec4(color, alpha);\n #ifdef SPRITE_ENABLED\n #ifdef UV_ANIMATION\n color *= texture2D(sprite, mix(v_Uv0, v_Uv1, gl_PointCoord));\n #else\n color *= texture2D(sprite, gl_PointCoord);\n #endif\n #endif\n #ifdef GRADIENT_ENABLED\n color *= texture2D(gradient, vec2(v_Age, 0.5));\n #endif\n gl_FragColor = color;\n}\n@end");var Pa=new Q(Q.source("clay.particle.vertex"),Q.source("clay.particle.fragment")),Ia=Mn.extend({loop:!0,oneshot:!1,duration:1,spriteAnimationTileX:1,spriteAnimationTileY:1,spriteAnimationRepeat:0,mode:Mn.POINTS,ignorePicking:!0,_elapsedTime:0,_emitting:!0},function(){this.geometry=new dn({dynamic:!0}),this.material||(this.material=new rr({shader:Pa,transparent:!0,depthMask:!1}),this.material.enableTexture("sprite")),this._particles=[],this._fields=[],this._emitters=[]},{culling:!1,frustumCulling:!1,castShadow:!1,receiveShadow:!1,addEmitter:function(t){this._emitters.push(t)},removeEmitter:function(t){this._emitters.splice(this._emitters.indexOf(t),1)},addField:function(t){this._fields.push(t)},removeField:function(t){this._fields.splice(this._fields.indexOf(t),1)},reset:function(){for(var t=0;t=i.life?(i.emitter.kill(i),e[r]=e[n-1],e.pop(),n--):r++}for(var r=0;r0)for(var a=0;a1,o=t.attributes.position.value,s=t.attributes.normal.value,u=t.attributes.texcoord0.value,l=t.attributes.texcoord1.value,c=this._particles.length;o&&o.length===3*c||(o=t.attributes.position.value=new Float32Array(3*c),s=t.attributes.normal.value=new Float32Array(3*c),a&&(u=t.attributes.texcoord0.value=new Float32Array(2*c),l=t.attributes.texcoord1.value=new Float32Array(2*c)));for(var h=1/e,f=0;fthis.duration&&!this.loop},dispose:function(t){for(var e=0;ethis._gamepadAxisThreshold)switch(e){case 0:this._moveLeft=r<0,this._moveRight=r>0;break;case 1:this._moveForward=r<0,this._moveBackward=r>0;break;case 2:this._offsetPitch+=r*this.lookAroundSpeed;break;case 3:this._offsetRoll+=r*this.lookAroundSpeed}}}}),Ua=function(){this._track=[]};Ua.prototype={constructor:Ua,recognize:function(t,e,r){return this._doTrack(t,e,r),this._recognize(t)},clear:function(){return this._track.length=0,this},_doTrack:function(t,e,r){var n=t.targetTouches;if(n){for(var i={points:[],touches:[],target:e,event:t},a=0,o=n.length;a1&&n&&n.length>1){var a=ue(n)/ue(i);!isFinite(a)&&(a=1),e.pinchScale=a;var o=le(n);return e.pinchX=o[0],e.pinchY=o[1],{type:"pinch",target:t[0].target,event:e}}}}},ka=[[0,0],[0,1],[1,1],[1,0]],Ha=[0,1,2,2,3,0],Ga=wn.extend({camera:null,plane:null,maxGrid:0,frustumCulling:!1},function(){var t=this.geometry=new dn({dynamic:!0});t.attributes.position.init(6),t.attributes.normal.init(6),t.attributes.texcoord0.init(6),t.indices=new Uint16Array(6),this.plane=new qr},{updateGeometry:function(){var t=this._unProjectGrid();if(t){for(var e=this.geometry.attributes.position,r=this.geometry.attributes.normal,n=this.geometry.attributes.texcoord0,i=this.geometry.indices,a=0;a<6;a++){var o=Ha[a];e.set(a,t[o].array),r.set(a,this.plane.normal.array),n.set(a,ka[o]),i[a]=a}this.geometry.dirty()}},_unProjectGrid:function(){for(var t=new qr,e=[0,1,0,2,1,3,2,3,4,5,4,6,5,7,6,7,0,4,1,5,2,6,3,7],r=new wr,n=new wr,i=[],a=[],o=0;o<4;o++)a[o]=new wr(0,0);var s=new tn;return function(){t.copy(this.plane),t.applyTransform(this.camera.viewMatrix);for(var o=this.camera.frustum.vertices,u=0,l=0;l<12;l++){r.array=o[e[2*l]],n.array=o[e[2*l+1]];var c=t.intersectLine(r,n,i[u]);c&&(i[u]||(i[u]=c),u++)}if(0!==u){for(var l=0;l0},update:function(t){if(t=t||16,this._rotating){var e=("cw"===this.autoRotateDirection?1:-1)*this.autoRotateSpeed/180*Math.PI;this._phi-=e*t/1e3,this._needsUpdate=!0}else this._rotateVelocity.len()>0&&(this._needsUpdate=!0);(Math.abs(this._zoomSpeed)>.01||this._panVelocity.len()>0)&&(this._needsUpdate=!0),this._needsUpdate&&(this._updateDistance(Math.min(t,50)),this._updatePan(Math.min(t,50)),this._updateRotate(Math.min(t,50)),this._updateTransform(),this.target.update(),this.trigger("update"),this._needsUpdate=!1)},_updateRotate:function(t){var e=this._rotateVelocity;this._phi=e.y*t/20+this._phi,this._theta=e.x*t/20+this._theta,this.setAlpha(this.getAlpha()),this.setBeta(this.getBeta()),this._vectorDamping(e,this.damping),e.x=e.y=0},_updateDistance:function(t){this._setDistance(this._distance+this._zoomSpeed*t/20),this._zoomSpeed*=this.damping},_setDistance:function(t){this._distance=Math.max(Math.min(t,this.maxDistance),this.minDistance)},_updatePan:function(t){var e=this._panVelocity,r=this._distance,n=this.target,i=n.worldTransform.y,a=n.worldTransform.x;this._center.scaleAndAdd(a,-e.x*r/200).scaleAndAdd(i,-e.y*r/200),this._vectorDamping(e,0),e.x=e.y=0},_updateTransform:function(){var t=this.target,e=new wr,r=this._theta+Math.PI/2,n=this._phi+Math.PI/2,i=Math.sin(r);e.x=i*Math.cos(n),e.y=-Math.cos(r),e.z=i*Math.sin(n),t.position.copy(this._center).scaleAndAdd(e,this._distance),t.rotation.identity().rotateY(-this._phi).rotateX(-this._theta)},_startCountingStill:function(){clearTimeout(this._stillTimeout);var t=this.autoRotateAfterStill,e=this;!isNaN(t)&&t>0&&(this._stillTimeout=setTimeout(function(){e._rotating=!0},1e3*t))},_vectorDamping:function(t,e){var r=t.len();r*=e,r<1e-4&&(r=0),t.normalize().scale(r)},decomposeTransform:function(){if(this.target){this.target.updateWorldTransform();var t=this.target.worldTransform.z,e=Math.asin(t.y),r=Math.atan2(t.x,t.z);this._theta=e,this._phi=-r,this.setBeta(this.getBeta()),this.setAlpha(this.getAlpha()),this._setDistance(this.target.position.dist(this._center))}},_mouseDownHandler:function(t){if(!this._isAnimating()){var e=t.clientX,r=t.clientY;if(t.targetTouches){var n=t.targetTouches[0];e=n.clientX,r=n.clientY,this._mode="rotate",this._processGesture(t,"start")}else 0===t.button?this._mode="rotate":1===t.button?this._mode="pan":this._mode=null;var i=this.domElement;i.addEventListener("touchmove",this._mouseMoveHandler),i.addEventListener("touchend",this._mouseUpHandler),i.addEventListener("mousemove",this._mouseMoveHandler),i.addEventListener("mouseup",this._mouseUpHandler),i.addEventListener("mouseout",this._mouseUpHandler),this._rotateVelocity.set(0,0),this._rotating=!1,this.autoRotate&&this._startCountingStill(),this._mouseX=e,this._mouseY=r}},_mouseMoveHandler:function(t){if(!this._isAnimating()){var e,r=t.clientX,n=t.clientY;if(t.targetTouches){var i=t.targetTouches[0];r=i.clientX,n=i.clientY,e=this._processGesture(t,"change")}var a=ce(this.panSensitivity),o=ce(this.rotateSensitivity);e||("rotate"===this._mode?(this._rotateVelocity.y+=(r-this._mouseX)/this.domElement.clientWidth*2*o[0],this._rotateVelocity.x+=(n-this._mouseY)/this.domElement.clientHeight*2*o[1]):"pan"===this._mode&&(this._panVelocity.x+=(r-this._mouseX)/this.domElement.clientWidth*a[0]*400,this._panVelocity.y+=(-n+this._mouseY)/this.domElement.clientHeight*a[1]*400)),this._mouseX=r,this._mouseY=n,t.preventDefault()}},_mouseWheelHandler:function(t){if(!this._isAnimating()){var e=t.deltaY;0!==e&&this._zoomHandler(t,e>0?1:-1)}},_pinchHandler:function(t){this._isAnimating()||this._zoomHandler(t,t.pinchScale>1?-.4:.4)},_zoomHandler:function(t,e){var r=Math.max(Math.min(this._distance-this.minDistance,this.maxDistance-this._distance));this._zoomSpeed=e*Math.max(r/40*this.zoomSensitivity,.2),this._rotating=!1,this.autoRotate&&"rotate"===this._mode&&this._startCountingStill(),t.preventDefault()},_mouseUpHandler:function(t){var e=this.domElement;e.removeEventListener("touchmove",this._mouseMoveHandler),e.removeEventListener("touchend",this._mouseUpHandler),e.removeEventListener("mousemove",this._mouseMoveHandler),e.removeEventListener("mouseup",this._mouseUpHandler), -e.removeEventListener("mouseout",this._mouseUpHandler),this._processGesture(t,"end")},_addAnimator:function(t){var e=this._animators;return e.push(t),t.done(function(){var r=e.indexOf(t);r>=0&&e.splice(r,1)}),t},_processGesture:function(t,e){var r=this._gestureMgr;"start"===e&&r.clear();var n=r.recognize(t,null,this.domElement);if("end"===e&&r.clear(),n){var i=n.type;t.gestureEvent=i,this._pinchHandler(n.event)}return n}});Object.defineProperty(Va.prototype,"autoRotate",{get:function(){return this._autoRotate},set:function(t){this._autoRotate=t,this._rotating=t}}),Object.defineProperty(Va.prototype,"target",{get:function(){return this._target},set:function(t){t&&t.target&&this.setCenter(t.target.toArray()),this._target=t,this.decomposeTransform()}});var Wa=dn.extend({dynamic:!1}),za={merge:function(t,e){if(t.length){var r=t[0],n=r.geometry,i=r.material,a=new dn({dynamic:!1});a.boundingBox=new Gr;for(var o=n.getEnabledAttributes(),s=0;s=65535?new Uint32Array(3*f):new Uint16Array(3*f);for(var _=0,g=0,v=n.isUseIndices(),y=0;y0;){for(var _=[],g=[],v=[],y=0,f=0;f=0&&-1===g[S]&&(y65535?new Uint32Array(3*L.triangles.length):new Uint16Array(3*L.triangles.length);var H=0;O=0;for(var f=0;f=0?N[S]:-1}O++}P.indices[H++]=C[A]}P.updateBoundingBox(),M.add(I)}for(var X=t.children(),f=0;f0&&(r.indices=fe(t.indices,e),n.push(r.indices.buffer)),r.attributes={};for(var i in t.attributes)if(t.attributes.hasOwnProperty(i)){var a=t.attributes[i];a&&a.value&&a.value.length>0&&(a=r.attributes[i]=he(a,e),n.push(a.value.buffer))}return{data:r,buffers:n}},toGeometry:function(t){if(!t)return null;if(t.data&&t.buffers)return ja.toGeometry(t.data);if(!t.metadata||t.metadata.generator!==Xa.generator)throw new Error("[util.transferable.toGeometry] the object is not generated by util.transferable.");var e={dynamic:t.dynamic,indices:t.indices};if(t.boundingBox){var r=(new wr).setArray(t.boundingBox.min),n=(new wr).setArray(t.boundingBox.max);e.boundingBox=new Gr(r,n)}var i=new dn(e);for(var a in t.attributes)if(t.attributes.hasOwnProperty(a)){var o=t.attributes[a];i.attributes[a]=new dn.Attribute(o.name,o.type,o.size,o.semantic),i.attributes[a].value=o.value}return i}};Q.import("@export clay.vr.disorter.output.vertex\nattribute vec2 texcoord: TEXCOORD_0;\nattribute vec3 position: POSITION;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n v_Texcoord = texcoord;\n gl_Position = vec4(position.xy, 0.5, 1.0);\n}\n@end\n@export clay.vr.disorter.output.fragment\nuniform sampler2D texture;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n gl_FragColor = texture2D(texture, v_Texcoord);\n}\n@end");var qa=Fe.extend(function(){return{clearColor:[0,0,0,1],_mesh:new wn({geometry:new dn({dynamic:!0}),culling:!1,material:new rr({depthTest:!1,shader:new Q({vertex:Q.source("clay.vr.disorter.output.vertex"),fragment:Q.source("clay.vr.disorter.output.fragment")})})}),_fakeCamera:new Cn}},{render:function(t,e){var r=this.clearColor,n=t.gl;n.clearColor(r[0],r[1],r[2],r[3]),n.clear(n.COLOR_BUFFER_BIT),n.disable(n.BLEND),this._mesh.material.set("texture",e),t.saveViewport(),t.setViewport(0,0,t.getWidth(),t.getHeight()),t.renderPass([this._mesh],this._fakeCamera),t.restoreViewport()},updateFromVRDisplay:function(t){t.deviceInfo_?this._updateMesh(20,20,t.deviceInfo_):console.warn("Cant get vrDisplay.deviceInfo_, seems code changed")},_updateMesh:function(t,e,r){var n=this._mesh.geometry.attributes.position,i=this._mesh.geometry.attributes.texcoord0;n.init(2*t*e),i.init(2*t*e);for(var a=r.getLeftEyeVisibleTanAngles(),o=r.getLeftEyeNoLensTanAngles(),s=r.getLeftEyeVisibleScreenRect(o),u=0,l=[],c=[],h=0;h<2;h++){for(var f=0;fi)t.length=i;else for(var a=n;a=0&&!(x[M]<=e);M--);M=Math.min(M,g-2)}else{for(M=D;Me);M++);M=Math.min(M-1,g-2)}D=M,B=e;var r=x[M+1]-x[M];0!==r&&(L=(e-x[M])/r,L=Math.max(Math.min(1,L),0),L=A[M+1](L),_?(P=E[M],N=E[0===M?M:M-1],I=E[M>g-2?g-1:M+1],O=E[M>g-3?g-1:M+2],f?m(t,s,f(p(t,s),N,P,I,O,L)):y?u(N,P,I,O,L,L*L,L*L*L,p(t,s),T):m(t,s,l(N,P,I,O,L,L*L,L*L*L))):f?m(t,s,f(p(t,s),E[M],E[M+1],L)):y?a(E[M],E[M+1],L,p(t,s),T):m(t,s,i(E[M],E[M+1],L)))},F=new me({target:t._target,life:d,loop:t._loop,delay:t._delay,onframe:U,onfinish:r});return e&&"spline"!==e&&F.setEasing(e),F}}}function d(t,e,i,a,o){this._tracks={},this._target=t,this._loop=e||!1,this._getter=i||r,this._setter=a||n,this._interpolater=o||null,this._delay=0,this._doneList=[],this._onframeList=[],this._clipList=[],this._maxTime=0,this._lastKFTime=0}function p(t){return t}function m(t){var e,r,n,i,a,o,s=Number.POSITIVE_INFINITY,u=Number.POSITIVE_INFINITY,l=Number.NEGATIVE_INFINITY,h=Number.NEGATIVE_INFINITY;for(e=t.length;e--;)t[e][0]l&&(l=t[e][0]),t[e][1]h&&(h=t[e][1]);return r=l-s,n=h-u,i=Math.max(r,n),a=s+.5*r,o=u+.5*n,[[a-20*i,o-i],[a,o+20*i],[a+20*i,o-i]]}function _(t,e,r,n){var i,a,o,s,u,l,h,c,f,d,p=t[e][0],m=t[e][1],_=t[r][0],g=t[r][1],v=t[n][0],y=t[n][1],T=Math.abs(m-g),x=Math.abs(g-y);if(Tx?o*(i-u)+h:s*(i-l)+c),f=_-i,d=g-a,{i:e,j:r,k:n,x:i,y:a,r:f*f+d*d}}function g(t){var e,r,n,i,a,o;for(r=t.length;r;)for(i=t[--r],n=t[--r],e=r;e;)if(o=t[--e],a=t[--e],n===a&&i===o||n===o&&i===a){t.splice(r,2),t.splice(e,2);break}}function v(t,e,r,n,i,a){var o=e[i],s=e[i+1],u=e[i+2];return t[0]=o+n*(r[a]-o),t[1]=s+n*(r[a+1]-s),t[2]=u+n*(r[a+2]-u),t}function y(t,e,r,n,i,a){var o,s,u,l,h,c=e[0+i],f=e[1+i],d=e[2+i],p=e[3+i],m=r[0+a],_=r[1+a],g=r[2+a],v=r[3+a];return s=c*m+f*_+d*g+p*v,s<0&&(s=-s,m=-m,_=-_,g=-g,v=-v),1-s>1e-6?(o=Math.acos(s),u=Math.sin(o),l=Math.sin((1-n)*o)/u,h=Math.sin(n*o)/u):(l=1-n,h=n),t[0]=l*c+h*m,t[1]=l*f+h*_,t[2]=l*d+h*g,t[3]=l*p+h*v,t}function T(t,e,r){"object"==typeof e&&(r=e,e=null);var n,i=this;if(!(t instanceof Function)){n=[];for(var a in t)t.hasOwnProperty(a)&&n.push(a)}var o=function(e){if(i.apply(this,arguments),t instanceof Function?x(this,t.call(this,e)):E(this,t,n),this.constructor===o)for(var r=o.__initializers__,a=0;a=400?t.onerror&&t.onerror():t.onload&&t.onload(e.response)},t.onerror&&(e.onerror=t.onerror),e.send(null)}function S(t){function e(e){var n=t.getExtension(e);n||(n=t.getExtension("MOZ_"+e)),n||(n=t.getExtension("WEBKIT_"+e)),r[e]=n}for(var r={},n={},i=0;i255?255:t}function w(t){return t=Math.round(t),t<0?0:t>360?360:t}function C(t){return t<0?0:t>1?1:t}function R(t){return M(t.length&&"%"===t.charAt(t.length-1)?parseFloat(t)/100*255:parseInt(t,10))}function L(t){return C(t.length&&"%"===t.charAt(t.length-1)?parseFloat(t)/100:parseFloat(t))}function N(t,e,r){return r<0?r+=1:r>1&&(r-=1),6*r<1?t+(e-t)*r*6:2*r<1?e:3*r<2?t+(e-t)*(2/3-r)*6:t}function P(t,e,r){return t+(e-t)*r}function I(t,e,r,n,i){return t[0]=e,t[1]=r,t[2]=n,t[3]=i,t}function O(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t}function D(t,e){$e&&O($e,e),$e=Qe.put(t,$e||e.slice())}function B(t,e){var r=(parseFloat(t[0])%360+360)%360/360,n=L(t[1]),i=L(t[2]),a=i<=.5?i*(n+1):i+n-i*n,o=2*i-a;return e=e||[],I(e,M(255*N(o,a,r+1/3)),M(255*N(o,a,r)),M(255*N(o,a,r-1/3)),1),4===t.length&&(e[3]=t[3]),e}function U(t){if(t){var e,r,n=t[0]/255,i=t[1]/255,a=t[2]/255,o=Math.min(n,i,a),s=Math.max(n,i,a),u=s-o,l=(s+o)/2;if(0===u)e=0,r=0;else{r=l<.5?u/(s+o):u/(2-s-o);var h=((s-n)/6+u/2)/u,c=((s-i)/6+u/2)/u,f=((s-a)/6+u/2)/u;n===s?e=f-c:i===s?e=1/3+h-f:a===s&&(e=2/3+c-h),e<0&&(e+=1),e>1&&(e-=1)}var d=[360*e,r,l];return null!=t[3]&&d.push(t[3]),d}}function F(t){var e=Object.keys(t);e.sort();for(var r=[],n=0;n0&&n.push("#define "+i.toUpperCase()+"_COUNT "+a)}if(r)for(var o=0;o=0){if(1!==u&&4!==u){Z();break}u=2,h=[]}else if(1!==u)if(4!==u)r(c),u=0;else{var f=c;fr.indexOf(f)>=0||dr.indexOf(f)>=0||pr.indexOf(f)>=0?l[s].semantic=f:"ignore"===f||"unconfigurable"===f?l[s].ignore=!0:l[s].value="bool"===t?"true"===f:parseFloat(f)}else l[s].value="bool"===t?"true"===c:parseFloat(c),h=null;else{if(2!==u){Z();break}if(!(h instanceof Array)){Z();break}h.push(+i[++o])}else l[s].value=new Ge.Float32Array(h),h=null,u=5;else if(2===u){if(!(h instanceof Array)){Z();break}h.push(+i[++o])}else u=5;else u=4;else{if(0!==u&&3!==u){Z();break}u=1}}return l}function Q(t,e){"object"==typeof t&&(e=t.fragment,t=t.vertex),t=K(t),e=K(e),this._shaderID=Y(t,e),this._vertexCode=Q.parseImport(t),this._fragmentCode=Q.parseImport(e),this.attributeSemantics={},this.matrixSemantics={},this.uniformSemantics={},this.matrixSemanticKeys=[],this.uniformTemplates={},this.attributes={},this.textures={},this.vertexDefines={},this.fragmentDefines={},this._parseAttributes(),this._parseUniforms(),this._parseDefines()}function $(t){return t.material}function tt(t,e,r){return e.uniforms[r].value}function et(t,e,r,n){return r!==n}function rt(t){return!0}function nt(){}function it(t,e,r){this.availableAttributes=t,this.availableAttributeSymbols=e,this.indicesBuffer=r,this.vao=null}function at(t){var e,r;this.bind=function(t){e||(e=Ge.createCanvas(),e.width=e.height=1,e.getContext("2d"));var n=t.gl,i=!r;i&&(r=n.createTexture()),n.bindTexture(n.TEXTURE_2D,r),i&&n.texImage2D(n.TEXTURE_2D,0,n.RGBA,n.RGBA,n.UNSIGNED_BYTE,e)},this.unbind=function(t){t.gl.bindTexture(t.gl.TEXTURE_2D,null)},this.isRenderable=function(){return!0}}function ot(t,e,r){return tr?r:t}function st(t){var e=[],r=Object.keys(t);r.sort();for(var n=0;n0){var i=Math.pow(2,t[3]-128-8+n);e[r+0]=t[0]*i,e[r+1]=t[1]*i,e[r+2]=t[2]*i}else e[r+0]=0,e[r+1]=0,e[r+2]=0;return e[r+3]=1,e}function bt(t,e,r){for(var n="",i=e;i0;)if(t[a][0]=e[r++],t[a][1]=e[r++],t[a][2]=e[r++],t[a][3]=e[r++],1===t[a][0]&&1===t[a][1]&&1===t[a][2]){for(var s=t[a][3]<>>0;s>0;s--)St(t[a-1],t[a]),a++,o--;i+=8}else a++,o--,i=0;return r}function wt(t,e,r,n){if(nyi)return Mt(t,e,r,n);var i=e[r++];if(2!=i)return Mt(t,e,r-1,n);if(t[0][1]=e[r++],t[0][2]=e[r++],i=e[r++],(t[0][2]<<8>>>0|i)>>>0!==n)return null;for(var i=0;i<4;i++)for(var a=0;a128){o=(127&o)>>>0;for(var s=e[r++];o--;)t[a++][i]=s}else for(;o--;)t[a++][i]=e[r++]}return r}function Ct(t){Ue.defaultsWithPropList(t,wi,Ci),Rt(t);for(var e="",r=0;r>16,r=t-(e<<8)>>8;return[e,r,t-(e<<16)-(r<<8)]}function se(t,e,r){return(t<<16)+(e<<8)+r}function ue(t){var e=t[1][0]-t[0][0],r=t[1][1]-t[0][1];return Math.sqrt(e*e+r*r)}function le(t){return[(t[0][0]+t[1][0])/2,(t[0][1]+t[1][1])/2]}function he(t){return Array.isArray(t)||(t=[t,t]),t}function ce(t,e){return{name:t.name,type:t.type,size:t.size,semantic:t.semantic,value:fe(t.value,e)}}function fe(t,e){return e?t:new t.constructor(t)}function de(t,e,r){return t*(1-r)+e*r}var pe={linear:function(t){return t},quadraticIn:function(t){return t*t},quadraticOut:function(t){return t*(2-t)},quadraticInOut:function(t){return(t*=2)<1?.5*t*t:-.5*(--t*(t-2)-1)},cubicIn:function(t){return t*t*t},cubicOut:function(t){return--t*t*t+1},cubicInOut:function(t){return(t*=2)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},quarticIn:function(t){return t*t*t*t},quarticOut:function(t){return 1- --t*t*t*t},quarticInOut:function(t){return(t*=2)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},quinticIn:function(t){return t*t*t*t*t},quinticOut:function(t){return--t*t*t*t*t+1},quinticInOut:function(t){return(t*=2)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},sinusoidalIn:function(t){return 1-Math.cos(t*Math.PI/2)},sinusoidalOut:function(t){return Math.sin(t*Math.PI/2)},sinusoidalInOut:function(t){return.5*(1-Math.cos(Math.PI*t))},exponentialIn:function(t){return 0===t?0:Math.pow(1024,t-1)},exponentialOut:function(t){return 1===t?1:1-Math.pow(2,-10*t)},exponentialInOut:function(t){return 0===t?0:1===t?1:(t*=2)<1?.5*Math.pow(1024,t-1):.5*(2-Math.pow(2,-10*(t-1)))},circularIn:function(t){return 1-Math.sqrt(1-t*t)},circularOut:function(t){return Math.sqrt(1- --t*t)},circularInOut:function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},elasticIn:function(t){var e,r=.1;return 0===t?0:1===t?1:(!r||r<1?(r=1,e=.1):e=.4*Math.asin(1/r)/(2*Math.PI),-r*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4))},elasticOut:function(t){var e,r=.1;return 0===t?0:1===t?1:(!r||r<1?(r=1,e=.1):e=.4*Math.asin(1/r)/(2*Math.PI),r*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/.4)+1)},elasticInOut:function(t){var e,r=.1;return 0===t?0:1===t?1:(!r||r<1?(r=1,e=.1):e=.4*Math.asin(1/r)/(2*Math.PI),(t*=2)<1?r*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4)*-.5:r*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4)*.5+1)},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){var e=1.70158;return--t*t*((e+1)*t+e)+1},backInOut:function(t){var e=2.5949095;return(t*=2)<1?t*t*((e+1)*t-e)*.5:.5*((t-=2)*t*((e+1)*t+e)+2)},bounceIn:function(t){return 1-pe.bounceOut(1-t)},bounceOut:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},bounceInOut:function(t){return t<.5?.5*pe.bounceIn(2*t):.5*pe.bounceOut(2*t-1)+.5}},me=function(t){t=t||{},this.name=t.name||"",this.target=t.target,this.life=t.life||1e3,this.delay=t.delay||0,this.gap=t.gap||0,this.playbackRate=t.playbackRate||1,this._initialized=!1,this._elapsedTime=0,this._loop=null!=t.loop&&t.loop,this.setLoop(this._loop),null!=t.easing&&this.setEasing(t.easing),this.onframe=t.onframe||e,this.onfinish=t.onfinish||e,this.onrestart=t.onrestart||e,this._paused=!1};me.prototype={gap:0,life:0,delay:0,setLoop:function(t){this._loop=t,t&&(this._loopRemained="number"==typeof t?t:1/0)},setEasing:function(t){"string"==typeof t&&(t=pe[t]),this.easing=t},step:function(t,e,r){if(this._initialized||(this._startTime=t+this.delay,this._initialized=!0),null!=this._currentTime&&(e=t-this._currentTime),this._currentTime=t,this._paused)return"paused";if(!(t0?(this._restartInLoop(t),this._loopRemained--,"restart"):(this._needsRemove=!0,"finish"):null}}},setTime:function(t){return this.step(t+this._startTime)},restart:function(t){var e=0;t&&(this._elapse(t),e=this._elapsedTime%this.life),t=t||Date.now(),this._startTime=t-e+this.delay,this._elapsedTime=0,this._needsRemove=!1,this._paused=!1},getElapsedTime:function(){return this._elapsedTime},_restartInLoop:function(t){this._startTime=t+this.gap,this._elapsedTime=0},_elapse:function(t,e){this._elapsedTime+=e*this.playbackRate},fire:function(t,e){var r="on"+t;this[r]&&this[r](this.target,e)},clone:function(){var t=new this.constructor;return t.name=this.name,t._loop=this._loop,t._loopRemained=this._loopRemained,t.life=this.life,t.gap=this.gap,t.delay=this.delay,t},pause:function(){this._paused=!0},resume:function(){this._paused=!1}},me.prototype.constructor=me;var _e=Array.prototype.slice;d.prototype={constructor:d,when:function(t,e,r){this._maxTime=Math.max(t,this._maxTime),r=("function"==typeof r?r:pe[r])||p;for(var n in e)this._tracks[n]||(this._tracks[n]=[],0!==t&&this._tracks[n].push({time:0,value:s(this._getter(this._target,n)),easing:r})),this._tracks[n].push({time:parseInt(t),value:e[n],easing:r});return this},then:function(t,e,r){return this.when(t+this._lastKFTime,e,r),this._lastKFTime+=t,this},during:function(t){return this._onframeList.push(t),this},_doneCallback:function(){this._tracks={},this._clipList.length=0;for(var t=this._doneList,e=t.length,r=0;rt)this.inputs.unshift(n);else if(this.inputs[i-1].position<=t)this.inputs.push(n);else{var a=this._findKey(t);this.inputs.splice(a,n)}return n},ve.prototype.step=function(t,e,r){var n=me.prototype.step.call(this,t);return"finish"!==n&&this.setTime(this.getElapsedTime()),r||"paused"===n||this.fire("frame"),n},ve.prototype.setTime=function(t){var e=this.position,r=this.inputs,n=r.length,i=r[0].position,a=r[n-1].position;if(e<=i||e>=a){var o=e<=i?r[0]:r[n-1],s=o.clip,u=o.offset;s.setTime((t+u)%s.life),s.output instanceof me?this.output.copy(s.output):this.output.copy(s)}else{var l=this._findKey(e),h=r[l],c=r[l+1],f=h.clip,d=c.clip;f.setTime((t+h.offset)%f.life),d.setTime((t+c.offset)%d.life);var p=(this.position-h.position)/(c.position-h.position),m=f.output instanceof me?f.output:f,_=d.output instanceof me?d.output:d;this.output.blend1D(m,_,p)}},ve.prototype.clone=function(t){var e=me.prototype.clone.call(this);e.output=this.output.clone();for(var r=0;r=r[i].position&&t=0;i--)t>=r[i].position&&t=0&&(this._cacheKey=e,this._cachePosition=t),e};var ye=1/1048576,Te={triangulate:function(t,e){var r,n,i,a,o,s,u,l,h,c,f,d,p=t.length;if(p<3)return[];if(t=t.slice(0),e)for(r=p;r--;)t[r]=t[r][e];for(i=new Array(p),r=p;r--;)i[r]=r;for(i.sort(function(e,r){var n=t[r][0]-t[e][0];return 0!==n?n:e-r}),a=m(t),t.push(a[0],a[1],a[2]),o=[_(t,p+0,p+1,p+2)],s=[],u=[],r=i.length;r--;u.length=0){for(d=i[r],n=o.length;n--;)l=t[d][0]-o[n].x,l>0&&l*l>o[n].r?(s.push(o[n]),o.splice(n,1)):(h=t[d][1]-o[n].y,l*l+h*h-o[n].r>ye||(u.push(o[n].i,o[n].j,o[n].j,o[n].k,o[n].k,o[n].i),o.splice(n,1)));for(g(u),n=u.length;n;)f=u[--n],c=u[--n],o.push(_(t,c,f,d))}for(r=o.length;r--;)s.push(o[r]);for(o.length=0,r=s.length;r--;)s[r].it[0][0]&&e[0]>t[1][0]&&e[0]>t[2][0]||e[1]t[0][1]&&e[1]>t[1][1]&&e[1]>t[2][1])return null;var r=t[1][0]-t[0][0],n=t[2][0]-t[0][0],i=t[1][1]-t[0][1],a=t[2][1]-t[0][1],o=r*a-n*i;if(0===o)return null;var s=(a*(e[0]-t[0][0])-n*(e[1]-t[0][1]))/o,u=(r*(e[1]-t[0][1])-i*(e[0]-t[0][0]))/o;return s<0||u<0||s+u>1?null:[s,u]}},xe=Array,Ee=Math.random,Ae={};Ae.create=function(){var t=new xe(2);return t[0]=0,t[1]=0,t},Ae.clone=function(t){var e=new xe(2);return e[0]=t[0],e[1]=t[1],e},Ae.fromValues=function(t,e){var r=new xe(2);return r[0]=t,r[1]=e,r},Ae.copy=function(t,e){return t[0]=e[0],t[1]=e[1],t},Ae.set=function(t,e,r){return t[0]=e,t[1]=r,t},Ae.add=function(t,e,r){return t[0]=e[0]+r[0],t[1]=e[1]+r[1],t},Ae.subtract=function(t,e,r){return t[0]=e[0]-r[0],t[1]=e[1]-r[1],t},Ae.sub=Ae.subtract,Ae.multiply=function(t,e,r){return t[0]=e[0]*r[0],t[1]=e[1]*r[1],t},Ae.mul=Ae.multiply,Ae.divide=function(t,e,r){return t[0]=e[0]/r[0],t[1]=e[1]/r[1],t},Ae.div=Ae.divide,Ae.min=function(t,e,r){return t[0]=Math.min(e[0],r[0]),t[1]=Math.min(e[1],r[1]),t},Ae.max=function(t,e,r){return t[0]=Math.max(e[0],r[0]),t[1]=Math.max(e[1],r[1]),t},Ae.scale=function(t,e,r){return t[0]=e[0]*r,t[1]=e[1]*r,t},Ae.scaleAndAdd=function(t,e,r,n){return t[0]=e[0]+r[0]*n,t[1]=e[1]+r[1]*n,t},Ae.distance=function(t,e){var r=e[0]-t[0],n=e[1]-t[1];return Math.sqrt(r*r+n*n)},Ae.dist=Ae.distance,Ae.squaredDistance=function(t,e){var r=e[0]-t[0],n=e[1]-t[1];return r*r+n*n},Ae.sqrDist=Ae.squaredDistance,Ae.length=function(t){var e=t[0],r=t[1];return Math.sqrt(e*e+r*r)},Ae.len=Ae.length,Ae.squaredLength=function(t){var e=t[0],r=t[1];return e*e+r*r},Ae.sqrLen=Ae.squaredLength,Ae.negate=function(t,e){return t[0]=-e[0],t[1]=-e[1],t},Ae.inverse=function(t,e){return t[0]=1/e[0],t[1]=1/e[1],t},Ae.normalize=function(t,e){var r=e[0],n=e[1],i=r*r+n*n;return i>0&&(i=1/Math.sqrt(i),t[0]=e[0]*i,t[1]=e[1]*i),t},Ae.dot=function(t,e){return t[0]*e[0]+t[1]*e[1]},Ae.cross=function(t,e,r){var n=e[0]*r[1]-e[1]*r[0];return t[0]=t[1]=0,t[2]=n,t},Ae.lerp=function(t,e,r,n){var i=e[0],a=e[1];return t[0]=i+n*(r[0]-i),t[1]=a+n*(r[1]-a),t},Ae.random=function(t,e){e=e||1;var r=2*GLMAT_RANDOM()*Math.PI;return t[0]=Math.cos(r)*e,t[1]=Math.sin(r)*e,t},Ae.transformMat2=function(t,e,r){var n=e[0],i=e[1];return t[0]=r[0]*n+r[2]*i,t[1]=r[1]*n+r[3]*i,t},Ae.transformMat2d=function(t,e,r){var n=e[0],i=e[1];return t[0]=r[0]*n+r[2]*i+r[4],t[1]=r[1]*n+r[3]*i+r[5],t},Ae.transformMat3=function(t,e,r){var n=e[0],i=e[1];return t[0]=r[0]*n+r[3]*i+r[6],t[1]=r[1]*n+r[4]*i+r[7],t},Ae.transformMat4=function(t,e,r){var n=e[0],i=e[1];return t[0]=r[0]*n+r[4]*i+r[12],t[1]=r[1]*n+r[5]*i+r[13],t},Ae.forEach=function(){var t=Ae.create();return function(e,r,n,i,a,o){var s,u;for(r||(r=2),n||(n=0),u=i?Math.min(i*r+n,e.length):e.length,s=n;s0&&(a=1/Math.sqrt(a),t[0]=e[0]*a,t[1]=e[1]*a,t[2]=e[2]*a),t},we.dot=function(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]},we.cross=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=r[0],s=r[1],u=r[2];return t[0]=i*u-a*s,t[1]=a*o-n*u,t[2]=n*s-i*o,t},we.lerp=function(t,e,r,n){var i=e[0],a=e[1],o=e[2];return t[0]=i+n*(r[0]-i),t[1]=a+n*(r[1]-a),t[2]=o+n*(r[2]-o),t},we.random=function(t,e){e=e||1;var r=2*Ee()*Math.PI,n=2*Ee()-1,i=Math.sqrt(1-n*n)*e;return t[0]=Math.cos(r)*i,t[1]=Math.sin(r)*i,t[2]=n*e,t},we.transformMat4=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=r[3]*n+r[7]*i+r[11]*a+r[15];return o=o||1,t[0]=(r[0]*n+r[4]*i+r[8]*a+r[12])/o,t[1]=(r[1]*n+r[5]*i+r[9]*a+r[13])/o,t[2]=(r[2]*n+r[6]*i+r[10]*a+r[14])/o,t},we.transformMat3=function(t,e,r){var n=e[0],i=e[1],a=e[2];return t[0]=n*r[0]+i*r[3]+a*r[6],t[1]=n*r[1]+i*r[4]+a*r[7],t[2]=n*r[2]+i*r[5]+a*r[8],t},we.transformQuat=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=r[0],s=r[1],u=r[2],l=r[3],h=l*n+s*a-u*i,c=l*i+u*n-o*a,f=l*a+o*i-s*n,d=-o*n-s*i-u*a;return t[0]=h*l+d*-o+c*-u-f*-s,t[1]=c*l+d*-s+f*-o-h*-u,t[2]=f*l+d*-u+h*-s-c*-o,t},we.rotateX=function(t,e,r,n){var i=[],a=[];return i[0]=e[0]-r[0],i[1]=e[1]-r[1],i[2]=e[2]-r[2],a[0]=i[0],a[1]=i[1]*Math.cos(n)-i[2]*Math.sin(n),a[2]=i[1]*Math.sin(n)+i[2]*Math.cos(n),t[0]=a[0]+r[0],t[1]=a[1]+r[1],t[2]=a[2]+r[2],t},we.rotateY=function(t,e,r,n){var i=[],a=[];return i[0]=e[0]-r[0],i[1]=e[1]-r[1],i[2]=e[2]-r[2],a[0]=i[2]*Math.sin(n)+i[0]*Math.cos(n),a[1]=i[1],a[2]=i[2]*Math.cos(n)-i[0]*Math.sin(n),t[0]=a[0]+r[0],t[1]=a[1]+r[1],t[2]=a[2]+r[2],t},we.rotateZ=function(t,e,r,n){var i=[],a=[];return i[0]=e[0]-r[0],i[1]=e[1]-r[1],i[2]=e[2]-r[2],a[0]=i[0]*Math.cos(n)-i[1]*Math.sin(n),a[1]=i[0]*Math.sin(n)+i[1]*Math.cos(n),a[2]=i[2],t[0]=a[0]+r[0],t[1]=a[1]+r[1],t[2]=a[2]+r[2],t},we.forEach=function(){var t=we.create();return function(e,r,n,i,a,o){var s,u;for(r||(r=3),n||(n=0),u=i?Math.min(i*r+n,e.length):e.length,s=n;s1?0:Math.acos(i)};var Ce={};Ce.create=function(){var t=new xe(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},Ce.clone=function(t){var e=new xe(4);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e},Ce.fromValues=function(t,e,r,n){var i=new xe(4);return i[0]=t,i[1]=e,i[2]=r,i[3]=n,i},Ce.copy=function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t},Ce.set=function(t,e,r,n,i){return t[0]=e,t[1]=r,t[2]=n,t[3]=i,t},Ce.add=function(t,e,r){return t[0]=e[0]+r[0],t[1]=e[1]+r[1],t[2]=e[2]+r[2],t[3]=e[3]+r[3],t},Ce.subtract=function(t,e,r){return t[0]=e[0]-r[0],t[1]=e[1]-r[1],t[2]=e[2]-r[2],t[3]=e[3]-r[3],t},Ce.sub=Ce.subtract,Ce.multiply=function(t,e,r){return t[0]=e[0]*r[0],t[1]=e[1]*r[1],t[2]=e[2]*r[2],t[3]=e[3]*r[3],t},Ce.mul=Ce.multiply,Ce.divide=function(t,e,r){return t[0]=e[0]/r[0],t[1]=e[1]/r[1],t[2]=e[2]/r[2],t[3]=e[3]/r[3],t},Ce.div=Ce.divide,Ce.min=function(t,e,r){return t[0]=Math.min(e[0],r[0]),t[1]=Math.min(e[1],r[1]),t[2]=Math.min(e[2],r[2]),t[3]=Math.min(e[3],r[3]),t},Ce.max=function(t,e,r){return t[0]=Math.max(e[0],r[0]),t[1]=Math.max(e[1],r[1]),t[2]=Math.max(e[2],r[2]),t[3]=Math.max(e[3],r[3]),t},Ce.scale=function(t,e,r){return t[0]=e[0]*r,t[1]=e[1]*r,t[2]=e[2]*r,t[3]=e[3]*r,t},Ce.scaleAndAdd=function(t,e,r,n){return t[0]=e[0]+r[0]*n,t[1]=e[1]+r[1]*n,t[2]=e[2]+r[2]*n,t[3]=e[3]+r[3]*n,t},Ce.distance=function(t,e){var r=e[0]-t[0],n=e[1]-t[1],i=e[2]-t[2],a=e[3]-t[3];return Math.sqrt(r*r+n*n+i*i+a*a)},Ce.dist=Ce.distance,Ce.squaredDistance=function(t,e){var r=e[0]-t[0],n=e[1]-t[1],i=e[2]-t[2],a=e[3]-t[3];return r*r+n*n+i*i+a*a},Ce.sqrDist=Ce.squaredDistance,Ce.length=function(t){var e=t[0],r=t[1],n=t[2],i=t[3];return Math.sqrt(e*e+r*r+n*n+i*i)},Ce.len=Ce.length,Ce.squaredLength=function(t){var e=t[0],r=t[1],n=t[2],i=t[3];return e*e+r*r+n*n+i*i},Ce.sqrLen=Ce.squaredLength,Ce.negate=function(t,e){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=-e[3],t},Ce.inverse=function(t,e){return t[0]=1/e[0],t[1]=1/e[1],t[2]=1/e[2],t[3]=1/e[3],t},Ce.normalize=function(t,e){var r=e[0],n=e[1],i=e[2],a=e[3],o=r*r+n*n+i*i+a*a;return o>0&&(o=1/Math.sqrt(o),t[0]=e[0]*o,t[1]=e[1]*o,t[2]=e[2]*o,t[3]=e[3]*o),t},Ce.dot=function(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]+t[3]*e[3]},Ce.lerp=function(t,e,r,n){var i=e[0],a=e[1],o=e[2],s=e[3];return t[0]=i+n*(r[0]-i),t[1]=a+n*(r[1]-a),t[2]=o+n*(r[2]-o),t[3]=s+n*(r[3]-s),t},Ce.random=function(t,e){return e=e||1,t[0]=Ee(),t[1]=Ee(),t[2]=Ee(),t[3]=Ee(),Ce.normalize(t,t),Ce.scale(t,t,e),t},Ce.transformMat4=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=e[3];return t[0]=r[0]*n+r[4]*i+r[8]*a+r[12]*o,t[1]=r[1]*n+r[5]*i+r[9]*a+r[13]*o,t[2]=r[2]*n+r[6]*i+r[10]*a+r[14]*o,t[3]=r[3]*n+r[7]*i+r[11]*a+r[15]*o,t},Ce.transformQuat=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=r[0],s=r[1],u=r[2],l=r[3],h=l*n+s*a-u*i,c=l*i+u*n-o*a,f=l*a+o*i-s*n,d=-o*n-s*i-u*a;return t[0]=h*l+d*-o+c*-u-f*-s,t[1]=c*l+d*-s+f*-o-h*-u,t[2]=f*l+d*-u+h*-s-c*-o,t},Ce.forEach=function(){var t=Ce.create();return function(e,r,n,i,a,o){var s,u;for(r||(r=4),n||(n=0),u=i?Math.min(i*r+n,e.length):e.length,s=n;s.999999?(n[0]=0,n[1]=0,n[2]=0,n[3]=1,n):(we.cross(t,i,a),n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=1+o,Le.normalize(n,n))}}(),Le.setAxes=function(){var t=Re.create();return function(e,r,n,i){return t[0]=n[0],t[3]=n[1],t[6]=n[2],t[1]=i[0],t[4]=i[1],t[7]=i[2],t[2]=-r[0],t[5]=-r[1],t[8]=-r[2],Le.normalize(e,Le.fromMat3(e,t))}}(),Le.clone=Ce.clone,Le.fromValues=Ce.fromValues,Le.copy=Ce.copy,Le.set=Ce.set,Le.identity=function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},Le.setAxisAngle=function(t,e,r){r*=.5;var n=Math.sin(r);return t[0]=n*e[0],t[1]=n*e[1],t[2]=n*e[2],t[3]=Math.cos(r),t},Le.add=Ce.add,Le.multiply=function(t,e,r){var n=e[0],i=e[1],a=e[2],o=e[3],s=r[0],u=r[1],l=r[2],h=r[3];return t[0]=n*h+o*s+i*l-a*u,t[1]=i*h+o*u+a*s-n*l,t[2]=a*h+o*l+n*u-i*s,t[3]=o*h-n*s-i*u-a*l,t},Le.mul=Le.multiply,Le.scale=Ce.scale,Le.rotateX=function(t,e,r){r*=.5;var n=e[0],i=e[1],a=e[2],o=e[3],s=Math.sin(r),u=Math.cos(r);return t[0]=n*u+o*s,t[1]=i*u+a*s,t[2]=a*u-i*s,t[3]=o*u-n*s,t},Le.rotateY=function(t,e,r){r*=.5;var n=e[0],i=e[1],a=e[2],o=e[3],s=Math.sin(r),u=Math.cos(r);return t[0]=n*u-a*s,t[1]=i*u+o*s,t[2]=a*u+n*s,t[3]=o*u-i*s,t},Le.rotateZ=function(t,e,r){r*=.5;var n=e[0],i=e[1],a=e[2],o=e[3],s=Math.sin(r),u=Math.cos(r);return t[0]=n*u+i*s,t[1]=i*u-n*s,t[2]=a*u+o*s,t[3]=o*u-a*s,t},Le.calculateW=function(t,e){var r=e[0],n=e[1],i=e[2];return t[0]=r,t[1]=n,t[2]=i,t[3]=Math.sqrt(Math.abs(1-r*r-n*n-i*i)),t},Le.dot=Ce.dot,Le.lerp=Ce.lerp,Le.slerp=function(t,e,r,n){var i,a,o,s,u,l=e[0],h=e[1],c=e[2],f=e[3],d=r[0],p=r[1],m=r[2],_=r[3];return a=l*d+h*p+c*m+f*_,a<0&&(a=-a,d=-d,p=-p,m=-m,_=-_),1-a>1e-6?(i=Math.acos(a),o=Math.sin(i),s=Math.sin((1-n)*i)/o,u=Math.sin(n*i)/o):(s=1-n,u=n),t[0]=s*l+u*d,t[1]=s*h+u*p,t[2]=s*c+u*m,t[3]=s*f+u*_,t},Le.invert=function(t,e){var r=e[0],n=e[1],i=e[2],a=e[3],o=r*r+n*n+i*i+a*a,s=o?1/o:0;return t[0]=-r*s,t[1]=-n*s,t[2]=-i*s,t[3]=a*s,t},Le.conjugate=function(t,e){return t[0]=-e[0],t[1]=-e[1],t[2]=-e[2],t[3]=e[3],t},Le.length=Ce.length,Le.len=Le.length,Le.squaredLength=Ce.squaredLength,Le.sqrLen=Le.squaredLength,Le.normalize=Ce.normalize,Le.fromMat3=function(t,e){var r,n=e[0]+e[4]+e[8];if(n>0)r=Math.sqrt(n+1),t[3]=.5*r,r=.5/r,t[0]=(e[5]-e[7])*r,t[1]=(e[6]-e[2])*r,t[2]=(e[1]-e[3])*r;else{var i=0;e[4]>e[0]&&(i=1),e[8]>e[3*i+i]&&(i=2);var a=(i+1)%3,o=(i+2)%3;r=Math.sqrt(e[3*i+i]-e[3*a+a]-e[3*o+o]+1),t[i]=.5*r,r=.5/r,t[3]=(e[3*a+o]-e[3*o+a])*r,t[a]=(e[3*a+i]+e[3*i+a])*r,t[o]=(e[3*o+i]+e[3*i+o])*r}return t};var Ne=function(t){t=t||{},this.name=t.name||"",this.target=t.target||null,this.position=we.create(),this.rotation=Le.create(),this.scale=we.fromValues(1,1,1),this.channels={time:null,position:null,rotation:null,scale:null},this._cacheKey=0,this._cacheTime=0};Ne.prototype.setTime=function(t){if(this.channels.time){var e=this.channels,r=e.time.length,n=-1;if(1===r)return e.rotation&&Le.copy(this.rotation,e.rotation),e.position&&we.copy(this.position,e.position),void(e.scale&&we.copy(this.scale,e.scale));if(t<=e.time[0])t=e.time[0],n=0;else if(t>=e.time[r-1])t=e.time[r-1],n=r-2;else if(t=0;a--)if(e.time[a-1]<=t&&e.time[a]>t){n=a-1;break}}else for(var a=this._cacheKey;at){n=a;break}if(n>-1){this._cacheKey=n,this._cacheTime=t;var o=n,s=n+1,u=e.time[o],l=e.time[s],h=l-u,c=0===h?0:(t-u)/h;e.rotation&&y(this.rotation,e.rotation,e.rotation,c,4*o,4*s),e.position&&v(this.position,e.position,e.position,c,3*o,3*s),e.scale&&v(this.scale,e.scale,e.scale,c,3*o,3*s)}n===r-2&&(this._cacheKey=0,this._cacheTime=0),this.updateTarget()}},Ne.prototype.updateTarget=function(){var t=this.channels;this.target&&(t.position&&this.target.position.setArray(this.position),t.rotation&&this.target.rotation.setArray(this.rotation),t.scale&&this.target.scale.setArray(this.scale))},Ne.prototype.getMaxTime=function(){return this.channels.time[this.channels.time.length-1]},Ne.prototype.getSubTrack=function(t,e){var r=new Ne({name:this.name}),n=this.channels.time[0];t=Math.min(Math.max(t,n),this.life),e=Math.min(Math.max(e,n),this.life);var i=this._findRange(t),a=this._findRange(e),o=a[0]-i[0]+1;0===i[1]&&0===a[1]&&(o-=1),this.channels.rotation&&(r.channels.rotation=new Float32Array(4*o)),this.channels.position&&(r.channels.position=new Float32Array(3*o)),this.channels.scale&&(r.channels.scale=new Float32Array(3*o)),this.channels.time&&(r.channels.time=new Float32Array(o)),this.setTime(t);for(var s=0;s<3;s++)r.channels.rotation[s]=this.rotation[s],r.channels.position[s]=this.position[s],r.channels.scale[s]=this.scale[s];r.channels.time[0]=0,r.channels.rotation[3]=this.rotation[3];for(var s=1;st&&(n=i);var a=0;if(n>=0)var o=e.time[n],s=e.time[n+1],a=(t-o)/(s-o);return[n,a]},Ne.prototype.blend1D=function(t,e,r){we.lerp(this.position,t.position,e.position,r),we.lerp(this.scale,t.scale,e.scale,r),Le.slerp(this.rotation,t.rotation,e.rotation,r)},Ne.prototype.blend2D=function(){var t=Le.create(),e=Le.create();return function(r,n,i,a,o){var s=1-a-o;this.position[0]=r.position[0]*s+n.position[0]*a+i.position[0]*o,this.position[1]=r.position[1]*s+n.position[1]*a+i.position[1]*o,this.position[2]=r.position[2]*s+n.position[2]*a+i.position[2]*o,this.scale[0]=r.scale[0]*s+n.scale[0]*a+i.scale[0]*o,this.scale[1]=r.scale[1]*s+n.scale[1]*a+i.scale[1]*o,this.scale[2]=r.scale[2]*s+n.scale[2]*a+i.scale[2]*o;var u=a+o;0===u?Le.copy(this.rotation,r.rotation):(Le.slerp(t,r.rotation,n.rotation,u),Le.slerp(e,r.rotation,i.rotation,u),Le.slerp(this.rotation,t,e,o/u))}}(),Ne.prototype.additiveBlend=function(t,e){we.add(this.position,t.position,e.position),we.add(this.scale,t.scale,e.scale),Le.multiply(this.rotation,e.rotation,t.rotation)},Ne.prototype.subtractiveBlend=function(t,e){we.sub(this.position,t.position,e.position),we.sub(this.scale,t.scale,e.scale),Le.invert(this.rotation,e.rotation),Le.multiply(this.rotation,this.rotation,t.rotation)},Ne.prototype.clone=function(){var t=Ne.prototype.clone.call(this);return t.channels={time:this.channels.time||null,position:this.channels.position||null,rotation:this.channels.rotation||null,scale:this.channels.scale||null},we.copy(t.position,this.position),Le.copy(t.rotation,this.rotation),we.copy(t.scale,this.scale),t.target=this.target,t.updateTarget(),t};var Pe={extend:T,derive:T},Ie={trigger:function(t){if(this.hasOwnProperty("__handlers__")&&this.__handlers__.hasOwnProperty(t)){var e=this.__handlers__[t],r=e.length,n=-1,i=arguments;switch(i.length){case 1:for(;++n=0&&this._clips.splice(e,1)},removeAnimator:function(t){for(var e=t.getClips(),r=0;r=0&&this.tracks.splice(e,1)},ze.prototype.getSubClip=function(t,e,r){for(var n=new ze({name:this.name}),i=0;i=this._maxSize&&r>0){var n=this._list.head;this._list.remove(n),delete this._map[n.key]}var i=this._list.insert(e);i.key=t,this._map[t]=i}},Ke.prototype.get=function(t){var e=this._map[t];if(this._map.hasOwnProperty(t))return e!==this._list.tail&&(this._list.remove(e),this._list.insertEntry(e)),e.value},Ke.prototype.remove=function(t){var e=this._map[t];void 0!==e&&(delete this._map[t],this._list.remove(e))},Ke.prototype.clear=function(){this._list.clear(),this._map={}};var Ze={},Je={transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]},Qe=new Ke(20),$e=null;Ze.parse=function(t,e){if(t){e=e||[];var r=Qe.get(t);if(r)return O(e,r);t+="";var n=t.replace(/ /g,"").toLowerCase();if(n in Je)return O(e,Je[n]),D(t,e),e;if("#"!==n.charAt(0)){var i=n.indexOf("("),a=n.indexOf(")");if(-1!==i&&a+1===n.length){var o=n.substr(0,i),s=n.substr(i+1,a-(i+1)).split(","),u=1;switch(o){case"rgba":if(4!==s.length)return void I(e,0,0,0,1);u=L(s.pop());case"rgb":return 3!==s.length?void I(e,0,0,0,1):(I(e,R(s[0]),R(s[1]),R(s[2]),u),D(t,e),e);case"hsla":return 4!==s.length?void I(e,0,0,0,1):(s[3]=L(s[3]),B(s,e),D(t,e),e);case"hsl":return 3!==s.length?void I(e,0,0,0,1):(B(s,e),D(t,e),e);default:return}}I(e,0,0,0,1)}else{if(4===n.length){var l=parseInt(n.substr(1),16);return l>=0&&l<=4095?(I(e,(3840&l)>>4|(3840&l)>>8,240&l|(240&l)>>4,15&l|(15&l)<<4,1),D(t,e),e):void I(e,0,0,0,1)}if(7===n.length){var l=parseInt(n.substr(1),16);return l>=0&&l<=16777215?(I(e,(16711680&l)>>16,(65280&l)>>8,255&l,1),D(t,e),e):void I(e,0,0,0,1)}}}},Ze.parseToFloat=function(t,e){if(e=Ze.parse(t,e))return e[0]/=255,e[1]/=255,e[2]/=255,e},Ze.lift=function(t,e){var r=Ze.parse(t);if(r){for(var n=0;n<3;n++)r[n]=e<0?r[n]*(1-e)|0:(255-r[n])*e+r[n]|0;return Ze.stringify(r,4===r.length?"rgba":"rgb")}},Ze.toHex=function(t){var e=Ze.parse(t);if(e)return((1<<24)+(e[0]<<16)+(e[1]<<8)+ +e[2]).toString(16).slice(1)},Ze.fastLerp=function(t,e,r){if(e&&e.length&&t>=0&&t<=1){r=r||[];var n=t*(e.length-1),i=Math.floor(n),a=Math.ceil(n),o=e[i],s=e[a],u=n-i;return r[0]=M(P(o[0],s[0],u)),r[1]=M(P(o[1],s[1],u)),r[2]=M(P(o[2],s[2],u)),r[3]=C(P(o[3],s[3],u)),r}},Ze.fastMapToColor=Ze.fastLerp,Ze.lerp=function(t,e,r){if(e&&e.length&&t>=0&&t<=1){var n=t*(e.length-1),i=Math.floor(n),a=Math.ceil(n),o=Ze.parse(e[i]),s=Ze.parse(e[a]),u=n-i,l=Ze.stringify([M(P(o[0],s[0],u)),M(P(o[1],s[1],u)),M(P(o[2],s[2],u)),C(P(o[3],s[3],u))],"rgba");return r?{color:l,leftIndex:i,rightIndex:a,value:n}:l}},Ze.mapToColor=Ze.lerp,Ze.modifyHSL=function(t,e,r,n){if(t=Ze.parse(t))return t=U(t),null!=e&&(t[0]=w(e)),null!=r&&(t[1]=L(r)),null!=n&&(t[2]=L(n)),Ze.stringify(B(t),"rgba")},Ze.modifyAlpha=function(t,e){if((t=Ze.parse(t))&&null!=e)return t[3]=C(e),Ze.stringify(t,"rgba")},Ze.stringify=function(t,e){if(t&&t.length){var r=t[0]+","+t[1]+","+t[2];return"rgba"!==e&&"hsva"!==e&&"hsla"!==e||(r+=","+t[3]),e+"("+r+")"}};var tr=Ze.parseToFloat,er={},rr=Fe.extend(function(){return{name:"",depthTest:!0,depthMask:!0,transparent:!1,blend:null,autoUpdateTextureStatus:!0,uniforms:{},vertexDefines:{},fragmentDefines:{},_textureStatus:{},_enabledUniforms:null}},function(){this.name||(this.name="MATERIAL_"+this.__uid__),this.shader&&this.attachShader(this.shader,!0)},{precision:"highp",setUniform:function(t,e){void 0===e&&console.warn('Uniform value "'+t+'" is undefined');var r=this.uniforms[t];r&&("string"==typeof e&&(e=tr(e)||e),r.value=e,this.autoUpdateTextureStatus&&"t"===r.type&&(e?this.enableTexture(t):this.disableTexture(t)))},setUniforms:function(t){for(var e in t){var r=t[e];this.setUniform(e,r)}},isUniformEnabled:function(t){return this._enabledUniforms.indexOf(t)>=0},getEnabledUniforms:function(){return this._enabledUniforms},getTextureUniforms:function(){return this._textureUniforms},set:function(t,e){if("object"==typeof t)for(var r in t){var n=t[r];this.setUniform(r,n)}else this.setUniform(t,e)},get:function(t){var e=this.uniforms[t];if(e)return e.value},attachShader:function(t,e){var r=this.uniforms;this.uniforms=t.createUniforms(),this.shader=t;var n=this.uniforms;this._enabledUniforms=Object.keys(n),this._enabledUniforms.sort(),this._textureUniforms=this._enabledUniforms.filter(function(t){var e=this.uniforms[t].type;return"t"===e||"tv"===e},this);var i=this.vertexDefines,a=this.fragmentDefines;if(this.vertexDefines=Ue.clone(t.vertexDefines),this.fragmentDefines=Ue.clone(t.fragmentDefines),e){for(var o in r)n[o]&&(n[o].value=r[o].value);Ue.defaults(this.vertexDefines,i),Ue.defaults(this.fragmentDefines,a)}var s={};for(var u in t.textures)s[u]={shaderType:t.textures[u].shaderType,type:t.textures[u].type,enabled:!(!e||!this._textureStatus[u])&&this._textureStatus[u].enabled};this._textureStatus=s,this._programKey=""},clone:function(){var t=new this.constructor({name:this.name,shader:this.shader});for(var e in this.uniforms)t.uniforms[e].value=this.uniforms[e].value;return t.depthTest=this.depthTest,t.depthMask=this.depthMask,t.transparent=this.transparent,t.blend=this.blend,t.vertexDefines=Ue.clone(this.vertexDefines),t.fragmentDefines=Ue.clone(this.fragmentDefines),t.enableTexture(this.getEnabledTextures()),t.precision=this.precision,t},define:function(t,e,r){var n=this.vertexDefines,i=this.fragmentDefines;"vertex"!==t&&"fragment"!==t&&"both"!==t&&arguments.length<3&&(r=e,e=t,t="both"),r=null!=r?r:null,"vertex"!==t&&"both"!==t||n[e]!==r&&(n[e]=r,this._programKey=""),"fragment"!==t&&"both"!==t||i[e]!==r&&(i[e]=r,"both"!==t&&(this._programKey=""))},undefine:function(t,e){"vertex"!==t&&"fragment"!==t&&"both"!==t&&arguments.length<2&&(e=t,t="both"),"vertex"!==t&&"both"!==t||this.isDefined("vertex",e)&&(delete this.vertexDefines[e],this._programKey=""),"fragment"!==t&&"both"!==t||this.isDefined("fragment",e)&&(delete this.fragmentDefines[e],"both"!==t&&(this._programKey=""))},isDefined:function(t,e){switch(t){case"vertex":return void 0!==this.vertexDefines[e];case"fragment":return void 0!==this.fragmentDefines[e]}},getDefine:function(t,e){switch(t){case"vertex":return this.vertexDefines[e];case"fragment":return this.fragmentDefines[e]}},enableTexture:function(t){if(Array.isArray(t))for(var e=0;eu.getMaxJointNumber()&&(f.USE_SKIN_MATRICES_TEXTURE=null),c="\n"+W(f)+"\n"}var d=c+W(e.vertexDefines,s,h),p=c+W(e.fragmentDefines,s,h),m=d+"\n"+e.shader.vertex,_=["OES_standard_derivatives","EXT_shader_texture_lod"].filter(function(t){return null!=u.getGLExtension(t)});_.indexOf("EXT_shader_texture_lod")>=0&&(p+="\n#define SUPPORT_TEXTURE_LOD"),_.indexOf("OES_standard_derivatives")>=0&&(p+="\n#define SUPPORT_STANDARD_DERIVATIVES");var g=z(_)+"\n"+X(e.precision)+"\n"+p+"\n"+e.shader.fragment,v=V(m,e.vertexDefines,s),y=V(g,e.fragmentDefines,s),o=new ar;o.uniformSemantics=e.shader.uniformSemantics,o.attributes=e.shader.attributes;var T=o.buildProgram(l,e.shader,v,y);return o.__error=T,n[a]=o,o};var sr=/uniform\s+(bool|float|int|vec2|vec3|vec4|ivec2|ivec3|ivec4|mat2|mat3|mat4|sampler2D|samplerCube)\s+([\s\S]*?);/g,ur=/attribute\s+(float|int|vec2|vec3|vec4)\s+([\s\S]*?);/g,lr=/#define\s+(\w+)?(\s+[\d-.]+)?\s*;?\s*\n/g,hr={bool:"1i",int:"1i",sampler2D:"t",samplerCube:"t",float:"1f",vec2:"2f",vec3:"3f",vec4:"4f",ivec2:"2i",ivec3:"3i",ivec4:"4i",mat2:"m2",mat3:"m3",mat4:"m4"},cr={bool:function(){return!0},int:function(){return 0},float:function(){return 0},sampler2D:function(){return null},samplerCube:function(){return null},vec2:function(){return q(2)},vec3:function(){return q(3)},vec4:function(){return q(4)},ivec2:function(){return q(2)},ivec3:function(){return q(3)},ivec4:function(){return q(4)},mat2:function(){return q(4)},mat3:function(){return q(9)},mat4:function(){return q(16)},array:function(){return[]}},fr=["POSITION","NORMAL","BINORMAL","TANGENT","TEXCOORD","TEXCOORD_0","TEXCOORD_1","COLOR","JOINT","WEIGHT"],dr=["SKIN_MATRIX","VIEWPORT_SIZE","VIEWPORT","DEVICEPIXELRATIO","WINDOW_SIZE","NEAR","FAR","TIME"],pr=["WORLD","VIEW","PROJECTION","WORLDVIEW","VIEWPROJECTION","WORLDVIEWPROJECTION","WORLDINVERSE","VIEWINVERSE","PROJECTIONINVERSE","WORLDVIEWINVERSE","VIEWPROJECTIONINVERSE","WORLDVIEWPROJECTIONINVERSE","WORLDTRANSPOSE","VIEWTRANSPOSE","PROJECTIONTRANSPOSE","WORLDVIEWTRANSPOSE","VIEWPROJECTIONTRANSPOSE","WORLDVIEWPROJECTIONTRANSPOSE","WORLDINVERSETRANSPOSE","VIEWINVERSETRANSPOSE","PROJECTIONINVERSETRANSPOSE","WORLDVIEWINVERSETRANSPOSE","VIEWPROJECTIONINVERSETRANSPOSE","WORLDVIEWPROJECTIONINVERSETRANSPOSE"],mr={vec4:4,vec3:3,vec2:2,float:1},_r={},gr={};Q.prototype={constructor:Q,createUniforms:function(){var t={};for(var e in this.uniformTemplates){var r=this.uniformTemplates[e];t[e]={type:r.type,value:r.value()}}return t},_parseImport:function(){this._vertexCode=Q.parseImport(this.vertex),this._fragmentCode=Q.parseImport(this.fragment)},_addSemanticUniform:function(t,e,r){if(fr.indexOf(r)>=0)this.attributeSemantics[r]={symbol:t,type:e};else if(pr.indexOf(r)>=0){var n=!1,i=r;r.match(/TRANSPOSE$/)&&(n=!0,i=r.slice(0,-9)),this.matrixSemantics[r]={symbol:t,type:e,isTranspose:n,semanticNoTranspose:i}}else dr.indexOf(r)>=0&&(this.uniformSemantics[r]={symbol:t,type:e})},_addMaterialUniform:function(t,e,r,n,i,a){a[t]={type:r,value:i?cr.array:n||cr[e],semantic:null}},_parseUniforms:function(){function t(t){return null!=t?function(){return t}:null}function e(e,a,o){var s=J(a,o),u=[];for(var l in s){var h=s[l],c=h.semantic,f=l,d=hr[a],p=t(s[l].value);s[l].isArray&&(f+="["+s[l].arraySize+"]",d+="v"),u.push(f),n._uniformList.push(l),h.ignore||("sampler2D"!==a&&"samplerCube"!==a||(n.textures[l]={shaderType:i,type:a}),c?n._addSemanticUniform(l,d,c):n._addMaterialUniform(l,a,d,p,s[l].isArray,r))}return u.length>0?"uniform "+a+" "+u.join(",")+";\n":""}var r={},n=this,i="vertex";this._uniformList=[],this._vertexCode=this._vertexCode.replace(sr,e),i="fragment",this._fragmentCode=this._fragmentCode.replace(sr,e),n.matrixSemanticKeys=Object.keys(this.matrixSemantics),this.uniformTemplates=r},_parseAttributes:function(){function t(t,n,i){var a=J(n,i),o=mr[n]||1,s=[];for(var u in a){var l=a[u].semantic;if(e[u]={type:"float",size:o,semantic:l||null},l){if(fr.indexOf(l)<0)throw new Error('Unkown semantic "'+l+'"');r.attributeSemantics[l]={symbol:u,type:n}}s.push(u)}return"attribute "+n+" "+s.join(",")+";\n"}var e={},r=this;this._vertexCode=this._vertexCode.replace(ur,t),this.attributes=e},_parseDefines:function(){function t(t,n,i){var a="vertex"===r?e.vertexDefines:e.fragmentDefines;return a[n]||(a[n]="false"!==i&&("true"===i||(i?isNaN(parseFloat(i))?i.trim():parseFloat(i):null))),""}var e=this,r="vertex";this._vertexCode=this._vertexCode.replace(lr,t),r="fragment",this._fragmentCode=this._fragmentCode.replace(lr,t)},clone:function(){var t=gr[this._shaderID];return new Q(t.vertex,t.fragment)}},Object.defineProperty&&(Object.defineProperty(Q.prototype,"shaderID",{get:function(){return this._shaderID}}),Object.defineProperty(Q.prototype,"vertex",{get:function(){return this._vertexCode}}),Object.defineProperty(Q.prototype,"fragment",{get:function(){return this._fragmentCode}}),Object.defineProperty(Q.prototype,"uniforms",{get:function(){return this._uniformList}}));var vr=/(@import)\s*([0-9a-zA-Z_\-\.]*)/g;Q.parseImport=function(t){return t=t.replace(vr,function(t,e,r){var t=Q.source(r) +;return t?Q.parseImport(t):(console.error('Shader chunk "'+r+'" not existed in library'),"")})};var yr=/(@export)\s*([0-9a-zA-Z_\-\.]*)\s*\n([\s\S]*?)@end/g;Q.import=function(t){t.replace(yr,function(t,e,r,n){var n=n.replace(/(^[\s\t\xa0\u3000]+)|([\u3000\xa0\s\t]+\x24)/g,"");if(n){for(var i,a=r.split("."),o=Q.codes,s=0;s0&&this.setViewport(this._viewportStack.pop())},saveClear:function(){this._clearStack.push({clearBit:this.clearBit,clearColor:this.clearColor})},restoreClear:function(){if(this._clearStack.length>0){var t=this._clearStack.pop();this.clearColor=t.clearColor,this.clearBit=t.clearBit}},bindSceneRendering:function(t){this._sceneRendering=t},render:function(t,e,r,n){var i=this.gl,a=this.clearColor;if(this.clearBit){i.colorMask(!0,!0,!0,!0),i.depthMask(!0);var o=this.viewport,s=!1,u=o.devicePixelRatio;(o.width!==this._width||o.height!==this._height||u&&u!==this.devicePixelRatio||o.x||o.y)&&(s=!0,i.enable(i.SCISSOR_TEST),i.scissor(o.x*u,o.y*u,o.width*u,o.height*u)),i.clearColor(a[0],a[1],a[2],a[3]),i.clear(this.clearBit),s&&i.disable(i.SCISSOR_TEST)}if(r||t.update(!1),t.updateLights(),!(e=e||t.getMainCamera()))return void console.error("Can't find camera in the scene.");e.update();var l=t.updateRenderList(e,!0);this._sceneRendering=t;var h=l.opaque,c=l.transparent,f=t.material;t.trigger("beforerender",this,t,e,l),n?(this.renderPreZ(h,t,e),i.depthFunc(i.LEQUAL)):i.depthFunc(i.LESS);for(var d=Er(),p=we.create(),m=0;m0){var s=t[i-1],u=s.joints?s.joints.length:0;if((a.joints?a.joints.length:0)===u&&a.material===s.material&&a.lightGroup===s.lightGroup){a.__program=s.__program;continue}}var l=this._programMgr.getProgram(a,o,e);this.validateProgram(l),a.__program=l}},renderPass:function(t,e,r){this.trigger("beforerenderpass",this,t,e,r),r=r||{},r.getMaterial=r.getMaterial||$,r.getUniform=r.getUniform||tt,r.isMaterialChanged=r.isMaterialChanged||et,r.beforeRender=r.beforeRender||nt,r.afterRender=r.afterRender||nt;var n=r.ifRender||rt;this.updatePrograms(t,this._sceneRendering,r),r.sortCompare&&t.sort(r.sortCompare);var i=this.viewport,a=i.devicePixelRatio,o=[i.x*a,i.y*a,i.width*a,i.height*a],s=this.devicePixelRatio,u=this.__currentFrameBuffer?[this.__currentFrameBuffer.getTextureWidth(),this.__currentFrameBuffer.getTextureHeight()]:[this._width*s,this._height*s],l=[o[2],o[3]],h=Date.now();e?(xr.copy(Mr.VIEW,e.viewMatrix.array),xr.copy(Mr.PROJECTION,e.projectionMatrix.array),xr.copy(Mr.VIEWINVERSE,e.worldTransform.array)):(xr.identity(Mr.VIEW),xr.identity(Mr.PROJECTION),xr.identity(Mr.VIEWINVERSE)),xr.multiply(Mr.VIEWPROJECTION,Mr.PROJECTION,Mr.VIEW),xr.invert(Mr.PROJECTIONINVERSE,Mr.PROJECTION),xr.invert(Mr.VIEWPROJECTIONINVERSE,Mr.VIEWPROJECTION);for(var c,f,d,p,m,_,g,v,y,T,x,E,A=this.gl,b=this._sceneRendering,S=null,M=0;Mthis._glinfo.getMaxJointNumber()){var a=i.getSubSkinMatricesTexture(t.__uid__,t.joints);e.useTextureSlot(this,a,r),e.setUniform(n,"1i","skinMatricesTexture",r),e.setUniform(n,"1f","skinMatricesTextureSize",a.width)}else{var o=i.getSubSkinMatrices(t.__uid__,t.joints);e.setUniformOfSemantic(n,"SKIN_MATRIX",o)}},_renderObject:function(t,e){var r=this.gl,n=t.geometry,i=t.mode;if(null==i&&(i=4),e.indicesBuffer){var a=this.getGLExtension("OES_element_index_uint"),o=a&&n.indices instanceof Uint32Array,s=o?r.UNSIGNED_INT:r.UNSIGNED_SHORT;r.drawElements(i,e.indicesBuffer.count,s,0)}else r.drawArrays(i,0,n.vertexCount)},_bindMaterial:function(t,e,r,n,i,a,o){for(var s=this.gl,u=a===r,l=r.currentTextureSlot(),h=e.getEnabledUniforms(),c=e.getTextureUniforms(),f=this._placeholderTexture,d=0;d0){var e=this.min,r=this.max,n=e.array,i=r.array;Hr(n,t[0]),Hr(i,t[0]);for(var a=1;ai[0]&&(i[0]=o[0]),o[1]>i[1]&&(i[1]=o[1]),o[2]>i[2]&&(i[2]=o[2])}e._dirty=!0,r._dirty=!0}},union:function(t){var e=this.min,r=this.max;return we.min(e.array,e.array,t.min.array),we.max(r.array,r.array,t.max.array),e._dirty=!0,r._dirty=!0,this},intersection:function(t){var e=this.min,r=this.max;return we.max(e.array,e.array,t.min.array),we.min(r.array,r.array,t.max.array),e._dirty=!0,r._dirty=!0,this},intersectBoundingBox:function(t){var e=this.min.array,r=this.max.array,n=t.min.array,i=t.max.array;return!(e[0]>i[0]||e[1]>i[1]||e[2]>i[2]||r[0]=i[0]&&r[1]>=i[1]&&r[2]>=i[2]},containPoint:function(t){var e=this.min.array,r=this.max.array,n=t.array;return e[0]<=n[0]&&e[1]<=n[1]&&e[2]<=n[2]&&r[0]>=n[0]&&r[1]>=n[1]&&r[2]>=n[2]},isFinite:function(){var t=this.min.array,e=this.max.array;return isFinite(t[0])&&isFinite(t[1])&&isFinite(t[2])&&isFinite(e[0])&&isFinite(e[1])&&isFinite(e[2])},applyTransform:function(t){this.transformFrom(this,t)},transformFrom:function(){var t=we.create(),e=we.create(),r=we.create(),n=we.create(),i=we.create(),a=we.create();return function(o,s){var u=o.min.array,l=o.max.array,h=s.array;return t[0]=h[0]*u[0],t[1]=h[1]*u[0],t[2]=h[2]*u[0],e[0]=h[0]*l[0],e[1]=h[1]*l[0],e[2]=h[2]*l[0],r[0]=h[4]*u[1],r[1]=h[5]*u[1],r[2]=h[6]*u[1],n[0]=h[4]*l[1],n[1]=h[5]*l[1],n[2]=h[6]*l[1],i[0]=h[8]*u[2],i[1]=h[9]*u[2],i[2]=h[10]*u[2],a[0]=h[8]*l[2],a[1]=h[9]*l[2],a[2]=h[10]*l[2],u=this.min.array,l=this.max.array,u[0]=Math.min(t[0],e[0])+Math.min(r[0],n[0])+Math.min(i[0],a[0])+h[12],u[1]=Math.min(t[1],e[1])+Math.min(r[1],n[1])+Math.min(i[1],a[1])+h[13],u[2]=Math.min(t[2],e[2])+Math.min(r[2],n[2])+Math.min(i[2],a[2])+h[14],l[0]=Math.max(t[0],e[0])+Math.max(r[0],n[0])+Math.max(i[0],a[0])+h[12],l[1]=Math.max(t[1],e[1])+Math.max(r[1],n[1])+Math.max(i[1],a[1])+h[13],l[2]=Math.max(t[2],e[2])+Math.max(r[2],n[2])+Math.max(i[2],a[2])+h[14],this.min._dirty=!0,this.max._dirty=!0,this}}(),applyProjection:function(t){var e=this.min.array,r=this.max.array,n=t.array,i=e[0],a=e[1],o=e[2],s=r[0],u=r[1],l=e[2],h=r[0],c=r[1],f=r[2];if(1===n[15])e[0]=n[0]*i+n[12],e[1]=n[5]*a+n[13],r[2]=n[10]*o+n[14],r[0]=n[0]*h+n[12],r[1]=n[5]*c+n[13],e[2]=n[10]*f+n[14];else{var d=-1/o;e[0]=n[0]*i*d,e[1]=n[5]*a*d,r[2]=(n[10]*o+n[14])*d,d=-1/l,r[0]=n[0]*s*d,r[1]=n[5]*u*d,d=-1/f,e[2]=(n[10]*f+n[14])*d}return this.min._dirty=!0,this.max._dirty=!0,this},updateVertices:function(){var t=this.vertices;if(!t){t=[];for(var e=0;e<8;e++)t[e]=we.fromValues(0,0,0);this.vertices=t}var r=this.min.array,n=this.max.array;return kr(t[0],r[0],r[1],r[2]),kr(t[1],r[0],n[1],r[2]),kr(t[2],n[0],r[1],r[2]),kr(t[3],n[0],n[1],r[2]),kr(t[4],r[0],r[1],n[2]),kr(t[5],r[0],n[1],n[2]),kr(t[6],n[0],r[1],n[2]),kr(t[7],n[0],n[1],n[2]),this},copy:function(t){var e=this.min,r=this.max;return Hr(e.array,t.min.array),Hr(r.array,t.max.array),e._dirty=!0,r._dirty=!0,this},clone:function(){var t=new Gr;return t.copy(this),t}};var Vr=0,Wr=Fe.extend({name:"",position:null,rotation:null,scale:null,worldTransform:null,localTransform:null,autoUpdateLocalTransform:!0,_parent:null,_scene:null,_needsUpdateWorldTransform:!0,_inIterating:!1,__depth:0},function(){this.name||(this.name=(this.type||"NODE")+"_"+Vr++),this.position||(this.position=new wr),this.rotation||(this.rotation=new Ir),this.scale||(this.scale=new wr(1,1,1)),this.worldTransform=new Br,this.localTransform=new Br,this._children=[]},{target:null,invisible:!1,isSkinnedMesh:function(){return!1},isRenderable:function(){return!1},setName:function(t){var e=this._scene;if(e){var r=e._nodeRepository;delete r[this.name],r[t]=this}this.name=t},add:function(t){var e=t._parent;if(e!==this){e&&e.remove(t),t._parent=this,this._children.push(t);var r=this._scene;r&&r!==t.scene&&t.traverse(this._addSelfToScene,this),t._needsUpdateWorldTransform=!0}},remove:function(t){var e=this._children,r=e.indexOf(t);r<0||(e.splice(r,1),t._parent=null,this._scene&&t.traverse(this._removeSelfFromScene,this))},removeAll:function(){for(var t=this._children,e=0;ethis.distance,i=1;i<8;i++)if(we.dot(e[i].array,r)>this.distance!=n)return!0},intersectLine:function(){var t=we.create();return function(e,r,n){var i=this.distanceToPoint(e),a=this.distanceToPoint(r);if(i>0&&a>0||i<0&&a<0)return null;var o=this.normal.array,s=this.distance,u=e.array;we.sub(t,r.array,e.array),we.normalize(t,t);var l=we.dot(o,t);if(0===l)return null;n||(n=new wr);var h=(we.dot(o,u)-s)/l;return we.scaleAndAdd(n.array,u,t,-h),n._dirty=!0,n}}(),applyTransform:function(){var t=xr.create(),e=Ce.create(),r=Ce.create();return r[3]=1,function(n){n=n.array,we.scale(r,this.normal.array,this.distance),Ce.transformMat4(r,r,n),this.distance=we.dot(r,this.normal.array),xr.invert(t,n),xr.transpose(t,t),e[3]=0,we.copy(e,this.normal.array),Ce.transformMat4(e,e,t),we.copy(this.normal.array,e)}}(),copy:function(t){we.copy(this.normal.array,t.normal.array),this.normal._dirty=!0,this.distance=t.distance},clone:function(){var t=new qr;return t.copy(this),t}};var Yr=we.set,Kr=we.copy,Zr=we.transformMat4,Jr=Math.min,Qr=Math.max,$r=function(){this.planes=[];for(var t=0;t<6;t++)this.planes.push(new qr);this.boundingBox=new Gr,this.vertices=[];for(var t=0;t<8;t++)this.vertices[t]=we.fromValues(0,0,0)};$r.prototype={setFromProjection:function(t){var e=this.planes,r=t.array,n=r[0],i=r[1],a=r[2],o=r[3],s=r[4],u=r[5],l=r[6],h=r[7],c=r[8],f=r[9],d=r[10],p=r[11],m=r[12],_=r[13],g=r[14],v=r[15];Yr(e[0].normal.array,o-n,h-s,p-c),e[0].distance=-(v-m),e[0].normalize(),Yr(e[1].normal.array,o+n,h+s,p+c),e[1].distance=-(v+m),e[1].normalize(),Yr(e[2].normal.array,o+i,h+u,p+f),e[2].distance=-(v+_),e[2].normalize(),Yr(e[3].normal.array,o-i,h-u,p-f),e[3].distance=-(v-_),e[3].normalize(),Yr(e[4].normal.array,o-a,h-l,p-d),e[4].distance=-(v-g),e[4].normalize(),Yr(e[5].normal.array,o+a,h+l,p+d),e[5].distance=-(v+g),e[5].normalize();var y=this.boundingBox,T=this.vertices;if(0===v){var x=u/n,E=-g/(d-1),A=-g/(d+1),b=-A/u,S=-E/u;y.min.set(-b*x,-b,A),y.max.set(b*x,b,E),Yr(T[0],-b*x,-b,A),Yr(T[1],-b*x,b,A),Yr(T[2],b*x,-b,A),Yr(T[3],b*x,b,A),Yr(T[4],-S*x,-S,E),Yr(T[5],-S*x,S,E),Yr(T[6],S*x,-S,E),Yr(T[7],S*x,S,E)}else{var M=(-1-m)/n,w=(1-m)/n,C=(1-_)/u,R=(-1-_)/u,L=(-1-g)/d,N=(1-g)/d;y.min.set(Math.min(M,w),Math.min(R,C),Math.min(N,L)),y.max.set(Math.max(w,M),Math.max(C,R),Math.max(L,N));var P=y.min.array,I=y.max.array;Yr(T[0],P[0],P[1],P[2]),Yr(T[1],P[0],I[1],P[2]),Yr(T[2],I[0],P[1],P[2]),Yr(T[3],I[0],I[1],P[2]),Yr(T[4],P[0],P[1],I[2]),Yr(T[5],P[0],I[1],I[2]),Yr(T[6],I[0],P[1],I[2]),Yr(T[7],I[0],I[1],I[2])}},getTransformedBoundingBox:function(){var t=we.create();return function(e,r){var n=this.vertices,i=r.array,a=e.min,o=e.max,s=a.array,u=o.array,l=n[0];Zr(t,l,i),Kr(s,t),Kr(u,t);for(var h=1;h<8;h++)l=n[h],Zr(t,l,i),s[0]=Jr(t[0],s[0]),s[1]=Jr(t[1],s[1]),s[2]=Jr(t[2],s[2]),u[0]=Qr(t[0],u[0]),u[1]=Qr(t[1],u[1]),u[2]=Qr(t[2],u[2]);return a._dirty=!0,o._dirty=!0,e}}()};var tn=function(t,e){this.origin=t||new wr,this.direction=e||new wr};tn.prototype={constructor:tn,intersectPlane:function(t,e){var r=t.normal.array,n=t.distance,i=this.origin.array,a=this.direction.array,o=we.dot(r,a);if(0===o)return null;e||(e=new wr);var s=(we.dot(r,i)-n)/o;return we.scaleAndAdd(e.array,i,a,-s),e._dirty=!0,e},mirrorAgainstPlane:function(t){var e=we.dot(t.normal.array,this.direction.array);we.scaleAndAdd(this.direction.array,this.direction.array,t.normal.array,2*-e),this.direction._dirty=!0},distanceToPoint:function(){var t=we.create();return function(e){we.sub(t,e,this.origin.array);var r=we.dot(t,this.direction.array);if(r<0)return we.distance(this.origin.array,e);var n=we.lenSquared(t);return Math.sqrt(n-r*r)}}(),intersectSphere:function(){var t=we.create();return function(e,r,n){var i=this.origin.array,a=this.direction.array;e=e.array,we.sub(t,e,i);var o=we.dot(t,a),s=we.squaredLength(t),u=s-o*o,l=r*r;if(!(u>l)){var h=Math.sqrt(l-u),c=o-h,f=o+h;return n||(n=new wr),c<0?f<0?null:(we.scaleAndAdd(n.array,i,a,f),n):(we.scaleAndAdd(n.array,i,a,c),n)}}}(),intersectBoundingBox:function(t,e){var r,n,i,a,o,s,u=this.direction.array,l=this.origin.array,h=t.min.array,c=t.max.array,f=1/u[0],d=1/u[1],p=1/u[2];if(f>=0?(r=(h[0]-l[0])*f,n=(c[0]-l[0])*f):(n=(h[0]-l[0])*f,r=(c[0]-l[0])*f),d>=0?(i=(h[1]-l[1])*d,a=(c[1]-l[1])*d):(a=(h[1]-l[1])*d,i=(c[1]-l[1])*d),r>a||i>n)return null;if((i>r||r!==r)&&(r=i),(a=0?(o=(h[2]-l[2])*p,s=(c[2]-l[2])*p):(s=(h[2]-l[2])*p,o=(c[2]-l[2])*p),r>s||o>n)return null;if((o>r||r!==r)&&(r=o),(s=0?r:n;return e||(e=new wr),we.scaleAndAdd(e.array,l,u,m),e},intersectTriangle:function(){var t=we.create(),e=we.create(),r=we.create(),n=we.create();return function(i,a,o,s,u,l){var h=this.direction.array,c=this.origin.array;i=i.array,a=a.array,o=o.array,we.sub(t,a,i),we.sub(e,o,i),we.cross(n,e,h);var f=we.dot(t,n);if(s){if(f>-1e-5)return null}else if(f>-1e-5&&f<1e-5)return null;we.sub(r,c,i);var d=we.dot(n,r)/f;if(d<0||d>1)return null;we.cross(n,t,r);var p=we.dot(h,n)/f;if(p<0||p>1||d+p>1)return null;we.cross(n,t,e);var m=-we.dot(r,n)/f;return m<0?null:(u||(u=new wr),l&&wr.set(l,1-d-p,d,p),we.scaleAndAdd(u.array,c,h,m),u)}}(),applyTransform:function(t){wr.add(this.direction,this.direction,this.origin),wr.transformMat4(this.origin,this.origin,t),wr.transformMat4(this.direction,this.direction,t),wr.sub(this.direction,this.direction,this.origin),wr.normalize(this.direction,this.direction)},copy:function(t){wr.copy(this.origin,t.origin),wr.copy(this.direction,t.direction)},clone:function(){var t=new tn;return t.copy(this),t}};var en=Wr.extend(function(){return{projectionMatrix:new Br,invProjectionMatrix:new Br,viewMatrix:new Br,frustum:new $r}},function(){this.update(!0)},{update:function(t){Wr.prototype.update.call(this,t),Br.invert(this.viewMatrix,this.worldTransform),this.updateProjectionMatrix(),Br.invert(this.invProjectionMatrix,this.projectionMatrix),this.frustum.setFromProjection(this.projectionMatrix)},setViewMatrix:function(t){Br.copy(this.viewMatrix,t),Br.invert(this.worldTransform,t),this.decomposeWorldTransform()},decomposeProjectionMatrix:function(){},setProjectionMatrix:function(t){Br.copy(this.projectionMatrix,t),Br.invert(this.invProjectionMatrix,t),this.decomposeProjectionMatrix()},updateProjectionMatrix:function(){},castRay:function(){var t=Ce.create();return function(e,r){var n=void 0!==r?r:new tn,i=e.array[0],a=e.array[1];return Ce.set(t,i,a,-1,1),Ce.transformMat4(t,t,this.invProjectionMatrix.array),Ce.transformMat4(t,t,this.worldTransform.array),we.scale(n.origin.array,t,1/t[3]),Ce.set(t,i,a,1,1),Ce.transformMat4(t,t,this.invProjectionMatrix.array),Ce.transformMat4(t,t,this.worldTransform.array),we.scale(t,t,1/t[3]),we.sub(n.direction.array,t,n.origin.array),we.normalize(n.direction.array,n.direction.array),n.direction._dirty=!0,n.origin._dirty=!0,n}}()}),rn=xr.create(),nn=xr.create(),an={};ut.prototype.startCount=function(){this._opaqueCount=0,this._transparentCount=0},ut.prototype.add=function(t,e){e?this.transparent[this._transparentCount++]=t:this.opaque[this._opaqueCount++]=t},ut.prototype.endCount=function(){this.transparent.length=this._transparentCount,this.opaque.length=this._opaqueCount};var on=Wr.extend(function(){return{material:null,lights:[],viewBoundingBoxLastFrame:new Gr,shadowUniforms:{},_cameraList:[],_lightUniforms:{},_previousLightNumber:{},_lightNumber:{},_lightProgramKeys:{},_nodeRepository:{},_renderLists:new Ke(20)}},function(){this._scene=this},{addToScene:function(t){t instanceof en?(this._cameraList.length>0&&console.warn("Found multiple camera in one scene. Use the fist one."),this._cameraList.push(t)):t instanceof jr&&this.lights.push(t),t.name&&(this._nodeRepository[t.name]=t)},removeFromScene:function(t){var e;t instanceof en?(e=this._cameraList.indexOf(t))>=0&&this._cameraList.splice(e,1):t instanceof jr&&(e=this.lights.indexOf(t))>=0&&this.lights.splice(e,1),t.name&&delete this._nodeRepository[t.name]},getNode:function(t){return this._nodeRepository[t]},setMainCamera:function(t){var e=this._cameraList.indexOf(t);e>=0&&this._cameraList.splice(e,1),this._cameraList.unshift(t)},getMainCamera:function(){return this._cameraList[0]},getLights:function(){return this.lights},updateLights:function(){var t=this.lights;this._previousLightNumber=this._lightNumber;for(var e={},r=0;r0&&this._doUpdateRenderList(o,e,r,n,i)}},isFrustumCulled:function(){var t=new Gr,e=new Br;return function(r,n,i){var a=r.boundingBox;if(a||(a=r.skeleton&&r.skeleton.boundingBox?r.skeleton.boundingBox:r.geometry.boundingBox),!a)return!1;if(e.array=i,t.transformFrom(a,e),r.castShadow&&this.viewBoundingBoxLastFrame.union(t),r.frustumCulling){if(!t.intersectBoundingBox(n.frustum.boundingBox))return!0;e.array=n.projectionMatrix.array,t.max.array[2]>0&&t.min.array[2]<0&&(t.max.array[2]=-1e-20),t.applyProjection(e);var o=t.min.array,s=t.max.array;if(s[0]<-1||o[0]>1||s[1]<-1||o[1]>1||s[2]<-1||o[2]>1)return!0}return!1}}(),_updateLightUniforms:function(){var t=this.lights;t.sort(lt);var e=this._lightUniforms;for(var r in e)for(var n in e[r])e[r][n].value.length=0;for(var i=0;i=0){e||(e=[]);var r=this.indices;return e[0]=r[3*t],e[1]=r[3*t+1],e[2]=r[3*t+2],e}},setTriangleIndices:function(t,e){var r=this.indices;r[3*t]=e[0],r[3*t+1]=e[1],r[3*t+2]=e[2]},isUseIndices:function(){return!!this.indices},initIndicesFromArray:function(t){var e,r=this.vertexCount>65535?Ge.Uint32Array:Ge.Uint16Array;if(t[0]&&t[0].length){var n=0;e=new r(3*t.length);for(var i=0;i=0&&(e.splice(r,1),delete this.attributes[t],!0)},getAttribute:function(t){return this.attributes[t]},getEnabledAttributes:function(){var t=this._enabledAttributes,e=this._attributeList;if(t)return t;for(var r=[],n=this.vertexCount,i=0;ia[0]&&(a[0]=s),u>a[1]&&(a[1]=u),l>a[2]&&(a[2]=l)}r._dirty=!0,n._dirty=!0}},generateVertexNormals:function(){if(this.vertexCount){var t=this.indices,e=this.attributes,r=e.position.value,n=e.normal.value;if(n&&n.length===r.length)for(var i=0;i65535&&(this.indices=new Ge.Uint32Array(this.indices));for(var t=this.attributes,e=this.indices,r=this.getEnabledAttributes(),n={},i=0;i65535?Uint32Array:Uint16Array,p=this.indices=new d(e*t*6),m=this.radius,_=this.phiStart,g=this.phiLength,v=this.thetaStart,y=this.thetaLength,m=this.radius,T=[],x=[],E=0,A=1/m;for(f=0;f<=t;f++)for(c=0;c<=e;c++)l=c/e,h=f/t,o=-m*Math.cos(_+l*g)*Math.sin(v+h*y),s=m*Math.cos(v+h*y),u=m*Math.sin(_+l*g)*Math.sin(v+h*y),T[0]=o,T[1]=s,T[2]=u,x[0]=l,x[1]=h,r.set(E,T),n.set(E,x),T[0]*=A,T[1]*=A,T[2]*=A,i.set(E,T),E++;var b,S,M,w,C=e+1,R=0;for(f=0;f65535?Uint32Array:Uint16Array,g=(o-1)*(s-1)*6,v=this.indices=new _(g),y=0,f=0;f>e;return t+1},dispose:function(t){var e=this._cache;e.use(t.__uid__);var r=e.get("webgl_texture");r&&t.gl.deleteTexture(r),e.deleteContext(t.__uid__)},isRenderable:function(){},isPowerOfTwo:function(){}});Object.defineProperty(yn.prototype,"width",{get:function(){return this._width},set:function(t){this._width=t}}),Object.defineProperty(yn.prototype,"height",{get:function(){return this._height},set:function(t){this._height=t}}),yn.BYTE=qe.BYTE,yn.UNSIGNED_BYTE=qe.UNSIGNED_BYTE,yn.SHORT=qe.SHORT,yn.UNSIGNED_SHORT=qe.UNSIGNED_SHORT,yn.INT=qe.INT,yn.UNSIGNED_INT=qe.UNSIGNED_INT,yn.FLOAT=qe.FLOAT,yn.HALF_FLOAT=36193,yn.UNSIGNED_INT_24_8_WEBGL=34042,yn.DEPTH_COMPONENT=qe.DEPTH_COMPONENT,yn.DEPTH_STENCIL=qe.DEPTH_STENCIL,yn.ALPHA=qe.ALPHA,yn.RGB=qe.RGB,yn.RGBA=qe.RGBA,yn.LUMINANCE=qe.LUMINANCE,yn.LUMINANCE_ALPHA=qe.LUMINANCE_ALPHA,yn.SRGB=35904,yn.SRGB_ALPHA=35906,yn.COMPRESSED_RGB_S3TC_DXT1_EXT=33776,yn.COMPRESSED_RGBA_S3TC_DXT1_EXT=33777,yn.COMPRESSED_RGBA_S3TC_DXT3_EXT=33778,yn.COMPRESSED_RGBA_S3TC_DXT5_EXT=33779,yn.NEAREST=qe.NEAREST,yn.LINEAR=qe.LINEAR,yn.NEAREST_MIPMAP_NEAREST=qe.NEAREST_MIPMAP_NEAREST,yn.LINEAR_MIPMAP_NEAREST=qe.LINEAR_MIPMAP_NEAREST,yn.NEAREST_MIPMAP_LINEAR=qe.NEAREST_MIPMAP_LINEAR,yn.LINEAR_MIPMAP_LINEAR=qe.LINEAR_MIPMAP_LINEAR,yn.REPEAT=qe.REPEAT,yn.CLAMP_TO_EDGE=qe.CLAMP_TO_EDGE,yn.MIRRORED_REPEAT=qe.MIRRORED_REPEAT;var Tn={};Tn.isPowerOfTwo=function(t){return 0==(t&t-1)},Tn.nextPowerOfTwo=function(t){return t--,t|=t>>1,t|=t>>2,t|=t>>4,t|=t>>8,t|=t>>16,++t},Tn.nearestPowerOfTwo=function(t){return Math.pow(2,Math.round(Math.log(t)/Math.LN2))};var xn=Tn.isPowerOfTwo,En=yn.extend(function(){return{image:null,pixels:null,mipmaps:[],convertToPOT:!1}},{textureType:"texture2D",update:function(t){var e=t.gl;e.bindTexture(e.TEXTURE_2D,this._cache.get("webgl_texture")),this.updateCommon(t);var r=this.format,n=this.type,i=!(!this.convertToPOT||this.mipmaps.length||!this.image||this.wrapS!==yn.REPEAT&&this.wrapT!==yn.REPEAT||!this.NPOT);e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,i?this.wrapS:this.getAvailableWrapS()),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,i?this.wrapT:this.getAvailableWrapT()),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,i?this.magFilter:this.getAvailableMagFilter()),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,i?this.minFilter:this.getAvailableMinFilter());var a=t.getGLExtension("EXT_texture_filter_anisotropic");if(a&&this.anisotropic>1&&e.texParameterf(e.TEXTURE_2D,a.TEXTURE_MAX_ANISOTROPY_EXT,this.anisotropic),36193===n){t.getGLExtension("OES_texture_half_float")||(n=qe.FLOAT)}if(this.mipmaps.length)for(var o=this.width,s=this.height,u=0;u=yn.COMPRESSED_RGB_S3TC_DXT1_EXT?t.compressedTexImage2D(t.TEXTURE_2D,r,a,n,i,0,e.pixels):t.texImage2D(t.TEXTURE_2D,r,a,n,i,0,a,o,e.pixels)},generateMipmap:function(t){var e=t.gl;this.useMipmap&&!this.NPOT&&(e.bindTexture(e.TEXTURE_2D,this._cache.get("webgl_texture")),e.generateMipmap(e.TEXTURE_2D))},isPowerOfTwo:function(){return xn(this.width)&&xn(this.height)},isRenderable:function(){return this.image?"CANVAS"===this.image.nodeName||"VIDEO"===this.image.nodeName||this.image.complete:!(!this.width||!this.height)},bind:function(t){t.gl.bindTexture(t.gl.TEXTURE_2D,this.getWebGLTexture(t))},unbind:function(t){t.gl.bindTexture(t.gl.TEXTURE_2D,null)},load:function(t,e){var r=Ge.createImage();e&&(r.crossOrigin=e);var n=this;return r.onload=function(){n.dirty(),n.trigger("success",n)},r.onerror=function(){n.trigger("error",n)},r.src=t,this.image=r,this}});Object.defineProperty(En.prototype,"width",{get:function(){return this.image?this.image.width:this._width},set:function(t){this.image?console.warn("Texture from image can't set width"):(this._width!==t&&this.dirty(),this._width=t)}}),Object.defineProperty(En.prototype,"height",{get:function(){return this.image?this.image.height:this._height},set:function(t){this.image?console.warn("Texture from image can't set height"):(this._height!==t&&this.dirty(),this._height=t)}});var An=Tn.isPowerOfTwo,bn=["px","nx","py","ny","pz","nz"],Sn=yn.extend(function(){return{image:{px:null,nx:null,py:null,ny:null,pz:null,nz:null},pixels:{px:null,nx:null,py:null,ny:null,pz:null,nz:null},mipmaps:[]}},{textureType:"textureCube",update:function(t){var e=t.gl;e.bindTexture(e.TEXTURE_CUBE_MAP,this._cache.get("webgl_texture")),this.updateCommon(t);var r=this.format,n=this.type;e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_WRAP_S,this.getAvailableWrapS()),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_WRAP_T,this.getAvailableWrapT()),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_MAG_FILTER,this.getAvailableMagFilter()),e.texParameteri(e.TEXTURE_CUBE_MAP,e.TEXTURE_MIN_FILTER,this.getAvailableMinFilter());var i=t.getGLExtension("EXT_texture_filter_anisotropic");if(i&&this.anisotropic>1&&e.texParameterf(e.TEXTURE_CUBE_MAP,i.TEXTURE_MAX_ANISOTROPY_EXT,this.anisotropic),36193===n){t.getGLExtension("OES_texture_half_float")||(n=qe.FLOAT)}if(this.mipmaps.length)for(var a=this.width,o=this.height,s=0;s0},beforeRender:function(t){},afterRender:function(t,e){},getBoundingBox:function(t,e){return e=Wr.prototype.getBoundingBox.call(this,t,e),this.geometry&&this.geometry.boundingBox&&e.union(this.geometry.boundingBox),e},clone:function(){var t=["castShadow","receiveShadow","mode","culling","cullFace","frontFace","frustumCulling","renderOrder","lineWidth","ignorePicking","ignorePreZ","ignoreGBuffer"];return function(){var e=Wr.prototype.clone.call(this);e.geometry=this.geometry,e.material=this.material;for(var r=0;r0)},clone:function(){var t=Mn.prototype.clone.call(this);return t.skeleton=this.skeleton,this.joints&&(t.joints=this.joints.slice()),t}});wn.POINTS=qe.POINTS,wn.LINES=qe.LINES,wn.LINE_LOOP=qe.LINE_LOOP,wn.LINE_STRIP=qe.LINE_STRIP,wn.TRIANGLES=qe.TRIANGLES,wn.TRIANGLE_STRIP=qe.TRIANGLE_STRIP,wn.TRIANGLE_FAN=qe.TRIANGLE_FAN,wn.BACK=qe.BACK,wn.FRONT=qe.FRONT,wn.FRONT_AND_BACK=qe.FRONT_AND_BACK,wn.CW=qe.CW,wn.CCW=qe.CCW;var Cn=en.extend({fov:50,aspect:1,near:.1,far:2e3},{updateProjectionMatrix:function(){var t=this.fov/180*Math.PI;this.projectionMatrix.perspective(t,this.aspect,this.near,this.far)},decomposeProjectionMatrix:function(){var t=this.projectionMatrix.array,e=2*Math.atan(1/t[5]);this.fov=e/Math.PI*180,this.aspect=t[5]/t[0],this.near=t[14]/(t[10]-1),this.far=t[14]/(t[10]+1)},clone:function(){var t=en.prototype.clone.call(this);return t.fov=this.fov,t.aspect=this.aspect,t.near=this.near,t.far=this.far,t}}),Rn=en.extend({left:-1,right:1,near:-1,far:1,top:1,bottom:-1},{updateProjectionMatrix:function(){this.projectionMatrix.ortho(this.left,this.right,this.bottom,this.top,this.near,this.far)},decomposeProjectionMatrix:function(){var t=this.projectionMatrix.array;this.left=(-1-t[12])/t[0],this.right=(1-t[12])/t[0],this.top=(1-t[13])/t[5],this.bottom=(-1-t[13])/t[5],this.near=-(-1-t[14])/t[10],this.far=-(1-t[14])/t[10]},clone:function(){var t=en.prototype.clone.call(this);return t.left=this.left,t.right=this.right,t.near=this.near,t.far=this.far,t.top=this.top,t.bottom=this.bottom,t} +}),Ln="\n@export clay.standard.chunk.varying\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nvarying vec3 v_Barycentric;\n#if defined(PARALLAXOCCLUSIONMAP_ENABLED) || defined(NORMALMAP_ENABLED)\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\n#endif\n#if defined(AOMAP_ENABLED)\nvarying vec2 v_Texcoord2;\n#endif\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n@end\n@export clay.standard.chunk.light_header\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n#ifdef AMBIENT_CUBEMAP_LIGHT_COUNT\n@import clay.header.ambient_cubemap_light\n#endif\n#ifdef POINT_LIGHT_COUNT\n@import clay.header.point_light\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n#ifdef SPOT_LIGHT_COUNT\n@import clay.header.spot_light\n#endif\n@end\n@export clay.standard.vertex\n#define SHADER_NAME standard\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\n#if defined(AOMAP_ENABLED)\nattribute vec2 texcoord2 : TEXCOORD_1;\n#endif\nattribute vec3 normal : NORMAL;\nattribute vec4 tangent : TANGENT;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\n#endif\nattribute vec3 barycentric;\n@import clay.standard.chunk.varying\n@import clay.chunk.skinning_header\nvoid main()\n{\n vec3 skinnedPosition = position;\n vec3 skinnedNormal = normal;\n vec3 skinnedTangent = tangent.xyz;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n skinnedNormal = (skinMatrixWS * vec4(normal, 0.0)).xyz;\n skinnedTangent = (skinMatrixWS * vec4(tangent.xyz, 0.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0);\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n v_WorldPosition = (world * vec4(skinnedPosition, 1.0)).xyz;\n v_Barycentric = barycentric;\n v_Normal = normalize((worldInverseTranspose * vec4(skinnedNormal, 0.0)).xyz);\n#if defined(PARALLAXOCCLUSIONMAP_ENABLED) || defined(NORMALMAP_ENABLED)\n v_Tangent = normalize((worldInverseTranspose * vec4(skinnedTangent, 0.0)).xyz);\n v_Bitangent = normalize(cross(v_Normal, v_Tangent) * tangent.w);\n#endif\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n#if defined(AOMAP_ENABLED)\n v_Texcoord2 = texcoord2;\n#endif\n}\n@end\n@export clay.standard.fragment\n#define PI 3.14159265358979\n#define GLOSSINESS_CHANNEL 0\n#define ROUGHNESS_CHANNEL 0\n#define METALNESS_CHANNEL 1\n#define DIFFUSEMAP_ALPHA_ALPHA\n@import clay.standard.chunk.varying\nuniform mat4 viewInverse : VIEWINVERSE;\n#ifdef NORMALMAP_ENABLED\nuniform sampler2D normalMap;\n#endif\nuniform float normalScale: 1.0;\n#ifdef DIFFUSEMAP_ENABLED\nuniform sampler2D diffuseMap;\n#endif\n#ifdef SPECULARMAP_ENABLED\nuniform sampler2D specularMap;\n#endif\n#ifdef USE_ROUGHNESS\nuniform float roughness : 0.5;\n #ifdef ROUGHNESSMAP_ENABLED\nuniform sampler2D roughnessMap;\n #endif\n#else\nuniform float glossiness: 0.5;\n #ifdef GLOSSINESSMAP_ENABLED\nuniform sampler2D glossinessMap;\n #endif\n#endif\n#ifdef METALNESSMAP_ENABLED\nuniform sampler2D metalnessMap;\n#endif\n#ifdef OCCLUSIONMAP_ENABLED\nuniform sampler2D occlusionMap;\n#endif\n#ifdef ENVIRONMENTMAP_ENABLED\nuniform samplerCube environmentMap;\n #ifdef PARALLAX_CORRECTED\nuniform vec3 environmentBoxMin;\nuniform vec3 environmentBoxMax;\n #endif\n#endif\n#ifdef BRDFLOOKUP_ENABLED\nuniform sampler2D brdfLookup;\n#endif\n#ifdef EMISSIVEMAP_ENABLED\nuniform sampler2D emissiveMap;\n#endif\n#ifdef SSAOMAP_ENABLED\nuniform sampler2D ssaoMap;\nuniform vec4 viewport : VIEWPORT;\n#endif\n#ifdef AOMAP_ENABLED\nuniform sampler2D aoMap;\nuniform float aoIntensity;\n#endif\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform float alpha : 1.0;\n#ifdef ALPHA_TEST\nuniform float alphaCutoff: 0.9;\n#endif\n#ifdef USE_METALNESS\nuniform float metalness : 0.0;\n#else\nuniform vec3 specularColor : [0.1, 0.1, 0.1];\n#endif\nuniform vec3 emission : [0.0, 0.0, 0.0];\nuniform float emissionIntensity: 1;\nuniform float lineWidth : 0.0;\nuniform vec4 lineColor : [0.0, 0.0, 0.0, 0.6];\n#ifdef ENVIRONMENTMAP_PREFILTER\nuniform float maxMipmapLevel: 5;\n#endif\n@import clay.standard.chunk.light_header\n@import clay.util.calculate_attenuation\n@import clay.util.edge_factor\n@import clay.util.rgbm\n@import clay.util.srgb\n@import clay.plugin.compute_shadow_map\n@import clay.util.parallax_correct\n@import clay.util.ACES\nfloat G_Smith(float g, float ndv, float ndl)\n{\n float roughness = 1.0 - g;\n float k = roughness * roughness / 2.0;\n float G1V = ndv / (ndv * (1.0 - k) + k);\n float G1L = ndl / (ndl * (1.0 - k) + k);\n return G1L * G1V;\n}\nvec3 F_Schlick(float ndv, vec3 spec) {\n return spec + (1.0 - spec) * pow(1.0 - ndv, 5.0);\n}\nfloat D_Phong(float g, float ndh) {\n float a = pow(8192.0, g);\n return (a + 2.0) / 8.0 * pow(ndh, a);\n}\nfloat D_GGX(float g, float ndh) {\n float r = 1.0 - g;\n float a = r * r;\n float tmp = ndh * ndh * (a - 1.0) + 1.0;\n return a / (PI * tmp * tmp);\n}\n#ifdef PARALLAXOCCLUSIONMAP_ENABLED\nuniform float parallaxOcclusionScale : 0.02;\nuniform float parallaxMaxLayers : 20;\nuniform float parallaxMinLayers : 5;\nuniform sampler2D parallaxOcclusionMap;\nmat3 transpose(in mat3 inMat)\n{\n vec3 i0 = inMat[0];\n vec3 i1 = inMat[1];\n vec3 i2 = inMat[2];\n return mat3(\n vec3(i0.x, i1.x, i2.x),\n vec3(i0.y, i1.y, i2.y),\n vec3(i0.z, i1.z, i2.z)\n );\n}\nvec2 parallaxUv(vec2 uv, vec3 viewDir)\n{\n float numLayers = mix(parallaxMaxLayers, parallaxMinLayers, abs(dot(vec3(0.0, 0.0, 1.0), viewDir)));\n float layerHeight = 1.0 / numLayers;\n float curLayerHeight = 0.0;\n vec2 deltaUv = viewDir.xy * parallaxOcclusionScale / (viewDir.z * numLayers);\n vec2 curUv = uv;\n float height = 1.0 - texture2D(parallaxOcclusionMap, curUv).r;\n for (int i = 0; i < 30; i++) {\n curLayerHeight += layerHeight;\n curUv -= deltaUv;\n height = 1.0 - texture2D(parallaxOcclusionMap, curUv).r;\n if (height < curLayerHeight) {\n break;\n }\n }\n vec2 prevUv = curUv + deltaUv;\n float next = height - curLayerHeight;\n float prev = 1.0 - texture2D(parallaxOcclusionMap, prevUv).r - curLayerHeight + layerHeight;\n return mix(curUv, prevUv, next / (next - prev));\n}\n#endif\nvoid main() {\n vec4 albedoColor = vec4(color, alpha);\n#ifdef VERTEX_COLOR\n albedoColor *= v_Color;\n#endif\n#ifdef SRGB_DECODE\n albedoColor = sRGBToLinear(albedoColor);\n#endif\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(eyePos - v_WorldPosition);\n vec2 uv = v_Texcoord;\n#if defined(PARALLAXOCCLUSIONMAP_ENABLED) || defined(NORMALMAP_ENABLED)\n mat3 tbn = mat3(v_Tangent, v_Bitangent, v_Normal);\n#endif\n#ifdef PARALLAXOCCLUSIONMAP_ENABLED\n uv = parallaxUv(v_Texcoord, normalize(transpose(tbn) * -V));\n#endif\n#ifdef DIFFUSEMAP_ENABLED\n vec4 texel = texture2D(diffuseMap, uv);\n #ifdef SRGB_DECODE\n texel = sRGBToLinear(texel);\n #endif\n albedoColor.rgb *= texel.rgb;\n #ifdef DIFFUSEMAP_ALPHA_ALPHA\n albedoColor.a *= texel.a;\n #endif\n#endif\n#ifdef USE_METALNESS\n float m = metalness;\n #ifdef METALNESSMAP_ENABLED\n float m2 = texture2D(metalnessMap, uv)[METALNESS_CHANNEL];\n m = clamp(m2 + (m - 0.5) * 2.0, 0.0, 1.0);\n #endif\n vec3 baseColor = albedoColor.rgb;\n albedoColor.rgb = baseColor * (1.0 - m);\n vec3 spec = mix(vec3(0.04), baseColor, m);\n#else\n vec3 spec = specularColor;\n#endif\n#ifdef USE_ROUGHNESS\n float g = clamp(1.0 - roughness, 0.0, 1.0);\n #ifdef ROUGHNESSMAP_ENABLED\n float g2 = 1.0 - texture2D(roughnessMap, uv)[ROUGHNESS_CHANNEL];\n g = clamp(g2 + (g - 0.5) * 2.0, 0.0, 1.0);\n #endif\n#else\n float g = glossiness;\n #ifdef GLOSSINESSMAP_ENABLED\n float g2 = texture2D(glossinessMap, uv)[GLOSSINESS_CHANNEL];\n g = clamp(g2 + (g - 0.5) * 2.0, 0.0, 1.0);\n #endif\n#endif\n#ifdef SPECULARMAP_ENABLED\n spec *= sRGBToLinear(texture2D(specularMap, uv)).rgb;\n#endif\n vec3 N = v_Normal;\n#ifdef DOUBLE_SIDED\n if (dot(N, V) < 0.0) {\n N = -N;\n }\n#endif\n#ifdef NORMALMAP_ENABLED\n if (dot(v_Tangent, v_Tangent) > 0.0) {\n vec3 normalTexel = texture2D(normalMap, uv).xyz;\n if (dot(normalTexel, normalTexel) > 0.0) { N = (normalTexel * 2.0 - 1.0);\n N = normalize(N * vec3(normalScale, normalScale, 1.0));\n tbn[1] = -tbn[1];\n N = normalize(tbn * N);\n }\n }\n#endif\n vec3 diffuseTerm = vec3(0.0, 0.0, 0.0);\n vec3 specularTerm = vec3(0.0, 0.0, 0.0);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n vec3 fresnelTerm = F_Schlick(ndv, spec);\n#ifdef AMBIENT_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_LIGHT_COUNT; _idx_++)\n {{\n diffuseTerm += ambientLightColor[_idx_];\n }}\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseTerm += calcAmbientSHLight(_idx_, N) * ambientSHLightColor[_idx_];\n }}\n#endif\n#ifdef POINT_LIGHT_COUNT\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsPoint[POINT_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfPointLights(v_WorldPosition, shadowContribsPoint);\n }\n#endif\n for(int _idx_ = 0; _idx_ < POINT_LIGHT_COUNT; _idx_++)\n {{\n vec3 lightPosition = pointLightPosition[_idx_];\n vec3 lc = pointLightColor[_idx_];\n float range = pointLightRange[_idx_];\n vec3 L = lightPosition - v_WorldPosition;\n float dist = length(L);\n float attenuation = lightAttenuation(dist, range);\n L /= dist;\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n if(shadowEnabled)\n {\n shadowContrib = shadowContribsPoint[_idx_];\n }\n#endif\n vec3 li = lc * ndl * attenuation * shadowContrib;\n diffuseTerm += li;\n specularTerm += li * fresnelTerm * D_Phong(g, ndh);\n }}\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int _idx_ = 0; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++)\n {{\n vec3 L = -normalize(directionalLightDirection[_idx_]);\n vec3 lc = directionalLightColor[_idx_];\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if(shadowEnabled)\n {\n shadowContrib = shadowContribsDir[_idx_];\n }\n#endif\n vec3 li = lc * ndl * shadowContrib;\n diffuseTerm += li;\n specularTerm += li * fresnelTerm * D_Phong(g, ndh);\n }}\n#endif\n#ifdef SPOT_LIGHT_COUNT\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsSpot[SPOT_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfSpotLights(v_WorldPosition, shadowContribsSpot);\n }\n#endif\n for(int i = 0; i < SPOT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = spotLightPosition[i];\n vec3 spotLightDirection = -normalize(spotLightDirection[i]);\n vec3 lc = spotLightColor[i];\n float range = spotLightRange[i];\n float a = spotLightUmbraAngleCosine[i];\n float b = spotLightPenumbraAngleCosine[i];\n float falloffFactor = spotLightFalloffFactor[i];\n vec3 L = lightPosition - v_WorldPosition;\n float dist = length(L);\n float attenuation = lightAttenuation(dist, range);\n L /= dist;\n float c = dot(spotLightDirection, L);\n float falloff;\n falloff = clamp((c - a) /(b - a), 0.0, 1.0);\n falloff = pow(falloff, falloffFactor);\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n if (shadowEnabled)\n {\n shadowContrib = shadowContribsSpot[i];\n }\n#endif\n vec3 li = lc * attenuation * (1.0 - falloff) * shadowContrib * ndl;\n diffuseTerm += li;\n specularTerm += li * fresnelTerm * D_Phong(g, ndh);\n }\n#endif\n vec4 outColor = albedoColor;\n outColor.rgb *= max(diffuseTerm, vec3(0.0));\n outColor.rgb += max(specularTerm, vec3(0.0));\n#ifdef AMBIENT_CUBEMAP_LIGHT_COUNT\n vec3 L = reflect(-V, N);\n float rough2 = clamp(1.0 - g, 0.0, 1.0);\n float bias2 = rough2 * 5.0;\n vec2 brdfParam2 = texture2D(ambientCubemapLightBRDFLookup[0], vec2(rough2, ndv)).xy;\n vec3 envWeight2 = spec * brdfParam2.x + brdfParam2.y;\n vec3 envTexel2;\n for(int _idx_ = 0; _idx_ < AMBIENT_CUBEMAP_LIGHT_COUNT; _idx_++)\n {{\n #ifdef SUPPORT_TEXTURE_LOD\n envTexel2 = RGBMDecode(textureCubeLodEXT(ambientCubemapLightCubemap[_idx_], L, bias2), 8.12);\n #else\n envTexel2 = RGBMDecode(textureCube(ambientCubemapLightCubemap[_idx_], L), 8.12);\n #endif\n outColor.rgb += ambientCubemapLightColor[_idx_] * envTexel2 * envWeight2;\n }}\n#endif\n#ifdef ENVIRONMENTMAP_ENABLED\n vec3 envWeight = g * fresnelTerm;\n vec3 L = reflect(-V, N);\n #ifdef PARALLAX_CORRECTED\n L = parallaxCorrect(L, v_WorldPosition, environmentBoxMin, environmentBoxMax);\n#endif\n #ifdef ENVIRONMENTMAP_PREFILTER\n float rough = clamp(1.0 - g, 0.0, 1.0);\n float bias = rough * maxMipmapLevel;\n #ifdef SUPPORT_TEXTURE_LOD\n vec3 envTexel = decodeHDR(textureCubeLodEXT(environmentMap, L, bias)).rgb;\n #else\n vec3 envTexel = decodeHDR(textureCube(environmentMap, L)).rgb;\n #endif\n #ifdef BRDFLOOKUP_ENABLED\n vec2 brdfParam = texture2D(brdfLookup, vec2(rough, ndv)).xy;\n envWeight = spec * brdfParam.x + brdfParam.y;\n #endif\n #else\n vec3 envTexel = textureCube(environmentMap, L).xyz;\n #endif\n outColor.rgb += envTexel * envWeight;\n#endif\n float aoFactor = 1.0;\n#ifdef SSAOMAP_ENABLED\n aoFactor = min(texture2D(ssaoMap, (gl_FragCoord.xy - viewport.xy) / viewport.zw).r, aoFactor);\n#endif\n#ifdef AOMAP_ENABLED\n aoFactor = min(1.0 - clamp((1.0 - texture2D(aoMap, v_Texcoord2).r) * aoIntensity, 0.0, 1.0), aoFactor);\n#endif\n#ifdef OCCLUSIONMAP_ENABLED\n aoFactor = min(1.0 - clamp((1.0 - texture2D(occlusionMap, v_Texcoord).r), 0.0, 1.0), aoFactor);\n#endif\n outColor.rgb *= aoFactor;\n vec3 lEmission = emission;\n#ifdef EMISSIVEMAP_ENABLED\n lEmission *= texture2D(emissiveMap, uv).rgb;\n#endif\n outColor.rgb += lEmission * emissionIntensity;\n if(lineWidth > 0.)\n {\n outColor.rgb = mix(outColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (outColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n outColor.rgb = ACESToneMapping(outColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n outColor = linearTosRGB(outColor);\n#endif\n gl_FragColor = encodeHDR(outColor);\n}\n@end\n@export clay.standardMR.vertex\n@import clay.standard.vertex\n@end\n@export clay.standardMR.fragment\n#define USE_METALNESS\n#define USE_ROUGHNESS\n@import clay.standard.fragment\n@end";Q.import(Ln);var Nn,Pn=["diffuseMap","normalMap","roughnessMap","metalnessMap","emissiveMap","environmentMap","brdfLookup","ssaoMap","aoMap"],In=["color","emission","emissionIntensity","alpha","roughness","metalness","uvRepeat","uvOffset","aoIntensity","alphaCutoff","normalScale"],On=["linear","encodeRGBM","decodeRGBM","doubleSided","alphaTest","roughnessChannel","metalnessChannel","environmentMapPrefiltered"],Dn={roughnessChannel:"ROUGHNESS_CHANNEL",metalnessChannel:"METALNESS_CHANNEL"},Bn={linear:"SRGB_DECODE",encodeRGBM:"RGBM_ENCODE",decodeRGBM:"RGBM_DECODE",doubleSided:"DOUBLE_SIDED",alphaTest:"ALPHA_TEST",environmentMapPrefiltered:"ENVIRONMENTMAP_PREFILTER"},Un=rr.extend(function(){return Nn||(Nn=new Q(Q.source("clay.standardMR.vertex"),Q.source("clay.standardMR.fragment"))),{shader:Nn}},function(t){Ue.extend(this,t),Ue.defaults(this,{color:[1,1,1],emission:[0,0,0],emissionIntensity:0,roughness:.5,metalness:0,alpha:1,alphaTest:!1,alphaCutoff:.9,normalScale:1,doubleSided:!1,diffuseMap:null,normalMap:null,roughnessMap:null,metalnessMap:null,emissiveMap:null,environmentMap:null,environmentBox:null,brdfLookup:null,ssaoMap:null,aoMap:null,uvRepeat:[1,1],uvOffset:[0,0],aoIntensity:1,environmentMapPrefiltered:!1,linear:!1,encodeRGBM:!1,decodeRGBM:!1,roughnessChannel:0,metalnessChannel:1})},{clone:function(){var t=new Un({name:this.name});return Pn.forEach(function(e){this[e]&&(t[e]=this[e])},this),In.concat(On).forEach(function(e){t[e]=this[e]},this),t}});In.forEach(function(t){Object.defineProperty(Un.prototype,t,{get:function(){return this.get(t)},set:function(e){this.setUniform(t,e)}})}),Pn.forEach(function(t){Object.defineProperty(Un.prototype,t,{get:function(){return this.get(t)},set:function(e){this.setUniform(t,e)}})}),On.forEach(function(t){var e="_"+t;Object.defineProperty(Un.prototype,t,{get:function(){return this[e]},set:function(r){if(this[e]=r,t in Dn){var n=Dn[t];this.define("fragment",n,r)}else{var n=Bn[t];r?this.define("fragment",n):this.undefine("fragment",n)}}})}),Object.defineProperty(Un.prototype,"environmentBox",{get:function(){var t=this._environmentBox;return t&&(t.min.setArray(this.get("environmentBoxMin")),t.max.setArray(this.get("environmentBoxMax"))),t},set:function(t){this._environmentBox=t;var e=this.uniforms=this.uniforms||{};e.environmentBoxMin=e.environmentBoxMin||{value:null},e.environmentBoxMax=e.environmentBoxMax||{value:null},t&&(this.setUniform("environmentBoxMin",t.min.array),this.setUniform("environmentBoxMax",t.max.array)),t?this.define("fragment","PARALLAX_CORRECTED"):this.undefine("fragment","PARALLAX_CORRECTED")}});var Fn={};yt.prototype.get=function(t){var e=t;if(this._pool[e])return this._pool[e];var r=Fn[t];if(!r)return void console.error('Shader "'+t+'" is not in the library');var n=new Q(r.vertex,r.fragment);return this._pool[e]=n,n},yt.prototype.clear=function(){this._pool={}};var kn=new yt,Hn={createLibrary:function(){return new yt},get:function(){return kn.get.apply(kn,arguments)},template:Tt,clear:function(){return kn.clear()}},Gn=Fe.extend({name:"",index:-1,node:null}),Vn=new Gr,Wn=new Br,zn=Fe.extend(function(){return{relativeRootNode:null,name:"",joints:[],boundingBox:null,_clips:[],_invBindPoseMatricesArray:null,_jointMatricesSubArrays:[],_skinMatricesArray:null,_skinMatricesSubArrays:[],_subSkinMatricesArray:{}}},{addClip:function(t,e){for(var r=0;r0&&this._clips.splice(e,1)},removeClipsAll:function(){this._clips=[]},getClip:function(t){if(this._clips[t])return this._clips[t].clip},getClipNumber:function(){return this._clips.length},updateJointMatrices:function(){var t=xr.create();return function(){this._invBindPoseMatricesArray=new Float32Array(16*this.joints.length),this._skinMatricesArray=new Float32Array(16*this.joints.length);for(var e=0;e.01){var f=s[c];h=Math.max(h,f);var d=a[f].min.array,p=a[f].max.array;a[f].__updated=!0,d=we.min(d,d,u),p=we.max(p,p,u)}}this._jointsBoundingBoxes=a,this.boundingBox=new Gr,h256?64:i>64?32:i>16?16:8;var a=this._skinMatricesTexture=this._skinMatricesTexture||new En({type:yn.FLOAT,minFilter:yn.NEAREST,magFilter:yn.NEAREST,useMipmap:!1,flipY:!1});return a.width=r,a.height=r,a.pixels&&a.pixels.length===r*r*4||(a.pixels=new Float32Array(r*r*4)),a.pixels.set(n),a.dirty(),a},getSkinMatricesTexture:function(){return this._skinMatricesTexture},_setPose:function(){if(this._clips[0])for(var t=this._clips[0].clip,e=this._clips[0].maps,r=0;r 0.)\n {\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (gl_FragColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n gl_FragColor.rgb = ACESToneMapping(gl_FragColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n}\n@end"), +Q.import("\n@export clay.lambert.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 normal : NORMAL;\nattribute vec3 barycentric;\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n@import clay.chunk.skinning_header\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nvarying vec3 v_Barycentric;\nvoid main()\n{\n vec3 skinnedPosition = position;\n vec3 skinnedNormal = normal;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n skinnedNormal = (skinMatrixWS * vec4(normal, 0.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4( skinnedPosition, 1.0 );\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n v_Normal = normalize( ( worldInverseTranspose * vec4(skinnedNormal, 0.0) ).xyz );\n v_WorldPosition = ( world * vec4( skinnedPosition, 1.0) ).xyz;\n v_Barycentric = barycentric;\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n}\n@end\n@export clay.lambert.fragment\n#define DIFFUSEMAP_ALPHA_ALPHA\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nuniform sampler2D diffuseMap;\nuniform sampler2D alphaMap;\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform vec3 emission : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\n#ifdef ALPHA_TEST\nuniform float alphaCutoff: 0.9;\n#endif\nuniform float lineWidth : 0.0;\nuniform vec4 lineColor : [0.0, 0.0, 0.0, 0.6];\nvarying vec3 v_Barycentric;\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n#ifdef POINT_LIGHT_COUNT\n@import clay.header.point_light\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n#ifdef SPOT_LIGHT_COUNT\n@import clay.header.spot_light\n#endif\n@import clay.util.calculate_attenuation\n@import clay.util.edge_factor\n@import clay.util.rgbm\n@import clay.plugin.compute_shadow_map\n@import clay.util.ACES\nvoid main()\n{\n gl_FragColor = vec4(color, alpha);\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(gl_FragColor);\n#endif\n#ifdef DIFFUSEMAP_ENABLED\n vec4 tex = texture2D( diffuseMap, v_Texcoord );\n#ifdef SRGB_DECODE\n tex.rgb = pow(tex.rgb, vec3(2.2));\n#endif\n gl_FragColor.rgb *= tex.rgb;\n#ifdef DIFFUSEMAP_ALPHA_ALPHA\n gl_FragColor.a *= tex.a;\n#endif\n#endif\n vec3 diffuseColor = vec3(0.0, 0.0, 0.0);\n#ifdef AMBIENT_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_LIGHT_COUNT; _idx_++)\n {\n diffuseColor += ambientLightColor[_idx_];\n }\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseColor += calcAmbientSHLight(_idx_, v_Normal) * ambientSHLightColor[_idx_];\n }}\n#endif\n#ifdef POINT_LIGHT_COUNT\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsPoint[POINT_LIGHT_COUNT];\n if( shadowEnabled )\n {\n computeShadowOfPointLights(v_WorldPosition, shadowContribsPoint);\n }\n#endif\n for(int i = 0; i < POINT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = pointLightPosition[i];\n vec3 lightColor = pointLightColor[i];\n float range = pointLightRange[i];\n vec3 lightDirection = lightPosition - v_WorldPosition;\n float dist = length(lightDirection);\n float attenuation = lightAttenuation(dist, range);\n lightDirection /= dist;\n float ndl = dot( v_Normal, lightDirection );\n float shadowContrib = 1.0;\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsPoint[i];\n }\n#endif\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0) * attenuation * shadowContrib;\n }\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++)\n {\n vec3 lightDirection = -directionalLightDirection[i];\n vec3 lightColor = directionalLightColor[i];\n float ndl = dot(v_Normal, normalize(lightDirection));\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsDir[i];\n }\n#endif\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0) * shadowContrib;\n }\n#endif\n#ifdef SPOT_LIGHT_COUNT\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsSpot[SPOT_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfSpotLights(v_WorldPosition, shadowContribsSpot);\n }\n#endif\n for(int i = 0; i < SPOT_LIGHT_COUNT; i++)\n {\n vec3 lightPosition = -spotLightPosition[i];\n vec3 spotLightDirection = -normalize( spotLightDirection[i] );\n vec3 lightColor = spotLightColor[i];\n float range = spotLightRange[i];\n float a = spotLightUmbraAngleCosine[i];\n float b = spotLightPenumbraAngleCosine[i];\n float falloffFactor = spotLightFalloffFactor[i];\n vec3 lightDirection = lightPosition - v_WorldPosition;\n float dist = length(lightDirection);\n float attenuation = lightAttenuation(dist, range);\n lightDirection /= dist;\n float c = dot(spotLightDirection, lightDirection);\n float falloff;\n falloff = clamp((c - a) /( b - a), 0.0, 1.0);\n falloff = pow(falloff, falloffFactor);\n float ndl = dot(v_Normal, lightDirection);\n ndl = clamp(ndl, 0.0, 1.0);\n float shadowContrib = 1.0;\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\n if( shadowEnabled )\n {\n shadowContrib = shadowContribsSpot[i];\n }\n#endif\n diffuseColor += lightColor * ndl * attenuation * (1.0-falloff) * shadowContrib;\n }\n#endif\n gl_FragColor.rgb *= diffuseColor;\n gl_FragColor.rgb += emission;\n if(lineWidth > 0.)\n {\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor(lineWidth)) * lineColor.a);\n }\n#ifdef ALPHA_TEST\n if (gl_FragColor.a < alphaCutoff) {\n discard;\n }\n#endif\n#ifdef TONEMAPPING\n gl_FragColor.rgb = ACESToneMapping(gl_FragColor.rgb);\n#endif\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n}\n@end"),Q.import(Ln),Q.import("@export clay.wireframe.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 world : WORLD;\nattribute vec3 position : POSITION;\nattribute vec3 barycentric;\n@import clay.chunk.skinning_header\nvarying vec3 v_Barycentric;\nvoid main()\n{\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0 );\n v_Barycentric = barycentric;\n}\n@end\n@export clay.wireframe.fragment\nuniform vec3 color : [0.0, 0.0, 0.0];\nuniform float alpha : 1.0;\nuniform float lineWidth : 1.0;\nvarying vec3 v_Barycentric;\n@import clay.util.edge_factor\nvoid main()\n{\n gl_FragColor.rgb = color;\n gl_FragColor.a = (1.0-edgeFactor(lineWidth)) * alpha;\n}\n@end"),Q.import(jn),Q.import(Tr),Hn.template("clay.basic",Q.source("clay.basic.vertex"),Q.source("clay.basic.fragment")),Hn.template("clay.lambert",Q.source("clay.lambert.vertex"),Q.source("clay.lambert.fragment")),Hn.template("clay.wireframe",Q.source("clay.wireframe.vertex"),Q.source("clay.wireframe.fragment")),Hn.template("clay.skybox",Q.source("clay.skybox.vertex"),Q.source("clay.skybox.fragment")),Hn.template("clay.prez",Q.source("clay.prez.vertex"),Q.source("clay.prez.fragment")),Hn.template("clay.standard",Q.source("clay.standard.vertex"),Q.source("clay.standard.fragment")),Hn.template("clay.standardMR",Q.source("clay.standardMR.vertex"),Q.source("clay.standardMR.fragment"));var qn={NORMAL:"normal",POSITION:"position",TEXCOORD_0:"texcoord0",TEXCOORD_1:"texcoord1",WEIGHTS_0:"weight",JOINTS_0:"joint",COLOR_0:"color"},Yn={5120:Ge.Int8Array,5121:Ge.Uint8Array,5122:Ge.Int16Array,5123:Ge.Uint16Array,5125:Ge.Uint32Array,5126:Ge.Float32Array},Kn={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},Zn=Fe.extend({rootNode:null,rootPath:null,textureRootPath:null,bufferRootPath:null,shader:"clay.standard",useStandardMaterial:!1,includeCamera:!0,includeAnimation:!0,includeMesh:!0,includeTexture:!0,crossOrigin:"",textureFlipY:!1,textureConvertToPOT:!1,shaderLibrary:null},function(){this.shaderLibrary||(this.shaderLibrary=Hn.createLibrary())},{load:function(t){var e=this,r=t.endsWith(".glb");null==this.rootPath&&(this.rootPath=t.slice(0,t.lastIndexOf("/"))),Ge.request.get({url:t,onprogress:function(t,r,n){e.trigger("progress",t,r,n)},onerror:function(t){e.trigger("error",t)},responseType:r?"arraybuffer":"text",onload:function(t){r?e.parseBinary(t):("string"==typeof t&&(t=JSON.parse(t)),e.parse(t))}})},parseBinary:function(t){var e=new Uint32Array(t,0,4);if(1179937895!==e[0])return void this.trigger("error","Invalid glTF binary format: Invalid header");if(e[0]<2)return void this.trigger("error","Only glTF2.0 is supported.");for(var r,n=new DataView(t,12),i=[],a=0;a=r.COLOR_ATTACHMENT0&&a<=r.COLOR_ATTACHMENT0+8&&i.push(a);n.drawBuffersEXT(i)}}this.trigger("beforerender",this,t);var o=this.clearDepth?r.DEPTH_BUFFER_BIT:0;if(r.depthMask(!0),this.clearColor){o|=r.COLOR_BUFFER_BIT,r.colorMask(!0,!0,!0,!0);var s=this.clearColor;Array.isArray(s)&&r.clearColor(s[0],s[1],s[2],s[3])}r.clear(o),this.blendWithPrevious?(r.enable(r.BLEND),this.material.transparent=!0):(r.disable(r.BLEND),this.material.transparent=!1),this.renderQuad(t),this.trigger("afterrender",this,t),e&&this.unbind(t,e)},renderQuad:function(t){si.material=this.material,t.renderPass([si],ui)},dispose:function(t){}});Q.import(jn);var hi=wn.extend(function(){var t=new Q({vertex:Q.source("clay.skybox.vertex"),fragment:Q.source("clay.skybox.fragment")}),e=new rr({shader:t,depthMask:!1});return{scene:null,geometry:new _n,material:e,environmentMap:null,culling:!1}},function(){var t=this.scene;t&&this.attachScene(t),this.environmentMap&&this.setEnvironmentMap(this.environmentMap)},{attachScene:function(t){this.scene&&this.detachScene(),t.skybox=this,this.scene=t,t.on("beforerender",this._beforeRenderScene,this)},detachScene:function(){this.scene&&(this.scene.off("beforerender",this._beforeRenderScene),this.scene.skybox=null),this.scene=null},dispose:function(t){this.detachScene(),this.geometry.dispose(t)},setEnvironmentMap:function(t){"texture2D"===t.textureType?(this.material.define("EQUIRECTANGULAR"),t.minFilter=yn.LINEAR):this.material.undefine("EQUIRECTANGULAR"),this.material.set("environmentMap",t)},getEnvironmentMap:function(){return this.material.get("environmentMap")},_beforeRenderScene:function(t,e,r){this.renderSkybox(t,r)},renderSkybox:function(t,e){this.position.copy(e.getWorldPosition()),this.update(),t.gl.disable(t.gl.BLEND), +this.material.get("lod")>0?this.material.define("fragment","LOD"):this.material.undefine("fragment","LOD"),t.renderPass([this],e)}}),ci=["px","nx","py","ny","pz","nz"],fi=Fe.extend(function(){var t={position:new wr,far:1e3,near:.1,texture:null,shadowMapPass:null},e=t._cameras={px:new Cn({fov:90}),nx:new Cn({fov:90}),py:new Cn({fov:90}),ny:new Cn({fov:90}),pz:new Cn({fov:90}),nz:new Cn({fov:90})};return e.px.lookAt(wr.POSITIVE_X,wr.NEGATIVE_Y),e.nx.lookAt(wr.NEGATIVE_X,wr.NEGATIVE_Y),e.py.lookAt(wr.POSITIVE_Y,wr.POSITIVE_Z),e.ny.lookAt(wr.NEGATIVE_Y,wr.NEGATIVE_Z),e.pz.lookAt(wr.POSITIVE_Z,wr.NEGATIVE_Y),e.nz.lookAt(wr.NEGATIVE_Z,wr.NEGATIVE_Y),t._frameBuffer=new ai,t},{getCamera:function(t){return this._cameras[t]},render:function(t,e,r){var n=t.gl;r||e.update();for(var i=this.texture.width,a=2*Math.atan(i/(i-.5))/Math.PI*180,o=0;o<6;o++){var s=ci[o],u=this._cameras[s];if(wr.copy(u.position,this.position),u.far=this.far,u.near=this.near,u.fov=a,this.shadowMapPass){u.update();var l=e.getBoundingBox();l.applyTransform(u.viewMatrix),e.viewBoundingBoxLastFrame.copy(l),this.shadowMapPass.render(t,e,u,!0)}this._frameBuffer.attach(this.texture,n.COLOR_ATTACHMENT0,n.TEXTURE_CUBE_MAP_POSITIVE_X+o),this._frameBuffer.bind(t),t.render(e,u,!0),this._frameBuffer.unbind(t)}},dispose:function(t){this._frameBuffer.dispose(t)}}),di=Et("DXT1"),pi=Et("DXT3"),mi=Et("DXT5"),_i={parse:function(t,e){var r=new Int32Array(t,0,31);if(542327876!==r[0])return null;if(4&!r(20))return null;var n,i,a=r(21),o=r[4],s=r[3],u=512&r[28],l=131072&r[2];switch(a){case di:n=8,i=yn.COMPRESSED_RGB_S3TC_DXT1_EXT;break;case pi:n=16,i=yn.COMPRESSED_RGBA_S3TC_DXT3_EXT;break;case mi:n=16,i=yn.COMPRESSED_RGBA_S3TC_DXT5_EXT;break;default:return null}var h=r[1]+4,c=u?6:1,f=1;l&&(f=Math.max(1,r[7]));for(var d=[],p=0;p=i)){a+=2;for(var o="";a20)return console.warn("Given image is not a height map"),t}var f,d,p,m;u%(4*n)==0?(f=o.data[u],p=o.data[u+4]):u%(4*n)==4*(n-1)?(f=o.data[u-4],p=o.data[u]):(f=o.data[u-4],p=o.data[u+4]),u<4*n?(d=o.data[u],m=o.data[u+4*n]):u>n*(i-1)*4?(d=o.data[u-4*n],m=o.data[u]):(d=o.data[u-4*n],m=o.data[u+4*n]),s.data[u]=f-p+127,s.data[u+1]=d-m+127,s.data[u+2]=255,s.data[u+3]=255}return a.putImageData(s,0,0),r},isHeightImage:function(t,e,r){if(!t||!t.width||!t.height)return!1;var n=document.createElement("canvas"),i=n.getContext("2d"),a=e||32;r=r||20,n.width=n.height=a,i.drawImage(t,0,0,a,a);for(var o=i.getImageData(0,0,a,a),s=0;sr)return!1}return!0},_fetchTexture:function(t,e,r){Ge.request.get({url:t,responseType:"arraybuffer",onload:e,onerror:r})},createChessboard:function(t,e,r,n){t=t||512,e=e||64,r=r||"black",n=n||"white";var i=Math.ceil(t/e),a=document.createElement("canvas");a.width=t,a.height=t;var o=a.getContext("2d");o.fillStyle=n,o.fillRect(0,0,t,t),o.fillStyle=r;for(var s=0;s 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nvoid main() {\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(v_WorldPosition - eyePos);\n vec3 N = V;\n vec3 prefilteredColor = vec3(0.0);\n float totalWeight = 0.0;\n float fMaxSampleNumber = float(SAMPLE_NUMBER);\n for (int i = 0; i < SAMPLE_NUMBER; i++) {\n vec3 H = importanceSampleNormal(float(i) / fMaxSampleNumber, roughness, N);\n vec3 L = reflect(-V, H);\n float NoL = clamp(dot(N, L), 0.0, 1.0);\n if (NoL > 0.0) {\n prefilteredColor += decodeHDR(textureCube(environmentMap, L)).rgb * NoL;\n totalWeight += NoL;\n }\n }\n gl_FragColor = encodeHDR(vec4(prefilteredColor / totalWeight, 1.0));\n}\n"})});c.set("normalDistribution",n),r.encodeRGBM&&c.define("fragment","RGBM_ENCODE"),r.decodeRGBM&&c.define("fragment","RGBM_DECODE");var f,d=new on;if("texture2D"===e.textureType){var p=new Sn({width:a,height:o,type:s===yn.FLOAT?yn.HALF_FLOAT:s});xi.panoramaToCubeMap(t,e,p,{encodeRGBM:r.decodeRGBM}),e=p}f=new hi({scene:d,material:c}),f.material.set("environmentMap",e);var m=new fi({texture:u});r.encodeRGBM&&(s=u.type=yn.UNSIGNED_BYTE);for(var _=new En({width:a,height:o,type:s}),g=new ai({depthBuffer:!1}),v=Ge[s===yn.UNSIGNED_BYTE?"Uint8Array":"Float32Array"],y=0;y 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nfloat G_Smith(float roughness, float NoV, float NoL) {\n float k = roughness * roughness / 2.0;\n float G1V = NoV / (NoV * (1.0 - k) + k);\n float G1L = NoL / (NoL * (1.0 - k) + k);\n return G1L * G1V;\n}\nvoid main() {\n vec2 uv = gl_FragCoord.xy / viewportSize;\n float NoV = uv.x;\n float roughness = uv.y;\n vec3 V;\n V.x = sqrt(1.0 - NoV * NoV);\n V.y = 0.0;\n V.z = NoV;\n float A = 0.0;\n float B = 0.0;\n for (int i = 0; i < SAMPLE_NUMBER; i++) {\n vec3 H = importanceSampleNormal(float(i) / fSampleNumber, roughness, N);\n vec3 L = reflect(-V, H);\n float NoL = clamp(L.z, 0.0, 1.0);\n float NoH = clamp(H.z, 0.0, 1.0);\n float VoH = clamp(dot(V, H), 0.0, 1.0);\n if (NoL > 0.0) {\n float G = G_Smith(roughness, NoV, NoL);\n float G_Vis = G * VoH / (NoH * NoV);\n float Fc = pow(1.0 - VoH, 5.0);\n A += (1.0 - Fc) * G_Vis;\n B += Fc * G_Vis;\n }\n }\n gl_FragColor = vec4(vec2(A, B) / fSampleNumber, 0.0, 1.0);\n}\n"}),i=new En({width:512,height:256,type:yn.HALF_FLOAT,wrapS:yn.CLAMP_TO_EDGE,wrapT:yn.CLAMP_TO_EDGE,minFilter:yn.NEAREST,magFilter:yn.NEAREST,useMipmap:!1});return n.setUniform("normalDistribution",e),n.setUniform("viewportSize",[512,256]),n.attachOutput(i),n.render(t,r),r.dispose(t),i},Ei.generateNormalDistribution=function(t,e){for(var t=t||256,e=e||1024,r=new En({width:t,height:e,type:yn.FLOAT,minFilter:yn.NEAREST,magFilter:yn.NEAREST,wrapS:yn.CLAMP_TO_EDGE,wrapT:yn.CLAMP_TO_EDGE,useMipmap:!1}),n=new Float32Array(e*t*4),i=[],a=0;a>>16)>>>0;l=((1431655765&l)<<1|(2863311530&l)>>>1)>>>0,l=((858993459&l)<<2|(3435973836&l)>>>2)>>>0,l=((252645135&l)<<4|(4042322160&l)>>>4)>>>0,l=(((16711935&l)<<8|(4278255360&l)>>>8)>>>0)/4294967296;var h=Math.sqrt((1-l)/(1+(s*s-1)*l));i[u]=h}for(var u=0;u 0.0) {\n if (texture2D(alphaMap, v_Texcoord).a <= alphaCutoff) {\n discard;\n }\n }\n#ifdef USE_VSM\n depth = depth * 0.5 + 0.5;\n float moment1 = depth;\n float moment2 = depth * depth;\n float dx = dFdx(depth);\n float dy = dFdy(depth);\n moment2 += 0.25*(dx*dx+dy*dy);\n gl_FragColor = vec4(moment1, moment2, 0.0, 1.0);\n#else\n float dx = dFdx(depth);\n float dy = dFdy(depth);\n depth += sqrt(dx*dx + dy*dy) * slopeScale + bias;\n gl_FragColor = encodeFloat(depth * 0.5 + 0.5);\n#endif\n}\n@end\n@export clay.sm.debug_depth\nuniform sampler2D depthMap;\nvarying vec2 v_Texcoord;\n@import clay.util.decode_float\nvoid main() {\n vec4 tex = texture2D(depthMap, v_Texcoord);\n#ifdef USE_VSM\n gl_FragColor = vec4(tex.rgb, 1.0);\n#else\n float depth = decodeFloat(tex);\n gl_FragColor = vec4(depth, depth, depth, 1.0);\n#endif\n}\n@end\n@export clay.sm.distance.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 world : WORLD;\nattribute vec3 position : POSITION;\n@import clay.chunk.skinning_header\nvarying vec3 v_WorldPosition;\nvoid main (){\n vec3 skinnedPosition = position;\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition , 1.0);\n v_WorldPosition = (world * vec4(skinnedPosition, 1.0)).xyz;\n}\n@end\n@export clay.sm.distance.fragment\nuniform vec3 lightPosition;\nuniform float range : 100;\nvarying vec3 v_WorldPosition;\n@import clay.util.encode_float\nvoid main(){\n float dist = distance(lightPosition, v_WorldPosition);\n#ifdef USE_VSM\n gl_FragColor = vec4(dist, dist * dist, 0.0, 0.0);\n#else\n dist = dist / range;\n gl_FragColor = encodeFloat(dist);\n#endif\n}\n@end\n@export clay.plugin.shadow_map_common\n@import clay.util.decode_float\nfloat tapShadowMap(sampler2D map, vec2 uv, float z){\n vec4 tex = texture2D(map, uv);\n return step(z, decodeFloat(tex) * 2.0 - 1.0);\n}\nfloat pcf(sampler2D map, vec2 uv, float z, float textureSize, vec2 scale) {\n float shadowContrib = tapShadowMap(map, uv, z);\n vec2 offset = vec2(1.0 / textureSize) * scale;\n#ifdef PCF_KERNEL_SIZE\n for (int _idx_ = 0; _idx_ < PCF_KERNEL_SIZE; _idx_++) {{\n shadowContrib += tapShadowMap(map, uv + offset * pcfKernel[_idx_], z);\n }}\n return shadowContrib / float(PCF_KERNEL_SIZE + 1);\n#else\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, 0.0), z);\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(0.0, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, 0.0), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, -offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, -offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(0.0, -offset.y), z);\n return shadowContrib / 9.0;\n#endif\n}\nfloat pcf(sampler2D map, vec2 uv, float z, float textureSize) {\n return pcf(map, uv, z, textureSize, vec2(1.0));\n}\nfloat chebyshevUpperBound(vec2 moments, float z){\n float p = 0.0;\n z = z * 0.5 + 0.5;\n if (z <= moments.x) {\n p = 1.0;\n }\n float variance = moments.y - moments.x * moments.x;\n variance = max(variance, 0.0000001);\n float mD = moments.x - z;\n float pMax = variance / (variance + mD * mD);\n pMax = clamp((pMax-0.4)/(1.0-0.4), 0.0, 1.0);\n return max(p, pMax);\n}\nfloat computeShadowContrib(\n sampler2D map, mat4 lightVPM, vec3 position, float textureSize, vec2 scale, vec2 offset\n) {\n vec4 posInLightSpace = lightVPM * vec4(position, 1.0);\n posInLightSpace.xyz /= posInLightSpace.w;\n float z = posInLightSpace.z;\n if(all(greaterThan(posInLightSpace.xyz, vec3(-0.99, -0.99, -1.0))) &&\n all(lessThan(posInLightSpace.xyz, vec3(0.99, 0.99, 1.0)))){\n vec2 uv = (posInLightSpace.xy+1.0) / 2.0;\n #ifdef USE_VSM\n vec2 moments = texture2D(map, uv * scale + offset).xy;\n return chebyshevUpperBound(moments, z);\n #else\n return pcf(map, uv * scale + offset, z, textureSize, scale);\n #endif\n }\n return 1.0;\n}\nfloat computeShadowContrib(sampler2D map, mat4 lightVPM, vec3 position, float textureSize) {\n return computeShadowContrib(map, lightVPM, position, textureSize, vec2(1.0), vec2(0.0));\n}\nfloat computeShadowContribOmni(samplerCube map, vec3 direction, float range)\n{\n float dist = length(direction);\n vec4 shadowTex = textureCube(map, direction);\n#ifdef USE_VSM\n vec2 moments = shadowTex.xy;\n float variance = moments.y - moments.x * moments.x;\n float mD = moments.x - dist;\n float p = variance / (variance + mD * mD);\n if(moments.x + 0.001 < dist){\n return clamp(p, 0.0, 1.0);\n }else{\n return 1.0;\n }\n#else\n return step(dist, (decodeFloat(shadowTex) + 0.0002) * range);\n#endif\n}\n@end\n@export clay.plugin.compute_shadow_map\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT) || defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT) || defined(POINT_LIGHT_SHADOWMAP_COUNT)\n#ifdef SPOT_LIGHT_SHADOWMAP_COUNT\nuniform sampler2D spotLightShadowMaps[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform mat4 spotLightMatrices[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform float spotLightShadowMapSizes[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\n#ifdef DIRECTIONAL_LIGHT_SHADOWMAP_COUNT\n#if defined(SHADOW_CASCADE)\nuniform sampler2D directionalLightShadowMaps[1]:unconfigurable;\nuniform mat4 directionalLightMatrices[SHADOW_CASCADE]:unconfigurable;\nuniform float directionalLightShadowMapSizes[1]:unconfigurable;\nuniform float shadowCascadeClipsNear[SHADOW_CASCADE]:unconfigurable;\nuniform float shadowCascadeClipsFar[SHADOW_CASCADE]:unconfigurable;\n#else\nuniform sampler2D directionalLightShadowMaps[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform mat4 directionalLightMatrices[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform float directionalLightShadowMapSizes[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\n#endif\n#ifdef POINT_LIGHT_SHADOWMAP_COUNT\nuniform samplerCube pointLightShadowMaps[POINT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\nuniform bool shadowEnabled : true;\n#ifdef PCF_KERNEL_SIZE\nuniform vec2 pcfKernel[PCF_KERNEL_SIZE];\n#endif\n@import clay.plugin.shadow_map_common\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\nvoid computeShadowOfSpotLights(vec3 position, inout float shadowContribs[SPOT_LIGHT_COUNT] ) {\n float shadowContrib;\n for(int _idx_ = 0; _idx_ < SPOT_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n shadowContrib = computeShadowContrib(\n spotLightShadowMaps[_idx_], spotLightMatrices[_idx_], position,\n spotLightShadowMapSizes[_idx_]\n );\n shadowContribs[_idx_] = shadowContrib;\n }}\n for(int _idx_ = SPOT_LIGHT_SHADOWMAP_COUNT; _idx_ < SPOT_LIGHT_COUNT; _idx_++){{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n#ifdef SHADOW_CASCADE\nvoid computeShadowOfDirectionalLights(vec3 position, inout float shadowContribs[DIRECTIONAL_LIGHT_COUNT]){\n float depth = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far)\n / (gl_DepthRange.far - gl_DepthRange.near);\n float shadowContrib;\n shadowContribs[0] = 1.0;\n for (int _idx_ = 0; _idx_ < SHADOW_CASCADE; _idx_++) {{\n if (\n depth >= shadowCascadeClipsNear[_idx_] &&\n depth <= shadowCascadeClipsFar[_idx_]\n ) {\n shadowContrib = computeShadowContrib(\n directionalLightShadowMaps[0], directionalLightMatrices[_idx_], position,\n directionalLightShadowMapSizes[0],\n vec2(1.0 / float(SHADOW_CASCADE), 1.0),\n vec2(float(_idx_) / float(SHADOW_CASCADE), 0.0)\n );\n shadowContribs[0] = shadowContrib;\n }\n }}\n for(int _idx_ = DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#else\nvoid computeShadowOfDirectionalLights(vec3 position, inout float shadowContribs[DIRECTIONAL_LIGHT_COUNT]){\n float shadowContrib;\n for(int _idx_ = 0; _idx_ < DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n shadowContrib = computeShadowContrib(\n directionalLightShadowMaps[_idx_], directionalLightMatrices[_idx_], position,\n directionalLightShadowMapSizes[_idx_]\n );\n shadowContribs[_idx_] = shadowContrib;\n }}\n for(int _idx_ = DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#endif\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\nvoid computeShadowOfPointLights(vec3 position, inout float shadowContribs[POINT_LIGHT_COUNT] ){\n vec3 lightPosition;\n vec3 direction;\n for(int _idx_ = 0; _idx_ < POINT_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n lightPosition = pointLightPosition[_idx_];\n direction = position - lightPosition;\n shadowContribs[_idx_] = computeShadowContribOmni(pointLightShadowMaps[_idx_], direction, pointLightRange[_idx_]);\n }}\n for(int _idx_ = POINT_LIGHT_SHADOWMAP_COUNT; _idx_ < POINT_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#endif\n@end");var Li=Fe.extend(function(){return{softShadow:Li.PCF,shadowBlur:1,lightFrustumBias:"auto",kernelPCF:new Float32Array([1,0,1,1,-1,1,0,1,-1,0,-1,-1,1,-1,0,-1]),precision:"highp",_lastRenderNotCastShadow:!1,_frameBuffer:new ai,_textures:{},_shadowMapNumber:{POINT_LIGHT:0,DIRECTIONAL_LIGHT:0,SPOT_LIGHT:0},_depthMaterials:{},_distanceMaterials:{},_receivers:[],_lightsCastShadow:[],_lightCameras:{},_lightMaterials:{},_texturePool:new Mi}},function(){this._gaussianPassH=new li({fragment:Q.source("clay.compositor.gaussian_blur")}),this._gaussianPassV=new li({fragment:Q.source("clay.compositor.gaussian_blur")}),this._gaussianPassH.setUniform("blurSize",this.shadowBlur),this._gaussianPassH.setUniform("blurDir",0),this._gaussianPassV.setUniform("blurSize",this.shadowBlur),this._gaussianPassV.setUniform("blurDir",1),this._outputDepthPass=new li({fragment:Q.source("clay.sm.debug_depth")})},{render:function(t,e,r,n){r||(r=e.getMainCamera()),this.trigger("beforerender",this,t,e,r),this._renderShadowPass(t,e,r,n),this.trigger("afterrender",this,t,e,r)},renderDebug:function(t,e){t.saveClear();var r=t.viewport,n=0,i=e||r.width/4,a=i;this.softShadow===Li.VSM?this._outputDepthPass.material.define("fragment","USE_VSM"):this._outputDepthPass.material.undefine("fragment","USE_VSM");for(var o in this._textures){var s=this._textures[o];t.setViewport(n,0,i*s.width/s.height,a),this._outputDepthPass.setUniform("depthMap",s),this._outputDepthPass.render(t),n+=i*s.width/s.height}t.setViewport(r),t.restoreClear()},_updateReceivers:function(t,e){if(e.receiveShadow?(this._receivers.push(e),e.material.set("shadowEnabled",1),e.material.set("pcfKernel",this.kernelPCF)):e.material.set("shadowEnabled",0),this.softShadow===Li.VSM)e.material.define("fragment","USE_VSM"),e.material.undefine("fragment","PCF_KERNEL_SIZE");else{e.material.undefine("fragment","USE_VSM");var r=this.kernelPCF;r&&r.length?e.material.define("fragment","PCF_KERNEL_SIZE",r.length/2):e.material.undefine("fragment","PCF_KERNEL_SIZE")}},_update:function(t,e){var r=this;e.traverse(function(e){e.isRenderable()&&r._updateReceivers(t,e)});for(var n=0;n4){console.warn("Support at most 4 cascade");continue}m.shadowCascade>1&&(s=m),this.renderDirectionalLightShadow(t,e,r,m,f,c,h)}else"SPOT_LIGHT"===m.type?this.renderSpotLightShadow(t,e,m,l,u):"POINT_LIGHT"===m.type&&this.renderPointLightShadow(t,e,m,d);this._shadowMapNumber[m.type]++}for(var _ in this._shadowMapNumber)for(var g=this._shadowMapNumber[_],v=_+"_SHADOWMAP_COUNT",p=0;p0?T.define("fragment",v,g):T.isDefined("fragment",v)&&T.undefine("fragment",v))}for(var p=0;p0){var E=h.map(i);if(x.directionalLightShadowMaps={value:h,type:"tv"},x.directionalLightMatrices={value:c,type:"m4v"},x.directionalLightShadowMapSizes={value:E,type:"1fv"},s){var A=f.slice(),b=f.slice();A.pop(),b.shift(),A.reverse(),b.reverse(),c.reverse(),x.shadowCascadeClipsNear={value:A,type:"1fv"},x.shadowCascadeClipsFar={value:b,type:"1fv"}}}if(u.length>0){var S=u.map(i),x=e.shadowUniforms;x.spotLightShadowMaps={value:u,type:"tv"},x.spotLightMatrices={value:l,type:"m4v"},x.spotLightShadowMapSizes={value:S,type:"1fv"}}d.length>0&&(x.pointLightShadowMaps={value:d,type:"tv"})}},renderDirectionalLightShadow:function(){var t=new $r,e=new Br,r=new Gr,n=new Br,i=new Br,a=new Br,o=new Br;return function(s,u,l,h,c,f,d){var p=this._getDepthMaterial(h),m={getMaterial:function(t){return t.shadowDepthMaterial||p},isMaterialChanged:Pt,getUniform:Nt,ifRender:function(t){return t.castShadow},sortCompare:Sr.opaqueSortCompare};if(!u.viewBoundingBoxLastFrame.isFinite()){var _=u.getBoundingBox();u.viewBoundingBoxLastFrame.copy(_).applyTransform(l.viewMatrix)}var g=Math.min(-u.viewBoundingBoxLastFrame.min.z,l.far),v=Math.max(-u.viewBoundingBoxLastFrame.max.z,l.near),y=this._getDirectionalLightCamera(h,u,l),T=a.array;o.copy(y.projectionMatrix),xr.invert(i.array,y.worldTransform.array),xr.multiply(i.array,i.array,l.worldTransform.array),xr.multiply(T,o.array,i.array);for(var x=[],E=l instanceof Cn,A=(l.near+l.far)/(l.near-l.far),b=2*l.near*l.far/(l.near-l.far),S=0;S<=h.shadowCascade;S++){var M=v*Math.pow(g/v,S/h.shadowCascade),w=v+(g-v)*S/h.shadowCascade,C=M*h.cascadeSplitLogFactor+w*(1-h.cascadeSplitLogFactor);x.push(C),c.push(-(-C*A+b)/-C)}var R=this._getTexture(h,h.shadowCascade);d.push(R);var L=s.viewport,N=s.gl;this._frameBuffer.attach(R),this._frameBuffer.bind(s),N.clear(N.COLOR_BUFFER_BIT|N.DEPTH_BUFFER_BIT);for(var S=0;Sf?s>d?p[i>0?"px":"nx"]=!0:p[o>0?"pz":"nz"]=!0:f>d?p[a>0?"py":"ny"]=!0:p[o>0?"pz":"nz"]=!0}for(var r=0;r=0&&x[y]>1e-4&&(we.transformMat4(b,T,g[E[y]]),we.scaleAndAdd(A,A,b,x[y]));S.set(v,A)}}for(var v=0;v=0){var l="touchend"!==u?i.targetTouches[0]:i.changedTouches[0];"touchstart"===u?u="mousedown":"touchend"===u?u="mouseup":"touchmove"===u&&(u="mousemove"),a=l.clientX-s.left,o=l.clientY-s.top}else a=i.clientX-s.left,o=i.clientY-s.top;var h,c=t.pick(a,o);if("DOMMouseScroll"!==u&&"mousewheel"!==u||(h=i.wheelDelta?i.wheelDelta/120:-(i.detail||0)/3),c){if(c.target.silent)return;if("mousemove"===u){var f=c.target!==r;f&&r&&Ht(r,kt("mouseout",{target:r},a,o)),Ht(c.target,kt("mousemove",c,a,o)),f&&Ht(c.target,kt("mouseover",c,a,o))}else Ht(c.target,kt(u,c,a,o,h));r=c.target}else r&&(Ht(r,kt("mouseout",{target:r},a,o)),r=null)}})},this)},Dt.prototype._updateGraphicOptions=function(t,e,r){for(var n,i=!!t.tonemapping,a=!!t.linear,o=0;o0){var e=this.outputs[t];e.keepLastFrame?(this._prevOutputTextures[t]&&this._compositor.releaseTexture(this._prevOutputTextures[t]),this._prevOutputTextures[t]=this._outputTextures[t]):this._compositor.releaseTexture(this._outputTextures[t])}}}),Gi=Fe.extend(function(){return{nodes:[]}},{dirty:function(){this._dirty=!0},addNode:function(t){this.nodes.indexOf(t)>=0||(this.nodes.push(t),this._dirty=!0)},removeNode:function(t){"string"==typeof t&&(t=this.getNodeByName(t));var e=this.nodes.indexOf(t);e>=0&&(this.nodes.splice(e,1),this._dirty=!0)},getNodeByName:function(t){for(var e=0;e=e.COLOR_ATTACHMENT0&&u<=e.COLOR_ATTACHMENT0+8&&h.push(u);l.drawBuffersEXT(h)}t.saveClear(),t.clearBit=qe.DEPTH_BUFFER_BIT|qe.COLOR_BUFFER_BIT,r=t.render(this.scene,this.camera,!this.autoUpdateScene,this.preZ),t.restoreClear(),n.unbind(t)}else r=t.render(this.scene,this.camera,!this.autoUpdateScene,this.preZ);this.trigger("afterrender",r),this._rendering=!1,this._rendered=!0}}),zi=Hi.extend(function(){return{texture:null,outputs:{color:{}}}},function(){},{getOutput:function(t,e){return this.texture},beforeFrame:function(){},afterFrame:function(){}}),Xi=Hi.extend(function(){return{name:"",inputs:{},outputs:null,shader:"",inputLinks:{},outputLinks:{},pass:null,_prevOutputTextures:{},_outputTextures:{},_outputReferences:{},_rendering:!1,_rendered:!1,_compositor:null}},function(){var t=new li({fragment:this.shader});this.pass=t},{render:function(t,e){this.trigger("beforerender",t),this._rendering=!0;var r=t.gl;for(var n in this.inputLinks){var i=this.inputLinks[n],a=i.node.getOutput(t,i.pin);this.pass.setUniform(n,a)}if(this.outputs){this.pass.outputs={};var o={};for(var s in this.outputs){var u=this.updateParameter(s,t);isNaN(u.width)&&this.updateParameter(s,t);var l=this.outputs[s],h=this._compositor.allocateTexture(u);this._outputTextures[s]=h;var c=l.attachment||r.COLOR_ATTACHMENT0;"string"==typeof c&&(c=r[c]),o[c]=h}this._compositor.getFrameBuffer().bind(t);for(var c in o)this._compositor.getFrameBuffer().attach(o[c],c);this.pass.render(t),this._compositor.getFrameBuffer().updateMipmap(t)}else this.pass.outputs=null,this._compositor.getFrameBuffer().unbind(t),this.pass.render(t,e);for(var n in this.inputLinks){var i=this.inputLinks[n];i.node.removeReference(i.pin)}this._rendering=!1,this._rendered=!0,this.trigger("afterrender",t)},updateParameter:function(t,e){var r=this.outputs[t],n=r.parameters,i=r._parametersCopy;if(i||(i=r._parametersCopy={}),n)for(var a in n)"width"!==a&&"height"!==a&&(i[a]=n[a]);var o,s;return o="function"==typeof n.width?n.width.call(this,e):n.width,s="function"==typeof n.height?n.height.call(this,e):n.height,o=Math.ceil(o),s=Math.ceil(s),i.width===o&&i.height===s||this._outputTextures[t]&&this._outputTextures[t].dispose(e),i.width=o,i.height=s,i},setParameter:function(t,e){this.pass.setUniform(t,e)},getParameter:function(t){return this.pass.getUniform(t)},setParameters:function(t){for(var e in t)this.setParameter(e,t[e])},define:function(t,e){this.pass.material.define("fragment",t,e)},undefine:function(t){this.pass.material.undefine("fragment",t)},removeReference:function(t){if(0===--this._outputReferences[t]){this.outputs[t].keepLastFrame?(this._prevOutputTextures[t]&&this._compositor.releaseTexture(this._prevOutputTextures[t]),this._prevOutputTextures[t]=this._outputTextures[t]):this._compositor.releaseTexture(this._outputTextures[t])}},clear:function(){Hi.prototype.clear.call(this),this.pass.material.disableTexturesAll()} +}),ji="@export clay.compositor.coloradjust\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float brightness : 0.0;\nuniform float contrast : 1.0;\nuniform float exposure : 0.0;\nuniform float gamma : 1.0;\nuniform float saturation : 1.0;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = clamp(tex.rgb + vec3(brightness), 0.0, 1.0);\n color = clamp( (color-vec3(0.5))*contrast+vec3(0.5), 0.0, 1.0);\n color = clamp( color * pow(2.0, exposure), 0.0, 1.0);\n color = clamp( pow(color, vec3(gamma)), 0.0, 1.0);\n float luminance = dot( color, w );\n color = mix(vec3(luminance), color, saturation);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.brightness\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float brightness : 0.0;\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = tex.rgb + vec3(brightness);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.contrast\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float contrast : 1.0;\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = (tex.rgb-vec3(0.5))*contrast+vec3(0.5);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.exposure\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float exposure : 0.0;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = tex.rgb * pow(2.0, exposure);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.gamma\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float gamma : 1.0;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = pow(tex.rgb, vec3(gamma));\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.saturation\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float saturation : 1.0;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = tex.rgb;\n float luminance = dot(color, w);\n color = mix(vec3(luminance), color, saturation);\n gl_FragColor = vec4(color, tex.a);\n}\n@end",qi="@export clay.compositor.kernel.gaussian_9\nfloat gaussianKernel[9];\ngaussianKernel[0] = 0.07;\ngaussianKernel[1] = 0.09;\ngaussianKernel[2] = 0.12;\ngaussianKernel[3] = 0.14;\ngaussianKernel[4] = 0.16;\ngaussianKernel[5] = 0.14;\ngaussianKernel[6] = 0.12;\ngaussianKernel[7] = 0.09;\ngaussianKernel[8] = 0.07;\n@end\n@export clay.compositor.kernel.gaussian_13\nfloat gaussianKernel[13];\ngaussianKernel[0] = 0.02;\ngaussianKernel[1] = 0.03;\ngaussianKernel[2] = 0.06;\ngaussianKernel[3] = 0.08;\ngaussianKernel[4] = 0.11;\ngaussianKernel[5] = 0.13;\ngaussianKernel[6] = 0.14;\ngaussianKernel[7] = 0.13;\ngaussianKernel[8] = 0.11;\ngaussianKernel[9] = 0.08;\ngaussianKernel[10] = 0.06;\ngaussianKernel[11] = 0.03;\ngaussianKernel[12] = 0.02;\n@end\n@export clay.compositor.gaussian_blur\n#define SHADER_NAME gaussian_blur\nuniform sampler2D texture;varying vec2 v_Texcoord;\nuniform float blurSize : 2.0;\nuniform vec2 textureSize : [512.0, 512.0];\nuniform float blurDir : 0.0;\n@import clay.util.rgbm\n@import clay.util.clamp_sample\nvoid main (void)\n{\n @import clay.compositor.kernel.gaussian_9\n vec2 off = blurSize / textureSize;\n off *= vec2(1.0 - blurDir, blurDir);\n vec4 sum = vec4(0.0);\n float weightAll = 0.0;\n for (int i = 0; i < 9; i++) {\n float w = gaussianKernel[i];\n vec4 texel = decodeHDR(clampSample(texture, v_Texcoord + float(i - 4) * off));\n sum += texel * w;\n weightAll += w;\n }\n gl_FragColor = encodeHDR(sum / max(weightAll, 0.01));\n}\n@end\n",Yi="@export clay.compositor.hdr.log_lum\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = decodeHDR(texture2D(texture, v_Texcoord));\n float luminance = dot(tex.rgb, w);\n luminance = log(luminance + 0.001);\n gl_FragColor = encodeHDR(vec4(vec3(luminance), 1.0));\n}\n@end\n@export clay.compositor.hdr.lum_adaption\nvarying vec2 v_Texcoord;\nuniform sampler2D adaptedLum;\nuniform sampler2D currentLum;\nuniform float frameTime : 0.02;\n@import clay.util.rgbm\nvoid main()\n{\n float fAdaptedLum = decodeHDR(texture2D(adaptedLum, vec2(0.5, 0.5))).r;\n float fCurrentLum = exp(encodeHDR(texture2D(currentLum, vec2(0.5, 0.5))).r);\n fAdaptedLum += (fCurrentLum - fAdaptedLum) * (1.0 - pow(0.98, 30.0 * frameTime));\n gl_FragColor = encodeHDR(vec4(vec3(fAdaptedLum), 1.0));\n}\n@end\n@export clay.compositor.lum\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord );\n float luminance = dot(tex.rgb, w);\n gl_FragColor = vec4(vec3(luminance), 1.0);\n}\n@end",Ki="\n@export clay.compositor.lut\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform sampler2D lookup;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n float blueColor = tex.b * 63.0;\n vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.g);\n vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.g);\n vec4 newColor1 = texture2D(lookup, texPos1);\n vec4 newColor2 = texture2D(lookup, texPos2);\n vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n gl_FragColor = vec4(newColor.rgb, tex.w);\n}\n@end",Zi="@export clay.compositor.vignette\n#define OUTPUT_ALPHA\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float darkness: 1;\nuniform float offset: 1;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 texel = decodeHDR(texture2D(texture, v_Texcoord));\n gl_FragColor.rgb = texel.rgb;\n vec2 uv = (v_Texcoord - vec2(0.5)) * vec2(offset);\n gl_FragColor = encodeHDR(vec4(mix(texel.rgb, vec3(1.0 - darkness), dot(uv, uv)), texel.a));\n}\n@end",Ji="@export clay.compositor.output\n#define OUTPUT_ALPHA\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = decodeHDR(texture2D(texture, v_Texcoord));\n gl_FragColor.rgb = tex.rgb;\n#ifdef OUTPUT_ALPHA\n gl_FragColor.a = tex.a;\n#else\n gl_FragColor.a = 1.0;\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n#ifdef PREMULTIPLY_ALPHA\n gl_FragColor.rgb *= gl_FragColor.a;\n#endif\n}\n@end",Qi="@export clay.compositor.bright\nuniform sampler2D texture;\nuniform float threshold : 1;\nuniform float scale : 1.0;\nuniform vec2 textureSize: [512, 512];\nvarying vec2 v_Texcoord;\nconst vec3 lumWeight = vec3(0.2125, 0.7154, 0.0721);\n@import clay.util.rgbm\nvec4 median(vec4 a, vec4 b, vec4 c)\n{\n return a + b + c - min(min(a, b), c) - max(max(a, b), c);\n}\nvoid main()\n{\n vec4 texel = decodeHDR(texture2D(texture, v_Texcoord));\n#ifdef ANTI_FLICKER\n vec3 d = 1.0 / textureSize.xyx * vec3(1.0, 1.0, 0.0);\n vec4 s1 = decodeHDR(texture2D(texture, v_Texcoord - d.xz));\n vec4 s2 = decodeHDR(texture2D(texture, v_Texcoord + d.xz));\n vec4 s3 = decodeHDR(texture2D(texture, v_Texcoord - d.zy));\n vec4 s4 = decodeHDR(texture2D(texture, v_Texcoord + d.zy));\n texel = median(median(texel, s1, s2), s3, s4);\n#endif\n float lum = dot(texel.rgb , lumWeight);\n vec4 color;\n if (lum > threshold && texel.a > 0.0)\n {\n color = vec4(texel.rgb * scale, texel.a * scale);\n }\n else\n {\n color = vec4(0.0);\n }\n gl_FragColor = encodeHDR(color);\n}\n@end\n",$i="@export clay.compositor.downsample\nuniform sampler2D texture;\nuniform vec2 textureSize : [512, 512];\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nfloat brightness(vec3 c)\n{\n return max(max(c.r, c.g), c.b);\n}\n@import clay.util.clamp_sample\nvoid main()\n{\n vec4 d = vec4(-1.0, -1.0, 1.0, 1.0) / textureSize.xyxy;\n#ifdef ANTI_FLICKER\n vec3 s1 = decodeHDR(clampSample(texture, v_Texcoord + d.xy)).rgb;\n vec3 s2 = decodeHDR(clampSample(texture, v_Texcoord + d.zy)).rgb;\n vec3 s3 = decodeHDR(clampSample(texture, v_Texcoord + d.xw)).rgb;\n vec3 s4 = decodeHDR(clampSample(texture, v_Texcoord + d.zw)).rgb;\n float s1w = 1.0 / (brightness(s1) + 1.0);\n float s2w = 1.0 / (brightness(s2) + 1.0);\n float s3w = 1.0 / (brightness(s3) + 1.0);\n float s4w = 1.0 / (brightness(s4) + 1.0);\n float oneDivideSum = 1.0 / (s1w + s2w + s3w + s4w);\n vec4 color = vec4(\n (s1 * s1w + s2 * s2w + s3 * s3w + s4 * s4w) * oneDivideSum,\n 1.0\n );\n#else\n vec4 color = decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.xw));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.zw));\n color *= 0.25;\n#endif\n gl_FragColor = encodeHDR(color);\n}\n@end",ta="\n@export clay.compositor.upsample\n#define HIGH_QUALITY\nuniform sampler2D texture;\nuniform vec2 textureSize : [512, 512];\nuniform float sampleScale: 0.5;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\n@import clay.util.clamp_sample\nvoid main()\n{\n#ifdef HIGH_QUALITY\n vec4 d = vec4(1.0, 1.0, -1.0, 0.0) / textureSize.xyxy * sampleScale;\n vec4 s;\n s = decodeHDR(clampSample(texture, v_Texcoord - d.xy));\n s += decodeHDR(clampSample(texture, v_Texcoord - d.wy)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord - d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zw)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord )) * 4.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xw)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.wy)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n gl_FragColor = encodeHDR(s / 16.0);\n#else\n vec4 d = vec4(-1.0, -1.0, +1.0, +1.0) / textureSize.xyxy;\n vec4 s;\n s = decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xw));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zw));\n gl_FragColor = encodeHDR(s / 4.0);\n#endif\n}\n@end",ea="@export clay.compositor.hdr.composite\n#define TONEMAPPING\nuniform sampler2D texture;\n#ifdef BLOOM_ENABLED\nuniform sampler2D bloom;\n#endif\n#ifdef LENSFLARE_ENABLED\nuniform sampler2D lensflare;\nuniform sampler2D lensdirt;\n#endif\n#ifdef LUM_ENABLED\nuniform sampler2D lum;\n#endif\n#ifdef LUT_ENABLED\nuniform sampler2D lut;\n#endif\n#ifdef COLOR_CORRECTION\nuniform float brightness : 0.0;\nuniform float contrast : 1.0;\nuniform float saturation : 1.0;\n#endif\n#ifdef VIGNETTE\nuniform float vignetteDarkness: 1.0;\nuniform float vignetteOffset: 1.0;\n#endif\nuniform float exposure : 1.0;\nuniform float bloomIntensity : 0.25;\nuniform float lensflareIntensity : 1;\nvarying vec2 v_Texcoord;\n@import clay.util.srgb\nvec3 ACESToneMapping(vec3 color)\n{\n const float A = 2.51;\n const float B = 0.03;\n const float C = 2.43;\n const float D = 0.59;\n const float E = 0.14;\n return (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nfloat eyeAdaption(float fLum)\n{\n return mix(0.2, fLum, 0.5);\n}\n#ifdef LUT_ENABLED\nvec3 lutTransform(vec3 color) {\n float blueColor = color.b * 63.0;\n vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);\n vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);\n vec4 newColor1 = texture2D(lut, texPos1);\n vec4 newColor2 = texture2D(lut, texPos2);\n vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n return newColor.rgb;\n}\n#endif\n@import clay.util.rgbm\nvoid main()\n{\n vec4 texel = vec4(0.0);\n vec4 originalTexel = vec4(0.0);\n#ifdef TEXTURE_ENABLED\n texel = decodeHDR(texture2D(texture, v_Texcoord));\n originalTexel = texel;\n#endif\n#ifdef BLOOM_ENABLED\n vec4 bloomTexel = decodeHDR(texture2D(bloom, v_Texcoord));\n texel.rgb += bloomTexel.rgb * bloomIntensity;\n texel.a += bloomTexel.a * bloomIntensity;\n#endif\n#ifdef LENSFLARE_ENABLED\n texel += decodeHDR(texture2D(lensflare, v_Texcoord)) * texture2D(lensdirt, v_Texcoord) * lensflareIntensity;\n#endif\n texel.a = min(texel.a, 1.0);\n#ifdef LUM_ENABLED\n float fLum = texture2D(lum, vec2(0.5, 0.5)).r;\n float adaptedLumDest = 3.0 / (max(0.1, 1.0 + 10.0*eyeAdaption(fLum)));\n float exposureBias = adaptedLumDest * exposure;\n#else\n float exposureBias = exposure;\n#endif\n#ifdef TONEMAPPING\n texel.rgb *= exposureBias;\n texel.rgb = ACESToneMapping(texel.rgb);\n#endif\n texel = linearTosRGB(texel);\n#ifdef LUT_ENABLED\n texel.rgb = lutTransform(clamp(texel.rgb,vec3(0.0),vec3(1.0)));\n#endif\n#ifdef COLOR_CORRECTION\n texel.rgb = clamp(texel.rgb + vec3(brightness), 0.0, 1.0);\n texel.rgb = clamp((texel.rgb - vec3(0.5))*contrast+vec3(0.5), 0.0, 1.0);\n float lum = dot(texel.rgb, vec3(0.2125, 0.7154, 0.0721));\n texel.rgb = mix(vec3(lum), texel.rgb, saturation);\n#endif\n#ifdef VIGNETTE\n vec2 uv = (v_Texcoord - vec2(0.5)) * vec2(vignetteOffset);\n texel.rgb = mix(texel.rgb, vec3(1.0 - vignetteDarkness), dot(uv, uv));\n#endif\n gl_FragColor = encodeHDR(texel);\n#ifdef DEBUG\n #if DEBUG == 1\n gl_FragColor = encodeHDR(decodeHDR(texture2D(texture, v_Texcoord)));\n #elif DEBUG == 2\n gl_FragColor = encodeHDR(decodeHDR(texture2D(bloom, v_Texcoord)) * bloomIntensity);\n #elif DEBUG == 3\n gl_FragColor = encodeHDR(decodeHDR(texture2D(lensflare, v_Texcoord) * lensflareIntensity));\n #endif\n#endif\n if (originalTexel.a <= 0.01 && gl_FragColor.a > 1e-5) {\n gl_FragColor.a = dot(gl_FragColor.rgb, vec3(0.2125, 0.7154, 0.0721));\n }\n#ifdef PREMULTIPLY_ALPHA\n gl_FragColor.rgb *= gl_FragColor.a;\n#endif\n}\n@end",ra="@export clay.compositor.lensflare\n#define SAMPLE_NUMBER 8\nuniform sampler2D texture;\nuniform sampler2D lenscolor;\nuniform vec2 textureSize : [512, 512];\nuniform float dispersal : 0.3;\nuniform float haloWidth : 0.4;\nuniform float distortion : 1.0;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nvec4 textureDistorted(\n in vec2 texcoord,\n in vec2 direction,\n in vec3 distortion\n) {\n return vec4(\n decodeHDR(texture2D(texture, texcoord + direction * distortion.r)).r,\n decodeHDR(texture2D(texture, texcoord + direction * distortion.g)).g,\n decodeHDR(texture2D(texture, texcoord + direction * distortion.b)).b,\n 1.0\n );\n}\nvoid main()\n{\n vec2 texcoord = -v_Texcoord + vec2(1.0); vec2 textureOffset = 1.0 / textureSize;\n vec2 ghostVec = (vec2(0.5) - texcoord) * dispersal;\n vec2 haloVec = normalize(ghostVec) * haloWidth;\n vec3 distortion = vec3(-textureOffset.x * distortion, 0.0, textureOffset.x * distortion);\n vec4 result = vec4(0.0);\n for (int i = 0; i < SAMPLE_NUMBER; i++)\n {\n vec2 offset = fract(texcoord + ghostVec * float(i));\n float weight = length(vec2(0.5) - offset) / length(vec2(0.5));\n weight = pow(1.0 - weight, 10.0);\n result += textureDistorted(offset, normalize(ghostVec), distortion) * weight;\n }\n result *= texture2D(lenscolor, vec2(length(vec2(0.5) - texcoord)) / length(vec2(0.5)));\n float weight = length(vec2(0.5) - fract(texcoord + haloVec)) / length(vec2(0.5));\n weight = pow(1.0 - weight, 10.0);\n vec2 offset = fract(texcoord + haloVec);\n result += textureDistorted(offset, normalize(ghostVec), distortion) * weight;\n gl_FragColor = result;\n}\n@end",na="@export clay.compositor.blend\n#define SHADER_NAME blend\n#ifdef TEXTURE1_ENABLED\nuniform sampler2D texture1;\nuniform float weight1 : 1.0;\n#endif\n#ifdef TEXTURE2_ENABLED\nuniform sampler2D texture2;\nuniform float weight2 : 1.0;\n#endif\n#ifdef TEXTURE3_ENABLED\nuniform sampler2D texture3;\nuniform float weight3 : 1.0;\n#endif\n#ifdef TEXTURE4_ENABLED\nuniform sampler2D texture4;\nuniform float weight4 : 1.0;\n#endif\n#ifdef TEXTURE5_ENABLED\nuniform sampler2D texture5;\nuniform float weight5 : 1.0;\n#endif\n#ifdef TEXTURE6_ENABLED\nuniform sampler2D texture6;\nuniform float weight6 : 1.0;\n#endif\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = vec4(0.0);\n#ifdef TEXTURE1_ENABLED\n tex += decodeHDR(texture2D(texture1, v_Texcoord)) * weight1;\n#endif\n#ifdef TEXTURE2_ENABLED\n tex += decodeHDR(texture2D(texture2, v_Texcoord)) * weight2;\n#endif\n#ifdef TEXTURE3_ENABLED\n tex += decodeHDR(texture2D(texture3, v_Texcoord)) * weight3;\n#endif\n#ifdef TEXTURE4_ENABLED\n tex += decodeHDR(texture2D(texture4, v_Texcoord)) * weight4;\n#endif\n#ifdef TEXTURE5_ENABLED\n tex += decodeHDR(texture2D(texture5, v_Texcoord)) * weight5;\n#endif\n#ifdef TEXTURE6_ENABLED\n tex += decodeHDR(texture2D(texture6, v_Texcoord)) * weight6;\n#endif\n gl_FragColor = encodeHDR(tex);\n}\n@end",ia="@export clay.compositor.fxaa\nuniform sampler2D texture;\nuniform vec4 viewport : VIEWPORT;\nvarying vec2 v_Texcoord;\n#define FXAA_REDUCE_MIN (1.0/128.0)\n#define FXAA_REDUCE_MUL (1.0/8.0)\n#define FXAA_SPAN_MAX 8.0\n@import clay.util.rgbm\nvoid main()\n{\n vec2 resolution = 1.0 / viewport.zw;\n vec3 rgbNW = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ) ).xyz;\n vec3 rgbNE = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ) ).xyz;\n vec3 rgbSW = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ) ).xyz;\n vec3 rgbSE = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ) ).xyz;\n vec4 rgbaM = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution ) );\n vec3 rgbM = rgbaM.xyz;\n float opacity = rgbaM.w;\n vec3 luma = vec3( 0.299, 0.587, 0.114 );\n float lumaNW = dot( rgbNW, luma );\n float lumaNE = dot( rgbNE, luma );\n float lumaSW = dot( rgbSW, luma );\n float lumaSE = dot( rgbSE, luma );\n float lumaM = dot( rgbM, luma );\n float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );\n float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );\n vec2 dir;\n dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\n dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\n float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );\n float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );\n dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),\n max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\n dir * rcpDirMin)) * resolution;\n vec3 rgbA = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * ( 1.0 / 3.0 - 0.5 ) ) ).xyz;\n rgbA += decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * ( 2.0 / 3.0 - 0.5 ) ) ).xyz;\n rgbA *= 0.5;\n vec3 rgbB = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * -0.5 ) ).xyz;\n rgbB += decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * 0.5 ) ).xyz;\n rgbB *= 0.25;\n rgbB += rgbA * 0.5;\n float lumaB = dot( rgbB, luma );\n if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) )\n {\n gl_FragColor = vec4( rgbA, opacity );\n }\n else {\n gl_FragColor = vec4( rgbB, opacity );\n }\n}\n@end";qt(Q);var aa=/^#source\((.*?)\)/;Q.import("@export clay.deferred.gbuffer.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\n#if defined(SECOND_PASS) || defined(FIRST_PASS)\nattribute vec2 texcoord : TEXCOORD_0;\nuniform vec2 uvRepeat;\nuniform vec2 uvOffset;\nvarying vec2 v_Texcoord;\n#endif\n#ifdef FIRST_PASS\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\nvarying vec3 v_Normal;\nattribute vec3 normal : NORMAL;\nattribute vec4 tangent : TANGENT;\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\nvarying vec3 v_WorldPosition;\n#endif\n@import clay.chunk.skinning_header\n#ifdef THIRD_PASS\nuniform mat4 prevWorldViewProjection;\nvarying vec4 v_ViewPosition;\nvarying vec4 v_PrevViewPosition;\n#ifdef SKINNING\n#ifdef USE_SKIN_MATRICES_TEXTURE\nuniform sampler2D prevSkinMatricesTexture;\nmat4 getPrevSkinMatrix(float idx) {\n return getSkinMatrix(prevSkinMatricesTexture, idx);\n}\n#else\nuniform mat4 prevSkinMatrix[JOINT_COUNT];\nmat4 getPrevSkinMatrix(float idx) {\n return prevSkinMatrix[int(idx)];\n}\n#endif\n#endif\n#endif\nvoid main()\n{\n vec3 skinnedPosition = position;\n vec3 prevSkinnedPosition = position;\n#ifdef FIRST_PASS\n vec3 skinnedNormal = normal;\n vec3 skinnedTangent = tangent.xyz;\n bool hasTangent = dot(tangent, tangent) > 0.0;\n#endif\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n skinnedPosition = (skinMatrixWS * vec4(position, 1.0)).xyz;\n #ifdef FIRST_PASS\n skinnedNormal = (skinMatrixWS * vec4(normal, 0.0)).xyz;\n if (hasTangent) {\n skinnedTangent = (skinMatrixWS * vec4(tangent.xyz, 0.0)).xyz;\n }\n #endif\n #ifdef THIRD_PASS\n {\n mat4 prevSkinMatrixWS = getPrevSkinMatrix(joint.x) * weight.x;\n if (weight.y > 1e-4) { prevSkinMatrixWS += getPrevSkinMatrix(joint.y) * weight.y; }\n if (weight.z > 1e-4) { prevSkinMatrixWS += getPrevSkinMatrix(joint.z) * weight.z; }\n float weightW = 1.0-weight.x-weight.y-weight.z;\n if (weightW > 1e-4) { prevSkinMatrixWS += getPrevSkinMatrix(joint.w) * weightW; }\n prevSkinnedPosition = (prevSkinMatrixWS * vec4(position, 1.0)).xyz;\n }\n #endif\n#endif\n#if defined(SECOND_PASS) || defined(FIRST_PASS)\n v_Texcoord = texcoord * uvRepeat + uvOffset;\n#endif\n#ifdef FIRST_PASS\n v_Normal = normalize((worldInverseTranspose * vec4(skinnedNormal, 0.0)).xyz);\n if (hasTangent) {\n v_Tangent = normalize((worldInverseTranspose * vec4(skinnedTangent, 0.0)).xyz);\n v_Bitangent = normalize(cross(v_Normal, v_Tangent) * tangent.w);\n }\n v_WorldPosition = (world * vec4(skinnedPosition, 1.0)).xyz;\n#endif\n#ifdef THIRD_PASS\n v_ViewPosition = worldViewProjection * vec4(skinnedPosition, 1.0);\n v_PrevViewPosition = prevWorldViewProjection * vec4(prevSkinnedPosition, 1.0);\n#endif\n gl_Position = worldViewProjection * vec4(skinnedPosition, 1.0);\n}\n@end\n@export clay.deferred.gbuffer1.fragment\nuniform mat4 viewInverse : VIEWINVERSE;\nuniform float glossiness;\nvarying vec2 v_Texcoord;\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\nuniform sampler2D normalMap;\nuniform sampler2D diffuseMap;\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\nuniform sampler2D roughGlossMap;\nuniform bool useRoughGlossMap;\nuniform bool useRoughness;\nuniform bool doubleSided;\nuniform float alphaCutoff: 0.0;\nuniform float alpha: 1.0;\nuniform int roughGlossChannel: 0;\nfloat indexingTexel(in vec4 texel, in int idx) {\n if (idx == 3) return texel.a;\n else if (idx == 1) return texel.g;\n else if (idx == 2) return texel.b;\n else return texel.r;\n}\nvoid main()\n{\n vec3 N = v_Normal;\n if (doubleSided) {\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = eyePos - v_WorldPosition;\n if (dot(N, V) < 0.0) {\n N = -N;\n }\n }\n if (alphaCutoff > 0.0) {\n float a = texture2D(diffuseMap, v_Texcoord).a * alpha;\n if (a < alphaCutoff) {\n discard;\n }\n }\n if (dot(v_Tangent, v_Tangent) > 0.0) {\n vec3 normalTexel = texture2D(normalMap, v_Texcoord).xyz;\n if (dot(normalTexel, normalTexel) > 0.0) { N = normalTexel * 2.0 - 1.0;\n mat3 tbn = mat3(v_Tangent, v_Bitangent, v_Normal);\n N = normalize(tbn * N);\n }\n }\n gl_FragColor.rgb = (N + 1.0) * 0.5;\n float g = glossiness;\n if (useRoughGlossMap) {\n float g2 = indexingTexel(texture2D(roughGlossMap, v_Texcoord), roughGlossChannel);\n if (useRoughness) {\n g2 = 1.0 - g2;\n }\n g = clamp(g2 + (g - 0.5) * 2.0, 0.0, 1.0);\n }\n gl_FragColor.a = g + 0.005;\n}\n@end\n@export clay.deferred.gbuffer2.fragment\nuniform sampler2D diffuseMap;\nuniform sampler2D metalnessMap;\nuniform vec3 color;\nuniform float metalness;\nuniform bool useMetalnessMap;\nuniform bool linear;\nuniform float alphaCutoff: 0.0;\nuniform float alpha: 1.0;\nvarying vec2 v_Texcoord;\n@import clay.util.srgb\nvoid main()\n{\n float m = metalness;\n if (useMetalnessMap) {\n vec4 metalnessTexel = texture2D(metalnessMap, v_Texcoord);\n m = clamp(metalnessTexel.r + (m * 2.0 - 1.0), 0.0, 1.0);\n }\n vec4 texel = texture2D(diffuseMap, v_Texcoord);\n if (linear) {\n texel = sRGBToLinear(texel);\n }\n if (alphaCutoff > 0.0) {\n float a = texel.a * alpha;\n if (a < alphaCutoff) {\n discard;\n }\n }\n gl_FragColor.rgb = texel.rgb * color;\n gl_FragColor.a = m + 0.005;\n}\n@end\n@export clay.deferred.gbuffer3.fragment\nuniform bool firstRender;\nvarying vec4 v_ViewPosition;\nvarying vec4 v_PrevViewPosition;\nvoid main()\n{\n vec2 a = v_ViewPosition.xy / v_ViewPosition.w;\n vec2 b = v_PrevViewPosition.xy / v_PrevViewPosition.w;\n if (firstRender) {\n gl_FragColor = vec4(0.0);\n }\n else {\n gl_FragColor = vec4((a - b) * 0.5 + 0.5, 0.0, 1.0);\n }\n}\n@end\n@export clay.deferred.gbuffer.debug\n@import clay.deferred.chunk.light_head\nuniform sampler2D gBufferTexture4;\nuniform int debug: 0;\nvoid main ()\n{\n @import clay.deferred.chunk.gbuffer_read\n if (debug == 0) {\n gl_FragColor = vec4(N, 1.0);\n }\n else if (debug == 1) {\n gl_FragColor = vec4(vec3(z), 1.0);\n }\n else if (debug == 2) {\n gl_FragColor = vec4(position, 1.0);\n }\n else if (debug == 3) {\n gl_FragColor = vec4(vec3(glossiness), 1.0);\n }\n else if (debug == 4) {\n gl_FragColor = vec4(vec3(metalness), 1.0);\n }\n else if (debug == 5) {\n gl_FragColor = vec4(albedo, 1.0);\n }\n else {\n vec4 color = texture2D(gBufferTexture4, uv);\n color.rg -= 0.5;\n color.rg *= 2.0;\n gl_FragColor = color;\n }\n}\n@end"),Q.import("@export clay.deferred.chunk.light_head\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture2;\nuniform sampler2D gBufferTexture3;\nuniform vec2 windowSize: WINDOW_SIZE;\nuniform vec4 viewport: VIEWPORT;\nuniform mat4 viewProjectionInv;\n#ifdef DEPTH_ENCODED\n@import clay.util.decode_float\n#endif\n@end\n@export clay.deferred.chunk.gbuffer_read\n vec2 uv = gl_FragCoord.xy / windowSize;\n vec2 uv2 = (gl_FragCoord.xy - viewport.xy) / viewport.zw;\n vec4 texel1 = texture2D(gBufferTexture1, uv);\n vec4 texel3 = texture2D(gBufferTexture3, uv);\n if (dot(texel1.rgb, vec3(1.0)) == 0.0) {\n discard;\n }\n float glossiness = texel1.a;\n float metalness = texel3.a;\n vec3 N = texel1.rgb * 2.0 - 1.0;\n float z = texture2D(gBufferTexture2, uv).r * 2.0 - 1.0;\n vec2 xy = uv2 * 2.0 - 1.0;\n vec4 projectedPos = vec4(xy, z, 1.0);\n vec4 p4 = viewProjectionInv * projectedPos;\n vec3 position = p4.xyz / p4.w;\n vec3 albedo = texel3.rgb;\n vec3 diffuseColor = albedo * (1.0 - metalness);\n vec3 specularColor = mix(vec3(0.04), albedo, metalness);\n@end\n@export clay.deferred.chunk.light_equation\nfloat D_Phong(in float g, in float ndh) {\n float a = pow(8192.0, g);\n return (a + 2.0) / 8.0 * pow(ndh, a);\n}\nfloat D_GGX(in float g, in float ndh) {\n float r = 1.0 - g;\n float a = r * r;\n float tmp = ndh * ndh * (a - 1.0) + 1.0;\n return a / (3.1415926 * tmp * tmp);\n}\nvec3 F_Schlick(in float ndv, vec3 spec) {\n return spec + (1.0 - spec) * pow(1.0 - ndv, 5.0);\n}\nvec3 lightEquation(\n in vec3 lightColor, in vec3 diffuseColor, in vec3 specularColor,\n in float ndl, in float ndh, in float ndv, in float g\n)\n{\n return ndl * lightColor\n * (diffuseColor + D_Phong(g, ndh) * F_Schlick(ndv, specularColor));\n}\n@end");var oa=Fe.extend(function(){var t={minFilter:yn.NEAREST,magFilter:yn.NEAREST,wrapS:yn.CLAMP_TO_EDGE,wrapT:yn.CLAMP_TO_EDGE};return{enableTargetTexture1:!0,enableTargetTexture2:!0,enableTargetTexture3:!0,enableTargetTexture4:!1,renderTransparent:!1,_gBufferRenderList:[],_gBufferTex1:new En(Object.assign({type:yn.HALF_FLOAT},t)),_gBufferTex2:new En(Object.assign({format:yn.DEPTH_STENCIL,type:yn.UNSIGNED_INT_24_8_WEBGL},t)),_gBufferTex3:new En(t),_gBufferTex4:new En(Object.assign({type:yn.HALF_FLOAT},t)),_defaultNormalMap:new En({image:ne("#000")}),_defaultRoughnessMap:new En({image:ne("#fff")}),_defaultMetalnessMap:new En({image:ne("#fff")}),_defaultDiffuseMap:new En({image:ne("#fff")}),_frameBuffer:new ai,_gBufferMaterial1:new rr({shader:new Q(Q.source("clay.deferred.gbuffer.vertex"),Q.source("clay.deferred.gbuffer1.fragment")),vertexDefines:{FIRST_PASS:null},fragmentDefines:{FIRST_PASS:null}}),_gBufferMaterial2:new rr({shader:new Q(Q.source("clay.deferred.gbuffer.vertex"),Q.source("clay.deferred.gbuffer2.fragment")),vertexDefines:{SECOND_PASS:null},fragmentDefines:{SECOND_PASS:null}}),_gBufferMaterial3:new rr({shader:new Q(Q.source("clay.deferred.gbuffer.vertex"),Q.source("clay.deferred.gbuffer3.fragment")),vertexDefines:{THIRD_PASS:null},fragmentDefines:{THIRD_PASS:null}}),_debugPass:new li({fragment:Q.source("clay.deferred.gbuffer.debug")})}},{resize:function(t,e){this._gBufferTex1.width===t&&this._gBufferTex1.height===e||(this._gBufferTex1.width=t,this._gBufferTex1.height=e,this._gBufferTex2.width=t,this._gBufferTex2.height=e,this._gBufferTex3.width=t,this._gBufferTex3.height=e,this._gBufferTex4.width=t,this._gBufferTex4.height=e)},setViewport:function(t,e,r,n,i){var a;a="object"==typeof t?t:{x:t,y:e,width:r,height:n,devicePixelRatio:i||1},this._frameBuffer.viewport=a},getViewport:function(){return this._frameBuffer.viewport?this._frameBuffer.viewport:{x:0,y:0,width:this._gBufferTex1.width,height:this._gBufferTex1.height,devicePixelRatio:1}},update:function(t,e,r,n){function i(){if(u){var t=u.devicePixelRatio;o.enable(o.SCISSOR_TEST),o.scissor(u.x*t,u.y*t,u.width*t,u.height*t)}o.clear(o.COLOR_BUFFER_BIT|o.DEPTH_BUFFER_BIT),u&&o.disable(o.SCISSOR_TEST)}function a(t,e){return t.material!==e.material}n=n||{};for(var o=t.gl,s=this._frameBuffer,u=s.viewport,l=e.updateRenderList(r,!0),h=l.opaque,c=l.transparent,f=0,d=this._gBufferRenderList,p=0;pt.getMaxJointNumber()){var a=n.getSubSkinMatricesTexture(e.__uid__,i),o=e.__prevSkinMatricesTexture;if(o||(o=e.__prevSkinMatricesTexture=new En({type:yn.FLOAT,minFilter:yn.NEAREST,magFilter:yn.NEAREST,useMipmap:!1,flipY:!1})),o.pixels&&o.pixels.length===a.pixels.length)for(var s=0;s= shadowCascadeClipsNear[_idx_] &&\n z <= shadowCascadeClipsFar[_idx_]\n ) {\n shadowContrib = computeShadowContrib(\n lightShadowMap, lightMatrices[_idx_], position, lightShadowMapSize,\n vec2(1.0 / float(SHADOW_CASCADE), 1.0),\n vec2(float(_idx_) / float(SHADOW_CASCADE), 0.0)\n );\n }\n }}\n gl_FragColor.rgb *= shadowContrib;\n#endif\n gl_FragColor.a = 1.0;\n}\n@end\n"),Q.import("@export clay.deferred.ambient_light\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture3;\nuniform vec3 lightColor;\nuniform vec2 windowSize: WINDOW_SIZE;\nvoid main()\n{\n vec2 uv = gl_FragCoord.xy / windowSize;\n vec4 texel1 = texture2D(gBufferTexture1, uv);\n if (dot(texel1.rgb, vec3(1.0)) == 0.0) {\n discard;\n }\n vec3 albedo = texture2D(gBufferTexture3, uv).rgb;\n gl_FragColor.rgb = lightColor * albedo;\n gl_FragColor.a = 1.0;\n}\n@end"),Q.import("@export clay.deferred.ambient_sh_light\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture3;\nuniform vec3 lightColor;\nuniform vec3 lightCoefficients[9];\nuniform vec2 windowSize: WINDOW_SIZE;\nvec3 calcAmbientSHLight(vec3 N) {\n return lightCoefficients[0]\n + lightCoefficients[1] * N.x\n + lightCoefficients[2] * N.y\n + lightCoefficients[3] * N.z\n + lightCoefficients[4] * N.x * N.z\n + lightCoefficients[5] * N.z * N.y\n + lightCoefficients[6] * N.y * N.x\n + lightCoefficients[7] * (3.0 * N.z * N.z - 1.0)\n + lightCoefficients[8] * (N.x * N.x - N.y * N.y);\n}\nvoid main()\n{\n vec2 uv = gl_FragCoord.xy / windowSize;\n vec4 texel1 = texture2D(gBufferTexture1, uv);\n if (dot(texel1.rgb, vec3(1.0)) == 0.0) {\n discard;\n }\n vec3 N = texel1.rgb * 2.0 - 1.0;\n vec3 albedo = texture2D(gBufferTexture3, uv).rgb;\n gl_FragColor.rgb = lightColor * albedo * calcAmbientSHLight(N);\n gl_FragColor.a = 1.0;\n}\n@end"),Q.import("@export clay.deferred.ambient_cubemap_light\n@import clay.deferred.chunk.light_head\nuniform vec3 lightColor;\nuniform samplerCube lightCubemap;\nuniform sampler2D brdfLookup;\nuniform vec3 eyePosition;\n@import clay.util.rgbm\nvoid main()\n{\n @import clay.deferred.chunk.gbuffer_read\n vec3 V = normalize(eyePosition - position);\n vec3 L = reflect(-V, N);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n float rough = clamp(1.0 - glossiness, 0.0, 1.0);\n float bias = rough * 5.0;\n vec2 brdfParam = texture2D(brdfLookup, vec2(rough, ndv)).xy;\n vec3 envWeight = specularColor * brdfParam.x + brdfParam.y;\n vec3 envTexel = RGBMDecode(textureCubeLodEXT(lightCubemap, L, bias), 8.12);\n gl_FragColor.rgb = lightColor * envTexel * envWeight;\n gl_FragColor.a = 1.0;\n}\n@end"),Q.import("@export clay.deferred.point_light\n@import clay.deferred.chunk.light_head\n@import clay.util.calculate_attenuation\n@import clay.deferred.chunk.light_equation\nuniform vec3 lightPosition;\nuniform vec3 lightColor;\nuniform float lightRange;\nuniform vec3 eyePosition;\n#ifdef SHADOWMAP_ENABLED\nuniform samplerCube lightShadowMap;\nuniform float lightShadowMapSize;\n#endif\nvarying vec3 v_Position;\n@import clay.plugin.shadow_map_common\nvoid main()\n{\n @import clay.deferred.chunk.gbuffer_read\n vec3 L = lightPosition - position;\n vec3 V = normalize(eyePosition - position);\n float dist = length(L);\n L /= dist;\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n float attenuation = lightAttenuation(dist, lightRange);\n gl_FragColor.rgb = attenuation * lightEquation(\n lightColor, diffuseColor, specularColor, ndl, ndh, ndv, glossiness\n );\n#ifdef SHADOWMAP_ENABLED\n float shadowContrib = computeShadowContribOmni(\n lightShadowMap, -L * dist, lightRange\n );\n gl_FragColor.rgb *= clamp(shadowContrib, 0.0, 1.0);\n#endif\n gl_FragColor.a = 1.0;\n}\n@end"),Q.import("@export clay.deferred.sphere_light\n@import clay.deferred.chunk.light_head\n@import clay.util.calculate_attenuation\n@import clay.deferred.chunk.light_equation\nuniform vec3 lightPosition;\nuniform vec3 lightColor;\nuniform float lightRange;\nuniform float lightRadius;\nuniform vec3 eyePosition;\nvarying vec3 v_Position;\nvoid main()\n{\n @import clay.deferred.chunk.gbuffer_read\n vec3 L = lightPosition - position;\n vec3 V = normalize(eyePosition - position);\n float dist = length(L);\n vec3 R = reflect(V, N);\n float tmp = dot(L, R);\n vec3 cToR = tmp * R - L;\n float d = length(cToR);\n L = L + cToR * clamp(lightRadius / d, 0.0, 1.0);\n L = normalize(L);\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, L), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n float attenuation = lightAttenuation(dist, lightRange);\n gl_FragColor.rgb = lightColor * ndl * attenuation;\n glossiness = clamp(glossiness - lightRadius / 2.0 / dist, 0.0, 1.0);\n gl_FragColor.rgb = attenuation * lightEquation(\n lightColor, diffuseColor, specularColor, ndl, ndh, ndv, glossiness\n );\n gl_FragColor.a = 1.0;\n}\n@end"),Q.import("@export clay.deferred.tube_light\n@import clay.deferred.chunk.light_head\n@import clay.util.calculate_attenuation\n@import clay.deferred.chunk.light_equation\nuniform vec3 lightPosition;\nuniform vec3 lightColor;\nuniform float lightRange;\nuniform vec3 lightExtend;\nuniform vec3 eyePosition;\nvarying vec3 v_Position;\nvoid main()\n{\n @import clay.deferred.chunk.gbuffer_read\n vec3 L = lightPosition - position;\n vec3 V = normalize(eyePosition - position);\n vec3 R = reflect(V, N);\n vec3 L0 = lightPosition - lightExtend - position;\n vec3 L1 = lightPosition + lightExtend - position;\n vec3 LD = L1 - L0;\n float len0 = length(L0);\n float len1 = length(L1);\n float irra = 2.0 * clamp(dot(N, L0) / (2.0 * len0) + dot(N, L1) / (2.0 * len1), 0.0, 1.0);\n float LDDotR = dot(R, LD);\n float t = (LDDotR * dot(R, L0) - dot(L0, LD)) / (dot(LD, LD) - LDDotR * LDDotR);\n t = clamp(t, 0.0, 1.0);\n L = L0 + t * LD;\n float dist = length(L);\n L /= dist;\n vec3 H = normalize(L + V);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n glossiness = clamp(glossiness - 0.0 / 2.0 / dist, 0.0, 1.0);\n gl_FragColor.rgb = lightColor * irra * lightAttenuation(dist, lightRange)\n * (diffuseColor + D_Phong(glossiness, ndh) * F_Schlick(ndv, specularColor));\n gl_FragColor.a = 1.0;\n}\n@end"),Q.import(Tr);var la=Fe.extend(function(){var t=Q.source("clay.compositor.vertex"),e=Q.source("clay.deferred.light_volume.vertex"),r=new Q(t,Q.source("clay.deferred.directional_light")),n=function(t){t.blendEquation(t.FUNC_ADD),t.blendFuncSeparate(t.ONE,t.ONE,t.ONE,t.ONE)},i=function(t){return new rr({shader:t,blend:n,transparent:!0,depthMask:!1})},a=function(t){return new Q(e,Q.source("clay.deferred."+t))},o=new sa({capSegments:10}),s=new Br;s.rotateX(Math.PI/2).translate(new wr(0,-1,0)),o.applyTransform(s);var u=new ua({capSegments:10});return s.identity().rotateZ(Math.PI/2),u.applyTransform(s),{shadowMapPass:null,autoResize:!0,_createLightPassMat:i,_gBuffer:new oa,_lightAccumFrameBuffer:new ai,_lightAccumTex:new En({type:yn.HALF_FLOAT,minFilter:yn.NEAREST,magFilter:yn.NEAREST}),_fullQuadPass:new li({blendWithPrevious:!0}),_directionalLightMat:i(r),_ambientMat:i(new Q(t,Q.source("clay.deferred.ambient_light"))),_ambientSHMat:i(new Q(t,Q.source("clay.deferred.ambient_sh_light"))),_ambientCubemapMat:i(new Q(t,Q.source("clay.deferred.ambient_cubemap_light"))),_spotLightShader:a("spot_light"),_pointLightShader:a("point_light"),_sphereLightShader:a("sphere_light"),_tubeLightShader:a("tube_light"),_lightSphereGeo:new gn({widthSegments:10,heightSegements:10}),_lightConeGeo:o,_lightCylinderGeo:u,_outputPass:new li({fragment:Q.source("clay.compositor.output")})}},{render:function(t,e,r,n){n=n||{},n.renderToTarget=n.renderToTarget||!1,n.notUpdateShadow=n.notUpdateShadow||!1,n.notUpdateScene=n.notUpdateScene||!1,n.notUpdateScene||e.update(!1,!0),e.updateLights(),r.update(!0);var i=t.getDevicePixelRatio();!this.autoResize||t.getWidth()*i===this._lightAccumTex.width&&t.getHeight()*i===this._lightAccumTex.height||this.resize(t.getWidth()*i,t.getHeight()*i),this._gBuffer.update(t,e,r),this._accumulateLightBuffer(t,e,r,!n.notUpdateShadow),n.renderToTarget||(this._outputPass.setUniform("texture",this._lightAccumTex),this._outputPass.render(t))},getTargetTexture:function(){return this._lightAccumTex},getTargetFrameBuffer:function(){return this._lightAccumFrameBuffer},getGBuffer:function(){return this._gBuffer},setViewport:function(t,e,r,n,i){this._gBuffer.setViewport(t,e,r,n,i),this._lightAccumFrameBuffer.viewport=this._gBuffer.getViewport()},resize:function(t,e){this._lightAccumTex.width=t,this._lightAccumTex.height=e,this._gBuffer.resize(t,e)},_accumulateLightBuffer:function(t,e,r,n){for(var i=t.gl,a=this._lightAccumTex,o=this._lightAccumFrameBuffer,s=r.getWorldPosition().array,u=0;u0&&we.scaleAndAdd(t.array,t.array,this.force.array,n/r)}});Q.import("@export clay.particle.vertex\nuniform mat4 worldView : WORLDVIEW;\nuniform mat4 projection : PROJECTION;\nattribute vec3 position : POSITION;\nattribute vec3 normal : NORMAL;\n#ifdef UV_ANIMATION\nattribute vec2 texcoord0 : TEXCOORD_0;\nattribute vec2 texcoord1 : TEXCOORD_1;\nvarying vec2 v_Uv0;\nvarying vec2 v_Uv1;\n#endif\nvarying float v_Age;\nvoid main() {\n v_Age = normal.x;\n float rotation = normal.y;\n vec4 worldViewPosition = worldView * vec4(position, 1.0);\n gl_Position = projection * worldViewPosition;\n float w = gl_Position.w;\n gl_PointSize = normal.z * projection[0].x / w;\n #ifdef UV_ANIMATION\n v_Uv0 = texcoord0;\n v_Uv1 = texcoord1;\n #endif\n}\n@end\n@export clay.particle.fragment\nuniform sampler2D sprite;\nuniform sampler2D gradient;\nuniform vec3 color : [1.0, 1.0, 1.0];\nuniform float alpha : 1.0;\nvarying float v_Age;\n#ifdef UV_ANIMATION\nvarying vec2 v_Uv0;\nvarying vec2 v_Uv1;\n#endif\nvoid main() {\n vec4 color = vec4(color, alpha);\n #ifdef SPRITE_ENABLED\n #ifdef UV_ANIMATION\n color *= texture2D(sprite, mix(v_Uv0, v_Uv1, gl_PointCoord));\n #else\n color *= texture2D(sprite, gl_PointCoord);\n #endif\n #endif\n #ifdef GRADIENT_ENABLED\n color *= texture2D(gradient, vec2(v_Age, 0.5));\n #endif\n gl_FragColor = color;\n}\n@end");var Pa=new Q(Q.source("clay.particle.vertex"),Q.source("clay.particle.fragment")),Ia=Mn.extend({loop:!0,oneshot:!1,duration:1,spriteAnimationTileX:1,spriteAnimationTileY:1,spriteAnimationRepeat:0,mode:Mn.POINTS,ignorePicking:!0,_elapsedTime:0,_emitting:!0},function(){this.geometry=new dn({dynamic:!0}),this.material||(this.material=new rr({shader:Pa,transparent:!0,depthMask:!1}),this.material.enableTexture("sprite")),this._particles=[],this._fields=[],this._emitters=[]},{culling:!1,frustumCulling:!1,castShadow:!1,receiveShadow:!1,addEmitter:function(t){this._emitters.push(t)},removeEmitter:function(t){this._emitters.splice(this._emitters.indexOf(t),1)},addField:function(t){this._fields.push(t)},removeField:function(t){this._fields.splice(this._fields.indexOf(t),1)},reset:function(){for(var t=0;t=i.life?(i.emitter.kill(i),e[r]=e[n-1],e.pop(),n--):r++}for(var r=0;r0)for(var a=0;a1,o=t.attributes.position.value,s=t.attributes.normal.value,u=t.attributes.texcoord0.value,l=t.attributes.texcoord1.value,h=this._particles.length;o&&o.length===3*h||(o=t.attributes.position.value=new Float32Array(3*h),s=t.attributes.normal.value=new Float32Array(3*h),a&&(u=t.attributes.texcoord0.value=new Float32Array(2*h),l=t.attributes.texcoord1.value=new Float32Array(2*h)));for(var c=1/e,f=0;fthis.duration&&!this.loop},dispose:function(t){for(var e=0;ethis._gamepadAxisThreshold)switch(e){case 0:this._moveLeft=r<0,this._moveRight=r>0;break;case 1:this._moveForward=r<0,this._moveBackward=r>0;break;case 2:this._offsetPitch+=r*this.lookAroundSpeed;break;case 3:this._offsetRoll+=r*this.lookAroundSpeed}}}}),Fa=function(){this._track=[]};Fa.prototype={constructor:Fa,recognize:function(t,e,r){return this._doTrack(t,e,r),this._recognize(t)},clear:function(){return this._track.length=0,this},_doTrack:function(t,e,r){var n=t.targetTouches;if(n){for(var i={points:[],touches:[],target:e,event:t},a=0,o=n.length;a1&&n&&n.length>1){var a=ue(n)/ue(i);!isFinite(a)&&(a=1),e.pinchScale=a;var o=le(n);return e.pinchX=o[0],e.pinchY=o[1],{type:"pinch",target:t[0].target,event:e}}}}},Ha=[[0,0],[0,1],[1,1],[1,0]],Ga=[0,1,2,2,3,0],Va=wn.extend({camera:null,plane:null,maxGrid:0,frustumCulling:!1},function(){var t=this.geometry=new dn({dynamic:!0});t.attributes.position.init(6),t.attributes.normal.init(6),t.attributes.texcoord0.init(6),t.indices=new Uint16Array(6),this.plane=new qr},{updateGeometry:function(){var t=this._unProjectGrid();if(t){for(var e=this.geometry.attributes.position,r=this.geometry.attributes.normal,n=this.geometry.attributes.texcoord0,i=this.geometry.indices,a=0;a<6;a++){var o=Ga[a];e.set(a,t[o].array),r.set(a,this.plane.normal.array),n.set(a,Ha[o]),i[a]=a}this.geometry.dirty()}},_unProjectGrid:function(){for(var t=new qr,e=[0,1,0,2,1,3,2,3,4,5,4,6,5,7,6,7,0,4,1,5,2,6,3,7],r=new wr,n=new wr,i=[],a=[],o=0;o<4;o++)a[o]=new wr(0,0);var s=new tn;return function(){t.copy(this.plane),t.applyTransform(this.camera.viewMatrix);for(var o=this.camera.frustum.vertices,u=0,l=0;l<12;l++){r.array=o[e[2*l]],n.array=o[e[2*l+1]];var h=t.intersectLine(r,n,i[u]);h&&(i[u]||(i[u]=h),u++)}if(0!==u){for(var l=0;l0},update:function(t){if(t=t||16,this._rotating){var e=("cw"===this.autoRotateDirection?1:-1)*this.autoRotateSpeed/180*Math.PI;this._phi-=e*t/1e3,this._needsUpdate=!0}else this._rotateVelocity.len()>0&&(this._needsUpdate=!0);(Math.abs(this._zoomSpeed)>.01||this._panVelocity.len()>0)&&(this._needsUpdate=!0),this._needsUpdate&&(this._updateDistance(Math.min(t,50)),this._updatePan(Math.min(t,50)),this._updateRotate(Math.min(t,50)),this._updateTransform(),this.target.update(),this.trigger("update"),this._needsUpdate=!1)},_updateRotate:function(t){var e=this._rotateVelocity;this._phi=e.y*t/20+this._phi,this._theta=e.x*t/20+this._theta,this.setAlpha(this.getAlpha()),this.setBeta(this.getBeta()),this._vectorDamping(e,this.damping)},_updateDistance:function(t){this._setDistance(this._distance+this._zoomSpeed*t/20),this._zoomSpeed*=this.damping},_setDistance:function(t){this._distance=Math.max(Math.min(t,this.maxDistance),this.minDistance)},_updatePan:function(t){var e=this._panVelocity,r=this._distance,n=this.target,i=n.worldTransform.y,a=n.worldTransform.x;this._center.scaleAndAdd(a,-e.x*r/200).scaleAndAdd(i,-e.y*r/200),this._vectorDamping(e,0),e.x=e.y=0},_updateTransform:function(){var t=this.target,e=new wr,r=this._theta+Math.PI/2,n=this._phi+Math.PI/2,i=Math.sin(r);e.x=i*Math.cos(n),e.y=-Math.cos(r),e.z=i*Math.sin(n),t.position.copy(this._center).scaleAndAdd(e,this._distance),t.rotation.identity().rotateY(-this._phi).rotateX(-this._theta)},_startCountingStill:function(){clearTimeout(this._stillTimeout);var t=this.autoRotateAfterStill,e=this;!isNaN(t)&&t>0&&(this._stillTimeout=setTimeout(function(){e._rotating=!0},1e3*t))},_vectorDamping:function(t,e){var r=t.len();r*=e,r<1e-4&&(r=0),t.normalize().scale(r)},decomposeTransform:function(){if(this.target){this.target.updateWorldTransform();var t=this.target.worldTransform.z,e=Math.asin(t.y),r=Math.atan2(t.x,t.z);this._theta=e,this._phi=-r,this.setBeta(this.getBeta()),this.setAlpha(this.getAlpha()),this._setDistance(this.target.position.dist(this._center))}},_mouseDownHandler:function(t){if(!this._isAnimating()){var e=t.clientX,r=t.clientY;if(t.targetTouches){var n=t.targetTouches[0];e=n.clientX,r=n.clientY,this._mode="rotate",this._processGesture(t,"start")}else 0===t.button?this._mode="rotate":1===t.button?(this._mode="pan",t.preventDefault()):this._mode=null;var i=this.domElement;Ge.addEventListener(i,"touchmove",this._mouseMoveHandler),Ge.addEventListener(i,"touchend",this._mouseUpHandler),Ge.addEventListener(i,"mousemove",this._mouseMoveHandler),Ge.addEventListener(i,"mouseup",this._mouseUpHandler),Ge.addEventListener(i,"mouseout",this._mouseUpHandler),this._rotateVelocity.set(0,0),this._rotating=!1,this.autoRotate&&this._startCountingStill(),this._mouseX=e,this._mouseY=r}},_mouseMoveHandler:function(t){if(!this._isAnimating()){var e,r=t.clientX,n=t.clientY;if(t.targetTouches){var i=t.targetTouches[0];r=i.clientX,n=i.clientY,e=this._processGesture(t,"change")}var a=he(this.panSensitivity),o=he(this.rotateSensitivity);e||("rotate"===this._mode?(this._rotateVelocity.y+=(r-this._mouseX)/this.domElement.clientWidth*2*o[0],this._rotateVelocity.x+=(n-this._mouseY)/this.domElement.clientHeight*2*o[1]):"pan"===this._mode&&(this._panVelocity.x+=(r-this._mouseX)/this.domElement.clientWidth*a[0]*400,this._panVelocity.y+=(-n+this._mouseY)/this.domElement.clientHeight*a[1]*400)),this._mouseX=r,this._mouseY=n,t.preventDefault&&t.preventDefault()}},_mouseWheelHandler:function(t){if(!this._isAnimating()){var e=t.deltaY;0!==e&&this._zoomHandler(t,e>0?1:-1)}},_pinchHandler:function(t){this._isAnimating()||this._zoomHandler(t,t.pinchScale>1?-.4:.4)},_zoomHandler:function(t,e){var r=Math.max(Math.min(this._distance-this.minDistance,this.maxDistance-this._distance));this._zoomSpeed=e*Math.max(r/40*this.zoomSensitivity,.2),this._rotating=!1,this.autoRotate&&"rotate"===this._mode&&this._startCountingStill(),t.preventDefault&&t.preventDefault()},_mouseUpHandler:function(t){var e=this.domElement +;Ge.removeEventListener(e,"touchmove",this._mouseMoveHandler),Ge.removeEventListener(e,"touchend",this._mouseUpHandler),Ge.removeEventListener(e,"mousemove",this._mouseMoveHandler),Ge.removeEventListener(e,"mouseup",this._mouseUpHandler),Ge.removeEventListener(e,"mouseout",this._mouseUpHandler),this._processGesture(t,"end")},_addAnimator:function(t){var e=this._animators;return e.push(t),t.done(function(){var r=e.indexOf(t);r>=0&&e.splice(r,1)}),t},_processGesture:function(t,e){var r=this._gestureMgr;"start"===e&&r.clear();var n=r.recognize(t,null,this.domElement);if("end"===e&&r.clear(),n){var i=n.type;t.gestureEvent=i,this._pinchHandler(n.event)}return n}});Object.defineProperty(Wa.prototype,"autoRotate",{get:function(){return this._autoRotate},set:function(t){this._autoRotate=t,this._rotating=t}}),Object.defineProperty(Wa.prototype,"target",{get:function(){return this._target},set:function(t){t&&t.target&&this.setCenter(t.target.toArray()),this._target=t,this.decomposeTransform()}});var za=dn.extend({dynamic:!1}),Xa={merge:function(t,e){if(t.length){var r=t[0],n=r.geometry,i=r.material,a=new dn({dynamic:!1});a.boundingBox=new Gr;for(var o=n.getEnabledAttributes(),s=0;s=65535?new Uint32Array(3*f):new Uint16Array(3*f);for(var _=0,g=0,v=n.isUseIndices(),y=0;y0;){for(var _=[],g=[],v=[],y=0,f=0;f=0&&-1===g[S]&&(y65535?new Uint32Array(3*L.triangles.length):new Uint16Array(3*L.triangles.length);var H=0;O=0;for(var f=0;f=0?N[S]:-1}O++}P.indices[H++]=C[A]}P.updateBoundingBox(),M.add(I)}for(var X=t.children(),f=0;f0&&(r.indices=fe(t.indices,e),n.push(r.indices.buffer)),r.attributes={};for(var i in t.attributes)if(t.attributes.hasOwnProperty(i)){var a=t.attributes[i];a&&a.value&&a.value.length>0&&(a=r.attributes[i]=ce(a,e),n.push(a.value.buffer))}return{data:r,buffers:n}},toGeometry:function(t){if(!t)return null;if(t.data&&t.buffers)return qa.toGeometry(t.data);if(!t.metadata||t.metadata.generator!==ja.generator)throw new Error("[util.transferable.toGeometry] the object is not generated by util.transferable.");var e={dynamic:t.dynamic,indices:t.indices};if(t.boundingBox){var r=(new wr).setArray(t.boundingBox.min),n=(new wr).setArray(t.boundingBox.max);e.boundingBox=new Gr(r,n)}var i=new dn(e);for(var a in t.attributes)if(t.attributes.hasOwnProperty(a)){var o=t.attributes[a];i.attributes[a]=new dn.Attribute(o.name,o.type,o.size,o.semantic),i.attributes[a].value=o.value}return i}};Q.import("@export clay.vr.disorter.output.vertex\nattribute vec2 texcoord: TEXCOORD_0;\nattribute vec3 position: POSITION;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n v_Texcoord = texcoord;\n gl_Position = vec4(position.xy, 0.5, 1.0);\n}\n@end\n@export clay.vr.disorter.output.fragment\nuniform sampler2D texture;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n gl_FragColor = texture2D(texture, v_Texcoord);\n}\n@end");var Ya=Fe.extend(function(){return{clearColor:[0,0,0,1],_mesh:new wn({geometry:new dn({dynamic:!0}),culling:!1,material:new rr({depthTest:!1,shader:new Q({vertex:Q.source("clay.vr.disorter.output.vertex"),fragment:Q.source("clay.vr.disorter.output.fragment")})})}),_fakeCamera:new Cn}},{render:function(t,e){var r=this.clearColor,n=t.gl;n.clearColor(r[0],r[1],r[2],r[3]),n.clear(n.COLOR_BUFFER_BIT),n.disable(n.BLEND),this._mesh.material.set("texture",e),t.saveViewport(),t.setViewport(0,0,t.getWidth(),t.getHeight()),t.renderPass([this._mesh],this._fakeCamera),t.restoreViewport()},updateFromVRDisplay:function(t){t.deviceInfo_?this._updateMesh(20,20,t.deviceInfo_):console.warn("Cant get vrDisplay.deviceInfo_, seems code changed")},_updateMesh:function(t,e,r){var n=this._mesh.geometry.attributes.position,i=this._mesh.geometry.attributes.texcoord0;n.init(2*t*e),i.init(2*t*e);for(var a=r.getLeftEyeVisibleTanAngles(),o=r.getLeftEyeNoLensTanAngles(),s=r.getLeftEyeVisibleScreenRect(o),u=0,l=[],h=[],c=0;c<2;c++){for(var f=0;f