v3d-core
Version:
WebGL-based humanoid model rendering engine.
16 lines (14 loc) • 320 kB
JavaScript
(()=>{"use strict";var e={d:(t,i)=>{for(var n in i)e.o(i,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:i[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{V3DCore:()=>Xe,V3DHelper:()=>Ge});const i=BABYLON,n=LOADERS;class r extends n.GLTFFileLoader{constructor(){super(...arguments),this.name="vrm",this.extensions={".vrm":{isBinary:!0},".vci":{isBinary:!0}},this.vrmManager=null}createPlugin(){return new r}loadAsync(e,t,i,n,r){return this.uri=i,r&&(this.uri+=r),super.loadAsync(e,t,i,n,r)}}class o{constructor(e,t){this.offset=e,this.radius=t}}class a{constructor(e){this.transform=e,this.colliders=[]}addCollider(e,t){this.colliders.push(new o(e,t))}}class s{constructor(e,t){this.position=e,this.radius=t}}class l{constructor(e,t,i,n){this.center=e,this.radius=t,this.transform=i,this.localChildPosition=n,i.rotationQuaternion||(i.rotationQuaternion=i.rotation.toQuaternion());const r=i.parent;null!==r&&null===r.rotationQuaternion&&(r.rotationQuaternion=r.rotation.toQuaternion()),this.init()}init(){this.centerAbsolutePos=this.center?this.center.absolutePosition:new i.Vector3(0,0,0),this.centerSpacePosition=this.transform.absolutePosition.subtract(this.centerAbsolutePos),this.parentAbsolutePos=this.transform.parent?this.transform.parent.absolutePosition:new i.Vector3(0,0,0),this.worldParentQuaternion=i.Quaternion.Identity(),this.localPosition=this.mirrorY(this.transform.position.clone()),this.localRotation=this.transform.rotationQuaternion.clone(),this.currentTail=this.localToWorld(this.localChildPosition).subtract(this.centerAbsolutePos),this.prevTail=this.currentTail.clone(),this.boneAxis=i.Vector3.Normalize(this.localChildPosition),this.boneLength=this.localChildPosition.length()}update(e,t,n,r,o){const a=this.transform.absolutePosition;if(Number.isNaN(a.x))return;e&&(this.centerAbsolutePos=e.absolutePosition),this.centerSpacePosition=a.subtract(this.centerAbsolutePos),this.parentAbsolutePos=this.transform.parent?this.transform.parent.absolutePosition:new i.Vector3(0,0,0),this.worldParentQuaternion=this.transform.parent?i.Quaternion.FromRotationMatrix(this.transform.parent.getWorldMatrix().getRotationMatrix()):i.Quaternion.Identity();const s=this.currentTail,l=this.prevTail;let f=this.currentTail.clone();const u=s.subtract(l).scaleInPlace(1-n);f.addInPlace(u);const d=this.localRotation.clone(),c=this.worldParentQuaternion.clone(),h=i.Vector3.Zero();this.boneAxis.rotateByQuaternionToRef(d,h),h.addInPlace(this.localPosition),h.rotateByQuaternionToRef(c,h),h.addInPlace(this.parentAbsolutePos).subtractInPlace(a).normalize();const p=h.scale(t);f.addInPlace(p),f.addInPlace(r);const m=f.subtract(this.centerSpacePosition);m.normalize(),m.scaleInPlace(this.boneLength),f=this.centerSpacePosition.add(m),f=this.collide(o,f),this.prevTail=s,this.currentTail=f;const v=this.transformToRotationLocal(f);this.transform.rotationQuaternion=this.localRotation.multiply(v)}localToWorld(e){const t=e.clone();return e.rotateByQuaternionToRef(this.worldParentQuaternion.multiply(this.transform.rotationQuaternion),t),t.addInPlace(this.transform.absolutePosition),t}transformToRotationLocal(e){const t=i.Quaternion.Inverse(this.localRotation),n=i.Quaternion.Inverse(this.worldParentQuaternion),r=this.boneAxis.clone(),o=i.Vector3.Zero();return e.add(this.centerAbsolutePos).subtract(this.parentAbsolutePos).rotateByQuaternionToRef(n,o),o.subtract(this.localPosition).rotateByQuaternionToRef(t,o),o.normalize(),class{static multiplyWithVector3(e,t){const n=2*e.x,r=2*e.y,o=2*e.z,a=e.x*n,s=e.y*r,l=e.z*o,f=e.x*r,u=e.x*o,d=e.y*o,c=e.w*n,h=e.w*r,p=e.w*o,m=new i.Vector3;return m.x=(1-(s+l))*t.x+(f-p)*t.y+(u+h)*t.z,m.y=(f+p)*t.x+(1-(a+l))*t.y+(d-c)*t.z,m.z=(u-h)*t.x+(d+c)*t.y+(1-(a+s))*t.z,m}static fromToRotation(e,t){const n=i.Vector3.Cross(e,t).normalize(),r=i.Vector3.Dot(e,t),o=e.length()*t.length(),a=Math.acos(Math.max(0,Math.min(1,r/o))),s=Math.sin(a/2);return new i.Quaternion(s*n.x,s*n.y,s*n.z,Math.cos(a/2))}}.fromToRotation(r,o)}collide(e,t){return e.forEach((e=>{const i=e.position.subtract(this.centerAbsolutePos);i.addInPlace(this.centerSpacePosition);const n=this.radius+e.radius,r=t.subtract(i);if(r.lengthSquared()<=n*n-.02){const e=i.add(r.normalize().scaleInPlace(n));t=e.subtractInPlace(this.centerSpacePosition).normalize().scaleInPlace(this.boneLength).addInPlace(this.centerSpacePosition)}})),t}mirrorY(e){return new i.Vector3(e.x,-e.y,e.z)}}class f{constructor(e,t,i,n,r,o,a,s,l){this.comment=e,this.stiffness=t,this.gravityPower=i,this.gravityDir=n,this.dragForce=r,this.center=o,this.hitRadius=a,this.bones=s,this.colliderGroups=l,this.verlets=[],this.initialLocalRotations=[],this.activeBones=[],this.drawGizmo=!1,this.boneGizmoList=[],this.colliderGizmoList=[],this.activeBones=this.bones.filter((e=>null!==e)),this.activeBones.forEach((e=>{e.rotationQuaternion=e.rotationQuaternion||e.rotation.toQuaternion(),this.initialLocalRotations.push(e.rotationQuaternion.clone())})),this.gravityDir.normalize()}setup(e=!1){e||this.activeBones.forEach(((e,t)=>{e.rotationQuaternion=this.initialLocalRotations[t].clone()})),this.verlets=[],this.activeBones.forEach(((e,t)=>{this.initialLocalRotations[t]=e.rotationQuaternion,this.setupRecursive(this.center,e)})),this.verlets=this.verlets.filter(((e,t,i)=>t===i.findIndex((t=>t.transform.name===e.transform.name))))}async update(e,t){if(0===this.verlets.length){if(0===this.activeBones.length)return;this.setup()}const n=this.updateOptions(t),r=[];this.colliderGroups.forEach((e=>{if(!e)return;const t=e.transform.getAbsolutePosition();Number.isNaN(t.x)||e.colliders.forEach((n=>{const o=t.add(n.offset);if(r.push(new s(o,n.radius)),this.drawGizmo){if(this.colliderGizmoList.length<r.length){const t=i.MeshBuilder.CreateSphere(`${e.transform.name}_colliderGizmo`,{segments:8,diameter:1,updatable:!0},e.transform.getScene()),n=new i.StandardMaterial(e.transform.name+"_colliderGizmomat",e.transform.getScene());n.emissiveColor=i.Color3.Yellow(),n.wireframe=!0,t.material=n,this.colliderGizmoList.push(t)}this.colliderGizmoList[r.length-1].position=o,this.colliderGizmoList[r.length-1].scaling=new i.Vector3(2*n.radius,2*n.radius,2*n.radius)}}))}));const o=this.stiffness*e,a=this.gravityDir.scale(this.gravityPower*e);this.verlets.map(((e,t)=>{e.update(this.center,o,this.dragForce,a,r),this.drawGizmo&&this.boneGizmoList[t]&&(this.boneGizmoList[t].position=e.transform.absolutePosition,this.boneGizmoList[t].rotationQuaternion=e.transform.rotationQuaternion)})),this.updateOptions(n)}setupRecursive(e,t){if(0===t.getChildTransformNodes().length){const n=t.parent,r=t.getAbsolutePosition().subtract(n.getAbsolutePosition()).normalize(),o=t.position.add(class{static multiplyByFloat(e,t){return new i.Vector3(e.x*t,e.y*t,e.z*t)}}.multiplyByFloat(r,.07));this.verlets.push(new l(e,this.hitRadius,t,o))}else{const i=t.getChildTransformNodes().shift(),n=i.position,r=i.scaling;this.verlets.push(new l(e,this.hitRadius,t,n.multiply(r)))}if(this.drawGizmo){const e=i.MeshBuilder.CreateSphere(t.name+"_boneGizmo",{segments:8,diameter:2*this.hitRadius,updatable:!0},t.getScene()),n=new i.StandardMaterial(t.name+"_boneGizmomat",t.getScene());n.emissiveColor=i.Color3.Red(),n.wireframe=!0,e.material=n,this.boneGizmoList.push(e)}t.getChildTransformNodes().forEach((t=>{this.setupRecursive(e,t)}))}updateOptions(e){const t={stiffness:this.stiffness,gravityPower:this.gravityPower,gravityDir:this.gravityDir.clone(),dragForce:this.dragForce,hitRadius:this.hitRadius};return this.stiffness=e?.stiffness||this.stiffness,this.gravityPower=e?.gravityPower||this.gravityPower,this.gravityDir=e?.gravityDir||this.gravityDir,this.dragForce=e?.dragForce||this.dragForce,this.hitRadius=e?.hitRadius||this.hitRadius,t}}class u{constructor(e,t,i){this.ext=e;const n=this.constructColliderGroups(t);this.springs=this.constructSprings(t,n,i)}dispose(){this.springs=[]}setup(e=!1){this.springs.forEach((t=>{t.setup(e)}))}async update(e,t){e=Math.max(0,Math.min(125,e))/1e3;const i=this.springs.map((i=>i.update(e,t)));return Promise.all(i).then((()=>{}))}constructColliderGroups(e){if(!this.ext.colliderGroups||!this.ext.colliderGroups.length)return[];const t=[];return this.ext.colliderGroups.forEach((n=>{const r=e(n.node),o=new a(r);n.colliders.forEach((e=>{o.addCollider(new i.Vector3(-e.offset.x,e.offset.y,-e.offset.z),e.radius)})),t.push(o)})),t}constructSprings(e,t,n){if(!this.ext.boneGroups||!this.ext.boneGroups.length)return[];const r=[];return this.ext.boneGroups.forEach((o=>{const a=(o.bones||[]).map((t=>e(t))),s=(o.colliderGroups||[]).map((e=>t[e]));r.push(new f(o.comment,n?.stiffness?n.stiffness:o.stiffiness,n?.gravityPower?n.gravityPower:o.gravityPower,n?.gravityDir?n.gravityDir:new i.Vector3(-o.gravityDir.x,o.gravityDir.y,-o.gravityDir.z).normalize(),n?.dragForce?n.dragForce:o.dragForce,e(o.center),n?.hitRadius?n.hitRadius:o.hitRadius,a,s))})),r}}class d extends Error{constructor(e){super(`Bone:${e} NotFound`),this.boneName=e,this.name="BoneNotFoundError"}}class c{constructor(e){this._nodeMap=e}get nodeMap(){return this._nodeMap}dispose(){this._nodeMap=null}get hips(){return this.getMandatoryBone("hips")}get leftUpperLeg(){return this.getMandatoryBone("leftUpperLeg")}get rightUpperLeg(){return this.getMandatoryBone("rightUpperLeg")}get leftLowerLeg(){return this.getMandatoryBone("leftLowerLeg")}get rightLowerLeg(){return this.getMandatoryBone("rightLowerLeg")}get leftFoot(){return this.getMandatoryBone("leftFoot")}get rightFoot(){return this.getMandatoryBone("rightFoot")}get spine(){return this.getMandatoryBone("spine")}get chest(){return this.getMandatoryBone("chest")}get neck(){return this.getMandatoryBone("neck")}get head(){return this.getMandatoryBone("head")}get leftShoulder(){return this.getMandatoryBone("leftShoulder")}get rightShoulder(){return this.getMandatoryBone("rightShoulder")}get leftUpperArm(){return this.getMandatoryBone("leftUpperArm")}get rightUpperArm(){return this.getMandatoryBone("rightUpperArm")}get leftLowerArm(){return this.getMandatoryBone("leftLowerArm")}get rightLowerArm(){return this.getMandatoryBone("rightLowerArm")}get leftHand(){return this.getMandatoryBone("leftHand")}get rightHand(){return this.getMandatoryBone("rightHand")}get leftToes(){return this.getOptionalBone("leftToes")}get rightToes(){return this.getOptionalBone("rightToes")}get leftEye(){return this.getOptionalBone("leftEye")}get rightEye(){return this.getOptionalBone("rightEye")}get jaw(){return this.getOptionalBone("jaw")}get leftThumbProximal(){return this.getOptionalBone("leftThumbProximal")}get leftThumbIntermediate(){return this.getOptionalBone("leftThumbIntermediate")}get leftThumbDistal(){return this.getOptionalBone("leftThumbDistal")}get leftIndexProximal(){return this.getOptionalBone("leftIndexProximal")}get leftIndexIntermediate(){return this.getOptionalBone("leftIndexIntermediate")}get leftIndexDistal(){return this.getOptionalBone("leftIndexDistal")}get leftMiddleProximal(){return this.getOptionalBone("leftMiddleProximal")}get leftMiddleIntermediate(){return this.getOptionalBone("leftMiddleIntermediate")}get leftMiddleDistal(){return this.getOptionalBone("leftMiddleDistal")}get leftRingProximal(){return this.getOptionalBone("leftRingProximal")}get leftRingIntermediate(){return this.getOptionalBone("leftRingIntermediate")}get leftRingDistal(){return this.getOptionalBone("leftRingDistal")}get leftLittleProximal(){return this.getOptionalBone("leftLittleProximal")}get leftLittleIntermediate(){return this.getOptionalBone("leftLittleIntermediate")}get leftLittleDistal(){return this.getOptionalBone("leftLittleDistal")}get rightThumbProximal(){return this.getOptionalBone("rightThumbProximal")}get rightThumbIntermediate(){return this.getOptionalBone("rightThumbIntermediate")}get rightThumbDistal(){return this.getOptionalBone("rightThumbDistal")}get rightIndexProximal(){return this.getOptionalBone("rightIndexProximal")}get rightIndexIntermediate(){return this.getOptionalBone("rightIndexIntermediate")}get rightIndexDistal(){return this.getOptionalBone("rightIndexDistal")}get rightMiddleProximal(){return this.getOptionalBone("rightMiddleProximal")}get rightMiddleIntermediate(){return this.getOptionalBone("rightMiddleIntermediate")}get rightMiddleDistal(){return this.getOptionalBone("rightMiddleDistal")}get rightRingProximal(){return this.getOptionalBone("rightRingProximal")}get rightRingIntermediate(){return this.getOptionalBone("rightRingIntermediate")}get rightRingDistal(){return this.getOptionalBone("rightRingDistal")}get rightLittleProximal(){return this.getOptionalBone("rightLittleProximal")}get rightLittleIntermediate(){return this.getOptionalBone("rightLittleIntermediate")}get rightLittleDistal(){return this.getOptionalBone("rightLittleDistal")}get upperChest(){return this.getOptionalBone("upperChest")}getMandatoryBone(e){const t=this.nodeMap[e];if(!t)throw new d(e);return t}getOptionalBone(e){return this.nodeMap&&this.nodeMap[e]||null}}class h{constructor(e,t,i){this.label=e,this.manager=i,this._value=t}get value(){return this._value}set value(e){this._value=Math.max(0,Math.min(1,e)),this.manager.morphing(this.label,e)}}class p{constructor(e,t,i,n,r){this.ext=e,this.scene=t,this.meshesFrom=i,this.transformNodesFrom=n,this.uri=r,this.morphTargetMap={},this.presetMorphTargetMap={},this.transformNodeMap={},this.transformNodeCache={},this.meshCache={},this._cameras=[],this.MorphTargetPropertyMap={},this.meshCache=this.constructMeshCache(),this.transformNodeCache=this.constructTransformNodeCache(),this.springBoneController=new u(this.ext.secondaryAnimation,this.findTransformNode.bind(this)),this.springBoneController.setup(),this.constructMorphTargetMap(),this.constructTransformNodeMap(),this._humanoidBone=new c(this.transformNodeMap),this.removeDuplicateSkeletons(),this._rootSkeleton=this.getRootSkeletonNode(),this.rootMesh.name=p.ROOT_MESH_PREFIX+this.scene.getNodes().filter((e=>e.name.includes(p.ROOT_MESH_PREFIX))).length}get transformNodeTree(){return this._transformNodeTree}get cameras(){return this._cameras}appendCamera(e){this._cameras.push(e)}resetCameras(){this._cameras=[]}removeDuplicateSkeletons(){let e=null;for(const t of Object.keys(this.meshCache).map(Number)){const i=this.meshCache[t];if(i.length&&i[0].skeleton)if(e){e.bones.length!=i[0].skeleton.bones.length&&console.warn("Skeletons have different numbers of bones!"),i[0].skeleton.dispose();for(const t of i)t.skeleton=e}else if(e=i[0].skeleton,this._rootMesh){"Root"!==e.bones[0].name&&console.warn('The first bone has a different name than "Root"')}}}getRootSkeletonNode(){const e=this._rootMesh.getChildren((e=>"Root"===e.name||"Armature"===e.name));if(e.length>0)return e[0];{const e=this.scene.getNodeByName("Root")?this.scene.getNodeByName("Root"):this.scene.getNodeByName("Armature");if(e&&!e.parent)return e;throw Error("Cannot find root skeleton node!")}}async update(e,t){await this.springBoneController.update(e,t)}dispose(){this.springBoneController.dispose(),this._humanoidBone.dispose(),this._rootSkeleton.dispose(),this._rootMesh&&this._rootMesh.dispose(),this.morphTargetMap=null,this.MorphTargetPropertyMap=null,this.presetMorphTargetMap=null,this.transformNodeMap=null,this.transformNodeCache=null,this.meshCache=null,this._cameras=null,this._transformNodeTree=null,this._rootMesh=null}morphing(e,t){this.morphTargetMap[e]&&this.morphTargetMap[e].forEach((e=>{e.target.influence=Math.max(0,Math.min(1,t))*(e.weight/100)}))}morphingPreset(e,t){this.presetMorphTargetMap[e]&&this.presetMorphTargetMap[e].forEach((e=>{e.target.influence=Math.max(0,Math.min(1,t))*(e.weight/100)}))}getMorphingList(){return Object.keys(this.morphTargetMap)}getFirstPersonCameraPosition(){const e=this.getFirstPersonBone();if(!e)return null;let t=e.getAbsolutePosition();const n=this.ext.firstPerson.firstPersonBoneOffset;return new i.Vector3(t.x+n.x,t.y+n.y,t.z+n.z)}getFirstPersonBone(){return this.findTransformNode(this.ext.firstPerson.firstPersonBone)}get humanoidBone(){return this._humanoidBone}get rootMesh(){return this._rootMesh}get rootSkeletonNode(){return this._rootSkeleton}findTransformNode(e){return this.transformNodeCache[e]||null}indexOfTransformNode(e){for(const[t,i]of Object.entries(this.transformNodeCache))if(e==i)return parseInt(t,10);return-1}findMeshes(e){return this.meshCache[e]||null}constructMorphTargetMap(){this.ext.blendShapeMaster&&this.ext.blendShapeMaster.blendShapeGroups&&this.ext.blendShapeMaster.blendShapeGroups.forEach((e=>{e.binds&&e.binds.forEach((t=>{const i=this.findMeshes(t.mesh);i?i.forEach((i=>{const n=i.morphTargetManager;if(!n)return void console.log("Undefined morphTargetManager",t);const r=n.getTarget(t.index);this.morphTargetMap[e.name]=this.morphTargetMap[e.name]||[],this.morphTargetMap[e.name].push({target:r,weight:t.weight}),this.MorphTargetPropertyMap[e.name]=new h(e.name,0,this),e.presetName&&(this.presetMorphTargetMap[e.presetName]=this.presetMorphTargetMap[e.presetName]||[],this.presetMorphTargetMap[e.presetName].push({target:r,weight:t.weight}))})):console.log("Undefined BlendShapeBind Mesh",t)}))}))}constructTransformNodeMap(){const e=[];this.ext.humanoid.humanBones.forEach((t=>{const i=this.findTransformNode(t.node);i&&(this.transformNodeMap[t.bone]=i,e.push({id:t.node,name:t.bone,parent:this.indexOfTransformNode(i.parent)}))}));const t=this.hierarchy(e);if(0===t.length)throw Error("Failed to construct bone hierarchy tree!");this._transformNodeTree=t[0]}hierarchy(e){const t=[],i={};return e.forEach((e=>{const n=e.id,r=e.parent;i[n]=i[n]||[],e.children=i[n],null!=r&&this.transformNodeCache[r].parent!=this._rootMesh&&"hips"!==e.name.toLowerCase()?(i[r]=i[r]||[]).push(e):t.push(e)})),t}constructTransformNodeCache(){const e={};for(let t=this.transformNodesFrom;t<this.scene.transformNodes.length;t++){const i=this.scene.transformNodes[t];if(i&&i.metadata&&i.metadata.gltf&&i.metadata.gltf.pointers&&0!==i.metadata.gltf.pointers.length)for(const t of i.metadata.gltf.pointers)if(t.startsWith("/nodes/")){e[parseInt(t.substring(7),10)]=i;break}}return e}constructMeshCache(){const e={};for(let t=this.meshesFrom;t<this.scene.meshes.length;t++){const i=this.scene.meshes[t];if("__root__"!==i.id){if(i&&i.metadata&&i.metadata.gltf&&i.metadata.gltf.pointers&&0!==i.metadata.gltf.pointers.length)for(const t of i.metadata.gltf.pointers){const n=t.match(/^\/meshes\/(\d+).+$/);if(n){const t=parseInt(n[1],10);e[t]=e[t]||[],e[t].push(i);break}}}else this._rootMesh=i}return e}setShadowEnabled(e){for(const t of Object.keys(this.meshCache).map(Number)){const i=this.meshCache[t];for(const t of i)t.receiveShadows=e}}}p.ROOT_MESH_PREFIX="vrm_root_";
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
var m=function(e,t){return m=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i])},m(e,t)};function v(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function i(){this.constructor=e}m(e,t),e.prototype=null===t?Object.create(t):(i.prototype=t.prototype,new i)}function g(e,t,i,n){var r,o=arguments.length,a=o<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,i,n);else for(var s=e.length-1;s>=0;s--)(r=e[s])&&(a=(o<3?r(a):o>3?r(t,i,a):r(t,i))||a);return o>3&&a&&Object.defineProperty(t,i,a),a}Object.create;Object.create;class _{constructor(e){this._texture=null,this.diffuseBlendLevel=1,this.roughnessBlendLevel=1,this.bumpLevel=1,this._normalBlendMethod=i.Material.MATERIAL_NORMALBLENDMETHOD_WHITEOUT,this._isEnabled=!1,this.isEnabled=!1,this._internalMarkAllSubMeshesAsTexturesDirty=e}_markAllSubMeshesAsTexturesDirty(){this._internalMarkAllSubMeshesAsTexturesDirty()}isReadyForSubMesh(e,t){if(!this._isEnabled)return!0;const n=t.getEngine();return!(e._areTexturesDirty&&t.texturesEnabled&&n.getCaps().standardDerivatives&&this._texture&&i.MaterialFlags.DetailTextureEnabled&&!this._texture.isReady())}prepareDefines(e,t){if(this._isEnabled){e.DETAIL_NORMALBLENDMETHOD=this._normalBlendMethod;const n=t.getEngine();e._areTexturesDirty&&(n.getCaps().standardDerivatives&&this._texture&&i.MaterialFlags.DetailTextureEnabled&&this._isEnabled?(i.MaterialHelper.PrepareDefinesForMergedUV(this._texture,e,"DETAIL"),e.DETAIL_NORMALBLENDMETHOD=this._normalBlendMethod):e.DETAIL=!1)}else e.DETAIL=!1}bindForSubMesh(e,t,n){this._isEnabled&&(e.useUbo&&n&&e.isSync||this._texture&&i.MaterialFlags.DetailTextureEnabled&&(e.updateFloat4("vDetailInfos",this._texture.coordinatesIndex,this.diffuseBlendLevel,this.bumpLevel,this.roughnessBlendLevel),i.MaterialHelper.BindTextureMatrix(this._texture,e,"detail")),t.texturesEnabled&&this._texture&&i.MaterialFlags.DetailTextureEnabled&&e.setTexture("detailSampler",this._texture))}hasTexture(e){return this._texture===e}getActiveTextures(e){this._texture&&e.push(this._texture)}getAnimatables(e){this._texture&&this._texture.animations&&this._texture.animations.length>0&&e.push(this._texture)}dispose(e){e&&this._texture?.dispose()}getClassName(){return"DetailMapConfiguration"}static AddUniforms(e){e.push("vDetailInfos"),e.push("detailMatrix")}static AddSamplers(e){e.push("detailSampler")}static PrepareUniformBuffer(e){e.addUniform("vDetailInfos",4),e.addUniform("detailMatrix",16)}copyTo(e){i.SerializationHelper.Clone((()=>e),this)}serialize(){return i.SerializationHelper.Serialize(this)}parse(e,t,n){i.SerializationHelper.Parse((()=>this),e,t,n)}}function T(){return[{label:"DiffuseColor",propertyName:"diffuseColor",type:i.InspectableType.Color3},{label:"AmbientColor",propertyName:"ambientColor",type:i.InspectableType.Color3},{label:"EmissiveColor",propertyName:"emissiveColor",type:i.InspectableType.Color3},{label:"ShadeColor",propertyName:"shadeColor",type:i.InspectableType.Color3},{label:"RimColor",propertyName:"rimColor",type:i.InspectableType.Color3},{label:"OutlineColor",propertyName:"outlineColor",type:i.InspectableType.Color3},{label:"ReceiveShadowRate",propertyName:"receiveShadowRate",type:i.InspectableType.Slider,min:0,max:1,step:.01},{label:"ShadingGradeRate",propertyName:"shadingGradeRate",type:i.InspectableType.Slider,min:0,max:1,step:.01},{label:"ShadeShift",propertyName:"shadeShift",type:i.InspectableType.Slider,min:-1,max:1,step:.01},{label:"ShadeToony",propertyName:"shadeToony",type:i.InspectableType.Slider,min:0,max:1,step:.01},{label:"LightColorAttenuation",propertyName:"lightColorAttenuation",type:i.InspectableType.Slider,min:0,max:1,step:.01},{label:"IndirectLightIntensity",propertyName:"indirectLightIntensity",type:i.InspectableType.Slider,min:0,max:1,step:.01},{label:"RimLightingMix",propertyName:"rimLightingMix",type:i.InspectableType.Slider,min:0,max:1,step:.01},{label:"RimFresnelPower",propertyName:"rimFresnelPower",type:i.InspectableType.Slider,min:.01,max:100,step:4},{label:"RimLift",propertyName:"rimLift",type:i.InspectableType.Slider,min:0,max:1,step:.01},{label:"OutlineWidth",propertyName:"outlineWidth",type:i.InspectableType.Slider,min:.01,max:1,step:.01},{label:"OutlineScaledMaxDistance",propertyName:"outlineScaledMaxDistance",type:i.InspectableType.Slider,min:1,max:10,step:.01},{label:"OutlineLightingMix",propertyName:"outlineLightingMix",type:i.InspectableType.Slider,min:0,max:1,step:.01},{label:"DebugMode",propertyName:"debugMode",type:i.InspectableType.Slider,min:0,max:2,step:1},{label:"OutlineWidthMode",propertyName:"outlineWidthMode",type:i.InspectableType.Slider,min:0,max:2,step:1},{label:"OutlineColorMode",propertyName:"outlineColorMode",type:i.InspectableType.Slider,min:0,max:1,step:1},{label:"CullMode",propertyName:"cullMode",type:i.InspectableType.Slider,min:0,max:2,step:1},{label:"OutlineCullMode",propertyName:"outlineCullMode",type:i.InspectableType.Slider,min:0,max:2,step:1},{label:"AlphaCutOff",propertyName:"alphaCutOff",type:i.InspectableType.Slider,min:0,max:1,step:.01},{label:"UV Animation Scroll X",propertyName:"uvAnimationScrollX",type:i.InspectableType.Slider,min:-1,max:1,step:.1},{label:"UV Animation Scroll Y",propertyName:"uvAnimationScrollY",type:i.InspectableType.Slider,min:-1,max:1,step:.1},{label:"UV Animation Rotation",propertyName:"uvAnimationRotation",type:i.InspectableType.Slider,min:-.5,max:.5,step:.01}]}g([(0,i.serializeAsTexture)("detailTexture"),(0,i.expandToProperty)("_markAllSubMeshesAsTexturesDirty")],_.prototype,"texture",void 0),g([(0,i.serialize)()],_.prototype,"diffuseBlendLevel",void 0),g([(0,i.serialize)()],_.prototype,"roughnessBlendLevel",void 0),g([(0,i.serialize)()],_.prototype,"bumpLevel",void 0),g([(0,i.serialize)(),(0,i.expandToProperty)("_markAllSubMeshesAsTexturesDirty")],_.prototype,"normalBlendMethod",void 0),g([(0,i.serialize)(),(0,i.expandToProperty)("_markAllSubMeshesAsTexturesDirty")],_.prototype,"isEnabled",void 0);class x extends i.MaterialDefines{constructor(){super(),this.MTOON_OUTLINE_WIDTH_WORLD=!1,this.MTOON_OUTLINE_WIDTH_SCREEN=!1,this.MTOON_OUTLINE_COLOR_FIXED=!1,this.MTOON_OUTLINE_COLOR_MIXED=!1,this.MTOON_DEBUG_NORMAL=!1,this.MTOON_DEBUG_LITSHADERRATE=!1,this.SHADE=!1,this.SHADEDIRECTUV=0,this.RECEIVE_SHADOW=!1,this.RECEIVE_SHADOWDIRECTUV=0,this.SHADING_GRADE=!1,this.SHADING_GRADEDIRECTUV=0,this.RIM=!1,this.RIMDIRECTUV=0,this.MATCAP=!1,this.MATCAPDIRECTUV=0,this.OUTLINE_WIDTH=!1,this.OUTLINE_WIDTHDIRECTUV=0,this.UV_ANIMATION_MASK=!1,this.UV_ANIMATION_MASKDIRECTUV=0,this.MAINUV1=!1,this.MAINUV2=!1,this.MAINUV3=!1,this.MAINUV4=!1,this.MAINUV5=!1,this.MAINUV6=!1,this.DIFFUSE=!1,this.DIFFUSEDIRECTUV=0,this.DETAIL=!1,this.DETAILDIRECTUV=0,this.DETAIL_NORMALBLENDMETHOD=0,this.AMBIENT=!1,this.AMBIENTDIRECTUV=0,this.EMISSIVE=!1,this.EMISSIVEDIRECTUV=0,this.SPECULAR=!1,this.BUMP=!1,this.BUMPDIRECTUV=0,this.CLIPPLANE=!1,this.CLIPPLANE2=!1,this.CLIPPLANE3=!1,this.CLIPPLANE4=!1,this.CLIPPLANE5=!1,this.CLIPPLANE6=!1,this.ALPHATEST=!1,this.DEPTHPREPASS=!1,this.ALPHAFROMDIFFUSE=!1,this.POINTSIZE=!1,this.FOG=!1,this.SPECULARTERM=!1,this.NORMAL=!1,this.TANGENT=!1,this.UV1=!1,this.UV2=!1,this.UV3=!1,this.UV4=!1,this.UV5=!1,this.UV6=!1,this.VERTEXCOLOR=!1,this.VERTEXALPHA=!1,this.NUM_BONE_INFLUENCERS=0,this.BonesPerMesh=0,this.BONETEXTURE=!1,this.BONES_VELOCITY_ENABLED=!1,this.INSTANCES=!1,this.THIN_INSTANCES=!1,this.EMISSIVEASILLUMINATION=!1,this.LINKEMISSIVEWITHDIFFUSE=!1,this.OBJECTSPACE_NORMALMAP=!1,this.LOGARITHMICDEPTH=!1,this.TWOSIDEDLIGHTING=!1,this.SHADOWFLOAT=!1,this.MORPHTARGETS=!1,this.MORPHTARGETS_NORMAL=!1,this.MORPHTARGETS_TANGENT=!1,this.MORPHTARGETS_UV=!1,this.NUM_MORPH_INFLUENCERS=0,this.MORPHTARGETS_TEXTURE=!1,this.NONUNIFORMSCALING=!1,this.PREMULTIPLYALPHA=!1,this.ALPHATEST_AFTERALLALPHACOMPUTATIONS=!1,this.ALPHABLEND=!0,this.MULTIVIEW=!1,this.rebuild()}setReflectionMode(e){throw new Error("This material cannot use `setReflectionMode`")}}class S{constructor(e,t){this.scene=e,this.material=t,this.zOffset=1,this.zOffsetUnits=4,this._savedDepthWrite=!1,this.name=`MToonOutline_${t.name}_${S.rendererId++}`,this.scene._addComponent(this),this._engine=this.scene.getEngine()}register(){this.scene._beforeRenderingMeshStage.registerStep(i.SceneComponentConstants.STEP_BEFORERENDERINGMESH_OUTLINE,this,this._beforeRenderingMesh),this.scene._afterRenderingMeshStage.registerStep(i.SceneComponentConstants.STEP_AFTERRENDERINGMESH_OUTLINE,this,this._afterRenderingMesh)}rebuild(){}dispose(){}render(e,t,i,n=!1){const r=t.effect;if(!r||!r.isReady()||!this.scene.activeCamera)return;const o=t.getMesh(),a=o._internalAbstractMeshDataInfo._actAsRegularMesh?o:null,s=t.getRenderingMesh(),l=a||s;this._engine.enableEffect(r),s._bind(t,r,this.material.fillMode),this._engine.setZOffset(-this.zOffset),this._engine.setZOffsetUnits(-this.zOffsetUnits),s._processRendering(l,t,r,this.material.fillMode,i,this.isHardwareInstancedRendering(t,i),((i,n,o)=>{o.bindForSubMesh(n,e,t),r.setMatrix("world",n),r.setFloat("isOutline",1)}),this.material),this._engine.setZOffset(0),this._engine.setZOffsetUnits(0)}_beforeRenderingMesh(e,t,n){if(this._savedDepthWrite=this._engine.getDepthWrite(),!this.willRender(e))return;const r=t.getMaterial();r.needAlphaBlendingForMesh(e)&&(this._engine.cacheStencilState(),this._engine.setDepthWrite(!1),this._engine.setColorWrite(!1),this._engine.setStencilBuffer(!0),this._engine.setStencilOperationPass(i.Constants.REPLACE),this._engine.setStencilFunction(i.Constants.ALWAYS),this._engine.setStencilMask(S._StencilReference),this._engine.setStencilFunctionReference(S._StencilReference),this.render(t.getRenderingMesh(),t,n,!0),this._engine.setColorWrite(!0),this._engine.setStencilFunction(i.Constants.NOTEQUAL)),this._engine.setDepthWrite(!1),this.render(t.getRenderingMesh(),t,n),this._engine.setDepthWrite(this._savedDepthWrite),r.needAlphaBlendingForMesh(e)&&this._engine.restoreStencilState()}_afterRenderingMesh(e,t,i){this.willRender(e)&&this._savedDepthWrite&&(this._engine.setDepthWrite(!0),this._engine.setColorWrite(!1),this.render(t.getRenderingMesh(),t,i),this._engine.setColorWrite(!0))}isHardwareInstancedRendering(e,t){if(!this._engine.getCaps().instancedArrays)return!1;let i=!1;return i=e.getRenderingMesh().hasThinInstances,null!==t.visibleInstances[e._id]&&void 0!==t.visibleInstances[e._id]||i}willRender(e){const t=e._internalMeshDataInfo._effectiveMaterial;return!(!t||"MToonMaterial"!==t.getClassName()||t.getOutlineRendererName()!==this.name)}}S._StencilReference=4,S.rendererId=0;var E,M,C,A;!function(e){e[e.None=0]="None",e[e.Normal=1]="Normal",e[e.LitShadeRate=2]="LitShadeRate"}(E||(E={})),function(e){e[e.FixedColor=0]="FixedColor",e[e.MixedLighting=1]="MixedLighting"}(M||(M={})),function(e){e[e.None=0]="None",e[e.WorldCorrdinates=1]="WorldCorrdinates",e[e.ScreenCoordinates=2]="ScreenCoordinates"}(C||(C={})),function(e){e[e.Off=0]="Off",e[e.Front=1]="Front",e[e.Back=2]="Back"}(A||(A={}));const P={effect:null,subMesh:null};class y extends i.PushMaterial{constructor(e,t){super(e,t),this._diffuseTexture=null,this._ambientTexture=null,this._emissiveTexture=null,this._specularTexture=null,this._bumpTexture=null,this._shadeTexture=null,this._receiveShadowTexture=null,this._shadingGradeTexture=null,this._rimTexture=null,this._matCapTexture=null,this._outlineWidthTexture=null,this._uvAnimationMaskTexture=null,this.ambientColor=new i.Color3(0,0,0),this.diffuseColor=new i.Color3(1,1,1),this.specularColor=new i.Color3(1,1,1),this.emissiveColor=new i.Color3(0,0,0),this.shadeColor=new i.Color3(.97,.81,.86),this.rimColor=new i.Color3(0,0,0),this.outlineColor=new i.Color3(0,0,0),this.specularPower=64,this._useAlphaFromDiffuseTexture=!0,this._useEmissiveAsIllumination=!1,this._linkEmissiveWithDiffuse=!1,this._useSpecularOverAlpha=!1,this._disableLighting=!1,this._useObjectSpaceNormalMap=!1,this._useParallax=!1,this._useParallaxOcclusion=!1,this.alphaCutOff=.4,this._useGlossinessFromSpecularMapAlpha=!1,this._maxSimultaneousLights=4,this._twoSidedLighting=!1,this.useVertexColor=!1,this.useBones=!0,this.useMorphTargets=!0,this.useVertexAlpha=!1,this.detailMap=new _(this._markAllSubMeshesAsTexturesDirty.bind(this)),this._worldViewProjectionMatrix=i.Matrix.Zero(),this._globalAmbientColor=new i.Color3(0,0,0),this._bumpScale=.1,this.parallaxScaleBias=this._bumpScale,this._receiveShadowRate=1,this._shadingGradeRate=1,this._shadeShift=0,this._shadeToony=.9,this._lightColorAttenuation=0,this._indirectLightIntensity=.1,this._rimLightingMix=0,this._rimFresnelPower=1,this._rimLift=0,this._outlineWidth=.5,this._outlineScaledMaxDistance=1,this._outlineLightingMix=1,this._uvAnimationScrollX=0,this._uvAnimationScrollY=0,this._uvAnimationRotation=0,this._debugMode=E.None,this.debugMode=E.None,this.outlineRenderer=new S(this.getScene(),this),this._outlineWidthMode=C.None,this.outlineWidthMode=C.None,this._outlineColorMode=M.MixedLighting,this.outlineColorMode=M.MixedLighting,this._cullMode=A.Back,this._outlineCullMode=A.Front,this.outlineCullMode=A.Front,this.storedCullMode=A.Back,i.Effect.ShadersStore.mtoonVertexShader&&i.Effect.ShadersStore.mtoonFragmentShader||(i.Effect.IncludesShadersStore.mtoonUboDeclaration="\n// include<__decl__mtoonVertex> または include<__decl__mtoonFragment> と書いた時に WebGL2 の場合展開される\n// @see effect.ts\n\nlayout(std140, column_major) uniform;\n\nuniform Material\n{\n // Color & Texture\n vec4 vDiffuseColor;\n vec2 vDiffuseInfos;\n mat4 diffuseMatrix;\n vec4 vSpecularColor;\n vec2 vSpecularInfos;\n mat4 specularMatrix;\n vec3 vAmbientColor;\n vec2 vAmbientInfos;\n mat4 ambientMatrix;\n vec3 vEmissiveColor;\n vec2 vEmissiveInfos;\n mat4 emissiveMatrix;\n vec3 vBumpInfos;\n mat4 bumpMatrix;\n vec3 vShadeColor;\n vec2 vShadeInfos;\n mat4 shadeMatrix;\n vec2 vReceiveShadowInfos;\n mat4 receiveShadowMatrix;\n vec2 vShadingGradeInfos;\n mat4 shadingGradeMatrix;\n vec3 vRimColor;\n vec2 vRimInfos;\n mat4 rimMatrix;\n vec2 vMatCapInfos;\n mat4 matCapMatrix;\n vec4 vOutlineColor;\n vec2 vOutlineWidthInfos;\n mat4 outlineWidthMatrix;\n vec2 vUvAnimationMaskInfos;\n mat4 uvAnimationMaskMatrix;\n\n // babylon specific\n vec2 vTangentSpaceParams;\n float pointSize;\n float alphaCutOff;\n\n // MToon params\n float shadingGradeRate;\n float receiveShadowRate;\n float shadeShift;\n float shadeToony;\n float lightColorAttenuation;\n float indirectLightIntensity;\n float rimLightingMix;\n float rimFresnelPower;\n float rimLift;\n float outlineWidth;\n float outlineScaledMaxDistance;\n float outlineLightingMix;\n float uvAnimationScrollX;\n float uvAnimationScrollY;\n float uvAnimationRotation;\n};\n\n// babylon specific\nuniform Scene {\n mat4 viewProjection;\n#ifdef MULTIVIEW\n mat4 viewProjectionR;\n#endif\n mat4 view;\n mat4 projection;\n vec4 vEyePosition;\n};\n",i.Effect.IncludesShadersStore.mtoonVertexDeclaration="\n// Uniforms\nuniform mat4 viewProjection;\nuniform mat4 view;\nuniform float outlineWidth;\nuniform float outlineScaledMaxDistance;\nuniform float outlineLightingMix;\n\n#ifdef DIFFUSE\nuniform mat4 diffuseMatrix;\nuniform vec2 vDiffuseInfos;\n#endif\n\n#ifdef EMISSIVE\nuniform vec2 vEmissiveInfos;\nuniform mat4 emissiveMatrix;\n#endif\n\n#ifdef BUMP\nuniform vec3 vBumpInfos;\nuniform mat4 bumpMatrix;\n#endif\n\n#ifdef SHADE\nuniform vec2 vShadeInfos;\nuniform mat4 shadeMatrix;\n#endif\n\n#ifdef RECEIVE_SHADOW\nuniform vec2 vReceiveShadowInfos;\nuniform mat4 receiveShadowMatrix;\n#endif\n\n#ifdef SHADING_GRADE\nuniform vec2 vShadingGradeInfos;\nuniform mat4 shadingGradeMatrix;\n#endif\n\n#ifdef RIM\nuniform vec2 vRimInfos;\nuniform mat4 rimMatrix;\n#endif\n\n#ifdef MATCAP\nuniform vec2 vMatCapInfos;\nuniform mat4 matCapMatrix;\n#endif\n\n#ifdef OUTLINE_WIDTH\nuniform vec2 vOutlineWidthInfos;\nuniform mat4 outlineWidthMatrix;\n#endif\n\n#ifdef UV_ANIMATION_MASK\nuniform vec2 vUvAnimationMaskInfos;\nuniform mat4 uvAnimationMaskMatrix;\n#endif\n\n#ifdef POINTSIZE\nuniform float pointSize;\n#endif\n",i.Effect.IncludesShadersStore.mtoonFragmentDeclaration="\nuniform vec4 vEyePosition;\nuniform mat4 viewProjection;\nuniform mat4 view;\n\n// Colors\nuniform vec4 vDiffuseColor;\n#ifdef SPECULARTERM\nuniform vec4 vSpecularColor;\n#endif\nuniform vec3 vEmissiveColor;\nuniform vec3 vAmbientColor;\nuniform vec3 vShadeColor;\nuniform vec3 vRimColor;\nuniform vec4 vOutlineColor;\n\n// Samplers\n#ifdef DIFFUSE\nuniform vec2 vDiffuseInfos;\n#endif\n#ifdef AMBIENT\nuniform vec2 vAmbientInfos;\n#endif\n#ifdef EMISSIVE\nuniform vec2 vEmissiveInfos;\n#endif\n#ifdef BUMP\nuniform vec3 vBumpInfos;\nuniform vec2 vTangentSpaceParams;\n#endif\n#ifdef SHADE\nuniform vec2 vShadeInfos;\n#endif\n#ifdef RECEIVE_SHADOW\nuniform vec2 vReceiveShadowInfos;\n#endif\n#ifdef SHADING_GRADE\nuniform vec2 vShadingGradeInfos;\n#endif\n#ifdef RIM\nuniform vec2 vRimInfos;\n#endif\n#ifdef MATCAP\nuniform vec2 vMatCapInfos;\n#endif\n#ifdef OUTLINE_WIDTH\nuniform vec2 vOutlineWidthInfos;\n#endif\n#ifdef UV_ANIMATION_MASK\nuniform vec2 vUvAnimationMaskInfos;\n#endif\n#ifdef ALPHATEST\nuniform float alphaCutOff;\n#endif\n#if defined(SPECULAR) && defined(SPECULARTERM)\nuniform vec2 vSpecularInfos;\n#endif\n\n// MToon params\nuniform float shadingGradeRate;\nuniform float receiveShadowRate;\nuniform float shadeShift;\nuniform float shadeToony;\nuniform float lightColorAttenuation;\nuniform float indirectLightIntensity;\nuniform float rimLightingMix;\nuniform float rimFresnelPower;\nuniform float rimLift;\nuniform float outlineWidth;\nuniform float outlineScaledMaxDistance;\nuniform float outlineLightingMix;\nuniform float uvAnimationScrollX;\nuniform float uvAnimationScrollY;\nuniform float uvAnimationRotation;\n",i.Effect.IncludesShadersStore.mtoonLightPreFragment="\n#ifdef LIGHT{X}\n/**\n #if defined(SHADOWONLY) || defined(LIGHTMAP) && defined(LIGHTMAPEXCLUDED{X}) && defined(LIGHTMAPNOSPECULAR{X})\n\n #else\n #ifdef PBR\n\n #ifdef SPOTLIGHT{X}\n preInfo=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);\n #elif defined(POINTLIGHT{X})\n preInfo=computePointAndSpotPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);\n #elif defined(HEMILIGHT{X})\n preInfo=computeHemisphericPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);\n #elif defined(DIRLIGHT{X})\n preInfo=computeDirectionalPreLightingInfo(light{X}.vLightData,viewDirectionW,normalW);\n #endif\n preInfo.NdotV=NdotV;\n\n #ifdef SPOTLIGHT{X}\n #ifdef LIGHT_FALLOFF_GLTF{X}\n preInfo.attenuation=computeDistanceLightFalloff_GLTF(preInfo.lightDistanceSquared,light{X}.vLightFalloff.y);\n preInfo.attenuation*=computeDirectionalLightFalloff_GLTF(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightFalloff.z,light{X}.vLightFalloff.w);\n #elif defined(LIGHT_FALLOFF_PHYSICAL{X})\n preInfo.attenuation=computeDistanceLightFalloff_Physical(preInfo.lightDistanceSquared);\n preInfo.attenuation*=computeDirectionalLightFalloff_Physical(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightDirection.w);\n #elif defined(LIGHT_FALLOFF_STANDARD{X})\n preInfo.attenuation=computeDistanceLightFalloff_Standard(preInfo.lightOffset,light{X}.vLightFalloff.x);\n preInfo.attenuation*=computeDirectionalLightFalloff_Standard(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightDirection.w,light{X}.vLightData.w);\n #else\n preInfo.attenuation=computeDistanceLightFalloff(preInfo.lightOffset,preInfo.lightDistanceSquared,light{X}.vLightFalloff.x,light{X}.vLightFalloff.y);\n preInfo.attenuation*=computeDirectionalLightFalloff(light{X}.vLightDirection.xyz,preInfo.L,light{X}.vLightDirection.w,light{X}.vLightData.w,light{X}.vLightFalloff.z,light{X}.vLightFalloff.w);\n #endif\n #elif defined(POINTLIGHT{X})\n #ifdef LIGHT_FALLOFF_GLTF{X}\n preInfo.attenuation=computeDistanceLightFalloff_GLTF(preInfo.lightDistanceSquared,light{X}.vLightFalloff.y);\n #elif defined(LIGHT_FALLOFF_PHYSICAL{X})\n preInfo.attenuation=computeDistanceLightFalloff_Physical(preInfo.lightDistanceSquared);\n #elif defined(LIGHT_FALLOFF_STANDARD{X})\n preInfo.attenuation=computeDistanceLightFalloff_Standard(preInfo.lightOffset,light{X}.vLightFalloff.x);\n #else\n preInfo.attenuation=computeDistanceLightFalloff(preInfo.lightOffset,preInfo.lightDistanceSquared,light{X}.vLightFalloff.x,light{X}.vLightFalloff.y);\n #endif\n #else\n preInfo.attenuation=1.0;\n #endif\n\n\n #ifdef HEMILIGHT{X}\n preInfo.roughness=roughness;\n #else\n preInfo.roughness=adjustRoughnessFromLightProperties(roughness,light{X}.vLightSpecular.a,preInfo.lightDistance);\n #endif\n\n #ifdef HEMILIGHT{X}\n info.diffuse=computeHemisphericDiffuseLighting(preInfo,light{X}.vLightDiffuse.rgb,light{X}.vLightGround);\n #elif defined(SS_TRANSLUCENCY)\n info.diffuse=computeDiffuseAndTransmittedLighting(preInfo,light{X}.vLightDiffuse.rgb,subSurfaceOut.transmittance);\n #else\n info.diffuse=computeDiffuseLighting(preInfo,light{X}.vLightDiffuse.rgb);\n #endif\n\n #ifdef SPECULARTERM\n #ifdef ANISOTROPIC\n info.specular=computeAnisotropicSpecularLighting(preInfo,viewDirectionW,normalW,anisotropicOut.anisotropicTangent,anisotropicOut.anisotropicBitangent,anisotropicOut.anisotropy,clearcoatOut.specularEnvironmentR0,specularEnvironmentR90,AARoughnessFactors.x,light{X}.vLightDiffuse.rgb);\n #else\n info.specular=computeSpecularLighting(preInfo,normalW,clearcoatOut.specularEnvironmentR0,specularEnvironmentR90,AARoughnessFactors.x,light{X}.vLightDiffuse.rgb);\n #endif\n #endif\n\n #ifdef SHEEN\n #ifdef SHEEN_LINKWITHALBEDO\n\n preInfo.roughness=sheenOut.sheenIntensity;\n #else\n #ifdef HEMILIGHT{X}\n preInfo.roughness=sheenOut.sheenRoughness;\n #else\n preInfo.roughness=adjustRoughnessFromLightProperties(sheenOut.sheenRoughness,light{X}.vLightSpecular.a,preInfo.lightDistance);\n #endif\n #endif\n info.sheen=computeSheenLighting(preInfo,normalW,sheenOut.sheenColor,specularEnvironmentR90,AARoughnessFactors.x,light{X}.vLightDiffuse.rgb);\n #endif\n\n #ifdef CLEARCOAT\n\n #ifdef HEMILIGHT{X}\n preInfo.roughness=clearcoatOut.clearCoatRoughness;\n #else\n preInfo.roughness=adjustRoughnessFromLightProperties(clearcoatOut.clearCoatRoughness,light{X}.vLightSpecular.a,preInfo.lightDistance);\n #endif\n info.clearCoat=computeClearCoatLighting(preInfo,clearcoatOut.clearCoatNormalW,clearcoatOut.clearCoatAARoughnessFactors.x,clearcoatOut.clearCoatIntensity,light{X}.vLightDiffuse.rgb);\n #ifdef CLEARCOAT_TINT\n\n absorption=computeClearCoatLightingAbsorption(clearcoatOut.clearCoatNdotVRefract,preInfo.L,clearcoatOut.clearCoatNormalW,clearcoatOut.clearCoatColor,clearcoatOut.clearCoatThickness,clearcoatOut.clearCoatIntensity);\n info.diffuse*=absorption;\n #ifdef SPECULARTERM\n info.specular*=absorption;\n #endif\n #endif\n\n info.diffuse*=info.clearCoat.w;\n #ifdef SPECULARTERM\n info.specular*=info.clearCoat.w;\n #endif\n #ifdef SHEEN\n info.sheen*=info.clearCoat.w;\n #endif\n #endif\n #else\n #ifdef SPOTLIGHT{X}\n info=computeSpotLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDirection,light{X}.vLightDiffuse.rgb,light{X}.vLightSpecular.rgb,light{X}.vLightDiffuse.a,glossiness);\n #elif defined(HEMILIGHT{X})\n info=computeHemisphericLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDiffuse.rgb,light{X}.vLightSpecular.rgb,light{X}.vLightGround,glossiness);\n #elif defined(POINTLIGHT{X}) || defined(DIRLIGHT{X})\n info=computeLighting(viewDirectionW,normalW,light{X}.vLightData,light{X}.vLightDiffuse.rgb,light{X}.vLightSpecular.rgb,light{X}.vLightDiffuse.a,glossiness);\n #endif\n #endif\n #ifdef PROJECTEDLIGHTTEXTURE{X}\n info.diffuse*=computeProjectionTextureDiffuseLighting(projectionLightSampler{X},textureProjectionMatrix{X});\n #endif\n #endif\n*/\n #ifdef SHADOW{X}\n #ifdef SHADOWCSM{X}\n for (int i=0; i<SHADOWCSMNUM_CASCADES{X}; i++)\n {\n #ifdef SHADOWCSM_RIGHTHANDED{X}\n diff{X}=viewFrustumZ{X}[i]+vPositionFromCamera{X}.z;\n #else\n diff{X}=viewFrustumZ{X}[i]-vPositionFromCamera{X}.z;\n #endif\n if (diff{X}>=0.) {\n index{X}=i;\n break;\n }\n }\n #ifdef SHADOWCSMUSESHADOWMAXZ{X}\n if (index{X}>=0)\n #endif\n {\n #if defined(SHADOWPCF{X})\n #if defined(SHADOWLOWQUALITY{X})\n shadow=computeShadowWithCSMPCF1(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowSampler{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n #elif defined(SHADOWMEDIUMQUALITY{X})\n shadow=computeShadowWithCSMPCF3(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowSampler{X},light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n #else\n shadow=computeShadowWithCSMPCF5(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowSampler{X},light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n #endif\n #elif defined(SHADOWPCSS{X})\n #if defined(SHADOWLOWQUALITY{X})\n shadow=computeShadowWithCSMPCSS16(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthSampler{X},shadowSampler{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,lightSizeUVCorrection{X}[index{X}],depthCorrection{X}[index{X}],penumbraDarkness{X});\n #elif defined(SHADOWMEDIUMQUALITY{X})\n shadow=computeShadowWithCSMPCSS32(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthSampler{X},shadowSampler{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,lightSizeUVCorrection{X}[index{X}],depthCorrection{X}[index{X}],penumbraDarkness{X});\n #else\n shadow=computeShadowWithCSMPCSS64(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthSampler{X},shadowSampler{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,lightSizeUVCorrection{X}[index{X}],depthCorrection{X}[index{X}],penumbraDarkness{X});\n #endif\n #else\n shadow=computeShadowCSM(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowSampler{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n #endif\n #ifdef SHADOWCSMDEBUG{X}\n shadowDebug{X}=vec3(shadow)*vCascadeColorsMultiplier{X}[index{X}];\n #endif\n #ifndef SHADOWCSMNOBLEND{X}\n float frustumLength=frustumLengths{X}[index{X}];\n float diffRatio=clamp(diff{X}/frustumLength,0.,1.)*cascadeBlendFactor{X};\n if (index{X}<(SHADOWCSMNUM_CASCADES{X}-1) && diffRatio<1.)\n {\n index{X}+=1;\n float nextShadow=0.;\n #if defined(SHADOWPCF{X})\n #if defined(SHADOWLOWQUALITY{X})\n nextShadow=computeShadowWithCSMPCF1(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowSampler{X},light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n #elif defined(SHADOWMEDIUMQUALITY{X})\n nextShadow=computeShadowWithCSMPCF3(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowSampler{X},light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n #else\n nextShadow=computeShadowWithCSMPCF5(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],shadowSampler{X},light{X}.shadowsInfo.yz,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w);\n #endif\n #elif defined(SHADOWPCSS{X})\n #if defined(SHADOWLOWQUALITY{X})\n nextShadow=computeShadowWithCSMPCSS16(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[index{X}],depthSampler{X},shadowSampler{X},light{X}.shadowsInfo.y,light{X}.shadowsInfo.z,light{X}.shadowsInfo.x,light{X}.shadowsInfo.w,lightSizeUVCorrection{X}[index{X}],depthCorrection{X}[index{X}],penumbraDarkness{X});\n #elif defined(SHADOWMEDIUMQUALITY{X})\n nextShadow=computeShadowWithCSMPCSS32(float(index{X}),vPositionFromLight{X}[index{X}],vDepthMetric{X}[