2026-01-22 11:29:51 +08:00
( function ( ) { "use strict" ; try { if ( typeof document < "u" ) { var e = document . createElement ( "style" ) ; e . appendChild ( document . createTextNode ( ' . bim - engine - wrapper { position : relative ; width : 100 % ; height : 100 % ; font - family : sans - serif ; box - sizing : border - box ; overflow : hidden ; background : linear - gradient ( to bottom , # d6e0eb , # f6faff ) } . bim - engine - opt - btn - container { z - index : 100 } . bim - construct - tree - btn { position : absolute ; top : 20 px ; left : 20 px ! important ; z - index : 100 } . bim - btn - group - root { display : flex ; gap : 8 px ; z - index : 1000 ; position : absolute ; pointer - events : auto } . bim - btn - group - root . static { position : relative ; inset : auto ; transform : none } . bim - btn - group - root . dir - row { flex - direction : row ; align - items : center } . bim - btn - group - root . dir - column { flex - direction : column ; align - items : stretch } . bim - btn - group - section { display : flex ; gap : 4 px ; background - color : var ( -- bim - btn - group - section - bg , rgba ( 17 , 17 , 17 , . 88 ) ) ; border - radius : 6 px ; padding : 4 px ; box - shadow : 0 2 px 8 px # 0000004 d , 0 1 px 3 px # 0003 } . bim - btn - group - root . dir - row . bim - btn - group - section { flex - direction : row ; align - items : center } . bim - btn - group - root . dir - column . bim - btn - group - section { flex - direction : column } . opt - btn - wrapper { position : relative } . opt - btn { display : flex ; cursor : pointer ; border - radius : 4 px ; transition : background - color . 2 s , color . 2 s , border - color . 2 s ; color : var ( -- bim - btn - text - color , # ccc ) ; background - color : var ( -- bim - btn - bg , transparent ) ; padding : 6 px ; align - items : center ; position : relative ; justify - content : center ; border : 1 px solid transparent ; outline : none } . opt - btn : hover { background - color : var ( -- bim - btn - hover - bg , # 444 ) } . opt - btn . active { background - color : var ( -- bim - btn - active - bg , rgba ( 255 , 255 , 255 , . 15 ) ) ; color : var ( -- bim - btn - text - active - color , # fff ) } . opt - btn . disabled { opacity : . 5 ; cursor : not - allowed } . opt - btn - icon { width : var ( -- bim - icon - size , 24 px ) ; height : var ( -- bim - icon - size , 24 px ) ; display : flex ; align - items : center ; justify - content : center ; color : var ( -- bim - icon - color , # ccc ) ; flex - shrink : 0 } . opt - btn - icon svg { width : 100 % ; height : 100 % ; fill : currentColor } . opt - btn - arrow { font - size : 10 px ; opacity : . 6 ; transition : transform . 2 s ; display : inline - block ; margin - left : 4 px } . opt - btn - arrow . rotated { transform : rotate ( 180 deg ) } . opt - btn - text - wrapper { display : flex ; align - items : center ; justify - content : center ; pointer - events : none } . opt - btn - label { display : inline } . opt - btn . no - label . opt - btn - label { display : none } . opt - btn . align - vertical : not ( . no - label ) { flex - direction : column ; text - align : center } . opt - btn . align - vertical : not ( . no - label ) . opt - btn - text - wrapper { margin - top : 4 px } . opt - btn . align - vertical : not ( . no - label ) . opt - btn - label { font - size : 12 px ; line - height : 1.2 } . opt - btn . align - horizontal : not ( . no - label ) { flex - direction : row } . opt - btn . align - horizontal : not ( . no - label ) . opt - btn - text - wrapper { margin - left : 8 px } . opt - btn . align - horizontal : not ( . no - label ) . opt - btn - label { font - size : 14 px } . opt - btn . no - label . opt - btn - text - wrapper { width : 0 ; height : 0 ; margin : 0 ; padding : 0 ; overflow : visible ; position : absolute ; top : 0 ; right : 0 } . opt - btn . no - label . opt - btn - arrow { position : absolute ; top : 2 px ; right : 2 px ; margin : 0 ; font - size : 8 px } . opt - btn - dropdown { position : absolute ; background - color : var ( -- bim - toolbar - bg , rgba ( 17 , 17 , 17 , . 95 ) ) ; border - radius : 4 px ; padding : 4 px ; box - shadow : 0 4 px 12 px # 0003 ; z - index : 1001 ; display : flex ; flex - direction : column ; border : 1 px solid rgba ( 255 , 255 , 255 , . 1 ) ; opacity : 0 ; visibility : hidden ; transform : translateY ( - 10 px ) ; transition : opacity . 2 s ease , transform . 2 s cubic - bezier ( . 2 , 0 , . 2 , 1 ) , visibility . 2 s } @ keyframes dropdown - fade - in { 0 % { opacity : 0 ; transform : translateY ( - 8 px ) scale ( . 98 ) } to { opacity : 1 ; transform : translateY ( 0 ) scale ( 1 ) } } . opt - btn - dropdown { animation : dropdown - fade - in . 2 s cubic - bezier ( . 2 , 0 , . 2 , 1 ) forwards ; opacity : 1 ; visibility : visible ; transform : none } . opt - btn - dropdown - item { display : flex ; align - items : center ; padding : 8 px 12 px ; cursor : pointer ; border - radius : 4 px ; color : var ( -- bim - btn - text - color , # ccc ) ; transition : background . 2 s , border - color . 2 s , color . 2 s ; box - sizing : border - box ; border : 1 px solid transparent ; outline : none } . opt - btn - dropdown - item . opt - btn - icon { color : var ( -- bim - icon - color , # ccc ) } . opt - btn - dropdown - item : hover { background - color : var ( -- bim - btn - hover - bg , # 444 ) } . opt - btn - dropdown - item . active { background - color : var ( -- bim - btn - active - bg , rgba ( 255 , 255 , 255 , . 15 ) ) ; color : var ( -- bim - btn - text - active - color , # fff ) } .
2026-01-22 15:23:57 +08:00
( function ( Gi , ks ) { typeof exports == "object" && typeof module < "u" ? ks ( exports ) : typeof define == "function" && define . amd ? define ( [ "exports" ] , ks ) : ( Gi = typeof globalThis < "u" ? globalThis : Gi || self , ks ( Gi . IflowEngine = { } ) ) } ) ( this , ( function ( Gi ) { "use strict" ; const ks = { common : { title : "BimEngine" , description : "这是一个使用 BIM-ENGINE。" , openTestDialog : "打开测试弹窗" , openInfoDialog : "打开信息弹窗 (封装版)" } , toolbar : { home : "首页" , measure : "测量" , zoomBox : "选框放大" , info : "信息" , location : "定位" , setting : "设置" , walk : "漫游" , map : "地图" , property : "构件详情" , fullscreen : "全屏" , walkMenu : "漫游菜单" , walkPerson : "第一人称" , walkBird : "第三人称" , tree : "模型树" , section : "剖切" , sectionPlane : "拾取面剖切" , sectionAxis : "轴向剖切" , sectionBox : "剖切盒" } , dialog : { testTitle : "测试弹窗" , testContent : '<div style="padding: 10px;">这是一个 <b>可拖拽</b> 且 <b>可缩放</b> 的弹窗。<br><br>你可以尝试拖动标题栏,或者拖动右下角改变大小。</div>' } , menu : { info : "信息" , home : "首页" } , tree : { searchPlaceholder : "请输入要搜索的内容" } , constructTree : { title : "目录树" } , tab : { component : "构件" , system : "系统" , space : "空间" } , panel : { property : { title : "构件详情" , base : "基本属性" , material : "材质信息" , advanced : "高级设置" , tab : { props : "属性" , material : "材质" } } } , measure : { btnName : "测量" , dialogTitle : "测量" , modes : { distance : "距离" , minDistance : "最小距离" , angle : "角度" , elevation : "标高" , volume : "体积" , laserDistance : "激光测距" , slope : "坡度" , spaceVolume : "空间体积" } , actions : { expand : "展开" , collapse : "收起" , clearAll : "删除全部" , settings : "设置" } , labels : { currentMode : "当前测量方式:" , x : "X: " , y : "Y: " , z : "Z: " , value : { distance : "距离:" , minDistance : "最小距离:" , angle : "角度:" , elevation : "标高:" , volume : "体积:" , laserDistance : "激光测距:" , slope : "坡度:" , spaceVolume : "空间体积:" } } , units : { mm : "mm" , cm : "cm" , m : "m" , km : "km" , deg : "°" , m3 : "m³" , percent : "%" } , settings : { title : "设置" , unit : "单位:" , precision : "精度:" , hint : "距离、最小距离和标高默认使用该单位;角度和体积有各自默认单位。" , save : "保存设置" , cancel : "取消" } } , sectionPlane : { dialogTitle : "拾取面剖切" , actions : { hide : "隐藏" , reverse : "反向" , reset : "重置" } } , sectionAxis : { dialogTitle : "轴向剖切" , actions : { hide : "隐藏" , reverse : "反向" , axisX : "X" , axisY : "Y" , axisZ : "Z" } } , sectionBox : { dialogTitle : "剖切盒" , actions : { hide : "隐藏" , reverse : "反向" , fitToModel : "适应" , reset : "重置" } , axes : { x : "X" , y : "Y" , z : "Z" } } , walkControl : { speed : "移动速度:" , gravity : "重力" , collision : "碰撞" , characterModel : { label : "建筑工人" , constructionWorker : "建筑工人" , officeMale : "办公室男性" } , walkMode : { label : "行走模式" , walk : "行走模式" , run : "奔跑模式" } , exit : "退出" , path : { dialogTitle : "路径漫游" } } , map : { dialogTitle : "地图" } } , mf = { common : { title : "BimEngine" , description : "This is a BIM-ENGINE demo." , openTestDialog : "Open Test Dialog" , openInfoDialog : "Open Info Dialog (Wrapped)" } , toolbar : { home : "Home" , measure : "Measure" , zoomBox : "Zoom Box" , info : "Info" , location : "Location" , setting : "Settings" , walk : "Walk" , map : "Map" , property : "Property" , fullscreen : "Fullscreen" , walkPerson : "Person" , walkBird : "Bird Eye" , walkMenu : "Menu" , tree : "Tree" , section : "Section" , sectionPlane : "Plane Section" , sectionAxis : "Axis Section" , sectionBox : "Section Box" } , dialog : { testTitle : "Test Dialog" , testContent : '<div style="padding: 10px;">This is a <b>draggable</b> and <b>resizable</b> dialog.<br><br>Try dragging the title bar or resizing from the bottom-right corner.</div>' } , menu : { info : "Info" , home : "Home" } , tree : { searchPlaceholder : "Please enter content to search" } , constructTree : { title : "Construct Tree" } , tab : { component : "Component" , system : "System" , space : "Space" } , panel : { property : { title : "Component Details" , base : "Basic Info" , material : "Material" , advanced : "Advanced" , tab : { props : "Properties" , material : "Material" } } } , measure : { btnName : "Measure" , dialogTitle : "Measure" , modes : { distance : "Distance" , minDistance : "Min Distance" , angle : "Angle" , elevation : "Elevation" , volume : "Volume" , laserDistance : "Laser Distance" , slope : "Slope" , spaceV
2026-01-22 11:29:51 +08:00
< li > < strong > Name : < / s t r o n g > S a m p l e P r o j e c t < / l i >
< li > < strong > Version : < / s t r o n g > 1 . 0 . 0 < / l i >
< li > < strong > Date : < / s t r o n g > $ { n e w D a t e ( ) . t o L o c a l e D a t e S t r i n g ( ) } < / l i >
< li > < strong > Status : < / s t r o n g > < s p a n s t y l e = " c o l o r : g r e e n ; " > A c t i v e < / s p a n > < / l i >
2026-01-22 15:23:57 +08:00
` ;const r=document.createElement("button");r.textContent="Update Status",r.style.marginTop="10px",r.onclick=()=>{alert("Status updated!")},t.appendChild(n),t.appendChild(i),t.appendChild(r),super({container:e,title:"dialog.testTitle",content:t,width:320,height:"auto",position:"center",resizable:!0,draggable:!0,onClose:()=>{console.log("Info dialog closed")},onOpen:()=>{console.log("Info dialog opened")}})}}class wf extends en{container;activeDialogs=[];constructor(e){super(),this.container=e,this.subscribe("ui:open-dialog",t=>{console.log("[DialogManager] Received open-dialog event:",t),t.id==="info"&&this.showInfoDialog()})}create(e){const t=new Tc({container:this.container,...e,onClose:()=>{this.activeDialogs=this.activeDialogs.filter(n=>n!==t),e.onClose&&e.onClose()}});return t.setTheme(st.getTheme()),this.activeDialogs.push(t),t}showInfoDialog(){new Sf(this.container)}updateTheme(e){this.activeDialogs.forEach(t=>{t.setTheme&&t.setTheme(e)})}destroy(){this.activeDialogs.forEach(e=>e.destroy()),this.activeDialogs=[],super.destroy()}}const Ga="181",Wi={ROTATE:0,DOLLY:1,PAN:2},Xi={ROTATE:0,PAN:1,DOLLY_PAN:2,DOLLY_ROTATE:3},Ef=0,Cc=1,Tf=2,Ac=1,Pc=2,qn=3,Sn=0,Yt=1,Dt=2,Ot=0,ji=1,Wa=2,Rc=3,Lc=4,Dc=5,wn=100,Cf=101,Af=102,Pf=103,Rf=104,Us=200,Lf=201,Df=202,If=203,Xa=204,ja=205,Za=206,Nf=207,qa=208,kf=209,Uf=210,Bf=211,Of=212,Ff=213,zf=214,Ya=0,Ka=1, $ a=2,Zi=3,Ja=4,Qa=5,eo=6,to=7,Sr=0,Hf=1,Vf=2,li=0,Ic=1,Nc=2,kc=3,no=4,Uc=5,Bc=6,Oc=7,Fc="attached",Gf="detached",zc=300,qi=301,Yi=302,io=303,so=304,wr=306,Bn=1e3,On=1001,Er=1002,Gt=1003,Hc=1004,Bs=1005,Wt=1006,Tr=1007,Yn=1008,En=1009,Vc=1010,Gc=1011,Os=1012,ro=1013,vi=1014,Tn=1015,xn=1016,ao=1017,oo=1018,Ki=1020,Wc=35902,Xc=35899,jc=1021,Zc=1022,tn=1023,Fs=1026, $ i=1027,lo=1028,co=1029,ho=1030,uo=1031,fo=1033,Cr=33776,Ar=33777,Pr=33778,Rr=33779,po=35840,mo=35841,go=35842,xo=35843,vo=36196,bo=37492,_o=37496,yo=37808,Mo=37809,So=37810,wo=37811,Eo=37812,To=37813,Co=37814,Ao=37815,Po=37816,Ro=37817,Lo=37818,Do=37819,Io=37820,No=37821,ko=36492,Uo=36494,Bo=36495,Oo=36283,Fo=36284,zo=36285,Ho=36286,zs=2300,Hs=2301,Vo=2302,qc=2400,Yc=2401,Kc=2402,Wf=2500,Xf=0, $ c=1,Go=2,jf=3200,Zf=3201,Vs=0,qf=1,ci="",pt="srgb",Et="srgb-linear",Lr="linear",ot="srgb",Ji=7680,Wo=7681,Xo=34055,jo=34056,Yf=517,Zo=519,Kf=512, $ f=513,Jf=514,Jc=515,Qf=516,ep=517,tp=518,np=519,qo=35044,Qc="300 es",Fn=2e3,Dr=2001;function eh(s){for(let e=s.length-1;e>=0;--e)if(s[e]>=65535)return!0;return!1}function Gs(s){return document.createElementNS("http://www.w3.org/1999/xhtml",s)}function ip(){const s=Gs("canvas");return s.style.display="block",s}const th={};function Ir(...s){const e="THREE."+s.shift();console.log(e,...s)}function ze(...s){const e="THREE."+s.shift();console.warn(e,...s)}function et(...s){const e="THREE."+s.shift();console.error(e,...s)}function Ws(...s){const e=s.join(" ");e in th||(th[e]=!0,ze(...s))}function sp(s,e,t){return new Promise(function(n,i){function r(){switch(s.clientWaitSync(e,s.SYNC_FLUSH_COMMANDS_BIT,0)){case s.WAIT_FAILED:i();break;case s.TIMEOUT_EXPIRED:setTimeout(r,t);break;default:n()}}setTimeout(r,t)})}class bi{addEventListener(e,t){this._listeners===void 0&&(this._listeners={});const n=this._listeners;n[e]===void 0&&(n[e]=[]),n[e].indexOf(t)===-1&&n[e].push(t)}hasEventListener(e,t){const n=this._listeners;return n===void 0?!1:n[e]!==void 0&&n[e].indexOf(t)!==-1}removeEventListener(e,t){const n=this._listeners;if(n===void 0)return;const i=n[e];if(i!==void 0){const r=i.indexOf(t);r!==-1&&i.splice(r,1)}}dispatchEvent(e){const t=this._listeners;if(t===void 0)return;const n=t[e.type];if(n!==void 0){e.target=this;const i=n.slice(0);for(let r=0,a=i.length;r<a;r++)i[r].call(this,e);e.target=null}}}const Xt=["00","01","02","03","04","05","06","07","08","09","0a","0b","0c","0d","0e","0f","10","11","12","13","14","15","16","17","18","19","1a","1b","1c","1d","1e","1f","20","21","22","23","24","25","26","27","28","29","2a","2b","2c","2d","2e","2f","30","31","32","33","34","35","36","37","38","39","3a","3b","3c","3d","3e","3f","40","41","42","43","44","45","46","47","48","49","4a","4b","4c","4d"
2026-01-22 11:29:51 +08:00
gl _Position = projectionMatrix * modelViewMatrix * vec4 ( position , 1.0 ) ;
2026-01-22 15:23:57 +08:00
} ` ,zp= ` void main ( ) {
2026-01-22 11:29:51 +08:00
gl _FragColor = vec4 ( 1.0 , 0.0 , 0.0 , 1.0 ) ;
2026-01-22 15:23:57 +08:00
} ` ;class Rt extends fn{constructor(e){super(),this.isShaderMaterial=!0,this.type="ShaderMaterial",this.defines={},this.uniforms={},this.uniformsGroups=[],this.vertexShader=Fp,this.fragmentShader=zp,this.linewidth=1,this.wireframe=!1,this.wireframeLinewidth=1,this.fog=!1,this.lights=!1,this.clipping=!1,this.forceSinglePass=!0,this.extensions={clipCullDistance:!1,multiDraw:!1},this.defaultAttributeValues={color:[1,1,1],uv:[0,0],uv1:[0,0]},this.index0AttributeName=void 0,this.uniformsNeedUpdate=!1,this.glslVersion=null,e!==void 0&&this.setValues(e)}copy(e){return super.copy(e),this.fragmentShader=e.fragmentShader,this.vertexShader=e.vertexShader,this.uniforms=ds(e.uniforms),this.uniformsGroups=Op(e.uniformsGroups),this.defines=Object.assign({},e.defines),this.wireframe=e.wireframe,this.wireframeLinewidth=e.wireframeLinewidth,this.fog=e.fog,this.lights=e.lights,this.clipping=e.clipping,this.extensions=Object.assign({},e.extensions),this.glslVersion=e.glslVersion,this}toJSON(e){const t=super.toJSON(e);t.glslVersion=this.glslVersion,t.uniforms={};for(const i in this.uniforms){const a=this.uniforms[i].value;a&&a.isTexture?t.uniforms[i]={type:"t",value:a.toJSON(e).uuid}:a&&a.isColor?t.uniforms[i]={type:"c",value:a.getHex()}:a&&a.isVector2?t.uniforms[i]={type:"v2",value:a.toArray()}:a&&a.isVector3?t.uniforms[i]={type:"v3",value:a.toArray()}:a&&a.isVector4?t.uniforms[i]={type:"v4",value:a.toArray()}:a&&a.isMatrix3?t.uniforms[i]={type:"m3",value:a.toArray()}:a&&a.isMatrix4?t.uniforms[i]={type:"m4",value:a.toArray()}:t.uniforms[i]={value:a}}Object.keys(this.defines).length>0&&(t.defines=this.defines),t.vertexShader=this.vertexShader,t.fragmentShader=this.fragmentShader,t.lights=this.lights,t.clipping=this.clipping;const n={};for(const i in this.extensions)this.extensions[i]===!0&&(n[i]=!0);return Object.keys(n).length>0&&(t.extensions=n),t}}class Mh extends _t{constructor(){super(),this.isCamera=!0,this.type="Camera",this.matrixWorldInverse=new Xe,this.projectionMatrix=new Xe,this.projectionMatrixInverse=new Xe,this.coordinateSystem=Fn,this._reversedDepth=!1}get reversedDepth(){return this._reversedDepth}copy(e,t){return super.copy(e,t),this.matrixWorldInverse.copy(e.matrixWorldInverse),this.projectionMatrix.copy(e.projectionMatrix),this.projectionMatrixInverse.copy(e.projectionMatrixInverse),this.coordinateSystem=e.coordinateSystem,this}getWorldDirection(e){return super.getWorldDirection(e).negate()}updateMatrixWorld(e){super.updateMatrixWorld(e),this.matrixWorldInverse.copy(this.matrixWorld).invert()}updateWorldMatrix(e,t){super.updateWorldMatrix(e,t),this.matrixWorldInverse.copy(this.matrixWorld).invert()}clone(){return new this.constructor().copy(this)}}const mi=new P,Sh=new ue,wh=new ue;class Zt extends Mh{constructor(e=50,t=1,n=.1,i=2e3){super(),this.isPerspectiveCamera=!0,this.type="PerspectiveCamera",this.fov=e,this.zoom=1,this.near=n,this.far=i,this.focus=10,this.aspect=t,this.view=null,this.filmGauge=35,this.filmOffset=0,this.updateProjectionMatrix()}copy(e,t){return super.copy(e,t),this.fov=e.fov,this.zoom=e.zoom,this.near=e.near,this.far=e.far,this.focus=e.focus,this.aspect=e.aspect,this.view=e.view===null?null:Object.assign({},e.view),this.filmGauge=e.filmGauge,this.filmOffset=e.filmOffset,this}setFocalLength(e){const t=.5*this.getFilmHeight()/e;this.fov=Qi*2*Math.atan(t),this.updateProjectionMatrix()}getFocalLength(){const e=Math.tan(Xs*.5*this.fov);return .5*this.getFilmHeight()/e}getEffectiveFOV(){return Qi*2*Math.atan(Math.tan(Xs*.5*this.fov)/this.zoom)}getFilmWidth(){return this.filmGauge*Math.min(this.aspect,1)}getFilmHeight(){return this.filmGauge/Math.max(this.aspect,1)}getViewBounds(e,t,n){mi.set(-1,-1,.5).applyMatrix4(this.projectionMatrixInverse),t.set(mi.x,mi.y).multiplyScalar(-e/mi.z),mi.set(1,1,.5).applyMatrix4(this.projectionMatrixInverse),n.set(mi.x,mi.y).multiplyScalar(-e/mi.z)}getViewSize(e,t){return this.getViewBounds(e,Sh,wh),t.subVectors(wh,Sh)}setViewOffset(e,t,n,i,r,a){this.aspect=e/t,this.view===null&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1}),this.vie
2026-01-22 11:29:51 +08:00
varying vec3 vWorldDirection ;
vec3 transformDirection ( in vec3 dir , in mat4 matrix ) {
return normalize ( ( matrix * vec4 ( dir , 0.0 ) ) . xyz ) ;
}
void main ( ) {
vWorldDirection = transformDirection ( position , modelMatrix ) ;
# include < begin _vertex >
# include < project _vertex >
}
` ,fragmentShader: `
uniform sampler2D tEquirect ;
varying vec3 vWorldDirection ;
# include < common >
void main ( ) {
vec3 direction = normalize ( vWorldDirection ) ;
vec2 sampleUV = equirectUv ( direction ) ;
gl _FragColor = texture2D ( tEquirect , sampleUV ) ;
}
2026-01-22 15:23:57 +08:00
` },i=new Si(5,5,5),r=new Rt({name:"CubemapFromEquirect",uniforms:ds(n.uniforms),vertexShader:n.vertexShader,fragmentShader:n.fragmentShader,side:Yt,blending:Ot});r.uniforms.tEquirect.value=t;const a=new ht(i,r),o=t.minFilter;return t.minFilter===Yn&&(t.minFilter=Wt),new Hp(1,10,this).update(e,a),t.minFilter=o,a.geometry.dispose(),a.material.dispose(),this}clear(e,t=!0,n=!0,i=!0){const r=e.getRenderTarget();for(let a=0;a<6;a++)e.setRenderTarget(this,a),e.clear(t,n,i);e.setRenderTarget(r)}}class $ t extends _t{constructor(){super(),this.isGroup=!0,this.type="Group"}}const Gp={type:"move"};class vl{constructor(){this._targetRay=null,this._grip=null,this._hand=null}getHandSpace(){return this._hand===null&&(this._hand=new $ t,this._hand.matrixAutoUpdate=!1,this._hand.visible=!1,this._hand.joints={},this._hand.inputState={pinching:!1}),this._hand}getTargetRaySpace(){return this._targetRay===null&&(this._targetRay=new $ t,this._targetRay.matrixAutoUpdate=!1,this._targetRay.visible=!1,this._targetRay.hasLinearVelocity=!1,this._targetRay.linearVelocity=new P,this._targetRay.hasAngularVelocity=!1,this._targetRay.angularVelocity=new P),this._targetRay}getGripSpace(){return this._grip===null&&(this._grip=new $ t,this._grip.matrixAutoUpdate=!1,this._grip.visible=!1,this._grip.hasLinearVelocity=!1,this._grip.linearVelocity=new P,this._grip.hasAngularVelocity=!1,this._grip.angularVelocity=new P),this._grip}dispatchEvent(e){return this._targetRay!==null&&this._targetRay.dispatchEvent(e),this._grip!==null&&this._grip.dispatchEvent(e),this._hand!==null&&this._hand.dispatchEvent(e),this}connect(e){if(e&&e.hand){const t=this._hand;if(t)for(const n of e.hand.values())this._getHandJoint(t,n)}return this.dispatchEvent({type:"connected",data:e}),this}disconnect(e){return this.dispatchEvent({type:"disconnected",data:e}),this._targetRay!==null&&(this._targetRay.visible=!1),this._grip!==null&&(this._grip.visible=!1),this._hand!==null&&(this._hand.visible=!1),this}update(e,t,n){let i=null,r=null,a=null;const o=this._targetRay,l=this._grip,c=this._hand;if(e&&t.session.visibilityState!=="visible-blurred"){if(c&&e.hand){a=!0;for(const g of e.hand.values()){const x=t.getJointPose(g,n),m=this._getHandJoint(c,g);x!==null&&(m.matrix.fromArray(x.transform.matrix),m.matrix.decompose(m.position,m.rotation,m.scale),m.matrixWorldNeedsUpdate=!0,m.jointRadius=x.radius),m.visible=x!==null}const h=c.joints["index-finger-tip"],u=c.joints["thumb-tip"],f=h.position.distanceTo(u.position),d=.02,p=.005;c.inputState.pinching&&f>d+p?(c.inputState.pinching=!1,this.dispatchEvent({type:"pinchend",handedness:e.handedness,target:this})):!c.inputState.pinching&&f<=d-p&&(c.inputState.pinching=!0,this.dispatchEvent({type:"pinchstart",handedness:e.handedness,target:this}))}else l!==null&&e.gripSpace&&(r=t.getPose(e.gripSpace,n),r!==null&&(l.matrix.fromArray(r.transform.matrix),l.matrix.decompose(l.position,l.rotation,l.scale),l.matrixWorldNeedsUpdate=!0,r.linearVelocity?(l.hasLinearVelocity=!0,l.linearVelocity.copy(r.linearVelocity)):l.hasLinearVelocity=!1,r.angularVelocity?(l.hasAngularVelocity=!0,l.angularVelocity.copy(r.angularVelocity)):l.hasAngularVelocity=!1));o!==null&&(i=t.getPose(e.targetRaySpace,n),i===null&&r!==null&&(i=r),i!==null&&(o.matrix.fromArray(i.transform.matrix),o.matrix.decompose(o.position,o.rotation,o.scale),o.matrixWorldNeedsUpdate=!0,i.linearVelocity?(o.hasLinearVelocity=!0,o.linearVelocity.copy(i.linearVelocity)):o.hasLinearVelocity=!1,i.angularVelocity?(o.hasAngularVelocity=!0,o.angularVelocity.copy(i.angularVelocity)):o.hasAngularVelocity=!1,this.dispatchEvent(Gp)))}return o!==null&&(o.visible=i!==null),l!==null&&(l.visible=r!==null),c!==null&&(c.visible=a!==null),this}_getHandJoint(e,t){if(e.joints[t.jointName]===void 0){const n=new $ t;n.matrixAutoUpdate=!1,n.visible=!1,e.joints[t.jointName]=n,e.add(n)}return e.joints[t.jointName]}}class Th extends _t{constructor(){super(),this.isScene=!0,this.type="Scene",this.background=null,this.environment=null,this.fog=null,this.backgroundBlurriness=0,this.backgroundIntensity=1,this.backgroundRotation=new sn,thi
2026-01-22 11:29:51 +08:00
if ( diffuseColor . a < getAlphaHashThreshold ( vPosition ) ) discard ;
2026-01-22 15:23:57 +08:00
# endif ` ,x0= ` # ifdef USE _ALPHAHASH
2026-01-22 11:29:51 +08:00
const float ALPHA _HASH _SCALE = 0.05 ;
float hash2D ( vec2 value ) {
return fract ( 1.0 e4 * sin ( 17.0 * value . x + 0.1 * value . y ) * ( 0.1 + abs ( sin ( 13.0 * value . y + value . x ) ) ) ) ;
}
float hash3D ( vec3 value ) {
return hash2D ( vec2 ( hash2D ( value . xy ) , value . z ) ) ;
}
float getAlphaHashThreshold ( vec3 position ) {
float maxDeriv = max (
length ( dFdx ( position . xyz ) ) ,
length ( dFdy ( position . xyz ) )
) ;
float pixScale = 1.0 / ( ALPHA _HASH _SCALE * maxDeriv ) ;
vec2 pixScales = vec2 (
exp2 ( floor ( log2 ( pixScale ) ) ) ,
exp2 ( ceil ( log2 ( pixScale ) ) )
) ;
vec2 alpha = vec2 (
hash3D ( floor ( pixScales . x * position . xyz ) ) ,
hash3D ( floor ( pixScales . y * position . xyz ) )
) ;
float lerpFactor = fract ( log2 ( pixScale ) ) ;
float x = ( 1.0 - lerpFactor ) * alpha . x + lerpFactor * alpha . y ;
float a = min ( lerpFactor , 1.0 - lerpFactor ) ;
vec3 cases = vec3 (
x * x / ( 2.0 * a * ( 1.0 - a ) ) ,
( x - 0.5 * a ) / ( 1.0 - a ) ,
1.0 - ( ( 1.0 - x ) * ( 1.0 - x ) / ( 2.0 * a * ( 1.0 - a ) ) )
) ;
float threshold = ( x < ( 1.0 - a ) )
? ( ( x < a ) ? cases . x : cases . y )
: cases . z ;
return clamp ( threshold , 1.0 e - 6 , 1.0 ) ;
}
2026-01-22 15:23:57 +08:00
# endif ` ,v0= ` # ifdef USE _ALPHAMAP
2026-01-22 11:29:51 +08:00
diffuseColor . a *= texture2D ( alphaMap , vAlphaMapUv ) . g ;
2026-01-22 15:23:57 +08:00
# endif ` ,b0= ` # ifdef USE _ALPHAMAP
2026-01-22 11:29:51 +08:00
uniform sampler2D alphaMap ;
2026-01-22 15:23:57 +08:00
# endif ` ,_0= ` # ifdef USE _ALPHATEST
2026-01-22 11:29:51 +08:00
# ifdef ALPHA _TO _COVERAGE
diffuseColor . a = smoothstep ( alphaTest , alphaTest + fwidth ( diffuseColor . a ) , diffuseColor . a ) ;
if ( diffuseColor . a == 0.0 ) discard ;
# else
if ( diffuseColor . a < alphaTest ) discard ;
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,y0= ` # ifdef USE _ALPHATEST
2026-01-22 11:29:51 +08:00
uniform float alphaTest ;
2026-01-22 15:23:57 +08:00
# endif ` ,M0= ` # ifdef USE _AOMAP
2026-01-22 11:29:51 +08:00
float ambientOcclusion = ( texture2D ( aoMap , vAoMapUv ) . r - 1.0 ) * aoMapIntensity + 1.0 ;
reflectedLight . indirectDiffuse *= ambientOcclusion ;
# if defined ( USE _CLEARCOAT )
clearcoatSpecularIndirect *= ambientOcclusion ;
# endif
# if defined ( USE _SHEEN )
sheenSpecularIndirect *= ambientOcclusion ;
# endif
# if defined ( USE _ENVMAP ) && defined ( STANDARD )
float dotNV = saturate ( dot ( geometryNormal , geometryViewDir ) ) ;
reflectedLight . indirectSpecular *= computeSpecularOcclusion ( dotNV , ambientOcclusion , material . roughness ) ;
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,S0= ` # ifdef USE _AOMAP
2026-01-22 11:29:51 +08:00
uniform sampler2D aoMap ;
uniform float aoMapIntensity ;
2026-01-22 15:23:57 +08:00
# endif ` ,w0= ` # ifdef USE _BATCHING
2026-01-22 11:29:51 +08:00
# if ! defined ( GL _ANGLE _multi _draw )
# define gl _DrawID _gl _DrawID
uniform int _gl _DrawID ;
# endif
uniform highp sampler2D batchingTexture ;
uniform highp usampler2D batchingIdTexture ;
mat4 getBatchingMatrix ( const in float i ) {
int size = textureSize ( batchingTexture , 0 ) . x ;
int j = int ( i ) * 4 ;
int x = j % size ;
int y = j / size ;
vec4 v1 = texelFetch ( batchingTexture , ivec2 ( x , y ) , 0 ) ;
vec4 v2 = texelFetch ( batchingTexture , ivec2 ( x + 1 , y ) , 0 ) ;
vec4 v3 = texelFetch ( batchingTexture , ivec2 ( x + 2 , y ) , 0 ) ;
vec4 v4 = texelFetch ( batchingTexture , ivec2 ( x + 3 , y ) , 0 ) ;
return mat4 ( v1 , v2 , v3 , v4 ) ;
}
float getIndirectIndex ( const in int i ) {
int size = textureSize ( batchingIdTexture , 0 ) . x ;
int x = i % size ;
int y = i / size ;
return float ( texelFetch ( batchingIdTexture , ivec2 ( x , y ) , 0 ) . r ) ;
}
# endif
# ifdef USE _BATCHING _COLOR
uniform sampler2D batchingColorTexture ;
vec3 getBatchingColor ( const in float i ) {
int size = textureSize ( batchingColorTexture , 0 ) . x ;
int j = int ( i ) ;
int x = j % size ;
int y = j / size ;
return texelFetch ( batchingColorTexture , ivec2 ( x , y ) , 0 ) . rgb ;
}
2026-01-22 15:23:57 +08:00
# endif ` ,E0= ` # ifdef USE _BATCHING
2026-01-22 11:29:51 +08:00
mat4 batchingMatrix = getBatchingMatrix ( getIndirectIndex ( gl _DrawID ) ) ;
2026-01-22 15:23:57 +08:00
# endif ` ,T0= ` vec3 transformed = vec3 ( position ) ;
2026-01-22 11:29:51 +08:00
# ifdef USE _ALPHAHASH
vPosition = vec3 ( position ) ;
2026-01-22 15:23:57 +08:00
# endif ` ,C0= ` vec3 objectNormal = vec3 ( normal ) ;
2026-01-22 11:29:51 +08:00
# ifdef USE _TANGENT
vec3 objectTangent = vec3 ( tangent . xyz ) ;
2026-01-22 15:23:57 +08:00
# endif ` ,A0= ` float G _BlinnPhong _Implicit ( ) {
2026-01-22 11:29:51 +08:00
return 0.25 ;
}
float D _BlinnPhong ( const in float shininess , const in float dotNH ) {
return RECIPROCAL _PI * ( shininess * 0.5 + 1.0 ) * pow ( dotNH , shininess ) ;
}
vec3 BRDF _BlinnPhong ( const in vec3 lightDir , const in vec3 viewDir , const in vec3 normal , const in vec3 specularColor , const in float shininess ) {
vec3 halfDir = normalize ( lightDir + viewDir ) ;
float dotNH = saturate ( dot ( normal , halfDir ) ) ;
float dotVH = saturate ( dot ( viewDir , halfDir ) ) ;
vec3 F = F _Schlick ( specularColor , 1.0 , dotVH ) ;
float G = G _BlinnPhong _Implicit ( ) ;
float D = D _BlinnPhong ( shininess , dotNH ) ;
return F * ( G * D ) ;
2026-01-22 15:23:57 +08:00
} // validated`,P0=`#ifdef USE_IRIDESCENCE
2026-01-22 11:29:51 +08:00
const mat3 XYZ _TO _REC709 = mat3 (
3.2404542 , - 0.9692660 , 0.0556434 ,
- 1.5371385 , 1.8760108 , - 0.2040259 ,
- 0.4985314 , 0.0415560 , 1.0572252
) ;
vec3 Fresnel0ToIor ( vec3 fresnel0 ) {
vec3 sqrtF0 = sqrt ( fresnel0 ) ;
return ( vec3 ( 1.0 ) + sqrtF0 ) / ( vec3 ( 1.0 ) - sqrtF0 ) ;
}
vec3 IorToFresnel0 ( vec3 transmittedIor , float incidentIor ) {
return pow2 ( ( transmittedIor - vec3 ( incidentIor ) ) / ( transmittedIor + vec3 ( incidentIor ) ) ) ;
}
float IorToFresnel0 ( float transmittedIor , float incidentIor ) {
return pow2 ( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ) ) ;
}
vec3 evalSensitivity ( float OPD , vec3 shift ) {
float phase = 2.0 * PI * OPD * 1.0 e - 9 ;
vec3 val = vec3 ( 5.4856 e - 13 , 4.4201 e - 13 , 5.2481 e - 13 ) ;
vec3 pos = vec3 ( 1.6810 e + 06 , 1.7953 e + 06 , 2.2084 e + 06 ) ;
vec3 var = vec3 ( 4.3278 e + 09 , 9.3046 e + 09 , 6.6121 e + 09 ) ;
vec3 xyz = val * sqrt ( 2.0 * PI * var ) * cos ( pos * phase + shift ) * exp ( - pow2 ( phase ) * var ) ;
xyz . x += 9.7470 e - 14 * sqrt ( 2.0 * PI * 4.5282 e + 09 ) * cos ( 2.2399 e + 06 * phase + shift [ 0 ] ) * exp ( - 4.5282 e + 09 * pow2 ( phase ) ) ;
xyz /= 1.0685 e - 7 ;
vec3 rgb = XYZ _TO _REC709 * xyz ;
return rgb ;
}
vec3 evalIridescence ( float outsideIOR , float eta2 , float cosTheta1 , float thinFilmThickness , vec3 baseF0 ) {
vec3 I ;
float iridescenceIOR = mix ( outsideIOR , eta2 , smoothstep ( 0.0 , 0.03 , thinFilmThickness ) ) ;
float sinTheta2Sq = pow2 ( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2 ( cosTheta1 ) ) ;
float cosTheta2Sq = 1.0 - sinTheta2Sq ;
if ( cosTheta2Sq < 0.0 ) {
return vec3 ( 1.0 ) ;
}
float cosTheta2 = sqrt ( cosTheta2Sq ) ;
float R0 = IorToFresnel0 ( iridescenceIOR , outsideIOR ) ;
float R12 = F _Schlick ( R0 , 1.0 , cosTheta1 ) ;
float T121 = 1.0 - R12 ;
float phi12 = 0.0 ;
if ( iridescenceIOR < outsideIOR ) phi12 = PI ;
float phi21 = PI - phi12 ;
vec3 baseIOR = Fresnel0ToIor ( clamp ( baseF0 , 0.0 , 0.9999 ) ) ; vec3 R1 = IorToFresnel0 ( baseIOR , iridescenceIOR ) ;
vec3 R23 = F _Schlick ( R1 , 1.0 , cosTheta2 ) ;
vec3 phi23 = vec3 ( 0.0 ) ;
if ( baseIOR [ 0 ] < iridescenceIOR ) phi23 [ 0 ] = PI ;
if ( baseIOR [ 1 ] < iridescenceIOR ) phi23 [ 1 ] = PI ;
if ( baseIOR [ 2 ] < iridescenceIOR ) phi23 [ 2 ] = PI ;
float OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2 ;
vec3 phi = vec3 ( phi21 ) + phi23 ;
vec3 R123 = clamp ( R12 * R23 , 1e-5 , 0.9999 ) ;
vec3 r123 = sqrt ( R123 ) ;
vec3 Rs = pow2 ( T121 ) * R23 / ( vec3 ( 1.0 ) - R123 ) ;
vec3 C0 = R12 + Rs ;
I = C0 ;
vec3 Cm = Rs - T121 ;
for ( int m = 1 ; m <= 2 ; ++ m ) {
Cm *= r123 ;
vec3 Sm = 2.0 * evalSensitivity ( float ( m ) * OPD , float ( m ) * phi ) ;
I += Cm * Sm ;
}
return max ( I , vec3 ( 0.0 ) ) ;
}
2026-01-22 15:23:57 +08:00
# endif ` ,R0= ` # ifdef USE _BUMPMAP
2026-01-22 11:29:51 +08:00
uniform sampler2D bumpMap ;
uniform float bumpScale ;
vec2 dHdxy _fwd ( ) {
vec2 dSTdx = dFdx ( vBumpMapUv ) ;
vec2 dSTdy = dFdy ( vBumpMapUv ) ;
float Hll = bumpScale * texture2D ( bumpMap , vBumpMapUv ) . x ;
float dBx = bumpScale * texture2D ( bumpMap , vBumpMapUv + dSTdx ) . x - Hll ;
float dBy = bumpScale * texture2D ( bumpMap , vBumpMapUv + dSTdy ) . x - Hll ;
return vec2 ( dBx , dBy ) ;
}
vec3 perturbNormalArb ( vec3 surf _pos , vec3 surf _norm , vec2 dHdxy , float faceDirection ) {
vec3 vSigmaX = normalize ( dFdx ( surf _pos . xyz ) ) ;
vec3 vSigmaY = normalize ( dFdy ( surf _pos . xyz ) ) ;
vec3 vN = surf _norm ;
vec3 R1 = cross ( vSigmaY , vN ) ;
vec3 R2 = cross ( vN , vSigmaX ) ;
float fDet = dot ( vSigmaX , R1 ) * faceDirection ;
vec3 vGrad = sign ( fDet ) * ( dHdxy . x * R1 + dHdxy . y * R2 ) ;
return normalize ( abs ( fDet ) * surf _norm - vGrad ) ;
}
2026-01-22 15:23:57 +08:00
# endif ` ,L0= ` # if NUM _CLIPPING _PLANES > 0
2026-01-22 11:29:51 +08:00
vec4 plane ;
# ifdef ALPHA _TO _COVERAGE
float distanceToPlane , distanceGradient ;
float clipOpacity = 1.0 ;
# pragma unroll _loop _start
for ( int i = 0 ; i < UNION _CLIPPING _PLANES ; i ++ ) {
plane = clippingPlanes [ i ] ;
distanceToPlane = - dot ( vClipPosition , plane . xyz ) + plane . w ;
distanceGradient = fwidth ( distanceToPlane ) / 2.0 ;
clipOpacity *= smoothstep ( - distanceGradient , distanceGradient , distanceToPlane ) ;
if ( clipOpacity == 0.0 ) discard ;
}
# pragma unroll _loop _end
# if UNION _CLIPPING _PLANES < NUM _CLIPPING _PLANES
float unionClipOpacity = 1.0 ;
# pragma unroll _loop _start
for ( int i = UNION _CLIPPING _PLANES ; i < NUM _CLIPPING _PLANES ; i ++ ) {
plane = clippingPlanes [ i ] ;
distanceToPlane = - dot ( vClipPosition , plane . xyz ) + plane . w ;
distanceGradient = fwidth ( distanceToPlane ) / 2.0 ;
unionClipOpacity *= 1.0 - smoothstep ( - distanceGradient , distanceGradient , distanceToPlane ) ;
}
# pragma unroll _loop _end
clipOpacity *= 1.0 - unionClipOpacity ;
# endif
diffuseColor . a *= clipOpacity ;
if ( diffuseColor . a == 0.0 ) discard ;
# else
# pragma unroll _loop _start
for ( int i = 0 ; i < UNION _CLIPPING _PLANES ; i ++ ) {
plane = clippingPlanes [ i ] ;
if ( dot ( vClipPosition , plane . xyz ) > plane . w ) discard ;
}
# pragma unroll _loop _end
# if UNION _CLIPPING _PLANES < NUM _CLIPPING _PLANES
bool clipped = true ;
# pragma unroll _loop _start
for ( int i = UNION _CLIPPING _PLANES ; i < NUM _CLIPPING _PLANES ; i ++ ) {
plane = clippingPlanes [ i ] ;
clipped = ( dot ( vClipPosition , plane . xyz ) > plane . w ) && clipped ;
}
# pragma unroll _loop _end
if ( clipped ) discard ;
# endif
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,D0= ` # if NUM _CLIPPING _PLANES > 0
2026-01-22 11:29:51 +08:00
varying vec3 vClipPosition ;
uniform vec4 clippingPlanes [ NUM _CLIPPING _PLANES ] ;
2026-01-22 15:23:57 +08:00
# endif ` ,I0= ` # if NUM _CLIPPING _PLANES > 0
2026-01-22 11:29:51 +08:00
varying vec3 vClipPosition ;
2026-01-22 15:23:57 +08:00
# endif ` ,N0= ` # if NUM _CLIPPING _PLANES > 0
2026-01-22 11:29:51 +08:00
vClipPosition = - mvPosition . xyz ;
2026-01-22 15:23:57 +08:00
# endif ` ,k0= ` # if defined ( USE _COLOR _ALPHA )
2026-01-22 11:29:51 +08:00
diffuseColor *= vColor ;
# elif defined ( USE _COLOR )
diffuseColor . rgb *= vColor ;
2026-01-22 15:23:57 +08:00
# endif ` ,U0= ` # if defined ( USE _COLOR _ALPHA )
2026-01-22 11:29:51 +08:00
varying vec4 vColor ;
# elif defined ( USE _COLOR )
varying vec3 vColor ;
2026-01-22 15:23:57 +08:00
# endif ` ,B0= ` # if defined ( USE _COLOR _ALPHA )
2026-01-22 11:29:51 +08:00
varying vec4 vColor ;
# elif defined ( USE _COLOR ) || defined ( USE _INSTANCING _COLOR ) || defined ( USE _BATCHING _COLOR )
varying vec3 vColor ;
2026-01-22 15:23:57 +08:00
# endif ` ,O0= ` # if defined ( USE _COLOR _ALPHA )
2026-01-22 11:29:51 +08:00
vColor = vec4 ( 1.0 ) ;
# elif defined ( USE _COLOR ) || defined ( USE _INSTANCING _COLOR ) || defined ( USE _BATCHING _COLOR )
vColor = vec3 ( 1.0 ) ;
# endif
# ifdef USE _COLOR
vColor *= color ;
# endif
# ifdef USE _INSTANCING _COLOR
vColor . xyz *= instanceColor . xyz ;
# endif
# ifdef USE _BATCHING _COLOR
vec3 batchingColor = getBatchingColor ( getIndirectIndex ( gl _DrawID ) ) ;
vColor . xyz *= batchingColor . xyz ;
2026-01-22 15:23:57 +08:00
# endif ` ,F0= ` # define PI 3.141592653589793
2026-01-22 11:29:51 +08:00
# define PI2 6.283185307179586
# define PI _HALF 1.5707963267948966
# define RECIPROCAL _PI 0.3183098861837907
# define RECIPROCAL _PI2 0.15915494309189535
# define EPSILON 1e-6
# ifndef saturate
# define saturate ( a ) clamp ( a , 0.0 , 1.0 )
# endif
# define whiteComplement ( a ) ( 1.0 - saturate ( a ) )
float pow2 ( const in float x ) { return x * x ; }
vec3 pow2 ( const in vec3 x ) { return x * x ; }
float pow3 ( const in float x ) { return x * x * x ; }
float pow4 ( const in float x ) { float x2 = x * x ; return x2 * x2 ; }
float max3 ( const in vec3 v ) { return max ( max ( v . x , v . y ) , v . z ) ; }
float average ( const in vec3 v ) { return dot ( v , vec3 ( 0.3333333 ) ) ; }
highp float rand ( const in vec2 uv ) {
const highp float a = 12.9898 , b = 78.233 , c = 43758.5453 ;
highp float dt = dot ( uv . xy , vec2 ( a , b ) ) , sn = mod ( dt , PI ) ;
return fract ( sin ( sn ) * c ) ;
}
# ifdef HIGH _PRECISION
float precisionSafeLength ( vec3 v ) { return length ( v ) ; }
# else
float precisionSafeLength ( vec3 v ) {
float maxComponent = max3 ( abs ( v ) ) ;
return length ( v / maxComponent ) * maxComponent ;
}
# endif
struct IncidentLight {
vec3 color ;
vec3 direction ;
bool visible ;
} ;
struct ReflectedLight {
vec3 directDiffuse ;
vec3 directSpecular ;
vec3 indirectDiffuse ;
vec3 indirectSpecular ;
} ;
# ifdef USE _ALPHAHASH
varying vec3 vPosition ;
# endif
vec3 transformDirection ( in vec3 dir , in mat4 matrix ) {
return normalize ( ( matrix * vec4 ( dir , 0.0 ) ) . xyz ) ;
}
vec3 inverseTransformDirection ( in vec3 dir , in mat4 matrix ) {
return normalize ( ( vec4 ( dir , 0.0 ) * matrix ) . xyz ) ;
}
bool isPerspectiveMatrix ( mat4 m ) {
return m [ 2 ] [ 3 ] == - 1.0 ;
}
vec2 equirectUv ( in vec3 dir ) {
float u = atan ( dir . z , dir . x ) * RECIPROCAL _PI2 + 0.5 ;
float v = asin ( clamp ( dir . y , - 1.0 , 1.0 ) ) * RECIPROCAL _PI + 0.5 ;
return vec2 ( u , v ) ;
}
vec3 BRDF _Lambert ( const in vec3 diffuseColor ) {
return RECIPROCAL _PI * diffuseColor ;
}
vec3 F _Schlick ( const in vec3 f0 , const in float f90 , const in float dotVH ) {
float fresnel = exp2 ( ( - 5.55473 * dotVH - 6.98316 ) * dotVH ) ;
return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel ) ;
}
float F _Schlick ( const in float f0 , const in float f90 , const in float dotVH ) {
float fresnel = exp2 ( ( - 5.55473 * dotVH - 6.98316 ) * dotVH ) ;
return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel ) ;
2026-01-22 15:23:57 +08:00
} // validated`,z0=`#ifdef ENVMAP_TYPE_CUBE_UV
2026-01-22 11:29:51 +08:00
# define cubeUV _minMipLevel 4.0
# define cubeUV _minTileSize 16.0
float getFace ( vec3 direction ) {
vec3 absDirection = abs ( direction ) ;
float face = - 1.0 ;
if ( absDirection . x > absDirection . z ) {
if ( absDirection . x > absDirection . y )
face = direction . x > 0.0 ? 0.0 : 3.0 ;
else
face = direction . y > 0.0 ? 1.0 : 4.0 ;
} else {
if ( absDirection . z > absDirection . y )
face = direction . z > 0.0 ? 2.0 : 5.0 ;
else
face = direction . y > 0.0 ? 1.0 : 4.0 ;
}
return face ;
}
vec2 getUV ( vec3 direction , float face ) {
vec2 uv ;
if ( face == 0.0 ) {
uv = vec2 ( direction . z , direction . y ) / abs ( direction . x ) ;
} else if ( face == 1.0 ) {
uv = vec2 ( - direction . x , - direction . z ) / abs ( direction . y ) ;
} else if ( face == 2.0 ) {
uv = vec2 ( - direction . x , direction . y ) / abs ( direction . z ) ;
} else if ( face == 3.0 ) {
uv = vec2 ( - direction . z , direction . y ) / abs ( direction . x ) ;
} else if ( face == 4.0 ) {
uv = vec2 ( - direction . x , direction . z ) / abs ( direction . y ) ;
} else {
uv = vec2 ( direction . x , direction . y ) / abs ( direction . z ) ;
}
return 0.5 * ( uv + 1.0 ) ;
}
vec3 bilinearCubeUV ( sampler2D envMap , vec3 direction , float mipInt ) {
float face = getFace ( direction ) ;
float filterInt = max ( cubeUV _minMipLevel - mipInt , 0.0 ) ;
mipInt = max ( mipInt , cubeUV _minMipLevel ) ;
float faceSize = exp2 ( mipInt ) ;
highp vec2 uv = getUV ( direction , face ) * ( faceSize - 2.0 ) + 1.0 ;
if ( face > 2.0 ) {
uv . y += faceSize ;
face -= 3.0 ;
}
uv . x += face * faceSize ;
uv . x += filterInt * 3.0 * cubeUV _minTileSize ;
uv . y += 4.0 * ( exp2 ( CUBEUV _MAX _MIP ) - faceSize ) ;
uv . x *= CUBEUV _TEXEL _WIDTH ;
uv . y *= CUBEUV _TEXEL _HEIGHT ;
# ifdef texture2DGradEXT
return texture2DGradEXT ( envMap , uv , vec2 ( 0.0 ) , vec2 ( 0.0 ) ) . rgb ;
# else
return texture2D ( envMap , uv ) . rgb ;
# endif
}
# define cubeUV _r0 1.0
# define cubeUV _m0 - 2.0
# define cubeUV _r1 0.8
# define cubeUV _m1 - 1.0
# define cubeUV _r4 0.4
# define cubeUV _m4 2.0
# define cubeUV _r5 0.305
# define cubeUV _m5 3.0
# define cubeUV _r6 0.21
# define cubeUV _m6 4.0
float roughnessToMip ( float roughness ) {
float mip = 0.0 ;
if ( roughness >= cubeUV _r1 ) {
mip = ( cubeUV _r0 - roughness ) * ( cubeUV _m1 - cubeUV _m0 ) / ( cubeUV _r0 - cubeUV _r1 ) + cubeUV _m0 ;
} else if ( roughness >= cubeUV _r4 ) {
mip = ( cubeUV _r1 - roughness ) * ( cubeUV _m4 - cubeUV _m1 ) / ( cubeUV _r1 - cubeUV _r4 ) + cubeUV _m1 ;
} else if ( roughness >= cubeUV _r5 ) {
mip = ( cubeUV _r4 - roughness ) * ( cubeUV _m5 - cubeUV _m4 ) / ( cubeUV _r4 - cubeUV _r5 ) + cubeUV _m4 ;
} else if ( roughness >= cubeUV _r6 ) {
mip = ( cubeUV _r5 - roughness ) * ( cubeUV _m6 - cubeUV _m5 ) / ( cubeUV _r5 - cubeUV _r6 ) + cubeUV _m5 ;
} else {
mip = - 2.0 * log2 ( 1.16 * roughness ) ; }
return mip ;
}
vec4 textureCubeUV ( sampler2D envMap , vec3 sampleDir , float roughness ) {
float mip = clamp ( roughnessToMip ( roughness ) , cubeUV _m0 , CUBEUV _MAX _MIP ) ;
float mipF = fract ( mip ) ;
float mipInt = floor ( mip ) ;
vec3 color0 = bilinearCubeUV ( envMap , sampleDir , mipInt ) ;
if ( mipF == 0.0 ) {
return vec4 ( color0 , 1.0 ) ;
} else {
vec3 color1 = bilinearCubeUV ( envMap , sampleDir , mipInt + 1.0 ) ;
return vec4 ( mix ( color0 , color1 , mipF ) , 1.0 ) ;
}
}
2026-01-22 15:23:57 +08:00
# endif ` ,H0= ` vec3 transformedNormal = objectNormal ;
2026-01-22 11:29:51 +08:00
# ifdef USE _TANGENT
vec3 transformedTangent = objectTangent ;
# endif
# ifdef USE _BATCHING
mat3 bm = mat3 ( batchingMatrix ) ;
transformedNormal /= vec3 ( dot ( bm [ 0 ] , bm [ 0 ] ) , dot ( bm [ 1 ] , bm [ 1 ] ) , dot ( bm [ 2 ] , bm [ 2 ] ) ) ;
transformedNormal = bm * transformedNormal ;
# ifdef USE _TANGENT
transformedTangent = bm * transformedTangent ;
# endif
# endif
# ifdef USE _INSTANCING
mat3 im = mat3 ( instanceMatrix ) ;
transformedNormal /= vec3 ( dot ( im [ 0 ] , im [ 0 ] ) , dot ( im [ 1 ] , im [ 1 ] ) , dot ( im [ 2 ] , im [ 2 ] ) ) ;
transformedNormal = im * transformedNormal ;
# ifdef USE _TANGENT
transformedTangent = im * transformedTangent ;
# endif
# endif
transformedNormal = normalMatrix * transformedNormal ;
# ifdef FLIP _SIDED
transformedNormal = - transformedNormal ;
# endif
# ifdef USE _TANGENT
transformedTangent = ( modelViewMatrix * vec4 ( transformedTangent , 0.0 ) ) . xyz ;
# ifdef FLIP _SIDED
transformedTangent = - transformedTangent ;
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,V0= ` # ifdef USE _DISPLACEMENTMAP
2026-01-22 11:29:51 +08:00
uniform sampler2D displacementMap ;
uniform float displacementScale ;
uniform float displacementBias ;
2026-01-22 15:23:57 +08:00
# endif ` ,G0= ` # ifdef USE _DISPLACEMENTMAP
2026-01-22 11:29:51 +08:00
transformed += normalize ( objectNormal ) * ( texture2D ( displacementMap , vDisplacementMapUv ) . x * displacementScale + displacementBias ) ;
2026-01-22 15:23:57 +08:00
# endif ` ,W0= ` # ifdef USE _EMISSIVEMAP
2026-01-22 11:29:51 +08:00
vec4 emissiveColor = texture2D ( emissiveMap , vEmissiveMapUv ) ;
# ifdef DECODE _VIDEO _TEXTURE _EMISSIVE
emissiveColor = sRGBTransferEOTF ( emissiveColor ) ;
# endif
totalEmissiveRadiance *= emissiveColor . rgb ;
2026-01-22 15:23:57 +08:00
# endif ` ,X0= ` # ifdef USE _EMISSIVEMAP
2026-01-22 11:29:51 +08:00
uniform sampler2D emissiveMap ;
2026-01-22 15:23:57 +08:00
# endif ` ,j0="gl_FragColor = linearToOutputTexel( gl_FragColor );",Z0= ` vec4 LinearTransferOETF ( in vec4 value ) {
2026-01-22 11:29:51 +08:00
return value ;
}
vec4 sRGBTransferEOTF ( in vec4 value ) {
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 . a ) ;
}
vec4 sRGBTransferOETF ( in vec4 value ) {
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 . a ) ;
2026-01-22 15:23:57 +08:00
} ` ,q0= ` # ifdef USE _ENVMAP
2026-01-22 11:29:51 +08:00
# ifdef ENV _WORLDPOS
vec3 cameraToFrag ;
if ( isOrthographic ) {
cameraToFrag = normalize ( vec3 ( - viewMatrix [ 0 ] [ 2 ] , - viewMatrix [ 1 ] [ 2 ] , - viewMatrix [ 2 ] [ 2 ] ) ) ;
} else {
cameraToFrag = normalize ( vWorldPosition - cameraPosition ) ;
}
vec3 worldNormal = inverseTransformDirection ( normal , viewMatrix ) ;
# ifdef ENVMAP _MODE _REFLECTION
vec3 reflectVec = reflect ( cameraToFrag , worldNormal ) ;
# else
vec3 reflectVec = refract ( cameraToFrag , worldNormal , refractionRatio ) ;
# endif
# else
vec3 reflectVec = vReflect ;
# endif
# ifdef ENVMAP _TYPE _CUBE
vec4 envColor = textureCube ( envMap , envMapRotation * vec3 ( flipEnvMap * reflectVec . x , reflectVec . yz ) ) ;
# else
vec4 envColor = vec4 ( 0.0 ) ;
# endif
# ifdef ENVMAP _BLENDING _MULTIPLY
outgoingLight = mix ( outgoingLight , outgoingLight * envColor . xyz , specularStrength * reflectivity ) ;
# elif defined ( ENVMAP _BLENDING _MIX )
outgoingLight = mix ( outgoingLight , envColor . xyz , specularStrength * reflectivity ) ;
# elif defined ( ENVMAP _BLENDING _ADD )
outgoingLight += envColor . xyz * specularStrength * reflectivity ;
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,Y0= ` # ifdef USE _ENVMAP
2026-01-22 11:29:51 +08:00
uniform float envMapIntensity ;
uniform float flipEnvMap ;
uniform mat3 envMapRotation ;
# ifdef ENVMAP _TYPE _CUBE
uniform samplerCube envMap ;
# else
uniform sampler2D envMap ;
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,K0= ` # ifdef USE _ENVMAP
2026-01-22 11:29:51 +08:00
uniform float reflectivity ;
# if defined ( USE _BUMPMAP ) || defined ( USE _NORMALMAP ) || defined ( PHONG ) || defined ( LAMBERT )
# define ENV _WORLDPOS
# endif
# ifdef ENV _WORLDPOS
varying vec3 vWorldPosition ;
uniform float refractionRatio ;
# else
varying vec3 vReflect ;
# endif
2026-01-22 15:23:57 +08:00
# endif ` , $ 0= ` # ifdef USE _ENVMAP
2026-01-22 11:29:51 +08:00
# if defined ( USE _BUMPMAP ) || defined ( USE _NORMALMAP ) || defined ( PHONG ) || defined ( LAMBERT )
# define ENV _WORLDPOS
# endif
# ifdef ENV _WORLDPOS
varying vec3 vWorldPosition ;
# else
varying vec3 vReflect ;
uniform float refractionRatio ;
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,J0= ` # ifdef USE _ENVMAP
2026-01-22 11:29:51 +08:00
# ifdef ENV _WORLDPOS
vWorldPosition = worldPosition . xyz ;
# else
vec3 cameraToVertex ;
if ( isOrthographic ) {
cameraToVertex = normalize ( vec3 ( - viewMatrix [ 0 ] [ 2 ] , - viewMatrix [ 1 ] [ 2 ] , - viewMatrix [ 2 ] [ 2 ] ) ) ;
} else {
cameraToVertex = normalize ( worldPosition . xyz - cameraPosition ) ;
}
vec3 worldNormal = inverseTransformDirection ( transformedNormal , viewMatrix ) ;
# ifdef ENVMAP _MODE _REFLECTION
vReflect = reflect ( cameraToVertex , worldNormal ) ;
# else
vReflect = refract ( cameraToVertex , worldNormal , refractionRatio ) ;
# endif
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,Q0= ` # ifdef USE _FOG
2026-01-22 11:29:51 +08:00
vFogDepth = - mvPosition . z ;
2026-01-22 15:23:57 +08:00
# endif ` ,eg= ` # ifdef USE _FOG
2026-01-22 11:29:51 +08:00
varying float vFogDepth ;
2026-01-22 15:23:57 +08:00
# endif ` ,tg= ` # ifdef USE _FOG
2026-01-22 11:29:51 +08:00
# ifdef FOG _EXP2
float fogFactor = 1.0 - exp ( - fogDensity * fogDensity * vFogDepth * vFogDepth ) ;
# else
float fogFactor = smoothstep ( fogNear , fogFar , vFogDepth ) ;
# endif
gl _FragColor . rgb = mix ( gl _FragColor . rgb , fogColor , fogFactor ) ;
2026-01-22 15:23:57 +08:00
# endif ` ,ng= ` # ifdef USE _FOG
2026-01-22 11:29:51 +08:00
uniform vec3 fogColor ;
varying float vFogDepth ;
# ifdef FOG _EXP2
uniform float fogDensity ;
# else
uniform float fogNear ;
uniform float fogFar ;
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,ig= ` # ifdef USE _GRADIENTMAP
2026-01-22 11:29:51 +08:00
uniform sampler2D gradientMap ;
# endif
vec3 getGradientIrradiance ( vec3 normal , vec3 lightDirection ) {
float dotNL = dot ( normal , lightDirection ) ;
vec2 coord = vec2 ( dotNL * 0.5 + 0.5 , 0.0 ) ;
# ifdef USE _GRADIENTMAP
return vec3 ( texture2D ( gradientMap , coord ) . r ) ;
# else
vec2 fw = fwidth ( coord ) * 0.5 ;
return mix ( vec3 ( 0.7 ) , vec3 ( 1.0 ) , smoothstep ( 0.7 - fw . x , 0.7 + fw . x , coord . x ) ) ;
# endif
2026-01-22 15:23:57 +08:00
} ` ,sg= ` # ifdef USE _LIGHTMAP
2026-01-22 11:29:51 +08:00
uniform sampler2D lightMap ;
uniform float lightMapIntensity ;
2026-01-22 15:23:57 +08:00
# endif ` ,rg= ` LambertMaterial material ;
2026-01-22 11:29:51 +08:00
material . diffuseColor = diffuseColor . rgb ;
2026-01-22 15:23:57 +08:00
material . specularStrength = specularStrength ; ` ,ag= ` varying vec3 vViewPosition ;
2026-01-22 11:29:51 +08:00
struct LambertMaterial {
vec3 diffuseColor ;
float specularStrength ;
} ;
void RE _Direct _Lambert ( const in IncidentLight directLight , const in vec3 geometryPosition , const in vec3 geometryNormal , const in vec3 geometryViewDir , const in vec3 geometryClearcoatNormal , const in LambertMaterial material , inout ReflectedLight reflectedLight ) {
float dotNL = saturate ( dot ( geometryNormal , directLight . direction ) ) ;
vec3 irradiance = dotNL * directLight . color ;
reflectedLight . directDiffuse += irradiance * BRDF _Lambert ( material . diffuseColor ) ;
}
void RE _IndirectDiffuse _Lambert ( const in vec3 irradiance , const in vec3 geometryPosition , const in vec3 geometryNormal , const in vec3 geometryViewDir , const in vec3 geometryClearcoatNormal , const in LambertMaterial material , inout ReflectedLight reflectedLight ) {
reflectedLight . indirectDiffuse += irradiance * BRDF _Lambert ( material . diffuseColor ) ;
}
# define RE _Direct RE _Direct _Lambert
2026-01-22 15:23:57 +08:00
# define RE _IndirectDiffuse RE _IndirectDiffuse _Lambert ` ,og= ` uniform bool receiveShadow ;
2026-01-22 11:29:51 +08:00
uniform vec3 ambientLightColor ;
# if defined ( USE _LIGHT _PROBES )
uniform vec3 lightProbe [ 9 ] ;
# endif
vec3 shGetIrradianceAt ( in vec3 normal , in vec3 shCoefficients [ 9 ] ) {
float x = normal . x , y = normal . y , z = normal . z ;
vec3 result = shCoefficients [ 0 ] * 0.886227 ;
result += shCoefficients [ 1 ] * 2.0 * 0.511664 * y ;
result += shCoefficients [ 2 ] * 2.0 * 0.511664 * z ;
result += shCoefficients [ 3 ] * 2.0 * 0.511664 * x ;
result += shCoefficients [ 4 ] * 2.0 * 0.429043 * x * y ;
result += shCoefficients [ 5 ] * 2.0 * 0.429043 * y * z ;
result += shCoefficients [ 6 ] * ( 0.743125 * z * z - 0.247708 ) ;
result += shCoefficients [ 7 ] * 2.0 * 0.429043 * x * z ;
result += shCoefficients [ 8 ] * 0.429043 * ( x * x - y * y ) ;
return result ;
}
vec3 getLightProbeIrradiance ( const in vec3 lightProbe [ 9 ] , const in vec3 normal ) {
vec3 worldNormal = inverseTransformDirection ( normal , viewMatrix ) ;
vec3 irradiance = shGetIrradianceAt ( worldNormal , lightProbe ) ;
return irradiance ;
}
vec3 getAmbientLightIrradiance ( const in vec3 ambientLightColor ) {
vec3 irradiance = ambientLightColor ;
return irradiance ;
}
float getDistanceAttenuation ( const in float lightDistance , const in float cutoffDistance , const in float decayExponent ) {
float distanceFalloff = 1.0 / max ( pow ( lightDistance , decayExponent ) , 0.01 ) ;
if ( cutoffDistance > 0.0 ) {
distanceFalloff *= pow2 ( saturate ( 1.0 - pow4 ( lightDistance / cutoffDistance ) ) ) ;
}
return distanceFalloff ;
}
float getSpotAttenuation ( const in float coneCosine , const in float penumbraCosine , const in float angleCosine ) {
return smoothstep ( coneCosine , penumbraCosine , angleCosine ) ;
}
# if NUM _DIR _LIGHTS > 0
struct DirectionalLight {
vec3 direction ;
vec3 color ;
} ;
uniform DirectionalLight directionalLights [ NUM _DIR _LIGHTS ] ;
void getDirectionalLightInfo ( const in DirectionalLight directionalLight , out IncidentLight light ) {
light . color = directionalLight . color ;
light . direction = directionalLight . direction ;
light . visible = true ;
}
# endif
# if NUM _POINT _LIGHTS > 0
struct PointLight {
vec3 position ;
vec3 color ;
float distance ;
float decay ;
} ;
uniform PointLight pointLights [ NUM _POINT _LIGHTS ] ;
void getPointLightInfo ( const in PointLight pointLight , const in vec3 geometryPosition , out IncidentLight light ) {
vec3 lVector = pointLight . position - geometryPosition ;
light . direction = normalize ( lVector ) ;
float lightDistance = length ( lVector ) ;
light . color = pointLight . color ;
light . color *= getDistanceAttenuation ( lightDistance , pointLight . distance , pointLight . decay ) ;
light . visible = ( light . color != vec3 ( 0.0 ) ) ;
}
# endif
# if NUM _SPOT _LIGHTS > 0
struct SpotLight {
vec3 position ;
vec3 direction ;
vec3 color ;
float distance ;
float decay ;
float coneCos ;
float penumbraCos ;
} ;
uniform SpotLight spotLights [ NUM _SPOT _LIGHTS ] ;
void getSpotLightInfo ( const in SpotLight spotLight , const in vec3 geometryPosition , out IncidentLight light ) {
vec3 lVector = spotLight . position - geometryPosition ;
light . direction = normalize ( lVector ) ;
float angleCos = dot ( light . direction , spotLight . direction ) ;
float spotAttenuation = getSpotAttenuation ( spotLight . coneCos , spotLight . penumbraCos , angleCos ) ;
if ( spotAttenuation > 0.0 ) {
float lightDistance = length ( lVector ) ;
light . color = spotLight . color * spotAttenuation ;
light . color *= getDistanceAttenuation ( lightDistance , spotLight . distance , spotLight . decay ) ;
light . visible = ( light . color != vec3 ( 0.0 ) ) ;
} else {
light . color = vec3 ( 0.0 ) ;
light . visible = false ;
}
}
# endif
# if NUM _RECT _AREA _LIGHTS > 0
struct RectAreaLight {
vec3 color ;
vec3 position ;
vec3 halfWidth ;
vec3 halfHeight ;
} ;
uniform sampler2D ltc _1 ; uniform sampler2D ltc _2 ;
uniform RectAreaLight rectAreaLights [ NUM _RECT _AREA _LIGHTS ] ;
# endif
# if NUM _HEMI _LIGHTS > 0
struct HemisphereLight {
vec3 direction ;
vec3 skyColor ;
vec3 groundColor ;
} ;
uniform HemisphereLight hemisphereLights [ NUM _HEMI _LIGHTS ] ;
vec3 getHemisphereLightIrradiance ( const in HemisphereLight hemiLight , const in vec3 normal ) {
float dotNL = dot ( normal , hemiLight . direction ) ;
float hemiDiffuseWeight = 0.5 * dotNL + 0.5 ;
vec3 irradiance = mix ( hemiLight . groundColor , hemiLight . skyColor , hemiDiffuseWeight ) ;
return irradiance ;
}
2026-01-22 15:23:57 +08:00
# endif ` ,lg= ` # ifdef USE _ENVMAP
2026-01-22 11:29:51 +08:00
vec3 getIBLIrradiance ( const in vec3 normal ) {
# ifdef ENVMAP _TYPE _CUBE _UV
vec3 worldNormal = inverseTransformDirection ( normal , viewMatrix ) ;
vec4 envMapColor = textureCubeUV ( envMap , envMapRotation * worldNormal , 1.0 ) ;
return PI * envMapColor . rgb * envMapIntensity ;
# else
return vec3 ( 0.0 ) ;
# endif
}
vec3 getIBLRadiance ( const in vec3 viewDir , const in vec3 normal , const in float roughness ) {
# ifdef ENVMAP _TYPE _CUBE _UV
vec3 reflectVec = reflect ( - viewDir , normal ) ;
reflectVec = normalize ( mix ( reflectVec , normal , pow4 ( roughness ) ) ) ;
reflectVec = inverseTransformDirection ( reflectVec , viewMatrix ) ;
vec4 envMapColor = textureCubeUV ( envMap , envMapRotation * reflectVec , roughness ) ;
return envMapColor . rgb * envMapIntensity ;
# else
return vec3 ( 0.0 ) ;
# endif
}
# ifdef USE _ANISOTROPY
vec3 getIBLAnisotropyRadiance ( const in vec3 viewDir , const in vec3 normal , const in float roughness , const in vec3 bitangent , const in float anisotropy ) {
# ifdef ENVMAP _TYPE _CUBE _UV
vec3 bentNormal = cross ( bitangent , viewDir ) ;
bentNormal = normalize ( cross ( bentNormal , bitangent ) ) ;
bentNormal = normalize ( mix ( bentNormal , normal , pow2 ( pow2 ( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) ) ;
return getIBLRadiance ( viewDir , bentNormal , roughness ) ;
# else
return vec3 ( 0.0 ) ;
# endif
}
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,cg= ` ToonMaterial material ;
material . diffuseColor = diffuseColor . rgb ; ` ,hg= ` varying vec3 vViewPosition ;
2026-01-22 11:29:51 +08:00
struct ToonMaterial {
vec3 diffuseColor ;
} ;
void RE _Direct _Toon ( const in IncidentLight directLight , const in vec3 geometryPosition , const in vec3 geometryNormal , const in vec3 geometryViewDir , const in vec3 geometryClearcoatNormal , const in ToonMaterial material , inout ReflectedLight reflectedLight ) {
vec3 irradiance = getGradientIrradiance ( geometryNormal , directLight . direction ) * directLight . color ;
reflectedLight . directDiffuse += irradiance * BRDF _Lambert ( material . diffuseColor ) ;
}
void RE _IndirectDiffuse _Toon ( const in vec3 irradiance , const in vec3 geometryPosition , const in vec3 geometryNormal , const in vec3 geometryViewDir , const in vec3 geometryClearcoatNormal , const in ToonMaterial material , inout ReflectedLight reflectedLight ) {
reflectedLight . indirectDiffuse += irradiance * BRDF _Lambert ( material . diffuseColor ) ;
}
# define RE _Direct RE _Direct _Toon
2026-01-22 15:23:57 +08:00
# define RE _IndirectDiffuse RE _IndirectDiffuse _Toon ` ,ug= ` BlinnPhongMaterial material ;
2026-01-22 11:29:51 +08:00
material . diffuseColor = diffuseColor . rgb ;
material . specularColor = specular ;
material . specularShininess = shininess ;
2026-01-22 15:23:57 +08:00
material . specularStrength = specularStrength ; ` ,dg= ` varying vec3 vViewPosition ;
2026-01-22 11:29:51 +08:00
struct BlinnPhongMaterial {
vec3 diffuseColor ;
vec3 specularColor ;
float specularShininess ;
float specularStrength ;
} ;
void RE _Direct _BlinnPhong ( const in IncidentLight directLight , const in vec3 geometryPosition , const in vec3 geometryNormal , const in vec3 geometryViewDir , const in vec3 geometryClearcoatNormal , const in BlinnPhongMaterial material , inout ReflectedLight reflectedLight ) {
float dotNL = saturate ( dot ( geometryNormal , directLight . direction ) ) ;
vec3 irradiance = dotNL * directLight . color ;
reflectedLight . directDiffuse += irradiance * BRDF _Lambert ( material . diffuseColor ) ;
reflectedLight . directSpecular += irradiance * BRDF _BlinnPhong ( directLight . direction , geometryViewDir , geometryNormal , material . specularColor , material . specularShininess ) * material . specularStrength ;
}
void RE _IndirectDiffuse _BlinnPhong ( const in vec3 irradiance , const in vec3 geometryPosition , const in vec3 geometryNormal , const in vec3 geometryViewDir , const in vec3 geometryClearcoatNormal , const in BlinnPhongMaterial material , inout ReflectedLight reflectedLight ) {
reflectedLight . indirectDiffuse += irradiance * BRDF _Lambert ( material . diffuseColor ) ;
}
# define RE _Direct RE _Direct _BlinnPhong
2026-01-22 15:23:57 +08:00
# define RE _IndirectDiffuse RE _IndirectDiffuse _BlinnPhong ` ,fg= ` PhysicalMaterial material ;
2026-01-22 11:29:51 +08:00
material . diffuseColor = diffuseColor . rgb * ( 1.0 - metalnessFactor ) ;
vec3 dxy = max ( abs ( dFdx ( nonPerturbedNormal ) ) , abs ( dFdy ( nonPerturbedNormal ) ) ) ;
float geometryRoughness = max ( max ( dxy . x , dxy . y ) , dxy . z ) ;
material . roughness = max ( roughnessFactor , 0.0525 ) ; material . roughness += geometryRoughness ;
material . roughness = min ( material . roughness , 1.0 ) ;
# ifdef IOR
material . ior = ior ;
# ifdef USE _SPECULAR
float specularIntensityFactor = specularIntensity ;
vec3 specularColorFactor = specularColor ;
# ifdef USE _SPECULAR _COLORMAP
specularColorFactor *= texture2D ( specularColorMap , vSpecularColorMapUv ) . rgb ;
# endif
# ifdef USE _SPECULAR _INTENSITYMAP
specularIntensityFactor *= texture2D ( specularIntensityMap , vSpecularIntensityMapUv ) . a ;
# endif
material . specularF90 = mix ( specularIntensityFactor , 1.0 , metalnessFactor ) ;
# else
float specularIntensityFactor = 1.0 ;
vec3 specularColorFactor = vec3 ( 1.0 ) ;
material . specularF90 = 1.0 ;
# endif
material . specularColor = mix ( min ( pow2 ( ( material . ior - 1.0 ) / ( material . ior + 1.0 ) ) * specularColorFactor , vec3 ( 1.0 ) ) * specularIntensityFactor , diffuseColor . rgb , metalnessFactor ) ;
# else
material . specularColor = mix ( vec3 ( 0.04 ) , diffuseColor . rgb , metalnessFactor ) ;
material . specularF90 = 1.0 ;
# endif
# ifdef USE _CLEARCOAT
material . clearcoat = clearcoat ;
material . clearcoatRoughness = clearcoatRoughness ;
material . clearcoatF0 = vec3 ( 0.04 ) ;
material . clearcoatF90 = 1.0 ;
# ifdef USE _CLEARCOATMAP
material . clearcoat *= texture2D ( clearcoatMap , vClearcoatMapUv ) . x ;
# endif
# ifdef USE _CLEARCOAT _ROUGHNESSMAP
material . clearcoatRoughness *= texture2D ( clearcoatRoughnessMap , vClearcoatRoughnessMapUv ) . y ;
# endif
material . clearcoat = saturate ( material . clearcoat ) ; material . clearcoatRoughness = max ( material . clearcoatRoughness , 0.0525 ) ;
material . clearcoatRoughness += geometryRoughness ;
material . clearcoatRoughness = min ( material . clearcoatRoughness , 1.0 ) ;
# endif
# ifdef USE _DISPERSION
material . dispersion = dispersion ;
# endif
# ifdef USE _IRIDESCENCE
material . iridescence = iridescence ;
material . iridescenceIOR = iridescenceIOR ;
# ifdef USE _IRIDESCENCEMAP
material . iridescence *= texture2D ( iridescenceMap , vIridescenceMapUv ) . r ;
# endif
# ifdef USE _IRIDESCENCE _THICKNESSMAP
material . iridescenceThickness = ( iridescenceThicknessMaximum - iridescenceThicknessMinimum ) * texture2D ( iridescenceThicknessMap , vIridescenceThicknessMapUv ) . g + iridescenceThicknessMinimum ;
# else
material . iridescenceThickness = iridescenceThicknessMaximum ;
# endif
# endif
# ifdef USE _SHEEN
material . sheenColor = sheenColor ;
# ifdef USE _SHEEN _COLORMAP
material . sheenColor *= texture2D ( sheenColorMap , vSheenColorMapUv ) . rgb ;
# endif
material . sheenRoughness = clamp ( sheenRoughness , 0.07 , 1.0 ) ;
# ifdef USE _SHEEN _ROUGHNESSMAP
material . sheenRoughness *= texture2D ( sheenRoughnessMap , vSheenRoughnessMapUv ) . a ;
# endif
# endif
# ifdef USE _ANISOTROPY
# ifdef USE _ANISOTROPYMAP
mat2 anisotropyMat = mat2 ( anisotropyVector . x , anisotropyVector . y , - anisotropyVector . y , anisotropyVector . x ) ;
vec3 anisotropyPolar = texture2D ( anisotropyMap , vAnisotropyMapUv ) . rgb ;
vec2 anisotropyV = anisotropyMat * normalize ( 2.0 * anisotropyPolar . rg - vec2 ( 1.0 ) ) * anisotropyPolar . b ;
# else
vec2 anisotropyV = anisotropyVector ;
# endif
material . anisotropy = length ( anisotropyV ) ;
if ( material . anisotropy == 0.0 ) {
anisotropyV = vec2 ( 1.0 , 0.0 ) ;
} else {
anisotropyV /= material . anisotropy ;
material . anisotropy = saturate ( material . anisotropy ) ;
}
material . alphaT = mix ( pow2 ( material . roughness ) , 1.0 , pow2 ( material . anisotropy ) ) ;
material . anisotropyT = tbn [ 0 ] * anisotropyV . x + tbn [ 1 ] * anisotropyV . y ;
material . anisotropyB = tbn [ 1 ] * anisotropyV . x - tbn [ 0 ] * anisotropyV . y ;
2026-01-22 15:23:57 +08:00
# endif ` ,pg= ` uniform sampler2D dfgLUT ;
2026-01-22 11:29:51 +08:00
struct PhysicalMaterial {
vec3 diffuseColor ;
float roughness ;
vec3 specularColor ;
float specularF90 ;
float dispersion ;
# ifdef USE _CLEARCOAT
float clearcoat ;
float clearcoatRoughness ;
vec3 clearcoatF0 ;
float clearcoatF90 ;
# endif
# ifdef USE _IRIDESCENCE
float iridescence ;
float iridescenceIOR ;
float iridescenceThickness ;
vec3 iridescenceFresnel ;
vec3 iridescenceF0 ;
# endif
# ifdef USE _SHEEN
vec3 sheenColor ;
float sheenRoughness ;
# endif
# ifdef IOR
float ior ;
# endif
# ifdef USE _TRANSMISSION
float transmission ;
float transmissionAlpha ;
float thickness ;
float attenuationDistance ;
vec3 attenuationColor ;
# endif
# ifdef USE _ANISOTROPY
float anisotropy ;
float alphaT ;
vec3 anisotropyT ;
vec3 anisotropyB ;
# endif
} ;
vec3 clearcoatSpecularDirect = vec3 ( 0.0 ) ;
vec3 clearcoatSpecularIndirect = vec3 ( 0.0 ) ;
vec3 sheenSpecularDirect = vec3 ( 0.0 ) ;
vec3 sheenSpecularIndirect = vec3 ( 0.0 ) ;
vec3 Schlick _to _F0 ( const in vec3 f , const in float f90 , const in float dotVH ) {
float x = clamp ( 1.0 - dotVH , 0.0 , 1.0 ) ;
float x2 = x * x ;
float x5 = clamp ( x * x2 * x2 , 0.0 , 0.9999 ) ;
return ( f - vec3 ( f90 ) * x5 ) / ( 1.0 - x5 ) ;
}
float V _GGX _SmithCorrelated ( const in float alpha , const in float dotNL , const in float dotNV ) {
float a2 = pow2 ( alpha ) ;
float gv = dotNL * sqrt ( a2 + ( 1.0 - a2 ) * pow2 ( dotNV ) ) ;
float gl = dotNV * sqrt ( a2 + ( 1.0 - a2 ) * pow2 ( dotNL ) ) ;
return 0.5 / max ( gv + gl , EPSILON ) ;
}
float D _GGX ( const in float alpha , const in float dotNH ) {
float a2 = pow2 ( alpha ) ;
float denom = pow2 ( dotNH ) * ( a2 - 1.0 ) + 1.0 ;
return RECIPROCAL _PI * a2 / pow2 ( denom ) ;
}
# ifdef USE _ANISOTROPY
float V _GGX _SmithCorrelated _Anisotropic ( const in float alphaT , const in float alphaB , const in float dotTV , const in float dotBV , const in float dotTL , const in float dotBL , const in float dotNV , const in float dotNL ) {
float gv = dotNL * length ( vec3 ( alphaT * dotTV , alphaB * dotBV , dotNV ) ) ;
float gl = dotNV * length ( vec3 ( alphaT * dotTL , alphaB * dotBL , dotNL ) ) ;
float v = 0.5 / ( gv + gl ) ;
return saturate ( v ) ;
}
float D _GGX _Anisotropic ( const in float alphaT , const in float alphaB , const in float dotNH , const in float dotTH , const in float dotBH ) {
float a2 = alphaT * alphaB ;
highp vec3 v = vec3 ( alphaB * dotTH , alphaT * dotBH , a2 * dotNH ) ;
highp float v2 = dot ( v , v ) ;
float w2 = a2 / v2 ;
return RECIPROCAL _PI * a2 * pow2 ( w2 ) ;
}
# endif
# ifdef USE _CLEARCOAT
vec3 BRDF _GGX _Clearcoat ( const in vec3 lightDir , const in vec3 viewDir , const in vec3 normal , const in PhysicalMaterial material ) {
vec3 f0 = material . clearcoatF0 ;
float f90 = material . clearcoatF90 ;
float roughness = material . clearcoatRoughness ;
float alpha = pow2 ( roughness ) ;
vec3 halfDir = normalize ( lightDir + viewDir ) ;
float dotNL = saturate ( dot ( normal , lightDir ) ) ;
float dotNV = saturate ( dot ( normal , viewDir ) ) ;
float dotNH = saturate ( dot ( normal , halfDir ) ) ;
float dotVH = saturate ( dot ( viewDir , halfDir ) ) ;
vec3 F = F _Schlick ( f0 , f90 , dotVH ) ;
float V = V _GGX _SmithCorrelated ( alpha , dotNL , dotNV ) ;
float D = D _GGX ( alpha , dotNH ) ;
return F * ( V * D ) ;
}
# endif
vec3 BRDF _GGX ( const in vec3 lightDir , const in vec3 viewDir , const in vec3 normal , const in PhysicalMaterial material ) {
vec3 f0 = material . specularColor ;
float f90 = material . specularF90 ;
float roughness = material . roughness ;
float alpha = pow2 ( roughness ) ;
vec3 halfDir = normalize ( lightDir + viewDir ) ;
float dotNL = saturate ( dot ( normal , lightDir ) ) ;
float dotNV = saturate ( dot ( normal , viewDir ) ) ;
float dotNH = saturate ( dot ( normal , halfDir ) ) ;
float dotVH = saturate ( dot ( viewDir , halfDir ) ) ;
vec3 F = F _Schlick ( f0 , f90 , dotVH ) ;
# ifdef USE _IRIDESCENCE
F = mix ( F , material . iridescenceFresnel , material . iridescence ) ;
# endif
# ifdef USE _ANISOTROPY
float dotTL = dot ( material . anisotropyT , lightDir ) ;
float dotTV = dot ( material . anisotropyT , viewDir ) ;
float dotTH = dot ( material . anisotropyT , halfDir ) ;
float dotBL = dot ( material . anisotropyB , lightDir ) ;
float dotBV = dot ( material . anisotropyB , viewDir ) ;
float dotBH = dot ( material . anisotropyB , halfDir ) ;
float V = V _GGX _SmithCorrelated _Anisotropic ( material . alphaT , alpha , dotTV , dotBV , dotTL , dotBL , dotNV , dotNL ) ;
float D = D _GGX _Anisotropic ( material . alphaT , alpha , dotNH , dotTH , dotBH ) ;
# else
float V = V _GGX _SmithCorrelated ( alpha , dotNL , dotNV ) ;
float D = D _GGX ( alpha , dotNH ) ;
# endif
return F * ( V * D ) ;
}
vec2 LTC _Uv ( const in vec3 N , const in vec3 V , const in float roughness ) {
const float LUT _SIZE = 64.0 ;
const float LUT _SCALE = ( LUT _SIZE - 1.0 ) / LUT _SIZE ;
const float LUT _BIAS = 0.5 / LUT _SIZE ;
float dotNV = saturate ( dot ( N , V ) ) ;
vec2 uv = vec2 ( roughness , sqrt ( 1.0 - dotNV ) ) ;
uv = uv * LUT _SCALE + LUT _BIAS ;
return uv ;
}
float LTC _ClippedSphereFormFactor ( const in vec3 f ) {
float l = length ( f ) ;
return max ( ( l * l + f . z ) / ( l + 1.0 ) , 0.0 ) ;
}
vec3 LTC _EdgeVectorFormFactor ( const in vec3 v1 , const in vec3 v2 ) {
float x = dot ( v1 , v2 ) ;
float y = abs ( x ) ;
float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y ;
float b = 3.4175940 + ( 4.1616724 + y ) * y ;
float v = a / b ;
float theta _sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt ( max ( 1.0 - x * x , 1e-7 ) ) - v ;
return cross ( v1 , v2 ) * theta _sintheta ;
}
vec3 LTC _Evaluate ( const in vec3 N , const in vec3 V , const in vec3 P , const in mat3 mInv , const in vec3 rectCoords [ 4 ] ) {
vec3 v1 = rectCoords [ 1 ] - rectCoords [ 0 ] ;
vec3 v2 = rectCoords [ 3 ] - rectCoords [ 0 ] ;
vec3 lightNormal = cross ( v1 , v2 ) ;
if ( dot ( lightNormal , P - rectCoords [ 0 ] ) < 0.0 ) return vec3 ( 0.0 ) ;
vec3 T1 , T2 ;
T1 = normalize ( V - N * dot ( V , N ) ) ;
T2 = - cross ( N , T1 ) ;
mat3 mat = mInv * transpose ( mat3 ( T1 , T2 , N ) ) ;
vec3 coords [ 4 ] ;
coords [ 0 ] = mat * ( rectCoords [ 0 ] - P ) ;
coords [ 1 ] = mat * ( rectCoords [ 1 ] - P ) ;
coords [ 2 ] = mat * ( rectCoords [ 2 ] - P ) ;
coords [ 3 ] = mat * ( rectCoords [ 3 ] - P ) ;
coords [ 0 ] = normalize ( coords [ 0 ] ) ;
coords [ 1 ] = normalize ( coords [ 1 ] ) ;
coords [ 2 ] = normalize ( coords [ 2 ] ) ;
coords [ 3 ] = normalize ( coords [ 3 ] ) ;
vec3 vectorFormFactor = vec3 ( 0.0 ) ;
vectorFormFactor += LTC _EdgeVectorFormFactor ( coords [ 0 ] , coords [ 1 ] ) ;
vectorFormFactor += LTC _EdgeVectorFormFactor ( coords [ 1 ] , coords [ 2 ] ) ;
vectorFormFactor += LTC _EdgeVectorFormFactor ( coords [ 2 ] , coords [ 3 ] ) ;
vectorFormFactor += LTC _EdgeVectorFormFactor ( coords [ 3 ] , coords [ 0 ] ) ;
float result = LTC _ClippedSphereFormFactor ( vectorFormFactor ) ;
return vec3 ( result ) ;
}
# if defined ( USE _SHEEN )
float D _Charlie ( float roughness , float dotNH ) {
float alpha = pow2 ( roughness ) ;
float invAlpha = 1.0 / alpha ;
float cos2h = dotNH * dotNH ;
float sin2h = max ( 1.0 - cos2h , 0.0078125 ) ;
return ( 2.0 + invAlpha ) * pow ( sin2h , invAlpha * 0.5 ) / ( 2.0 * PI ) ;
}
float V _Neubelt ( float dotNV , float dotNL ) {
return saturate ( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) ) ;
}
vec3 BRDF _Sheen ( const in vec3 lightDir , const in vec3 viewDir , const in vec3 normal , vec3 sheenColor , const in float sheenRoughness ) {
vec3 halfDir = normalize ( lightDir + viewDir ) ;
float dotNL = saturate ( dot ( normal , lightDir ) ) ;
float dotNV = saturate ( dot ( normal , viewDir ) ) ;
float dotNH = saturate ( dot ( normal , halfDir ) ) ;
float D = D _Charlie ( sheenRoughness , dotNH ) ;
float V = V _Neubelt ( dotNV , dotNL ) ;
return sheenColor * ( D * V ) ;
}
# endif
float IBLSheenBRDF ( const in vec3 normal , const in vec3 viewDir , const in float roughness ) {
float dotNV = saturate ( dot ( normal , viewDir ) ) ;
float r2 = roughness * roughness ;
float a = roughness < 0.25 ? - 339.2 * r2 + 161.4 * roughness - 25.9 : - 8.48 * r2 + 14.3 * roughness - 9.95 ;
float b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72 ;
float DG = exp ( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) ) ;
return saturate ( DG * RECIPROCAL _PI ) ;
}
vec2 DFGApprox ( const in vec3 normal , const in vec3 viewDir , const in float roughness ) {
float dotNV = saturate ( dot ( normal , viewDir ) ) ;
vec2 uv = vec2 ( roughness , dotNV ) ;
return texture2D ( dfgLUT , uv ) . rg ;
}
vec3 EnvironmentBRDF ( const in vec3 normal , const in vec3 viewDir , const in vec3 specularColor , const in float specularF90 , const in float roughness ) {
vec2 fab = DFGApprox ( normal , viewDir , roughness ) ;
return specularColor * fab . x + specularF90 * fab . y ;
}
# ifdef USE _IRIDESCENCE
void computeMultiscatteringIridescence ( const in vec3 normal , const in vec3 viewDir , const in vec3 specularColor , const in float specularF90 , const in float iridescence , const in vec3 iridescenceF0 , const in float roughness , inout vec3 singleScatter , inout vec3 multiScatter ) {
# else
void computeMultiscattering ( const in vec3 normal , const in vec3 viewDir , const in vec3 specularColor , const in float specularF90 , const in float roughness , inout vec3 singleScatter , inout vec3 multiScatter ) {
# endif
vec2 fab = DFGApprox ( normal , viewDir , roughness ) ;
# ifdef USE _IRIDESCENCE
vec3 Fr = mix ( specularColor , iridescenceF0 , iridescence ) ;
# else
vec3 Fr = specularColor ;
# endif
vec3 FssEss = Fr * fab . x + specularF90 * fab . y ;
float Ess = fab . x + fab . y ;
float Ems = 1.0 - Ess ;
vec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619 ; vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg ) ;
singleScatter += FssEss ;
multiScatter += Fms * Ems ;
}
vec3 BRDF _GGX _Multiscatter ( const in vec3 lightDir , const in vec3 viewDir , const in vec3 normal , const in PhysicalMaterial material ) {
vec3 singleScatter = BRDF _GGX ( lightDir , viewDir , normal , material ) ;
float dotNL = saturate ( dot ( normal , lightDir ) ) ;
float dotNV = saturate ( dot ( normal , viewDir ) ) ;
vec2 dfgV = DFGApprox ( vec3 ( 0.0 , 0.0 , 1.0 ) , vec3 ( sqrt ( 1.0 - dotNV * dotNV ) , 0.0 , dotNV ) , material . roughness ) ;
vec2 dfgL = DFGApprox ( vec3 ( 0.0 , 0.0 , 1.0 ) , vec3 ( sqrt ( 1.0 - dotNL * dotNL ) , 0.0 , dotNL ) , material . roughness ) ;
vec3 FssEss _V = material . specularColor * dfgV . x + material . specularF90 * dfgV . y ;
vec3 FssEss _L = material . specularColor * dfgL . x + material . specularF90 * dfgL . y ;
float Ess _V = dfgV . x + dfgV . y ;
float Ess _L = dfgL . x + dfgL . y ;
float Ems _V = 1.0 - Ess _V ;
float Ems _L = 1.0 - Ess _L ;
vec3 Favg = material . specularColor + ( 1.0 - material . specularColor ) * 0.047619 ;
vec3 Fms = FssEss _V * FssEss _L * Favg / ( 1.0 - Ems _V * Ems _L * Favg * Favg + EPSILON ) ;
float compensationFactor = Ems _V * Ems _L ;
vec3 multiScatter = Fms * compensationFactor ;
return singleScatter + multiScatter ;
}
# if NUM _RECT _AREA _LIGHTS > 0
void RE _Direct _RectArea _Physical ( const in RectAreaLight rectAreaLight , const in vec3 geometryPosition , const in vec3 geometryNormal , const in vec3 geometryViewDir , const in vec3 geometryClearcoatNormal , const in PhysicalMaterial material , inout ReflectedLight reflectedLight ) {
vec3 normal = geometryNormal ;
vec3 viewDir = geometryViewDir ;
vec3 position = geometryPosition ;
vec3 lightPos = rectAreaLight . position ;
vec3 halfWidth = rectAreaLight . halfWidth ;
vec3 halfHeight = rectAreaLight . halfHeight ;
vec3 lightColor = rectAreaLight . color ;
float roughness = material . roughness ;
vec3 rectCoords [ 4 ] ;
rectCoords [ 0 ] = lightPos + halfWidth - halfHeight ; rectCoords [ 1 ] = lightPos - halfWidth - halfHeight ;
rectCoords [ 2 ] = lightPos - halfWidth + halfHeight ;
rectCoords [ 3 ] = lightPos + halfWidth + halfHeight ;
vec2 uv = LTC _Uv ( normal , viewDir , roughness ) ;
vec4 t1 = texture2D ( ltc _1 , uv ) ;
vec4 t2 = texture2D ( ltc _2 , uv ) ;
mat3 mInv = mat3 (
vec3 ( t1 . x , 0 , t1 . y ) ,
vec3 ( 0 , 1 , 0 ) ,
vec3 ( t1 . z , 0 , t1 . w )
) ;
vec3 fresnel = ( material . specularColor * t2 . x + ( vec3 ( 1.0 ) - material . specularColor ) * t2 . y ) ;
reflectedLight . directSpecular += lightColor * fresnel * LTC _Evaluate ( normal , viewDir , position , mInv , rectCoords ) ;
reflectedLight . directDiffuse += lightColor * material . diffuseColor * LTC _Evaluate ( normal , viewDir , position , mat3 ( 1.0 ) , rectCoords ) ;
}
# endif
void RE _Direct _Physical ( const in IncidentLight directLight , const in vec3 geometryPosition , const in vec3 geometryNormal , const in vec3 geometryViewDir , const in vec3 geometryClearcoatNormal , const in PhysicalMaterial material , inout ReflectedLight reflectedLight ) {
float dotNL = saturate ( dot ( geometryNormal , directLight . direction ) ) ;
vec3 irradiance = dotNL * directLight . color ;
# ifdef USE _CLEARCOAT
float dotNLcc = saturate ( dot ( geometryClearcoatNormal , directLight . direction ) ) ;
vec3 ccIrradiance = dotNLcc * directLight . color ;
clearcoatSpecularDirect += ccIrradiance * BRDF _GGX _Clearcoat ( directLight . direction , geometryViewDir , geometryClearcoatNormal , material ) ;
# endif
# ifdef USE _SHEEN
sheenSpecularDirect += irradiance * BRDF _Sheen ( directLight . direction , geometryViewDir , geometryNormal , material . sheenColor , material . sheenRoughness ) ;
# endif
reflectedLight . directSpecular += irradiance * BRDF _GGX _Multiscatter ( directLight . direction , geometryViewDir , geometryNormal , material ) ;
reflectedLight . directDiffuse += irradiance * BRDF _Lambert ( material . diffuseColor ) ;
}
void RE _IndirectDiffuse _Physical ( const in vec3 irradiance , const in vec3 geometryPosition , const in vec3 geometryNormal , const in vec3 geometryViewDir , const in vec3 geometryClearcoatNormal , const in PhysicalMaterial material , inout ReflectedLight reflectedLight ) {
reflectedLight . indirectDiffuse += irradiance * BRDF _Lambert ( material . diffuseColor ) ;
}
void RE _IndirectSpecular _Physical ( const in vec3 radiance , const in vec3 irradiance , const in vec3 clearcoatRadiance , const in vec3 geometryPosition , const in vec3 geometryNormal , const in vec3 geometryViewDir , const in vec3 geometryClearcoatNormal , const in PhysicalMaterial material , inout ReflectedLight reflectedLight ) {
# ifdef USE _CLEARCOAT
clearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF ( geometryClearcoatNormal , geometryViewDir , material . clearcoatF0 , material . clearcoatF90 , material . clearcoatRoughness ) ;
# endif
# ifdef USE _SHEEN
sheenSpecularIndirect += irradiance * material . sheenColor * IBLSheenBRDF ( geometryNormal , geometryViewDir , material . sheenRoughness ) ;
# endif
vec3 singleScattering = vec3 ( 0.0 ) ;
vec3 multiScattering = vec3 ( 0.0 ) ;
vec3 cosineWeightedIrradiance = irradiance * RECIPROCAL _PI ;
# ifdef USE _IRIDESCENCE
computeMultiscatteringIridescence ( geometryNormal , geometryViewDir , material . specularColor , material . specularF90 , material . iridescence , material . iridescenceFresnel , material . roughness , singleScattering , multiScattering ) ;
# else
computeMultiscattering ( geometryNormal , geometryViewDir , material . specularColor , material . specularF90 , material . roughness , singleScattering , multiScattering ) ;
# endif
vec3 totalScattering = singleScattering + multiScattering ;
vec3 diffuse = material . diffuseColor * ( 1.0 - max ( max ( totalScattering . r , totalScattering . g ) , totalScattering . b ) ) ;
reflectedLight . indirectSpecular += radiance * singleScattering ;
reflectedLight . indirectSpecular += multiScattering * cosineWeightedIrradiance ;
reflectedLight . indirectDiffuse += diffuse * cosineWeightedIrradiance ;
}
# define RE _Direct RE _Direct _Physical
# define RE _Direct _RectArea RE _Direct _RectArea _Physical
# define RE _IndirectDiffuse RE _IndirectDiffuse _Physical
# define RE _IndirectSpecular RE _IndirectSpecular _Physical
float computeSpecularOcclusion ( const in float dotNV , const in float ambientOcclusion , const in float roughness ) {
return saturate ( pow ( dotNV + ambientOcclusion , exp2 ( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion ) ;
2026-01-22 15:23:57 +08:00
} ` ,mg= `
2026-01-22 11:29:51 +08:00
vec3 geometryPosition = - vViewPosition ;
vec3 geometryNormal = normal ;
vec3 geometryViewDir = ( isOrthographic ) ? vec3 ( 0 , 0 , 1 ) : normalize ( vViewPosition ) ;
vec3 geometryClearcoatNormal = vec3 ( 0.0 ) ;
# ifdef USE _CLEARCOAT
geometryClearcoatNormal = clearcoatNormal ;
# endif
# ifdef USE _IRIDESCENCE
float dotNVi = saturate ( dot ( normal , geometryViewDir ) ) ;
if ( material . iridescenceThickness == 0.0 ) {
material . iridescence = 0.0 ;
} else {
material . iridescence = saturate ( material . iridescence ) ;
}
if ( material . iridescence > 0.0 ) {
material . iridescenceFresnel = evalIridescence ( 1.0 , material . iridescenceIOR , dotNVi , material . iridescenceThickness , material . specularColor ) ;
material . iridescenceF0 = Schlick _to _F0 ( material . iridescenceFresnel , 1.0 , dotNVi ) ;
}
# endif
IncidentLight directLight ;
# if ( NUM _POINT _LIGHTS > 0 ) && defined ( RE _Direct )
PointLight pointLight ;
# if defined ( USE _SHADOWMAP ) && NUM _POINT _LIGHT _SHADOWS > 0
PointLightShadow pointLightShadow ;
# endif
# pragma unroll _loop _start
for ( int i = 0 ; i < NUM _POINT _LIGHTS ; i ++ ) {
pointLight = pointLights [ i ] ;
getPointLightInfo ( pointLight , geometryPosition , directLight ) ;
# if defined ( USE _SHADOWMAP ) && ( UNROLLED _LOOP _INDEX < NUM _POINT _LIGHT _SHADOWS )
pointLightShadow = pointLightShadows [ i ] ;
directLight . color *= ( directLight . visible && receiveShadow ) ? getPointShadow ( pointShadowMap [ i ] , pointLightShadow . shadowMapSize , pointLightShadow . shadowIntensity , pointLightShadow . shadowBias , pointLightShadow . shadowRadius , vPointShadowCoord [ i ] , pointLightShadow . shadowCameraNear , pointLightShadow . shadowCameraFar ) : 1.0 ;
# endif
RE _Direct ( directLight , geometryPosition , geometryNormal , geometryViewDir , geometryClearcoatNormal , material , reflectedLight ) ;
}
# pragma unroll _loop _end
# endif
# if ( NUM _SPOT _LIGHTS > 0 ) && defined ( RE _Direct )
SpotLight spotLight ;
vec4 spotColor ;
vec3 spotLightCoord ;
bool inSpotLightMap ;
# if defined ( USE _SHADOWMAP ) && NUM _SPOT _LIGHT _SHADOWS > 0
SpotLightShadow spotLightShadow ;
# endif
# pragma unroll _loop _start
for ( int i = 0 ; i < NUM _SPOT _LIGHTS ; i ++ ) {
spotLight = spotLights [ i ] ;
getSpotLightInfo ( spotLight , geometryPosition , directLight ) ;
# if ( UNROLLED _LOOP _INDEX < NUM _SPOT _LIGHT _SHADOWS _WITH _MAPS )
# define SPOT _LIGHT _MAP _INDEX UNROLLED _LOOP _INDEX
# elif ( UNROLLED _LOOP _INDEX < NUM _SPOT _LIGHT _SHADOWS )
# define SPOT _LIGHT _MAP _INDEX NUM _SPOT _LIGHT _MAPS
# else
# define SPOT _LIGHT _MAP _INDEX ( UNROLLED _LOOP _INDEX - NUM _SPOT _LIGHT _SHADOWS + NUM _SPOT _LIGHT _SHADOWS _WITH _MAPS )
# endif
# if ( SPOT _LIGHT _MAP _INDEX < NUM _SPOT _LIGHT _MAPS )
spotLightCoord = vSpotLightCoord [ i ] . xyz / vSpotLightCoord [ i ] . w ;
inSpotLightMap = all ( lessThan ( abs ( spotLightCoord * 2. - 1. ) , vec3 ( 1.0 ) ) ) ;
spotColor = texture2D ( spotLightMap [ SPOT _LIGHT _MAP _INDEX ] , spotLightCoord . xy ) ;
directLight . color = inSpotLightMap ? directLight . color * spotColor . rgb : directLight . color ;
# endif
# undef SPOT _LIGHT _MAP _INDEX
# if defined ( USE _SHADOWMAP ) && ( UNROLLED _LOOP _INDEX < NUM _SPOT _LIGHT _SHADOWS )
spotLightShadow = spotLightShadows [ i ] ;
directLight . color *= ( directLight . visible && receiveShadow ) ? getShadow ( spotShadowMap [ i ] , spotLightShadow . shadowMapSize , spotLightShadow . shadowIntensity , spotLightShadow . shadowBias , spotLightShadow . shadowRadius , vSpotLightCoord [ i ] ) : 1.0 ;
# endif
RE _Direct ( directLight , geometryPosition , geometryNormal , geometryViewDir , geometryClearcoatNormal , material , reflectedLight ) ;
}
# pragma unroll _loop _end
# endif
# if ( NUM _DIR _LIGHTS > 0 ) && defined ( RE _Direct )
DirectionalLight directionalLight ;
# if defined ( USE _SHADOWMAP ) && NUM _DIR _LIGHT _SHADOWS > 0
DirectionalLightShadow directionalLightShadow ;
# endif
# pragma unroll _loop _start
for ( int i = 0 ; i < NUM _DIR _LIGHTS ; i ++ ) {
directionalLight = directionalLights [ i ] ;
getDirectionalLightInfo ( directionalLight , directLight ) ;
# if defined ( USE _SHADOWMAP ) && ( UNROLLED _LOOP _INDEX < NUM _DIR _LIGHT _SHADOWS )
directionalLightShadow = directionalLightShadows [ i ] ;
directLight . color *= ( directLight . visible && receiveShadow ) ? getShadow ( directionalShadowMap [ i ] , directionalLightShadow . shadowMapSize , directionalLightShadow . shadowIntensity , directionalLightShadow . shadowBias , directionalLightShadow . shadowRadius , vDirectionalShadowCoord [ i ] ) : 1.0 ;
# endif
RE _Direct ( directLight , geometryPosition , geometryNormal , geometryViewDir , geometryClearcoatNormal , material , reflectedLight ) ;
}
# pragma unroll _loop _end
# endif
# if ( NUM _RECT _AREA _LIGHTS > 0 ) && defined ( RE _Direct _RectArea )
RectAreaLight rectAreaLight ;
# pragma unroll _loop _start
for ( int i = 0 ; i < NUM _RECT _AREA _LIGHTS ; i ++ ) {
rectAreaLight = rectAreaLights [ i ] ;
RE _Direct _RectArea ( rectAreaLight , geometryPosition , geometryNormal , geometryViewDir , geometryClearcoatNormal , material , reflectedLight ) ;
}
# pragma unroll _loop _end
# endif
# if defined ( RE _IndirectDiffuse )
vec3 iblIrradiance = vec3 ( 0.0 ) ;
vec3 irradiance = getAmbientLightIrradiance ( ambientLightColor ) ;
# if defined ( USE _LIGHT _PROBES )
irradiance += getLightProbeIrradiance ( lightProbe , geometryNormal ) ;
# endif
# if ( NUM _HEMI _LIGHTS > 0 )
# pragma unroll _loop _start
for ( int i = 0 ; i < NUM _HEMI _LIGHTS ; i ++ ) {
irradiance += getHemisphereLightIrradiance ( hemisphereLights [ i ] , geometryNormal ) ;
}
# pragma unroll _loop _end
# endif
# endif
# if defined ( RE _IndirectSpecular )
vec3 radiance = vec3 ( 0.0 ) ;
vec3 clearcoatRadiance = vec3 ( 0.0 ) ;
2026-01-22 15:23:57 +08:00
# endif ` ,gg= ` # if defined ( RE _IndirectDiffuse )
2026-01-22 11:29:51 +08:00
# ifdef USE _LIGHTMAP
vec4 lightMapTexel = texture2D ( lightMap , vLightMapUv ) ;
vec3 lightMapIrradiance = lightMapTexel . rgb * lightMapIntensity ;
irradiance += lightMapIrradiance ;
# endif
# if defined ( USE _ENVMAP ) && defined ( STANDARD ) && defined ( ENVMAP _TYPE _CUBE _UV )
iblIrradiance += getIBLIrradiance ( geometryNormal ) ;
# endif
# endif
# if defined ( USE _ENVMAP ) && defined ( RE _IndirectSpecular )
# ifdef USE _ANISOTROPY
radiance += getIBLAnisotropyRadiance ( geometryViewDir , geometryNormal , material . roughness , material . anisotropyB , material . anisotropy ) ;
# else
radiance += getIBLRadiance ( geometryViewDir , geometryNormal , material . roughness ) ;
# endif
# ifdef USE _CLEARCOAT
clearcoatRadiance += getIBLRadiance ( geometryViewDir , geometryClearcoatNormal , material . clearcoatRoughness ) ;
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,xg= ` # if defined ( RE _IndirectDiffuse )
2026-01-22 11:29:51 +08:00
RE _IndirectDiffuse ( irradiance , geometryPosition , geometryNormal , geometryViewDir , geometryClearcoatNormal , material , reflectedLight ) ;
# endif
# if defined ( RE _IndirectSpecular )
RE _IndirectSpecular ( radiance , iblIrradiance , clearcoatRadiance , geometryPosition , geometryNormal , geometryViewDir , geometryClearcoatNormal , material , reflectedLight ) ;
2026-01-22 15:23:57 +08:00
# endif ` ,vg= ` # if defined ( USE _LOGARITHMIC _DEPTH _BUFFER )
2026-01-22 11:29:51 +08:00
gl _FragDepth = vIsPerspective == 0.0 ? gl _FragCoord . z : log2 ( vFragDepth ) * logDepthBufFC * 0.5 ;
2026-01-22 15:23:57 +08:00
# endif ` ,bg= ` # if defined ( USE _LOGARITHMIC _DEPTH _BUFFER )
2026-01-22 11:29:51 +08:00
uniform float logDepthBufFC ;
varying float vFragDepth ;
varying float vIsPerspective ;
2026-01-22 15:23:57 +08:00
# endif ` ,_g= ` # ifdef USE _LOGARITHMIC _DEPTH _BUFFER
2026-01-22 11:29:51 +08:00
varying float vFragDepth ;
varying float vIsPerspective ;
2026-01-22 15:23:57 +08:00
# endif ` ,yg= ` # ifdef USE _LOGARITHMIC _DEPTH _BUFFER
2026-01-22 11:29:51 +08:00
vFragDepth = 1.0 + gl _Position . w ;
vIsPerspective = float ( isPerspectiveMatrix ( projectionMatrix ) ) ;
2026-01-22 15:23:57 +08:00
# endif ` ,Mg= ` # ifdef USE _MAP
2026-01-22 11:29:51 +08:00
vec4 sampledDiffuseColor = texture2D ( map , vMapUv ) ;
# ifdef DECODE _VIDEO _TEXTURE
sampledDiffuseColor = sRGBTransferEOTF ( sampledDiffuseColor ) ;
# endif
diffuseColor *= sampledDiffuseColor ;
2026-01-22 15:23:57 +08:00
# endif ` ,Sg= ` # ifdef USE _MAP
2026-01-22 11:29:51 +08:00
uniform sampler2D map ;
2026-01-22 15:23:57 +08:00
# endif ` ,wg= ` # if defined ( USE _MAP ) || defined ( USE _ALPHAMAP )
2026-01-22 11:29:51 +08:00
# if defined ( USE _POINTS _UV )
vec2 uv = vUv ;
# else
vec2 uv = ( uvTransform * vec3 ( gl _PointCoord . x , 1.0 - gl _PointCoord . y , 1 ) ) . xy ;
# endif
# endif
# ifdef USE _MAP
diffuseColor *= texture2D ( map , uv ) ;
# endif
# ifdef USE _ALPHAMAP
diffuseColor . a *= texture2D ( alphaMap , uv ) . g ;
2026-01-22 15:23:57 +08:00
# endif ` ,Eg= ` # if defined ( USE _POINTS _UV )
2026-01-22 11:29:51 +08:00
varying vec2 vUv ;
# else
# if defined ( USE _MAP ) || defined ( USE _ALPHAMAP )
uniform mat3 uvTransform ;
# endif
# endif
# ifdef USE _MAP
uniform sampler2D map ;
# endif
# ifdef USE _ALPHAMAP
uniform sampler2D alphaMap ;
2026-01-22 15:23:57 +08:00
# endif ` ,Tg= ` float metalnessFactor = metalness ;
2026-01-22 11:29:51 +08:00
# ifdef USE _METALNESSMAP
vec4 texelMetalness = texture2D ( metalnessMap , vMetalnessMapUv ) ;
metalnessFactor *= texelMetalness . b ;
2026-01-22 15:23:57 +08:00
# endif ` ,Cg= ` # ifdef USE _METALNESSMAP
2026-01-22 11:29:51 +08:00
uniform sampler2D metalnessMap ;
2026-01-22 15:23:57 +08:00
# endif ` ,Ag= ` # ifdef USE _INSTANCING _MORPH
2026-01-22 11:29:51 +08:00
float morphTargetInfluences [ MORPHTARGETS _COUNT ] ;
float morphTargetBaseInfluence = texelFetch ( morphTexture , ivec2 ( 0 , gl _InstanceID ) , 0 ) . r ;
for ( int i = 0 ; i < MORPHTARGETS _COUNT ; i ++ ) {
morphTargetInfluences [ i ] = texelFetch ( morphTexture , ivec2 ( i + 1 , gl _InstanceID ) , 0 ) . r ;
}
2026-01-22 15:23:57 +08:00
# endif ` ,Pg= ` # if defined ( USE _MORPHCOLORS )
2026-01-22 11:29:51 +08:00
vColor *= morphTargetBaseInfluence ;
for ( int i = 0 ; i < MORPHTARGETS _COUNT ; i ++ ) {
# if defined ( USE _COLOR _ALPHA )
if ( morphTargetInfluences [ i ] != 0.0 ) vColor += getMorph ( gl _VertexID , i , 2 ) * morphTargetInfluences [ i ] ;
# elif defined ( USE _COLOR )
if ( morphTargetInfluences [ i ] != 0.0 ) vColor += getMorph ( gl _VertexID , i , 2 ) . rgb * morphTargetInfluences [ i ] ;
# endif
}
2026-01-22 15:23:57 +08:00
# endif ` ,Rg= ` # ifdef USE _MORPHNORMALS
2026-01-22 11:29:51 +08:00
objectNormal *= morphTargetBaseInfluence ;
for ( int i = 0 ; i < MORPHTARGETS _COUNT ; i ++ ) {
if ( morphTargetInfluences [ i ] != 0.0 ) objectNormal += getMorph ( gl _VertexID , i , 1 ) . xyz * morphTargetInfluences [ i ] ;
}
2026-01-22 15:23:57 +08:00
# endif ` ,Lg= ` # ifdef USE _MORPHTARGETS
2026-01-22 11:29:51 +08:00
# ifndef USE _INSTANCING _MORPH
uniform float morphTargetBaseInfluence ;
uniform float morphTargetInfluences [ MORPHTARGETS _COUNT ] ;
# endif
uniform sampler2DArray morphTargetsTexture ;
uniform ivec2 morphTargetsTextureSize ;
vec4 getMorph ( const in int vertexIndex , const in int morphTargetIndex , const in int offset ) {
int texelIndex = vertexIndex * MORPHTARGETS _TEXTURE _STRIDE + offset ;
int y = texelIndex / morphTargetsTextureSize . x ;
int x = texelIndex - y * morphTargetsTextureSize . x ;
ivec3 morphUV = ivec3 ( x , y , morphTargetIndex ) ;
return texelFetch ( morphTargetsTexture , morphUV , 0 ) ;
}
2026-01-22 15:23:57 +08:00
# endif ` ,Dg= ` # ifdef USE _MORPHTARGETS
2026-01-22 11:29:51 +08:00
transformed *= morphTargetBaseInfluence ;
for ( int i = 0 ; i < MORPHTARGETS _COUNT ; i ++ ) {
if ( morphTargetInfluences [ i ] != 0.0 ) transformed += getMorph ( gl _VertexID , i , 0 ) . xyz * morphTargetInfluences [ i ] ;
}
2026-01-22 15:23:57 +08:00
# endif ` ,Ig= ` float faceDirection = gl _FrontFacing ? 1.0 : - 1.0 ;
2026-01-22 11:29:51 +08:00
# ifdef FLAT _SHADED
vec3 fdx = dFdx ( vViewPosition ) ;
vec3 fdy = dFdy ( vViewPosition ) ;
vec3 normal = normalize ( cross ( fdx , fdy ) ) ;
# else
vec3 normal = normalize ( vNormal ) ;
# ifdef DOUBLE _SIDED
normal *= faceDirection ;
# endif
# endif
# if defined ( USE _NORMALMAP _TANGENTSPACE ) || defined ( USE _CLEARCOAT _NORMALMAP ) || defined ( USE _ANISOTROPY )
# ifdef USE _TANGENT
mat3 tbn = mat3 ( normalize ( vTangent ) , normalize ( vBitangent ) , normal ) ;
# else
mat3 tbn = getTangentFrame ( - vViewPosition , normal ,
# if defined ( USE _NORMALMAP )
vNormalMapUv
# elif defined ( USE _CLEARCOAT _NORMALMAP )
vClearcoatNormalMapUv
# else
vUv
# endif
) ;
# endif
# if defined ( DOUBLE _SIDED ) && ! defined ( FLAT _SHADED )
tbn [ 0 ] *= faceDirection ;
tbn [ 1 ] *= faceDirection ;
# endif
# endif
# ifdef USE _CLEARCOAT _NORMALMAP
# ifdef USE _TANGENT
mat3 tbn2 = mat3 ( normalize ( vTangent ) , normalize ( vBitangent ) , normal ) ;
# else
mat3 tbn2 = getTangentFrame ( - vViewPosition , normal , vClearcoatNormalMapUv ) ;
# endif
# if defined ( DOUBLE _SIDED ) && ! defined ( FLAT _SHADED )
tbn2 [ 0 ] *= faceDirection ;
tbn2 [ 1 ] *= faceDirection ;
# endif
# endif
2026-01-22 15:23:57 +08:00
vec3 nonPerturbedNormal = normal ; ` ,Ng= ` # ifdef USE _NORMALMAP _OBJECTSPACE
2026-01-22 11:29:51 +08:00
normal = texture2D ( normalMap , vNormalMapUv ) . xyz * 2.0 - 1.0 ;
# ifdef FLIP _SIDED
normal = - normal ;
# endif
# ifdef DOUBLE _SIDED
normal = normal * faceDirection ;
# endif
normal = normalize ( normalMatrix * normal ) ;
# elif defined ( USE _NORMALMAP _TANGENTSPACE )
vec3 mapN = texture2D ( normalMap , vNormalMapUv ) . xyz * 2.0 - 1.0 ;
mapN . xy *= normalScale ;
normal = normalize ( tbn * mapN ) ;
# elif defined ( USE _BUMPMAP )
normal = perturbNormalArb ( - vViewPosition , normal , dHdxy _fwd ( ) , faceDirection ) ;
2026-01-22 15:23:57 +08:00
# endif ` ,kg= ` # ifndef FLAT _SHADED
2026-01-22 11:29:51 +08:00
varying vec3 vNormal ;
# ifdef USE _TANGENT
varying vec3 vTangent ;
varying vec3 vBitangent ;
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,Ug= ` # ifndef FLAT _SHADED
2026-01-22 11:29:51 +08:00
varying vec3 vNormal ;
# ifdef USE _TANGENT
varying vec3 vTangent ;
varying vec3 vBitangent ;
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,Bg= ` # ifndef FLAT _SHADED
2026-01-22 11:29:51 +08:00
vNormal = normalize ( transformedNormal ) ;
# ifdef USE _TANGENT
vTangent = normalize ( transformedTangent ) ;
vBitangent = normalize ( cross ( vNormal , vTangent ) * tangent . w ) ;
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,Og= ` # ifdef USE _NORMALMAP
2026-01-22 11:29:51 +08:00
uniform sampler2D normalMap ;
uniform vec2 normalScale ;
# endif
# ifdef USE _NORMALMAP _OBJECTSPACE
uniform mat3 normalMatrix ;
# endif
# if ! defined ( USE _TANGENT ) && ( defined ( USE _NORMALMAP _TANGENTSPACE ) || defined ( USE _CLEARCOAT _NORMALMAP ) || defined ( USE _ANISOTROPY ) )
mat3 getTangentFrame ( vec3 eye _pos , vec3 surf _norm , vec2 uv ) {
vec3 q0 = dFdx ( eye _pos . xyz ) ;
vec3 q1 = dFdy ( eye _pos . xyz ) ;
vec2 st0 = dFdx ( uv . st ) ;
vec2 st1 = dFdy ( uv . st ) ;
vec3 N = surf _norm ;
vec3 q1perp = cross ( q1 , N ) ;
vec3 q0perp = cross ( N , q0 ) ;
vec3 T = q1perp * st0 . x + q0perp * st1 . x ;
vec3 B = q1perp * st0 . y + q0perp * st1 . y ;
float det = max ( dot ( T , T ) , dot ( B , B ) ) ;
float scale = ( det == 0.0 ) ? 0.0 : inversesqrt ( det ) ;
return mat3 ( T * scale , B * scale , N ) ;
}
2026-01-22 15:23:57 +08:00
# endif ` ,Fg= ` # ifdef USE _CLEARCOAT
2026-01-22 11:29:51 +08:00
vec3 clearcoatNormal = nonPerturbedNormal ;
2026-01-22 15:23:57 +08:00
# endif ` ,zg= ` # ifdef USE _CLEARCOAT _NORMALMAP
2026-01-22 11:29:51 +08:00
vec3 clearcoatMapN = texture2D ( clearcoatNormalMap , vClearcoatNormalMapUv ) . xyz * 2.0 - 1.0 ;
clearcoatMapN . xy *= clearcoatNormalScale ;
clearcoatNormal = normalize ( tbn2 * clearcoatMapN ) ;
2026-01-22 15:23:57 +08:00
# endif ` ,Hg= ` # ifdef USE _CLEARCOATMAP
2026-01-22 11:29:51 +08:00
uniform sampler2D clearcoatMap ;
# endif
# ifdef USE _CLEARCOAT _NORMALMAP
uniform sampler2D clearcoatNormalMap ;
uniform vec2 clearcoatNormalScale ;
# endif
# ifdef USE _CLEARCOAT _ROUGHNESSMAP
uniform sampler2D clearcoatRoughnessMap ;
2026-01-22 15:23:57 +08:00
# endif ` ,Vg= ` # ifdef USE _IRIDESCENCEMAP
2026-01-22 11:29:51 +08:00
uniform sampler2D iridescenceMap ;
# endif
# ifdef USE _IRIDESCENCE _THICKNESSMAP
uniform sampler2D iridescenceThicknessMap ;
2026-01-22 15:23:57 +08:00
# endif ` ,Gg= ` # ifdef OPAQUE
2026-01-22 11:29:51 +08:00
diffuseColor . a = 1.0 ;
# endif
# ifdef USE _TRANSMISSION
diffuseColor . a *= material . transmissionAlpha ;
# endif
2026-01-22 15:23:57 +08:00
gl _FragColor = vec4 ( outgoingLight , diffuseColor . a ) ; ` ,Wg= ` vec3 packNormalToRGB ( const in vec3 normal ) {
2026-01-22 11:29:51 +08:00
return normalize ( normal ) * 0.5 + 0.5 ;
}
vec3 unpackRGBToNormal ( const in vec3 rgb ) {
return 2.0 * rgb . xyz - 1.0 ;
}
const float PackUpscale = 256. / 255. ; const float UnpackDownscale = 255. / 256. ; const float ShiftRight8 = 1. / 256. ;
const float Inv255 = 1. / 255. ;
const vec4 PackFactors = vec4 ( 1.0 , 256.0 , 256.0 * 256.0 , 256.0 * 256.0 * 256.0 ) ;
const vec2 UnpackFactors2 = vec2 ( UnpackDownscale , 1.0 / PackFactors . g ) ;
const vec3 UnpackFactors3 = vec3 ( UnpackDownscale / PackFactors . rg , 1.0 / PackFactors . b ) ;
const vec4 UnpackFactors4 = vec4 ( UnpackDownscale / PackFactors . rgb , 1.0 / PackFactors . a ) ;
vec4 packDepthToRGBA ( const in float v ) {
if ( v <= 0.0 )
return vec4 ( 0. , 0. , 0. , 0. ) ;
if ( v >= 1.0 )
return vec4 ( 1. , 1. , 1. , 1. ) ;
float vuf ;
float af = modf ( v * PackFactors . a , vuf ) ;
float bf = modf ( vuf * ShiftRight8 , vuf ) ;
float gf = modf ( vuf * ShiftRight8 , vuf ) ;
return vec4 ( vuf * Inv255 , gf * PackUpscale , bf * PackUpscale , af ) ;
}
vec3 packDepthToRGB ( const in float v ) {
if ( v <= 0.0 )
return vec3 ( 0. , 0. , 0. ) ;
if ( v >= 1.0 )
return vec3 ( 1. , 1. , 1. ) ;
float vuf ;
float bf = modf ( v * PackFactors . b , vuf ) ;
float gf = modf ( vuf * ShiftRight8 , vuf ) ;
return vec3 ( vuf * Inv255 , gf * PackUpscale , bf ) ;
}
vec2 packDepthToRG ( const in float v ) {
if ( v <= 0.0 )
return vec2 ( 0. , 0. ) ;
if ( v >= 1.0 )
return vec2 ( 1. , 1. ) ;
float vuf ;
float gf = modf ( v * 256. , vuf ) ;
return vec2 ( vuf * Inv255 , gf ) ;
}
float unpackRGBAToDepth ( const in vec4 v ) {
return dot ( v , UnpackFactors4 ) ;
}
float unpackRGBToDepth ( const in vec3 v ) {
return dot ( v , UnpackFactors3 ) ;
}
float unpackRGToDepth ( const in vec2 v ) {
return v . r * UnpackFactors2 . r + v . g * UnpackFactors2 . g ;
}
vec4 pack2HalfToRGBA ( const in vec2 v ) {
vec4 r = vec4 ( v . x , fract ( v . x * 255.0 ) , v . y , fract ( v . y * 255.0 ) ) ;
return vec4 ( r . x - r . y / 255.0 , r . y , r . z - r . w / 255.0 , r . w ) ;
}
vec2 unpackRGBATo2Half ( const in vec4 v ) {
return vec2 ( v . x + ( v . y / 255.0 ) , v . z + ( v . w / 255.0 ) ) ;
}
float viewZToOrthographicDepth ( const in float viewZ , const in float near , const in float far ) {
return ( viewZ + near ) / ( near - far ) ;
}
float orthographicDepthToViewZ ( const in float depth , const in float near , const in float far ) {
return depth * ( near - far ) - near ;
}
float viewZToPerspectiveDepth ( const in float viewZ , const in float near , const in float far ) {
return ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ ) ;
}
float perspectiveDepthToViewZ ( const in float depth , const in float near , const in float far ) {
return ( near * far ) / ( ( far - near ) * depth - far ) ;
2026-01-22 15:23:57 +08:00
} ` ,Xg= ` # ifdef PREMULTIPLIED _ALPHA
2026-01-22 11:29:51 +08:00
gl _FragColor . rgb *= gl _FragColor . a ;
2026-01-22 15:23:57 +08:00
# endif ` ,jg= ` vec4 mvPosition = vec4 ( transformed , 1.0 ) ;
2026-01-22 11:29:51 +08:00
# ifdef USE _BATCHING
mvPosition = batchingMatrix * mvPosition ;
# endif
# ifdef USE _INSTANCING
mvPosition = instanceMatrix * mvPosition ;
# endif
mvPosition = modelViewMatrix * mvPosition ;
2026-01-22 15:23:57 +08:00
gl _Position = projectionMatrix * mvPosition ; ` ,Zg= ` # ifdef DITHERING
2026-01-22 11:29:51 +08:00
gl _FragColor . rgb = dithering ( gl _FragColor . rgb ) ;
2026-01-22 15:23:57 +08:00
# endif ` ,qg= ` # ifdef DITHERING
2026-01-22 11:29:51 +08:00
vec3 dithering ( vec3 color ) {
float grid _position = rand ( gl _FragCoord . xy ) ;
vec3 dither _shift _RGB = vec3 ( 0.25 / 255.0 , - 0.25 / 255.0 , 0.25 / 255.0 ) ;
dither _shift _RGB = mix ( 2.0 * dither _shift _RGB , - 2.0 * dither _shift _RGB , grid _position ) ;
return color + dither _shift _RGB ;
}
2026-01-22 15:23:57 +08:00
# endif ` ,Yg= ` float roughnessFactor = roughness ;
2026-01-22 11:29:51 +08:00
# ifdef USE _ROUGHNESSMAP
vec4 texelRoughness = texture2D ( roughnessMap , vRoughnessMapUv ) ;
roughnessFactor *= texelRoughness . g ;
2026-01-22 15:23:57 +08:00
# endif ` ,Kg= ` # ifdef USE _ROUGHNESSMAP
2026-01-22 11:29:51 +08:00
uniform sampler2D roughnessMap ;
2026-01-22 15:23:57 +08:00
# endif ` , $ g= ` # if NUM _SPOT _LIGHT _COORDS > 0
2026-01-22 11:29:51 +08:00
varying vec4 vSpotLightCoord [ NUM _SPOT _LIGHT _COORDS ] ;
# endif
# if NUM _SPOT _LIGHT _MAPS > 0
uniform sampler2D spotLightMap [ NUM _SPOT _LIGHT _MAPS ] ;
# endif
# ifdef USE _SHADOWMAP
# if NUM _DIR _LIGHT _SHADOWS > 0
uniform sampler2D directionalShadowMap [ NUM _DIR _LIGHT _SHADOWS ] ;
varying vec4 vDirectionalShadowCoord [ NUM _DIR _LIGHT _SHADOWS ] ;
struct DirectionalLightShadow {
float shadowIntensity ;
float shadowBias ;
float shadowNormalBias ;
float shadowRadius ;
vec2 shadowMapSize ;
} ;
uniform DirectionalLightShadow directionalLightShadows [ NUM _DIR _LIGHT _SHADOWS ] ;
# endif
# if NUM _SPOT _LIGHT _SHADOWS > 0
uniform sampler2D spotShadowMap [ NUM _SPOT _LIGHT _SHADOWS ] ;
struct SpotLightShadow {
float shadowIntensity ;
float shadowBias ;
float shadowNormalBias ;
float shadowRadius ;
vec2 shadowMapSize ;
} ;
uniform SpotLightShadow spotLightShadows [ NUM _SPOT _LIGHT _SHADOWS ] ;
# endif
# if NUM _POINT _LIGHT _SHADOWS > 0
uniform sampler2D pointShadowMap [ NUM _POINT _LIGHT _SHADOWS ] ;
varying vec4 vPointShadowCoord [ NUM _POINT _LIGHT _SHADOWS ] ;
struct PointLightShadow {
float shadowIntensity ;
float shadowBias ;
float shadowNormalBias ;
float shadowRadius ;
vec2 shadowMapSize ;
float shadowCameraNear ;
float shadowCameraFar ;
} ;
uniform PointLightShadow pointLightShadows [ NUM _POINT _LIGHT _SHADOWS ] ;
# endif
float texture2DCompare ( sampler2D depths , vec2 uv , float compare ) {
float depth = unpackRGBAToDepth ( texture2D ( depths , uv ) ) ;
# ifdef USE _REVERSED _DEPTH _BUFFER
return step ( depth , compare ) ;
# else
return step ( compare , depth ) ;
# endif
}
vec2 texture2DDistribution ( sampler2D shadow , vec2 uv ) {
return unpackRGBATo2Half ( texture2D ( shadow , uv ) ) ;
}
float VSMShadow ( sampler2D shadow , vec2 uv , float compare ) {
float occlusion = 1.0 ;
vec2 distribution = texture2DDistribution ( shadow , uv ) ;
# ifdef USE _REVERSED _DEPTH _BUFFER
float hard _shadow = step ( distribution . x , compare ) ;
# else
float hard _shadow = step ( compare , distribution . x ) ;
# endif
if ( hard _shadow != 1.0 ) {
float distance = compare - distribution . x ;
float variance = max ( 0.00000 , distribution . y * distribution . y ) ;
float softness _probability = variance / ( variance + distance * distance ) ; softness _probability = clamp ( ( softness _probability - 0.3 ) / ( 0.95 - 0.3 ) , 0.0 , 1.0 ) ; occlusion = clamp ( max ( hard _shadow , softness _probability ) , 0.0 , 1.0 ) ;
}
return occlusion ;
}
float getShadow ( sampler2D shadowMap , vec2 shadowMapSize , float shadowIntensity , float shadowBias , float shadowRadius , vec4 shadowCoord ) {
float shadow = 1.0 ;
shadowCoord . xyz /= shadowCoord . w ;
shadowCoord . z += shadowBias ;
bool inFrustum = shadowCoord . x >= 0.0 && shadowCoord . x <= 1.0 && shadowCoord . y >= 0.0 && shadowCoord . y <= 1.0 ;
bool frustumTest = inFrustum && shadowCoord . z <= 1.0 ;
if ( frustumTest ) {
# if defined ( SHADOWMAP _TYPE _PCF )
vec2 texelSize = vec2 ( 1.0 ) / shadowMapSize ;
float dx0 = - texelSize . x * shadowRadius ;
float dy0 = - texelSize . y * shadowRadius ;
float dx1 = + texelSize . x * shadowRadius ;
float dy1 = + texelSize . y * shadowRadius ;
float dx2 = dx0 / 2.0 ;
float dy2 = dy0 / 2.0 ;
float dx3 = dx1 / 2.0 ;
float dy3 = dy1 / 2.0 ;
shadow = (
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( dx0 , dy0 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( 0.0 , dy0 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( dx1 , dy0 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( dx2 , dy2 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( 0.0 , dy2 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( dx3 , dy2 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( dx0 , 0.0 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( dx2 , 0.0 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( dx3 , 0.0 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( dx1 , 0.0 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( dx2 , dy3 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( 0.0 , dy3 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( dx3 , dy3 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( dx0 , dy1 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( 0.0 , dy1 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , shadowCoord . xy + vec2 ( dx1 , dy1 ) , shadowCoord . z )
) * ( 1.0 / 17.0 ) ;
# elif defined ( SHADOWMAP _TYPE _PCF _SOFT )
vec2 texelSize = vec2 ( 1.0 ) / shadowMapSize ;
float dx = texelSize . x ;
float dy = texelSize . y ;
vec2 uv = shadowCoord . xy ;
vec2 f = fract ( uv * shadowMapSize + 0.5 ) ;
uv -= f * texelSize ;
shadow = (
texture2DCompare ( shadowMap , uv , shadowCoord . z ) +
texture2DCompare ( shadowMap , uv + vec2 ( dx , 0.0 ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , uv + vec2 ( 0.0 , dy ) , shadowCoord . z ) +
texture2DCompare ( shadowMap , uv + texelSize , shadowCoord . z ) +
mix ( texture2DCompare ( shadowMap , uv + vec2 ( - dx , 0.0 ) , shadowCoord . z ) ,
texture2DCompare ( shadowMap , uv + vec2 ( 2.0 * dx , 0.0 ) , shadowCoord . z ) ,
f . x ) +
mix ( texture2DCompare ( shadowMap , uv + vec2 ( - dx , dy ) , shadowCoord . z ) ,
texture2DCompare ( shadowMap , uv + vec2 ( 2.0 * dx , dy ) , shadowCoord . z ) ,
f . x ) +
mix ( texture2DCompare ( shadowMap , uv + vec2 ( 0.0 , - dy ) , shadowCoord . z ) ,
texture2DCompare ( shadowMap , uv + vec2 ( 0.0 , 2.0 * dy ) , shadowCoord . z ) ,
f . y ) +
mix ( texture2DCompare ( shadowMap , uv + vec2 ( dx , - dy ) , shadowCoord . z ) ,
texture2DCompare ( shadowMap , uv + vec2 ( dx , 2.0 * dy ) , shadowCoord . z ) ,
f . y ) +
mix ( mix ( texture2DCompare ( shadowMap , uv + vec2 ( - dx , - dy ) , shadowCoord . z ) ,
texture2DCompare ( shadowMap , uv + vec2 ( 2.0 * dx , - dy ) , shadowCoord . z ) ,
f . x ) ,
mix ( texture2DCompare ( shadowMap , uv + vec2 ( - dx , 2.0 * dy ) , shadowCoord . z ) ,
texture2DCompare ( shadowMap , uv + vec2 ( 2.0 * dx , 2.0 * dy ) , shadowCoord . z ) ,
f . x ) ,
f . y )
) * ( 1.0 / 9.0 ) ;
# elif defined ( SHADOWMAP _TYPE _VSM )
shadow = VSMShadow ( shadowMap , shadowCoord . xy , shadowCoord . z ) ;
# else
shadow = texture2DCompare ( shadowMap , shadowCoord . xy , shadowCoord . z ) ;
# endif
}
return mix ( 1.0 , shadow , shadowIntensity ) ;
}
vec2 cubeToUV ( vec3 v , float texelSizeY ) {
vec3 absV = abs ( v ) ;
float scaleToCube = 1.0 / max ( absV . x , max ( absV . y , absV . z ) ) ;
absV *= scaleToCube ;
v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY ) ;
vec2 planar = v . xy ;
float almostATexel = 1.5 * texelSizeY ;
float almostOne = 1.0 - almostATexel ;
if ( absV . z >= almostOne ) {
if ( v . z > 0.0 )
planar . x = 4.0 - v . x ;
} else if ( absV . x >= almostOne ) {
float signX = sign ( v . x ) ;
planar . x = v . z * signX + 2.0 * signX ;
} else if ( absV . y >= almostOne ) {
float signY = sign ( v . y ) ;
planar . x = v . x + 2.0 * signY + 2.0 ;
planar . y = v . z * signY - 2.0 ;
}
return vec2 ( 0.125 , 0.25 ) * planar + vec2 ( 0.375 , 0.75 ) ;
}
float getPointShadow ( sampler2D shadowMap , vec2 shadowMapSize , float shadowIntensity , float shadowBias , float shadowRadius , vec4 shadowCoord , float shadowCameraNear , float shadowCameraFar ) {
float shadow = 1.0 ;
vec3 lightToPosition = shadowCoord . xyz ;
float lightToPositionLength = length ( lightToPosition ) ;
if ( lightToPositionLength - shadowCameraFar <= 0.0 && lightToPositionLength - shadowCameraNear >= 0.0 ) {
float dp = ( lightToPositionLength - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear ) ; dp += shadowBias ;
vec3 bd3D = normalize ( lightToPosition ) ;
vec2 texelSize = vec2 ( 1.0 ) / ( shadowMapSize * vec2 ( 4.0 , 2.0 ) ) ;
# if defined ( SHADOWMAP _TYPE _PCF ) || defined ( SHADOWMAP _TYPE _PCF _SOFT ) || defined ( SHADOWMAP _TYPE _VSM )
vec2 offset = vec2 ( - 1 , 1 ) * shadowRadius * texelSize . y ;
shadow = (
texture2DCompare ( shadowMap , cubeToUV ( bd3D + offset . xyy , texelSize . y ) , dp ) +
texture2DCompare ( shadowMap , cubeToUV ( bd3D + offset . yyy , texelSize . y ) , dp ) +
texture2DCompare ( shadowMap , cubeToUV ( bd3D + offset . xyx , texelSize . y ) , dp ) +
texture2DCompare ( shadowMap , cubeToUV ( bd3D + offset . yyx , texelSize . y ) , dp ) +
texture2DCompare ( shadowMap , cubeToUV ( bd3D , texelSize . y ) , dp ) +
texture2DCompare ( shadowMap , cubeToUV ( bd3D + offset . xxy , texelSize . y ) , dp ) +
texture2DCompare ( shadowMap , cubeToUV ( bd3D + offset . yxy , texelSize . y ) , dp ) +
texture2DCompare ( shadowMap , cubeToUV ( bd3D + offset . xxx , texelSize . y ) , dp ) +
texture2DCompare ( shadowMap , cubeToUV ( bd3D + offset . yxx , texelSize . y ) , dp )
) * ( 1.0 / 9.0 ) ;
# else
shadow = texture2DCompare ( shadowMap , cubeToUV ( bd3D , texelSize . y ) , dp ) ;
# endif
}
return mix ( 1.0 , shadow , shadowIntensity ) ;
}
2026-01-22 15:23:57 +08:00
# endif ` ,Jg= ` # if NUM _SPOT _LIGHT _COORDS > 0
2026-01-22 11:29:51 +08:00
uniform mat4 spotLightMatrix [ NUM _SPOT _LIGHT _COORDS ] ;
varying vec4 vSpotLightCoord [ NUM _SPOT _LIGHT _COORDS ] ;
# endif
# ifdef USE _SHADOWMAP
# if NUM _DIR _LIGHT _SHADOWS > 0
uniform mat4 directionalShadowMatrix [ NUM _DIR _LIGHT _SHADOWS ] ;
varying vec4 vDirectionalShadowCoord [ NUM _DIR _LIGHT _SHADOWS ] ;
struct DirectionalLightShadow {
float shadowIntensity ;
float shadowBias ;
float shadowNormalBias ;
float shadowRadius ;
vec2 shadowMapSize ;
} ;
uniform DirectionalLightShadow directionalLightShadows [ NUM _DIR _LIGHT _SHADOWS ] ;
# endif
# if NUM _SPOT _LIGHT _SHADOWS > 0
struct SpotLightShadow {
float shadowIntensity ;
float shadowBias ;
float shadowNormalBias ;
float shadowRadius ;
vec2 shadowMapSize ;
} ;
uniform SpotLightShadow spotLightShadows [ NUM _SPOT _LIGHT _SHADOWS ] ;
# endif
# if NUM _POINT _LIGHT _SHADOWS > 0
uniform mat4 pointShadowMatrix [ NUM _POINT _LIGHT _SHADOWS ] ;
varying vec4 vPointShadowCoord [ NUM _POINT _LIGHT _SHADOWS ] ;
struct PointLightShadow {
float shadowIntensity ;
float shadowBias ;
float shadowNormalBias ;
float shadowRadius ;
vec2 shadowMapSize ;
float shadowCameraNear ;
float shadowCameraFar ;
} ;
uniform PointLightShadow pointLightShadows [ NUM _POINT _LIGHT _SHADOWS ] ;
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,Qg= ` # if ( defined ( USE _SHADOWMAP ) && ( NUM _DIR _LIGHT _SHADOWS > 0 || NUM _POINT _LIGHT _SHADOWS > 0 ) ) || ( NUM _SPOT _LIGHT _COORDS > 0 )
2026-01-22 11:29:51 +08:00
vec3 shadowWorldNormal = inverseTransformDirection ( transformedNormal , viewMatrix ) ;
vec4 shadowWorldPosition ;
# endif
# if defined ( USE _SHADOWMAP )
# if NUM _DIR _LIGHT _SHADOWS > 0
# pragma unroll _loop _start
for ( int i = 0 ; i < NUM _DIR _LIGHT _SHADOWS ; i ++ ) {
shadowWorldPosition = worldPosition + vec4 ( shadowWorldNormal * directionalLightShadows [ i ] . shadowNormalBias , 0 ) ;
vDirectionalShadowCoord [ i ] = directionalShadowMatrix [ i ] * shadowWorldPosition ;
}
# pragma unroll _loop _end
# endif
# if NUM _POINT _LIGHT _SHADOWS > 0
# pragma unroll _loop _start
for ( int i = 0 ; i < NUM _POINT _LIGHT _SHADOWS ; i ++ ) {
shadowWorldPosition = worldPosition + vec4 ( shadowWorldNormal * pointLightShadows [ i ] . shadowNormalBias , 0 ) ;
vPointShadowCoord [ i ] = pointShadowMatrix [ i ] * shadowWorldPosition ;
}
# pragma unroll _loop _end
# endif
# endif
# if NUM _SPOT _LIGHT _COORDS > 0
# pragma unroll _loop _start
for ( int i = 0 ; i < NUM _SPOT _LIGHT _COORDS ; i ++ ) {
shadowWorldPosition = worldPosition ;
# if ( defined ( USE _SHADOWMAP ) && UNROLLED _LOOP _INDEX < NUM _SPOT _LIGHT _SHADOWS )
shadowWorldPosition . xyz += shadowWorldNormal * spotLightShadows [ i ] . shadowNormalBias ;
# endif
vSpotLightCoord [ i ] = spotLightMatrix [ i ] * shadowWorldPosition ;
}
# pragma unroll _loop _end
2026-01-22 15:23:57 +08:00
# endif ` ,ex= ` float getShadowMask ( ) {
2026-01-22 11:29:51 +08:00
float shadow = 1.0 ;
# ifdef USE _SHADOWMAP
# if NUM _DIR _LIGHT _SHADOWS > 0
DirectionalLightShadow directionalLight ;
# pragma unroll _loop _start
for ( int i = 0 ; i < NUM _DIR _LIGHT _SHADOWS ; i ++ ) {
directionalLight = directionalLightShadows [ i ] ;
shadow *= receiveShadow ? getShadow ( directionalShadowMap [ i ] , directionalLight . shadowMapSize , directionalLight . shadowIntensity , directionalLight . shadowBias , directionalLight . shadowRadius , vDirectionalShadowCoord [ i ] ) : 1.0 ;
}
# pragma unroll _loop _end
# endif
# if NUM _SPOT _LIGHT _SHADOWS > 0
SpotLightShadow spotLight ;
# pragma unroll _loop _start
for ( int i = 0 ; i < NUM _SPOT _LIGHT _SHADOWS ; i ++ ) {
spotLight = spotLightShadows [ i ] ;
shadow *= receiveShadow ? getShadow ( spotShadowMap [ i ] , spotLight . shadowMapSize , spotLight . shadowIntensity , spotLight . shadowBias , spotLight . shadowRadius , vSpotLightCoord [ i ] ) : 1.0 ;
}
# pragma unroll _loop _end
# endif
# if NUM _POINT _LIGHT _SHADOWS > 0
PointLightShadow pointLight ;
# pragma unroll _loop _start
for ( int i = 0 ; i < NUM _POINT _LIGHT _SHADOWS ; i ++ ) {
pointLight = pointLightShadows [ i ] ;
shadow *= receiveShadow ? getPointShadow ( pointShadowMap [ i ] , pointLight . shadowMapSize , pointLight . shadowIntensity , pointLight . shadowBias , pointLight . shadowRadius , vPointShadowCoord [ i ] , pointLight . shadowCameraNear , pointLight . shadowCameraFar ) : 1.0 ;
}
# pragma unroll _loop _end
# endif
# endif
return shadow ;
2026-01-22 15:23:57 +08:00
} ` ,tx= ` # ifdef USE _SKINNING
2026-01-22 11:29:51 +08:00
mat4 boneMatX = getBoneMatrix ( skinIndex . x ) ;
mat4 boneMatY = getBoneMatrix ( skinIndex . y ) ;
mat4 boneMatZ = getBoneMatrix ( skinIndex . z ) ;
mat4 boneMatW = getBoneMatrix ( skinIndex . w ) ;
2026-01-22 15:23:57 +08:00
# endif ` ,nx= ` # ifdef USE _SKINNING
2026-01-22 11:29:51 +08:00
uniform mat4 bindMatrix ;
uniform mat4 bindMatrixInverse ;
uniform highp sampler2D boneTexture ;
mat4 getBoneMatrix ( const in float i ) {
int size = textureSize ( boneTexture , 0 ) . x ;
int j = int ( i ) * 4 ;
int x = j % size ;
int y = j / size ;
vec4 v1 = texelFetch ( boneTexture , ivec2 ( x , y ) , 0 ) ;
vec4 v2 = texelFetch ( boneTexture , ivec2 ( x + 1 , y ) , 0 ) ;
vec4 v3 = texelFetch ( boneTexture , ivec2 ( x + 2 , y ) , 0 ) ;
vec4 v4 = texelFetch ( boneTexture , ivec2 ( x + 3 , y ) , 0 ) ;
return mat4 ( v1 , v2 , v3 , v4 ) ;
}
2026-01-22 15:23:57 +08:00
# endif ` ,ix= ` # ifdef USE _SKINNING
2026-01-22 11:29:51 +08:00
vec4 skinVertex = bindMatrix * vec4 ( transformed , 1.0 ) ;
vec4 skinned = vec4 ( 0.0 ) ;
skinned += boneMatX * skinVertex * skinWeight . x ;
skinned += boneMatY * skinVertex * skinWeight . y ;
skinned += boneMatZ * skinVertex * skinWeight . z ;
skinned += boneMatW * skinVertex * skinWeight . w ;
transformed = ( bindMatrixInverse * skinned ) . xyz ;
2026-01-22 15:23:57 +08:00
# endif ` ,sx= ` # ifdef USE _SKINNING
2026-01-22 11:29:51 +08:00
mat4 skinMatrix = mat4 ( 0.0 ) ;
skinMatrix += skinWeight . x * boneMatX ;
skinMatrix += skinWeight . y * boneMatY ;
skinMatrix += skinWeight . z * boneMatZ ;
skinMatrix += skinWeight . w * boneMatW ;
skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix ;
objectNormal = vec4 ( skinMatrix * vec4 ( objectNormal , 0.0 ) ) . xyz ;
# ifdef USE _TANGENT
objectTangent = vec4 ( skinMatrix * vec4 ( objectTangent , 0.0 ) ) . xyz ;
# endif
2026-01-22 15:23:57 +08:00
# endif ` ,rx= ` float specularStrength ;
2026-01-22 11:29:51 +08:00
# ifdef USE _SPECULARMAP
vec4 texelSpecular = texture2D ( specularMap , vSpecularMapUv ) ;
specularStrength = texelSpecular . r ;
# else
specularStrength = 1.0 ;
2026-01-22 15:23:57 +08:00
# endif ` ,ax= ` # ifdef USE _SPECULARMAP
2026-01-22 11:29:51 +08:00
uniform sampler2D specularMap ;
2026-01-22 15:23:57 +08:00
# endif ` ,ox= ` # if defined ( TONE _MAPPING )
2026-01-22 11:29:51 +08:00
gl _FragColor . rgb = toneMapping ( gl _FragColor . rgb ) ;
2026-01-22 15:23:57 +08:00
# endif ` ,lx= ` # ifndef saturate
2026-01-22 11:29:51 +08:00
# define saturate ( a ) clamp ( a , 0.0 , 1.0 )
# endif
uniform float toneMappingExposure ;
vec3 LinearToneMapping ( vec3 color ) {
return saturate ( toneMappingExposure * color ) ;
}
vec3 ReinhardToneMapping ( vec3 color ) {
color *= toneMappingExposure ;
return saturate ( color / ( vec3 ( 1.0 ) + color ) ) ;
}
vec3 CineonToneMapping ( vec3 color ) {
color *= toneMappingExposure ;
color = max ( vec3 ( 0.0 ) , color - 0.004 ) ;
return pow ( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ) , vec3 ( 2.2 ) ) ;
}
vec3 RRTAndODTFit ( vec3 v ) {
vec3 a = v * ( v + 0.0245786 ) - 0.000090537 ;
vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081 ;
return a / b ;
}
vec3 ACESFilmicToneMapping ( vec3 color ) {
const mat3 ACESInputMat = mat3 (
vec3 ( 0.59719 , 0.07600 , 0.02840 ) , vec3 ( 0.35458 , 0.90834 , 0.13383 ) ,
vec3 ( 0.04823 , 0.01566 , 0.83777 )
) ;
const mat3 ACESOutputMat = mat3 (
vec3 ( 1.60475 , - 0.10208 , - 0.00327 ) , vec3 ( - 0.53108 , 1.10813 , - 0.07276 ) ,
vec3 ( - 0.07367 , - 0.00605 , 1.07602 )
) ;
color *= toneMappingExposure / 0.6 ;
color = ACESInputMat * color ;
color = RRTAndODTFit ( color ) ;
color = ACESOutputMat * color ;
return saturate ( color ) ;
}
const mat3 LINEAR _REC2020 _TO _LINEAR _SRGB = mat3 (
vec3 ( 1.6605 , - 0.1246 , - 0.0182 ) ,
vec3 ( - 0.5876 , 1.1329 , - 0.1006 ) ,
vec3 ( - 0.0728 , - 0.0083 , 1.1187 )
) ;
const mat3 LINEAR _SRGB _TO _LINEAR _REC2020 = mat3 (
vec3 ( 0.6274 , 0.0691 , 0.0164 ) ,
vec3 ( 0.3293 , 0.9195 , 0.0880 ) ,
vec3 ( 0.0433 , 0.0113 , 0.8956 )
) ;
vec3 agxDefaultContrastApprox ( vec3 x ) {
vec3 x2 = x * x ;
vec3 x4 = x2 * x2 ;
return + 15.5 * x4 * x2
- 40.14 * x4 * x
+ 31.96 * x4
- 6.868 * x2 * x
+ 0.4298 * x2
+ 0.1191 * x
- 0.00232 ;
}
vec3 AgXToneMapping ( vec3 color ) {
const mat3 AgXInsetMatrix = mat3 (
vec3 ( 0.856627153315983 , 0.137318972929847 , 0.11189821299995 ) ,
vec3 ( 0.0951212405381588 , 0.761241990602591 , 0.0767994186031903 ) ,
vec3 ( 0.0482516061458583 , 0.101439036467562 , 0.811302368396859 )
) ;
const mat3 AgXOutsetMatrix = mat3 (
vec3 ( 1.1271005818144368 , - 0.1413297634984383 , - 0.14132976349843826 ) ,
vec3 ( - 0.11060664309660323 , 1.157823702216272 , - 0.11060664309660294 ) ,
vec3 ( - 0.016493938717834573 , - 0.016493938717834257 , 1.2519364065950405 )
) ;
const float AgxMinEv = - 12.47393 ; const float AgxMaxEv = 4.026069 ;
color *= toneMappingExposure ;
color = LINEAR _SRGB _TO _LINEAR _REC2020 * color ;
color = AgXInsetMatrix * color ;
color = max ( color , 1e-10 ) ; color = log2 ( color ) ;
color = ( color - AgxMinEv ) / ( AgxMaxEv - AgxMinEv ) ;
color = clamp ( color , 0.0 , 1.0 ) ;
color = agxDefaultContrastApprox ( color ) ;
color = AgXOutsetMatrix * color ;
color = pow ( max ( vec3 ( 0.0 ) , color ) , vec3 ( 2.2 ) ) ;
color = LINEAR _REC2020 _TO _LINEAR _SRGB * color ;
color = clamp ( color , 0.0 , 1.0 ) ;
return color ;
}
vec3 NeutralToneMapping ( vec3 color ) {
const float StartCompression = 0.8 - 0.04 ;
const float Desaturation = 0.15 ;
color *= toneMappingExposure ;
float x = min ( color . r , min ( color . g , color . b ) ) ;
float offset = x < 0.08 ? x - 6.25 * x * x : 0.04 ;
color -= offset ;
float peak = max ( color . r , max ( color . g , color . b ) ) ;
if ( peak < StartCompression ) return color ;
float d = 1. - StartCompression ;
float newPeak = 1. - d * d / ( peak + d - StartCompression ) ;
color *= newPeak / peak ;
float g = 1. - 1. / ( Desaturation * ( peak - newPeak ) + 1. ) ;
return mix ( color , vec3 ( newPeak ) , g ) ;
}
2026-01-22 15:23:57 +08:00
vec3 CustomToneMapping ( vec3 color ) { return color ; } ` ,cx= ` # ifdef USE _TRANSMISSION
2026-01-22 11:29:51 +08:00
material . transmission = transmission ;
material . transmissionAlpha = 1.0 ;
material . thickness = thickness ;
material . attenuationDistance = attenuationDistance ;
material . attenuationColor = attenuationColor ;
# ifdef USE _TRANSMISSIONMAP
material . transmission *= texture2D ( transmissionMap , vTransmissionMapUv ) . r ;
# endif
# ifdef USE _THICKNESSMAP
material . thickness *= texture2D ( thicknessMap , vThicknessMapUv ) . g ;
# endif
vec3 pos = vWorldPosition ;
vec3 v = normalize ( cameraPosition - pos ) ;
vec3 n = inverseTransformDirection ( normal , viewMatrix ) ;
vec4 transmitted = getIBLVolumeRefraction (
n , v , material . roughness , material . diffuseColor , material . specularColor , material . specularF90 ,
pos , modelMatrix , viewMatrix , projectionMatrix , material . dispersion , material . ior , material . thickness ,
material . attenuationColor , material . attenuationDistance ) ;
material . transmissionAlpha = mix ( material . transmissionAlpha , transmitted . a , material . transmission ) ;
totalDiffuse = mix ( totalDiffuse , transmitted . rgb , material . transmission ) ;
2026-01-22 15:23:57 +08:00
# endif ` ,hx= ` # ifdef USE _TRANSMISSION
2026-01-22 11:29:51 +08:00
uniform float transmission ;
uniform float thickness ;
uniform float attenuationDistance ;
uniform vec3 attenuationColor ;
# ifdef USE _TRANSMISSIONMAP
uniform sampler2D transmissionMap ;
# endif
# ifdef USE _THICKNESSMAP
uniform sampler2D thicknessMap ;
# endif
uniform vec2 transmissionSamplerSize ;
uniform sampler2D transmissionSamplerMap ;
uniform mat4 modelMatrix ;
uniform mat4 projectionMatrix ;
varying vec3 vWorldPosition ;
float w0 ( float a ) {
return ( 1.0 / 6.0 ) * ( a * ( a * ( - a + 3.0 ) - 3.0 ) + 1.0 ) ;
}
float w1 ( float a ) {
return ( 1.0 / 6.0 ) * ( a * a * ( 3.0 * a - 6.0 ) + 4.0 ) ;
}
float w2 ( float a ) {
return ( 1.0 / 6.0 ) * ( a * ( a * ( - 3.0 * a + 3.0 ) + 3.0 ) + 1.0 ) ;
}
float w3 ( float a ) {
return ( 1.0 / 6.0 ) * ( a * a * a ) ;
}
float g0 ( float a ) {
return w0 ( a ) + w1 ( a ) ;
}
float g1 ( float a ) {
return w2 ( a ) + w3 ( a ) ;
}
float h0 ( float a ) {
return - 1.0 + w1 ( a ) / ( w0 ( a ) + w1 ( a ) ) ;
}
float h1 ( float a ) {
return 1.0 + w3 ( a ) / ( w2 ( a ) + w3 ( a ) ) ;
}
vec4 bicubic ( sampler2D tex , vec2 uv , vec4 texelSize , float lod ) {
uv = uv * texelSize . zw + 0.5 ;
vec2 iuv = floor ( uv ) ;
vec2 fuv = fract ( uv ) ;
float g0x = g0 ( fuv . x ) ;
float g1x = g1 ( fuv . x ) ;
float h0x = h0 ( fuv . x ) ;
float h1x = h1 ( fuv . x ) ;
float h0y = h0 ( fuv . y ) ;
float h1y = h1 ( fuv . y ) ;
vec2 p0 = ( vec2 ( iuv . x + h0x , iuv . y + h0y ) - 0.5 ) * texelSize . xy ;
vec2 p1 = ( vec2 ( iuv . x + h1x , iuv . y + h0y ) - 0.5 ) * texelSize . xy ;
vec2 p2 = ( vec2 ( iuv . x + h0x , iuv . y + h1y ) - 0.5 ) * texelSize . xy ;
vec2 p3 = ( vec2 ( iuv . x + h1x , iuv . y + h1y ) - 0.5 ) * texelSize . xy ;
return g0 ( fuv . y ) * ( g0x * textureLod ( tex , p0 , lod ) + g1x * textureLod ( tex , p1 , lod ) ) +
g1 ( fuv . y ) * ( g0x * textureLod ( tex , p2 , lod ) + g1x * textureLod ( tex , p3 , lod ) ) ;
}
vec4 textureBicubic ( sampler2D sampler , vec2 uv , float lod ) {
vec2 fLodSize = vec2 ( textureSize ( sampler , int ( lod ) ) ) ;
vec2 cLodSize = vec2 ( textureSize ( sampler , int ( lod + 1.0 ) ) ) ;
vec2 fLodSizeInv = 1.0 / fLodSize ;
vec2 cLodSizeInv = 1.0 / cLodSize ;
vec4 fSample = bicubic ( sampler , uv , vec4 ( fLodSizeInv , fLodSize ) , floor ( lod ) ) ;
vec4 cSample = bicubic ( sampler , uv , vec4 ( cLodSizeInv , cLodSize ) , ceil ( lod ) ) ;
return mix ( fSample , cSample , fract ( lod ) ) ;
}
vec3 getVolumeTransmissionRay ( const in vec3 n , const in vec3 v , const in float thickness , const in float ior , const in mat4 modelMatrix ) {
vec3 refractionVector = refract ( - v , normalize ( n ) , 1.0 / ior ) ;
vec3 modelScale ;
modelScale . x = length ( vec3 ( modelMatrix [ 0 ] . xyz ) ) ;
modelScale . y = length ( vec3 ( modelMatrix [ 1 ] . xyz ) ) ;
modelScale . z = length ( vec3 ( modelMatrix [ 2 ] . xyz ) ) ;
return normalize ( refractionVector ) * thickness * modelScale ;
}
float applyIorToRoughness ( const in float roughness , const in float ior ) {
return roughness * clamp ( ior * 2.0 - 2.0 , 0.0 , 1.0 ) ;
}
vec4 getTransmissionSample ( const in vec2 fragCoord , const in float roughness , const in float ior ) {
float lod = log2 ( transmissionSamplerSize . x ) * applyIorToRoughness ( roughness , ior ) ;
return textureBicubic ( transmissionSamplerMap , fragCoord . xy , lod ) ;
}
vec3 volumeAttenuation ( const in float transmissionDistance , const in vec3 attenuationColor , const in float attenuationDistance ) {
if ( isinf ( attenuationDistance ) ) {
return vec3 ( 1.0 ) ;
} else {
vec3 attenuationCoefficient = - log ( attenuationColor ) / attenuationDistance ;
vec3 transmittance = exp ( - attenuationCoefficient * transmissionDistance ) ; return transmittance ;
}
}
vec4 getIBLVolumeRefraction ( const in vec3 n , const in vec3 v , const in float roughness , const in vec3 diffuseColor ,
const in vec3 specularColor , const in float specularF90 , const in vec3 position , const in mat4 modelMatrix ,
const in mat4 viewMatrix , const in mat4 projMatrix , const in float dispersion , const in float ior , const in float thickness ,
const in vec3 attenuationColor , const in float attenuationDistance ) {
vec4 transmittedLight ;
vec3 transmittance ;
# ifdef USE _DISPERSION
float halfSpread = ( ior - 1.0 ) * 0.025 * dispersion ;
vec3 iors = vec3 ( ior - halfSpread , ior , ior + halfSpread ) ;
for ( int i = 0 ; i < 3 ; i ++ ) {
vec3 transmissionRay = getVolumeTransmissionRay ( n , v , thickness , iors [ i ] , modelMatrix ) ;
vec3 refractedRayExit = position + transmissionRay ;
vec4 ndcPos = projMatrix * viewMatrix * vec4 ( refractedRayExit , 1.0 ) ;
vec2 refractionCoords = ndcPos . xy / ndcPos . w ;
refractionCoords += 1.0 ;
refractionCoords /= 2.0 ;
vec4 transmissionSample = getTransmissionSample ( refractionCoords , roughness , iors [ i ] ) ;
transmittedLight [ i ] = transmissionSample [ i ] ;
transmittedLight . a += transmissionSample . a ;
transmittance [ i ] = diffuseColor [ i ] * volumeAttenuation ( length ( transmissionRay ) , attenuationColor , attenuationDistance ) [ i ] ;
}
transmittedLight . a /= 3.0 ;
# else
vec3 transmissionRay = getVolumeTransmissionRay ( n , v , thickness , ior , modelMatrix ) ;
vec3 refractedRayExit = position + transmissionRay ;
vec4 ndcPos = projMatrix * viewMatrix * vec4 ( refractedRayExit , 1.0 ) ;
vec2 refractionCoords = ndcPos . xy / ndcPos . w ;
refractionCoords += 1.0 ;
refractionCoords /= 2.0 ;
transmittedLight = getTransmissionSample ( refractionCoords , roughness , ior ) ;
transmittance = diffuseColor * volumeAttenuation ( length ( transmissionRay ) , attenuationColor , attenuationDistance ) ;
# endif
vec3 attenuatedColor = transmittance * transmittedLight . rgb ;
vec3 F = EnvironmentBRDF ( n , v , specularColor , specularF90 , roughness ) ;
float transmittanceFactor = ( transmittance . r + transmittance . g + transmittance . b ) / 3.0 ;
return vec4 ( ( 1.0 - F ) * attenuatedColor , 1.0 - ( 1.0 - transmittedLight . a ) * transmittanceFactor ) ;
}
2026-01-22 15:23:57 +08:00
# endif ` ,ux= ` # if defined ( USE _UV ) || defined ( USE _ANISOTROPY )
2026-01-22 11:29:51 +08:00
varying vec2 vUv ;
# endif
# ifdef USE _MAP
varying vec2 vMapUv ;
# endif
# ifdef USE _ALPHAMAP
varying vec2 vAlphaMapUv ;
# endif
# ifdef USE _LIGHTMAP
varying vec2 vLightMapUv ;
# endif
# ifdef USE _AOMAP
varying vec2 vAoMapUv ;
# endif
# ifdef USE _BUMPMAP
varying vec2 vBumpMapUv ;
# endif
# ifdef USE _NORMALMAP
varying vec2 vNormalMapUv ;
# endif
# ifdef USE _EMISSIVEMAP
varying vec2 vEmissiveMapUv ;
# endif
# ifdef USE _METALNESSMAP
varying vec2 vMetalnessMapUv ;
# endif
# ifdef USE _ROUGHNESSMAP
varying vec2 vRoughnessMapUv ;
# endif
# ifdef USE _ANISOTROPYMAP
varying vec2 vAnisotropyMapUv ;
# endif
# ifdef USE _CLEARCOATMAP
varying vec2 vClearcoatMapUv ;
# endif
# ifdef USE _CLEARCOAT _NORMALMAP
varying vec2 vClearcoatNormalMapUv ;
# endif
# ifdef USE _CLEARCOAT _ROUGHNESSMAP
varying vec2 vClearcoatRoughnessMapUv ;
# endif
# ifdef USE _IRIDESCENCEMAP
varying vec2 vIridescenceMapUv ;
# endif
# ifdef USE _IRIDESCENCE _THICKNESSMAP
varying vec2 vIridescenceThicknessMapUv ;
# endif
# ifdef USE _SHEEN _COLORMAP
varying vec2 vSheenColorMapUv ;
# endif
# ifdef USE _SHEEN _ROUGHNESSMAP
varying vec2 vSheenRoughnessMapUv ;
# endif
# ifdef USE _SPECULARMAP
varying vec2 vSpecularMapUv ;
# endif
# ifdef USE _SPECULAR _COLORMAP
varying vec2 vSpecularColorMapUv ;
# endif
# ifdef USE _SPECULAR _INTENSITYMAP
varying vec2 vSpecularIntensityMapUv ;
# endif
# ifdef USE _TRANSMISSIONMAP
uniform mat3 transmissionMapTransform ;
varying vec2 vTransmissionMapUv ;
# endif
# ifdef USE _THICKNESSMAP
uniform mat3 thicknessMapTransform ;
varying vec2 vThicknessMapUv ;
2026-01-22 15:23:57 +08:00
# endif ` ,dx= ` # if defined ( USE _UV ) || defined ( USE _ANISOTROPY )
2026-01-22 11:29:51 +08:00
varying vec2 vUv ;
# endif
# ifdef USE _MAP
uniform mat3 mapTransform ;
varying vec2 vMapUv ;
# endif
# ifdef USE _ALPHAMAP
uniform mat3 alphaMapTransform ;
varying vec2 vAlphaMapUv ;
# endif
# ifdef USE _LIGHTMAP
uniform mat3 lightMapTransform ;
varying vec2 vLightMapUv ;
# endif
# ifdef USE _AOMAP
uniform mat3 aoMapTransform ;
varying vec2 vAoMapUv ;
# endif
# ifdef USE _BUMPMAP
uniform mat3 bumpMapTransform ;
varying vec2 vBumpMapUv ;
# endif
# ifdef USE _NORMALMAP
uniform mat3 normalMapTransform ;
varying vec2 vNormalMapUv ;
# endif
# ifdef USE _DISPLACEMENTMAP
uniform mat3 displacementMapTransform ;
varying vec2 vDisplacementMapUv ;
# endif
# ifdef USE _EMISSIVEMAP
uniform mat3 emissiveMapTransform ;
varying vec2 vEmissiveMapUv ;
# endif
# ifdef USE _METALNESSMAP
uniform mat3 metalnessMapTransform ;
varying vec2 vMetalnessMapUv ;
# endif
# ifdef USE _ROUGHNESSMAP
uniform mat3 roughnessMapTransform ;
varying vec2 vRoughnessMapUv ;
# endif
# ifdef USE _ANISOTROPYMAP
uniform mat3 anisotropyMapTransform ;
varying vec2 vAnisotropyMapUv ;
# endif
# ifdef USE _CLEARCOATMAP
uniform mat3 clearcoatMapTransform ;
varying vec2 vClearcoatMapUv ;
# endif
# ifdef USE _CLEARCOAT _NORMALMAP
uniform mat3 clearcoatNormalMapTransform ;
varying vec2 vClearcoatNormalMapUv ;
# endif
# ifdef USE _CLEARCOAT _ROUGHNESSMAP
uniform mat3 clearcoatRoughnessMapTransform ;
varying vec2 vClearcoatRoughnessMapUv ;
# endif
# ifdef USE _SHEEN _COLORMAP
uniform mat3 sheenColorMapTransform ;
varying vec2 vSheenColorMapUv ;
# endif
# ifdef USE _SHEEN _ROUGHNESSMAP
uniform mat3 sheenRoughnessMapTransform ;
varying vec2 vSheenRoughnessMapUv ;
# endif
# ifdef USE _IRIDESCENCEMAP
uniform mat3 iridescenceMapTransform ;
varying vec2 vIridescenceMapUv ;
# endif
# ifdef USE _IRIDESCENCE _THICKNESSMAP
uniform mat3 iridescenceThicknessMapTransform ;
varying vec2 vIridescenceThicknessMapUv ;
# endif
# ifdef USE _SPECULARMAP
uniform mat3 specularMapTransform ;
varying vec2 vSpecularMapUv ;
# endif
# ifdef USE _SPECULAR _COLORMAP
uniform mat3 specularColorMapTransform ;
varying vec2 vSpecularColorMapUv ;
# endif
# ifdef USE _SPECULAR _INTENSITYMAP
uniform mat3 specularIntensityMapTransform ;
varying vec2 vSpecularIntensityMapUv ;
# endif
# ifdef USE _TRANSMISSIONMAP
uniform mat3 transmissionMapTransform ;
varying vec2 vTransmissionMapUv ;
# endif
# ifdef USE _THICKNESSMAP
uniform mat3 thicknessMapTransform ;
varying vec2 vThicknessMapUv ;
2026-01-22 15:23:57 +08:00
# endif ` ,fx= ` # if defined ( USE _UV ) || defined ( USE _ANISOTROPY )
2026-01-22 11:29:51 +08:00
vUv = vec3 ( uv , 1 ) . xy ;
# endif
# ifdef USE _MAP
vMapUv = ( mapTransform * vec3 ( MAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _ALPHAMAP
vAlphaMapUv = ( alphaMapTransform * vec3 ( ALPHAMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _LIGHTMAP
vLightMapUv = ( lightMapTransform * vec3 ( LIGHTMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _AOMAP
vAoMapUv = ( aoMapTransform * vec3 ( AOMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _BUMPMAP
vBumpMapUv = ( bumpMapTransform * vec3 ( BUMPMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _NORMALMAP
vNormalMapUv = ( normalMapTransform * vec3 ( NORMALMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _DISPLACEMENTMAP
vDisplacementMapUv = ( displacementMapTransform * vec3 ( DISPLACEMENTMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _EMISSIVEMAP
vEmissiveMapUv = ( emissiveMapTransform * vec3 ( EMISSIVEMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _METALNESSMAP
vMetalnessMapUv = ( metalnessMapTransform * vec3 ( METALNESSMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _ROUGHNESSMAP
vRoughnessMapUv = ( roughnessMapTransform * vec3 ( ROUGHNESSMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _ANISOTROPYMAP
vAnisotropyMapUv = ( anisotropyMapTransform * vec3 ( ANISOTROPYMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _CLEARCOATMAP
vClearcoatMapUv = ( clearcoatMapTransform * vec3 ( CLEARCOATMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _CLEARCOAT _NORMALMAP
vClearcoatNormalMapUv = ( clearcoatNormalMapTransform * vec3 ( CLEARCOAT _NORMALMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _CLEARCOAT _ROUGHNESSMAP
vClearcoatRoughnessMapUv = ( clearcoatRoughnessMapTransform * vec3 ( CLEARCOAT _ROUGHNESSMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _IRIDESCENCEMAP
vIridescenceMapUv = ( iridescenceMapTransform * vec3 ( IRIDESCENCEMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _IRIDESCENCE _THICKNESSMAP
vIridescenceThicknessMapUv = ( iridescenceThicknessMapTransform * vec3 ( IRIDESCENCE _THICKNESSMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _SHEEN _COLORMAP
vSheenColorMapUv = ( sheenColorMapTransform * vec3 ( SHEEN _COLORMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _SHEEN _ROUGHNESSMAP
vSheenRoughnessMapUv = ( sheenRoughnessMapTransform * vec3 ( SHEEN _ROUGHNESSMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _SPECULARMAP
vSpecularMapUv = ( specularMapTransform * vec3 ( SPECULARMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _SPECULAR _COLORMAP
vSpecularColorMapUv = ( specularColorMapTransform * vec3 ( SPECULAR _COLORMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _SPECULAR _INTENSITYMAP
vSpecularIntensityMapUv = ( specularIntensityMapTransform * vec3 ( SPECULAR _INTENSITYMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _TRANSMISSIONMAP
vTransmissionMapUv = ( transmissionMapTransform * vec3 ( TRANSMISSIONMAP _UV , 1 ) ) . xy ;
# endif
# ifdef USE _THICKNESSMAP
vThicknessMapUv = ( thicknessMapTransform * vec3 ( THICKNESSMAP _UV , 1 ) ) . xy ;
2026-01-22 15:23:57 +08:00
# endif ` ,px= ` # if defined ( USE _ENVMAP ) || defined ( DISTANCE ) || defined ( USE _SHADOWMAP ) || defined ( USE _TRANSMISSION ) || NUM _SPOT _LIGHT _COORDS > 0
2026-01-22 11:29:51 +08:00
vec4 worldPosition = vec4 ( transformed , 1.0 ) ;
# ifdef USE _BATCHING
worldPosition = batchingMatrix * worldPosition ;
# endif
# ifdef USE _INSTANCING
worldPosition = instanceMatrix * worldPosition ;
# endif
worldPosition = modelMatrix * worldPosition ;
2026-01-22 15:23:57 +08:00
# endif ` ;const Qe={alphahash_fragment:g0,alphahash_pars_fragment:x0,alphamap_fragment:v0,alphamap_pars_fragment:b0,alphatest_fragment:_0,alphatest_pars_fragment:y0,aomap_fragment:M0,aomap_pars_fragment:S0,batching_pars_vertex:w0,batching_vertex:E0,begin_vertex:T0,beginnormal_vertex:C0,bsdfs:A0,iridescence_fragment:P0,bumpmap_pars_fragment:R0,clipping_planes_fragment:L0,clipping_planes_pars_fragment:D0,clipping_planes_pars_vertex:I0,clipping_planes_vertex:N0,color_fragment:k0,color_pars_fragment:U0,color_pars_vertex:B0,color_vertex:O0,common:F0,cube_uv_reflection_fragment:z0,defaultnormal_vertex:H0,displacementmap_pars_vertex:V0,displacementmap_vertex:G0,emissivemap_fragment:W0,emissivemap_pars_fragment:X0,colorspace_fragment:j0,colorspace_pars_fragment:Z0,envmap_fragment:q0,envmap_common_pars_fragment:Y0,envmap_pars_fragment:K0,envmap_pars_vertex: $ 0,envmap_physical_pars_fragment:lg,envmap_vertex:J0,fog_vertex:Q0,fog_pars_vertex:eg,fog_fragment:tg,fog_pars_fragment:ng,gradientmap_pars_fragment:ig,lightmap_pars_fragment:sg,lights_lambert_fragment:rg,lights_lambert_pars_fragment:ag,lights_pars_begin:og,lights_toon_fragment:cg,lights_toon_pars_fragment:hg,lights_phong_fragment:ug,lights_phong_pars_fragment:dg,lights_physical_fragment:fg,lights_physical_pars_fragment:pg,lights_fragment_begin:mg,lights_fragment_maps:gg,lights_fragment_end:xg,logdepthbuf_fragment:vg,logdepthbuf_pars_fragment:bg,logdepthbuf_pars_vertex:_g,logdepthbuf_vertex:yg,map_fragment:Mg,map_pars_fragment:Sg,map_particle_fragment:wg,map_particle_pars_fragment:Eg,metalnessmap_fragment:Tg,metalnessmap_pars_fragment:Cg,morphinstance_vertex:Ag,morphcolor_vertex:Pg,morphnormal_vertex:Rg,morphtarget_pars_vertex:Lg,morphtarget_vertex:Dg,normal_fragment_begin:Ig,normal_fragment_maps:Ng,normal_pars_fragment:kg,normal_pars_vertex:Ug,normal_vertex:Bg,normalmap_pars_fragment:Og,clearcoat_normal_fragment_begin:Fg,clearcoat_normal_fragment_maps:zg,clearcoat_pars_fragment:Hg,iridescence_pars_fragment:Vg,opaque_fragment:Gg,packing:Wg,premultiplied_alpha_fragment:Xg,project_vertex:jg,dithering_fragment:Zg,dithering_pars_fragment:qg,roughnessmap_fragment:Yg,roughnessmap_pars_fragment:Kg,shadowmap_pars_fragment: $ g,shadowmap_pars_vertex:Jg,shadowmap_vertex:Qg,shadowmask_pars_fragment:ex,skinbase_vertex:tx,skinning_pars_vertex:nx,skinning_vertex:ix,skinnormal_vertex:sx,specularmap_fragment:rx,specularmap_pars_fragment:ax,tonemapping_fragment:ox,tonemapping_pars_fragment:lx,transmission_fragment:cx,transmission_pars_fragment:hx,uv_pars_fragment:ux,uv_pars_vertex:dx,uv_vertex:fx,worldpos_vertex:px,background_vert: ` varying vec2 vUv ;
2026-01-22 11:29:51 +08:00
uniform mat3 uvTransform ;
void main ( ) {
vUv = ( uvTransform * vec3 ( uv , 1 ) ) . xy ;
gl _Position = vec4 ( position . xy , 1.0 , 1.0 ) ;
} ` ,background_frag: ` uniform sampler2D t2D ;
uniform float backgroundIntensity ;
varying vec2 vUv ;
void main ( ) {
vec4 texColor = texture2D ( t2D , vUv ) ;
# ifdef DECODE _VIDEO _TEXTURE
texColor = vec4 ( mix ( pow ( texColor . rgb * 0.9478672986 + vec3 ( 0.0521327014 ) , vec3 ( 2.4 ) ) , texColor . rgb * 0.0773993808 , vec3 ( lessThanEqual ( texColor . rgb , vec3 ( 0.04045 ) ) ) ) , texColor . w ) ;
# endif
texColor . rgb *= backgroundIntensity ;
gl _FragColor = texColor ;
# include < tonemapping _fragment >
# include < colorspace _fragment >
} ` ,backgroundCube_vert: ` varying vec3 vWorldDirection ;
# include < common >
void main ( ) {
vWorldDirection = transformDirection ( position , modelMatrix ) ;
# include < begin _vertex >
# include < project _vertex >
gl _Position . z = gl _Position . w ;
} ` ,backgroundCube_frag: ` # ifdef ENVMAP _TYPE _CUBE
uniform samplerCube envMap ;
# elif defined ( ENVMAP _TYPE _CUBE _UV )
uniform sampler2D envMap ;
# endif
uniform float flipEnvMap ;
uniform float backgroundBlurriness ;
uniform float backgroundIntensity ;
uniform mat3 backgroundRotation ;
varying vec3 vWorldDirection ;
# include < cube _uv _reflection _fragment >
void main ( ) {
# ifdef ENVMAP _TYPE _CUBE
vec4 texColor = textureCube ( envMap , backgroundRotation * vec3 ( flipEnvMap * vWorldDirection . x , vWorldDirection . yz ) ) ;
# elif defined ( ENVMAP _TYPE _CUBE _UV )
vec4 texColor = textureCubeUV ( envMap , backgroundRotation * vWorldDirection , backgroundBlurriness ) ;
# else
vec4 texColor = vec4 ( 0.0 , 0.0 , 0.0 , 1.0 ) ;
# endif
texColor . rgb *= backgroundIntensity ;
gl _FragColor = texColor ;
# include < tonemapping _fragment >
# include < colorspace _fragment >
} ` ,cube_vert: ` varying vec3 vWorldDirection ;
# include < common >
void main ( ) {
vWorldDirection = transformDirection ( position , modelMatrix ) ;
# include < begin _vertex >
# include < project _vertex >
gl _Position . z = gl _Position . w ;
} ` ,cube_frag: ` uniform samplerCube tCube ;
uniform float tFlip ;
uniform float opacity ;
varying vec3 vWorldDirection ;
void main ( ) {
vec4 texColor = textureCube ( tCube , vec3 ( tFlip * vWorldDirection . x , vWorldDirection . yz ) ) ;
gl _FragColor = texColor ;
gl _FragColor . a *= opacity ;
# include < tonemapping _fragment >
# include < colorspace _fragment >
} ` ,depth_vert: ` # include < common >
# include < batching _pars _vertex >
# include < uv _pars _vertex >
# include < displacementmap _pars _vertex >
# include < morphtarget _pars _vertex >
# include < skinning _pars _vertex >
# include < logdepthbuf _pars _vertex >
# include < clipping _planes _pars _vertex >
varying vec2 vHighPrecisionZW ;
void main ( ) {
# include < uv _vertex >
# include < batching _vertex >
# include < skinbase _vertex >
# include < morphinstance _vertex >
# ifdef USE _DISPLACEMENTMAP
# include < beginnormal _vertex >
# include < morphnormal _vertex >
# include < skinnormal _vertex >
# endif
# include < begin _vertex >
# include < morphtarget _vertex >
# include < skinning _vertex >
# include < displacementmap _vertex >
# include < project _vertex >
# include < logdepthbuf _vertex >
# include < clipping _planes _vertex >
vHighPrecisionZW = gl _Position . zw ;
} ` ,depth_frag: ` # if DEPTH _PACKING == 3200
uniform float opacity ;
# endif
# include < common >
# include < packing >
# include < uv _pars _fragment >
# include < map _pars _fragment >
# include < alphamap _pars _fragment >
# include < alphatest _pars _fragment >
# include < alphahash _pars _fragment >
# include < logdepthbuf _pars _fragment >
# include < clipping _planes _pars _fragment >
varying vec2 vHighPrecisionZW ;
void main ( ) {
vec4 diffuseColor = vec4 ( 1.0 ) ;
# include < clipping _planes _fragment >
# if DEPTH _PACKING == 3200
diffuseColor . a = opacity ;
# endif
# include < map _fragment >
# include < alphamap _fragment >
# include < alphatest _fragment >
# include < alphahash _fragment >
# include < logdepthbuf _fragment >
# ifdef USE _REVERSED _DEPTH _BUFFER
float fragCoordZ = vHighPrecisionZW [ 0 ] / vHighPrecisionZW [ 1 ] ;
# else
float fragCoordZ = 0.5 * vHighPrecisionZW [ 0 ] / vHighPrecisionZW [ 1 ] + 0.5 ;
# endif
# if DEPTH _PACKING == 3200
gl _FragColor = vec4 ( vec3 ( 1.0 - fragCoordZ ) , opacity ) ;
# elif DEPTH _PACKING == 3201
gl _FragColor = packDepthToRGBA ( fragCoordZ ) ;
# elif DEPTH _PACKING == 3202
gl _FragColor = vec4 ( packDepthToRGB ( fragCoordZ ) , 1.0 ) ;
# elif DEPTH _PACKING == 3203
gl _FragColor = vec4 ( packDepthToRG ( fragCoordZ ) , 0.0 , 1.0 ) ;
# endif
} ` ,distanceRGBA_vert: ` # define DISTANCE
varying vec3 vWorldPosition ;
# include < common >
# include < batching _pars _vertex >
# include < uv _pars _vertex >
# include < displacementmap _pars _vertex >
# include < morphtarget _pars _vertex >
# include < skinning _pars _vertex >
# include < clipping _planes _pars _vertex >
void main ( ) {
# include < uv _vertex >
# include < batching _vertex >
# include < skinbase _vertex >
# include < morphinstance _vertex >
# ifdef USE _DISPLACEMENTMAP
# include < beginnormal _vertex >
# include < morphnormal _vertex >
# include < skinnormal _vertex >
# endif
# include < begin _vertex >
# include < morphtarget _vertex >
# include < skinning _vertex >
# include < displacementmap _vertex >
# include < project _vertex >
# include < worldpos _vertex >
# include < clipping _planes _vertex >
vWorldPosition = worldPosition . xyz ;
} ` ,distanceRGBA_frag: ` # define DISTANCE
uniform vec3 referencePosition ;
uniform float nearDistance ;
uniform float farDistance ;
varying vec3 vWorldPosition ;
# include < common >
# include < packing >
# include < uv _pars _fragment >
# include < map _pars _fragment >
# include < alphamap _pars _fragment >
# include < alphatest _pars _fragment >
# include < alphahash _pars _fragment >
# include < clipping _planes _pars _fragment >
void main ( ) {
vec4 diffuseColor = vec4 ( 1.0 ) ;
# include < clipping _planes _fragment >
# include < map _fragment >
# include < alphamap _fragment >
# include < alphatest _fragment >
# include < alphahash _fragment >
float dist = length ( vWorldPosition - referencePosition ) ;
dist = ( dist - nearDistance ) / ( farDistance - nearDistance ) ;
dist = saturate ( dist ) ;
gl _FragColor = packDepthToRGBA ( dist ) ;
} ` ,equirect_vert: ` varying vec3 vWorldDirection ;
# include < common >
void main ( ) {
vWorldDirection = transformDirection ( position , modelMatrix ) ;
# include < begin _vertex >
# include < project _vertex >
} ` ,equirect_frag: ` uniform sampler2D tEquirect ;
varying vec3 vWorldDirection ;
# include < common >
void main ( ) {
vec3 direction = normalize ( vWorldDirection ) ;
vec2 sampleUV = equirectUv ( direction ) ;
gl _FragColor = texture2D ( tEquirect , sampleUV ) ;
# include < tonemapping _fragment >
# include < colorspace _fragment >
} ` ,linedashed_vert: ` uniform float scale ;
attribute float lineDistance ;
varying float vLineDistance ;
# include < common >
# include < uv _pars _vertex >
# include < color _pars _vertex >
# include < fog _pars _vertex >
# include < morphtarget _pars _vertex >
# include < logdepthbuf _pars _vertex >
# include < clipping _planes _pars _vertex >
void main ( ) {
vLineDistance = scale * lineDistance ;
# include < uv _vertex >
# include < color _vertex >
# include < morphinstance _vertex >
# include < morphcolor _vertex >
# include < begin _vertex >
# include < morphtarget _vertex >
# include < project _vertex >
# include < logdepthbuf _vertex >
# include < clipping _planes _vertex >
# include < fog _vertex >
} ` ,linedashed_frag: ` uniform vec3 diffuse ;
uniform float opacity ;
uniform float dashSize ;
uniform float totalSize ;
varying float vLineDistance ;
# include < common >
# include < color _pars _fragment >
# include < uv _pars _fragment >
# include < map _pars _fragment >
# include < fog _pars _fragment >
# include < logdepthbuf _pars _fragment >
# include < clipping _planes _pars _fragment >
void main ( ) {
vec4 diffuseColor = vec4 ( diffuse , opacity ) ;
# include < clipping _planes _fragment >
if ( mod ( vLineDistance , totalSize ) > dashSize ) {
discard ;
}
vec3 outgoingLight = vec3 ( 0.0 ) ;
# include < logdepthbuf _fragment >
# include < map _fragment >
# include < color _fragment >
outgoingLight = diffuseColor . rgb ;
# include < opaque _fragment >
# include < tonemapping _fragment >
# include < colorspace _fragment >
# include < fog _fragment >
# include < premultiplied _alpha _fragment >
} ` ,meshbasic_vert: ` # include < common >
# include < batching _pars _vertex >
# include < uv _pars _vertex >
# include < envmap _pars _vertex >
# include < color _pars _vertex >
# include < fog _pars _vertex >
# include < morphtarget _pars _vertex >
# include < skinning _pars _vertex >
# include < logdepthbuf _pars _vertex >
# include < clipping _planes _pars _vertex >
void main ( ) {
# include < uv _vertex >
# include < color _vertex >
# include < morphinstance _vertex >
# include < morphcolor _vertex >
# include < batching _vertex >
# if defined ( USE _ENVMAP ) || defined ( USE _SKINNING )
# include < beginnormal _vertex >
# include < morphnormal _vertex >
# include < skinbase _vertex >
# include < skinnormal _vertex >
# include < defaultnormal _vertex >
# endif
# include < begin _vertex >
# include < morphtarget _vertex >
# include < skinning _vertex >
# include < project _vertex >
# include < logdepthbuf _vertex >
# include < clipping _planes _vertex >
# include < worldpos _vertex >
# include < envmap _vertex >
# include < fog _vertex >
} ` ,meshbasic_frag: ` uniform vec3 diffuse ;
uniform float opacity ;
# ifndef FLAT _SHADED
varying vec3 vNormal ;
# endif
# include < common >
# include < dithering _pars _fragment >
# include < color _pars _fragment >
# include < uv _pars _fragment >
# include < map _pars _fragment >
# include < alphamap _pars _fragment >
# include < alphatest _pars _fragment >
# include < alphahash _pars _fragment >
# include < aomap _pars _fragment >
# include < lightmap _pars _fragment >
# include < envmap _common _pars _fragment >
# include < envmap _pars _fragment >
# include < fog _pars _fragment >
# include < specularmap _pars _fragment >
# include < logdepthbuf _pars _fragment >
# include < clipping _planes _pars _fragment >
void main ( ) {
vec4 diffuseColor = vec4 ( diffuse , opacity ) ;
# include < clipping _planes _fragment >
# include < logdepthbuf _fragment >
# include < map _fragment >
# include < color _fragment >
# include < alphamap _fragment >
# include < alphatest _fragment >
# include < alphahash _fragment >
# include < specularmap _fragment >
ReflectedLight reflectedLight = ReflectedLight ( vec3 ( 0.0 ) , vec3 ( 0.0 ) , vec3 ( 0.0 ) , vec3 ( 0.0 ) ) ;
# ifdef USE _LIGHTMAP
vec4 lightMapTexel = texture2D ( lightMap , vLightMapUv ) ;
reflectedLight . indirectDiffuse += lightMapTexel . rgb * lightMapIntensity * RECIPROCAL _PI ;
# else
reflectedLight . indirectDiffuse += vec3 ( 1.0 ) ;
# endif
# include < aomap _fragment >
reflectedLight . indirectDiffuse *= diffuseColor . rgb ;
vec3 outgoingLight = reflectedLight . indirectDiffuse ;
# include < envmap _fragment >
# include < opaque _fragment >
# include < tonemapping _fragment >
# include < colorspace _fragment >
# include < fog _fragment >
# include < premultiplied _alpha _fragment >
# include < dithering _fragment >
} ` ,meshlambert_vert: ` # define LAMBERT
varying vec3 vViewPosition ;
# include < common >
# include < batching _pars _vertex >
# include < uv _pars _vertex >
# include < displacementmap _pars _vertex >
# include < envmap _pars _vertex >
# include < color _pars _vertex >
# include < fog _pars _vertex >
# include < normal _pars _vertex >
# include < morphtarget _pars _vertex >
# include < skinning _pars _vertex >
# include < shadowmap _pars _vertex >
# include < logdepthbuf _pars _vertex >
# include < clipping _planes _pars _vertex >
void main ( ) {
# include < uv _vertex >
# include < color _vertex >
# include < morphinstance _vertex >
# include < morphcolor _vertex >
# include < batching _vertex >
# include < beginnormal _vertex >
# include < morphnormal _vertex >
# include < skinbase _vertex >
# include < skinnormal _vertex >
# include < defaultnormal _vertex >
# include < normal _vertex >
# include < begin _vertex >
# include < morphtarget _vertex >
# include < skinning _vertex >
# include < displacementmap _vertex >
# include < project _vertex >
# include < logdepthbuf _vertex >
# include < clipping _planes _vertex >
vViewPosition = - mvPosition . xyz ;
# include < worldpos _vertex >
# include < envmap _vertex >
# include < shadowmap _vertex >
# include < fog _vertex >
} ` ,meshlambert_frag: ` # define LAMBERT
uniform vec3 diffuse ;
uniform vec3 emissive ;
uniform float opacity ;
# include < common >
# include < packing >
# include < dithering _pars _fragment >
# include < color _pars _fragment >
# include < uv _pars _fragment >
# include < map _pars _fragment >
# include < alphamap _pars _fragment >
# include < alphatest _pars _fragment >
# include < alphahash _pars _fragment >
# include < aomap _pars _fragment >
# include < lightmap _pars _fragment >
# include < emissivemap _pars _fragment >
# include < envmap _common _pars _fragment >
# include < envmap _pars _fragment >
# include < fog _pars _fragment >
# include < bsdfs >
# include < lights _pars _begin >
# include < normal _pars _fragment >
# include < lights _lambert _pars _fragment >
# include < shadowmap _pars _fragment >
# include < bumpmap _pars _fragment >
# include < normalmap _pars _fragment >
# include < specularmap _pars _fragment >
# include < logdepthbuf _pars _fragment >
# include < clipping _planes _pars _fragment >
void main ( ) {
vec4 diffuseColor = vec4 ( diffuse , opacity ) ;
# include < clipping _planes _fragment >
ReflectedLight reflectedLight = ReflectedLight ( vec3 ( 0.0 ) , vec3 ( 0.0 ) , vec3 ( 0.0 ) , vec3 ( 0.0 ) ) ;
vec3 totalEmissiveRadiance = emissive ;
# include < logdepthbuf _fragment >
# include < map _fragment >
# include < color _fragment >
# include < alphamap _fragment >
# include < alphatest _fragment >
# include < alphahash _fragment >
# include < specularmap _fragment >
# include < normal _fragment _begin >
# include < normal _fragment _maps >
# include < emissivemap _fragment >
# include < lights _lambert _fragment >
# include < lights _fragment _begin >
# include < lights _fragment _maps >
# include < lights _fragment _end >
# include < aomap _fragment >
vec3 outgoingLight = reflectedLight . directDiffuse + reflectedLight . indirectDiffuse + totalEmissiveRadiance ;
# include < envmap _fragment >
# include < opaque _fragment >
# include < tonemapping _fragment >
# include < colorspace _fragment >
# include < fog _fragment >
# include < premultiplied _alpha _fragment >
# include < dithering _fragment >
} ` ,meshmatcap_vert: ` # define MATCAP
varying vec3 vViewPosition ;
# include < common >
# include < batching _pars _vertex >
# include < uv _pars _vertex >
# include < color _pars _vertex >
# include < displacementmap _pars _vertex >
# include < fog _pars _vertex >
# include < normal _pars _vertex >
# include < morphtarget _pars _vertex >
# include < skinning _pars _vertex >
# include < logdepthbuf _pars _vertex >
# include < clipping _planes _pars _vertex >
void main ( ) {
# include < uv _vertex >
# include < color _vertex >
# include < morphinstance _vertex >
# include < morphcolor _vertex >
# include < batching _vertex >
# include < beginnormal _vertex >
# include < morphnormal _vertex >
# include < skinbase _vertex >
# include < skinnormal _vertex >
# include < defaultnormal _vertex >
# include < normal _vertex >
# include < begin _vertex >
# include < morphtarget _vertex >
# include < skinning _vertex >
# include < displacementmap _vertex >
# include < project _vertex >
# include < logdepthbuf _vertex >
# include < clipping _planes _vertex >
# include < fog _vertex >
vViewPosition = - mvPosition . xyz ;
} ` ,meshmatcap_frag: ` # define MATCAP
uniform vec3 diffuse ;
uniform float opacity ;
uniform sampler2D matcap ;
varying vec3 vViewPosition ;
# include < common >
# include < dithering _pars _fragment >
# include < color _pars _fragment >
# include < uv _pars _fragment >
# include < map _pars _fragment >
# include < alphamap _pars _fragment >
# include < alphatest _pars _fragment >
# include < alphahash _pars _fragment >
# include < fog _pars _fragment >
# include < normal _pars _fragment >
# include < bumpmap _pars _fragment >
# include < normalmap _pars _fragment >
# include < logdepthbuf _pars _fragment >
# include < clipping _planes _pars _fragment >
void main ( ) {
vec4 diffuseColor = vec4 ( diffuse , opacity ) ;
# include < clipping _planes _fragment >
# include < logdepthbuf _fragment >
# include < map _fragment >
# include < color _fragment >
# include < alphamap _fragment >
# include < alphatest _fragment >
# include < alphahash _fragment >
# include < normal _fragment _begin >
# include < normal _fragment _maps >
vec3 viewDir = normalize ( vViewPosition ) ;
vec3 x = normalize ( vec3 ( viewDir . z , 0.0 , - viewDir . x ) ) ;
vec3 y = cross ( viewDir , x ) ;
vec2 uv = vec2 ( dot ( x , normal ) , dot ( y , normal ) ) * 0.495 + 0.5 ;
# ifdef USE _MATCAP
vec4 matcapColor = texture2D ( matcap , uv ) ;
# else
vec4 matcapColor = vec4 ( vec3 ( mix ( 0.2 , 0.8 , uv . y ) ) , 1.0 ) ;
# endif
vec3 outgoingLight = diffuseColor . rgb * matcapColor . rgb ;
# include < opaque _fragment >
# include < tonemapping _fragment >
# include < colorspace _fragment >
# include < fog _fragment >
# include < premultiplied _alpha _fragment >
# include < dithering _fragment >
} ` ,meshnormal_vert: ` # define NORMAL
# if defined ( FLAT _SHADED ) || defined ( USE _BUMPMAP ) || defined ( USE _NORMALMAP _TANGENTSPACE )
varying vec3 vViewPosition ;
# endif
# include < common >
# include < batching _pars _vertex >
# include < uv _pars _vertex >
# include < displacementmap _pars _vertex >
# include < normal _pars _vertex >
# include < morphtarget _pars _vertex >
# include < skinning _pars _vertex >
# include < logdepthbuf _pars _vertex >
# include < clipping _planes _pars _vertex >
void main ( ) {
# include < uv _vertex >
# include < batching _vertex >
# include < beginnormal _vertex >
# include < morphinstance _vertex >
# include < morphnormal _vertex >
# include < skinbase _vertex >
# include < skinnormal _vertex >
# include < defaultnormal _vertex >
# include < normal _vertex >
# include < begin _vertex >
# include < morphtarget _vertex >
# include < skinning _vertex >
# include < displacementmap _vertex >
# include < project _vertex >
# include < logdepthbuf _vertex >
# include < clipping _planes _vertex >
# if defined ( FLAT _SHADED ) || defined ( USE _BUMPMAP ) || defined ( USE _NORMALMAP _TANGENTSPACE )
vViewPosition = - mvPosition . xyz ;
# endif
} ` ,meshnormal_frag: ` # define NORMAL
uniform float opacity ;
# if defined ( FLAT _SHADED ) || defined ( USE _BUMPMAP ) || defined ( USE _NORMALMAP _TANGENTSPACE )
varying vec3 vViewPosition ;
# endif
# include < packing >
# include < uv _pars _fragment >
# include < normal _pars _fragment >
# include < bumpmap _pars _fragment >
# include < normalmap _pars _fragment >
# include < logdepthbuf _pars _fragment >
# include < clipping _planes _pars _fragment >
void main ( ) {
vec4 diffuseColor = vec4 ( 0.0 , 0.0 , 0.0 , opacity ) ;
# include < clipping _planes _fragment >
# include < logdepthbuf _fragment >
# include < normal _fragment _begin >
# include < normal _fragment _maps >
gl _FragColor = vec4 ( packNormalToRGB ( normal ) , diffuseColor . a ) ;
# ifdef OPAQUE
gl _FragColor . a = 1.0 ;
# endif
} ` ,meshphong_vert: ` # define PHONG
varying vec3 vViewPosition ;
# include < common >
# include < batching _pars _vertex >
# include < uv _pars _vertex >
# include < displacementmap _pars _vertex >
# include < envmap _pars _vertex >
# include < color _pars _vertex >
# include < fog _pars _vertex >
# include < normal _pars _vertex >
# include < morphtarget _pars _vertex >
# include < skinning _pars _vertex >
# include < shadowmap _pars _vertex >
# include < logdepthbuf _pars _vertex >
# include < clipping _planes _pars _vertex >
void main ( ) {
# include < uv _vertex >
# include < color _vertex >
# include < morphcolor _vertex >
# include < batching _vertex >
# include < beginnormal _vertex >
# include < morphinstance _vertex >
# include < morphnormal _vertex >
# include < skinbase _vertex >
# include < skinnormal _vertex >
# include < defaultnormal _vertex >
# include < normal _vertex >
# include < begin _vertex >
# include < morphtarget _vertex >
# include < skinning _vertex >
# include < displacementmap _vertex >
# include < project _vertex >
# include < logdepthbuf _vertex >
# include < clipping _planes _vertex >
vViewPosition = - mvPosition . xyz ;
# include < worldpos _vertex >
# include < envmap _vertex >
# include < shadowmap _vertex >
# include < fog _vertex >
} ` ,meshphong_frag: ` # define PHONG
uniform vec3 diffuse ;
uniform vec3 emissive ;
uniform vec3 specular ;
uniform float shininess ;
uniform float opacity ;
# include < common >
# include < packing >
# include < dithering _pars _fragment >
# include < color _pars _fragment >
# include < uv _pars _fragment >
# include < map _pars _fragment >
# include < alphamap _pars _fragment >
# include < alphatest _pars _fragment >
# include < alphahash _pars _fragment >
# include < aomap _pars _fragment >
# include < lightmap _pars _fragment >
# include < emissivemap _pars _fragment >
# include < envmap _common _pars _fragment >
# include < envmap _pars _fragment >
# include < fog _pars _fragment >
# include < bsdfs >
# include < lights _pars _begin >
# include < normal _pars _fragment >
# include < lights _phong _pars _fragment >
# include < shadowmap _pars _fragment >
# include < bumpmap _pars _fragment >
# include < normalmap _pars _fragment >
# include < specularmap _pars _fragment >
# include < logdepthbuf _pars _fragment >
# include < clipping _planes _pars _fragment >
void main ( ) {
vec4 diffuseColor = vec4 ( diffuse , opacity ) ;
# include < clipping _planes _fragment >
ReflectedLight reflectedLight = ReflectedLight ( vec3 ( 0.0 ) , vec3 ( 0.0 ) , vec3 ( 0.0 ) , vec3 ( 0.0 ) ) ;
vec3 totalEmissiveRadiance = emissive ;
# include < logdepthbuf _fragment >
# include < map _fragment >
# include < color _fragment >
# include < alphamap _fragment >
# include < alphatest _fragment >
# include < alphahash _fragment >
# include < specularmap _fragment >
# include < normal _fragment _begin >
# include < normal _fragment _maps >
# include < emissivemap _fragment >
# include < lights _phong _fragment >
# include < lights _fragment _begin >
# include < lights _fragment _maps >
# include < lights _fragment _end >
# include < aomap _fragment >
vec3 outgoingLight = reflectedLight . directDiffuse + reflectedLight . indirectDiffuse + reflectedLight . directSpecular + reflectedLight . indirectSpecular + totalEmissiveRadiance ;
# include < envmap _fragment >
# include < opaque _fragment >
# include < tonemapping _fragment >
# include < colorspace _fragment >
# include < fog _fragment >
# include < premultiplied _alpha _fragment >
# include < dithering _fragment >
} ` ,meshphysical_vert: ` # define STANDARD
varying vec3 vViewPosition ;
# ifdef USE _TRANSMISSION
varying vec3 vWorldPosition ;
# endif
# include < common >
# include < batching _pars _vertex >
# include < uv _pars _vertex >
# include < displacementmap _pars _vertex >
# include < color _pars _vertex >
# include < fog _pars _vertex >
# include < normal _pars _vertex >
# include < morphtarget _pars _vertex >
# include < skinning _pars _vertex >
# include < shadowmap _pars _vertex >
# include < logdepthbuf _pars _vertex >
# include < clipping _planes _pars _vertex >
void main ( ) {
# include < uv _vertex >
# include < color _vertex >
# include < morphinstance _vertex >
# include < morphcolor _vertex >
# include < batching _vertex >
# include < beginnormal _vertex >
# include < morphnormal _vertex >
# include < skinbase _vertex >
# include < skinnormal _vertex >
# include < defaultnormal _vertex >
# include < normal _vertex >
# include < begin _vertex >
# include < morphtarget _vertex >
# include < skinning _vertex >
# include < displacementmap _vertex >
# include < project _vertex >
# include < logdepthbuf _vertex >
# include < clipping _planes _vertex >
vViewPosition = - mvPosition . xyz ;
# include < worldpos _vertex >
# include < shadowmap _vertex >
# include < fog _vertex >
# ifdef USE _TRANSMISSION
vWorldPosition = worldPosition . xyz ;
# endif
} ` ,meshphysical_frag: ` # define STANDARD
# ifdef PHYSICAL
# define IOR
# define USE _SPECULAR
# endif
uniform vec3 diffuse ;
uniform vec3 emissive ;
uniform float roughness ;
uniform float metalness ;
uniform float opacity ;
# ifdef IOR
uniform float ior ;
# endif
# ifdef USE _SPECULAR
uniform float specularIntensity ;
uniform vec3 specularColor ;
# ifdef USE _SPECULAR _COLORMAP
uniform sampler2D specularColorMap ;
# endif
# ifdef USE _SPECULAR _INTENSITYMAP
uniform sampler2D specularIntensityMap ;
# endif
# endif
# ifdef USE _CLEARCOAT
uniform float clearcoat ;
uniform float clearcoatRoughness ;
# endif
# ifdef USE _DISPERSION
uniform float dispersion ;
# endif
# ifdef USE _IRIDESCENCE
uniform float iridescence ;
uniform float iridescenceIOR ;
uniform float iridescenceThicknessMinimum ;
uniform float iridescenceThicknessMaximum ;
# endif
# ifdef USE _SHEEN
uniform vec3 sheenColor ;
uniform float sheenRoughness ;
# ifdef USE _SHEEN _COLORMAP
uniform sampler2D sheenColorMap ;
# endif
# ifdef USE _SHEEN _ROUGHNESSMAP
uniform sampler2D sheenRoughnessMap ;
# endif
# endif
# ifdef USE _ANISOTROPY
uniform vec2 anisotropyVector ;
# ifdef USE _ANISOTROPYMAP
uniform sampler2D anisotropyMap ;
# endif
# endif
varying vec3 vViewPosition ;
# include < common >
# include < packing >
# include < dithering _pars _fragment >
# include < color _pars _fragment >
# include < uv _pars _fragment >
# include < map _pars _fragment >
# include < alphamap _pars _fragment >
# include < alphatest _pars _fragment >
# include < alphahash _pars _fragment >
# include < aomap _pars _fragment >
# include < lightmap _pars _fragment >
# include < emissivemap _pars _fragment >
# include < iridescence _fragment >
# include < cube _uv _reflection _fragment >
# include < envmap _common _pars _fragment >
# include < envmap _physical _pars _fragment >
# include < fog _pars _fragment >
# include < lights _pars _begin >
# include < normal _pars _fragment >
# include < lights _physical _pars _fragment >
# include < transmission _pars _fragment >
# include < shadowmap _pars _fragment >
# include < bumpmap _pars _fragment >
# include < normalmap _pars _fragment >
# include < clearcoat _pars _fragment >
# include < iridescence _pars _fragment >
# include < roughnessmap _pars _fragment >
# include < metalnessmap _pars _fragment >
# include < logdepthbuf _pars _fragment >
# include < clipping _planes _pars _fragment >
void main ( ) {
vec4 diffuseColor = vec4 ( diffuse , opacity ) ;
# include < clipping _planes _fragment >
ReflectedLight reflectedLight = ReflectedLight ( vec3 ( 0.0 ) , vec3 ( 0.0 ) , vec3 ( 0.0 ) , vec3 ( 0.0 ) ) ;
vec3 totalEmissiveRadiance = emissive ;
# include < logdepthbuf _fragment >
# include < map _fragment >
# include < color _fragment >
# include < alphamap _fragment >
# include < alphatest _fragment >
# include < alphahash _fragment >
# include < roughnessmap _fragment >
# include < metalnessmap _fragment >
# include < normal _fragment _begin >
# include < normal _fragment _maps >
# include < clearcoat _normal _fragment _begin >
# include < clearcoat _normal _fragment _maps >
# include < emissivemap _fragment >
# include < lights _physical _fragment >
# include < lights _fragment _begin >
# include < lights _fragment _maps >
# include < lights _fragment _end >
# include < aomap _fragment >
vec3 totalDiffuse = reflectedLight . directDiffuse + reflectedLight . indirectDiffuse ;
vec3 totalSpecular = reflectedLight . directSpecular + reflectedLight . indirectSpecular ;
# include < transmission _fragment >
vec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance ;
# ifdef USE _SHEEN
float sheenEnergyComp = 1.0 - 0.157 * max3 ( material . sheenColor ) ;
outgoingLight = outgoingLight * sheenEnergyComp + sheenSpecularDirect + sheenSpecularIndirect ;
# endif
# ifdef USE _CLEARCOAT
float dotNVcc = saturate ( dot ( geometryClearcoatNormal , geometryViewDir ) ) ;
vec3 Fcc = F _Schlick ( material . clearcoatF0 , material . clearcoatF90 , dotNVcc ) ;
outgoingLight = outgoingLight * ( 1.0 - material . clearcoat * Fcc ) + ( clearcoatSpecularDirect + clearcoatSpecularIndirect ) * material . clearcoat ;
# endif
# include < opaque _fragment >
# include < tonemapping _fragment >
# include < colorspace _fragment >
# include < fog _fragment >
# include < premultiplied _alpha _fragment >
# include < dithering _fragment >
} ` ,meshtoon_vert: ` # define TOON
varying vec3 vViewPosition ;
# include < common >
# include < batching _pars _vertex >
# include < uv _pars _vertex >
# include < displacementmap _pars _vertex >
# include < color _pars _vertex >
# include < fog _pars _vertex >
# include < normal _pars _vertex >
# include < morphtarget _pars _vertex >
# include < skinning _pars _vertex >
# include < shadowmap _pars _vertex >
# include < logdepthbuf _pars _vertex >
# include < clipping _planes _pars _vertex >
void main ( ) {
# include < uv _vertex >
# include < color _vertex >
# include < morphinstance _vertex >
# include < morphcolor _vertex >
# include < batching _vertex >
# include < beginnormal _vertex >
# include < morphnormal _vertex >
# include < skinbase _vertex >
# include < skinnormal _vertex >
# include < defaultnormal _vertex >
# include < normal _vertex >
# include < begin _vertex >
# include < morphtarget _vertex >
# include < skinning _vertex >
# include < displacementmap _vertex >
# include < project _vertex >
# include < logdepthbuf _vertex >
# include < clipping _planes _vertex >
vViewPosition = - mvPosition . xyz ;
# include < worldpos _vertex >
# include < shadowmap _vertex >
# include < fog _vertex >
} ` ,meshtoon_frag: ` # define TOON
uniform vec3 diffuse ;
uniform vec3 emissive ;
uniform float opacity ;
# include < common >
# include < packing >
# include < dithering _pars _fragment >
# include < color _pars _fragment >
# include < uv _pars _fragment >
# include < map _pars _fragment >
# include < alphamap _pars _fragment >
# include < alphatest _pars _fragment >
# include < alphahash _pars _fragment >
# include < aomap _pars _fragment >
# include < lightmap _pars _fragment >
# include < emissivemap _pars _fragment >
# include < gradientmap _pars _fragment >
# include < fog _pars _fragment >
# include < bsdfs >
# include < lights _pars _begin >
# include < normal _pars _fragment >
# include < lights _toon _pars _fragment >
# include < shadowmap _pars _fragment >
# include < bumpmap _pars _fragment >
# include < normalmap _pars _fragment >
# include < logdepthbuf _pars _fragment >
# include < clipping _planes _pars _fragment >
void main ( ) {
vec4 diffuseColor = vec4 ( diffuse , opacity ) ;
# include < clipping _planes _fragment >
ReflectedLight reflectedLight = ReflectedLight ( vec3 ( 0.0 ) , vec3 ( 0.0 ) , vec3 ( 0.0 ) , vec3 ( 0.0 ) ) ;
vec3 totalEmissiveRadiance = emissive ;
# include < logdepthbuf _fragment >
# include < map _fragment >
# include < color _fragment >
# include < alphamap _fragment >
# include < alphatest _fragment >
# include < alphahash _fragment >
# include < normal _fragment _begin >
# include < normal _fragment _maps >
# include < emissivemap _fragment >
# include < lights _toon _fragment >
# include < lights _fragment _begin >
# include < lights _fragment _maps >
# include < lights _fragment _end >
# include < aomap _fragment >
vec3 outgoingLight = reflectedLight . directDiffuse + reflectedLight . indirectDiffuse + totalEmissiveRadiance ;
# include < opaque _fragment >
# include < tonemapping _fragment >
# include < colorspace _fragment >
# include < fog _fragment >
# include < premultiplied _alpha _fragment >
# include < dithering _fragment >
} ` ,points_vert: ` uniform float size ;
uniform float scale ;
# include < common >
# include < color _pars _vertex >
# include < fog _pars _vertex >
# include < morphtarget _pars _vertex >
# include < logdepthbuf _pars _vertex >
# include < clipping _planes _pars _vertex >
# ifdef USE _POINTS _UV
varying vec2 vUv ;
uniform mat3 uvTransform ;
# endif
void main ( ) {
# ifdef USE _POINTS _UV
vUv = ( uvTransform * vec3 ( uv , 1 ) ) . xy ;
# endif
# include < color _vertex >
# include < morphinstance _vertex >
# include < morphcolor _vertex >
# include < begin _vertex >
# include < morphtarget _vertex >
# include < project _vertex >
gl _PointSize = size ;
# ifdef USE _SIZEATTENUATION
bool isPerspective = isPerspectiveMatrix ( projectionMatrix ) ;
if ( isPerspective ) gl _PointSize *= ( scale / - mvPosition . z ) ;
# endif
# include < logdepthbuf _vertex >
# include < clipping _planes _vertex >
# include < worldpos _vertex >
# include < fog _vertex >
} ` ,points_frag: ` uniform vec3 diffuse ;
uniform float opacity ;
# include < common >
# include < color _pars _fragment >
# include < map _particle _pars _fragment >
# include < alphatest _pars _fragment >
# include < alphahash _pars _fragment >
# include < fog _pars _fragment >
# include < logdepthbuf _pars _fragment >
# include < clipping _planes _pars _fragment >
void main ( ) {
vec4 diffuseColor = vec4 ( diffuse , opacity ) ;
# include < clipping _planes _fragment >
vec3 outgoingLight = vec3 ( 0.0 ) ;
# include < logdepthbuf _fragment >
# include < map _particle _fragment >
# include < color _fragment >
# include < alphatest _fragment >
# include < alphahash _fragment >
outgoingLight = diffuseColor . rgb ;
# include < opaque _fragment >
# include < tonemapping _fragment >
# include < colorspace _fragment >
# include < fog _fragment >
# include < premultiplied _alpha _fragment >
} ` ,shadow_vert: ` # include < common >
# include < batching _pars _vertex >
# include < fog _pars _vertex >
# include < morphtarget _pars _vertex >
# include < skinning _pars _vertex >
# include < logdepthbuf _pars _vertex >
# include < shadowmap _pars _vertex >
void main ( ) {
# include < batching _vertex >
# include < beginnormal _vertex >
# include < morphinstance _vertex >
# include < morphnormal _vertex >
# include < skinbase _vertex >
# include < skinnormal _vertex >
# include < defaultnormal _vertex >
# include < begin _vertex >
# include < morphtarget _vertex >
# include < skinning _vertex >
# include < project _vertex >
# include < logdepthbuf _vertex >
# include < worldpos _vertex >
# include < shadowmap _vertex >
# include < fog _vertex >
} ` ,shadow_frag: ` uniform vec3 color ;
uniform float opacity ;
# include < common >
# include < packing >
# include < fog _pars _fragment >
# include < bsdfs >
# include < lights _pars _begin >
# include < logdepthbuf _pars _fragment >
# include < shadowmap _pars _fragment >
# include < shadowmask _pars _fragment >
void main ( ) {
# include < logdepthbuf _fragment >
gl _FragColor = vec4 ( color , opacity * ( 1.0 - getShadowMask ( ) ) ) ;
# include < tonemapping _fragment >
# include < colorspace _fragment >
# include < fog _fragment >
} ` ,sprite_vert: ` uniform float rotation ;
uniform vec2 center ;
# include < common >
# include < uv _pars _vertex >
# include < fog _pars _vertex >
# include < logdepthbuf _pars _vertex >
# include < clipping _planes _pars _vertex >
void main ( ) {
# include < uv _vertex >
vec4 mvPosition = modelViewMatrix [ 3 ] ;
vec2 scale = vec2 ( length ( modelMatrix [ 0 ] . xyz ) , length ( modelMatrix [ 1 ] . xyz ) ) ;
# ifndef USE _SIZEATTENUATION
bool isPerspective = isPerspectiveMatrix ( projectionMatrix ) ;
if ( isPerspective ) scale *= - mvPosition . z ;
# endif
vec2 alignedPosition = ( position . xy - ( center - vec2 ( 0.5 ) ) ) * scale ;
vec2 rotatedPosition ;
rotatedPosition . x = cos ( rotation ) * alignedPosition . x - sin ( rotation ) * alignedPosition . y ;
rotatedPosition . y = sin ( rotation ) * alignedPosition . x + cos ( rotation ) * alignedPosition . y ;
mvPosition . xy += rotatedPosition ;
gl _Position = projectionMatrix * mvPosition ;
# include < logdepthbuf _vertex >
# include < clipping _planes _vertex >
# include < fog _vertex >
} ` ,sprite_frag: ` uniform vec3 diffuse ;
uniform float opacity ;
# include < common >
# include < uv _pars _fragment >
# include < map _pars _fragment >
# include < alphamap _pars _fragment >
# include < alphatest _pars _fragment >
# include < alphahash _pars _fragment >
# include < fog _pars _fragment >
# include < logdepthbuf _pars _fragment >
# include < clipping _planes _pars _fragment >
void main ( ) {
vec4 diffuseColor = vec4 ( diffuse , opacity ) ;
# include < clipping _planes _fragment >
vec3 outgoingLight = vec3 ( 0.0 ) ;
# include < logdepthbuf _fragment >
# include < map _fragment >
# include < alphamap _fragment >
# include < alphatest _fragment >
# include < alphahash _fragment >
outgoingLight = diffuseColor . rgb ;
# include < opaque _fragment >
# include < tonemapping _fragment >
# include < colorspace _fragment >
# include < fog _fragment >
2026-01-22 15:23:57 +08:00
} ` },Pe={common:{diffuse:{value:new Fe(16777215)},opacity:{value:1},map:{value:null},mapTransform:{value:new Je},alphaMap:{value:null},alphaMapTransform:{value:new Je},alphaTest:{value:0}},specularmap:{specularMap:{value:null},specularMapTransform:{value:new Je}},envmap:{envMap:{value:null},envMapRotation:{value:new Je},flipEnvMap:{value:-1},reflectivity:{value:1},ior:{value:1.5},refractionRatio:{value:.98},dfgLUT:{value:null}},aomap:{aoMap:{value:null},aoMapIntensity:{value:1},aoMapTransform:{value:new Je}},lightmap:{lightMap:{value:null},lightMapIntensity:{value:1},lightMapTransform:{value:new Je}},bumpmap:{bumpMap:{value:null},bumpMapTransform:{value:new Je},bumpScale:{value:1}},normalmap:{normalMap:{value:null},normalMapTransform:{value:new Je},normalScale:{value:new ue(1,1)}},displacementmap:{displacementMap:{value:null},displacementMapTransform:{value:new Je},displacementScale:{value:1},displacementBias:{value:0}},emissivemap:{emissiveMap:{value:null},emissiveMapTransform:{value:new Je}},metalnessmap:{metalnessMap:{value:null},metalnessMapTransform:{value:new Je}},roughnessmap:{roughnessMap:{value:null},roughnessMapTransform:{value:new Je}},gradientmap:{gradientMap:{value:null}},fog:{fogDensity:{value:25e-5},fogNear:{value:1},fogFar:{value:2e3},fogColor:{value:new Fe(16777215)}},lights:{ambientLightColor:{value:[]},lightProbe:{value:[]},directionalLights:{value:[],properties:{direction:{},color:{}}},directionalLightShadows:{value:[],properties:{shadowIntensity:1,shadowBias:{},shadowNormalBias:{},shadowRadius:{},shadowMapSize:{}}},directionalShadowMap:{value:[]},directionalShadowMatrix:{value:[]},spotLights:{value:[],properties:{color:{},position:{},direction:{},distance:{},coneCos:{},penumbraCos:{},decay:{}}},spotLightShadows:{value:[],properties:{shadowIntensity:1,shadowBias:{},shadowNormalBias:{},shadowRadius:{},shadowMapSize:{}}},spotLightMap:{value:[]},spotShadowMap:{value:[]},spotLightMatrix:{value:[]},pointLights:{value:[],properties:{color:{},position:{},decay:{},distance:{}}},pointLightShadows:{value:[],properties:{shadowIntensity:1,shadowBias:{},shadowNormalBias:{},shadowRadius:{},shadowMapSize:{},shadowCameraNear:{},shadowCameraFar:{}}},pointShadowMap:{value:[]},pointShadowMatrix:{value:[]},hemisphereLights:{value:[],properties:{direction:{},skyColor:{},groundColor:{}}},rectAreaLights:{value:[],properties:{color:{},position:{},width:{},height:{}}},ltc_1:{value:null},ltc_2:{value:null}},points:{diffuse:{value:new Fe(16777215)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},alphaMap:{value:null},alphaMapTransform:{value:new Je},alphaTest:{value:0},uvTransform:{value:new Je}},sprite:{diffuse:{value:new Fe(16777215)},opacity:{value:1},center:{value:new ue(.5,.5)},rotation:{value:0},map:{value:null},mapTransform:{value:new Je},alphaMap:{value:null},alphaMapTransform:{value:new Je},alphaTest:{value:0}}},Gn={basic:{uniforms:Kt([Pe.common,Pe.specularmap,Pe.envmap,Pe.aomap,Pe.lightmap,Pe.fog]),vertexShader:Qe.meshbasic_vert,fragmentShader:Qe.meshbasic_frag},lambert:{uniforms:Kt([Pe.common,Pe.specularmap,Pe.envmap,Pe.aomap,Pe.lightmap,Pe.emissivemap,Pe.bumpmap,Pe.normalmap,Pe.displacementmap,Pe.fog,Pe.lights,{emissive:{value:new Fe(0)}}]),vertexShader:Qe.meshlambert_vert,fragmentShader:Qe.meshlambert_frag},phong:{uniforms:Kt([Pe.common,Pe.specularmap,Pe.envmap,Pe.aomap,Pe.lightmap,Pe.emissivemap,Pe.bumpmap,Pe.normalmap,Pe.displacementmap,Pe.fog,Pe.lights,{emissive:{value:new Fe(0)},specular:{value:new Fe(1118481)},shininess:{value:30}}]),vertexShader:Qe.meshphong_vert,fragmentShader:Qe.meshphong_frag},standard:{uniforms:Kt([Pe.common,Pe.envmap,Pe.aomap,Pe.lightmap,Pe.emissivemap,Pe.bumpmap,Pe.normalmap,Pe.displacementmap,Pe.roughnessmap,Pe.metalnessmap,Pe.fog,Pe.lights,{emissive:{value:new Fe(0)},roughness:{value:1},metalness:{value:0},envMapIntensity:{value:1}}]),vertexShader:Qe.meshphysical_vert,fragmentShader:Qe.meshphysical_frag},toon:{uniforms:Kt([Pe.common,Pe.aomap,Pe.lightmap,Pe.emissivemap,Pe.bumpmap,Pe.normalmap,Pe.displacementmap,Pe.gradientmap,Pe.fog,Pe.lights,{emissive:{value:new Fe(0
2026-01-22 11:29:51 +08:00
precision highp float ;
precision highp int ;
varying vec3 vOutputDirection ;
uniform sampler2D envMap ;
uniform float roughness ;
uniform float mipInt ;
# define ENVMAP _TYPE _CUBE _UV
# include < cube _uv _reflection _fragment >
# define PI 3.14159265359
// Van der Corput radical inverse
float radicalInverse _VdC ( uint bits ) {
bits = ( bits << 16 u ) | ( bits >> 16 u ) ;
bits = ( ( bits & 0x55555555 u ) << 1 u ) | ( ( bits & 0xAAAAAAAA u ) >> 1 u ) ;
bits = ( ( bits & 0x33333333 u ) << 2 u ) | ( ( bits & 0xCCCCCCCC u ) >> 2 u ) ;
bits = ( ( bits & 0x0F0F0F0F u ) << 4 u ) | ( ( bits & 0xF0F0F0F0 u ) >> 4 u ) ;
bits = ( ( bits & 0x00FF00FF u ) << 8 u ) | ( ( bits & 0xFF00FF00 u ) >> 8 u ) ;
return float ( bits ) * 2.3283064365386963 e - 10 ; // / 0x100000000
}
// Hammersley sequence
vec2 hammersley ( uint i , uint N ) {
return vec2 ( float ( i ) / float ( N ) , radicalInverse _VdC ( i ) ) ;
}
// GGX VNDF importance sampling (Eric Heitz 2018)
// "Sampling the GGX Distribution of Visible Normals"
// https://jcgt.org/published/0007/04/01/
vec3 importanceSampleGGX _VNDF ( vec2 Xi , vec3 V , float roughness ) {
float alpha = roughness * roughness ;
// Section 3.2: Transform view direction to hemisphere configuration
vec3 Vh = normalize ( vec3 ( alpha * V . x , alpha * V . y , V . z ) ) ;
// Section 4.1: Orthonormal basis
float lensq = Vh . x * Vh . x + Vh . y * Vh . y ;
vec3 T1 = lensq > 0.0 ? vec3 ( - Vh . y , Vh . x , 0.0 ) / sqrt ( lensq ) : vec3 ( 1.0 , 0.0 , 0.0 ) ;
vec3 T2 = cross ( Vh , T1 ) ;
// Section 4.2: Parameterization of projected area
float r = sqrt ( Xi . x ) ;
float phi = 2.0 * PI * Xi . y ;
float t1 = r * cos ( phi ) ;
float t2 = r * sin ( phi ) ;
float s = 0.5 * ( 1.0 + Vh . z ) ;
t2 = ( 1.0 - s ) * sqrt ( 1.0 - t1 * t1 ) + s * t2 ;
// Section 4.3: Reprojection onto hemisphere
vec3 Nh = t1 * T1 + t2 * T2 + sqrt ( max ( 0.0 , 1.0 - t1 * t1 - t2 * t2 ) ) * Vh ;
// Section 3.4: Transform back to ellipsoid configuration
return normalize ( vec3 ( alpha * Nh . x , alpha * Nh . y , max ( 0.0 , Nh . z ) ) ) ;
}
void main ( ) {
vec3 N = normalize ( vOutputDirection ) ;
vec3 V = N ; // Assume view direction equals normal for pre-filtering
vec3 prefilteredColor = vec3 ( 0.0 ) ;
float totalWeight = 0.0 ;
// For very low roughness, just sample the environment directly
if ( roughness < 0.001 ) {
gl _FragColor = vec4 ( bilinearCubeUV ( envMap , N , mipInt ) , 1.0 ) ;
return ;
}
// Tangent space basis for VNDF sampling
vec3 up = abs ( N . z ) < 0.999 ? vec3 ( 0.0 , 0.0 , 1.0 ) : vec3 ( 1.0 , 0.0 , 0.0 ) ;
vec3 tangent = normalize ( cross ( up , N ) ) ;
vec3 bitangent = cross ( N , tangent ) ;
for ( uint i = 0 u ; i < uint ( GGX _SAMPLES ) ; i ++ ) {
vec2 Xi = hammersley ( i , uint ( GGX _SAMPLES ) ) ;
// For PMREM, V = N, so in tangent space V is always (0, 0, 1)
vec3 H _tangent = importanceSampleGGX _VNDF ( Xi , vec3 ( 0.0 , 0.0 , 1.0 ) , roughness ) ;
// Transform H back to world space
vec3 H = normalize ( tangent * H _tangent . x + bitangent * H _tangent . y + N * H _tangent . z ) ;
vec3 L = normalize ( 2.0 * dot ( V , H ) * H - V ) ;
float NdotL = max ( dot ( N , L ) , 0.0 ) ;
if ( NdotL > 0.0 ) {
// Sample environment at fixed mip level
// VNDF importance sampling handles the distribution filtering
vec3 sampleColor = bilinearCubeUV ( envMap , L , mipInt ) ;
// Weight by NdotL for the split-sum approximation
// VNDF PDF naturally accounts for the visible microfacet distribution
prefilteredColor += sampleColor * NdotL ;
totalWeight += NdotL ;
}
}
if ( totalWeight > 0.0 ) {
prefilteredColor = prefilteredColor / totalWeight ;
}
gl _FragColor = vec4 ( prefilteredColor , 1.0 ) ;
}
2026-01-22 15:23:57 +08:00
` ,blending:Ot,depthTest:!1,depthWrite:!1})}function Tx(s,e,t){const n=new Float32Array(Ii),i=new P(0,1,0);return new Rt({name:"SphericalGaussianBlur",defines:{n:Ii,CUBEUV_TEXEL_WIDTH:1/e,CUBEUV_TEXEL_HEIGHT:1/t,CUBEUV_MAX_MIP: ` $ { s } . 0 ` },uniforms:{envMap:{value:null},samples:{value:1},weights:{value:n},latitudinal:{value:!1},dTheta:{value:0},mipInt:{value:0},poleAxis:{value:i}},vertexShader:pa(),fragmentShader: `
2026-01-22 11:29:51 +08:00
precision mediump float ;
precision mediump int ;
varying vec3 vOutputDirection ;
uniform sampler2D envMap ;
uniform int samples ;
uniform float weights [ n ] ;
uniform bool latitudinal ;
uniform float dTheta ;
uniform float mipInt ;
uniform vec3 poleAxis ;
# define ENVMAP _TYPE _CUBE _UV
# include < cube _uv _reflection _fragment >
vec3 getSample ( float theta , vec3 axis ) {
float cosTheta = cos ( theta ) ;
// Rodrigues' axis-angle rotation
vec3 sampleDirection = vOutputDirection * cosTheta
+ cross ( axis , vOutputDirection ) * sin ( theta )
+ axis * dot ( axis , vOutputDirection ) * ( 1.0 - cosTheta ) ;
return bilinearCubeUV ( envMap , sampleDirection , mipInt ) ;
}
void main ( ) {
vec3 axis = latitudinal ? poleAxis : cross ( poleAxis , vOutputDirection ) ;
if ( all ( equal ( axis , vec3 ( 0.0 ) ) ) ) {
axis = vec3 ( vOutputDirection . z , 0.0 , - vOutputDirection . x ) ;
}
axis = normalize ( axis ) ;
gl _FragColor = vec4 ( 0.0 , 0.0 , 0.0 , 1.0 ) ;
gl _FragColor . rgb += weights [ 0 ] * getSample ( 0.0 , axis ) ;
for ( int i = 1 ; i < n ; i ++ ) {
if ( i >= samples ) {
break ;
}
float theta = dTheta * float ( i ) ;
gl _FragColor . rgb += weights [ i ] * getSample ( - 1.0 * theta , axis ) ;
gl _FragColor . rgb += weights [ i ] * getSample ( theta , axis ) ;
}
}
2026-01-22 15:23:57 +08:00
` ,blending:Ot,depthTest:!1,depthWrite:!1})}function Su(){return new Rt({name:"EquirectangularToCubeUV",uniforms:{envMap:{value:null}},vertexShader:pa(),fragmentShader: `
2026-01-22 11:29:51 +08:00
precision mediump float ;
precision mediump int ;
varying vec3 vOutputDirection ;
uniform sampler2D envMap ;
# include < common >
void main ( ) {
vec3 outputDirection = normalize ( vOutputDirection ) ;
vec2 uv = equirectUv ( outputDirection ) ;
gl _FragColor = vec4 ( texture2D ( envMap , uv ) . rgb , 1.0 ) ;
}
2026-01-22 15:23:57 +08:00
` ,blending:Ot,depthTest:!1,depthWrite:!1})}function wu(){return new Rt({name:"CubemapToCubeUV",uniforms:{envMap:{value:null},flipEnvMap:{value:-1}},vertexShader:pa(),fragmentShader: `
2026-01-22 11:29:51 +08:00
precision mediump float ;
precision mediump int ;
uniform float flipEnvMap ;
varying vec3 vOutputDirection ;
uniform samplerCube envMap ;
void main ( ) {
gl _FragColor = textureCube ( envMap , vec3 ( flipEnvMap * vOutputDirection . x , vOutputDirection . yz ) ) ;
}
2026-01-22 15:23:57 +08:00
` ,blending:Ot,depthTest:!1,depthWrite:!1})}function pa(){return `
2026-01-22 11:29:51 +08:00
precision mediump float ;
precision mediump int ;
attribute float faceIndex ;
varying vec3 vOutputDirection ;
// RH coordinate system; PMREM face-indexing convention
vec3 getDirection ( vec2 uv , float face ) {
uv = 2.0 * uv - 1.0 ;
vec3 direction = vec3 ( uv , 1.0 ) ;
if ( face == 0.0 ) {
direction = direction . zyx ; // ( 1, v, u ) pos x
} else if ( face == 1.0 ) {
direction = direction . xzy ;
direction . xz *= - 1.0 ; // ( -u, 1, -v ) pos y
} else if ( face == 2.0 ) {
direction . x *= - 1.0 ; // ( -u, v, 1 ) pos z
} else if ( face == 3.0 ) {
direction = direction . zyx ;
direction . xz *= - 1.0 ; // ( -1, v, -u ) neg x
} else if ( face == 4.0 ) {
direction = direction . xzy ;
direction . xy *= - 1.0 ; // ( -u, -1, v ) neg y
} else if ( face == 5.0 ) {
direction . z *= - 1.0 ; // ( u, v, -1 ) neg z
}
return direction ;
}
void main ( ) {
vOutputDirection = getDirection ( uv , faceIndex ) ;
gl _Position = vec4 ( position , 1.0 ) ;
}
2026-01-22 15:23:57 +08:00
` }function Cx(s){let e=new WeakMap,t=null;function n(o){if(o&&o.isTexture){const l=o.mapping,c=l===io||l===so,h=l===qi||l===Yi;if(c||h){let u=e.get(o);const f=u!==void 0?u.texture.pmremVersion:0;if(o.isRenderTargetTexture&&o.pmremVersion!==f)return t===null&&(t=new yu(s)),u=c?t.fromEquirectangular(o,u):t.fromCubemap(o,u),u.texture.pmremVersion=o.pmremVersion,e.set(o,u),u.texture;if(u!==void 0)return u.texture;{const d=o.image;return c&&d&&d.height>0||h&&d&&i(d)?(t===null&&(t=new yu(s)),u=c?t.fromEquirectangular(o):t.fromCubemap(o),u.texture.pmremVersion=o.pmremVersion,e.set(o,u),o.addEventListener("dispose",r),u.texture):null}}}return o}function i(o){let l=0;const c=6;for(let h=0;h<c;h++)o[h]!==void 0&&l++;return l===c}function r(o){const l=o.target;l.removeEventListener("dispose",r);const c=e.get(l);c!==void 0&&(e.delete(l),c.dispose())}function a(){e=new WeakMap,t!==null&&(t.dispose(),t=null)}return{get:n,dispose:a}}function Ax(s){const e={};function t(n){if(e[n]!==void 0)return e[n];const i=s.getExtension(n);return e[n]=i,i}return{has:function(n){return t(n)!==null},init:function(){t("EXT_color_buffer_float"),t("WEBGL_clip_cull_distance"),t("OES_texture_float_linear"),t("EXT_color_buffer_half_float"),t("WEBGL_multisampled_render_to_texture"),t("WEBGL_render_shared_exponent")},get:function(n){const i=t(n);return i===null&&Ws("WebGLRenderer: "+n+" extension not supported."),i}}}function Px(s,e,t,n){const i={},r=new WeakMap;function a(u){const f=u.target;f.index!==null&&e.remove(f.index);for(const p in f.attributes)e.remove(f.attributes[p]);f.removeEventListener("dispose",a),delete i[f.id];const d=r.get(f);d&&(e.remove(d),r.delete(f)),n.releaseStatesOfGeometry(f),f.isInstancedBufferGeometry===!0&&delete f._maxInstanceCount,t.memory.geometries--}function o(u,f){return i[f.id]===!0||(f.addEventListener("dispose",a),i[f.id]=!0,t.memory.geometries++),f}function l(u){const f=u.attributes;for(const d in f)e.update(f[d],s.ARRAY_BUFFER)}function c(u){const f=[],d=u.index,p=u.attributes.position;let g=0;if(d!==null){const v=d.array;g=d.version;for(let b=0,M=v.length;b<M;b+=3){const C=v[b+0],T=v[b+1],D=v[b+2];f.push(C,T,T,D,D,C)}}else if(p!==void 0){const v=p.array;g=p.version;for(let b=0,M=v.length/3-1;b<M;b+=3){const C=b+0,T=b+1,D=b+2;f.push(C,T,T,D,D,C)}}else return;const x=new(eh(f)?xh:gh)(f,1);x.version=g;const m=r.get(u);m&&e.remove(m),r.set(u,x)}function h(u){const f=r.get(u);if(f){const d=u.index;d!==null&&f.version<d.version&&c(u)}else c(u);return r.get(u)}return{get:o,update:l,getWireframeAttribute:h}}function Rx(s,e,t){let n;function i(f){n=f}let r,a;function o(f){r=f.type,a=f.bytesPerElement}function l(f,d){s.drawElements(n,d,r,f*a),t.update(d,n,1)}function c(f,d,p){p!==0&&(s.drawElementsInstanced(n,d,r,f*a,p),t.update(d,n,p))}function h(f,d,p){if(p===0)return;e.get("WEBGL_multi_draw").multiDrawElementsWEBGL(n,d,0,r,f,0,p);let x=0;for(let m=0;m<p;m++)x+=d[m];t.update(x,n,1)}function u(f,d,p,g){if(p===0)return;const x=e.get("WEBGL_multi_draw");if(x===null)for(let m=0;m<f.length;m++)c(f[m]/a,d[m],g[m]);else{x.multiDrawElementsInstancedWEBGL(n,d,0,r,f,0,g,0,p);let m=0;for(let v=0;v<p;v++)m+=d[v]*g[v];t.update(m,n,1)}}this.setMode=i,this.setIndex=o,this.render=l,this.renderInstances=c,this.renderMultiDraw=h,this.renderMultiDrawInstances=u}function Lx(s){const e={geometries:0,textures:0},t={frame:0,calls:0,triangles:0,points:0,lines:0};function n(r,a,o){switch(t.calls++,a){case s.TRIANGLES:t.triangles+=o*(r/3);break;case s.LINES:t.lines+=o*(r/2);break;case s.LINE_STRIP:t.lines+=o*(r-1);break;case s.LINE_LOOP:t.lines+=o*r;break;case s.POINTS:t.points+=o*r;break;default:et("WebGLInfo: Unknown draw mode:",a);break}}function i(){t.calls=0,t.triangles=0,t.points=0,t.lines=0}return{memory:e,render:t,programs:null,autoReset:!0,reset:i,update:n}}function Dx(s,e,t){const n=new WeakMap,i=new at;function r(a,o,l){const c=a.morphTargetInfluences,h=o.morphAttributes.position||o.morphAttributes.normal||o.morphAttributes.color,u=h!==void 0?h.length:0;let f=n.get(o);if(f===void 0||f.count!==u){let S=function(){D.dispose(),n.delete(o),o.r
2026-01-22 11:29:51 +08:00
` ),n=[],i=Math.max(e-6,0),r=Math.min(e+6,t.length);for(let a=i;a<r;a++){const o=a+1;n.push( ` $ { o === e ? ">" : " " } $ { o } : $ { t [ a ] } ` )}return n.join( `
2026-01-22 15:23:57 +08:00
` )}const Bu=new Je;function C1(s){nt._getMatrix(Bu,nt.workingColorSpace,s);const e= ` mat3 ( $ { Bu . elements . map ( t => t . toFixed ( 4 ) ) } ) ` ;switch(nt.getTransfer(s)){case Lr:return[e,"LinearTransferOETF"];case ot:return[e,"sRGBTransferOETF"];default:return ze("WebGLProgram: Unsupported color space: ",s),[e,"LinearTransferOETF"]}}function Ou(s,e,t){const n=s.getShaderParameter(e,s.COMPILE_STATUS),r=(s.getShaderInfoLog(e)||"").trim();if(n&&r==="")return"";const a=/ERROR: 0:( \d +)/.exec(r);if(a){const o=parseInt(a[1]);return t.toUpperCase()+ `
2026-01-22 11:29:51 +08:00
` +r+ `
2026-01-22 15:23:57 +08:00
` +T1(s.getShaderSource(e),o)}else return r}function A1(s,e){const t=C1(e);return[ ` vec4 $ { s } ( vec4 value ) { ` , ` return $ { t [ 1 ] } ( vec4 ( value . rgb * $ { t [ 0 ] } , value . a ) ) ; ` ,"}"].join( `
` )}function P1(s,e){let t;switch(e){case Ic:t="Linear";break;case Nc:t="Reinhard";break;case kc:t="Cineon";break;case no:t="ACESFilmic";break;case Bc:t="AgX";break;case Oc:t="Neutral";break;case Uc:t="Custom";break;default:ze("WebGLProgram: Unsupported toneMapping:",e),t="Linear"}return"vec3 "+s+"( vec3 color ) { return "+t+"ToneMapping( color ); }"}const xa=new P;function R1(){nt.getLuminanceCoefficients(xa);const s=xa.x.toFixed(4),e=xa.y.toFixed(4),t=xa.z.toFixed(4);return["float luminance( const in vec3 rgb ) {", ` const vec3 weights = vec3 ( $ { s } , $ { e } , $ { t } ) ; ` ," return dot( weights, rgb );","}"].join( `
` )}function L1(s){return[s.extensionClipCullDistance?"#extension GL_ANGLE_clip_cull_distance : require":"",s.extensionMultiDraw?"#extension GL_ANGLE_multi_draw : require":""].filter(dr).join( `
` )}function D1(s){const e=[];for(const t in s){const n=s[t];n!==!1&&e.push("#define "+t+" "+n)}return e.join( `
` )}function I1(s,e){const t={},n=s.getProgramParameter(e,s.ACTIVE_ATTRIBUTES);for(let i=0;i<n;i++){const r=s.getActiveAttrib(e,i),a=r.name;let o=1;r.type===s.FLOAT_MAT2&&(o=2),r.type===s.FLOAT_MAT3&&(o=3),r.type===s.FLOAT_MAT4&&(o=4),t[a]={type:r.type,location:s.getAttribLocation(e,a),locationSize:o}}return t}function dr(s){return s!==""}function Fu(s,e){const t=e.numSpotLightShadows+e.numSpotLightMaps-e.numSpotLightShadowsWithMaps;return s.replace(/NUM_DIR_LIGHTS/g,e.numDirLights).replace(/NUM_SPOT_LIGHTS/g,e.numSpotLights).replace(/NUM_SPOT_LIGHT_MAPS/g,e.numSpotLightMaps).replace(/NUM_SPOT_LIGHT_COORDS/g,t).replace(/NUM_RECT_AREA_LIGHTS/g,e.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g,e.numPointLights).replace(/NUM_HEMI_LIGHTS/g,e.numHemiLights).replace(/NUM_DIR_LIGHT_SHADOWS/g,e.numDirLightShadows).replace(/NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS/g,e.numSpotLightShadowsWithMaps).replace(/NUM_SPOT_LIGHT_SHADOWS/g,e.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g,e.numPointLightShadows)}function zu(s,e){return s.replace(/NUM_CLIPPING_PLANES/g,e.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g,e.numClippingPlanes-e.numClipIntersection)}const N1=/^[ \t ]*#include +<([ \w \d ./]+)>/gm;function Kl(s){return s.replace(N1,U1)}const k1=new Map;function U1(s,e){let t=Qe[e];if(t===void 0){const n=k1.get(e);if(n!==void 0)t=Qe[n],ze('WebGLRenderer: Shader chunk "%s" has been deprecated. Use "%s" instead.',e,n);else throw new Error("Can not resolve #include <"+e+">")}return Kl(t)}const B1=/#pragma unroll_loop_start \s +for \s * \( \s *int \s +i \s *= \s *( \d +) \s *; \s *i \s *< \s *( \d +) \s *; \s *i \s * \+ \+ \s * \) \s *{([ \s \S ]+?)} \s +#pragma unroll_loop_end/g;function Hu(s){return s.replace(B1,O1)}function O1(s,e,t,n){let i="";for(let r=parseInt(e);r<parseInt(t);r++)i+=n.replace(/ \[ \s *i \s * \] /g,"[ "+r+" ]").replace(/UNROLLED_LOOP_INDEX/g,r);return i}function Vu(s){let e= ` precision $ { s . precision } float ;
2026-01-22 11:29:51 +08:00
precision $ { s . precision } int ;
precision $ { s . precision } sampler2D ;
precision $ { s . precision } samplerCube ;
precision $ { s . precision } sampler3D ;
precision $ { s . precision } sampler2DArray ;
precision $ { s . precision } sampler2DShadow ;
precision $ { s . precision } samplerCubeShadow ;
precision $ { s . precision } sampler2DArrayShadow ;
precision $ { s . precision } isampler2D ;
precision $ { s . precision } isampler3D ;
precision $ { s . precision } isamplerCube ;
precision $ { s . precision } isampler2DArray ;
precision $ { s . precision } usampler2D ;
precision $ { s . precision } usampler3D ;
precision $ { s . precision } usamplerCube ;
precision $ { s . precision } usampler2DArray ;
` ;return s.precision==="highp"?e+= `
# define HIGH _PRECISION ` :s.precision==="mediump"?e+= `
# define MEDIUM _PRECISION ` :s.precision==="lowp"&&(e+= `
2026-01-22 15:23:57 +08:00
# define LOW _PRECISION ` ),e}function F1(s){let e="SHADOWMAP_TYPE_BASIC";return s.shadowMapType===Ac?e="SHADOWMAP_TYPE_PCF":s.shadowMapType===Pc?e="SHADOWMAP_TYPE_PCF_SOFT":s.shadowMapType===qn&&(e="SHADOWMAP_TYPE_VSM"),e}function z1(s){let e="ENVMAP_TYPE_CUBE";if(s.envMap)switch(s.envMapMode){case qi:case Yi:e="ENVMAP_TYPE_CUBE";break;case wr:e="ENVMAP_TYPE_CUBE_UV";break}return e}function H1(s){let e="ENVMAP_MODE_REFLECTION";if(s.envMap)switch(s.envMapMode){case Yi:e="ENVMAP_MODE_REFRACTION";break}return e}function V1(s){let e="ENVMAP_BLENDING_NONE";if(s.envMap)switch(s.combine){case Sr:e="ENVMAP_BLENDING_MULTIPLY";break;case Hf:e="ENVMAP_BLENDING_MIX";break;case Vf:e="ENVMAP_BLENDING_ADD";break}return e}function G1(s){const e=s.envMapCubeUVHeight;if(e===null)return null;const t=Math.log2(e)-2,n=1/e;return{texelWidth:1/(3*Math.max(Math.pow(2,t),112)),texelHeight:n,maxMip:t}}function W1(s,e,t,n){const i=s.getContext(),r=t.defines;let a=t.vertexShader,o=t.fragmentShader;const l=F1(t),c=z1(t),h=H1(t),u=V1(t),f=G1(t),d=L1(t),p=D1(r),g=i.createProgram();let x,m,v=t.glslVersion?"#version "+t.glslVersion+ `
` :"";t.isRawShaderMaterial?(x=["#define SHADER_TYPE "+t.shaderType,"#define SHADER_NAME "+t.shaderName,p].filter(dr).join( `
2026-01-22 11:29:51 +08:00
` ),x.length>0&&(x+= `
2026-01-22 15:23:57 +08:00
` ),m=["#define SHADER_TYPE "+t.shaderType,"#define SHADER_NAME "+t.shaderName,p].filter(dr).join( `
2026-01-22 11:29:51 +08:00
` ),m.length>0&&(m+= `
2026-01-22 15:23:57 +08:00
` )):(x=[Vu(t),"#define SHADER_TYPE "+t.shaderType,"#define SHADER_NAME "+t.shaderName,p,t.extensionClipCullDistance?"#define USE_CLIP_DISTANCE":"",t.batching?"#define USE_BATCHING":"",t.batchingColor?"#define USE_BATCHING_COLOR":"",t.instancing?"#define USE_INSTANCING":"",t.instancingColor?"#define USE_INSTANCING_COLOR":"",t.instancingMorph?"#define USE_INSTANCING_MORPH":"",t.useFog&&t.fog?"#define USE_FOG":"",t.useFog&&t.fogExp2?"#define FOG_EXP2":"",t.map?"#define USE_MAP":"",t.envMap?"#define USE_ENVMAP":"",t.envMap?"#define "+h:"",t.lightMap?"#define USE_LIGHTMAP":"",t.aoMap?"#define USE_AOMAP":"",t.bumpMap?"#define USE_BUMPMAP":"",t.normalMap?"#define USE_NORMALMAP":"",t.normalMapObjectSpace?"#define USE_NORMALMAP_OBJECTSPACE":"",t.normalMapTangentSpace?"#define USE_NORMALMAP_TANGENTSPACE":"",t.displacementMap?"#define USE_DISPLACEMENTMAP":"",t.emissiveMap?"#define USE_EMISSIVEMAP":"",t.anisotropy?"#define USE_ANISOTROPY":"",t.anisotropyMap?"#define USE_ANISOTROPYMAP":"",t.clearcoatMap?"#define USE_CLEARCOATMAP":"",t.clearcoatRoughnessMap?"#define USE_CLEARCOAT_ROUGHNESSMAP":"",t.clearcoatNormalMap?"#define USE_CLEARCOAT_NORMALMAP":"",t.iridescenceMap?"#define USE_IRIDESCENCEMAP":"",t.iridescenceThicknessMap?"#define USE_IRIDESCENCE_THICKNESSMAP":"",t.specularMap?"#define USE_SPECULARMAP":"",t.specularColorMap?"#define USE_SPECULAR_COLORMAP":"",t.specularIntensityMap?"#define USE_SPECULAR_INTENSITYMAP":"",t.roughnessMap?"#define USE_ROUGHNESSMAP":"",t.metalnessMap?"#define USE_METALNESSMAP":"",t.alphaMap?"#define USE_ALPHAMAP":"",t.alphaHash?"#define USE_ALPHAHASH":"",t.transmission?"#define USE_TRANSMISSION":"",t.transmissionMap?"#define USE_TRANSMISSIONMAP":"",t.thicknessMap?"#define USE_THICKNESSMAP":"",t.sheenColorMap?"#define USE_SHEEN_COLORMAP":"",t.sheenRoughnessMap?"#define USE_SHEEN_ROUGHNESSMAP":"",t.mapUv?"#define MAP_UV "+t.mapUv:"",t.alphaMapUv?"#define ALPHAMAP_UV "+t.alphaMapUv:"",t.lightMapUv?"#define LIGHTMAP_UV "+t.lightMapUv:"",t.aoMapUv?"#define AOMAP_UV "+t.aoMapUv:"",t.emissiveMapUv?"#define EMISSIVEMAP_UV "+t.emissiveMapUv:"",t.bumpMapUv?"#define BUMPMAP_UV "+t.bumpMapUv:"",t.normalMapUv?"#define NORMALMAP_UV "+t.normalMapUv:"",t.displacementMapUv?"#define DISPLACEMENTMAP_UV "+t.displacementMapUv:"",t.metalnessMapUv?"#define METALNESSMAP_UV "+t.metalnessMapUv:"",t.roughnessMapUv?"#define ROUGHNESSMAP_UV "+t.roughnessMapUv:"",t.anisotropyMapUv?"#define ANISOTROPYMAP_UV "+t.anisotropyMapUv:"",t.clearcoatMapUv?"#define CLEARCOATMAP_UV "+t.clearcoatMapUv:"",t.clearcoatNormalMapUv?"#define CLEARCOAT_NORMALMAP_UV "+t.clearcoatNormalMapUv:"",t.clearcoatRoughnessMapUv?"#define CLEARCOAT_ROUGHNESSMAP_UV "+t.clearcoatRoughnessMapUv:"",t.iridescenceMapUv?"#define IRIDESCENCEMAP_UV "+t.iridescenceMapUv:"",t.iridescenceThicknessMapUv?"#define IRIDESCENCE_THICKNESSMAP_UV "+t.iridescenceThicknessMapUv:"",t.sheenColorMapUv?"#define SHEEN_COLORMAP_UV "+t.sheenColorMapUv:"",t.sheenRoughnessMapUv?"#define SHEEN_ROUGHNESSMAP_UV "+t.sheenRoughnessMapUv:"",t.specularMapUv?"#define SPECULARMAP_UV "+t.specularMapUv:"",t.specularColorMapUv?"#define SPECULAR_COLORMAP_UV "+t.specularColorMapUv:"",t.specularIntensityMapUv?"#define SPECULAR_INTENSITYMAP_UV "+t.specularIntensityMapUv:"",t.transmissionMapUv?"#define TRANSMISSIONMAP_UV "+t.transmissionMapUv:"",t.thicknessMapUv?"#define THICKNESSMAP_UV "+t.thicknessMapUv:"",t.vertexTangents&&t.flatShading===!1?"#define USE_TANGENT":"",t.vertexColors?"#define USE_COLOR":"",t.vertexAlphas?"#define USE_COLOR_ALPHA":"",t.vertexUv1s?"#define USE_UV1":"",t.vertexUv2s?"#define USE_UV2":"",t.vertexUv3s?"#define USE_UV3":"",t.pointsUvs?"#define USE_POINTS_UV":"",t.flatShading?"#define FLAT_SHADED":"",t.skinning?"#define USE_SKINNING":"",t.morphTargets?"#define USE_MORPHTARGETS":"",t.morphNormals&&t.flatShading===!1?"#define USE_MORPHNORMALS":"",t.morphColors?"#define USE_MORPHCOLORS":"",t.morphTargetsCount>0?"#define MORPHTARGETS_TEXTURE_STRIDE "+t.morphTextureStride:"",t.morphTargetsCount>0?"#define MORPHTARGETS_COUNT "+t.morphTargetsCount:"",t.doubleSided?"#define DOUBLE_SIDED":"",
` ].filter(dr).join( `
` ),m=[Vu(t),"#define SHADER_TYPE "+t.shaderType,"#define SHADER_NAME "+t.shaderName,p,t.useFog&&t.fog?"#define USE_FOG":"",t.useFog&&t.fogExp2?"#define FOG_EXP2":"",t.alphaToCoverage?"#define ALPHA_TO_COVERAGE":"",t.map?"#define USE_MAP":"",t.matcap?"#define USE_MATCAP":"",t.envMap?"#define USE_ENVMAP":"",t.envMap?"#define "+c:"",t.envMap?"#define "+h:"",t.envMap?"#define "+u:"",f?"#define CUBEUV_TEXEL_WIDTH "+f.texelWidth:"",f?"#define CUBEUV_TEXEL_HEIGHT "+f.texelHeight:"",f?"#define CUBEUV_MAX_MIP "+f.maxMip+".0":"",t.lightMap?"#define USE_LIGHTMAP":"",t.aoMap?"#define USE_AOMAP":"",t.bumpMap?"#define USE_BUMPMAP":"",t.normalMap?"#define USE_NORMALMAP":"",t.normalMapObjectSpace?"#define USE_NORMALMAP_OBJECTSPACE":"",t.normalMapTangentSpace?"#define USE_NORMALMAP_TANGENTSPACE":"",t.emissiveMap?"#define USE_EMISSIVEMAP":"",t.anisotropy?"#define USE_ANISOTROPY":"",t.anisotropyMap?"#define USE_ANISOTROPYMAP":"",t.clearcoat?"#define USE_CLEARCOAT":"",t.clearcoatMap?"#define USE_CLEARCOATMAP":"",t.clearcoatRoughnessMap?"#define USE_CLEARCOAT_ROUGHNESSMAP":"",t.clearcoatNormalMap?"#define USE_CLEARCOAT_NORMALMAP":"",t.dispersion?"#define USE_DISPERSION":"",t.iridescence?"#define USE_IRIDESCENCE":"",t.iridescenceMap?"#define USE_IRIDESCENCEMAP":"",t.iridescenceThicknessMap?"#define USE_IRIDESCENCE_THICKNESSMAP":"",t.specularMap?"#define USE_SPECULARMAP":"",t.specularColorMap?"#define USE_SPECULAR_COLORMAP":"",t.specularIntensityMap?"#define USE_SPECULAR_INTENSITYMAP":"",t.roughnessMap?"#define USE_ROUGHNESSMAP":"",t.metalnessMap?"#define USE_METALNESSMAP":"",t.alphaMap?"#define USE_ALPHAMAP":"",t.alphaTest?"#define USE_ALPHATEST":"",t.alphaHash?"#define USE_ALPHAHASH":"",t.sheen?"#define USE_SHEEN":"",t.sheenColorMap?"#define USE_SHEEN_COLORMAP":"",t.sheenRoughnessMap?"#define USE_SHEEN_ROUGHNESSMAP":"",t.transmission?"#define USE_TRANSMISSION":"",t.transmissionMap?"#define USE_TRANSMISSIONMAP":"",t.thicknessMap?"#define USE_THICKNESSMAP":"",t.vertexTangents&&t.flatShading===!1?"#define USE_TANGENT":"",t.vertexColors||t.instancingColor||t.batchingColor?"#define USE_COLOR":"",t.vertexAlphas?"#define USE_COLOR_ALPHA":"",t.vertexUv1s?"#define USE_UV1":"",t.vertexUv2s?"#define USE_UV2":"",t.vertexUv3s?"#define USE_UV3":"",t.pointsUvs?"#define USE_POINTS_UV":"",t.gradientMap?"#define USE_GRADIENTMAP":"",t.flatShading?"#define FLAT_SHADED":"",t.doubleSided?"#define DOUBLE_SIDED":"",t.flipSided?"#define FLIP_SIDED":"",t.shadowMapEnabled?"#define USE_SHADOWMAP":"",t.shadowMapEnabled?"#define "+l:"",t.premultipliedAlpha?"#define PREMULTIPLIED_ALPHA":"",t.numLightProbes>0?"#define USE_LIGHT_PROBES":"",t.decodeVideoTexture?"#define DECODE_VIDEO_TEXTURE":"",t.decodeVideoTextureEmissive?"#define DECODE_VIDEO_TEXTURE_EMISSIVE":"",t.logarithmicDepthBuffer?"#define USE_LOGARITHMIC_DEPTH_BUFFER":"",t.reversedDepthBuffer?"#define USE_REVERSED_DEPTH_BUFFER":"","uniform mat4 viewMatrix;","uniform vec3 cameraPosition;","uniform bool isOrthographic;",t.toneMapping!==li?"#define TONE_MAPPING":"",t.toneMapping!==li?Qe.tonemapping_pars_fragment:"",t.toneMapping!==li?P1("toneMapping",t.toneMapping):"",t.dithering?"#define DITHERING":"",t.opaque?"#define OPAQUE":"",Qe.colorspace_pars_fragment,A1("linearToOutputTexel",t.outputColorSpace),R1(),t.useDepthPacking?"#define DEPTH_PACKING "+t.depthPacking:"", `
` ].filter(dr).join( `
` )),a=Kl(a),a=Fu(a,t),a=zu(a,t),o=Kl(o),o=Fu(o,t),o=zu(o,t),a=Hu(a),o=Hu(o),t.isRawShaderMaterial!==!0&&(v= ` # version 300 es
2026-01-22 11:29:51 +08:00
` ,x=[d,"#define attribute in","#define varying out","#define texture2D texture"].join( `
` )+ `
2026-01-22 15:23:57 +08:00
` +x,m=["#define varying in",t.glslVersion===Qc?"":"layout(location = 0) out highp vec4 pc_fragColor;",t.glslVersion===Qc?"":"#define gl_FragColor pc_fragColor","#define gl_FragDepthEXT gl_FragDepth","#define texture2D texture","#define textureCube texture","#define texture2DProj textureProj","#define texture2DLodEXT textureLod","#define texture2DProjLodEXT textureProjLod","#define textureCubeLodEXT textureLod","#define texture2DGradEXT textureGrad","#define texture2DProjGradEXT textureProjGrad","#define textureCubeGradEXT textureGrad"].join( `
2026-01-22 11:29:51 +08:00
` )+ `
2026-01-22 15:23:57 +08:00
` +m);const b=v+x+a,M=v+m+o,C=Uu(i,i.VERTEX_SHADER,b),T=Uu(i,i.FRAGMENT_SHADER,M);i.attachShader(g,C),i.attachShader(g,T),t.index0AttributeName!==void 0?i.bindAttribLocation(g,0,t.index0AttributeName):t.morphTargets===!0&&i.bindAttribLocation(g,0,"position"),i.linkProgram(g);function D(B){if(s.debug.checkShaderErrors){const R=i.getProgramInfoLog(g)||"",O=i.getShaderInfoLog(C)||"",y=i.getShaderInfoLog(T)||"",H=R.trim(),Y=O.trim(),j=y.trim();let J=!0,Z=!0;if(i.getProgramParameter(g,i.LINK_STATUS)===!1)if(J=!1,typeof s.debug.onShaderError=="function")s.debug.onShaderError(i,g,C,T);else{const ae=Ou(i,C,"vertex"),X=Ou(i,T,"fragment");et("THREE.WebGLProgram: Shader Error "+i.getError()+" - VALIDATE_STATUS "+i.getProgramParameter(g,i.VALIDATE_STATUS)+ `
2026-01-22 11:29:51 +08:00
Material Name : ` +B.name+ `
Material Type : ` +B.type+ `
Program Info Log : ` +H+ `
` +ae+ `
2026-01-22 15:23:57 +08:00
` +X)}else H!==""?ze("WebGLProgram: Program Info Log:",H):(Y===""||j==="")&&(Z=!1);Z&&(B.diagnostics={runnable:J,programLog:H,vertexShader:{log:Y,prefix:x},fragmentShader:{log:j,prefix:m}})}i.deleteShader(C),i.deleteShader(T),U=new ga(i,g),S=I1(i,g)}let U;this.getUniforms=function(){return U===void 0&&D(this),U};let S;this.getAttributes=function(){return S===void 0&&D(this),S};let w=t.rendererExtensionParallelShaderCompile===!1;return this.isReady=function(){return w===!1&&(w=i.getProgramParameter(g,w1)),w},this.destroy=function(){n.releaseStatesOfProgram(this),i.deleteProgram(g),this.program=void 0},this.type=t.shaderType,this.name=t.shaderName,this.id=E1++,this.cacheKey=e,this.usedTimes=1,this.program=g,this.vertexShader=C,this.fragmentShader=T,this}let X1=0;class j1{constructor(){this.shaderCache=new Map,this.materialCache=new Map}update(e){const t=e.vertexShader,n=e.fragmentShader,i=this._getShaderStage(t),r=this._getShaderStage(n),a=this._getShaderCacheForMaterial(e);return a.has(i)===!1&&(a.add(i),i.usedTimes++),a.has(r)===!1&&(a.add(r),r.usedTimes++),this}remove(e){const t=this.materialCache.get(e);for(const n of t)n.usedTimes--,n.usedTimes===0&&this.shaderCache.delete(n.code);return this.materialCache.delete(e),this}getVertexShaderID(e){return this._getShaderStage(e.vertexShader).id}getFragmentShaderID(e){return this._getShaderStage(e.fragmentShader).id}dispose(){this.shaderCache.clear(),this.materialCache.clear()}_getShaderCacheForMaterial(e){const t=this.materialCache;let n=t.get(e);return n===void 0&&(n=new Set,t.set(e,n)),n}_getShaderStage(e){const t=this.shaderCache;let n=t.get(e);return n===void 0&&(n=new Z1(e),t.set(e,n)),n}}class Z1{constructor(e){this.id=X1++,this.code=e,this.usedTimes=0}}function q1(s,e,t,n,i,r,a){const o=new al,l=new j1,c=new Set,h=[],u=i.logarithmicDepthBuffer,f=i.vertexTextures;let d=i.precision;const p={MeshDepthMaterial:"depth",MeshDistanceMaterial:"distanceRGBA",MeshNormalMaterial:"normal",MeshBasicMaterial:"basic",MeshLambertMaterial:"lambert",MeshPhongMaterial:"phong",MeshToonMaterial:"toon",MeshStandardMaterial:"physical",MeshPhysicalMaterial:"physical",MeshMatcapMaterial:"matcap",LineBasicMaterial:"basic",LineDashedMaterial:"dashed",PointsMaterial:"points",ShadowMaterial:"shadow",SpriteMaterial:"sprite"};function g(S){return c.add(S),S===0?"uv": ` uv$ { S } ` }function x(S,w,B,R,O){const y=R.fog,H=O.geometry,Y=S.isMeshStandardMaterial?R.environment:null,j=(S.isMeshStandardMaterial?t:e).get(S.envMap||Y),J=j&&j.mapping===wr?j.image.height:null,Z=p[S.type];S.precision!==null&&(d=i.getMaxPrecision(S.precision),d!==S.precision&&ze("WebGLProgram.getParameters:",S.precision,"not supported, using",d,"instead."));const ae=H.morphAttributes.position||H.morphAttributes.normal||H.morphAttributes.color,X=ae!==void 0?ae.length:0;let q=0;H.morphAttributes.position!==void 0&&(q=1),H.morphAttributes.normal!==void 0&&(q=2),H.morphAttributes.color!==void 0&&(q=3);let ge,pe,de,ie;if(Z){const dt=Gn[Z];ge=dt.vertexShader,pe=dt.fragmentShader}else ge=S.vertexShader,pe=S.fragmentShader,l.update(S),de=l.getVertexShaderID(S),ie=l.getFragmentShaderID(S);const ce=s.getRenderTarget(),fe=s.state.buffers.depth.getReversed(),ve=O.isInstancedMesh===!0,Ee=O.isBatchedMesh===!0,Ne=!!S.map,Ke=!!S.matcap,ke=!!j,_=!!S.aoMap,A=!!S.lightMap,V=!!S.bumpMap,N=!!S.normalMap,I=!!S.displacementMap,F=!!S.emissiveMap,ee=!!S.metalnessMap, $ =!!S.roughnessMap,G=S.anisotropy>0,L=S.clearcoat>0,E=S.dispersion>0,z=S.iridescence>0,K=S.sheen>0,le=S.transmission>0,te=G&&!!S.anisotropyMap,Te=L&&!!S.clearcoatMap,be=L&&!!S.clearcoatNormalMap,Re=L&&!!S.clearcoatRoughnessMap,De=z&&!!S.iridescenceMap,he=z&&!!S.iridescenceThicknessMap,_e=K&&!!S.sheenColorMap,He=K&&!!S.sheenRoughnessMap,Ue=!!S.specularMap,Ce=!!S.specularColorMap,Ve=!!S.specularIntensityMap,W=le&&!!S.transmissionMap,we=le&&!!S.thicknessMap,ye=!!S.gradientMap,Me=!!S.alphaMap,xe=S.alphaTest>0,me=!!S.alphaHash,Be=!!S.extensions;let qe=li;S.toneMapped&&(ce===null||ce.isXRRenderTarget===!0)&&(qe=s.toneMapping);const bt={shaderID:Z,shaderType:S.type,shaderName:S.name,vertexShader:ge,fragmen
2026-01-22 11:29:51 +08:00
gl _Position = vec4 ( position , 1.0 ) ;
2026-01-22 15:23:57 +08:00
} ` ,rv= ` uniform sampler2D shadow _pass ;
2026-01-22 11:29:51 +08:00
uniform vec2 resolution ;
uniform float radius ;
# include < packing >
void main ( ) {
const float samples = float ( VSM _SAMPLES ) ;
float mean = 0.0 ;
float squared _mean = 0.0 ;
float uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 ) ;
float uvStart = samples <= 1.0 ? 0.0 : - 1.0 ;
for ( float i = 0.0 ; i < samples ; i ++ ) {
float uvOffset = uvStart + i * uvStride ;
# ifdef HORIZONTAL _PASS
vec2 distribution = unpackRGBATo2Half ( texture2D ( shadow _pass , ( gl _FragCoord . xy + vec2 ( uvOffset , 0.0 ) * radius ) / resolution ) ) ;
mean += distribution . x ;
squared _mean += distribution . y * distribution . y + distribution . x * distribution . x ;
# else
float depth = unpackRGBAToDepth ( texture2D ( shadow _pass , ( gl _FragCoord . xy + vec2 ( 0.0 , uvOffset ) * radius ) / resolution ) ) ;
mean += depth ;
squared _mean += depth * depth ;
# endif
}
mean = mean / samples ;
squared _mean = squared _mean / samples ;
float std _dev = sqrt ( squared _mean - mean * mean ) ;
gl _FragColor = pack2HalfToRGBA ( vec2 ( mean , std _dev ) ) ;
2026-01-22 15:23:57 +08:00
} ` ;function av(s,e,t){let n=new El;const i=new ue,r=new ue,a=new at,o=new km({depthPacking:Zf}),l=new Um,c={},h=t.maxTextureSize,u={[Sn]:Yt,[Yt]:Sn,[Dt]:Dt},f=new Rt({defines:{VSM_SAMPLES:8},uniforms:{shadow_pass:{value:null},resolution:{value:new ue},radius:{value:4}},vertexShader:sv,fragmentShader:rv}),d=f.clone();d.defines.HORIZONTAL_PASS=1;const p=new vt;p.setAttribute("position",new xt(new Float32Array([-1,-1,.5,3,-1,.5,-1,3,.5]),3));const g=new ht(p,f),x=this;this.enabled=!1,this.autoUpdate=!0,this.needsUpdate=!1,this.type=Ac;let m=this.type;this.render=function(T,D,U){if(x.enabled===!1||x.autoUpdate===!1&&x.needsUpdate===!1||T.length===0)return;const S=s.getRenderTarget(),w=s.getActiveCubeFace(),B=s.getActiveMipmapLevel(),R=s.state;R.setBlending(Ot),R.buffers.depth.getReversed()===!0?R.buffers.color.setClear(0,0,0,0):R.buffers.color.setClear(1,1,1,1),R.buffers.depth.setTest(!0),R.setScissorTest(!1);const O=m!==qn&&this.type===qn,y=m===qn&&this.type!==qn;for(let H=0,Y=T.length;H<Y;H++){const j=T[H],J=j.shadow;if(J===void 0){ze("WebGLShadowMap:",j,"has no shadow.");continue}if(J.autoUpdate===!1&&J.needsUpdate===!1)continue;i.copy(J.mapSize);const Z=J.getFrameExtents();if(i.multiply(Z),r.copy(J.mapSize),(i.x>h||i.y>h)&&(i.x>h&&(r.x=Math.floor(h/Z.x),i.x=r.x*Z.x,J.mapSize.x=r.x),i.y>h&&(r.y=Math.floor(h/Z.y),i.y=r.y*Z.y,J.mapSize.y=r.y)),J.map===null||O===!0||y===!0){const X=this.type!==qn?{minFilter:Gt,magFilter:Gt}:{};J.map!==null&&J.map.dispose(),J.map=new nn(i.x,i.y,X),J.map.texture.name=j.name+".shadowMap",J.camera.updateProjectionMatrix()}s.setRenderTarget(J.map),s.clear();const ae=J.getViewportCount();for(let X=0;X<ae;X++){const q=J.getViewport(X);a.set(r.x*q.x,r.y*q.y,r.x*q.z,r.y*q.w),R.viewport(a),J.updateMatrices(j,X),n=J.getFrustum(),M(D,U,J.camera,j,this.type)}J.isPointLightShadow!==!0&&this.type===qn&&v(J,U),J.needsUpdate=!1}m=this.type,x.needsUpdate=!1,s.setRenderTarget(S,w,B)};function v(T,D){const U=e.update(g);f.defines.VSM_SAMPLES!==T.blurSamples&&(f.defines.VSM_SAMPLES=T.blurSamples,d.defines.VSM_SAMPLES=T.blurSamples,f.needsUpdate=!0,d.needsUpdate=!0),T.mapPass===null&&(T.mapPass=new nn(i.x,i.y)),f.uniforms.shadow_pass.value=T.map.texture,f.uniforms.resolution.value=T.mapSize,f.uniforms.radius.value=T.radius,s.setRenderTarget(T.mapPass),s.clear(),s.renderBufferDirect(D,null,U,f,g,null),d.uniforms.shadow_pass.value=T.mapPass.texture,d.uniforms.resolution.value=T.mapSize,d.uniforms.radius.value=T.radius,s.setRenderTarget(T.map),s.clear(),s.renderBufferDirect(D,null,U,d,g,null)}function b(T,D,U,S){let w=null;const B=U.isPointLight===!0?T.customDistanceMaterial:T.customDepthMaterial;if(B!==void 0)w=B;else if(w=U.isPointLight===!0?l:o,s.localClippingEnabled&&D.clipShadows===!0&&Array.isArray(D.clippingPlanes)&&D.clippingPlanes.length!==0||D.displacementMap&&D.displacementScale!==0||D.alphaMap&&D.alphaTest>0||D.map&&D.alphaTest>0||D.alphaToCoverage===!0){const R=w.uuid,O=D.uuid;let y=c[R];y===void 0&&(y={},c[R]=y);let H=y[O];H===void 0&&(H=w.clone(),y[O]=H,D.addEventListener("dispose",C)),w=H}if(w.visible=D.visible,w.wireframe=D.wireframe,S===qn?w.side=D.shadowSide!==null?D.shadowSide:D.side:w.side=D.shadowSide!==null?D.shadowSide:u[D.side],w.alphaMap=D.alphaMap,w.alphaTest=D.alphaToCoverage===!0?.5:D.alphaTest,w.map=D.map,w.clipShadows=D.clipShadows,w.clippingPlanes=D.clippingPlanes,w.clipIntersection=D.clipIntersection,w.displacementMap=D.displacementMap,w.displacementScale=D.displacementScale,w.displacementBias=D.displacementBias,w.wireframeLinewidth=D.wireframeLinewidth,w.linewidth=D.linewidth,U.isPointLight===!0&&w.isMeshDistanceMaterial===!0){const R=s.properties.get(w);R.light=U}return w}function M(T,D,U,S,w){if(T.visible===!1)return;if(T.layers.test(D.layers)&&(T.isMesh||T.isLine||T.isPoints)&&(T.castShadow||T.receiveShadow&&w===qn)&&(!T.frustumCulled||n.intersectsObject(T))){T.modelViewMatrix.multiplyMatrices(U.matrixWorldInverse,T.matrixWorld);const O=e.update(T),y=T.material;if(Array.isArray(y)){const H=O.groups;for(let Y=0,j=H.length;Y<j;Y++){const J=H[Y],Z=y[J.materialIndex];if(Z&&Z.visible
2026-01-22 11:29:51 +08:00
void main ( ) {
gl _Position = vec4 ( position , 1.0 ) ;
2026-01-22 15:23:57 +08:00
} ` ,dv= `
2026-01-22 11:29:51 +08:00
uniform sampler2DArray depthColor ;
uniform float depthWidth ;
uniform float depthHeight ;
void main ( ) {
vec2 coord = vec2 ( gl _FragCoord . x / depthWidth , gl _FragCoord . y / depthHeight ) ;
if ( coord . x >= 1.0 ) {
gl _FragDepth = texture ( depthColor , vec3 ( coord . x - 1.0 , coord . y , 1 ) ) . r ;
} else {
gl _FragDepth = texture ( depthColor , vec3 ( coord . x , coord . y , 0 ) ) . r ;
}
2026-01-22 15:23:57 +08:00
} ` ;class fv{constructor(){this.texture=null,this.mesh=null,this.depthNear=0,this.depthFar=0}init(e,t){if(this.texture===null){const n=new Xh(e.texture);(e.depthNear!==t.depthNear||e.depthFar!==t.depthFar)&&(this.depthNear=e.depthNear,this.depthFar=e.depthFar),this.texture=n}}getMesh(e){if(this.texture!==null&&this.mesh===null){const t=e.cameras[0].viewport,n=new Rt({vertexShader:uv,fragmentShader:dv,uniforms:{depthColor:{value:this.texture},depthWidth:{value:t.z},depthHeight:{value:t.w}}});this.mesh=new ht(new Ai(20,20),n)}return this.mesh}reset(){this.texture=null,this.mesh=null}getDepthTexture(){return this.texture}}class pv extends bi{constructor(e,t){super();const n=this;let i=null,r=1,a=null,o="local-floor",l=1,c=null,h=null,u=null,f=null,d=null,p=null;const g=typeof XRWebGLBinding<"u",x=new fv,m={},v=t.getContextAttributes();let b=null,M=null;const C=[],T=[],D=new ue;let U=null;const S=new Zt;S.viewport=new at;const w=new Zt;w.viewport=new at;const B=[S,w],R=new n0;let O=null,y=null;this.cameraAutoUpdate=!0,this.enabled=!1,this.isPresenting=!1,this.getController=function(ie){let ce=C[ie];return ce===void 0&&(ce=new vl,C[ie]=ce),ce.getTargetRaySpace()},this.getControllerGrip=function(ie){let ce=C[ie];return ce===void 0&&(ce=new vl,C[ie]=ce),ce.getGripSpace()},this.getHand=function(ie){let ce=C[ie];return ce===void 0&&(ce=new vl,C[ie]=ce),ce.getHandSpace()};function H(ie){const ce=T.indexOf(ie.inputSource);if(ce===-1)return;const fe=C[ce];fe!==void 0&&(fe.update(ie.inputSource,ie.frame,c||a),fe.dispatchEvent({type:ie.type,data:ie.inputSource}))}function Y(){i.removeEventListener("select",H),i.removeEventListener("selectstart",H),i.removeEventListener("selectend",H),i.removeEventListener("squeeze",H),i.removeEventListener("squeezestart",H),i.removeEventListener("squeezeend",H),i.removeEventListener("end",Y),i.removeEventListener("inputsourceschange",j);for(let ie=0;ie<C.length;ie++){const ce=T[ie];ce!==null&&(T[ie]=null,C[ie].disconnect(ce))}O=null,y=null,x.reset();for(const ie in m)delete m[ie];e.setRenderTarget(b),d=null,f=null,u=null,i=null,M=null,de.stop(),n.isPresenting=!1,e.setPixelRatio(U),e.setSize(D.width,D.height,!1),n.dispatchEvent({type:"sessionend"})}this.setFramebufferScaleFactor=function(ie){r=ie,n.isPresenting===!0&&ze("WebXRManager: Cannot change framebuffer scale while presenting.")},this.setReferenceSpaceType=function(ie){o=ie,n.isPresenting===!0&&ze("WebXRManager: Cannot change reference space type while presenting.")},this.getReferenceSpace=function(){return c||a},this.setReferenceSpace=function(ie){c=ie},this.getBaseLayer=function(){return f!==null?f:d},this.getBinding=function(){return u===null&&g&&(u=new XRWebGLBinding(i,t)),u},this.getFrame=function(){return p},this.getSession=function(){return i},this.setSession=async function(ie){if(i=ie,i!==null){if(b=e.getRenderTarget(),i.addEventListener("select",H),i.addEventListener("selectstart",H),i.addEventListener("selectend",H),i.addEventListener("squeeze",H),i.addEventListener("squeezestart",H),i.addEventListener("squeezeend",H),i.addEventListener("end",Y),i.addEventListener("inputsourceschange",j),v.xrCompatible!==!0&&await t.makeXRCompatible(),U=e.getPixelRatio(),e.getSize(D),g&&"createProjectionLayer"in XRWebGLBinding.prototype){let fe=null,ve=null,Ee=null;v.depth&&(Ee=v.stencil?t.DEPTH24_STENCIL8:t.DEPTH_COMPONENT24,fe=v.stencil? $ i:Fs,ve=v.stencil?Ki:vi);const Ne={colorFormat:t.RGBA8,depthFormat:Ee,scaleFactor:r};u=this.getBinding(),f=u.createProjectionLayer(Ne),i.updateRenderState({layers:[f]}),e.setPixelRatio(1),e.setSize(f.textureWidth,f.textureHeight,!1),M=new nn(f.textureWidth,f.textureHeight,{format:tn,type:En,depthTexture:new Al(f.textureWidth,f.textureHeight,ve,void 0,void 0,void 0,void 0,void 0,void 0,fe),stencilBuffer:v.stencil,colorSpace:e.outputColorSpace,samples:v.antialias?4:0,resolveDepthBuffer:f.ignoreDepthValues===!1,resolveStencilBuffer:f.ignoreDepthValues===!1})}else{const fe={antialias:v.antialias,alpha:!0,depth:v.depth,stencil:v.stencil,framebufferScaleFactor:r};d=new XRWebGLLayer(i,t,fe),i.updateRenderState({baseLayer:d}
2026-01-22 11:29:51 +08:00
varying vec2 vUv ;
void main ( ) {
vUv = uv ;
gl _Position = projectionMatrix * modelViewMatrix * vec4 ( position , 1.0 ) ;
} ` ,fragmentShader: `
uniform float opacity ;
uniform sampler2D tDiffuse ;
varying vec2 vUv ;
void main ( ) {
vec4 texel = texture2D ( tDiffuse , vUv ) ;
gl _FragColor = opacity * texel ;
2026-01-22 15:23:57 +08:00
} ` };class Ui{constructor(){this.isPass=!0,this.enabled=!0,this.needsSwap=!0,this.clear=!1,this.renderToScreen=!1}setSize(){}render(){console.error("THREE.Pass: .render() must be implemented in derived pass.")}dispose(){}}const Fv=new Ri(-1,1,1,-1,0,1);class zv extends vt{constructor(){super(),this.setAttribute("position",new rn([-1,3,0,-1,-1,0,3,-1,0],3)),this.setAttribute("uv",new rn([0,2,0,0,2,0],2))}}const Hv=new zv;class ba{constructor(e){this._mesh=new ht(Hv,e)}dispose(){this._mesh.geometry.dispose()}render(e){e.render(this._mesh,Fv)}get material(){return this._mesh.material}set material(e){this._mesh.material=e}}class _a extends Ui{constructor(e,t="tDiffuse"){super(),this.textureID=t,this.uniforms=null,this.material=null,e instanceof Rt?(this.uniforms=e.uniforms,this.material=e):e&&(this.uniforms=Hn.clone(e.uniforms),this.material=new Rt({name:e.name!==void 0?e.name:"unspecified",defines:Object.assign({},e.defines),uniforms:this.uniforms,vertexShader:e.vertexShader,fragmentShader:e.fragmentShader})),this._fsQuad=new ba(this.material)}render(e,t,n){this.uniforms[this.textureID]&&(this.uniforms[this.textureID].value=n.texture),this._fsQuad.material=this.material,this.renderToScreen?(e.setRenderTarget(null),this._fsQuad.render(e)):(e.setRenderTarget(t),this.clear&&e.clear(e.autoClearColor,e.autoClearDepth,e.autoClearStencil),this._fsQuad.render(e))}dispose(){this.material.dispose(),this._fsQuad.dispose()}}class $ u extends Ui{constructor(e,t){super(),this.scene=e,this.camera=t,this.clear=!0,this.needsSwap=!1,this.inverse=!1}render(e,t,n){const i=e.getContext(),r=e.state;r.buffers.color.setMask(!1),r.buffers.depth.setMask(!1),r.buffers.color.setLocked(!0),r.buffers.depth.setLocked(!0);let a,o;this.inverse?(a=0,o=1):(a=1,o=0),r.buffers.stencil.setTest(!0),r.buffers.stencil.setOp(i.REPLACE,i.REPLACE,i.REPLACE),r.buffers.stencil.setFunc(i.ALWAYS,a,4294967295),r.buffers.stencil.setClear(o),r.buffers.stencil.setLocked(!0),e.setRenderTarget(n),this.clear&&e.clear(),e.render(this.scene,this.camera),e.setRenderTarget(t),this.clear&&e.clear(),e.render(this.scene,this.camera),r.buffers.color.setLocked(!1),r.buffers.depth.setLocked(!1),r.buffers.color.setMask(!0),r.buffers.depth.setMask(!0),r.buffers.stencil.setLocked(!1),r.buffers.stencil.setFunc(i.EQUAL,1,4294967295),r.buffers.stencil.setOp(i.KEEP,i.KEEP,i.KEEP),r.buffers.stencil.setLocked(!0)}}class Vv extends Ui{constructor(){super(),this.needsSwap=!1}render(e){e.state.buffers.stencil.setLocked(!1),e.state.buffers.stencil.setTest(!1)}}class Gv{constructor(e,t){if(this.renderer=e,this._pixelRatio=e.getPixelRatio(),t===void 0){const n=e.getSize(new ue);this._width=n.width,this._height=n.height,t=new nn(this._width*this._pixelRatio,this._height*this._pixelRatio,{type:xn}),t.texture.name="EffectComposer.rt1"}else this._width=t.width,this._height=t.height;this.renderTarget1=t,this.renderTarget2=t.clone(),this.renderTarget2.texture.name="EffectComposer.rt2",this.writeBuffer=this.renderTarget1,this.readBuffer=this.renderTarget2,this.renderToScreen=!0,this.passes=[],this.copyPass=new _a(ki),this.copyPass.material.blending=Ot,this.clock=new i0}swapBuffers(){const e=this.readBuffer;this.readBuffer=this.writeBuffer,this.writeBuffer=e}addPass(e){this.passes.push(e),e.setSize(this._width*this._pixelRatio,this._height*this._pixelRatio)}insertPass(e,t){this.passes.splice(t,0,e),e.setSize(this._width*this._pixelRatio,this._height*this._pixelRatio)}removePass(e){const t=this.passes.indexOf(e);t!==-1&&this.passes.splice(t,1)}isLastEnabledPass(e){for(let t=e+1;t<this.passes.length;t++)if(this.passes[t].enabled)return!1;return!0}render(e){e===void 0&&(e=this.clock.getDelta());const t=this.renderer.getRenderTarget();let n=!1;for(let i=0,r=this.passes.length;i<r;i++){const a=this.passes[i];if(a.enabled!==!1){if(a.renderToScreen=this.renderToScreen&&this.isLastEnabledPass(i),a.render(this.renderer,this.writeBuffer,this.readBuffer,e,n),a.needsSwap){if(n){const o=this.renderer.getContext(),l=this.renderer.state.buffers.stencil;l.setFunc(o.NOTEQUAL,1,4294967295),this.copyPass.render(this.renderer,th
2026-01-22 11:29:51 +08:00
varying vec2 vUv ;
void main ( ) {
vUv = uv ;
gl _Position = projectionMatrix * modelViewMatrix * vec4 ( position , 1.0 ) ;
} ` ,fragmentShader: `
varying vec2 vUv ;
uniform highp sampler2D tNormal ;
uniform highp sampler2D tDepth ;
uniform sampler2D tNoise ;
uniform vec2 resolution ;
uniform float cameraNear ;
uniform float cameraFar ;
uniform mat4 cameraProjectionMatrix ;
uniform mat4 cameraProjectionMatrixInverse ;
uniform mat4 cameraWorldMatrix ;
uniform float radius ;
uniform float distanceExponent ;
uniform float thickness ;
uniform float distanceFallOff ;
uniform float scale ;
# if SCENE _CLIP _BOX == 1
uniform vec3 sceneBoxMin ;
uniform vec3 sceneBoxMax ;
# endif
# include < common >
# include < packing >
# ifndef FRAGMENT _OUTPUT
# define FRAGMENT _OUTPUT vec4 ( vec3 ( ao ) , 1. )
# endif
vec3 getViewPosition ( const in vec2 screenPosition , const in float depth ) {
vec4 clipSpacePosition = vec4 ( vec3 ( screenPosition , depth ) * 2.0 - 1.0 , 1.0 ) ;
vec4 viewSpacePosition = cameraProjectionMatrixInverse * clipSpacePosition ;
return viewSpacePosition . xyz / viewSpacePosition . w ;
}
float getDepth ( const vec2 uv ) {
return textureLod ( tDepth , uv . xy , 0.0 ) . DEPTH _SWIZZLING ;
}
float fetchDepth ( const ivec2 uv ) {
return texelFetch ( tDepth , uv . xy , 0 ) . DEPTH _SWIZZLING ;
}
float getViewZ ( const in float depth ) {
# if PERSPECTIVE _CAMERA == 1
return perspectiveDepthToViewZ ( depth , cameraNear , cameraFar ) ;
# else
return orthographicDepthToViewZ ( depth , cameraNear , cameraFar ) ;
# endif
}
vec3 computeNormalFromDepth ( const vec2 uv ) {
vec2 size = vec2 ( textureSize ( tDepth , 0 ) ) ;
ivec2 p = ivec2 ( uv * size ) ;
float c0 = fetchDepth ( p ) ;
float l2 = fetchDepth ( p - ivec2 ( 2 , 0 ) ) ;
float l1 = fetchDepth ( p - ivec2 ( 1 , 0 ) ) ;
float r1 = fetchDepth ( p + ivec2 ( 1 , 0 ) ) ;
float r2 = fetchDepth ( p + ivec2 ( 2 , 0 ) ) ;
float b2 = fetchDepth ( p - ivec2 ( 0 , 2 ) ) ;
float b1 = fetchDepth ( p - ivec2 ( 0 , 1 ) ) ;
float t1 = fetchDepth ( p + ivec2 ( 0 , 1 ) ) ;
float t2 = fetchDepth ( p + ivec2 ( 0 , 2 ) ) ;
float dl = abs ( ( 2.0 * l1 - l2 ) - c0 ) ;
float dr = abs ( ( 2.0 * r1 - r2 ) - c0 ) ;
float db = abs ( ( 2.0 * b1 - b2 ) - c0 ) ;
float dt = abs ( ( 2.0 * t1 - t2 ) - c0 ) ;
vec3 ce = getViewPosition ( uv , c0 ) . xyz ;
vec3 dpdx = ( dl < dr ) ? ce - getViewPosition ( ( uv - vec2 ( 1.0 / size . x , 0.0 ) ) , l1 ) . xyz : - ce + getViewPosition ( ( uv + vec2 ( 1.0 / size . x , 0.0 ) ) , r1 ) . xyz ;
vec3 dpdy = ( db < dt ) ? ce - getViewPosition ( ( uv - vec2 ( 0.0 , 1.0 / size . y ) ) , b1 ) . xyz : - ce + getViewPosition ( ( uv + vec2 ( 0.0 , 1.0 / size . y ) ) , t1 ) . xyz ;
return normalize ( cross ( dpdx , dpdy ) ) ;
}
vec3 getViewNormal ( const vec2 uv ) {
# if NORMAL _VECTOR _TYPE == 2
return normalize ( textureLod ( tNormal , uv , 0. ) . rgb ) ;
# elif NORMAL _VECTOR _TYPE == 1
return unpackRGBToNormal ( textureLod ( tNormal , uv , 0. ) . rgb ) ;
# else
return computeNormalFromDepth ( uv ) ;
# endif
}
vec3 getSceneUvAndDepth ( vec3 sampleViewPos ) {
vec4 sampleClipPos = cameraProjectionMatrix * vec4 ( sampleViewPos , 1. ) ;
vec2 sampleUv = sampleClipPos . xy / sampleClipPos . w * 0.5 + 0.5 ;
float sampleSceneDepth = getDepth ( sampleUv ) ;
return vec3 ( sampleUv , sampleSceneDepth ) ;
}
void main ( ) {
float depth = getDepth ( vUv . xy ) ;
if ( depth >= 1.0 ) {
discard ;
return ;
}
vec3 viewPos = getViewPosition ( vUv , depth ) ;
vec3 viewNormal = getViewNormal ( vUv ) ;
float radiusToUse = radius ;
float distanceFalloffToUse = thickness ;
# if SCREEN _SPACE _RADIUS == 1
float radiusScale = getViewPosition ( vec2 ( 0.5 + float ( SCREEN _SPACE _RADIUS _SCALE ) / resolution . x , 0.0 ) , depth ) . x ;
radiusToUse *= radiusScale ;
distanceFalloffToUse *= radiusScale ;
# endif
# if SCENE _CLIP _BOX == 1
vec3 worldPos = ( cameraWorldMatrix * vec4 ( viewPos , 1.0 ) ) . xyz ;
float boxDistance = length ( max ( vec3 ( 0.0 ) , max ( sceneBoxMin - worldPos , worldPos - sceneBoxMax ) ) ) ;
if ( boxDistance > radiusToUse ) {
discard ;
return ;
}
# endif
vec2 noiseResolution = vec2 ( textureSize ( tNoise , 0 ) ) ;
vec2 noiseUv = vUv * resolution / noiseResolution ;
vec4 noiseTexel = textureLod ( tNoise , noiseUv , 0.0 ) ;
vec3 randomVec = noiseTexel . xyz * 2.0 - 1.0 ;
vec3 tangent = normalize ( vec3 ( randomVec . xy , 0. ) ) ;
vec3 bitangent = vec3 ( - tangent . y , tangent . x , 0. ) ;
mat3 kernelMatrix = mat3 ( tangent , bitangent , vec3 ( 0. , 0. , 1. ) ) ;
const int DIRECTIONS = SAMPLES < 30 ? 3 : 5 ;
const int STEPS = ( SAMPLES + DIRECTIONS - 1 ) / DIRECTIONS ;
float ao = 0.0 ;
for ( int i = 0 ; i < DIRECTIONS ; ++ i ) {
float angle = float ( i ) / float ( DIRECTIONS ) * PI ;
vec4 sampleDir = vec4 ( cos ( angle ) , sin ( angle ) , 0. , 0.5 + 0.5 * noiseTexel . w ) ;
sampleDir . xyz = normalize ( kernelMatrix * sampleDir . xyz ) ;
vec3 viewDir = normalize ( - viewPos . xyz ) ;
vec3 sliceBitangent = normalize ( cross ( sampleDir . xyz , viewDir ) ) ;
vec3 sliceTangent = cross ( sliceBitangent , viewDir ) ;
vec3 normalInSlice = normalize ( viewNormal - sliceBitangent * dot ( viewNormal , sliceBitangent ) ) ;
vec3 tangentToNormalInSlice = cross ( normalInSlice , sliceBitangent ) ;
vec2 cosHorizons = vec2 ( dot ( viewDir , tangentToNormalInSlice ) , dot ( viewDir , - tangentToNormalInSlice ) ) ;
for ( int j = 0 ; j < STEPS ; ++ j ) {
vec3 sampleViewOffset = sampleDir . xyz * radiusToUse * sampleDir . w * pow ( float ( j + 1 ) / float ( STEPS ) , distanceExponent ) ;
vec3 sampleSceneUvDepth = getSceneUvAndDepth ( viewPos + sampleViewOffset ) ;
vec3 sampleSceneViewPos = getViewPosition ( sampleSceneUvDepth . xy , sampleSceneUvDepth . z ) ;
vec3 viewDelta = sampleSceneViewPos - viewPos ;
if ( abs ( viewDelta . z ) < thickness ) {
float sampleCosHorizon = dot ( viewDir , normalize ( viewDelta ) ) ;
cosHorizons . x += max ( 0. , ( sampleCosHorizon - cosHorizons . x ) * mix ( 1. , 2. / float ( j + 2 ) , distanceFallOff ) ) ;
}
sampleSceneUvDepth = getSceneUvAndDepth ( viewPos - sampleViewOffset ) ;
sampleSceneViewPos = getViewPosition ( sampleSceneUvDepth . xy , sampleSceneUvDepth . z ) ;
viewDelta = sampleSceneViewPos - viewPos ;
if ( abs ( viewDelta . z ) < thickness ) {
float sampleCosHorizon = dot ( viewDir , normalize ( viewDelta ) ) ;
cosHorizons . y += max ( 0. , ( sampleCosHorizon - cosHorizons . y ) * mix ( 1. , 2. / float ( j + 2 ) , distanceFallOff ) ) ;
}
}
vec2 sinHorizons = sqrt ( 1. - cosHorizons * cosHorizons ) ;
float nx = dot ( normalInSlice , sliceTangent ) ;
float ny = dot ( normalInSlice , viewDir ) ;
float nxb = 1. / 2. * ( acos ( cosHorizons . y ) - acos ( cosHorizons . x ) + sinHorizons . x * cosHorizons . x - sinHorizons . y * cosHorizons . y ) ;
float nyb = 1. / 2. * ( 2. - cosHorizons . x * cosHorizons . x - cosHorizons . y * cosHorizons . y ) ;
float occlusion = nx * nxb + ny * nyb ;
ao += occlusion ;
}
ao = clamp ( ao / float ( DIRECTIONS ) , 0. , 1. ) ;
# if SCENE _CLIP _BOX == 1
ao = mix ( ao , 1. , smoothstep ( 0. , radiusToUse , boxDistance ) ) ;
# endif
ao = pow ( ao , scale ) ;
gl _FragColor = FRAGMENT _OUTPUT ;
2026-01-22 15:23:57 +08:00
} ` },Ma={defines:{PERSPECTIVE_CAMERA:1},uniforms:{tDepth:{value:null},cameraNear:{value:null},cameraFar:{value:null}},vertexShader: `
2026-01-22 11:29:51 +08:00
varying vec2 vUv ;
void main ( ) {
vUv = uv ;
gl _Position = projectionMatrix * modelViewMatrix * vec4 ( position , 1.0 ) ;
} ` ,fragmentShader: `
uniform sampler2D tDepth ;
uniform float cameraNear ;
uniform float cameraFar ;
varying vec2 vUv ;
# include < packing >
float getLinearDepth ( const in vec2 screenPosition ) {
# if PERSPECTIVE _CAMERA == 1
float fragCoordZ = texture2D ( tDepth , screenPosition ) . x ;
float viewZ = perspectiveDepthToViewZ ( fragCoordZ , cameraNear , cameraFar ) ;
return viewZToOrthographicDepth ( viewZ , cameraNear , cameraFar ) ;
# else
return texture2D ( tDepth , screenPosition ) . x ;
# endif
}
void main ( ) {
float depth = getLinearDepth ( vUv ) ;
gl _FragColor = vec4 ( vec3 ( 1.0 - depth ) , 1.0 ) ;
2026-01-22 15:23:57 +08:00
} ` },Ql={uniforms:{tDiffuse:{value:null},intensity:{value:1}},vertexShader: `
2026-01-22 11:29:51 +08:00
varying vec2 vUv ;
void main ( ) {
vUv = uv ;
gl _Position = projectionMatrix * modelViewMatrix * vec4 ( position , 1.0 ) ;
} ` ,fragmentShader: `
uniform float intensity ;
uniform sampler2D tDiffuse ;
varying vec2 vUv ;
void main ( ) {
vec4 texel = texture2D ( tDiffuse , vUv ) ;
gl _FragColor = vec4 ( mix ( vec3 ( 1. ) , texel . rgb , intensity ) , texel . a ) ;
2026-01-22 15:23:57 +08:00
} ` };function Xv(s=5){const e=Math.floor(s)%2===0?Math.floor(s)+1:Math.floor(s),t=jv(e),n=t.length,i=new Uint8Array(n*4);for(let a=0;a<n;++a){const o=t[a],l=2*Math.PI*o/n,c=new P(Math.cos(l),Math.sin(l),0).normalize();i[a*4]=(c.x*.5+.5)*255,i[a*4+1]=(c.y*.5+.5)*255,i[a*4+2]=127,i[a*4+3]=255}const r=new Js(i,e,e);return r.wrapS=Bn,r.wrapT=Bn,r.needsUpdate=!0,r}function jv(s){const e=Math.floor(s)%2===0?Math.floor(s)+1:Math.floor(s),t=e*e,n=Array(t).fill(0);let i=Math.floor(e/2),r=e-1;for(let a=1;a<=t;){if(i===-1&&r===e?(r=e-2,i=0):(r===e&&(r=0),i<0&&(i=e-1)),n[i*e+r]!==0){r-=2,i++;continue}else n[i*e+r]=a++;r++,i--}return n}const Sa={defines:{SAMPLES:16,SAMPLE_VECTORS:Ju(16,2,1),NORMAL_VECTOR_TYPE:1,DEPTH_VALUE_SOURCE:0},uniforms:{tDiffuse:{value:null},tNormal:{value:null},tDepth:{value:null},tNoise:{value:null},resolution:{value:new ue},cameraProjectionMatrixInverse:{value:new Xe},lumaPhi:{value:5},depthPhi:{value:5},normalPhi:{value:5},radius:{value:4},index:{value:0}},vertexShader: `
2026-01-22 11:29:51 +08:00
varying vec2 vUv ;
void main ( ) {
vUv = uv ;
gl _Position = projectionMatrix * modelViewMatrix * vec4 ( position , 1.0 ) ;
} ` ,fragmentShader: `
varying vec2 vUv ;
uniform sampler2D tDiffuse ;
uniform sampler2D tNormal ;
uniform sampler2D tDepth ;
uniform sampler2D tNoise ;
uniform vec2 resolution ;
uniform mat4 cameraProjectionMatrixInverse ;
uniform float lumaPhi ;
uniform float depthPhi ;
uniform float normalPhi ;
uniform float radius ;
uniform int index ;
# include < common >
# include < packing >
# ifndef SAMPLE _LUMINANCE
# define SAMPLE _LUMINANCE dot ( vec3 ( 0.2125 , 0.7154 , 0.0721 ) , a )
# endif
# ifndef FRAGMENT _OUTPUT
# define FRAGMENT _OUTPUT vec4 ( denoised , 1. )
# endif
float getLuminance ( const in vec3 a ) {
return SAMPLE _LUMINANCE ;
}
const vec3 poissonDisk [ SAMPLES ] = SAMPLE _VECTORS ;
vec3 getViewPosition ( const in vec2 screenPosition , const in float depth ) {
vec4 clipSpacePosition = vec4 ( vec3 ( screenPosition , depth ) * 2.0 - 1.0 , 1.0 ) ;
vec4 viewSpacePosition = cameraProjectionMatrixInverse * clipSpacePosition ;
return viewSpacePosition . xyz / viewSpacePosition . w ;
}
float getDepth ( const vec2 uv ) {
# if DEPTH _VALUE _SOURCE == 1
return textureLod ( tDepth , uv . xy , 0.0 ) . a ;
# else
return textureLod ( tDepth , uv . xy , 0.0 ) . r ;
# endif
}
float fetchDepth ( const ivec2 uv ) {
# if DEPTH _VALUE _SOURCE == 1
return texelFetch ( tDepth , uv . xy , 0 ) . a ;
# else
return texelFetch ( tDepth , uv . xy , 0 ) . r ;
# endif
}
vec3 computeNormalFromDepth ( const vec2 uv ) {
vec2 size = vec2 ( textureSize ( tDepth , 0 ) ) ;
ivec2 p = ivec2 ( uv * size ) ;
float c0 = fetchDepth ( p ) ;
float l2 = fetchDepth ( p - ivec2 ( 2 , 0 ) ) ;
float l1 = fetchDepth ( p - ivec2 ( 1 , 0 ) ) ;
float r1 = fetchDepth ( p + ivec2 ( 1 , 0 ) ) ;
float r2 = fetchDepth ( p + ivec2 ( 2 , 0 ) ) ;
float b2 = fetchDepth ( p - ivec2 ( 0 , 2 ) ) ;
float b1 = fetchDepth ( p - ivec2 ( 0 , 1 ) ) ;
float t1 = fetchDepth ( p + ivec2 ( 0 , 1 ) ) ;
float t2 = fetchDepth ( p + ivec2 ( 0 , 2 ) ) ;
float dl = abs ( ( 2.0 * l1 - l2 ) - c0 ) ;
float dr = abs ( ( 2.0 * r1 - r2 ) - c0 ) ;
float db = abs ( ( 2.0 * b1 - b2 ) - c0 ) ;
float dt = abs ( ( 2.0 * t1 - t2 ) - c0 ) ;
vec3 ce = getViewPosition ( uv , c0 ) . xyz ;
vec3 dpdx = ( dl < dr ) ? ce - getViewPosition ( ( uv - vec2 ( 1.0 / size . x , 0.0 ) ) , l1 ) . xyz
: - ce + getViewPosition ( ( uv + vec2 ( 1.0 / size . x , 0.0 ) ) , r1 ) . xyz ;
vec3 dpdy = ( db < dt ) ? ce - getViewPosition ( ( uv - vec2 ( 0.0 , 1.0 / size . y ) ) , b1 ) . xyz
: - ce + getViewPosition ( ( uv + vec2 ( 0.0 , 1.0 / size . y ) ) , t1 ) . xyz ;
return normalize ( cross ( dpdx , dpdy ) ) ;
}
vec3 getViewNormal ( const vec2 uv ) {
# if NORMAL _VECTOR _TYPE == 2
return normalize ( textureLod ( tNormal , uv , 0. ) . rgb ) ;
# elif NORMAL _VECTOR _TYPE == 1
return unpackRGBToNormal ( textureLod ( tNormal , uv , 0. ) . rgb ) ;
# else
return computeNormalFromDepth ( uv ) ;
# endif
}
void denoiseSample ( in vec3 center , in vec3 viewNormal , in vec3 viewPos , in vec2 sampleUv , inout vec3 denoised , inout float totalWeight ) {
vec4 sampleTexel = textureLod ( tDiffuse , sampleUv , 0.0 ) ;
float sampleDepth = getDepth ( sampleUv ) ;
vec3 sampleNormal = getViewNormal ( sampleUv ) ;
vec3 neighborColor = sampleTexel . rgb ;
vec3 viewPosSample = getViewPosition ( sampleUv , sampleDepth ) ;
float normalDiff = dot ( viewNormal , sampleNormal ) ;
float normalSimilarity = pow ( max ( normalDiff , 0. ) , normalPhi ) ;
float lumaDiff = abs ( getLuminance ( neighborColor ) - getLuminance ( center ) ) ;
float lumaSimilarity = max ( 1.0 - lumaDiff / lumaPhi , 0.0 ) ;
float depthDiff = abs ( dot ( viewPos - viewPosSample , viewNormal ) ) ;
float depthSimilarity = max ( 1. - depthDiff / depthPhi , 0. ) ;
float w = lumaSimilarity * depthSimilarity * normalSimilarity ;
denoised += w * neighborColor ;
totalWeight += w ;
}
void main ( ) {
float depth = getDepth ( vUv . xy ) ;
vec3 viewNormal = getViewNormal ( vUv ) ;
if ( depth == 1. || dot ( viewNormal , viewNormal ) == 0. ) {
discard ;
return ;
}
vec4 texel = textureLod ( tDiffuse , vUv , 0.0 ) ;
vec3 center = texel . rgb ;
vec3 viewPos = getViewPosition ( vUv , depth ) ;
vec2 noiseResolution = vec2 ( textureSize ( tNoise , 0 ) ) ;
vec2 noiseUv = vUv * resolution / noiseResolution ;
vec4 noiseTexel = textureLod ( tNoise , noiseUv , 0.0 ) ;
vec2 noiseVec = vec2 ( sin ( noiseTexel [ index % 4 ] * 2. * PI ) , cos ( noiseTexel [ index % 4 ] * 2. * PI ) ) ;
mat2 rotationMatrix = mat2 ( noiseVec . x , - noiseVec . y , noiseVec . x , noiseVec . y ) ;
float totalWeight = 1.0 ;
vec3 denoised = texel . rgb ;
for ( int i = 0 ; i < SAMPLES ; i ++ ) {
vec3 sampleDir = poissonDisk [ i ] ;
vec2 offset = rotationMatrix * ( sampleDir . xy * ( 1. + sampleDir . z * ( radius - 1. ) ) / resolution ) ;
vec2 sampleUv = vUv + offset ;
denoiseSample ( center , viewNormal , viewPos , sampleUv , denoised , totalWeight ) ;
}
if ( totalWeight > 0. ) {
denoised /= totalWeight ;
}
gl _FragColor = FRAGMENT _OUTPUT ;
2026-01-22 15:23:57 +08:00
} ` };function Ju(s,e,t){const n=Zv(s,e,t);let i="vec3[SAMPLES](";for(let r=0;r<s;r++){const a=n[r];i+= ` vec3 ( $ { a . x } , $ { a . y } , $ { a . z } ) $ { r < s - 1 ? "," : ")" } ` }return i}function Zv(s,e,t){const n=[];for(let i=0;i<s;i++){const r=2*Math.PI*e*i/s,a=Math.pow(i/(s-1),t);n.push(new P(Math.cos(r),Math.sin(r),a))}return n}class qv{constructor(e=Math){this.grad3=[[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]],this.grad4=[[0,1,1,1],[0,1,1,-1],[0,1,-1,1],[0,1,-1,-1],[0,-1,1,1],[0,-1,1,-1],[0,-1,-1,1],[0,-1,-1,-1],[1,0,1,1],[1,0,1,-1],[1,0,-1,1],[1,0,-1,-1],[-1,0,1,1],[-1,0,1,-1],[-1,0,-1,1],[-1,0,-1,-1],[1,1,0,1],[1,1,0,-1],[1,-1,0,1],[1,-1,0,-1],[-1,1,0,1],[-1,1,0,-1],[-1,-1,0,1],[-1,-1,0,-1],[1,1,1,0],[1,1,-1,0],[1,-1,1,0],[1,-1,-1,0],[-1,1,1,0],[-1,1,-1,0],[-1,-1,1,0],[-1,-1,-1,0]],this.p=[];for(let t=0;t<256;t++)this.p[t]=Math.floor(e.random()*256);this.perm=[];for(let t=0;t<512;t++)this.perm[t]=this.p[t&255];this.simplex=[[0,1,2,3],[0,1,3,2],[0,0,0,0],[0,2,3,1],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,2,3,0],[0,2,1,3],[0,0,0,0],[0,3,1,2],[0,3,2,1],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,3,2,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,2,0,3],[0,0,0,0],[1,3,0,2],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,3,0,1],[2,3,1,0],[1,0,2,3],[1,0,3,2],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,0,3,1],[0,0,0,0],[2,1,3,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,0,1,3],[0,0,0,0],[0,0,0,0],[0,0,0,0],[3,0,1,2],[3,0,2,1],[0,0,0,0],[3,1,2,0],[2,1,0,3],[0,0,0,0],[0,0,0,0],[0,0,0,0],[3,1,0,2],[0,0,0,0],[3,2,0,1],[3,2,1,0]]}noise(e,t){let n,i,r;const a=.5*(Math.sqrt(3)-1),o=(e+t)*a,l=Math.floor(e+o),c=Math.floor(t+o),h=(3-Math.sqrt(3))/6,u=(l+c)*h,f=l-u,d=c-u,p=e-f,g=t-d;let x,m;p>g?(x=1,m=0):(x=0,m=1);const v=p-x+h,b=g-m+h,M=p-1+2*h,C=g-1+2*h,T=l&255,D=c&255,U=this.perm[T+this.perm[D]]%12,S=this.perm[T+x+this.perm[D+m]]%12,w=this.perm[T+1+this.perm[D+1]]%12;let B=.5-p*p-g*g;B<0?n=0:(B*=B,n=B*B*this._dot(this.grad3[U],p,g));let R=.5-v*v-b*b;R<0?i=0:(R*=R,i=R*R*this._dot(this.grad3[S],v,b));let O=.5-M*M-C*C;return O<0?r=0:(O*=O,r=O*O*this._dot(this.grad3[w],M,C)),70*(n+i+r)}noise3d(e,t,n){let i,r,a,o;const l=(e+t+n)*.3333333333333333,c=Math.floor(e+l),h=Math.floor(t+l),u=Math.floor(n+l),f=1/6,d=(c+h+u)*f,p=c-d,g=h-d,x=u-d,m=e-p,v=t-g,b=n-x;let M,C,T,D,U,S;m>=v?v>=b?(M=1,C=0,T=0,D=1,U=1,S=0):m>=b?(M=1,C=0,T=0,D=1,U=0,S=1):(M=0,C=0,T=1,D=1,U=0,S=1):v<b?(M=0,C=0,T=1,D=0,U=1,S=1):m<b?(M=0,C=1,T=0,D=0,U=1,S=1):(M=0,C=1,T=0,D=1,U=1,S=0);const w=m-M+f,B=v-C+f,R=b-T+f,O=m-D+2*f,y=v-U+2*f,H=b-S+2*f,Y=m-1+3*f,j=v-1+3*f,J=b-1+3*f,Z=c&255,ae=h&255,X=u&255,q=this.perm[Z+this.perm[ae+this.perm[X]]]%12,ge=this.perm[Z+M+this.perm[ae+C+this.perm[X+T]]]%12,pe=this.perm[Z+D+this.perm[ae+U+this.perm[X+S]]]%12,de=this.perm[Z+1+this.perm[ae+1+this.perm[X+1]]]%12;let ie=.6-m*m-v*v-b*b;ie<0?i=0:(ie*=ie,i=ie*ie*this._dot3(this.grad3[q],m,v,b));let ce=.6-w*w-B*B-R*R;ce<0?r=0:(ce*=ce,r=ce*ce*this._dot3(this.grad3[ge],w,B,R));let fe=.6-O*O-y*y-H*H;fe<0?a=0:(fe*=fe,a=fe*fe*this._dot3(this.grad3[pe],O,y,H));let ve=.6-Y*Y-j*j-J*J;return ve<0?o=0:(ve*=ve,o=ve*ve*this._dot3(this.grad3[de],Y,j,J)),32*(i+r+a+o)}noise4d(e,t,n,i){const r=this.grad4,a=this.simplex,o=this.perm,l=(Math.sqrt(5)-1)/4,c=(5-Math.sqrt(5))/20;let h,u,f,d,p;const g=(e+t+n+i)*l,x=Math.floor(e+g),m=Math.floor(t+g),v=Math.floor(n+g),b=Math.floor(i+g),M=(x+m+v+b)*c,C=x-M,T=m-M,D=v-M,U=b-M,S=e-C,w=t-T,B=n-D,R=i-U,O=S>w?32:0,y=S>B?16:0,H=w>B?8:0,Y=S>R?4:0,j=w>R?2:0,J=B>R?1:0,Z=O+y+H+Y+j+J,ae=a[Z][0]>=3?1:0,X=a[Z][1]>=3?1:0,q=a[Z][2]>=3?1:0,ge=a[Z][3]>=3?1:0,pe=a[Z][0]>=2?1:0,de=a[Z][1]>=2?1:0,ie=a[Z][2]>=2?1:0,ce=a[Z][3]>=2?1:0,fe=a[Z][0]>=1?1:0,ve=a[Z][1]>=1?1:0,Ee=a[Z][2]>=1?1:0,Ne=a[Z][3]>=1?1:0,Ke=S-ae+c,ke=w-X+c,_=B-q+c,A=R-ge+c,V=S-pe+2*c,N=w-de+2*c,I=B-ie+2*c,F=R-ce+2*c,ee=S-fe+3*c, $ =w-ve+3*c,G=B-Ee+3*c,L=R-Ne+3*c,E=S-1+4*c,z=w-1+4*c,K=B-1+4*c,le=R-1+4*c,te=x&255,Te=m&255,be=v&255,Re=b&255,De=o[te+o[Te+o[be+o[Re]]]]%32,he=o[te+ae+o[Te+X+o[be+q+o[Re+ge]]]]%32,_e=o[te+pe+o[Te+de+o[be+ie+o[Re+ce]]]]%32,He=o[te+fe+
2026-01-22 11:29:51 +08:00
varying vec2 vUv ;
void main ( ) {
vUv = uv ;
gl _Position = projectionMatrix * modelViewMatrix * vec4 ( position , 1.0 ) ;
} ` ,fragmentShader: `
uniform sampler2D tDiffuse ;
uniform vec3 defaultColor ;
uniform float defaultOpacity ;
uniform float luminosityThreshold ;
uniform float smoothWidth ;
varying vec2 vUv ;
void main ( ) {
vec4 texel = texture2D ( tDiffuse , vUv ) ;
float v = luminance ( texel . xyz ) ;
vec4 outputColor = vec4 ( defaultColor . rgb , defaultOpacity ) ;
float alpha = smoothstep ( luminosityThreshold , luminosityThreshold + smoothWidth , v ) ;
gl _FragColor = mix ( outputColor , texel , alpha ) ;
2026-01-22 15:23:57 +08:00
} ` };class As extends Ui{constructor(e,t=1,n,i){super(),this.strength=t,this.radius=n,this.threshold=i,this.resolution=e!==void 0?new ue(e.x,e.y):new ue(256,256),this.clearColor=new Fe(0,0,0),this.needsSwap=!1,this.renderTargetsHorizontal=[],this.renderTargetsVertical=[],this.nMips=5;let r=Math.round(this.resolution.x/2),a=Math.round(this.resolution.y/2);this.renderTargetBright=new nn(r,a,{type:xn}),this.renderTargetBright.texture.name="UnrealBloomPass.bright",this.renderTargetBright.texture.generateMipmaps=!1;for(let h=0;h<this.nMips;h++){const u=new nn(r,a,{type:xn});u.texture.name="UnrealBloomPass.h"+h,u.texture.generateMipmaps=!1,this.renderTargetsHorizontal.push(u);const f=new nn(r,a,{type:xn});f.texture.name="UnrealBloomPass.v"+h,f.texture.generateMipmaps=!1,this.renderTargetsVertical.push(f),r=Math.round(r/2),a=Math.round(a/2)}const o=Yv;this.highPassUniforms=Hn.clone(o.uniforms),this.highPassUniforms.luminosityThreshold.value=i,this.highPassUniforms.smoothWidth.value=.01,this.materialHighPassFilter=new Rt({uniforms:this.highPassUniforms,vertexShader:o.vertexShader,fragmentShader:o.fragmentShader}),this.separableBlurMaterials=[];const l=[6,10,14,18,22];r=Math.round(this.resolution.x/2),a=Math.round(this.resolution.y/2);for(let h=0;h<this.nMips;h++)this.separableBlurMaterials.push(this._getSeparableBlurMaterial(l[h])),this.separableBlurMaterials[h].uniforms.invSize.value=new ue(1/r,1/a),r=Math.round(r/2),a=Math.round(a/2);this.compositeMaterial=this._getCompositeMaterial(this.nMips),this.compositeMaterial.uniforms.blurTexture1.value=this.renderTargetsVertical[0].texture,this.compositeMaterial.uniforms.blurTexture2.value=this.renderTargetsVertical[1].texture,this.compositeMaterial.uniforms.blurTexture3.value=this.renderTargetsVertical[2].texture,this.compositeMaterial.uniforms.blurTexture4.value=this.renderTargetsVertical[3].texture,this.compositeMaterial.uniforms.blurTexture5.value=this.renderTargetsVertical[4].texture,this.compositeMaterial.uniforms.bloomStrength.value=t,this.compositeMaterial.uniforms.bloomRadius.value=.1;const c=[1,.8,.6,.4,.2];this.compositeMaterial.uniforms.bloomFactors.value=c,this.bloomTintColors=[new P(1,1,1),new P(1,1,1),new P(1,1,1),new P(1,1,1),new P(1,1,1)],this.compositeMaterial.uniforms.bloomTintColors.value=this.bloomTintColors,this.copyUniforms=Hn.clone(ki.uniforms),this.blendMaterial=new Rt({uniforms:this.copyUniforms,vertexShader:ki.vertexShader,fragmentShader:ki.fragmentShader,blending:Wa,depthTest:!1,depthWrite:!1,transparent:!0}),this._oldClearColor=new Fe,this._oldClearAlpha=1,this._basic=new Nt,this._fsQuad=new ba(null)}dispose(){for(let e=0;e<this.renderTargetsHorizontal.length;e++)this.renderTargetsHorizontal[e].dispose();for(let e=0;e<this.renderTargetsVertical.length;e++)this.renderTargetsVertical[e].dispose();this.renderTargetBright.dispose();for(let e=0;e<this.separableBlurMaterials.length;e++)this.separableBlurMaterials[e].dispose();this.compositeMaterial.dispose(),this.blendMaterial.dispose(),this._basic.dispose(),this._fsQuad.dispose()}setSize(e,t){let n=Math.round(e/2),i=Math.round(t/2);this.renderTargetBright.setSize(n,i);for(let r=0;r<this.nMips;r++)this.renderTargetsHorizontal[r].setSize(n,i),this.renderTargetsVertical[r].setSize(n,i),this.separableBlurMaterials[r].uniforms.invSize.value=new ue(1/n,1/i),n=Math.round(n/2),i=Math.round(i/2)}render(e,t,n,i,r){e.getClearColor(this._oldClearColor),this._oldClearAlpha=e.getClearAlpha();const a=e.autoClear;e.autoClear=!1,e.setClearColor(this.clearColor,0),r&&e.state.buffers.stencil.setTest(!1),this.renderToScreen&&(this._fsQuad.material=this._basic,this._basic.map=n.texture,e.setRenderTarget(null),e.clear(),this._fsQuad.render(e)),this.highPassUniforms.tDiffuse.value=n.texture,this.highPassUniforms.luminosityThreshold.value=this.threshold,this._fsQuad.material=this.materialHighPassFilter,e.setRenderTarget(this.renderTargetBright),e.clear(),this._fsQuad.render(e);let o=this.renderTargetBright;for(let l=0;l<this.nMips;l++)this._fsQuad.material=this.separableBlurMaterials[l],this.separableBlurMaterials[l].uniforms.colorT
2026-01-22 11:29:51 +08:00
void main ( ) {
vUv = uv ;
gl _Position = projectionMatrix * modelViewMatrix * vec4 ( position , 1.0 ) ;
} ` ,fragmentShader: ` # include < common >
varying vec2 vUv ;
uniform sampler2D colorTexture ;
uniform vec2 invSize ;
uniform vec2 direction ;
uniform float gaussianCoefficients [ KERNEL _RADIUS ] ;
void main ( ) {
float weightSum = gaussianCoefficients [ 0 ] ;
vec3 diffuseSum = texture2D ( colorTexture , vUv ) . rgb * weightSum ;
for ( int i = 1 ; i < KERNEL _RADIUS ; i ++ ) {
float x = float ( i ) ;
float w = gaussianCoefficients [ i ] ;
vec2 uvOffset = direction * invSize * x ;
vec3 sample1 = texture2D ( colorTexture , vUv + uvOffset ) . rgb ;
vec3 sample2 = texture2D ( colorTexture , vUv - uvOffset ) . rgb ;
diffuseSum += ( sample1 + sample2 ) * w ;
}
gl _FragColor = vec4 ( diffuseSum , 1.0 ) ;
2026-01-22 15:23:57 +08:00
} ` })}_getCompositeMaterial(e){return new Rt({defines:{NUM_MIPS:e},uniforms:{blurTexture1:{value:null},blurTexture2:{value:null},blurTexture3:{value:null},blurTexture4:{value:null},blurTexture5:{value:null},bloomStrength:{value:1},bloomFactors:{value:null},bloomTintColors:{value:null},bloomRadius:{value:0}},vertexShader: ` varying vec2 vUv ;
2026-01-22 11:29:51 +08:00
void main ( ) {
vUv = uv ;
gl _Position = projectionMatrix * modelViewMatrix * vec4 ( position , 1.0 ) ;
} ` ,fragmentShader: ` varying vec2 vUv ;
uniform sampler2D blurTexture1 ;
uniform sampler2D blurTexture2 ;
uniform sampler2D blurTexture3 ;
uniform sampler2D blurTexture4 ;
uniform sampler2D blurTexture5 ;
uniform float bloomStrength ;
uniform float bloomRadius ;
uniform float bloomFactors [ NUM _MIPS ] ;
uniform vec3 bloomTintColors [ NUM _MIPS ] ;
float lerpBloomFactor ( const in float factor ) {
float mirrorFactor = 1.2 - factor ;
return mix ( factor , mirrorFactor , bloomRadius ) ;
}
void main ( ) {
gl _FragColor = bloomStrength * ( lerpBloomFactor ( bloomFactors [ 0 ] ) * vec4 ( bloomTintColors [ 0 ] , 1.0 ) * texture2D ( blurTexture1 , vUv ) +
lerpBloomFactor ( bloomFactors [ 1 ] ) * vec4 ( bloomTintColors [ 1 ] , 1.0 ) * texture2D ( blurTexture2 , vUv ) +
lerpBloomFactor ( bloomFactors [ 2 ] ) * vec4 ( bloomTintColors [ 2 ] , 1.0 ) * texture2D ( blurTexture3 , vUv ) +
lerpBloomFactor ( bloomFactors [ 3 ] ) * vec4 ( bloomTintColors [ 3 ] , 1.0 ) * texture2D ( blurTexture4 , vUv ) +
lerpBloomFactor ( bloomFactors [ 4 ] ) * vec4 ( bloomTintColors [ 4 ] , 1.0 ) * texture2D ( blurTexture5 , vUv ) ) ;
2026-01-22 15:23:57 +08:00
} ` })}}As.BlurDirectionX=new ue(1,0),As.BlurDirectionY=new ue(0,1);const wa={name:"OutputShader",uniforms:{tDiffuse:{value:null},toneMappingExposure:{value:1}},vertexShader: `
2026-01-22 11:29:51 +08:00
precision highp float ;
uniform mat4 modelViewMatrix ;
uniform mat4 projectionMatrix ;
attribute vec3 position ;
attribute vec2 uv ;
varying vec2 vUv ;
void main ( ) {
vUv = uv ;
gl _Position = projectionMatrix * modelViewMatrix * vec4 ( position , 1.0 ) ;
} ` ,fragmentShader: `
precision highp float ;
uniform sampler2D tDiffuse ;
# include < tonemapping _pars _fragment >
# include < colorspace _pars _fragment >
varying vec2 vUv ;
void main ( ) {
gl _FragColor = texture2D ( tDiffuse , vUv ) ;
// tone mapping
# ifdef LINEAR _TONE _MAPPING
gl _FragColor . rgb = LinearToneMapping ( gl _FragColor . rgb ) ;
# elif defined ( REINHARD _TONE _MAPPING )
gl _FragColor . rgb = ReinhardToneMapping ( gl _FragColor . rgb ) ;
# elif defined ( CINEON _TONE _MAPPING )
gl _FragColor . rgb = CineonToneMapping ( gl _FragColor . rgb ) ;
# elif defined ( ACES _FILMIC _TONE _MAPPING )
gl _FragColor . rgb = ACESFilmicToneMapping ( gl _FragColor . rgb ) ;
# elif defined ( AGX _TONE _MAPPING )
gl _FragColor . rgb = AgXToneMapping ( gl _FragColor . rgb ) ;
# elif defined ( NEUTRAL _TONE _MAPPING )
gl _FragColor . rgb = NeutralToneMapping ( gl _FragColor . rgb ) ;
# elif defined ( CUSTOM _TONE _MAPPING )
gl _FragColor . rgb = CustomToneMapping ( gl _FragColor . rgb ) ;
# endif
// color space
# ifdef SRGB _TRANSFER
gl _FragColor = sRGBTransferOETF ( gl _FragColor ) ;
# endif
2026-01-22 15:23:57 +08:00
} ` };class Kv extends Ui{constructor(){super(),this.uniforms=Hn.clone(wa.uniforms),this.material=new Dm({name:wa.name,uniforms:this.uniforms,vertexShader:wa.vertexShader,fragmentShader:wa.fragmentShader}),this._fsQuad=new ba(this.material),this._outputColorSpace=null,this._toneMapping=null}render(e,t,n){this.uniforms.tDiffuse.value=n.texture,this.uniforms.toneMappingExposure.value=e.toneMappingExposure,(this._outputColorSpace!==e.outputColorSpace||this._toneMapping!==e.toneMapping)&&(this._outputColorSpace=e.outputColorSpace,this._toneMapping=e.toneMapping,this.material.defines={},nt.getTransfer(this._outputColorSpace)===ot&&(this.material.defines.SRGB_TRANSFER=""),this._toneMapping===Ic?this.material.defines.LINEAR_TONE_MAPPING="":this._toneMapping===Nc?this.material.defines.REINHARD_TONE_MAPPING="":this._toneMapping===kc?this.material.defines.CINEON_TONE_MAPPING="":this._toneMapping===no?this.material.defines.ACES_FILMIC_TONE_MAPPING="":this._toneMapping===Bc?this.material.defines.AGX_TONE_MAPPING="":this._toneMapping===Oc?this.material.defines.NEUTRAL_TONE_MAPPING="":this._toneMapping===Uc&&(this.material.defines.CUSTOM_TONE_MAPPING=""),this.material.needsUpdate=!0),this.renderToScreen===!0?(e.setRenderTarget(null),this._fsQuad.render(e)):(e.setRenderTarget(t),this.clear&&e.clear(e.autoClearColor,e.autoClearDepth,e.autoClearStencil),this._fsQuad.render(e))}dispose(){this.material.dispose(),this._fsQuad.dispose()}}const $ v={name:"FXAAShader",uniforms:{tDiffuse:{value:null},resolution:{value:new ue(1/1024,1/512)}},vertexShader: `
2026-01-22 11:29:51 +08:00
varying vec2 vUv ;
void main ( ) {
vUv = uv ;
gl _Position = projectionMatrix * modelViewMatrix * vec4 ( position , 1.0 ) ;
} ` ,fragmentShader: `
uniform sampler2D tDiffuse ;
uniform vec2 resolution ;
varying vec2 vUv ;
# define EDGE _STEP _COUNT 6
# define EDGE _GUESS 8.0
# define EDGE _STEPS 1.0 , 1.5 , 2.0 , 2.0 , 2.0 , 4.0
const float edgeSteps [ EDGE _STEP _COUNT ] = float [ EDGE _STEP _COUNT ] ( EDGE _STEPS ) ;
float _ContrastThreshold = 0.0312 ;
float _RelativeThreshold = 0.063 ;
float _SubpixelBlending = 1.0 ;
vec4 Sample ( sampler2D tex2D , vec2 uv ) {
return texture ( tex2D , uv ) ;
}
float SampleLuminance ( sampler2D tex2D , vec2 uv ) {
return dot ( Sample ( tex2D , uv ) . rgb , vec3 ( 0.3 , 0.59 , 0.11 ) ) ;
}
float SampleLuminance ( sampler2D tex2D , vec2 texSize , vec2 uv , float uOffset , float vOffset ) {
uv += texSize * vec2 ( uOffset , vOffset ) ;
return SampleLuminance ( tex2D , uv ) ;
}
struct LuminanceData {
float m , n , e , s , w ;
float ne , nw , se , sw ;
float highest , lowest , contrast ;
} ;
LuminanceData SampleLuminanceNeighborhood ( sampler2D tex2D , vec2 texSize , vec2 uv ) {
LuminanceData l ;
l . m = SampleLuminance ( tex2D , uv ) ;
l . n = SampleLuminance ( tex2D , texSize , uv , 0.0 , 1.0 ) ;
l . e = SampleLuminance ( tex2D , texSize , uv , 1.0 , 0.0 ) ;
l . s = SampleLuminance ( tex2D , texSize , uv , 0.0 , - 1.0 ) ;
l . w = SampleLuminance ( tex2D , texSize , uv , - 1.0 , 0.0 ) ;
l . ne = SampleLuminance ( tex2D , texSize , uv , 1.0 , 1.0 ) ;
l . nw = SampleLuminance ( tex2D , texSize , uv , - 1.0 , 1.0 ) ;
l . se = SampleLuminance ( tex2D , texSize , uv , 1.0 , - 1.0 ) ;
l . sw = SampleLuminance ( tex2D , texSize , uv , - 1.0 , - 1.0 ) ;
l . highest = max ( max ( max ( max ( l . n , l . e ) , l . s ) , l . w ) , l . m ) ;
l . lowest = min ( min ( min ( min ( l . n , l . e ) , l . s ) , l . w ) , l . m ) ;
l . contrast = l . highest - l . lowest ;
return l ;
}
bool ShouldSkipPixel ( LuminanceData l ) {
float threshold = max ( _ContrastThreshold , _RelativeThreshold * l . highest ) ;
return l . contrast < threshold ;
}
float DeterminePixelBlendFactor ( LuminanceData l ) {
float f = 2.0 * ( l . n + l . e + l . s + l . w ) ;
f += l . ne + l . nw + l . se + l . sw ;
f *= 1.0 / 12.0 ;
f = abs ( f - l . m ) ;
f = clamp ( f / l . contrast , 0.0 , 1.0 ) ;
float blendFactor = smoothstep ( 0.0 , 1.0 , f ) ;
return blendFactor * blendFactor * _SubpixelBlending ;
}
struct EdgeData {
bool isHorizontal ;
float pixelStep ;
float oppositeLuminance , gradient ;
} ;
EdgeData DetermineEdge ( vec2 texSize , LuminanceData l ) {
EdgeData e ;
float horizontal =
abs ( l . n + l . s - 2.0 * l . m ) * 2.0 +
abs ( l . ne + l . se - 2.0 * l . e ) +
abs ( l . nw + l . sw - 2.0 * l . w ) ;
float vertical =
abs ( l . e + l . w - 2.0 * l . m ) * 2.0 +
abs ( l . ne + l . nw - 2.0 * l . n ) +
abs ( l . se + l . sw - 2.0 * l . s ) ;
e . isHorizontal = horizontal >= vertical ;
float pLuminance = e . isHorizontal ? l . n : l . e ;
float nLuminance = e . isHorizontal ? l . s : l . w ;
float pGradient = abs ( pLuminance - l . m ) ;
float nGradient = abs ( nLuminance - l . m ) ;
e . pixelStep = e . isHorizontal ? texSize . y : texSize . x ;
if ( pGradient < nGradient ) {
e . pixelStep = - e . pixelStep ;
e . oppositeLuminance = nLuminance ;
e . gradient = nGradient ;
} else {
e . oppositeLuminance = pLuminance ;
e . gradient = pGradient ;
}
return e ;
}
float DetermineEdgeBlendFactor ( sampler2D tex2D , vec2 texSize , LuminanceData l , EdgeData e , vec2 uv ) {
vec2 uvEdge = uv ;
vec2 edgeStep ;
if ( e . isHorizontal ) {
uvEdge . y += e . pixelStep * 0.5 ;
edgeStep = vec2 ( texSize . x , 0.0 ) ;
} else {
uvEdge . x += e . pixelStep * 0.5 ;
edgeStep = vec2 ( 0.0 , texSize . y ) ;
}
float edgeLuminance = ( l . m + e . oppositeLuminance ) * 0.5 ;
float gradientThreshold = e . gradient * 0.25 ;
vec2 puv = uvEdge + edgeStep * edgeSteps [ 0 ] ;
float pLuminanceDelta = SampleLuminance ( tex2D , puv ) - edgeLuminance ;
bool pAtEnd = abs ( pLuminanceDelta ) >= gradientThreshold ;
for ( int i = 1 ; i < EDGE _STEP _COUNT && ! pAtEnd ; i ++ ) {
puv += edgeStep * edgeSteps [ i ] ;
pLuminanceDelta = SampleLuminance ( tex2D , puv ) - edgeLuminance ;
pAtEnd = abs ( pLuminanceDelta ) >= gradientThreshold ;
}
if ( ! pAtEnd ) {
puv += edgeStep * EDGE _GUESS ;
}
vec2 nuv = uvEdge - edgeStep * edgeSteps [ 0 ] ;
float nLuminanceDelta = SampleLuminance ( tex2D , nuv ) - edgeLuminance ;
bool nAtEnd = abs ( nLuminanceDelta ) >= gradientThreshold ;
for ( int i = 1 ; i < EDGE _STEP _COUNT && ! nAtEnd ; i ++ ) {
nuv -= edgeStep * edgeSteps [ i ] ;
nLuminanceDelta = SampleLuminance ( tex2D , nuv ) - edgeLuminance ;
nAtEnd = abs ( nLuminanceDelta ) >= gradientThreshold ;
}
if ( ! nAtEnd ) {
nuv -= edgeStep * EDGE _GUESS ;
}
float pDistance , nDistance ;
if ( e . isHorizontal ) {
pDistance = puv . x - uv . x ;
nDistance = uv . x - nuv . x ;
} else {
pDistance = puv . y - uv . y ;
nDistance = uv . y - nuv . y ;
}
float shortestDistance ;
bool deltaSign ;
if ( pDistance <= nDistance ) {
shortestDistance = pDistance ;
deltaSign = pLuminanceDelta >= 0.0 ;
} else {
shortestDistance = nDistance ;
deltaSign = nLuminanceDelta >= 0.0 ;
}
if ( deltaSign == ( l . m - edgeLuminance >= 0.0 ) ) {
return 0.0 ;
}
return 0.5 - shortestDistance / ( pDistance + nDistance ) ;
}
vec4 ApplyFXAA ( sampler2D tex2D , vec2 texSize , vec2 uv ) {
LuminanceData luminance = SampleLuminanceNeighborhood ( tex2D , texSize , uv ) ;
if ( ShouldSkipPixel ( luminance ) ) {
return Sample ( tex2D , uv ) ;
}
float pixelBlend = DeterminePixelBlendFactor ( luminance ) ;
EdgeData edge = DetermineEdge ( texSize , luminance ) ;
float edgeBlend = DetermineEdgeBlendFactor ( tex2D , texSize , luminance , edge , uv ) ;
float finalBlend = max ( pixelBlend , edgeBlend ) ;
if ( edge . isHorizontal ) {
uv . y += edge . pixelStep * finalBlend ;
} else {
uv . x += edge . pixelStep * finalBlend ;
}
return Sample ( tex2D , uv ) ;
}
void main ( ) {
gl _FragColor = ApplyFXAA ( tDiffuse , resolution . xy , vUv ) ;
2026-01-22 15:23:57 +08:00
} ` },Jv={uniforms:{tDiffuse:{value:null},saturation:{value:1.2},contrast:{value:1.2}},vertexShader: `
2026-01-22 11:29:51 +08:00
varying vec2 vUv ;
void main ( ) {
vUv = uv ;
gl _Position = projectionMatrix * modelViewMatrix * vec4 ( position , 1.0 ) ;
}
` ,fragmentShader: `
uniform sampler2D tDiffuse ;
uniform float saturation ;
uniform float contrast ;
varying vec2 vUv ;
void main ( ) {
vec4 color = texture2D ( tDiffuse , vUv ) ;
// 转换为灰度值用于饱和度调整
float gray = dot ( color . rgb , vec3 ( 0.299 , 0.587 , 0.114 ) ) ;
// 混合原始颜色和灰度值来调整饱和度
color . rgb = mix ( vec3 ( gray ) , color . rgb , saturation ) ;
// 调整对比度
color . rgb = ( color . rgb - 0.5 ) * contrast + 0.5 ;
gl _FragColor = color ;
}
2026-01-22 15:23:57 +08:00
` };class Qv{engine;composer;saturationPass;constructor(e){this.engine=e}resize(){const{width:e,height:t}=this.engine.deviceModule.getContainerSize(),n=e/t;if(this.composer){this.composer.setPixelRatio(n),this.composer.setSize(e,t);const i=this.composer.passes.find(r=>r instanceof _a&&r.material.uniforms.resolution);i&&(i.material.uniforms.resolution.value.x=1/(e*n),i.material.uniforms.resolution.value.y=1/(t*n))}}init(){const{width:e,height:t}=this.engine.deviceModule.getContainerSize(),n=this.engine.scene,i=this.engine.camera,r=this.engine.renderer,a=e/t,o=new nn(e,t,{minFilter:Wt,magFilter:Wt,format:tn,samples:4});this.composer=new Gv(r,o),this.composer.setPixelRatio(a),this.composer.setSize(e,t);const l=new Wv(n,i);this.composer.addPass(l);const c=new on(n,i,e,t);c.output=on.OUTPUT.Default,c.blendIntensity=.5,c.updateGtaoMaterial&&c.updateGtaoMaterial({radius:1,distanceExponent:1,thickness:1,scale:1,distanceFallOff:1,screenSpaceRadius:!0}),new As(new ue(e,t),.1,.1,.5),this.saturationPass=new _a(Jv),this.saturationPass.uniforms.saturation.value=1.3,this.saturationPass.uniforms.contrast.value=1.1,this.composer.addPass(this.saturationPass);const h=new Kv;this.composer.addPass(h);const u=new _a( $ v);u.material.uniforms.resolution.value.x=1/(e*a),u.material.uniforms.resolution.value.y=1/(t*a),this.composer.addPass(u)}}var Ea=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Qu(s){return s&&s.__esModule&&Object.prototype.hasOwnProperty.call(s,"default")?s.default:s}function Ta(s){throw new Error('Could not dynamically require "'+s+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}var ed={exports:{}},td;function eb(){return td||(td=1,(function(s,e){(function(t){s.exports=t()})(function(){return(function t(n,i,r){function a(c,h){if(!i[c]){if(!n[c]){var u=typeof Ta=="function"&&Ta;if(!h&&u)return u(c,!0);if(o)return o(c,!0);var f=new Error("Cannot find module '"+c+"'");throw f.code="MODULE_NOT_FOUND",f}var d=i[c]={exports:{}};n[c][0].call(d.exports,function(p){var g=n[c][1][p];return a(g||p)},d,d.exports,t,n,i,r)}return i[c].exports}for(var o=typeof Ta=="function"&&Ta,l=0;l<r.length;l++)a(r[l]);return a})({1:[function(t,n,i){var r=t("./utils"),a=t("./support"),o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";i.encode=function(l){for(var c,h,u,f,d,p,g,x=[],m=0,v=l.length,b=v,M=r.getTypeOf(l)!=="string";m<l.length;)b=v-m,u=M?(c=l[m++],h=m<v?l[m++]:0,m<v?l[m++]:0):(c=l.charCodeAt(m++),h=m<v?l.charCodeAt(m++):0,m<v?l.charCodeAt(m++):0),f=c>>2,d=(3&c)<<4|h>>4,p=1<b?(15&h)<<2|u>>6:64,g=2<b?63&u:64,x.push(o.charAt(f)+o.charAt(d)+o.charAt(p)+o.charAt(g));return x.join("")},i.decode=function(l){var c,h,u,f,d,p,g=0,x=0,m="data:";if(l.substr(0,m.length)===m)throw new Error("Invalid base64 input, it looks like a data url.");var v,b=3*(l=l.replace(/[^A-Za-z0-9+/=]/g,"")).length/4;if(l.charAt(l.length-1)===o.charAt(64)&&b--,l.charAt(l.length-2)===o.charAt(64)&&b--,b%1!=0)throw new Error("Invalid base64 input, bad content length.");for(v=a.uint8array?new Uint8Array(0|b):new Array(0|b);g<l.length;)c=o.indexOf(l.charAt(g++))<<2|(f=o.indexOf(l.charAt(g++)))>>4,h=(15&f)<<4|(d=o.indexOf(l.charAt(g++)))>>2,u=(3&d)<<6|(p=o.indexOf(l.charAt(g++))),v[x++]=c,d!==64&&(v[x++]=h),p!==64&&(v[x++]=u);return v}},{"./support":30,"./utils":32}],2:[function(t,n,i){var r=t("./external"),a=t("./stream/DataWorker"),o=t("./stream/Crc32Probe"),l=t("./stream/DataLengthProbe");function c(h,u,f,d,p){this.compressedSize=h,this.uncompressedSize=u,this.crc32=f,this.compression=d,this.compressedContent=p}c.prototype={getContentWorker:function(){var h=new a(r.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new l("data_length")),u=this;return h.on("end",function(){if(this.streamInfo.data_length!==u.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),h},getCompressedWorker:function(){return new a(r.Promise.resolve(thi
\ 0 ` ,pe+=r(X,2),pe+=T.magic,pe+=r(b,2),pe+=r(M,2),pe+=r(ae.crc32,4),pe+=r(ae.compressedSize,4),pe+=r(ae.uncompressedSize,4),pe+=r(U.length,2),pe+=r(H.length,2),{fileRecord:u.LOCAL_FILE_HEADER+pe+U+H,dirRecord:u.CENTRAL_FILE_HEADER+r(ge,2)+pe+r(B.length,2)+" \0 \0 \0 \0 "+r(q,4)+r(x,4)+U+H+B}}var o=t("../utils"),l=t("../stream/GenericWorker"),c=t("../utf8"),h=t("../crc32"),u=t("../signature");function f(d,p,g,x){l.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=p,this.zipPlatform=g,this.encodeFileName=x,this.streamFiles=d,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}o.inherits(f,l),f.prototype.push=function(d){var p=d.meta.percent||0,g=this.entriesCount,x=this._sources.length;this.accumulate?this.contentBuffer.push(d):(this.bytesWritten+=d.data.length,l.prototype.push.call(this,{data:d.data,meta:{currentFile:this.currentFile,percent:g?(p+100*(g-x-1))/g:100}}))},f.prototype.openedSource=function(d){this.currentSourceOffset=this.bytesWritten,this.currentFile=d.file.name;var p=this.streamFiles&&!d.file.dir;if(p){var g=a(d,p,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:g.fileRecord,meta:{percent:0}})}else this.accumulate=!0},f.prototype.closedSource=function(d){this.accumulate=!1;var p=this.streamFiles&&!d.file.dir,g=a(d,p,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(g.dirRecord),p)this.push({data:(function(x){return u.DATA_DESCRIPTOR+r(x.crc32,4)+r(x.compressedSize,4)+r(x.uncompressedSize,4)})(d),meta:{percent:100}});else for(this.push({data:g.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},f.prototype.flush=function(){for(var d=this.bytesWritten,p=0;p<this.dirRecords.length;p++)this.push({data:this.dirRecords[p],meta:{percent:100}});var g=this.bytesWritten-d,x=(function(m,v,b,M,C){var T=o.transformTo("string",C(M));return u.CENTRAL_DIRECTORY_END+" \0 \0 \0 \0 "+r(m,2)+r(m,2)+r(v,4)+r(b,4)+r(T.length,2)+T})(this.dirRecords.length,g,d,this.zipComment,this.encodeFileName);this.push({data:x,meta:{percent:100}})},f.prototype.prepareNextSource=function(){this.previous=this._sources.shift(),this.openedSource(this.previous.streamInfo),this.isPaused?this.previous.pause():this.previous.resume()},f.prototype.registerPrevious=function(d){this._sources.push(d);var p=this;return d.on("data",function(g){p.processChunk(g)}),d.on("end",function(){p.closedSource(p.previous.streamInfo),p._sources.length?p.prepareNextSource():p.end()}),d.on("error",function(g){p.error(g)}),this},f.prototype.resume=function(){return!!l.prototype.resume.call(this)&&(!this.previous&&this._sources.length?(this.prepareNextSource(),!0):this.previous||this._sources.length||this.generatedError?void 0:(this.end(),!0))},f.prototype.error=function(d){var p=this._sources;if(!l.prototype.error.call(this,d))return!1;for(var g=0;g<p.length;g++)try{p[g].error(d)}catch{}return!0},f.prototype.lock=function(){l.prototype.lock.call(this);for(var d=this._sources,p=0;p<d.length;p++)d[p].lock()},n.exports=f},{"../crc32":4,"../signature":23,"../stream/GenericWorker":28,"../utf8":31,"../utils":32}],9:[function(t,n,i){var r=t("../compressions"),a=t("./ZipFileWorker");i.generateWorker=function(o,l,c){var h=new a(l.streamFiles,c,l.platform,l.encodeFileName),u=0;try{o.forEach(function(f,d){u++;var p=(function(v,b){var M=v||b,C=r[M];if(!C)throw new Error(M+" is not a valid compression method !");return C})(d.options.compression,l.compression),g=d.options.compressionOptions||l.compressionOptions||{},x=d.dir,m=d.date;d._compressWorker(p,g).withStreamInfo("file",{name:f,dir:x,date:m,comment:d.comment||"",unixPermissions:d.unixPermissions,dosPermissions:d.dosPermissions}).pipe(h)}),h.entriesCount=u}catch(f){h.error(f)}return h}},{"../compressions":3,"./ZipFileWorker":8}],10:[function(t,n,i){function r(){if(!(this instanceof r))return new r;if(arguments.length)throw new Error("The constructor with parameters has been removed in JSZip 3.0, pl
` ).forEach(function(r){i=r.indexOf(":"),t=r.substring(0,i).trim().toLowerCase(),n=r.substring(i+1).trim(),!(!t||e[t]&&s_[t])&&(t==="set-cookie"?e[t]?e[t].push(n):e[t]=[n]:e[t]=e[t]?e[t]+", "+n:n)}),e},yd=Symbol("internals");function xr(s){return s&&String(s).trim().toLowerCase()}function Da(s){return s===!1||s==null?s:se.isArray(s)?s.map(Da):String(s)}function a_(s){const e=Object.create(null),t=/([^ \s ,;=]+) \s *(?:= \s *([^,;]+))?/g;let n;for(;n=t.exec(s);)e[n[1]]=n[2];return e}const o_=s=>/^[-_a-zA-Z0-9^ ` | ~ , ! # $ % & ' * + . ] + $ / . test ( s . trim ( ) ) ; function ac ( s , e , t , n , i ) { if ( se . isFunction ( n ) ) return n . call ( this , e , t ) ; if ( i && ( e = t ) , ! ! se . isString ( e ) ) { if ( se . isString ( n ) ) return e . indexOf ( n ) !== - 1 ; if ( se . isRegExp ( n ) ) return n . test ( e ) } } function l _ ( s ) { return s . trim ( ) . toLowerCase ( ) . replace ( /([a-z\d])(\w*)/g , ( e , t , n ) => t . toUpperCase ( ) + n ) } function c _ ( s , e ) { const t = se . toCamelCase ( " " + e ) ; [ "get" , "set" , "has" ] . forEach ( n => { Object . defineProperty ( s , n + t , { value : function ( i , r , a ) { return this [ n ] . call ( this , e , i , r , a ) } , configurable : ! 0 } ) } ) } let cn = class { constructor ( s ) { s && this . set ( s ) } set ( s , e , t ) { const n = this ; function i ( a , o , l ) { const c = xr ( o ) ; if ( ! c ) throw new Error ( "header name must be a non-empty string" ) ; const h = se . findKey ( n , c ) ; ( ! h || n [ h ] === void 0 || l === ! 0 || l === void 0 && n [ h ] !== ! 1 ) && ( n [ h || o ] = Da ( a ) ) } const r = ( a , o ) => se . forEach ( a , ( l , c ) => i ( l , c , o ) ) ; if ( se . isPlainObject ( s ) || s instanceof this . constructor ) r ( s , e ) ; else if ( se . isString ( s ) && ( s = s . trim ( ) ) && ! o _ ( s ) ) r ( r _ ( s ) , e ) ; else if ( se . isObject ( s ) && se . isIterable ( s ) ) { let a = { } , o , l ; for ( const c of s ) { if ( ! se . isArray ( c ) ) throw TypeError ( "Object iterator must return a key-value pair" ) ; a [ l = c [ 0 ] ] = ( o = a [ l ] ) ? se . isArray ( o ) ? [ ... o , c [ 1 ] ] : [ o , c [ 1 ] ] : c [ 1 ] } r ( a , e ) } else s != null && i ( e , s , t ) ; return this } get ( s , e ) { if ( s = xr ( s ) , s ) { const t = se . findKey ( this , s ) ; if ( t ) { const n = this [ t ] ; if ( ! e ) return n ; if ( e === ! 0 ) return a _ ( n ) ; if ( se . isFunction ( e ) ) return e . call ( this , n , t ) ; if ( se . isRegExp ( e ) ) return e . exec ( n ) ; throw new TypeError ( "parser must be boolean|regexp|function" ) } } } has ( s , e ) { if ( s = xr ( s ) , s ) { const t = se . findKey ( this , s ) ; return ! ! ( t && this [ t ] !== void 0 && ( ! e || ac ( this , this [ t ] , t , e ) ) ) } return ! 1 } delete ( s , e ) { const t = this ; let n = ! 1 ; function i ( r ) { if ( r = xr ( r ) , r ) { const a = se . findKey ( t , r ) ; a && ( ! e || ac ( t , t [ a ] , a , e ) ) && ( delete t [ a ] , n = ! 0 ) } } return se . isArray ( s ) ? s . forEach ( i ) : i ( s ) , n } clear ( s ) { const e = Object . keys ( this ) ; let t = e . length , n = ! 1 ; for ( ; t -- ; ) { const i = e [ t ] ; ( ! s || ac ( this , this [ i ] , i , s , ! 0 ) ) && ( delete this [ i ] , n = ! 0 ) } return n } normalize ( s ) { const e = this , t = { } ; return se . forEach ( this , ( n , i ) => { const r = se . findKey ( t , i ) ; if ( r ) { e [ r ] = Da ( n ) , delete e [ i ] ; return } const a = s ? l _ ( i ) : String ( i ) . trim ( ) ; a !== i && delete e [ i ] , e [ a ] = Da ( n ) , t [ a ] = ! 0 } ) , this } concat ( ... s ) { return this . constructor . concat ( this , ... s ) } toJSON ( s ) { const e = Object . create ( null ) ; return se . forEach ( this , ( t , n ) => { t != null && t !== ! 1 && ( e [ n ] = s && se . isArray ( t ) ? t . join ( ", " ) : t ) } ) , e } [ Symbol . iterator ] ( ) { return Object . entries ( this . toJSON ( ) ) [ Symbol . iterator ] ( ) } toString ( ) { return Object . entries ( this . toJSON ( ) ) . map ( ( [ s , e ] ) => s + ": " + e ) . join ( `
` )}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(s){return s instanceof this?s:new this(s)}static concat(s,...e){const t=new this(s);return e.forEach(n=>t.set(n)),t}static accessor(s){const e=(this[yd]=this[yd]={accessors:{}}).accessors,t=this.prototype;function n(i){const r=xr(i);e[r]||(c_(t,i),e[r]=!0)}return se.isArray(s)?s.forEach(n):n(s),this}};cn.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),se.reduceDescriptors(cn.prototype,({value:s},e)=>{let t=e[0].toUpperCase()+e.slice(1);return{get:()=>s,set(n){this[t]=n}}}),se.freezeMethods(cn);function oc(s,e){const t=this||gr,n=e||t,i=cn.from(n.headers);let r=n.data;return se.forEach(s,function(a){r=a.call(t,r,i.normalize(),e?e.status:void 0)}),i.normalize(),r}function Md(s){return!!(s&&s.__CANCEL__)}function Ls(s,e,t){Ye.call(this,s??"canceled",Ye.ERR_CANCELED,e,t),this.name="CanceledError"}se.inherits(Ls,Ye,{__CANCEL__:!0});function Sd(s,e,t){const n=t.config.validateStatus;!t.status||!n||n(t.status)?s(t):e(new Ye("Request failed with status code "+t.status,[Ye.ERR_BAD_REQUEST,Ye.ERR_BAD_RESPONSE][Math.floor(t.status/100)-4],t.config,t.request,t))}function h_(s){const e=/^([-+ \w ]{1,25})(:? \/ \/ |:)/.exec(s);return e&&e[1]||""}function u_(s,e){s=s||10;const t=new Array(s),n=new Array(s);let i=0,r=0,a;return e=e!==void 0?e:1e3,function(o){const l=Date.now(),c=n[r];a||(a=l),t[i]=o,n[i]=l;let h=r,u=0;for(;h!==i;)u+=t[h++],h=h%s;if(i=(i+1)%s,i===r&&(r=(r+1)%s),l-a<e)return;const f=c&&l-c;return f?Math.round(u*1e3/f):void 0}}function d_(s,e){let t=0,n=1e3/e,i,r;const a=(o,l=Date.now())=>{t=l,i=null,r&&(clearTimeout(r),r=null),s(...o)};return[(...o)=>{const l=Date.now(),c=l-t;c>=n?a(o,l):(i=o,r||(r=setTimeout(()=>{r=null,a(i)},n-c)))},()=>i&&a(i)]}const Ia=(s,e,t=3)=>{let n=0;const i=u_(50,250);return d_(r=>{const a=r.loaded,o=r.lengthComputable?r.total:void 0,l=a-n,c=i(l),h=a<=o;n=a;const u={loaded:a,total:o,progress:o?a/o:void 0,bytes:l,rate:c||void 0,estimated:c&&o&&h?(o-a)/c:void 0,event:r,lengthComputable:o!=null,[e?"download":"upload"]:!0};s(u)},t)},wd=(s,e)=>{const t=s!=null;return[n=>e[0]({lengthComputable:t,total:s,loaded:n}),e[1]]},Ed=s=>(...e)=>se.asap(()=>s(...e)),f_=qt.hasStandardBrowserEnv?((s,e)=>t=>(t=new URL(t,qt.origin),s.protocol===t.protocol&&s.host===t.host&&(e||s.port===t.port)))(new URL(qt.origin),qt.navigator&&/(msie|trident)/i.test(qt.navigator.userAgent)):()=>!0,p_=qt.hasStandardBrowserEnv?{write(s,e,t,n,i,r,a){if(typeof document>"u")return;const o=[ ` $ { s } = $ { encodeURIComponent ( e ) } ` ];se.isNumber(t)&&o.push( ` expires = $ { new Date ( t ) . toUTCString ( ) } ` ),se.isString(n)&&o.push( ` path = $ { n } ` ),se.isString(i)&&o.push( ` domain = $ { i } ` ),r===!0&&o.push("secure"),se.isString(a)&&o.push( ` SameSite = $ { a } ` ),document.cookie=o.join("; ")},read(s){if(typeof document>"u")return null;const e=document.cookie.match(new RegExp("(?:^|; )"+s+"=([^;]*)"));return e?decodeURIComponent(e[1]):null},remove(s){this.write(s,"",Date.now()-864e5,"/")}}:{write(){},read(){return null},remove(){}};function m_(s){return/^([a-z][a-z \d + \- .]*:)? \/ \/ /i.test(s)}function g_(s,e){return e?s.replace(/ \/ ? \/ $ /,"")+"/"+e.replace(/^ \/ +/,""):s}function Td(s,e,t){let n=!m_(e);return s&&(n||t==!1)?g_(s,e):e}const Cd=s=>s instanceof cn?{...s}:s;function Oi(s,e){e=e||{};const t={};function n(c,h,u,f){return se.isPlainObject(c)&&se.isPlainObject(h)?se.merge.call({caseless:f},c,h):se.isPlainObject(h)?se.merge({},h):se.isArray(h)?h.slice():h}function i(c,h,u,f){if(se.isUndefined(h)){if(!se.isUndefined(c))return n(void 0,c,u,f)}else return n(c,h,u,f)}function r(c,h){if(!se.isUndefined(h))return n(void 0,h)}function a(c,h){if(se.isUndefined(h)){if(!se.isUndefined(c))return n(void 0,c)}else return n(void 0,h)}function o(c,h,u){if(u in e)return n(c,h);if(u in s)return n(void 0,c)}const l={url:r,method:r,data:r,baseURL:a,transformRequest:a,transformResponse:a,paramsSerializer:a,timeout:a,timeoutMessage:a,withCredentials:a,withXSRFToken:a,adapter:a,responseType:a,xsrfCookieName:a,xsrfHeaderName:a,onUploadProgress:a,o
` +a.map(kd).join( `
` ):" "+kd(a[0]):"as no adapter specified";throw new Ye("There is no suitable adapter to dispatch the request "+o,"ERR_NOT_SUPPORT")}return i}const Ud={getAdapter:C_,adapters:lc};function cc(s){if(s.cancelToken&&s.cancelToken.throwIfRequested(),s.signal&&s.signal.aborted)throw new Ls(null,s)}function Bd(s){return cc(s),s.headers=cn.from(s.headers),s.data=oc.call(s,s.transformRequest),["post","put","patch"].indexOf(s.method)!==-1&&s.headers.setContentType("application/x-www-form-urlencoded",!1),Ud.getAdapter(s.adapter||gr.adapter,s)(s).then(function(e){return cc(s),e.data=oc.call(s,s.transformResponse,e),e.headers=cn.from(e.headers),e},function(e){return Md(e)||(cc(s),e&&e.response&&(e.response.data=oc.call(s,s.transformResponse,e.response),e.response.headers=cn.from(e.response.headers))),Promise.reject(e)})}const Od="1.13.2",ka={};["object","boolean","number","function","string","symbol"].forEach((s,e)=>{ka[s]=function(t){return typeof t===s||"a"+(e<1?"n ":" ")+s}});const Fd={};ka.transitional=function(s,e,t){function n(i,r){return"[Axios v"+Od+"] Transitional option '"+i+"'"+r+(t?". "+t:"")}return(i,r,a)=>{if(s===!1)throw new Ye(n(r," has been removed"+(e?" in "+e:"")),Ye.ERR_DEPRECATED);return e&&!Fd[r]&&(Fd[r]=!0,console.warn(n(r," has been deprecated since v"+e+" and will be removed in the near future"))),s?s(i,r,a):!0}},ka.spelling=function(s){return(e,t)=>(console.warn( ` $ { t } is likely a misspelling of $ { s } ` ),!0)};function A_(s,e,t){if(typeof s!="object")throw new Ye("options must be an object",Ye.ERR_BAD_OPTION_VALUE);const n=Object.keys(s);let i=n.length;for(;i-- >0;){const r=n[i],a=e[r];if(a){const o=s[r],l=o===void 0||a(o,r,s);if(l!==!0)throw new Ye("option "+r+" must be "+l,Ye.ERR_BAD_OPTION_VALUE);continue}if(t!==!0)throw new Ye("Unknown option "+r,Ye.ERR_BAD_OPTION)}}const Ua={assertOptions:A_,validators:ka},Wn=Ua.validators;let Fi=class{constructor(s){this.defaults=s||{},this.interceptors={request:new vd,response:new vd}}async request(s,e){try{return await this._request(s,e)}catch(t){if(t instanceof Error){let n={};Error.captureStackTrace?Error.captureStackTrace(n):n=new Error;const i=n.stack?n.stack.replace(/^.+ \n /,""):"";try{t.stack?i&&!String(t.stack).endsWith(i.replace(/^.+ \n .+ \n /,""))&&(t.stack+= `
` +i):t.stack=i}catch{}}throw t}}_request(s,e){typeof s=="string"?(e=e||{},e.url=s):e=s||{},e=Oi(this.defaults,e);const{transitional:t,paramsSerializer:n,headers:i}=e;t!==void 0&&Ua.assertOptions(t,{silentJSONParsing:Wn.transitional(Wn.boolean),forcedJSONParsing:Wn.transitional(Wn.boolean),clarifyTimeoutError:Wn.transitional(Wn.boolean)},!1),n!=null&&(se.isFunction(n)?e.paramsSerializer={serialize:n}:Ua.assertOptions(n,{encode:Wn.function,serialize:Wn.function},!0)),e.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?e.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:e.allowAbsoluteUrls=!0),Ua.assertOptions(e,{baseUrl:Wn.spelling("baseURL"),withXsrfToken:Wn.spelling("withXSRFToken")},!0),e.method=(e.method||this.defaults.method||"get").toLowerCase();let r=i&&se.merge(i.common,i[e.method]);i&&se.forEach(["delete","get","head","post","put","patch","common"],d=>{delete i[d]}),e.headers=cn.concat(r,i);const a=[];let o=!0;this.interceptors.request.forEach(function(d){typeof d.runWhen=="function"&&d.runWhen(e)===!1||(o=o&&d.synchronous,a.unshift(d.fulfilled,d.rejected))});const l=[];this.interceptors.response.forEach(function(d){l.push(d.fulfilled,d.rejected)});let c,h=0,u;if(!o){const d=[Bd.bind(this),void 0];for(d.unshift(...a),d.push(...l),u=d.length,c=Promise.resolve(e);h<u;)c=c.then(d[h++],d[h++]);return c}u=a.length;let f=e;for(;h<u;){const d=a[h++],p=a[h++];try{f=d(f)}catch(g){p.call(this,g);break}}try{c=Bd.call(this,f)}catch(d){return Promise.reject(d)}for(h=0,u=l.length;h<u;)c=c.then(l[h++],l[h++]);return c}getUri(s){s=Oi(this.defaults,s);const e=Td(s.baseURL,s.url,s.allowAbsoluteUrls);return xd(e,s.params,s.paramsSerializer)}};se.forEach(["delete","get","head","options"],function(s){Fi.prototype[s]=function(e,t){return this.request(Oi(t||{},{method:s,url:e,data:(t||{}).data}))}}),se.forEach(["post","put","patch"],function(s){function e(t){return function(n,i,r){return this.request(Oi(r||{},{method:s,headers:t?{"Content-Type":"multipart/form-data"}:{},url:n,data:i}))}}Fi.prototype[s]=e(),Fi.prototype[s+"Form"]=e(!0)});let P_=class pf{constructor(e){if(typeof e!="function")throw new TypeError("executor must be a function.");let t;this.promise=new Promise(function(i){t=i});const n=this;this.promise.then(i=>{if(!n._listeners)return;let r=n._listeners.length;for(;r-- >0;)n._listeners[r](i);n._listeners=null}),this.promise.then=i=>{let r;const a=new Promise(o=>{n.subscribe(o),r=o}).then(i);return a.cancel=function(){n.unsubscribe(r)},a},e(function(i,r,a){n.reason||(n.reason=new Ls(i,r,a),t(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const t=this._listeners.indexOf(e);t!==-1&&this._listeners.splice(t,1)}toAbortSignal(){const e=new AbortController,t=n=>{e.abort(n)};return this.subscribe(t),e.signal.unsubscribe=()=>this.unsubscribe(t),e.signal}static source(){let e;return{token:new pf(function(t){e=t}),cancel:e}}};function R_(s){return function(e){return s.apply(null,e)}}function L_(s){return se.isObject(s)&&s.isAxiosError===!0}const hc={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:4
` );this.workerSourceURL=URL.createObjectURL(new Blob([a]))}),this.decoderPending}_getWorker(e,t){return this._initDecoder().then(()=>{if(this.workerPool.length<this.workerLimit){const i=new Worker(this.workerSourceURL);i._callbacks={},i._taskCosts={},i._taskLoad=0,i.postMessage({type:"init",decoderConfig:this.decoderConfig}),i.onmessage=function(r){const a=r.data;switch(a.type){case"decode":i._callbacks[a.id].resolve(a);break;case"error":i._callbacks[a.id].reject(a);break;default:console.error('THREE.DRACOLoader: Unexpected message, "'+a.type+'"')}},this.workerPool.push(i)}else this.workerPool.sort(function(i,r){return i._taskLoad>r._taskLoad?-1:1});const n=this.workerPool[this.workerPool.length-1];return n._taskCosts[e]=t,n._taskLoad+=t,n})}_releaseTask(e,t){e._taskLoad-=e._taskCosts[t],delete e._callbacks[t],delete e._taskCosts[t]}debug(){console.log("Task load: ",this.workerPool.map(e=>e._taskLoad))}dispose(){for(let e=0;e<this.workerPool.length;++e)this.workerPool[e].terminate();return this.workerPool.length=0,this.workerSourceURL!==""&&URL.revokeObjectURL(this.workerSourceURL),this}}function N_(){let s,e;onmessage=function(a){const o=a.data;switch(o.type){case"init":s=o.decoderConfig,e=new Promise(function(h){s.onModuleLoaded=function(u){h({draco:u})},DracoDecoderModule(s)});break;case"decode":const l=o.buffer,c=o.taskConfig;e.then(h=>{const u=h.draco,f=new u.Decoder;try{const d=t(u,f,new Int8Array(l),c),p=d.attributes.map(g=>g.array.buffer);d.index&&p.push(d.index.array.buffer),self.postMessage({type:"decode",id:o.id,geometry:d},p)}catch(d){console.error(d),self.postMessage({type:"error",id:o.id,error:d.message})}finally{u.destroy(f)}});break}};function t(a,o,l,c){const h=c.attributeIDs,u=c.attributeTypes;let f,d;const p=o.GetEncodedGeometryType(l);if(p===a.TRIANGULAR_MESH)f=new a.Mesh,d=o.DecodeArrayToMesh(l,l.byteLength,f);else if(p===a.POINT_CLOUD)f=new a.PointCloud,d=o.DecodeArrayToPointCloud(l,l.byteLength,f);else throw new Error("THREE.DRACOLoader: Unexpected geometry type.");if(!d.ok()||f.ptr===0)throw new Error("THREE.DRACOLoader: Decoding failed: "+d.error_msg());const g={index:null,attributes:[]};for(const x in h){const m=self[u[x]];let v,b;if(c.useUniqueIDs)b=h[x],v=o.GetAttributeByUniqueId(f,b);else{if(b=o.GetAttributeId(f,a[h[x]]),b===-1)continue;v=o.GetAttribute(f,b)}const M=i(a,o,f,x,m,v);x==="color"&&(M.vertexColorSpace=c.vertexColorSpace),g.attributes.push(M)}return p===a.TRIANGULAR_MESH&&(g.index=n(a,o,f)),a.destroy(f),g}function n(a,o,l){const c=l.num_faces()*3,h=c*4,u=a._malloc(h);o.GetTrianglesUInt32Array(l,h,u);const f=new Uint32Array(a.HEAPF32.buffer,u,c).slice();return a._free(u),{array:f,itemSize:1}}function i(a,o,l,c,h,u){const f=l.num_points(),d=u.num_components(),p=r(a,h),g=d*h.BYTES_PER_ELEMENT,x=Math.ceil(g/4)*4,m=x/h.BYTES_PER_ELEMENT,v=f*g,b=f*x,M=a._malloc(v);o.GetAttributeDataArrayForAllPoints(l,u,p,v,M);const C=new h(a.HEAPF32.buffer,M,v/h.BYTES_PER_ELEMENT);let T;if(g===x)T=C.slice();else{T=new h(b/h.BYTES_PER_ELEMENT);let D=0;for(let U=0,S=C.length;U<S;U++){for(let w=0;w<d;w++)T[D+w]=C[U*d+w];D+=m}}return a._free(M),{name:c,count:f,itemSize:d,array:T,stride:m}}function r(a,o){switch(o){case Float32Array:return a.DT_FLOAT32;case Int8Array:return a.DT_INT8;case Int16Array:return a.DT_INT16;case Int32Array:return a.DT_INT32;case Uint8Array:return a.DT_UINT8;case Uint16Array:return a.DT_UINT16;case Uint32Array:return a.DT_UINT32}}}var vr=(s=>(s.ModelLoadStart="model-load-start",s.ModelLoadProgress="model-load-progress",s.ModelLoaded="model-loaded",s.ModelError="model-error",s.SelectionChanged="selection-changed",s.HoverChanged="hover-changed",s.Click="click",s.MouseMove="mouse-move",s.CameraChanged="camera-changed",s.CameraIdle="camera-idle",s.EngineFree="engine-free",s.EngineBusy="engine-busy",s))(vr||{});function k_(s,e,t,n){let i=0,r=0,a=0,o=s.models.find(d=>d.url==t),l=e.circularMeps,c=e.rectMeps.filter(d=>d.type==="风管"),h=e.rectMeps.filter(d=>d.type==="桥架"),u=e.ellipseMeps,f=s.scene;if(new Nt,new vt,Ba(f,"InstancedMesh"),l&&l.length){let d=[];for(let p of l)p.color=new
2026-01-22 11:29:51 +08:00
< div style = "width:24px;height:24px;background:#9ca3af;margin-right:8px;border:1px solid #6b7280;border-radius:2px;" > < / d i v >
< span > Concrete - Cast - in - Place Gray < / s p a n >
2026-01-22 15:23:57 +08:00
` ;const n=document.createElement("div");return new Mc({container:n,items:[{label:"Preview",value:t},{label:"Class",value:"Concrete"},{label:"Density",value:"2400 kg/m³"},{label:"Thermal",value:"0.6 W/(m·K)"}]}),e.appendChild(n),e}isOpen(){return this.dialog!==null}hide(){this.dialog&&(this.dialog.destroy(),this.dialog=null)}destroy(){this.hide(),super.destroy()}}const M2={distance:'<svg viewBox="0 0 32 32" aria-hidden="true"><g transform="translate(0 4.197)"><path fill="currentColor" d="M29.692,3.03,27.55.919a.529.529,0,0,1-.014-.756A.549.549,0,0,1,28.3.15l.014.013,3.067,3.023a.529.529,0,0,1,0,.756L28.317,6.966a.549.549,0,0,1-.767.013.529.529,0,0,1-.014-.756l.014-.013L29.692,4.1H2.31L4.452,6.21a.528.528,0,0,1,.013.756.547.547,0,0,1-.766.013l-.014-.013L.616,3.942a.531.531,0,0,1,0-.756L3.685.163a.548.548,0,0,1,.767.014.528.528,0,0,1,0,.742L2.31,3.03ZM24.136,15.055H23.051V18H21.966v-2.94H20.882V18H19.8v-2.94H18.712V18H17.627v-2.94H16.543v5.078H15.458V15.055H14.373V18H13.288v-2.94H12.2V18H11.119v-2.94H10.034V18H8.949v-2.94H7.865V18H6.78v-2.94H5.7v5.078H4.61V15.055H1.9a.27.27,0,0,0-.272.268v6.413A.269.269,0,0,0,1.9,22H30.1a.268.268,0,0,0,.271-.267V15.323a.269.269,0,0,0-.271-.268H27.39v5.078H26.305V15.055H25.221V18H24.136Zm5.966-1.6A1.884,1.884,0,0,1,32,15.323v6.413a1.885,1.885,0,0,1-1.9,1.871H1.9A1.885,1.885,0,0,1,0,21.736V15.323a1.885,1.885,0,0,1,1.9-1.871Z"/></g></svg>',minDistance:'<svg viewBox="0 0 32 32" aria-hidden="true"><path fill="currentColor" d="M-5.839,24.8H-34.16A1.875,1.875,0,0,1-36,22.933V16.52a1.887,1.887,0,0,1,1.9-1.871H-5.9A1.887,1.887,0,0,1-4,16.52v6.412A1.875,1.875,0,0,1-5.839,24.8ZM-34.1,16.252a.27.27,0,0,0-.272.268v6.412a.27.27,0,0,0,.272.267H-5.9a.269.269,0,0,0,.271-.267V16.52a.27.27,0,0,0-.271-.268H-8.61V21.33H-9.695V16.252h-1.085v2.939h-1.085V16.252h-1.085v2.939h-1.085V16.252h-1.084v2.939H-16.2V16.252h-1.085v2.939h-1.085V16.252h-1.084V21.33h-1.084V16.252h-1.085v2.939h-1.085V16.252H-23.8v2.939h-1.085V16.252h-1.085v2.939h-1.085V16.252h-1.084v2.939H-29.22V16.252H-30.3V21.33H-31.39V16.252Z" transform="translate(36 2)"/><path fill="currentColor" d="M23.716,7.947V4.875c0-.8-.232-1.085-.765-1.085a1.573,1.573,0,0,0-1.133.585V7.947H20.4V2.75h1.163l.1.687H21.7a2.547,2.547,0,0,1,1.763-.817c1.172,0,1.676.78,1.676,2.089V7.947Zm-7.26,0V2.62h1.58V7.947Zm-3.8,0V4.875c0-.8-.243-1.085-.76-1.085a1.606,1.606,0,0,0-1.049.585V7.947H9.421V4.875c0-.8-.243-1.085-.758-1.085a1.608,1.608,0,0,0-1.05.585V7.947H6.194V2.75H7.36l.1.7H7.5A2.326,2.326,0,0,1,9.169,2.62a1.486,1.486,0,0,1,1.5.91A2.445,2.445,0,0,1,12.4,2.62c1.156,0,1.691.78,1.691,2.089V7.947Zm3.8-6.849a.79.79,0,0,1,1.58,0,.79.79,0,0,1-1.58,0Z" transform="translate(0.333 3.053)"/></svg>',angle:'<svg viewBox="0 0 32 32" aria-hidden="true"><path fill="currentColor" d="M39.587,50.766h13.7a1,1,0,0,1,0,2H23.171a1,1,0,0,1,0-2h1.418l6.582-7.006v-.006a.517.517,0,0,1,.14-.357.456.456,0,0,1,.337-.144l12.1-12.876a.451.451,0,0,1,.665,0,.524.524,0,0,1,0,.708L32.883,43.355a8.3,8.3,0,0,1,6.7,7.411Zm-.949,0a7.254,7.254,0,0,0-6.611-6.5l-6.108,6.5Z" transform="translate(-22.229 -26.489)"/></svg>',elevation:'<svg viewBox="0 0 32 32" aria-hidden="true"><path fill="currentColor" d="M84.131,193.119a1.056,1.056,0,0,1,1.116.982v7.857a1.056,1.056,0,0,1-1.116.982H54.367a1.056,1.056,0,0,1-1.116-.982V194.1a1.056,1.056,0,0,1,1.116-.982Zm-1.116,1.964H55.483v5.893H83.015Zm1.116-13.749a1.064,1.064,0,0,1,1.114.935,1.032,1.032,0,0,1-1.007,1.025l-.107,0H71.2l-7.858,6.914a1.227,1.227,0,0,1-1.578,0l-8.185-7.2-.018-.016-.032-.031.049.047a1.107,1.107,0,0,1-.092-.092l-.011-.014a.869.869,0,0,1-.182-.857l0-.008L53.31,182l.012-.029.02-.045.019-.035a1.1,1.1,0,0,1,.891-.552h.007q.053,0,.107,0ZM68.043,183.3H57.06l5.492,4.831Z" transform="translate(-53.247 -176.136)"/></svg>',volume:'<svg viewBox="0 0 32 32" aria-hidden="true"><path fill="currentColor" d="M94.74,86.658V71.189a.371.371,0,0,1,.2-.329l13.869-7.22a.371.371,0,0,1,.344,0l13.053,6.891h0l.819.431a.371.371,0,0,1,.2.328v15.3a.371.371,0,0,1-.2.328l-13.872,7.255a.371.371,0,0,1-.342,0L94.94,86.987a.371.371,0,0,1-.2-.329Zm2.119-.837,11.2,5.8a.024.024,0,0,0
2026-01-22 11:29:51 +08:00
< svg viewBox = "0 0 24 24" aria - hidden = "true" >
< circle cx = "12" cy = "12" r = "9" > < / c i r c l e >
< / s v g >
2026-01-22 15:23:57 +08:00
` ;for(let g=0;g<i.length;g++){const x=i[g],m=document.createElement("button");m.type="button",m.className="bim-measure-tool-btn",m.dataset.mode=x;const v=document.createElement("span");v.className="bim-measure-tool-icon",v.innerHTML=M2[x]||r,m.appendChild(v),m.addEventListener("click",()=>{this.setActiveMode(x)}),this.toolButtons.set(x,m),n.appendChild(m)}t.appendChild(n);const a=document.createElement("div");a.className="bim-measure-toggle",this.toggleBtn=document.createElement("button"),this.toggleBtn.type="button",this.toggleBtn.className="bim-measure-toggle-btn",this.toggleTextEl=document.createElement("span"),this.toggleTextEl.className="bim-measure-toggle-text";const o=document.createElement("span");o.className="bim-measure-toggle-icon",o.innerHTML= `
2026-01-22 11:29:51 +08:00
< svg viewBox = "0 0 24 24" aria - hidden = "true" >
< path d = "M7 10l5 5 5-5z" > < / p a t h >
< / s v g >
` ,this.toggleBtn.appendChild(this.toggleTextEl),this.toggleBtn.appendChild(o),this.toggleBtn.addEventListener("click",()=>{this.isExpanded=!this.isExpanded,this.applyExpandedState(),this.setLocales(),this.options.onExpandedChange&&this.options.onExpandedChange(this.isExpanded)}),a.appendChild(this.toggleBtn),t.appendChild(a),this.mainViewEl.appendChild(t);const l=document.createElement("div");l.className="bim-measure-result";const c=document.createElement("div");c.className="bim-measure-row";const h=document.createElement("span");h.className="label",this.mainValueLabelEl=h;const u=document.createElement("span");u.className="value",this.mainValueValueEl=u,this.mainNumberEl=document.createElement("span"),this.mainNumberEl.className="bim-measure-main-number",this.mainUnitEl=document.createElement("span"),this.mainUnitEl.className="bim-measure-main-unit",this.mainValueValueEl.appendChild(this.mainNumberEl),this.mainValueValueEl.appendChild(document.createTextNode(" ")),this.mainValueValueEl.appendChild(this.mainUnitEl),c.appendChild(h),c.appendChild(u),l.appendChild(c);const f=document.createElement("div");f.className="bim-measure-xyz",this.xyzBoxEl=f;const d=(g,x,m)=>{const v=document.createElement("div");v.className="bim-measure-row";const b=document.createElement("span");b.className="label",b.dataset.i18nKey=g;const M=document.createElement("span");return M.className= ` value $ { x } ` ,m(M),v.appendChild(b),v.appendChild(M),v};f.appendChild(d("measure.labels.x","bim-measure-xyz-x",g=>this.xyzXEl=g)),f.appendChild(d("measure.labels.y","bim-measure-xyz-y",g=>this.xyzYEl=g)),f.appendChild(d("measure.labels.z","bim-measure-xyz-z",g=>this.xyzZEl=g)),l.appendChild(f),this.mainViewEl.appendChild(l);const p=document.createElement("div");return p.className="bim-measure-footer",this.clearBtn=document.createElement("button"),this.clearBtn.type="button",this.clearBtn.className="bim-measure-clear-btn",this.clearBtn.addEventListener("click",()=>{this.clearAll()}),this.settingsBtn=document.createElement("button"),this.settingsBtn.type="button",this.settingsBtn.className="bim-measure-settings-btn",this.settingsBtn.innerHTML= `
< svg viewBox = "0 0 24 24" aria - hidden = "true" >
< path d = "M19.14 12.94c.04-.31.06-.63.06-.94s-.02-.63-.06-.94l2.03-1.58a.5.5 0 0 0 .12-.64l-1.92-3.32a.5.5 0 0 0-.6-.22l-2.39.96a7.27 7.27 0 0 0-1.63-.94l-.36-2.54A.5.5 0 0 0 13.9 1h-3.8a.5.5 0 0 0-.49.42l-.36 2.54c-.58.23-1.12.54-1.63.94l-2.39-.96a.5.5 0 0 0-.6.22L2.71 7.48a.5.5 0 0 0 .12.64l2.03 1.58c-.04.31-.06.63-.06.94s.02.63.06.94L2.83 14.52a.5.5 0 0 0-.12.64l1.92 3.32c.13.22.39.3.6.22l2.39-.96c.5.4 1.05.71 1.63.94l.36 2.54c.04.24.25.42.49.42h3.8c.24 0 .45-.18.49-.42l.36-2.54c.58-.23 1.12-.54 1.63-.94l2.39.96c.22.09.47 0 .6-.22l1.92-3.32a.5.5 0 0 0-.12-.64l-2.03-1.58zM12 15.5A3.5 3.5 0 1 1 12 8a3.5 3.5 0 0 1 0 7.5z" > < / p a t h >
< / s v g >
2026-01-22 15:23:57 +08:00
` ,this.settingsBtn.addEventListener("click",()=>{this.openSettings()}),p.appendChild(this.clearBtn),p.appendChild(this.settingsBtn),this.mainViewEl.appendChild(p),this.settingsViewEl=this.createSettingsDom(),e.appendChild(this.mainViewEl),e.appendChild(this.settingsViewEl),e}createSettingsDom(){const e=document.createElement("div");e.className="bim-measure-settings";const t=document.createElement("div");t.className="bim-measure-settings-title",t.dataset.i18nKey="measure.settings.title",e.appendChild(t);const n=document.createElement("div");n.className="bim-measure-settings-row";const i=document.createElement("div");i.className="label",i.dataset.i18nKey="measure.settings.unit",this.unitSelectEl=document.createElement("select"),this.unitSelectEl.className="bim-measure-settings-select",this.unitSelectEl.appendChild(this.makeOption("m")),this.unitSelectEl.appendChild(this.makeOption("cm")),this.unitSelectEl.appendChild(this.makeOption("mm")),this.unitSelectEl.appendChild(this.makeOption("km")),n.appendChild(i),n.appendChild(this.unitSelectEl),e.appendChild(n);const r=document.createElement("div");r.className="bim-measure-settings-hint",r.dataset.i18nKey="measure.settings.hint",e.appendChild(r);const a=document.createElement("div");a.className="bim-measure-settings-row";const o=document.createElement("div");o.className="label",o.dataset.i18nKey="measure.settings.precision",this.precisionSelectEl=document.createElement("select"),this.precisionSelectEl.className="bim-measure-settings-select",this.precisionSelectEl.appendChild(this.makePrecisionOption(0)),this.precisionSelectEl.appendChild(this.makePrecisionOption(1)),this.precisionSelectEl.appendChild(this.makePrecisionOption(2)),this.precisionSelectEl.appendChild(this.makePrecisionOption(3)),a.appendChild(o),a.appendChild(this.precisionSelectEl),e.appendChild(a);const l=document.createElement("div");return l.className="bim-measure-settings-actions",this.saveSettingsBtn=document.createElement("button"),this.saveSettingsBtn.type="button",this.saveSettingsBtn.className="bim-measure-settings-save",this.saveSettingsBtn.addEventListener("click",()=>{this.saveSettings()}),this.cancelSettingsBtn=document.createElement("button"),this.cancelSettingsBtn.type="button",this.cancelSettingsBtn.className="bim-measure-settings-cancel",this.cancelSettingsBtn.addEventListener("click",()=>{this.cancelSettings()}),l.appendChild(this.saveSettingsBtn),l.appendChild(this.cancelSettingsBtn),e.appendChild(l),this.syncSettingsFormFromConfig(this.config),e}makeOption(e){const t=document.createElement("option");return t.value=e,t.textContent=e,t}makePrecisionOption(e){const t=document.createElement("option");return t.value=String(e),t.textContent=e===0?"0": ` 0. $ { "0" . repeat ( e ) } ` ,t}enterSettingsView(){this.draftConfig={...this.config},this.view="settings",this.syncSettingsFormFromConfig(this.config),this.applyViewState()}saveSettings(){const e=this.unitSelectEl.value||this.config.unit,t=Number(this.precisionSelectEl.value),n={unit:e,precision:this.isValidPrecision(t)?t:this.config.precision};this.config=n,this.saveConfigToCache(n),this.draftConfig=null,this.view="main",this.applyViewState(),this.renderResult(),this.options.onExpandedChange&&this.options.onExpandedChange(this.isExpanded)}cancelSettings(){this.draftConfig&&(this.config={...this.draftConfig}),this.draftConfig=null,this.view="main",this.applyViewState(),this.renderResult(),this.options.onExpandedChange&&this.options.onExpandedChange(this.isExpanded)}syncSettingsFormFromConfig(e){this.unitSelectEl.value=e.unit,this.precisionSelectEl.value=String(e.precision)}applyViewState(){this.view==="settings"?(this.mainViewEl.style.display="none",this.settingsViewEl.style.display="block"):(this.mainViewEl.style.display="block",this.settingsViewEl.style.display="none")}loadConfigFromCache(){try{const e=localStorage.getItem(yr.CONFIG_CACHE_KEY);if(!e)return null;const t=JSON.parse(e);if(!t||typeof t!="object")return null;const n=t.unit,i=t.precision;return!this.isValidUnit(n)||!this.isValidPrecision(i)?null:{unit:n,precision:i}}catch{return null}}saveConf
2026-01-22 11:29:51 +08:00
//# sourceMappingURL=iflow-engine.umd.js.map