@pixiv/three-vrm
Version:
VRM file loader for three.js.
11 lines (10 loc) • 12.4 kB
JavaScript
/*! (c) 2019-2025 pixiv Inc. - https://github.com/pixiv/three-vrm/blob/release/LICENSE */
import*as Y from"three";import*as X from"three/webgpu";import{cos as Z,mat2 as $,sin as J,uv as k,vec2 as M,vec4 as Q}from"three/tsl";import{materialReference as o}from"three/tsl";import*as z from"three/webgpu";import{BRDF_Lambert as S,diffuseColor as B,float as yt,mix as F,transformedNormalView as Ct,vec3 as x}from"three/tsl";import*as s from"three/webgpu";import{nodeImmutable as h}from"three/tsl";import*as j from"three/tsl";import*as v from"three/webgpu";import*as a from"three/webgpu";import{cameraProjectionMatrix as Pt,diffuseColor as At,float as p,length as Ht,matcapUV as Wt,materialNormal as Ut,mix as Ot,modelNormalMatrix as It,modelViewMatrix as kt,normalLocal as bt,normalMap as Dt,positionLocal as R,vec3 as d,vec4 as Yt}from"three/tsl";import{float as Xt,modelViewPosition as zt,transformedNormalView as Bt}from"three/tsl";var I=parseInt(Y.REVISION,10);I<167&&console.warn(`MToonNodeMaterial requires Three.js r167 or higher (You are using r${I}). This would not work correctly.`);var tt=o("color","color"),it=o("map","texture"),et=o("normalMap","texture"),ot=o("normalScale","vec2"),rt=o("emissive","color"),at=o("emissiveIntensity","float"),nt=o("emissiveMap","texture"),lt=o("shadeColorFactor","color"),st=o("shadingShiftFactor","float"),b=o("shadeMultiplyTexture","texture"),ht=o("shadeMultiplyTextureScale","float"),ut=o("shadingToonyFactor","float"),mt=o("rimLightingMixFactor","float"),dt=o("rimMultiplyTexture","texture"),ct=o("matcapFactor","color"),pt=o("matcapTexture","texture"),ft=o("parametricRimColorFactor","color"),Nt=o("parametricRimLiftFactor","float"),gt=o("parametricRimFresnelPowerFactor","float"),vt=o("outlineWidthMultiplyTexture","texture"),Tt=o("outlineWidthFactor","float"),D=o("outlineColorFactor","color"),Mt=o("outlineLightingMixFactor","float"),xt=o("uvAnimationMaskTexture","texture"),Rt=o("uvAnimationScrollXOffset","float"),St=o("uvAnimationScrollYOffset","float"),Ft=o("uvAnimationRotationPhase","float"),Et=class extends X.TempNode{constructor(t){super("vec2"),this.hasMaskTexture=t}setup(){let t=1;this.hasMaskTexture&&(t=Q(xt).context({getUV:()=>k()}).r);let i=k(),e=Ft.mul(t),r=Z(e),n=J(e);i=i.sub(M(.5,.5)),i=i.mul($(r,n,n.negate(),r)),i=i.add(M(.5,.5));let l=M(Rt,St).mul(t);return i=i.add(l),i.toVar("AnimatedUV")}},q=h(s.PropertyNode,"vec3").toVar("ShadeColor"),G=h(s.PropertyNode,"float").toVar("ShadingShift"),K=h(s.PropertyNode,"float").toVar("ShadingToony"),E=h(s.PropertyNode,"float").toVar("RimLightingMix"),y=h(s.PropertyNode,"vec3").toVar("RimMultiply"),C=h(s.PropertyNode,"vec3").toVar("matcap"),_=h(s.PropertyNode,"vec3").toVar("ParametricRim"),T=t=>parseInt(v.REVISION,10)>=168?j.Fn(t):v.tslFn(t),_t=T(({a:t,b:i,t:e})=>{let r=e.sub(t),n=i.sub(t);return r.div(n).clamp()}),Vt=T(({dotNL:t})=>{let e=yt(1).sub(K),r=t.add(G);return r=_t({a:e.negate(),b:e,t:r}),r=r.mul(1),r}),Lt=T(({shading:t,lightColor:i})=>{let e=F(q,B,t);return i.mul(S({diffuseColor:e}))}),wt=class extends z.LightingModel{constructor(){super()}direct({lightDirection:t,lightColor:i,reflectedLight:e}){let r=Ct.dot(t).clamp(-1,1),n=Vt({dotNL:r});e.directDiffuse.addAssign(Lt({shading:n,lightColor:i})),e.directSpecular.addAssign(_.add(C).mul(y).mul(F(x(0),S({diffuseColor:i}),E)))}indirect(t){let i="context"in t?t.context:t;this.indirectDiffuse(i),this.indirectSpecular(i)}indirectDiffuse(t){let{irradiance:i,reflectedLight:e}=t;e.indirectDiffuse.addAssign(i.mul(S({diffuseColor:B})))}indirectSpecular(t){let{reflectedLight:i}=t;i.indirectSpecular.addAssign(_.add(C).mul(y).mul(F(x(1),x(0),E)))}},f={None:"none",WorldCoordinates:"worldCoordinates",ScreenCoordinates:"screenCoordinates"},qt=T(({parametricRimLift:t,parametricRimFresnelPower:i,parametricRimColor:e})=>{let r=zt.normalize(),n=Bt.dot(r.negate());return Xt(1).sub(n).add(t).clamp().pow(i).mul(e)}),Qt=class extends a.NodeMaterial{customProgramCacheKey(){let t=super.customProgramCacheKey();return t+=`isOutline:${this.isOutline},`,t}get isMToonNodeMaterial(){return!0}constructor(t={}){super(),t.transparentWithZWrite&&(t.depthWrite=!0),delete t.transparentWithZWrite,delete t.giEqualizationFactor,delete t.v0CompatShade,delete t.debugMode,this.emissiveNode=null,this.lights=!0,this.color=new a.Color(1,1,1),this.map=null,this.emissive=new a.Color(0,0,0),this.emissiveIntensity=1,this.emissiveMap=null,this.normalMap=null,this.normalScale=new a.Vector2(1,1),this.shadeColorFactor=new a.Color(0,0,0),this.shadeMultiplyTexture=null,this.shadingShiftFactor=0,this.shadingShiftTexture=null,this.shadingShiftTextureScale=1,this.shadingToonyFactor=.9,this.rimLightingMixFactor=1,this.rimMultiplyTexture=null,this.matcapFactor=new a.Color(1,1,1),this.matcapTexture=null,this.parametricRimColorFactor=new a.Color(0,0,0),this.parametricRimLiftFactor=0,this.parametricRimFresnelPowerFactor=5,this.outlineWidthMode=f.None,this.outlineWidthMultiplyTexture=null,this.outlineWidthFactor=0,this.outlineColorFactor=new a.Color(0,0,0),this.outlineLightingMixFactor=1,this.uvAnimationScrollXSpeedFactor=0,this.uvAnimationScrollYSpeedFactor=0,this.uvAnimationRotationSpeedFactor=0,this.uvAnimationMaskTexture=null,this.shadeColorNode=null,this.shadingShiftNode=null,this.shadingToonyNode=null,this.rimLightingMixNode=null,this.rimMultiplyNode=null,this.matcapNode=null,this.parametricRimColorNode=null,this.parametricRimLiftNode=null,this.parametricRimFresnelPowerNode=null,this.uvAnimationScrollXOffset=0,this.uvAnimationScrollYOffset=0,this.uvAnimationRotationPhase=0,this.isOutline=!1,this._animatedUVNode=null,this.setValues(t)}setupLightingModel(){return new wt}setup(t){var i;this._animatedUVNode=new Et((i=this.uvAnimationMaskTexture&&this.uvAnimationMaskTexture.isTexture===!0)!=null?i:!1),super.setup(t)}setupDiffuseColor(t){let i=null;if(this.colorNode==null){if(i=tt,this.map&&this.map.isTexture===!0){let e=it.context({getUV:()=>this._animatedUVNode});i=i.mul(e)}this.colorNode=i}this.vertexColors===!0&&t.geometry.hasAttribute("color")&&(console.warn("MToonNodeMaterial: MToon ignores vertex colors. Consider using a model without vertex colors instead."),this.vertexColors=!1),super.setupDiffuseColor(t),parseInt(a.REVISION,10)<166&&this.transparent===!1&&this.blending===a.NormalBlending&&this.alphaToCoverage===!1&&At.a.assign(1),this.colorNode===i&&(this.colorNode=null)}setupVariants(){q.assign(this._setupShadeColorNode()),G.assign(this._setupShadingShiftNode()),K.assign(this._setupShadingToonyNode()),E.assign(this._setupRimLightingMixNode()),y.assign(this._setupRimMultiplyNode()),C.assign(this._setupMatcapNode()),_.assign(this._setupParametricRimNode())}setupNormal(t){let i=this.normalNode;if(this.normalNode==null){if(this.normalNode=Ut,this.normalMap&&this.normalMap.isTexture===!0){let r=et.context({getUV:()=>this._animatedUVNode});this.normalNode=Dt(r,ot)}this.isOutline&&(this.normalNode=this.normalNode.negate())}if(parseInt(a.REVISION,10)>=168){let r=this.normalNode;return this.normalNode=i,r}else{super.setupNormal(t),this.normalNode=i;return}}setupLighting(t){let i=null;if(this.emissiveNode==null){if(i=rt.mul(at),this.emissiveMap&&this.emissiveMap.isTexture===!0){let r=nt.context({getUV:()=>this._animatedUVNode});i=i.mul(r)}this.emissiveNode=i}let e=super.setupLighting(t);return this.emissiveNode===i&&(this.emissiveNode=null),e}setupOutput(t,i){return this.isOutline&&this.outlineWidthMode!==f.None&&(i=Yt(Ot(D,i.xyz.mul(D),Mt),i.w)),super.setupOutput(t,i)}setupPosition(t){var i,e;let r=this.positionNode;if(this.isOutline&&this.outlineWidthMode!==f.None){(i=this.positionNode)!=null||(this.positionNode=R);let l=bt.normalize(),u=Tt;if(this.outlineWidthMultiplyTexture&&this.outlineWidthMultiplyTexture.isTexture===!0){let m=vt.context({getUV:()=>this._animatedUVNode});u=u.mul(m)}let N=Ht(It.mul(l)),c=u.mul(N).mul(l);if(this.outlineWidthMode===f.WorldCoordinates)this.positionNode=this.positionNode.add(c);else if(this.outlineWidthMode===f.ScreenCoordinates){let m=Pt.element(1).element(1),g=kt.mul(R);this.positionNode=this.positionNode.add(c.div(m).mul(g.z.negate()))}(e=this.positionNode)!=null||(this.positionNode=R)}let n=super.setupPosition(t);return n.z.add(n.w.mul(1e-6)),this.positionNode=r,n}copy(t){var i,e,r,n,l,u,N,c,m,g,V,L,w,P,A,H,W,U,O;return this.color.copy(t.color),this.map=(i=t.map)!=null?i:null,this.emissive.copy(t.emissive),this.emissiveIntensity=t.emissiveIntensity,this.emissiveMap=(e=t.emissiveMap)!=null?e:null,this.normalMap=(r=t.normalMap)!=null?r:null,this.normalScale.copy(t.normalScale),this.shadeColorFactor.copy(t.shadeColorFactor),this.shadeMultiplyTexture=(n=t.shadeMultiplyTexture)!=null?n:null,this.shadingShiftFactor=t.shadingShiftFactor,this.shadingShiftTexture=(l=t.shadingShiftTexture)!=null?l:null,this.shadingShiftTextureScale=t.shadingShiftTextureScale,this.shadingToonyFactor=t.shadingToonyFactor,this.rimLightingMixFactor=t.rimLightingMixFactor,this.rimMultiplyTexture=(u=t.rimMultiplyTexture)!=null?u:null,this.matcapFactor.copy(t.matcapFactor),this.matcapTexture=(N=t.matcapTexture)!=null?N:null,this.parametricRimColorFactor.copy(t.parametricRimColorFactor),this.parametricRimLiftFactor=t.parametricRimLiftFactor,this.parametricRimFresnelPowerFactor=t.parametricRimFresnelPowerFactor,this.outlineWidthMode=t.outlineWidthMode,this.outlineWidthMultiplyTexture=(c=t.outlineWidthMultiplyTexture)!=null?c:null,this.outlineWidthFactor=t.outlineWidthFactor,this.outlineColorFactor.copy(t.outlineColorFactor),this.outlineLightingMixFactor=t.outlineLightingMixFactor,this.uvAnimationScrollXSpeedFactor=t.uvAnimationScrollXSpeedFactor,this.uvAnimationScrollYSpeedFactor=t.uvAnimationScrollYSpeedFactor,this.uvAnimationRotationSpeedFactor=t.uvAnimationRotationSpeedFactor,this.uvAnimationMaskTexture=(m=t.uvAnimationMaskTexture)!=null?m:null,this.shadeColorNode=(g=t.shadeColorNode)!=null?g:null,this.shadingShiftNode=(V=t.shadingShiftNode)!=null?V:null,this.shadingToonyNode=(L=t.shadingToonyNode)!=null?L:null,this.rimLightingMixNode=(w=t.rimLightingMixNode)!=null?w:null,this.rimMultiplyNode=(P=t.rimMultiplyNode)!=null?P:null,this.matcapNode=(A=t.matcapNode)!=null?A:null,this.parametricRimColorNode=(H=t.parametricRimColorNode)!=null?H:null,this.parametricRimLiftNode=(W=t.parametricRimLiftNode)!=null?W:null,this.parametricRimFresnelPowerNode=(U=t.parametricRimFresnelPowerNode)!=null?U:null,this.isOutline=(O=t.isOutline)!=null?O:null,super.copy(t)}update(t){this.uvAnimationScrollXOffset+=t*this.uvAnimationScrollXSpeedFactor,this.uvAnimationScrollYOffset+=t*this.uvAnimationScrollYSpeedFactor,this.uvAnimationRotationPhase+=t*this.uvAnimationRotationSpeedFactor}_setupShadeColorNode(){if(this.shadeColorNode!=null)return d(this.shadeColorNode);let t=lt;if(this.shadeMultiplyTexture&&this.shadeMultiplyTexture.isTexture===!0){let i=b.context({getUV:()=>this._animatedUVNode});t=t.mul(i)}return t}_setupShadingShiftNode(){if(this.shadingShiftNode!=null)return p(this.shadingShiftNode);let t=st;if(this.shadingShiftTexture&&this.shadingShiftTexture.isTexture===!0){let i=b.context({getUV:()=>this._animatedUVNode});t=t.add(i.mul(ht))}return t}_setupShadingToonyNode(){return this.shadingToonyNode!=null?p(this.shadingToonyNode):ut}_setupRimLightingMixNode(){return this.rimLightingMixNode!=null?p(this.rimLightingMixNode):mt}_setupRimMultiplyNode(){return this.rimMultiplyNode!=null?d(this.rimMultiplyNode):this.rimMultiplyTexture&&this.rimMultiplyTexture.isTexture===!0?dt.context({getUV:()=>this._animatedUVNode}):d(1)}_setupMatcapNode(){return this.matcapNode!=null?d(this.matcapNode):this.matcapTexture&&this.matcapTexture.isTexture===!0?pt.context({getUV:()=>Wt.mul(1,-1).add(0,1)}).mul(ct):d(0)}_setupParametricRimNode(){let t=this.parametricRimColorNode!=null?d(this.parametricRimColorNode):ft,i=this.parametricRimLiftNode!=null?p(this.parametricRimLiftNode):Nt,e=this.parametricRimFresnelPowerNode!=null?p(this.parametricRimFresnelPowerNode):gt;return qt({parametricRimLift:i,parametricRimFresnelPower:e,parametricRimColor:t})}};export{Et as MToonAnimatedUVNode,wt as MToonLightingModel,Qt as MToonNodeMaterial};
/*!
* @pixiv/three-vrm-materials-mtoon v3.4.1
* MToon (toon material) module for @pixiv/three-vrm
*
* Copyright (c) 2019-2025 pixiv Inc.
* @pixiv/three-vrm-materials-mtoon is distributed under MIT License
* https://github.com/pixiv/three-vrm/blob/release/LICENSE
*/