diff --git a/docs/assets/index-BZLAT-kz.js b/docs/assets/index-BZLAT-kz.js new file mode 100644 index 0000000..2b135d5 --- /dev/null +++ b/docs/assets/index-BZLAT-kz.js @@ -0,0 +1,2288 @@ +var im=Object.defineProperty;var om=(He,st,nt)=>st in He?im(He,st,{enumerable:!0,configurable:!0,writable:!0,value:nt}):He[st]=nt;var ee=(He,st,nt)=>om(He,typeof st!="symbol"?st+"":st,nt);(async()=>{var sl,nl;function He(s,e){var t=s.__state.conversionName.toString(),r=Math.round(s.r),n=Math.round(s.g),i=Math.round(s.b),o=s.a,u=Math.round(s.h),l=s.s.toFixed(1),m=s.v.toFixed(1);if(e||t==="THREE_CHAR_HEX"||t==="SIX_CHAR_HEX"){for(var y=s.hex.toString(16);y.length<6;)y="0"+y;return"#"+y}return t==="CSS_RGB"?"rgb("+r+","+n+","+i+")":t==="CSS_RGBA"?"rgba("+r+","+n+","+i+","+o+")":t==="HEX"?"0x"+s.hex.toString(16):t==="RGB_ARRAY"?"["+r+","+n+","+i+"]":t==="RGBA_ARRAY"?"["+r+","+n+","+i+","+o+"]":t==="RGB_OBJ"?"{r:"+r+",g:"+n+",b:"+i+"}":t==="RGBA_OBJ"?"{r:"+r+",g:"+n+",b:"+i+",a:"+o+"}":t==="HSV_OBJ"?"{h:"+u+",s:"+l+",v:"+m+"}":t==="HSVA_OBJ"?"{h:"+u+",s:"+l+",v:"+m+",a:"+o+"}":"unknown format"}(function(){const s=document.createElement("link").relList;if(!(s&&s.supports&&s.supports("modulepreload"))){for(const t of document.querySelectorAll('link[rel="modulepreload"]'))e(t);new MutationObserver(t=>{for(const r of t)if(r.type==="childList")for(const n of r.addedNodes)n.tagName==="LINK"&&n.rel==="modulepreload"&&e(n)}).observe(document,{childList:!0,subtree:!0})}function e(t){if(t.ep)return;t.ep=!0;const r=function(n){const i={};return n.integrity&&(i.integrity=n.integrity),n.referrerPolicy&&(i.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?i.credentials="include":n.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}(t);fetch(t.href,r)}})();var st=Array.prototype.forEach,nt=Array.prototype.slice,N={BREAK:{},extend:function(s){return this.each(nt.call(arguments,1),function(e){(this.isObject(e)?Object.keys(e):[]).forEach((function(t){this.isUndefined(e[t])||(s[t]=e[t])}).bind(this))},this),s},defaults:function(s){return this.each(nt.call(arguments,1),function(e){(this.isObject(e)?Object.keys(e):[]).forEach((function(t){this.isUndefined(s[t])&&(s[t]=e[t])}).bind(this))},this),s},compose:function(){var s=nt.call(arguments);return function(){for(var e=nt.call(arguments),t=s.length-1;t>=0;t--)e=[s[t].apply(this,e)];return e[0]}},each:function(s,e,t){if(s){if(st&&s.forEach&&s.forEach===st)s.forEach(e,t);else if(s.length===s.length+0){var r,n=void 0;for(n=0,r=s.length;n1?N.toArray(arguments):arguments[0];return N.each(cl,function(e){if(e.litmus(s))return N.each(e.conversions,function(t,r){if(vr=t.read(s),es===!1&&vr!==!1)return es=vr,vr.conversionName=r,vr.conversion=t,N.BREAK}),N.BREAK}),es},Ao=void 0,ts={hsv_to_rgb:function(s,e,t){var r=Math.floor(s/60)%6,n=s/60-Math.floor(s/60),i=t*(1-e),o=t*(1-n*e),u=t*(1-(1-n)*e),l=[[t,u,i],[o,t,i],[i,t,u],[i,o,t],[u,i,t],[t,i,o]][r];return{r:255*l[0],g:255*l[1],b:255*l[2]}},rgb_to_hsv:function(s,e,t){var r=Math.min(s,e,t),n=Math.max(s,e,t),i=n-r,o=void 0;return n===0?{h:NaN,s:0,v:0}:(o=s===n?(e-t)/i:e===n?2+(t-s)/i:4+(s-e)/i,(o/=6)<0&&(o+=1),{h:360*o,s:i/n,v:n/255})},rgb_to_hex:function(s,e,t){var r=this.hex_with_component(0,2,s);return r=this.hex_with_component(r,1,e),r=this.hex_with_component(r,0,t)},component_from_hex:function(s,e){return s>>8*e&255},hex_with_component:function(s,e,t){return t<<(Ao=8*e)|s&~(255<-1?e.length-e.indexOf(".")-1:0}var To=function(){function s(e,t,r){$e(this,s);var n=At(this,(s.__proto__||Object.getPrototypeOf(s)).call(this,e,t)),i=r||{};return n.__min=i.min,n.__max=i.max,n.__step=i.step,N.isUndefined(n.__step)?n.initialValue===0?n.__impliedStep=1:n.__impliedStep=Math.pow(10,Math.floor(Math.log(Math.abs(n.initialValue))/Math.LN10))/10:n.__impliedStep=n.__step,n.__precision=Co(n.__impliedStep),n}return Bt(s,Ot),Xe(s,[{key:"setValue",value:function(e){var t=e;return this.__min!==void 0&&tthis.__max&&(t=this.__max),this.__step!==void 0&&t%this.__step!=0&&(t=Math.round(t/this.__step)*this.__step),_t(s.prototype.__proto__||Object.getPrototypeOf(s.prototype),"setValue",this).call(this,t)}},{key:"min",value:function(e){return this.__min=e,this}},{key:"max",value:function(e){return this.__max=e,this}},{key:"step",value:function(e){return this.__step=e,this.__impliedStep=e,this.__precision=Co(e),this}}]),s}(),rs=function(){function s(e,t,r){$e(this,s);var n=At(this,(s.__proto__||Object.getPrototypeOf(s)).call(this,e,t,r));n.__truncationSuspended=!1;var i=n,o=void 0;function u(){i.__onFinishChange&&i.__onFinishChange.call(i,i.getValue())}function l(y){var d=o-y.clientY;i.setValue(i.getValue()+d*i.__impliedStep),o=y.clientY}function m(){I.unbind(window,"mousemove",l),I.unbind(window,"mouseup",m),u()}return n.__input=document.createElement("input"),n.__input.setAttribute("type","text"),I.bind(n.__input,"change",function(){var y=parseFloat(i.__input.value);N.isNaN(y)||i.setValue(y)}),I.bind(n.__input,"blur",function(){u()}),I.bind(n.__input,"mousedown",function(y){I.bind(window,"mousemove",l),I.bind(window,"mouseup",m),o=y.clientY}),I.bind(n.__input,"keydown",function(y){y.keyCode===13&&(i.__truncationSuspended=!0,this.blur(),i.__truncationSuspended=!1,u())}),n.updateDisplay(),n.domElement.appendChild(n.__input),n}return Bt(s,To),Xe(s,[{key:"updateDisplay",value:function(){var e,t,r;return this.__input.value=this.__truncationSuspended?this.getValue():(e=this.getValue(),t=this.__precision,r=Math.pow(10,t),Math.round(e*r)/r),_t(s.prototype.__proto__||Object.getPrototypeOf(s.prototype),"updateDisplay",this).call(this)}}]),s}();function So(s,e,t,r,n){return r+(s-e)/(t-e)*(n-r)}var En=function(){function s(e,t,r,n,i){$e(this,s);var o=At(this,(s.__proto__||Object.getPrototypeOf(s)).call(this,e,t,{min:r,max:n,step:i})),u=o;function l(x){x.preventDefault();var b=u.__background.getBoundingClientRect();return u.setValue(So(x.clientX,b.left,b.right,u.__min,u.__max)),!1}function m(){I.unbind(window,"mousemove",l),I.unbind(window,"mouseup",m),u.__onFinishChange&&u.__onFinishChange.call(u,u.getValue())}function y(x){var b=x.touches[0].clientX,_=u.__background.getBoundingClientRect();u.setValue(So(b,_.left,_.right,u.__min,u.__max))}function d(){I.unbind(window,"touchmove",y),I.unbind(window,"touchend",d),u.__onFinishChange&&u.__onFinishChange.call(u,u.getValue())}return o.__background=document.createElement("div"),o.__foreground=document.createElement("div"),I.bind(o.__background,"mousedown",function(x){document.activeElement.blur(),I.bind(window,"mousemove",l),I.bind(window,"mouseup",m),l(x)}),I.bind(o.__background,"touchstart",function(x){x.touches.length===1&&(I.bind(window,"touchmove",y),I.bind(window,"touchend",d),y(x))}),I.addClass(o.__background,"slider"),I.addClass(o.__foreground,"slider-fg"),o.updateDisplay(),o.__background.appendChild(o.__foreground),o.domElement.appendChild(o.__background),o}return Bt(s,To),Xe(s,[{key:"updateDisplay",value:function(){var e=(this.getValue()-this.__min)/(this.__max-this.__min);return this.__foreground.style.width=100*e+"%",_t(s.prototype.__proto__||Object.getPrototypeOf(s.prototype),"updateDisplay",this).call(this)}}]),s}(),Eo=function(){function s(e,t,r){$e(this,s);var n=At(this,(s.__proto__||Object.getPrototypeOf(s)).call(this,e,t)),i=n;return n.__button=document.createElement("div"),n.__button.innerHTML=r===void 0?"Fire":r,I.bind(n.__button,"click",function(o){return o.preventDefault(),i.fire(),!1}),I.addClass(n.__button,"button"),n.domElement.appendChild(n.__button),n}return Bt(s,Ot),Xe(s,[{key:"fire",value:function(){this.__onChange&&this.__onChange.call(this),this.getValue().call(this.object),this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}}]),s}(),Mn=function(){function s(e,t){$e(this,s);var r=At(this,(s.__proto__||Object.getPrototypeOf(s)).call(this,e,t));r.__color=new be(r.getValue()),r.__temp=new be(0);var n=r;r.domElement=document.createElement("div"),I.makeSelectable(r.domElement,!1),r.__selector=document.createElement("div"),r.__selector.className="selector",r.__saturation_field=document.createElement("div"),r.__saturation_field.className="saturation-field",r.__field_knob=document.createElement("div"),r.__field_knob.className="field-knob",r.__field_knob_border="2px solid ",r.__hue_knob=document.createElement("div"),r.__hue_knob.className="hue-knob",r.__hue_field=document.createElement("div"),r.__hue_field.className="hue-field",r.__input=document.createElement("input"),r.__input.type="text",r.__input_textShadow="0 1px 1px ",I.bind(r.__input,"keydown",function(C){C.keyCode===13&&d.call(this)}),I.bind(r.__input,"blur",d),I.bind(r.__selector,"mousedown",function(){I.addClass(this,"drag").bind(window,"mouseup",function(){I.removeClass(n.__selector,"drag")})}),I.bind(r.__selector,"touchstart",function(){I.addClass(this,"drag").bind(window,"touchend",function(){I.removeClass(n.__selector,"drag")})});var i,o=document.createElement("div");function u(C){b(C),I.bind(window,"mousemove",b),I.bind(window,"touchmove",b),I.bind(window,"mouseup",m),I.bind(window,"touchend",m)}function l(C){_(C),I.bind(window,"mousemove",_),I.bind(window,"touchmove",_),I.bind(window,"mouseup",y),I.bind(window,"touchend",y)}function m(){I.unbind(window,"mousemove",b),I.unbind(window,"touchmove",b),I.unbind(window,"mouseup",m),I.unbind(window,"touchend",m),x()}function y(){I.unbind(window,"mousemove",_),I.unbind(window,"touchmove",_),I.unbind(window,"mouseup",y),I.unbind(window,"touchend",y),x()}function d(){var C=Cn(this.value);C!==!1?(n.__color.__state=C,n.setValue(n.__color.toOriginal())):this.value=n.__color.toString()}function x(){n.__onFinishChange&&n.__onFinishChange.call(n,n.__color.toOriginal())}function b(C){C.type.indexOf("touch")===-1&&C.preventDefault();var f=n.__saturation_field.getBoundingClientRect(),p=C.touches&&C.touches[0]||C,a=p.clientX,c=p.clientY,h=(a-f.left)/(f.right-f.left),g=1-(c-f.top)/(f.bottom-f.top);return g>1?g=1:g<0&&(g=0),h>1?h=1:h<0&&(h=0),n.__color.v=g,n.__color.s=h,n.setValue(n.__color.toOriginal()),!1}function _(C){C.type.indexOf("touch")===-1&&C.preventDefault();var f=n.__hue_field.getBoundingClientRect(),p=1-((C.touches&&C.touches[0]||C).clientY-f.top)/(f.bottom-f.top);return p>1?p=1:p<0&&(p=0),n.__color.h=360*p,n.setValue(n.__color.toOriginal()),!1}return N.extend(r.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"}),N.extend(r.__field_knob.style,{position:"absolute",width:"12px",height:"12px",border:r.__field_knob_border+(r.__color.v<.5?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1}),N.extend(r.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1}),N.extend(r.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"}),N.extend(o.style,{width:"100%",height:"100%",background:"none"}),Mo(o,"top","rgba(0,0,0,0)","#000"),N.extend(r.__hue_field.style,{width:"15px",height:"100px",border:"1px solid #555",cursor:"ns-resize",position:"absolute",top:"3px",right:"3px"}),(i=r.__hue_field).style.background="",i.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);",i.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",i.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",i.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",i.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",N.extend(r.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:r.__input_textShadow+"rgba(0,0,0,0.7)"}),I.bind(r.__saturation_field,"mousedown",u),I.bind(r.__saturation_field,"touchstart",u),I.bind(r.__field_knob,"mousedown",u),I.bind(r.__field_knob,"touchstart",u),I.bind(r.__hue_field,"mousedown",l),I.bind(r.__hue_field,"touchstart",l),r.__saturation_field.appendChild(o),r.__selector.appendChild(r.__field_knob),r.__selector.appendChild(r.__saturation_field),r.__selector.appendChild(r.__hue_field),r.__hue_field.appendChild(r.__hue_knob),r.domElement.appendChild(r.__input),r.domElement.appendChild(r.__selector),r.updateDisplay(),r}return Bt(s,Ot),Xe(s,[{key:"updateDisplay",value:function(){var e=Cn(this.getValue());if(e!==!1){var t=!1;N.each(be.COMPONENTS,function(i){if(!N.isUndefined(e[i])&&!N.isUndefined(this.__color.__state[i])&&e[i]!==this.__color.__state[i])return t=!0,{}},this),t&&N.extend(this.__color.__state,e)}N.extend(this.__temp.__state,this.__color.__state),this.__temp.a=1;var r=this.__color.v<.5||this.__color.s>.5?255:0,n=255-r;N.extend(this.__field_knob.style,{marginLeft:100*this.__color.s-7+"px",marginTop:100*(1-this.__color.v)-7+"px",backgroundColor:this.__temp.toHexString(),border:this.__field_knob_border+"rgb("+r+","+r+","+r+")"}),this.__hue_knob.style.marginTop=100*(1-this.__color.h/360)+"px",this.__temp.s=1,this.__temp.v=1,Mo(this.__saturation_field,"left","#fff",this.__temp.toHexString()),this.__input.value=this.__color.toString(),N.extend(this.__input.style,{backgroundColor:this.__color.toHexString(),color:"rgb("+r+","+r+","+r+")",textShadow:this.__input_textShadow+"rgba("+n+","+n+","+n+",.7)"})}}]),s}(),pl=["-moz-","-o-","-webkit-","-ms-",""];function Mo(s,e,t,r){s.style.background="",N.each(pl,function(n){s.style.cssText+="background: "+n+"linear-gradient("+e+", "+t+" 0%, "+r+" 100%); "})}var ml=function(s,e){var t=e||document,r=document.createElement("style");r.type="text/css",r.innerHTML=s;var n=t.getElementsByTagName("head")[0];try{n.appendChild(r)}catch{}},gl=function(s,e){var t=s[e];return N.isArray(arguments[2])||N.isObject(arguments[2])?new hl(s,e,arguments[2]):N.isNumber(t)?N.isNumber(arguments[2])&&N.isNumber(arguments[3])?N.isNumber(arguments[4])?new En(s,e,arguments[2],arguments[3],arguments[4]):new En(s,e,arguments[2],arguments[3]):N.isNumber(arguments[4])?new rs(s,e,{min:arguments[2],max:arguments[3],step:arguments[4]}):new rs(s,e,{min:arguments[2],max:arguments[3]}):N.isString(t)?new fl(s,e):N.isFunction(t)?new Eo(s,e,""):N.isBoolean(t)?new wo(s,e):null},yl=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(s){setTimeout(s,1e3/60)},bl=function(){function s(){$e(this,s),this.backgroundElement=document.createElement("div"),N.extend(this.backgroundElement.style,{backgroundColor:"rgba(0,0,0,0.8)",top:0,left:0,display:"none",zIndex:"1000",opacity:0,WebkitTransition:"opacity 0.2s linear",transition:"opacity 0.2s linear"}),I.makeFullscreen(this.backgroundElement),this.backgroundElement.style.position="fixed",this.domElement=document.createElement("div"),N.extend(this.domElement.style,{position:"fixed",display:"none",zIndex:"1001",opacity:0,WebkitTransition:"-webkit-transform 0.2s ease-out, opacity 0.2s linear",transition:"transform 0.2s ease-out, opacity 0.2s linear"}),document.body.appendChild(this.backgroundElement),document.body.appendChild(this.domElement);var e=this;I.bind(this.backgroundElement,"click",function(){e.hide()})}return Xe(s,[{key:"show",value:function(){var e=this;this.backgroundElement.style.display="block",this.domElement.style.display="block",this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)",this.layout(),N.defer(function(){e.backgroundElement.style.opacity=1,e.domElement.style.opacity=1,e.domElement.style.webkitTransform="scale(1)"})}},{key:"hide",value:function(){var e=this,t=function r(){e.domElement.style.display="none",e.backgroundElement.style.display="none",I.unbind(e.domElement,"webkitTransitionEnd",r),I.unbind(e.domElement,"transitionend",r),I.unbind(e.domElement,"oTransitionEnd",r)};I.bind(this.domElement,"webkitTransitionEnd",t),I.bind(this.domElement,"transitionend",t),I.bind(this.domElement,"oTransitionEnd",t),this.backgroundElement.style.opacity=0,this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)"}},{key:"layout",value:function(){this.domElement.style.left=window.innerWidth/2-I.getWidth(this.domElement)/2+"px",this.domElement.style.top=window.innerHeight/2-I.getHeight(this.domElement)/2+"px"}}]),s}(),xl=function(s){if(typeof window<"u"){var e=document.createElement("style");return e.setAttribute("type","text/css"),e.innerHTML=s,document.head.appendChild(e),s}}(`.dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li>*{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .cr.function .property-name{width:100%}.dg .c{float:left;width:60%;position:relative}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:7px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .cr.color{overflow:visible}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.color{border-left:3px solid}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2FA1D6}.dg .cr.number input[type=text]{color:#2FA1D6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2FA1D6;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda} +`);ml(xl);var wr="Default",Cr=function(){try{return!!window.localStorage}catch{return!1}}(),ss=void 0,Po=!0,Zt=void 0,Pn=!1,Ro=[],le=function s(e){var t=this,r=e||{};this.domElement=document.createElement("div"),this.__ul=document.createElement("ul"),this.domElement.appendChild(this.__ul),I.addClass(this.domElement,"dg"),this.__folders={},this.__controllers=[],this.__rememberedObjects=[],this.__rememberedObjectIndecesToControllers=[],this.__listening=[],r=N.defaults(r,{closeOnTop:!1,autoPlace:!0,width:s.DEFAULT_WIDTH}),r=N.defaults(r,{resizable:r.autoPlace,hideable:r.autoPlace}),N.isUndefined(r.load)?r.load={preset:wr}:r.preset&&(r.load.preset=r.preset),N.isUndefined(r.parent)&&r.hideable&&Ro.push(this),r.resizable=N.isUndefined(r.parent)&&r.resizable,r.autoPlace&&N.isUndefined(r.scrollable)&&(r.scrollable=!0);var n,i=Cr&&localStorage.getItem(er(this,"isLocal"))==="true",o=void 0,u=void 0;if(Object.defineProperties(this,{parent:{get:function(){return r.parent}},scrollable:{get:function(){return r.scrollable}},autoPlace:{get:function(){return r.autoPlace}},closeOnTop:{get:function(){return r.closeOnTop}},preset:{get:function(){return t.parent?t.getRoot().preset:r.load.preset},set:function(y){t.parent?t.getRoot().preset=y:r.load.preset=y,function(d){for(var x=0;x1){var C=d.__li.nextElementSibling;return d.remove(),Tr(m,d.object,d.property,{before:C,factoryArgs:[N.toArray(arguments)]})}if(N.isArray(_)||N.isObject(_)){var f=d.__li.nextElementSibling;return d.remove(),Tr(m,d.object,d.property,{before:f,factoryArgs:[_]})}},name:function(_){return d.__li.firstElementChild.firstElementChild.innerHTML=_,d},listen:function(){return d.__gui.listen(d),d},remove:function(){return d.__gui.remove(d),d}}),d instanceof En){var x=new rs(d.object,d.property,{min:d.__min,max:d.__max,step:d.__step});N.each(["updateDisplay","onChange","onFinishChange","step","min","max"],function(_){var C=d[_],f=x[_];d[_]=x[_]=function(){var p=Array.prototype.slice.call(arguments);return f.apply(x,p),C.apply(d,p)}}),I.addClass(y,"has-slider"),d.domElement.insertBefore(x.domElement,d.domElement.firstElementChild)}else if(d instanceof rs){var b=function(_){if(N.isNumber(d.__min)&&N.isNumber(d.__max)){var C=d.__li.firstElementChild.firstElementChild.innerHTML,f=d.__gui.__listening.indexOf(d)>-1;d.remove();var p=Tr(m,d.object,d.property,{before:d.__li.nextElementSibling,factoryArgs:[d.__min,d.__max,d.__step]});return p.name(C),f&&p.listen(),p}return _};d.min=N.compose(b,d.min),d.max=N.compose(b,d.max)}else d instanceof wo?(I.bind(y,"click",function(){I.fakeEvent(d.__checkbox,"click")}),I.bind(d.__checkbox,"click",function(_){_.stopPropagation()})):d instanceof Eo?(I.bind(y,"click",function(){I.fakeEvent(d.__button,"click")}),I.bind(y,"mouseover",function(){I.addClass(d.__button,"hover")}),I.bind(y,"mouseout",function(){I.removeClass(d.__button,"hover")})):d instanceof Mn&&(I.addClass(y,"color"),d.updateDisplay=N.compose(function(_){return y.style.borderLeftColor=d.__color.toString(),_},d.updateDisplay),d.updateDisplay());d.setValue=N.compose(function(_){return m.getRoot().__preset_select&&d.isModified()&&Gn(m.getRoot(),!0),_},d.setValue)}(s,l,n),s.__controllers.push(n),n}function er(s,e){return document.location.href+"."+e}function Ln(s,e,t){var r=document.createElement("option");r.innerHTML=e,r.value=e,s.__preset_select.appendChild(r),t&&(s.__preset_select.selectedIndex=s.__preset_select.length-1)}function Oo(s,e){e.style.display=s.useLocalStorage?"block":"none"}function _l(s){var e=void 0;function t(i){return i.preventDefault(),s.width+=e-i.clientX,s.onResize(),e=i.clientX,!1}function r(){I.removeClass(s.__closeButton,le.CLASS_DRAG),I.unbind(window,"mousemove",t),I.unbind(window,"mouseup",r)}function n(i){return i.preventDefault(),e=i.clientX,I.addClass(s.__closeButton,le.CLASS_DRAG),I.bind(window,"mousemove",t),I.bind(window,"mouseup",r),!1}s.__resize_handle=document.createElement("div"),N.extend(s.__resize_handle.style,{width:"6px",marginLeft:"-3px",height:"200px",cursor:"ew-resize",position:"absolute"}),I.bind(s.__resize_handle,"mousedown",n),I.bind(s.__closeButton,"mousedown",n),s.domElement.insertBefore(s.__resize_handle,s.domElement.firstElementChild)}function On(s,e){s.domElement.style.width=e+"px",s.__save_row&&s.autoPlace&&(s.__save_row.style.width=e+"px"),s.__closeButton&&(s.__closeButton.style.width=e+"px")}function ns(s,e){var t={};return N.each(s.__rememberedObjects,function(r,n){var i={},o=s.__rememberedObjectIndecesToControllers[n];N.each(o,function(u,l){i[l]=e?u.initialValue:u.getValue()}),t[n]=i}),t}function Io(s){s.length!==0&&yl.call(window,function(){Io(s)}),N.each(s,function(e){e.updateDisplay()})}le.toggleHide=function(){Pn=!Pn,N.each(Ro,function(s){s.domElement.style.display=Pn?"none":""})},le.CLASS_AUTO_PLACE="a",le.CLASS_AUTO_PLACE_CONTAINER="ac",le.CLASS_MAIN="main",le.CLASS_CONTROLLER_ROW="cr",le.CLASS_TOO_TALL="taller-than-window",le.CLASS_CLOSED="closed",le.CLASS_CLOSE_BUTTON="close-button",le.CLASS_CLOSE_TOP="close-top",le.CLASS_CLOSE_BOTTOM="close-bottom",le.CLASS_DRAG="drag",le.DEFAULT_WIDTH=245,le.TEXT_CLOSED="Close Controls",le.TEXT_OPEN="Open Controls",le._keydownHandler=function(s){document.activeElement.type==="text"||s.which!==72&&s.keyCode!==72||le.toggleHide()},I.bind(window,"keydown",le._keydownHandler,!1),N.extend(le.prototype,{add:function(s,e){return Tr(this,s,e,{factoryArgs:Array.prototype.slice.call(arguments,2)})},addColor:function(s,e){return Tr(this,s,e,{color:!0})},remove:function(s){this.__ul.removeChild(s.__li),this.__controllers.splice(this.__controllers.indexOf(s),1);var e=this;N.defer(function(){e.onResize()})},destroy:function(){if(this.parent)throw new Error("Only the root GUI should be removed with .destroy(). For subfolders, use gui.removeFolder(folder) instead.");this.autoPlace&&Zt.removeChild(this.domElement);var s=this;N.each(this.__folders,function(e){s.removeFolder(e)}),I.unbind(window,"keydown",le._keydownHandler,!1),Go(this)},addFolder:function(s){if(this.__folders[s]!==void 0)throw new Error('You already have a folder in this GUI by the name "'+s+'"');var e={name:s,parent:this};e.autoPlace=this.autoPlace,this.load&&this.load.folders&&this.load.folders[s]&&(e.closed=this.load.folders[s].closed,e.load=this.load.folders[s]);var t=new le(e);this.__folders[s]=t;var r=Rn(this,t.domElement);return I.addClass(r,"folder"),t},removeFolder:function(s){this.__ul.removeChild(s.domElement.parentElement),delete this.__folders[s.name],this.load&&this.load.folders&&this.load.folders[s.name]&&delete this.load.folders[s.name],Go(s);var e=this;N.each(s.__folders,function(t){s.removeFolder(t)}),N.defer(function(){e.onResize()})},open:function(){this.closed=!1},close:function(){this.closed=!0},hide:function(){this.domElement.style.display="none"},show:function(){this.domElement.style.display=""},onResize:function(){var s=this.getRoot();if(s.scrollable){var e=I.getOffset(s.__ul).top,t=0;N.each(s.__ul.childNodes,function(r){s.autoPlace&&r===s.__save_row||(t+=I.getHeight(r))}),window.innerHeight-e-20 + + Here's the new load parameter for your GUI's constructor: + + + +
+ + Automatically save + values to localStorage on exit. + +
The values saved to localStorage will + override those passed to dat.GUI's constructor. This makes it + easier to work incrementally, but localStorage is fragile, + and your friends may not see the same values you do. + +
+ +
+ +`),this.parent)throw new Error("You can only call remember on a top level GUI.");var s=this;N.each(Array.prototype.slice.call(arguments),function(e){s.__rememberedObjects.length===0&&function(t){var r=t.__save_row=document.createElement("li");I.addClass(t.domElement,"has-save"),t.__ul.insertBefore(r,t.__ul.firstChild),I.addClass(r,"save-row");var n=document.createElement("span");n.innerHTML=" ",I.addClass(n,"button gears");var i=document.createElement("span");i.innerHTML="Save",I.addClass(i,"button"),I.addClass(i,"save");var o=document.createElement("span");o.innerHTML="New",I.addClass(o,"button"),I.addClass(o,"save-as");var u=document.createElement("span");u.innerHTML="Revert",I.addClass(u,"button"),I.addClass(u,"revert");var l=t.__preset_select=document.createElement("select");if(t.load&&t.load.remembered?N.each(t.load.remembered,function(x,b){Ln(t,b,b===t.preset)}):Ln(t,wr,!1),I.bind(l,"change",function(){for(var x=0;x0&&(s.preset=this.preset,s.remembered||(s.remembered={}),s.remembered[this.preset]=ns(this)),s.folders={},N.each(this.__folders,function(e,t){s.folders[t]=e.getSaveObject()}),s},save:function(){this.load.remembered||(this.load.remembered={}),this.load.remembered[this.preset]=ns(this),Gn(this,!1),this.saveToLocalStorageIfPossible()},saveAs:function(s){this.load.remembered||(this.load.remembered={},this.load.remembered[wr]=ns(this,!0)),this.load.remembered[s]=ns(this),this.preset=s,Ln(this,s,!0),this.saveToLocalStorageIfPossible()},revert:function(s){N.each(this.__controllers,function(e){this.getRoot().load.remembered?Lo(s||this.getRoot(),e):e.setValue(e.initialValue),e.__onFinishChange&&e.__onFinishChange.call(e,e.getValue())},this),N.each(this.__folders,function(e){e.revert(e)}),s||Gn(this.getRoot(),!1)},listen:function(s){var e=this.__listening.length===0;this.__listening.push(s),e&&Io(this.__listening)},updateDisplay:function(){N.each(this.__controllers,function(s){s.updateDisplay()}),N.each(this.__folders,function(s){s.updateDisplay()})}});var Bl=le;const Al=(Do=Array,Fo=s=>s.fill(0),class extends Do{constructor(...s){super(...s),Fo(this)}});var Do,Fo;let ne=1e-6;const Uo=new Map;function ko(s){let e=Uo.get(s);return e||(e=function(t){function r(a=0,c=0){const h=new t(2);return a!==void 0&&(h[0]=a,c!==void 0&&(h[1]=c)),h}function n(a,c,h){const g=h??new t(2);return g[0]=a[0]-c[0],g[1]=a[1]-c[1],g}function i(a,c,h,g){const B=g??new t(2);return B[0]=a[0]+h*(c[0]-a[0]),B[1]=a[1]+h*(c[1]-a[1]),B}function o(a,c,h){const g=h??new t(2);return g[0]=a[0]*c,g[1]=a[1]*c,g}function u(a,c){const h=c??new t(2);return h[0]=1/a[0],h[1]=1/a[1],h}function l(a,c){return a[0]*c[0]+a[1]*c[1]}function m(a){const c=a[0],h=a[1];return Math.sqrt(c*c+h*h)}function y(a){const c=a[0],h=a[1];return c*c+h*h}function d(a,c){const h=a[0]-c[0],g=a[1]-c[1];return Math.sqrt(h*h+g*g)}function x(a,c){const h=a[0]-c[0],g=a[1]-c[1];return h*h+g*g}function b(a,c){const h=c??new t(2),g=a[0],B=a[1],w=Math.sqrt(g*g+B*B);return w>1e-5?(h[0]=g/w,h[1]=B/w):(h[0]=0,h[1]=0),h}function _(a,c){const h=c??new t(2);return h[0]=a[0],h[1]=a[1],h}function C(a,c,h){const g=h??new t(2);return g[0]=a[0]*c[0],g[1]=a[1]*c[1],g}function f(a,c,h){const g=h??new t(2);return g[0]=a[0]/c[0],g[1]=a[1]/c[1],g}function p(a,c,h){const g=h??new t(2);return b(a,g),o(g,c,g)}return{create:r,fromValues:r,set:function(a,c,h){const g=h??new t(2);return g[0]=a,g[1]=c,g},ceil:function(a,c){const h=c??new t(2);return h[0]=Math.ceil(a[0]),h[1]=Math.ceil(a[1]),h},floor:function(a,c){const h=c??new t(2);return h[0]=Math.floor(a[0]),h[1]=Math.floor(a[1]),h},round:function(a,c){const h=c??new t(2);return h[0]=Math.round(a[0]),h[1]=Math.round(a[1]),h},clamp:function(a,c=0,h=1,g){const B=g??new t(2);return B[0]=Math.min(h,Math.max(c,a[0])),B[1]=Math.min(h,Math.max(c,a[1])),B},add:function(a,c,h){const g=h??new t(2);return g[0]=a[0]+c[0],g[1]=a[1]+c[1],g},addScaled:function(a,c,h,g){const B=g??new t(2);return B[0]=a[0]+c[0]*h,B[1]=a[1]+c[1]*h,B},angle:function(a,c){const h=a[0],g=a[1],B=c[0],w=c[1],R=Math.sqrt(h*h+g*g)*Math.sqrt(B*B+w*w),U=R&&l(a,c)/R;return Math.acos(U)},subtract:n,sub:n,equalsApproximately:function(a,c){return Math.abs(a[0]-c[0])c?p(a,c,g):_(a,g)},midpoint:function(a,c,h){return i(a,c,.5,h??new t(2))}}}(s),Uo.set(s,e)),e}const No=new Map;function is(s){let e=No.get(s);return e||(e=function(t){function r(a,c,h){const g=new t(3);return a!==void 0&&(g[0]=a,c!==void 0&&(g[1]=c,h!==void 0&&(g[2]=h))),g}function n(a,c,h){const g=h??new t(3);return g[0]=a[0]-c[0],g[1]=a[1]-c[1],g[2]=a[2]-c[2],g}function i(a,c,h,g){const B=g??new t(3);return B[0]=a[0]+h*(c[0]-a[0]),B[1]=a[1]+h*(c[1]-a[1]),B[2]=a[2]+h*(c[2]-a[2]),B}function o(a,c,h){const g=h??new t(3);return g[0]=a[0]*c,g[1]=a[1]*c,g[2]=a[2]*c,g}function u(a,c){const h=c??new t(3);return h[0]=1/a[0],h[1]=1/a[1],h[2]=1/a[2],h}function l(a,c){return a[0]*c[0]+a[1]*c[1]+a[2]*c[2]}function m(a){const c=a[0],h=a[1],g=a[2];return Math.sqrt(c*c+h*h+g*g)}function y(a){const c=a[0],h=a[1],g=a[2];return c*c+h*h+g*g}function d(a,c){const h=a[0]-c[0],g=a[1]-c[1],B=a[2]-c[2];return Math.sqrt(h*h+g*g+B*B)}function x(a,c){const h=a[0]-c[0],g=a[1]-c[1],B=a[2]-c[2];return h*h+g*g+B*B}function b(a,c){const h=c??new t(3),g=a[0],B=a[1],w=a[2],R=Math.sqrt(g*g+B*B+w*w);return R>1e-5?(h[0]=g/R,h[1]=B/R,h[2]=w/R):(h[0]=0,h[1]=0,h[2]=0),h}function _(a,c){const h=c??new t(3);return h[0]=a[0],h[1]=a[1],h[2]=a[2],h}function C(a,c,h){const g=h??new t(3);return g[0]=a[0]*c[0],g[1]=a[1]*c[1],g[2]=a[2]*c[2],g}function f(a,c,h){const g=h??new t(3);return g[0]=a[0]/c[0],g[1]=a[1]/c[1],g[2]=a[2]/c[2],g}function p(a,c,h){const g=h??new t(3);return b(a,g),o(g,c,g)}return{create:r,fromValues:r,set:function(a,c,h,g){const B=g??new t(3);return B[0]=a,B[1]=c,B[2]=h,B},ceil:function(a,c){const h=c??new t(3);return h[0]=Math.ceil(a[0]),h[1]=Math.ceil(a[1]),h[2]=Math.ceil(a[2]),h},floor:function(a,c){const h=c??new t(3);return h[0]=Math.floor(a[0]),h[1]=Math.floor(a[1]),h[2]=Math.floor(a[2]),h},round:function(a,c){const h=c??new t(3);return h[0]=Math.round(a[0]),h[1]=Math.round(a[1]),h[2]=Math.round(a[2]),h},clamp:function(a,c=0,h=1,g){const B=g??new t(3);return B[0]=Math.min(h,Math.max(c,a[0])),B[1]=Math.min(h,Math.max(c,a[1])),B[2]=Math.min(h,Math.max(c,a[2])),B},add:function(a,c,h){const g=h??new t(3);return g[0]=a[0]+c[0],g[1]=a[1]+c[1],g[2]=a[2]+c[2],g},addScaled:function(a,c,h,g){const B=g??new t(3);return B[0]=a[0]+c[0]*h,B[1]=a[1]+c[1]*h,B[2]=a[2]+c[2]*h,B},angle:function(a,c){const h=a[0],g=a[1],B=a[2],w=c[0],R=c[1],U=c[2],k=Math.sqrt(h*h+g*g+B*B)*Math.sqrt(w*w+R*R+U*U),T=k&&l(a,c)/k;return Math.acos(T)},subtract:n,sub:n,equalsApproximately:function(a,c){return Math.abs(a[0]-c[0])c?p(a,c,g):_(a,g)},midpoint:function(a,c,h){return i(a,c,.5,h??new t(3))}}}(s),No.set(s,e)),e}const Vo=new Map;function vl(s){let e=Vo.get(s);return e||(e=function(t){const r=ko(t),n=is(t);function i(d,x){const b=x??new t(12);return b[0]=d[0],b[1]=d[1],b[2]=d[2],b[4]=d[4],b[5]=d[5],b[6]=d[6],b[8]=d[8],b[9]=d[9],b[10]=d[10],b}function o(d){const x=d??new t(12);return x[0]=1,x[1]=0,x[2]=0,x[4]=0,x[5]=1,x[6]=0,x[8]=0,x[9]=0,x[10]=1,x}function u(d,x){const b=x??new t(12),_=d[0],C=d[1],f=d[2],p=d[4],a=d[5],c=d[6],h=d[8],g=d[9],B=d[10],w=B*a-c*g,R=-B*p+c*h,U=g*p-a*h,k=1/(_*w+C*R+f*U);return b[0]=w*k,b[1]=(-B*C+f*g)*k,b[2]=(c*C-f*a)*k,b[4]=R*k,b[5]=(B*_-f*h)*k,b[6]=(-c*_+f*p)*k,b[8]=U*k,b[9]=(-g*_+C*h)*k,b[10]=(a*_-C*p)*k,b}function l(d,x,b){const _=b??new t(12),C=d[0],f=d[1],p=d[2],a=d[4],c=d[5],h=d[6],g=d[8],B=d[9],w=d[10],R=x[0],U=x[1],k=x[2],T=x[4],S=x[5],P=x[6],L=x[8],D=x[9],O=x[10];return _[0]=C*R+a*U+g*k,_[1]=f*R+c*U+B*k,_[2]=p*R+h*U+w*k,_[4]=C*T+a*S+g*P,_[5]=f*T+c*S+B*P,_[6]=p*T+h*S+w*P,_[8]=C*L+a*D+g*O,_[9]=f*L+c*D+B*O,_[10]=p*L+h*D+w*O,_}function m(d,x){const b=x??new t(12),_=Math.cos(d),C=Math.sin(d);return b[0]=_,b[1]=C,b[2]=0,b[4]=-C,b[5]=_,b[6]=0,b[8]=0,b[9]=0,b[10]=1,b}function y(d,x,b){const _=b??new t(12),C=d[0],f=d[1],p=d[2],a=d[4],c=d[5],h=d[6],g=Math.cos(x),B=Math.sin(x);return _[0]=g*C+B*a,_[1]=g*f+B*c,_[2]=g*p+B*h,_[4]=g*a-B*C,_[5]=g*c-B*f,_[6]=g*h-B*p,d!==_&&(_[8]=d[8],_[9]=d[9],_[10]=d[10]),_}return{clone:i,create:function(d,x,b,_,C,f,p,a,c){const h=new t(12);return h[3]=0,h[7]=0,h[11]=0,d!==void 0&&(h[0]=d,x!==void 0&&(h[1]=x,b!==void 0&&(h[2]=b,_!==void 0&&(h[4]=_,C!==void 0&&(h[5]=C,f!==void 0&&(h[6]=f,p!==void 0&&(h[8]=p,a!==void 0&&(h[9]=a,c!==void 0&&(h[10]=c))))))))),h},set:function(d,x,b,_,C,f,p,a,c,h){const g=h??new t(12);return g[0]=d,g[1]=x,g[2]=b,g[3]=0,g[4]=_,g[5]=C,g[6]=f,g[7]=0,g[8]=p,g[9]=a,g[10]=c,g[11]=0,g},fromMat4:function(d,x){const b=x??new t(12);return b[0]=d[0],b[1]=d[1],b[2]=d[2],b[3]=0,b[4]=d[4],b[5]=d[5],b[6]=d[6],b[7]=0,b[8]=d[8],b[9]=d[9],b[10]=d[10],b[11]=0,b},fromQuat:function(d,x){const b=x??new t(12),_=d[0],C=d[1],f=d[2],p=d[3],a=_+_,c=C+C,h=f+f,g=_*a,B=C*a,w=C*c,R=f*a,U=f*c,k=f*h,T=p*a,S=p*c,P=p*h;return b[0]=1-w-k,b[1]=B+P,b[2]=R-S,b[3]=0,b[4]=B-P,b[5]=1-g-k,b[6]=U+T,b[7]=0,b[8]=R+S,b[9]=U-T,b[10]=1-g-w,b[11]=0,b},negate:function(d,x){const b=x??new t(12);return b[0]=-d[0],b[1]=-d[1],b[2]=-d[2],b[4]=-d[4],b[5]=-d[5],b[6]=-d[6],b[8]=-d[8],b[9]=-d[9],b[10]=-d[10],b},copy:i,equalsApproximately:function(d,x){return Math.abs(d[0]-x[0])ne){const pe=Math.acos(fe),ye=Math.sin(pe);j=Math.sin((1-P)*pe)/ye,z=Math.sin(P*pe)/ye}else j=1-P,z=P;return D[0]=j*O+z*q,D[1]=j*H+z*Z,D[2]=j*K+z*te,D[3]=j*$+z*re,D}function y(T,S){const P=S??new t(4);return P[0]=T[0],P[1]=T[1],P[2]=T[2],P[3]=T[3],P}const d=y;function x(T,S,P){const L=P??new t(4);return L[0]=T[0]-S[0],L[1]=T[1]-S[1],L[2]=T[2]-S[2],L[3]=T[3]-S[3],L}const b=x;function _(T,S,P){const L=P??new t(4);return L[0]=T[0]*S,L[1]=T[1]*S,L[2]=T[2]*S,L[3]=T[3]*S,L}const C=_;function f(T,S){return T[0]*S[0]+T[1]*S[1]+T[2]*S[2]+T[3]*S[3]}function p(T){const S=T[0],P=T[1],L=T[2],D=T[3];return Math.sqrt(S*S+P*P+L*L+D*D)}const a=p;function c(T){const S=T[0],P=T[1],L=T[2],D=T[3];return S*S+P*P+L*L+D*D}const h=c;function g(T,S){const P=S??new t(4),L=T[0],D=T[1],O=T[2],H=T[3],K=Math.sqrt(L*L+D*D+O*O+H*H);return K>1e-5?(P[0]=L/K,P[1]=D/K,P[2]=O/K,P[3]=H/K):(P[0]=0,P[1]=0,P[2]=0,P[3]=1),P}const B=r.create(),w=r.create(),R=r.create(),U=new t(4),k=new t(4);return{create:n,fromValues:i,set:function(T,S,P,L,D){const O=D??new t(4);return O[0]=T,O[1]=S,O[2]=P,O[3]=L,O},fromAxisAngle:o,toAxisAngle:function(T,S){const P=S??r.create(3),L=2*Math.acos(T[3]),D=Math.sin(.5*L);return D>ne?(P[0]=T[0]/D,P[1]=T[1]/D,P[2]=T[2]/D):(P[0]=1,P[1]=0,P[2]=0),{angle:L,axis:P}},angle:function(T,S){const P=f(T,S);return Math.acos(2*P*P-1)},multiply:u,mul:l,rotateX:function(T,S,P){const L=P??new t(4),D=.5*S,O=T[0],H=T[1],K=T[2],$=T[3],j=Math.sin(D),z=Math.cos(D);return L[0]=O*z+$*j,L[1]=H*z+K*j,L[2]=K*z-H*j,L[3]=$*z-O*j,L},rotateY:function(T,S,P){const L=P??new t(4),D=.5*S,O=T[0],H=T[1],K=T[2],$=T[3],j=Math.sin(D),z=Math.cos(D);return L[0]=O*z-K*j,L[1]=H*z+$*j,L[2]=K*z+O*j,L[3]=$*z-H*j,L},rotateZ:function(T,S,P){const L=P??new t(4),D=.5*S,O=T[0],H=T[1],K=T[2],$=T[3],j=Math.sin(D),z=Math.cos(D);return L[0]=O*z+H*j,L[1]=H*z-O*j,L[2]=K*z+$*j,L[3]=$*z-K*j,L},slerp:m,inverse:function(T,S){const P=S??new t(4),L=T[0],D=T[1],O=T[2],H=T[3],K=L*L+D*D+O*O+H*H,$=K?1/K:0;return P[0]=-L*$,P[1]=-D*$,P[2]=-O*$,P[3]=H*$,P},conjugate:function(T,S){const P=S??new t(4);return P[0]=-T[0],P[1]=-T[1],P[2]=-T[2],P[3]=T[3],P},fromMat:function(T,S){const P=S??new t(4),L=T[0]+T[5]+T[10];if(L>0){const D=Math.sqrt(L+1);P[3]=.5*D;const O=.5/D;P[0]=(T[6]-T[9])*O,P[1]=(T[8]-T[2])*O,P[2]=(T[1]-T[4])*O}else{let D=0;T[5]>T[0]&&(D=1),T[10]>T[4*D+D]&&(D=2);const O=(D+1)%3,H=(D+2)%3,K=Math.sqrt(T[4*D+D]-T[4*O+O]-T[4*H+H]+1);P[D]=.5*K;const $=.5/K;P[3]=(T[4*O+H]-T[4*H+O])*$,P[O]=(T[4*O+D]+T[4*D+O])*$,P[H]=(T[4*H+D]+T[4*D+H])*$}return P},fromEuler:function(T,S,P,L,D){const O=D??new t(4),H=.5*T,K=.5*S,$=.5*P,j=Math.sin(H),z=Math.cos(H),q=Math.sin(K),Z=Math.cos(K),te=Math.sin($),re=Math.cos($);switch(L){case"xyz":O[0]=j*Z*re+z*q*te,O[1]=z*q*re-j*Z*te,O[2]=z*Z*te+j*q*re,O[3]=z*Z*re-j*q*te;break;case"xzy":O[0]=j*Z*re-z*q*te,O[1]=z*q*re-j*Z*te,O[2]=z*Z*te+j*q*re,O[3]=z*Z*re+j*q*te;break;case"yxz":O[0]=j*Z*re+z*q*te,O[1]=z*q*re-j*Z*te,O[2]=z*Z*te-j*q*re,O[3]=z*Z*re+j*q*te;break;case"yzx":O[0]=j*Z*re+z*q*te,O[1]=z*q*re+j*Z*te,O[2]=z*Z*te-j*q*re,O[3]=z*Z*re-j*q*te;break;case"zxy":O[0]=j*Z*re-z*q*te,O[1]=z*q*re+j*Z*te,O[2]=z*Z*te+j*q*re,O[3]=z*Z*re-j*q*te;break;case"zyx":O[0]=j*Z*re-z*q*te,O[1]=z*q*re+j*Z*te,O[2]=z*Z*te-j*q*re,O[3]=z*Z*re+j*q*te;break;default:throw new Error(`Unknown rotation order: ${L}`)}return O},copy:y,clone:d,add:function(T,S,P){const L=P??new t(4);return L[0]=T[0]+S[0],L[1]=T[1]+S[1],L[2]=T[2]+S[2],L[3]=T[3]+S[3],L},subtract:x,sub:b,mulScalar:_,scale:C,divScalar:function(T,S,P){const L=P??new t(4);return L[0]=T[0]/S,L[1]=T[1]/S,L[2]=T[2]/S,L[3]=T[3]/S,L},dot:f,lerp:function(T,S,P,L){const D=L??new t(4);return D[0]=T[0]+P*(S[0]-T[0]),D[1]=T[1]+P*(S[1]-T[1]),D[2]=T[2]+P*(S[2]-T[2]),D[3]=T[3]+P*(S[3]-T[3]),D},length:p,len:a,lengthSq:c,lenSq:h,normalize:g,equalsApproximately:function(T,S){return Math.abs(T[0]-S[0]).999999?(L[0]=0,L[1]=0,L[2]=0,L[3]=1,L):(r.cross(T,S,B),L[0]=B[0],L[1]=B[1],L[2]=B[2],L[3]=1+D,g(L,L))},sqlerp:function(T,S,P,L,D,O){const H=O??new t(4);return m(T,L,D,U),m(S,P,D,k),m(U,k,2*D*(1-D),H),H}}}(s),Jo.set(s,e)),e}const zo=new Map;function Tl(s){let e=zo.get(s);return e||(e=function(t){function r(p,a,c,h){const g=new t(4);return p!==void 0&&(g[0]=p,a!==void 0&&(g[1]=a,c!==void 0&&(g[2]=c,h!==void 0&&(g[3]=h)))),g}function n(p,a,c){const h=c??new t(4);return h[0]=p[0]-a[0],h[1]=p[1]-a[1],h[2]=p[2]-a[2],h[3]=p[3]-a[3],h}function i(p,a,c,h){const g=h??new t(4);return g[0]=p[0]+c*(a[0]-p[0]),g[1]=p[1]+c*(a[1]-p[1]),g[2]=p[2]+c*(a[2]-p[2]),g[3]=p[3]+c*(a[3]-p[3]),g}function o(p,a,c){const h=c??new t(4);return h[0]=p[0]*a,h[1]=p[1]*a,h[2]=p[2]*a,h[3]=p[3]*a,h}function u(p,a){const c=a??new t(4);return c[0]=1/p[0],c[1]=1/p[1],c[2]=1/p[2],c[3]=1/p[3],c}function l(p){const a=p[0],c=p[1],h=p[2],g=p[3];return Math.sqrt(a*a+c*c+h*h+g*g)}function m(p){const a=p[0],c=p[1],h=p[2],g=p[3];return a*a+c*c+h*h+g*g}function y(p,a){const c=p[0]-a[0],h=p[1]-a[1],g=p[2]-a[2],B=p[3]-a[3];return Math.sqrt(c*c+h*h+g*g+B*B)}function d(p,a){const c=p[0]-a[0],h=p[1]-a[1],g=p[2]-a[2],B=p[3]-a[3];return c*c+h*h+g*g+B*B}function x(p,a){const c=a??new t(4),h=p[0],g=p[1],B=p[2],w=p[3],R=Math.sqrt(h*h+g*g+B*B+w*w);return R>1e-5?(c[0]=h/R,c[1]=g/R,c[2]=B/R,c[3]=w/R):(c[0]=0,c[1]=0,c[2]=0,c[3]=0),c}function b(p,a){const c=a??new t(4);return c[0]=p[0],c[1]=p[1],c[2]=p[2],c[3]=p[3],c}function _(p,a,c){const h=c??new t(4);return h[0]=p[0]*a[0],h[1]=p[1]*a[1],h[2]=p[2]*a[2],h[3]=p[3]*a[3],h}function C(p,a,c){const h=c??new t(4);return h[0]=p[0]/a[0],h[1]=p[1]/a[1],h[2]=p[2]/a[2],h[3]=p[3]/a[3],h}function f(p,a,c){const h=c??new t(4);return x(p,h),o(h,a,h)}return{create:r,fromValues:r,set:function(p,a,c,h,g){const B=g??new t(4);return B[0]=p,B[1]=a,B[2]=c,B[3]=h,B},ceil:function(p,a){const c=a??new t(4);return c[0]=Math.ceil(p[0]),c[1]=Math.ceil(p[1]),c[2]=Math.ceil(p[2]),c[3]=Math.ceil(p[3]),c},floor:function(p,a){const c=a??new t(4);return c[0]=Math.floor(p[0]),c[1]=Math.floor(p[1]),c[2]=Math.floor(p[2]),c[3]=Math.floor(p[3]),c},round:function(p,a){const c=a??new t(4);return c[0]=Math.round(p[0]),c[1]=Math.round(p[1]),c[2]=Math.round(p[2]),c[3]=Math.round(p[3]),c},clamp:function(p,a=0,c=1,h){const g=h??new t(4);return g[0]=Math.min(c,Math.max(a,p[0])),g[1]=Math.min(c,Math.max(a,p[1])),g[2]=Math.min(c,Math.max(a,p[2])),g[3]=Math.min(c,Math.max(a,p[3])),g},add:function(p,a,c){const h=c??new t(4);return h[0]=p[0]+a[0],h[1]=p[1]+a[1],h[2]=p[2]+a[2],h[3]=p[3]+a[3],h},addScaled:function(p,a,c,h){const g=h??new t(4);return g[0]=p[0]+a[0]*c,g[1]=p[1]+a[1]*c,g[2]=p[2]+a[2]*c,g[3]=p[3]+a[3]*c,g},subtract:n,sub:n,equalsApproximately:function(p,a){return Math.abs(p[0]-a[0])a?f(p,a,h):b(p,h)},midpoint:function(p,a,c){return i(p,a,.5,c??new t(4))}}}(s),zo.set(s,e)),e}function In(s,e,t,r,n,i){return{mat3:vl(s),mat4:wl(e),quat:Cl(t),vec2:ko(r),vec3:is(n),vec4:Tl(i)}}const{mat3:os,mat4:Q,quat:as,vec2:Ee,vec3:F,vec4:Sr}=In(Float32Array,Float32Array,Float32Array,Float32Array,Float32Array,Float32Array);In(Float64Array,Float64Array,Float64Array,Float64Array,Float64Array,Float64Array),In(Al,Array,Array,Array,Array,Array);const Sl=""+new URL("Sponza-Eg7MFCLQ.gltf",import.meta.url).href;class Ye{constructor(){throw new Error(`${this.constructor.name} is non-instantiable`)}}class tr extends Ye{static linear(e){return e}static quad_In(e){return e*e}static quad_Out(e){return e*(2-e)}static quad_InOut(e){return(e*=2)<1?.5*e*e:-.5*(--e*(e-2)-1)}static cubic_In(e){return e*e*e}static cubic_Out(e){return--e*e*e+1}static cubic_InOut(e){return(e*=2)<1?.5*e*e*e:.5*((e-=2)*e*e+2)}static quart_In(e){return e*e*e*e}static quart_Out(e){return 1- --e*e*e*e}static quart_InOut(e){return(e*=2)<1?.5*e*e*e*e:-.5*((e-=2)*e*e*e-2)}static quint_In(e){return e*e*e*e*e}static quint_Out(e){return--e*e*e*e*e+1}static quint_InOut(e){return(e*=2)<1?.5*e*e*e*e*e:.5*((e-=2)*e*e*e*e+2)}static sine_In(e){return 1-Math.cos(e*Math.PI/2)}static sine_Out(e){return Math.sin(e*Math.PI/2)}static sine_InOut(e){return .5*(1-Math.cos(Math.PI*e))}static exp_In(e){return e===0?0:Math.pow(1024,e-1)}static exp_Out(e){return e===1?1:1-Math.pow(2,-10*e)}static exp_InOut(e){return e===0||e===1?e:(e*=2)<1?.5*Math.pow(1024,e-1):.5*(2-Math.pow(2,-10*(e-1)))}static circ_In(e){return 1-Math.sqrt(1-e*e)}static circ_Out(e){return Math.sqrt(1- --e*e)}static circ_InOut(e){return(e*=2)<1?-.5*(Math.sqrt(1-e*e)-1):.5*(Math.sqrt(1-(e-=2)*e)+1)}static elastic_In(e){return e===0||e===1?e:-Math.pow(2,10*(e-1))*Math.sin(5*(e-1.1)*Math.PI)}static elastic_Out(e){return e===0||e===1?e:Math.pow(2,-10*e)*Math.sin(5*(e-.1)*Math.PI)+1}static elastic_InOut(e){return e===0||e===1?e:(e*=2)<1?-.5*Math.pow(2,10*(e-1))*Math.sin(5*(e-1.1)*Math.PI):.5*Math.pow(2,-10*(e-1))*Math.sin(5*(e-1.1)*Math.PI)+1}static back_In(e){return e*e*(2.70158*e-1.70158)}static back_Out(e){return--e*e*(2.70158*e+1.70158)+1}static back_InOut(e){const t=2.5949095;return(e*=2)<1?e*e*((t+1)*e-t)*.5:.5*((e-=2)*e*((t+1)*e+t)+2)}static bounce_In(e){return 1-tr.bounce_Out(1-e)}static bounce_Out(e){return e<1/2.75?7.5625*e*e:e<2/2.75?7.5625*(e-=1.5/2.75)*e+.75:e<2.5/2.75?7.5625*(e-=2.25/2.75)*e+.9375:7.5625*(e-=2.625/2.75)*e+.984375}static bounce_InOut(e){return e<.5?.5*tr.bounce_In(2*e):.5*tr.bounce_Out(2*e-1)+.5}}class us{constructor({durationMS:e,delayMS:t=0,easeName:r="linear",onUpdate:n,onComplete:i=()=>{}}){this.startMS=0,this.update=()=>{this.rafID=window.requestAnimationFrame(this.update);let o=(performance.now()-this.startMS)/this.durationMS;o<0?o=0:o>1&&(o=1);const u=this.easeFunc(o);this.onUpdate(u,o),o>=1&&(this.onComplete(),this.stop())},this.durationMS=e,this.delayMS=t,this.easeFunc=tr[r],this.onUpdate=n,this.onComplete=i}start(){const e=()=>{this.startMS=performance.now(),this.rafID=window.requestAnimationFrame(this.update),clearTimeout(this.delayID)};return this.delayMS?this.delayID=window.setTimeout(e,this.delayMS):e(),this}stop(){return window.clearTimeout(this.delayID),window.cancelAnimationFrame(this.rafID),this.rafID=-1,this}setEase(e){return this.easeFunc=tr[e],this}}const Ce=F.create(),El=87,Ml=83,Pl=65,Rl=68,Gl=69,Ll=81,Dn="ontouchstart"in window||navigator.maxTouchPoints>0,ae=class ae{constructor(e,t=document.body,r=t){this.camera=e,this.keyboardDomElement=t,this.mouseDomElement=r,this.angles=Ee.create(0,.5*-Math.PI),this.viewMat=Q.create(),this.rotMat=Q.identity(),this.lastX=0,this.lastY=0,this.oldTime=0,this.presedKeys=new Array(128),this.rafId=-1,this.speed=40,this.touchMoveX=.5*-ae.TOUCHMOVE_HANDLE_SIZE,this.touchMoveY=.5*-ae.TOUCHMOVE_HANDLE_SIZE,this.touchMoveTargetX=.5*-ae.TOUCHMOVE_HANDLE_SIZE,this.touchMoveTargetY=.5*-ae.TOUCHMOVE_HANDLE_SIZE,this.touchMoveAngle=0,this.touchLookX=.5*-ae.TOUCHMOVE_HANDLE_SIZE,this.touchLookY=.5*-ae.TOUCHMOVE_HANDLE_SIZE,this.touchLookTargetX=.5*-ae.TOUCHMOVE_HANDLE_SIZE,this.touchLookTargetY=.5*-ae.TOUCHMOVE_HANDLE_SIZE,this.touchLookAngle=0,this.isTouchMoveActive=!1,this.isTouchLookActive=!1,this.onLookHandleTouchStart=()=>{},this.onLookHandleTouchMove=n=>{n.preventDefault();const i=n.targetTouches[0].clientX,o=n.targetTouches[0].clientY,u=innerWidth-24-.5*ae.TOUCHMOVE_ROOT_SIZE-i,l=innerHeight-24-.5*ae.TOUCHMOVE_ROOT_SIZE-o,m=Math.min(Math.sqrt(u*u+l*l),60),y=Math.atan2(-l,-u),d=Math.cos(y)*m-.5*ae.TOUCHMOVE_HANDLE_SIZE,x=Math.sin(y)*m-.5*ae.TOUCHMOVE_HANDLE_SIZE;this.touchLookTargetX=d,this.touchLookTargetY=x,this.touchLookAngle=y,this.isTouchLookActive=!0},this.onLookHandleTouchEnd=()=>{this.touchLookTargetX=.5*-ae.TOUCHMOVE_HANDLE_SIZE,this.touchLookTargetY=.5*-ae.TOUCHMOVE_HANDLE_SIZE,this.isTouchLookActive=!1},this.onMoveHandleTouchStart=()=>{},this.onMoveHandleTouchEnd=()=>{this.touchMoveTargetX=.5*-ae.TOUCHMOVE_HANDLE_SIZE,this.touchMoveTargetY=.5*-ae.TOUCHMOVE_HANDLE_SIZE,this.isTouchMoveActive=!1},this.onMoveHandleTouchMove=n=>{n.preventDefault();const i=n.targetTouches[0].clientX,o=n.targetTouches[0].clientY,u=24+.5*ae.TOUCHMOVE_ROOT_SIZE-i,l=innerHeight-24-.5*ae.TOUCHMOVE_ROOT_SIZE-o,m=Math.min(Math.sqrt(u*u+l*l),60),y=Math.atan2(-l,-u),d=Math.cos(y)*m-.5*ae.TOUCHMOVE_HANDLE_SIZE,x=Math.sin(y)*m-.5*ae.TOUCHMOVE_HANDLE_SIZE;this.touchMoveTargetX=d,this.touchMoveTargetY=x,this.touchMoveAngle=y,this.isTouchMoveActive=!0},this.update=()=>{var l,m;const n=.001*this.speed;F.set(0,0,0,Ce);const i=.001*performance.now(),o=i-this.oldTime;if(this.oldTime=i,Dn){if(this.touchMoveX+=(this.touchMoveTargetX-this.touchMoveX)*o*5,this.touchMoveY+=(this.touchMoveTargetY-this.touchMoveY)*o*5,(l=this.$touchMoveHandle)==null||l.style.setProperty("transform",`translate3d(${this.touchMoveX}px, ${this.touchMoveY}px, 0)`),this.touchLookX+=(this.touchLookTargetX-this.touchLookX)*o*5,this.touchLookY+=(this.touchLookTargetY-this.touchLookY)*o*5,(m=this.$touchLookHandle)==null||m.style.setProperty("transform",`translate3d(${this.touchLookX}px, ${this.touchLookY}px, 0)`),this.isTouchLookActive){const y=Math.cos(this.touchLookAngle),d=Math.sin(this.touchLookAngle);this.rotateView(.03*y,.03*d)}if(this.isTouchMoveActive){const y=Math.cos(this.touchMoveAngle),d=Math.sin(this.touchMoveAngle);Ce[0]=.05*y,Ce[2]=.05*d}}else(this.presedKeys[El]||this.presedKeys[38])&&(Ce[2]-=n),(this.presedKeys[Ml]||this.presedKeys[40])&&(Ce[2]+=n),(this.presedKeys[Pl]||this.presedKeys[37])&&(Ce[0]-=n),(this.presedKeys[Rl]||this.presedKeys[39])&&(Ce[0]+=n),this.presedKeys[Gl]&&(Ce[1]+=n),this.presedKeys[Ll]&&(Ce[1]-=n);Ce[0]===0&&Ce[1]===0&&Ce[2]===0||(F.transformMat4(Ce,this.rotMat,Ce),F.add(this.position,Ce,this.position));const u=this.viewMat;Q.identity(u),Q.rotateX(u,this.angles[0],u),Q.rotateY(u,this.angles[1],u),Q.translate(u,F.negate(this.position),u),this.camera.setPosition(this.position[0],this.position[1],this.position[2]),this.camera.updateViewMatrixWithMat(u),this.rafId=requestAnimationFrame(this.update)},this.onMouseDown=n=>{this.lastX=n.pageX,this.lastY=n.pageY,this.mouseDomElement.addEventListener("mousemove",this.onMouseMove)},this.onMouseUp=()=>{this.mouseDomElement.removeEventListener("mousemove",this.onMouseMove)},this.onMouseMove=n=>{const i=n.pageX-this.lastX,o=n.pageY-this.lastY;this.lastX=n.pageX,this.lastY=n.pageY,this.rotateView(.0075*i,.005*o)},this.onKeyDown=n=>{this.presedKeys[n.keyCode]=!0},this.onKeyUp=n=>{this.presedKeys[n.keyCode]=!1},this.position=e.position,t.addEventListener("keydown",this.onKeyDown),t.addEventListener("keyup",this.onKeyUp),r.addEventListener("mousedown",this.onMouseDown),r.addEventListener("mouseup",this.onMouseUp),this.rotateView(.0075,.005),Dn&&(this.$touchMoveRoot=document.createElement("div"),this.$touchMoveRoot.style.setProperty("position","fixed"),this.$touchMoveRoot.style.setProperty("left","24px"),this.$touchMoveRoot.style.setProperty("bottom","24px"),this.$touchMoveRoot.style.setProperty("width",`${ae.TOUCHMOVE_ROOT_SIZE}px`),this.$touchMoveRoot.style.setProperty("height",`${ae.TOUCHMOVE_ROOT_SIZE}px`),this.$touchMoveRoot.style.setProperty("border-radius","50%"),this.$touchMoveRoot.style.setProperty("border","2px solid white"),this.$touchMoveRoot.style.setProperty("z-index","9999"),this.$touchMoveRoot.style.setProperty("transition","opacity 0.125s ease"),this.$touchMoveRoot.style.setProperty("opacity","0"),this.$touchMoveHandle=document.createElement("div"),this.$touchMoveHandle.style.setProperty("width",`${ae.TOUCHMOVE_HANDLE_SIZE}px`),this.$touchMoveHandle.style.setProperty("height",`${ae.TOUCHMOVE_HANDLE_SIZE}px`),this.$touchMoveHandle.style.setProperty("position","absolute"),this.$touchMoveHandle.style.setProperty("left","50%"),this.$touchMoveHandle.style.setProperty("top","50%"),this.$touchMoveHandle.style.setProperty("background-color","rgba(255, 255, 255, 0.72)"),this.$touchMoveHandle.style.setProperty("border-radius","50%"),this.$touchMoveRoot.appendChild(this.$touchMoveHandle),document.body.appendChild(this.$touchMoveRoot),this.$touchLookRoot=document.createElement("div"),this.$touchLookRoot.style.setProperty("position","fixed"),this.$touchLookRoot.style.setProperty("bottom","24px"),this.$touchLookRoot.style.setProperty("right","24px"),this.$touchLookRoot.style.setProperty("width",`${ae.TOUCHMOVE_ROOT_SIZE}px`),this.$touchLookRoot.style.setProperty("height",`${ae.TOUCHMOVE_ROOT_SIZE}px`),this.$touchLookRoot.style.setProperty("border","2px solid white"),this.$touchLookRoot.style.setProperty("border-radius","50%"),this.$touchLookRoot.style.setProperty("z-index","9999"),this.$touchLookRoot.style.setProperty("transition","opacity 0.125s ease"),this.$touchLookRoot.style.setProperty("opacity","0"),document.body.appendChild(this.$touchLookRoot),this.$touchLookHandle=document.createElement("div"),this.$touchLookHandle.style.setProperty("width",`${ae.TOUCHMOVE_HANDLE_SIZE}px`),this.$touchLookHandle.style.setProperty("height",`${ae.TOUCHMOVE_HANDLE_SIZE}px`),this.$touchLookHandle.style.setProperty("position","absolute"),this.$touchLookHandle.style.setProperty("left","50%"),this.$touchLookHandle.style.setProperty("top","50%"),this.$touchLookHandle.style.setProperty("background-color","rgba(255, 255, 255, 0.72)"),this.$touchLookHandle.style.setProperty("border-radius","50%"),this.$touchLookRoot.appendChild(this.$touchLookHandle),this.$touchMoveHandle.addEventListener("touchstart",this.onMoveHandleTouchStart),this.$touchMoveHandle.addEventListener("touchmove",this.onMoveHandleTouchMove),this.$touchMoveHandle.addEventListener("touchend",this.onMoveHandleTouchEnd),this.$touchMoveHandle.addEventListener("touchcancel",this.onMoveHandleTouchEnd),this.$touchLookHandle.addEventListener("touchstart",this.onLookHandleTouchStart),this.$touchLookHandle.addEventListener("touchmove",this.onLookHandleTouchMove),this.$touchLookHandle.addEventListener("touchend",this.onLookHandleTouchEnd),this.$touchLookHandle.addEventListener("touchcancel",this.onLookHandleTouchEnd))}revealTouchControls(){Dn&&(this.$touchMoveRoot.style.setProperty("opacity","1"),this.$touchLookRoot.style.setProperty("opacity","1"))}startTick(){this.rafId=requestAnimationFrame(this.update)}endTick(){cancelAnimationFrame(this.rafId)}rotateView(e,t){if(e||t){for(this.angles[1]+=e;this.angles[1]<0;)this.angles[1]+=2*Math.PI;for(;this.angles[1]>=2*Math.PI;)this.angles[1]-=2*Math.PI;this.angles[0]+=t,this.angles[0]<.5*-Math.PI&&(this.angles[0]=.5*-Math.PI),this.angles[0]>.5*Math.PI&&(this.angles[0]=.5*Math.PI),Q.identity(this.rotMat),Q.rotateY(this.rotMat,-this.angles[1],this.rotMat),Q.rotateX(this.rotMat,-this.angles[0],this.rotMat)}}};ae.TOUCHMOVE_ROOT_SIZE=120,ae.TOUCHMOVE_HANDLE_SIZE=90;let Fn=ae;const jo=(s,e,t)=>s+t*(e-s),It=(s,e)=>{const t=Math.max(s,e);return 1+Math.log2(t)|0},Ol=Q.identity(),Il=[[1,0,0],[-1,0,0],[0,1,0],[0,-1,0],[0,0,1],[0,0,-1]],Dl=[[0,1,0],[0,1,0],[0,0,-1],[0,0,1],[0,1,0],[0,1,0]],Ko=new Float32Array(1),Fl=new Int32Array(Ko.buffer),cs=s=>{Ko[0]=s;const e=Fl[0];let t=e>>16&32768,r=e>>12&2047;const n=e>>23&255;return n<103?t:n>142?(t|=31744,t|=(n==255?0:1)&&8388607&e,t):n<113?(r|=2048,t|=(r>>114-n)+(r>>113-n&1),t):(t|=n-112<<10|r>>1,t+=1&r,t)},Un=(s,e)=>((s+e-1)/e|0)*e,$o=s=>s&&typeof s.length=="number"&&s.buffer instanceof ArrayBuffer&&typeof s.byteLength=="number",oe={i32:{numElements:1,align:4,size:4,type:"i32",View:Int32Array},u32:{numElements:1,align:4,size:4,type:"u32",View:Uint32Array},f32:{numElements:1,align:4,size:4,type:"f32",View:Float32Array},f16:{numElements:1,align:2,size:2,type:"u16",View:Uint16Array},vec2f:{numElements:2,align:8,size:8,type:"f32",View:Float32Array},vec2i:{numElements:2,align:8,size:8,type:"i32",View:Int32Array},vec2u:{numElements:2,align:8,size:8,type:"u32",View:Uint32Array},vec2h:{numElements:2,align:4,size:4,type:"u16",View:Uint16Array},vec3i:{numElements:3,align:16,size:12,type:"i32",View:Int32Array},vec3u:{numElements:3,align:16,size:12,type:"u32",View:Uint32Array},vec3f:{numElements:3,align:16,size:12,type:"f32",View:Float32Array},vec3h:{numElements:3,align:8,size:6,type:"u16",View:Uint16Array},vec4i:{numElements:4,align:16,size:16,type:"i32",View:Int32Array},vec4u:{numElements:4,align:16,size:16,type:"u32",View:Uint32Array},vec4f:{numElements:4,align:16,size:16,type:"f32",View:Float32Array},vec4h:{numElements:4,align:8,size:8,type:"u16",View:Uint16Array},mat2x2f:{numElements:4,align:8,size:16,type:"f32",View:Float32Array},mat2x2h:{numElements:4,align:4,size:8,type:"u16",View:Uint16Array},mat3x2f:{numElements:6,align:8,size:24,type:"f32",View:Float32Array},mat3x2h:{numElements:6,align:4,size:12,type:"u16",View:Uint16Array},mat4x2f:{numElements:8,align:8,size:32,type:"f32",View:Float32Array},mat4x2h:{numElements:8,align:4,size:16,type:"u16",View:Uint16Array},mat2x3f:{numElements:8,align:16,size:32,pad:[3,1],type:"f32",View:Float32Array},mat2x3h:{numElements:8,align:8,size:16,pad:[3,1],type:"u16",View:Uint16Array},mat3x3f:{numElements:12,align:16,size:48,pad:[3,1],type:"f32",View:Float32Array},mat3x3h:{numElements:12,align:8,size:24,pad:[3,1],type:"u16",View:Uint16Array},mat4x3f:{numElements:16,align:16,size:64,pad:[3,1],type:"f32",View:Float32Array},mat4x3h:{numElements:16,align:8,size:32,pad:[3,1],type:"u16",View:Uint16Array},mat2x4f:{numElements:8,align:16,size:32,type:"f32",View:Float32Array},mat2x4h:{numElements:8,align:8,size:16,type:"u16",View:Uint16Array},mat3x4f:{numElements:12,align:16,size:48,pad:[3,1],type:"f32",View:Float32Array},mat3x4h:{numElements:12,align:8,size:24,pad:[3,1],type:"u16",View:Uint16Array},mat4x4f:{numElements:16,align:16,size:64,type:"f32",View:Float32Array},mat4x4h:{numElements:16,align:8,size:32,type:"u16",View:Uint16Array},bool:{numElements:0,align:1,size:0,type:"bool",View:Uint32Array}},rr={...oe,"atomic":oe.i32,"atomic":oe.u32,"vec2":oe.vec2i,"vec2":oe.vec2u,"vec2":oe.vec2f,"vec2":oe.vec2h,"vec3":oe.vec3i,"vec3":oe.vec3u,"vec3":oe.vec3f,"vec3":oe.vec3h,"vec4":oe.vec4i,"vec4":oe.vec4u,"vec4":oe.vec4f,"vec4":oe.vec4h,"mat2x2":oe.mat2x2f,"mat2x2":oe.mat2x2h,"mat3x2":oe.mat3x2f,"mat3x2":oe.mat3x2h,"mat4x2":oe.mat4x2f,"mat4x2":oe.mat4x2h,"mat2x3":oe.mat2x3f,"mat2x3":oe.mat2x3h,"mat3x3":oe.mat3x3f,"mat3x3":oe.mat3x3h,"mat4x3":oe.mat4x3f,"mat4x3":oe.mat4x3h,"mat2x4":oe.mat2x4f,"mat2x4":oe.mat2x4h,"mat3x4":oe.mat3x4f,"mat3x4":oe.mat3x4h,"mat4x4":oe.mat4x4f,"mat4x4":oe.mat4x4h},Ul=(Xo=rr,Object.keys(Xo));var Xo;function Yo(s,e,t,r){const{size:n,type:i}=s;try{const{View:o,align:u}=rr[i],l=r!==void 0,m=l?Un(n,u):n,y=m/o.BYTES_PER_ELEMENT;return new o(e,t,y*(l?r===0?(e.byteLength-t)/m:r:1))}catch{throw new Error(`unknown type: ${i}`)}}function kl(s,e,t){const r=t||0,n=new ArrayBuffer(function(o){const u=o;if(u.elementType)return u.size;{const l=o,m=u.numElements||1;if(l.fields)return o.size*m;{const y=o,{align:d}=rr[y.type];return m>1?Un(o.size,d)*m:o.size}}}(s)),i=(o,u)=>{const l=o,m=l.elementType;if(m){if(function(d){return!d.fields&&!d.elementType}(m)&&rr[m.type].flatten)return Yo(m,n,u,l.numElements);{const{size:d}=Wo(o),x=l.numElements===0?(n.byteLength-u)/d:l.numElements;return y=b=>i(m,u+d*b),new Array(x).fill(0).map((b,_)=>y(_))}}if(typeof o=="string")throw Error("unreachable");{const d=o.fields;if(d){const x={};for(const[b,{type:_,offset:C}]of Object.entries(d))x[b]=i(_,u+C);return x}return Yo(o,n,u)}var y};return{views:i(s,r),arrayBuffer:n}}function kn(s,e){if(s!==void 0)if($o(e)){const t=e;if(t.length===1&&typeof s=="number")t[0]=s;else if(Array.isArray(s[0])||$o(s[0])){const r=s[0].length,n=r===3?4:r;for(let i=0;i{kn(r,t[n])})}else{const t=e;for(const[r,n]of Object.entries(s)){const i=t[r];i&&kn(n,i)}}}function vt(s,e,t=0){const r=s,n=kl(r.group===void 0?s:r.typeDefinition,0,t);return{...n,set(i){kn(i,n.views)}}}function Nn(s){const e=s.elementType;if(e)return Nn(e);const t=s.fields;if(t)return Object.values(t).reduce((i,{type:o})=>Math.max(i,Nn(o)),0);const{type:r}=s,{align:n}=rr[r];return n}function Wo(s){const e=s.elementType;if(e){const r=e.size,n=Nn(e);return{unalignedSize:r,align:n,size:Un(r,n)}}const t=s.fields;if(t){const r=Object.values(t).pop();if(r.type.size===0)return Wo(r.type)}return{size:0,unalignedSize:0,align:1}}(function(s=[],e){const t=new Set;for(const r of Ul){const n=rr[r];t.has(n)||(t.add(n),n.flatten=s.includes(r)?e:!e)}})();class Nl{constructor(){this.constants=new Map,this.aliases=new Map,this.structs=new Map}}let dt=class{constructor(){}get isAstNode(){return!0}get astNodeType(){return""}evaluate(s){throw new Error("Cannot evaluate node")}evaluateString(s){return this.evaluate(s).toString()}search(s){}searchBlock(s,e){if(s){e(ls.instance);for(const t of s)t instanceof Array?this.searchBlock(t,e):t.search(e);e(ds.instance)}}};class ls extends dt{}ls.instance=new ls;class ds extends dt{}ds.instance=new ds;class he extends dt{constructor(){super()}}let Vn=class extends he{constructor(s,e,t,r,n,i){super(),this.calls=new Set,this.name=s,this.args=e,this.returnType=t,this.body=r,this.startLine=n,this.endLine=i}get astNodeType(){return"function"}search(s){this.searchBlock(this.body,s)}};class Vl extends he{constructor(e){super(),this.expression=e}get astNodeType(){return"staticAssert"}search(e){this.expression.search(e)}}class Hl extends he{constructor(e,t){super(),this.condition=e,this.body=t}get astNodeType(){return"while"}search(e){this.condition.search(e),this.searchBlock(this.body,e)}}class Jl extends he{constructor(e){super(),this.body=e}get astNodeType(){return"continuing"}search(e){this.searchBlock(this.body,e)}}class zl extends he{constructor(e,t,r,n){super(),this.init=e,this.condition=t,this.increment=r,this.body=n}get astNodeType(){return"for"}search(e){var t,r,n;(t=this.init)===null||t===void 0||t.search(e),(r=this.condition)===null||r===void 0||r.search(e),(n=this.increment)===null||n===void 0||n.search(e),this.searchBlock(this.body,e)}}class Dt extends he{constructor(e,t,r,n,i){super(),this.name=e,this.type=t,this.storage=r,this.access=n,this.value=i}get astNodeType(){return"var"}search(e){var t;e(this),(t=this.value)===null||t===void 0||t.search(e)}}class qo extends he{constructor(e,t,r){super(),this.name=e,this.type=t,this.value=r}get astNodeType(){return"override"}search(e){var t;(t=this.value)===null||t===void 0||t.search(e)}}class Hn extends he{constructor(e,t,r,n,i){super(),this.name=e,this.type=t,this.storage=r,this.access=n,this.value=i}get astNodeType(){return"let"}search(e){var t;e(this),(t=this.value)===null||t===void 0||t.search(e)}}class Qo extends he{constructor(e,t,r,n,i){super(),this.name=e,this.type=t,this.storage=r,this.access=n,this.value=i}get astNodeType(){return"const"}evaluate(e){return this.value.evaluate(e)}search(e){var t;e(this),(t=this.value)===null||t===void 0||t.search(e)}}var sr,Er,G,E,xe;(function(s){s.increment="++",s.decrement="--"})(sr||(sr={})),function(s){s.parse=function(e){const t=e;if(t=="parse")throw new Error("Invalid value for IncrementOperator");return s[t]}}(sr||(sr={}));class jl extends he{constructor(e,t){super(),this.operator=e,this.variable=t}get astNodeType(){return"increment"}search(e){this.variable.search(e)}}(function(s){s.assign="=",s.addAssign="+=",s.subtractAssin="-=",s.multiplyAssign="*=",s.divideAssign="/=",s.moduloAssign="%=",s.andAssign="&=",s.orAssign="|=",s.xorAssign="^=",s.shiftLeftAssign="<<=",s.shiftRightAssign=">>="})(Er||(Er={})),function(s){s.parse=function(e){const t=e;if(t=="parse")throw new Error("Invalid value for AssignOperator");return t}}(Er||(Er={}));class Kl extends he{constructor(e,t,r){super(),this.operator=e,this.variable=t,this.value=r}get astNodeType(){return"assign"}search(e){this.variable.search(e),this.value.search(e)}}class Zo extends he{constructor(e,t){super(),this.name=e,this.args=t}get astNodeType(){return"call"}search(e){for(const t of this.args)t.search(e);e(this)}}class $l extends he{constructor(e,t){super(),this.body=e,this.continuing=t}get astNodeType(){return"loop"}}class Xl extends he{constructor(e,t){super(),this.condition=e,this.body=t}get astNodeType(){return"body"}}class Yl extends he{constructor(e,t,r,n){super(),this.condition=e,this.body=t,this.elseif=r,this.else=n}get astNodeType(){return"if"}search(e){this.condition.search(e),this.searchBlock(this.body,e),this.searchBlock(this.elseif,e),this.searchBlock(this.else,e)}}class Wl extends he{constructor(e){super(),this.value=e}get astNodeType(){return"return"}search(e){var t;(t=this.value)===null||t===void 0||t.search(e)}}class ql extends he{constructor(e){super(),this.name=e}get astNodeType(){return"enable"}}class Ql extends he{constructor(e){super(),this.extensions=e}get astNodeType(){return"requires"}}class Zl extends he{constructor(e,t){super(),this.severity=e,this.rule=t}get astNodeType(){return"diagnostic"}}class ea extends he{constructor(e,t){super(),this.name=e,this.type=t}get astNodeType(){return"alias"}}class ed extends he{constructor(){super()}get astNodeType(){return"discard"}}class td extends he{constructor(){super()}get astNodeType(){return"break"}}class rd extends he{constructor(){super()}get astNodeType(){return"continue"}}class Ft extends he{constructor(e){super(),this.name=e}get astNodeType(){return"type"}get isStruct(){return!1}get isArray(){return!1}}class Ut extends Ft{constructor(e,t,r,n){super(e),this.members=t,this.startLine=r,this.endLine=n}get astNodeType(){return"struct"}get isStruct(){return!0}getMemberIndex(e){for(let t=0;t":return this.left.evaluate(e)>this.right.evaluate(e)?1:0;case"<=":return this.left.evaluate(e)<=this.right.evaluate(e)?1:0;case">=":return this.left.evaluate(e)>=this.right.evaluate(e)?1:0;case"&&":return this.left.evaluate(e)&&this.right.evaluate(e)?1:0;case"||":return this.left.evaluate(e)||this.right.evaluate(e)?1:0;default:throw new Error(`Unknown operator ${this.operator}`)}}search(e){this.left.search(e),this.right.search(e)}}class ca extends dt{constructor(){super()}}class ud extends ca{constructor(e,t){super(),this.selector=e,this.body=t}get astNodeType(){return"case"}search(e){this.searchBlock(this.body,e)}}class cd extends ca{constructor(e){super(),this.body=e}get astNodeType(){return"default"}search(e){this.searchBlock(this.body,e)}}class ld extends dt{constructor(e,t,r){super(),this.name=e,this.type=t,this.attributes=r}get astNodeType(){return"argument"}}class dd extends dt{constructor(e,t){super(),this.condition=e,this.body=t}get astNodeType(){return"elseif"}search(e){this.condition.search(e),this.searchBlock(this.body,e)}}class hd extends dt{constructor(e,t,r){super(),this.name=e,this.type=t,this.attributes=r}get astNodeType(){return"member"}}class la extends dt{constructor(e,t){super(),this.name=e,this.value=t}get astNodeType(){return"attribute"}}(function(s){s[s.token=0]="token",s[s.keyword=1]="keyword",s[s.reserved=2]="reserved"})(E||(E={}));class M{constructor(e,t,r){this.name=e,this.type=t,this.rule=r}toString(){return this.name}}class v{}G=v,v.none=new M("",E.reserved,""),v.eof=new M("EOF",E.token,""),v.reserved={asm:new M("asm",E.reserved,"asm"),bf16:new M("bf16",E.reserved,"bf16"),do:new M("do",E.reserved,"do"),enum:new M("enum",E.reserved,"enum"),f16:new M("f16",E.reserved,"f16"),f64:new M("f64",E.reserved,"f64"),handle:new M("handle",E.reserved,"handle"),i8:new M("i8",E.reserved,"i8"),i16:new M("i16",E.reserved,"i16"),i64:new M("i64",E.reserved,"i64"),mat:new M("mat",E.reserved,"mat"),premerge:new M("premerge",E.reserved,"premerge"),regardless:new M("regardless",E.reserved,"regardless"),typedef:new M("typedef",E.reserved,"typedef"),u8:new M("u8",E.reserved,"u8"),u16:new M("u16",E.reserved,"u16"),u64:new M("u64",E.reserved,"u64"),unless:new M("unless",E.reserved,"unless"),using:new M("using",E.reserved,"using"),vec:new M("vec",E.reserved,"vec"),void:new M("void",E.reserved,"void")},v.keywords={array:new M("array",E.keyword,"array"),atomic:new M("atomic",E.keyword,"atomic"),bool:new M("bool",E.keyword,"bool"),f32:new M("f32",E.keyword,"f32"),i32:new M("i32",E.keyword,"i32"),mat2x2:new M("mat2x2",E.keyword,"mat2x2"),mat2x3:new M("mat2x3",E.keyword,"mat2x3"),mat2x4:new M("mat2x4",E.keyword,"mat2x4"),mat3x2:new M("mat3x2",E.keyword,"mat3x2"),mat3x3:new M("mat3x3",E.keyword,"mat3x3"),mat3x4:new M("mat3x4",E.keyword,"mat3x4"),mat4x2:new M("mat4x2",E.keyword,"mat4x2"),mat4x3:new M("mat4x3",E.keyword,"mat4x3"),mat4x4:new M("mat4x4",E.keyword,"mat4x4"),ptr:new M("ptr",E.keyword,"ptr"),sampler:new M("sampler",E.keyword,"sampler"),sampler_comparison:new M("sampler_comparison",E.keyword,"sampler_comparison"),struct:new M("struct",E.keyword,"struct"),texture_1d:new M("texture_1d",E.keyword,"texture_1d"),texture_2d:new M("texture_2d",E.keyword,"texture_2d"),texture_2d_array:new M("texture_2d_array",E.keyword,"texture_2d_array"),texture_3d:new M("texture_3d",E.keyword,"texture_3d"),texture_cube:new M("texture_cube",E.keyword,"texture_cube"),texture_cube_array:new M("texture_cube_array",E.keyword,"texture_cube_array"),texture_multisampled_2d:new M("texture_multisampled_2d",E.keyword,"texture_multisampled_2d"),texture_storage_1d:new M("texture_storage_1d",E.keyword,"texture_storage_1d"),texture_storage_2d:new M("texture_storage_2d",E.keyword,"texture_storage_2d"),texture_storage_2d_array:new M("texture_storage_2d_array",E.keyword,"texture_storage_2d_array"),texture_storage_3d:new M("texture_storage_3d",E.keyword,"texture_storage_3d"),texture_depth_2d:new M("texture_depth_2d",E.keyword,"texture_depth_2d"),texture_depth_2d_array:new M("texture_depth_2d_array",E.keyword,"texture_depth_2d_array"),texture_depth_cube:new M("texture_depth_cube",E.keyword,"texture_depth_cube"),texture_depth_cube_array:new M("texture_depth_cube_array",E.keyword,"texture_depth_cube_array"),texture_depth_multisampled_2d:new M("texture_depth_multisampled_2d",E.keyword,"texture_depth_multisampled_2d"),texture_external:new M("texture_external",E.keyword,"texture_external"),u32:new M("u32",E.keyword,"u32"),vec2:new M("vec2",E.keyword,"vec2"),vec3:new M("vec3",E.keyword,"vec3"),vec4:new M("vec4",E.keyword,"vec4"),bitcast:new M("bitcast",E.keyword,"bitcast"),block:new M("block",E.keyword,"block"),break:new M("break",E.keyword,"break"),case:new M("case",E.keyword,"case"),continue:new M("continue",E.keyword,"continue"),continuing:new M("continuing",E.keyword,"continuing"),default:new M("default",E.keyword,"default"),diagnostic:new M("diagnostic",E.keyword,"diagnostic"),discard:new M("discard",E.keyword,"discard"),else:new M("else",E.keyword,"else"),enable:new M("enable",E.keyword,"enable"),fallthrough:new M("fallthrough",E.keyword,"fallthrough"),false:new M("false",E.keyword,"false"),fn:new M("fn",E.keyword,"fn"),for:new M("for",E.keyword,"for"),function:new M("function",E.keyword,"function"),if:new M("if",E.keyword,"if"),let:new M("let",E.keyword,"let"),const:new M("const",E.keyword,"const"),loop:new M("loop",E.keyword,"loop"),while:new M("while",E.keyword,"while"),private:new M("private",E.keyword,"private"),read:new M("read",E.keyword,"read"),read_write:new M("read_write",E.keyword,"read_write"),return:new M("return",E.keyword,"return"),requires:new M("requires",E.keyword,"requires"),storage:new M("storage",E.keyword,"storage"),switch:new M("switch",E.keyword,"switch"),true:new M("true",E.keyword,"true"),alias:new M("alias",E.keyword,"alias"),type:new M("type",E.keyword,"type"),uniform:new M("uniform",E.keyword,"uniform"),var:new M("var",E.keyword,"var"),override:new M("override",E.keyword,"override"),workgroup:new M("workgroup",E.keyword,"workgroup"),write:new M("write",E.keyword,"write"),r8unorm:new M("r8unorm",E.keyword,"r8unorm"),r8snorm:new M("r8snorm",E.keyword,"r8snorm"),r8uint:new M("r8uint",E.keyword,"r8uint"),r8sint:new M("r8sint",E.keyword,"r8sint"),r16uint:new M("r16uint",E.keyword,"r16uint"),r16sint:new M("r16sint",E.keyword,"r16sint"),r16float:new M("r16float",E.keyword,"r16float"),rg8unorm:new M("rg8unorm",E.keyword,"rg8unorm"),rg8snorm:new M("rg8snorm",E.keyword,"rg8snorm"),rg8uint:new M("rg8uint",E.keyword,"rg8uint"),rg8sint:new M("rg8sint",E.keyword,"rg8sint"),r32uint:new M("r32uint",E.keyword,"r32uint"),r32sint:new M("r32sint",E.keyword,"r32sint"),r32float:new M("r32float",E.keyword,"r32float"),rg16uint:new M("rg16uint",E.keyword,"rg16uint"),rg16sint:new M("rg16sint",E.keyword,"rg16sint"),rg16float:new M("rg16float",E.keyword,"rg16float"),rgba8unorm:new M("rgba8unorm",E.keyword,"rgba8unorm"),rgba8unorm_srgb:new M("rgba8unorm_srgb",E.keyword,"rgba8unorm_srgb"),rgba8snorm:new M("rgba8snorm",E.keyword,"rgba8snorm"),rgba8uint:new M("rgba8uint",E.keyword,"rgba8uint"),rgba8sint:new M("rgba8sint",E.keyword,"rgba8sint"),bgra8unorm:new M("bgra8unorm",E.keyword,"bgra8unorm"),bgra8unorm_srgb:new M("bgra8unorm_srgb",E.keyword,"bgra8unorm_srgb"),rgb10a2unorm:new M("rgb10a2unorm",E.keyword,"rgb10a2unorm"),rg11b10float:new M("rg11b10float",E.keyword,"rg11b10float"),rg32uint:new M("rg32uint",E.keyword,"rg32uint"),rg32sint:new M("rg32sint",E.keyword,"rg32sint"),rg32float:new M("rg32float",E.keyword,"rg32float"),rgba16uint:new M("rgba16uint",E.keyword,"rgba16uint"),rgba16sint:new M("rgba16sint",E.keyword,"rgba16sint"),rgba16float:new M("rgba16float",E.keyword,"rgba16float"),rgba32uint:new M("rgba32uint",E.keyword,"rgba32uint"),rgba32sint:new M("rgba32sint",E.keyword,"rgba32sint"),rgba32float:new M("rgba32float",E.keyword,"rgba32float"),static_assert:new M("static_assert",E.keyword,"static_assert")},v.tokens={decimal_float_literal:new M("decimal_float_literal",E.token,/((-?[0-9]*\.[0-9]+|-?[0-9]+\.[0-9]*)((e|E)(\+|-)?[0-9]+)?f?)|(-?[0-9]+(e|E)(\+|-)?[0-9]+f?)|([0-9]+f)/),hex_float_literal:new M("hex_float_literal",E.token,/-?0x((([0-9a-fA-F]*\.[0-9a-fA-F]+|[0-9a-fA-F]+\.[0-9a-fA-F]*)((p|P)(\+|-)?[0-9]+f?)?)|([0-9a-fA-F]+(p|P)(\+|-)?[0-9]+f?))/),int_literal:new M("int_literal",E.token,/-?0x[0-9a-fA-F]+|0i?|-?[1-9][0-9]*i?/),uint_literal:new M("uint_literal",E.token,/0x[0-9a-fA-F]+u|0u|[1-9][0-9]*u/),ident:new M("ident",E.token,/[_a-zA-Z][0-9a-zA-Z_]*/),and:new M("and",E.token,"&"),and_and:new M("and_and",E.token,"&&"),arrow:new M("arrow ",E.token,"->"),attr:new M("attr",E.token,"@"),attr_left:new M("attr_left",E.token,"[["),attr_right:new M("attr_right",E.token,"]]"),forward_slash:new M("forward_slash",E.token,"/"),bang:new M("bang",E.token,"!"),bracket_left:new M("bracket_left",E.token,"["),bracket_right:new M("bracket_right",E.token,"]"),brace_left:new M("brace_left",E.token,"{"),brace_right:new M("brace_right",E.token,"}"),colon:new M("colon",E.token,":"),comma:new M("comma",E.token,","),equal:new M("equal",E.token,"="),equal_equal:new M("equal_equal",E.token,"=="),not_equal:new M("not_equal",E.token,"!="),greater_than:new M("greater_than",E.token,">"),greater_than_equal:new M("greater_than_equal",E.token,">="),shift_right:new M("shift_right",E.token,">>"),less_than:new M("less_than",E.token,"<"),less_than_equal:new M("less_than_equal",E.token,"<="),shift_left:new M("shift_left",E.token,"<<"),modulo:new M("modulo",E.token,"%"),minus:new M("minus",E.token,"-"),minus_minus:new M("minus_minus",E.token,"--"),period:new M("period",E.token,"."),plus:new M("plus",E.token,"+"),plus_plus:new M("plus_plus",E.token,"++"),or:new M("or",E.token,"|"),or_or:new M("or_or",E.token,"||"),paren_left:new M("paren_left",E.token,"("),paren_right:new M("paren_right",E.token,")"),semicolon:new M("semicolon",E.token,";"),star:new M("star",E.token,"*"),tilde:new M("tilde",E.token,"~"),underscore:new M("underscore",E.token,"_"),xor:new M("xor",E.token,"^"),plus_equal:new M("plus_equal",E.token,"+="),minus_equal:new M("minus_equal",E.token,"-="),times_equal:new M("times_equal",E.token,"*="),division_equal:new M("division_equal",E.token,"/="),modulo_equal:new M("modulo_equal",E.token,"%="),and_equal:new M("and_equal",E.token,"&="),or_equal:new M("or_equal",E.token,"|="),xor_equal:new M("xor_equal",E.token,"^="),shift_right_equal:new M("shift_right_equal",E.token,">>="),shift_left_equal:new M("shift_left_equal",E.token,"<<=")},v.simpleTokens={"@":G.tokens.attr,"{":G.tokens.brace_left,"}":G.tokens.brace_right,":":G.tokens.colon,",":G.tokens.comma,"(":G.tokens.paren_left,")":G.tokens.paren_right,";":G.tokens.semicolon},v.literalTokens={"&":G.tokens.and,"&&":G.tokens.and_and,"->":G.tokens.arrow,"[[":G.tokens.attr_left,"]]":G.tokens.attr_right,"/":G.tokens.forward_slash,"!":G.tokens.bang,"[":G.tokens.bracket_left,"]":G.tokens.bracket_right,"=":G.tokens.equal,"==":G.tokens.equal_equal,"!=":G.tokens.not_equal,">":G.tokens.greater_than,">=":G.tokens.greater_than_equal,">>":G.tokens.shift_right,"<":G.tokens.less_than,"<=":G.tokens.less_than_equal,"<<":G.tokens.shift_left,"%":G.tokens.modulo,"-":G.tokens.minus,"--":G.tokens.minus_minus,".":G.tokens.period,"+":G.tokens.plus,"++":G.tokens.plus_plus,"|":G.tokens.or,"||":G.tokens.or_or,"*":G.tokens.star,"~":G.tokens.tilde,_:G.tokens.underscore,"^":G.tokens.xor,"+=":G.tokens.plus_equal,"-=":G.tokens.minus_equal,"*=":G.tokens.times_equal,"/=":G.tokens.division_equal,"%=":G.tokens.modulo_equal,"&=":G.tokens.and_equal,"|=":G.tokens.or_equal,"^=":G.tokens.xor_equal,">>=":G.tokens.shift_right_equal,"<<=":G.tokens.shift_left_equal},v.regexTokens={decimal_float_literal:G.tokens.decimal_float_literal,hex_float_literal:G.tokens.hex_float_literal,int_literal:G.tokens.int_literal,uint_literal:G.tokens.uint_literal,ident:G.tokens.ident},v.storage_class=[G.keywords.function,G.keywords.private,G.keywords.workgroup,G.keywords.uniform,G.keywords.storage],v.access_mode=[G.keywords.read,G.keywords.write,G.keywords.read_write],v.sampler_type=[G.keywords.sampler,G.keywords.sampler_comparison],v.sampled_texture_type=[G.keywords.texture_1d,G.keywords.texture_2d,G.keywords.texture_2d_array,G.keywords.texture_3d,G.keywords.texture_cube,G.keywords.texture_cube_array],v.multisampled_texture_type=[G.keywords.texture_multisampled_2d],v.storage_texture_type=[G.keywords.texture_storage_1d,G.keywords.texture_storage_2d,G.keywords.texture_storage_2d_array,G.keywords.texture_storage_3d],v.depth_texture_type=[G.keywords.texture_depth_2d,G.keywords.texture_depth_2d_array,G.keywords.texture_depth_cube,G.keywords.texture_depth_cube_array,G.keywords.texture_depth_multisampled_2d],v.texture_external_type=[G.keywords.texture_external],v.any_texture_type=[...G.sampled_texture_type,...G.multisampled_texture_type,...G.storage_texture_type,...G.depth_texture_type,...G.texture_external_type],v.texel_format=[G.keywords.r8unorm,G.keywords.r8snorm,G.keywords.r8uint,G.keywords.r8sint,G.keywords.r16uint,G.keywords.r16sint,G.keywords.r16float,G.keywords.rg8unorm,G.keywords.rg8snorm,G.keywords.rg8uint,G.keywords.rg8sint,G.keywords.r32uint,G.keywords.r32sint,G.keywords.r32float,G.keywords.rg16uint,G.keywords.rg16sint,G.keywords.rg16float,G.keywords.rgba8unorm,G.keywords.rgba8unorm_srgb,G.keywords.rgba8snorm,G.keywords.rgba8uint,G.keywords.rgba8sint,G.keywords.bgra8unorm,G.keywords.bgra8unorm_srgb,G.keywords.rgb10a2unorm,G.keywords.rg11b10float,G.keywords.rg32uint,G.keywords.rg32sint,G.keywords.rg32float,G.keywords.rgba16uint,G.keywords.rgba16sint,G.keywords.rgba16float,G.keywords.rgba32uint,G.keywords.rgba32sint,G.keywords.rgba32float],v.const_literal=[G.tokens.int_literal,G.tokens.uint_literal,G.tokens.decimal_float_literal,G.tokens.hex_float_literal,G.keywords.true,G.keywords.false],v.literal_or_ident=[G.tokens.ident,G.tokens.int_literal,G.tokens.uint_literal,G.tokens.decimal_float_literal,G.tokens.hex_float_literal],v.element_count_expression=[G.tokens.int_literal,G.tokens.uint_literal,G.tokens.ident],v.template_types=[G.keywords.vec2,G.keywords.vec3,G.keywords.vec4,G.keywords.mat2x2,G.keywords.mat2x3,G.keywords.mat2x4,G.keywords.mat3x2,G.keywords.mat3x3,G.keywords.mat3x4,G.keywords.mat4x2,G.keywords.mat4x3,G.keywords.mat4x4,G.keywords.atomic,G.keywords.bitcast,...G.any_texture_type],v.attribute_name=[G.tokens.ident,G.keywords.block,G.keywords.diagnostic],v.assignment_operators=[G.tokens.equal,G.tokens.plus_equal,G.tokens.minus_equal,G.tokens.times_equal,G.tokens.division_equal,G.tokens.modulo_equal,G.tokens.and_equal,G.tokens.or_equal,G.tokens.xor_equal,G.tokens.shift_right_equal,G.tokens.shift_left_equal],v.increment_operators=[G.tokens.plus_plus,G.tokens.minus_minus];class da{constructor(e,t,r){this.type=e,this.lexeme=t,this.line=r}toString(){return this.lexeme}isTemplateType(){return v.template_types.indexOf(this.type)!=-1}isArrayType(){return this.type==v.keywords.array}isArrayOrTemplateType(){return this.isArrayType()||this.isTemplateType()}}class fd{constructor(e){this._tokens=[],this._start=0,this._current=0,this._line=1,this._source=e??""}scanTokens(){for(;!this._isAtEnd();)if(this._start=this._current,!this.scanToken())throw`Invalid syntax at line ${this._line}`;return this._tokens.push(new da(v.eof,"",this._line)),this._tokens}scanToken(){let e=this._advance();if(e==` +`)return this._line++,!0;if(this._isWhitespace(e))return!0;if(e=="/"){if(this._peekAhead()=="/"){for(;e!=` +`;){if(this._isAtEnd())return!0;e=this._advance()}return this._line++,!0}if(this._peekAhead()=="*"){this._advance();let o=1;for(;o>0;){if(this._isAtEnd())return!0;if(e=this._advance(),e==` +`)this._line++;else if(e=="*"){if(this._peekAhead()=="/"&&(this._advance(),o--,o==0))return!0}else e=="/"&&this._peekAhead()=="*"&&(this._advance(),o++)}return!0}}const t=v.simpleTokens[e];if(t)return this._addToken(t),!0;let r=v.none;const n=this._isAlpha(e),i=e==="_";if(this._isAlphaNumeric(e)){let o=this._peekAhead();for(;this._isAlphaNumeric(o);)e+=this._advance(),o=this._peekAhead()}if(n){const o=v.keywords[e];if(o)return this._addToken(o),!0}if(n||i)return this._addToken(v.tokens.ident),!0;for(;;){let o=this._findType(e);const u=this._peekAhead();if(e==">"&&(u==">"||u=="=")){let l=!1,m=this._tokens.length-1;for(let y=0;y<5&&m>=0;++y,--m)if(this._tokens[m].type===v.tokens.less_than){m>0&&this._tokens[m-1].isArrayOrTemplateType()&&(l=!0);break}if(l)return this._addToken(o),!0}if(o===v.none){let l=e,m=0;const y=2;for(let d=0;d=this._source.length}_isAlpha(e){return e>="a"&&e<="z"||e>="A"&&e<="Z"}_isAlphaNumeric(e){return e>="a"&&e<="z"||e>="A"&&e<="Z"||e=="_"||e>="0"&&e<="9"}_isWhitespace(e){return e==" "||e==" "||e=="\r"}_advance(e=0){let t=this._source[this._current];return e=e||0,e++,this._current+=e,t}_peekAhead(e=0){return e=e||0,this._current+e>=this._source.length?"\0":this._source[this._current+e]}_addToken(e){const t=this._source.substring(this._start,this._current);this._tokens.push(new da(e,t,this._line))}}class pd{constructor(){this._tokens=[],this._current=0,this._currentLine=0,this._context=new Nl,this._deferArrayCountEval=[]}parse(e){this._initialize(e),this._deferArrayCountEval.length=0;const t=[];for(;!this._isAtEnd();){const r=this._global_decl_or_directive();if(!r)break;t.push(r)}if(this._deferArrayCountEval.length>0){for(const r of this._deferArrayCountEval){const n=r.arrayType,i=r.countNode;if(i instanceof Jn){const o=i.name,u=this._context.constants.get(o);if(u)try{const l=u.evaluate(this._context);n.count=l}catch{}}}this._deferArrayCountEval.length=0}return t}_initialize(e){if(e)if(typeof e=="string"){const t=new fd(e);this._tokens=t.scanTokens()}else this._tokens=e;else this._tokens=[];this._current=0}_error(e,t){return{token:e,message:t,toString:function(){return`${t}`}}}_isAtEnd(){return this._current>=this._tokens.length||this._peek().type==v.eof}_match(e){if(e instanceof M)return!!this._check(e)&&(this._advance(),!0);for(let t=0,r=e.length;t'.");const n=this._paren_expression();return new nd(r,n)}const e=this._type_decl(),t=this._argument_expression_list();return new id(e,t)}_argument_expression_list(){if(!this._match(v.tokens.paren_left))return null;const e=[];do{if(this._check(v.tokens.paren_right))break;const t=this._short_circuit_or_expression();e.push(t)}while(this._match(v.tokens.comma));return this._consume(v.tokens.paren_right,"Expected ')' for agument list"),e}_optional_paren_expression(){this._match(v.tokens.paren_left);const e=this._short_circuit_or_expression();return this._match(v.tokens.paren_right),new aa([e])}_paren_expression(){this._consume(v.tokens.paren_left,"Expected '('.");const e=this._short_circuit_or_expression();return this._consume(v.tokens.paren_right,"Expected ')'."),new aa([e])}_struct_decl(){if(!this._match(v.keywords.struct))return null;const e=this._currentLine,t=this._consume(v.tokens.ident,"Expected name for struct.").toString();this._consume(v.tokens.brace_left,"Expected '{' for struct body.");const r=[];for(;!this._check(v.tokens.brace_right);){const o=this._attribute(),u=this._consume(v.tokens.ident,"Expected variable name.").toString();this._consume(v.tokens.colon,"Expected ':' for struct member type.");const l=this._attribute(),m=this._type_decl();m!=null&&(m.attributes=l),this._check(v.tokens.brace_right)?this._match(v.tokens.comma):this._consume(v.tokens.comma,"Expected ',' for struct member."),r.push(new hd(u,m,o))}this._consume(v.tokens.brace_right,"Expected '}' after struct body.");const n=this._currentLine,i=new Ut(t,r,e,n);return this._context.structs.set(t,i),i}_global_variable_decl(){const e=this._variable_decl();return e&&this._match(v.tokens.equal)&&(e.value=this._const_expression()),e}_override_variable_decl(){const e=this._override_decl();return e&&this._match(v.tokens.equal)&&(e.value=this._const_expression()),e}_global_const_decl(){if(!this._match(v.keywords.const))return null;const e=this._consume(v.tokens.ident,"Expected variable name");let t=null;if(this._match(v.tokens.colon)){const i=this._attribute();t=this._type_decl(),t!=null&&(t.attributes=i)}let r=null;if(this._match(v.tokens.equal)){const i=this._short_circuit_or_expression();if(i instanceof nr)r=i;else if(i instanceof ia&&i.initializer instanceof nr)r=i.initializer;else try{const o=i.evaluate(this._context);r=new oa(o)}catch{r=i}}const n=new Qo(e.toString(),t,"","",r);return this._context.constants.set(n.name,n),n}_global_let_decl(){if(!this._match(v.keywords.let))return null;const e=this._consume(v.tokens.ident,"Expected variable name");let t=null;if(this._match(v.tokens.colon)){const n=this._attribute();t=this._type_decl(),t!=null&&(t.attributes=n)}let r=null;return this._match(v.tokens.equal)&&(r=this._const_expression()),new Hn(e.toString(),t,"","",r)}_const_expression(){if(this._match(v.const_literal))return new sa(this._previous().toString());const e=this._type_decl();this._consume(v.tokens.paren_left,"Expected '('.");let t=[];for(;!this._check(v.tokens.paren_right)&&(t.push(this._const_expression()),this._check(v.tokens.comma));)this._advance();return this._consume(v.tokens.paren_right,"Expected ')'."),new nr(e,t)}_variable_decl(){if(!this._match(v.keywords.var))return null;let e="",t="";this._match(v.tokens.less_than)&&(e=this._consume(v.storage_class,"Expected storage_class.").toString(),this._match(v.tokens.comma)&&(t=this._consume(v.access_mode,"Expected access_mode.").toString()),this._consume(v.tokens.greater_than,"Expected '>'."));const r=this._consume(v.tokens.ident,"Expected variable name");let n=null;if(this._match(v.tokens.colon)){const i=this._attribute();n=this._type_decl(),n!=null&&(n.attributes=i)}return new Dt(r.toString(),n,e,t,null)}_override_decl(){if(!this._match(v.keywords.override))return null;const e=this._consume(v.tokens.ident,"Expected variable name");let t=null;if(this._match(v.tokens.colon)){const r=this._attribute();t=this._type_decl(),t!=null&&(t.attributes=r)}return new qo(e.toString(),t,null)}_diagnostic(){this._consume(v.tokens.paren_left,"Expected '('");const e=this._consume(v.tokens.ident,"Expected severity control name.");this._consume(v.tokens.comma,"Expected ','");const t=this._consume(v.tokens.ident,"Expected diagnostic rule name.");return this._consume(v.tokens.paren_right,"Expected ')'"),new Zl(e.toString(),t.toString())}_enable_directive(){const e=this._consume(v.tokens.ident,"identity expected.");return new ql(e.toString())}_requires_directive(){const e=[this._consume(v.tokens.ident,"identity expected.").toString()];for(;this._match(v.tokens.comma);){const t=this._consume(v.tokens.ident,"identity expected.");e.push(t.toString())}return new Ql(e)}_type_alias(){const e=this._consume(v.tokens.ident,"identity expected.");this._consume(v.tokens.equal,"Expected '=' for type alias.");let t=this._type_decl();if(t===null)throw this._error(this._peek(),"Expected Type for Alias.");this._context.aliases.has(t.name)&&(t=this._context.aliases.get(t.name).type);const r=new ea(e.toString(),t);return this._context.aliases.set(r.name,r),r}_type_decl(){if(this._check([v.tokens.ident,...v.texel_format,v.keywords.bool,v.keywords.f32,v.keywords.i32,v.keywords.u32])){const r=this._advance(),n=r.toString();return this._context.structs.has(n)?this._context.structs.get(n):this._context.aliases.has(n)?this._context.aliases.get(n).type:new Ft(r.toString())}let e=this._texture_sampler_types();if(e)return e;if(this._check(v.template_types)){let r=this._advance().toString(),n=null,i=null;return this._match(v.tokens.less_than)&&(n=this._type_decl(),i=null,this._match(v.tokens.comma)&&(i=this._consume(v.access_mode,"Expected access_mode for pointer").toString()),this._consume(v.tokens.greater_than,"Expected '>' for type.")),new ta(r,n,i)}if(this._match(v.keywords.ptr)){let r=this._previous().toString();this._consume(v.tokens.less_than,"Expected '<' for pointer.");const n=this._consume(v.storage_class,"Expected storage_class for pointer");this._consume(v.tokens.comma,"Expected ',' for pointer.");const i=this._type_decl();let o=null;return this._match(v.tokens.comma)&&(o=this._consume(v.access_mode,"Expected access_mode for pointer").toString()),this._consume(v.tokens.greater_than,"Expected '>' for pointer."),new sd(r,n.toString(),i,o)}const t=this._attribute();if(this._match(v.keywords.array)){let r=null,n=-1;const i=this._previous();let o=null;if(this._match(v.tokens.less_than)){r=this._type_decl(),this._context.aliases.has(r.name)&&(r=this._context.aliases.get(r.name).type);let l="";if(this._match(v.tokens.comma)){o=this._shift_expression();try{l=o.evaluate(this._context).toString(),o=null}catch{l="1"}}this._consume(v.tokens.greater_than,"Expected '>' for array."),n=l?parseInt(l):0}const u=new ra(i.toString(),t,r,n);return o&&this._deferArrayCountEval.push({arrayType:u,countNode:o}),u}return null}_texture_sampler_types(){if(this._match(v.sampler_type))return new Mr(this._previous().toString(),null,null);if(this._match(v.depth_texture_type))return new Mr(this._previous().toString(),null,null);if(this._match(v.sampled_texture_type)||this._match(v.multisampled_texture_type)){const e=this._previous();this._consume(v.tokens.less_than,"Expected '<' for sampler type.");const t=this._type_decl();return this._consume(v.tokens.greater_than,"Expected '>' for sampler type."),new Mr(e.toString(),t,null)}if(this._match(v.storage_texture_type)){const e=this._previous();this._consume(v.tokens.less_than,"Expected '<' for sampler type.");const t=this._consume(v.texel_format,"Invalid texel format.").toString();this._consume(v.tokens.comma,"Expected ',' after texel format.");const r=this._consume(v.access_mode,"Expected access mode for storage texture type.").toString();return this._consume(v.tokens.greater_than,"Expected '>' for sampler type."),new Mr(e.toString(),t,r)}return null}_attribute(){let e=[];for(;this._match(v.tokens.attr);){const t=this._consume(v.attribute_name,"Expected attribute name"),r=new la(t.toString(),null);if(this._match(v.tokens.paren_left)){if(r.value=this._consume(v.literal_or_ident,"Expected attribute value").toString(),this._check(v.tokens.comma)){this._advance();do{const n=this._consume(v.literal_or_ident,"Expected attribute value").toString();r.value instanceof Array||(r.value=[r.value]),r.value.push(n)}while(this._match(v.tokens.comma))}this._consume(v.tokens.paren_right,"Expected ')'")}e.push(r)}for(;this._match(v.tokens.attr_left);){if(!this._check(v.tokens.attr_right))do{const t=this._consume(v.attribute_name,"Expected attribute name"),r=new la(t.toString(),null);if(this._match(v.tokens.paren_left)){if(r.value=[this._consume(v.literal_or_ident,"Expected attribute value").toString()],this._check(v.tokens.comma)){this._advance();do{const n=this._consume(v.literal_or_ident,"Expected attribute value").toString();r.value.push(n)}while(this._match(v.tokens.comma))}this._consume(v.tokens.paren_right,"Expected ')'")}e.push(r)}while(this._match(v.tokens.comma));this._consume(v.tokens.attr_right,"Expected ']]' after attribute declarations")}return e.length==0?null:e}}class ir{constructor(e,t){this.name=e,this.attributes=t,this.size=0}get isArray(){return!1}get isStruct(){return!1}get isTemplate(){return!1}}class ha{constructor(e,t,r){this.name=e,this.type=t,this.attributes=r,this.offset=0,this.size=0}get isArray(){return this.type.isArray}get isStruct(){return this.type.isStruct}get isTemplate(){return this.type.isTemplate}get align(){return this.type.isStruct?this.type.align:0}get members(){return this.type.isStruct?this.type.members:null}get format(){return this.type.isArray||this.type.isTemplate?this.type.format:null}get count(){return this.type.isArray?this.type.count:0}get stride(){return this.type.isArray?this.type.stride:this.size}}class hs extends ir{constructor(e,t){super(e,t),this.members=[],this.align=0,this.startLine=-1,this.endLine=-1,this.inUse=!1}get isStruct(){return!0}}class zn extends ir{constructor(e,t){super(e,t),this.count=0,this.stride=0}get isArray(){return!0}}class fa extends ir{constructor(e,t,r,n){super(e,r),this.format=t,this.access=n}get isTemplate(){return!0}}(function(s){s[s.Uniform=0]="Uniform",s[s.Storage=1]="Storage",s[s.Texture=2]="Texture",s[s.Sampler=3]="Sampler",s[s.StorageTexture=4]="StorageTexture"})(xe||(xe={}));class fs{constructor(e,t,r,n,i,o,u){this.name=e,this.type=t,this.group=r,this.binding=n,this.attributes=i,this.resourceType=o,this.access=u}get isArray(){return this.type.isArray}get isStruct(){return this.type.isStruct}get isTemplate(){return this.type.isTemplate}get size(){return this.type.size}get align(){return this.type.isStruct?this.type.align:0}get members(){return this.type.isStruct?this.type.members:null}get format(){return this.type.isArray||this.type.isTemplate?this.type.format:null}get count(){return this.type.isArray?this.type.count:0}get stride(){return this.type.isArray?this.type.stride:this.size}}class md{constructor(e,t){this.name=e,this.type=t}}class ps{constructor(e,t){this.align=e,this.size=t}}class gd{constructor(e,t,r,n){this.name=e,this.type=t,this.locationType=r,this.location=n,this.interpolation=null}}class pa{constructor(e,t,r,n){this.name=e,this.type=t,this.locationType=r,this.location=n}}class yd{constructor(e,t=null){this.stage=null,this.inputs=[],this.outputs=[],this.resources=[],this.startLine=-1,this.endLine=-1,this.inUse=!1,this.calls=new Set,this.name=e,this.stage=t}}class bd{constructor(){this.vertex=[],this.fragment=[],this.compute=[]}}class xd{constructor(e,t,r,n){this.name=e,this.type=t,this.attributes=r,this.id=n}}class _d{constructor(e){this.resources=null,this.inUse=!1,this.info=null,this.node=e}}class ht{constructor(e){this.uniforms=[],this.storage=[],this.textures=[],this.samplers=[],this.aliases=[],this.overrides=[],this.structs=[],this.entry=new bd,this.functions=[],this._types=new Map,this._functions=new Map,e&&this.update(e)}_isStorageTexture(e){return e.name=="texture_storage_1d"||e.name=="texture_storage_2d"||e.name=="texture_storage_2d_array"||e.name=="texture_storage_3d"}update(e){const t=new pd().parse(e);for(const r of t)r instanceof Vn&&this._functions.set(r.name,new _d(r));for(const r of t)if(r instanceof Ut){const n=this._getTypeInfo(r,null);n instanceof hs&&this.structs.push(n)}for(const r of t)if(r instanceof ea)this.aliases.push(this._getAliasInfo(r));else if(r instanceof qo){const n=r,i=this._getAttributeNum(n.attributes,"id",0),o=n.type!=null?this._getTypeInfo(n.type,n.attributes):null;this.overrides.push(new xd(n.name,o,n.attributes,i))}else if(this._isUniformVar(r)){const n=r,i=this._getAttributeNum(n.attributes,"group",0),o=this._getAttributeNum(n.attributes,"binding",0),u=this._getTypeInfo(n.type,n.attributes),l=new fs(n.name,u,i,o,n.attributes,xe.Uniform,n.access);this.uniforms.push(l)}else if(this._isStorageVar(r)){const n=r,i=this._getAttributeNum(n.attributes,"group",0),o=this._getAttributeNum(n.attributes,"binding",0),u=this._getTypeInfo(n.type,n.attributes),l=this._isStorageTexture(u),m=new fs(n.name,u,i,o,n.attributes,l?xe.StorageTexture:xe.Storage,n.access);this.storage.push(m)}else if(this._isTextureVar(r)){const n=r,i=this._getAttributeNum(n.attributes,"group",0),o=this._getAttributeNum(n.attributes,"binding",0),u=this._getTypeInfo(n.type,n.attributes),l=this._isStorageTexture(u),m=new fs(n.name,u,i,o,n.attributes,l?xe.StorageTexture:xe.Texture,n.access);l?this.storage.push(m):this.textures.push(m)}else if(this._isSamplerVar(r)){const n=r,i=this._getAttributeNum(n.attributes,"group",0),o=this._getAttributeNum(n.attributes,"binding",0),u=this._getTypeInfo(n.type,n.attributes),l=new fs(n.name,u,i,o,n.attributes,xe.Sampler,n.access);this.samplers.push(l)}else if(r instanceof Vn){const n=this._getAttribute(r,"vertex"),i=this._getAttribute(r,"fragment"),o=this._getAttribute(r,"compute"),u=n||i||o,l=new yd(r.name,u==null?void 0:u.name);l.startLine=r.startLine,l.endLine=r.endLine,this.functions.push(l),this._functions.get(r.name).info=l,u&&(this._functions.get(r.name).inUse=!0,l.inUse=!0,l.resources=this._findResources(r,!!u),l.inputs=this._getInputs(r.args),l.outputs=this._getOutputs(r.returnType),this.entry[u.name].push(l))}for(const r of this._functions.values())r.info&&(r.info.inUse=r.inUse,this._addCalls(r.node,r.info.calls));for(const r of this.uniforms)this._markStructsInUse(r.type);for(const r of this.storage)this._markStructsInUse(r.type)}_markStructsInUse(e){if(e.isStruct){e.inUse=!0;for(const t of e.members)this._markStructsInUse(t.type)}else if(e.isArray)this._markStructsInUse(e.format);else if(e.isTemplate)this._markStructsInUse(e.format);else{const t=this._getAlias(e.name);t&&this._markStructsInUse(t)}}_addCalls(e,t){var r;for(const n of e.calls){const i=(r=this._functions.get(n.name))===null||r===void 0?void 0:r.info;i&&t.add(i)}}findResource(e,t){for(const r of this.uniforms)if(r.group==e&&r.binding==t)return r;for(const r of this.storage)if(r.group==e&&r.binding==t)return r;for(const r of this.textures)if(r.group==e&&r.binding==t)return r;for(const r of this.samplers)if(r.group==e&&r.binding==t)return r;return null}_findResource(e){for(const t of this.uniforms)if(t.name==e)return t;for(const t of this.storage)if(t.name==e)return t;for(const t of this.textures)if(t.name==e)return t;for(const t of this.samplers)if(t.name==e)return t;return null}_markStructsFromAST(e){const t=this._getTypeInfo(e,null);this._markStructsInUse(t)}_findResources(e,t){const r=[],n=this,i=[];return e.search(o=>{if(o instanceof ls)i.push({});else if(o instanceof ds)i.pop();else if(o instanceof Dt){const u=o;t&&u.type!==null&&this._markStructsFromAST(u.type),i.length>0&&(i[i.length-1][u.name]=u)}else if(o instanceof nr){const u=o;t&&u.type!==null&&this._markStructsFromAST(u.type)}else if(o instanceof Hn){const u=o;t&&u.type!==null&&this._markStructsFromAST(u.type),i.length>0&&(i[i.length-1][u.name]=u)}else if(o instanceof Jn){const u=o;if(i.length>0&&i[i.length-1][u.name])return;const l=n._findResource(u.name);l&&r.push(l)}else if(o instanceof na){const u=o,l=n._functions.get(u.name);l&&(t&&(l.inUse=!0),e.calls.add(l.node),l.resources===null&&(l.resources=n._findResources(l.node,t)),r.push(...l.resources))}else if(o instanceof Zo){const u=o,l=n._functions.get(u.name);l&&(t&&(l.inUse=!0),e.calls.add(l.node),l.resources===null&&(l.resources=n._findResources(l.node,t)),r.push(...l.resources))}}),[...new Map(r.map(o=>[o.name,o])).values()]}getBindGroups(){const e=[];function t(r,n){r>=e.length&&(e.length=r+1),e[r]===void 0&&(e[r]=[]),n>=e[r].length&&(e[r].length=n+1)}for(const r of this.uniforms)t(r.group,r.binding),e[r.group][r.binding]=r;for(const r of this.storage)t(r.group,r.binding),e[r.group][r.binding]=r;for(const r of this.textures)t(r.group,r.binding),e[r.group][r.binding]=r;for(const r of this.samplers)t(r.group,r.binding),e[r.group][r.binding]=r;return e}_getOutputs(e,t=void 0){if(t===void 0&&(t=[]),e instanceof Ut)this._getStructOutputs(e,t);else{const r=this._getOutputInfo(e);r!==null&&t.push(r)}return t}_getStructOutputs(e,t){for(const r of e.members)if(r.type instanceof Ut)this._getStructOutputs(r.type,t);else{const n=this._getAttribute(r,"location")||this._getAttribute(r,"builtin");if(n!==null){const i=this._getTypeInfo(r.type,r.type.attributes),o=this._parseInt(n.value),u=new pa(r.name,i,n.name,o);t.push(u)}}}_getOutputInfo(e){const t=this._getAttribute(e,"location")||this._getAttribute(e,"builtin");if(t!==null){const r=this._getTypeInfo(e,e.attributes),n=this._parseInt(t.value);return new pa("",r,t.name,n)}return null}_getInputs(e,t=void 0){t===void 0&&(t=[]);for(const r of e)if(r.type instanceof Ut)this._getStructInputs(r.type,t);else{const n=this._getInputInfo(r);n!==null&&t.push(n)}return t}_getStructInputs(e,t){for(const r of e.members)if(r.type instanceof Ut)this._getStructInputs(r.type,t);else{const n=this._getInputInfo(r);n!==null&&t.push(n)}}_getInputInfo(e){const t=this._getAttribute(e,"location")||this._getAttribute(e,"builtin");if(t!==null){const r=this._getAttribute(e,"interpolation"),n=this._getTypeInfo(e.type,e.attributes),i=this._parseInt(t.value),o=new gd(e.name,n,t.name,i);return r!==null&&(o.interpolation=this._parseString(r.value)),o}return null}_parseString(e){return e instanceof Array&&(e=e[0]),e}_parseInt(e){e instanceof Array&&(e=e[0]);const t=parseInt(e);return isNaN(t)?e:t}_getAlias(e){for(const t of this.aliases)if(t.name==e)return t.type;return null}_getAliasInfo(e){return new md(e.name,this._getTypeInfo(e.type,null))}_getTypeInfo(e,t){if(this._types.has(e))return this._types.get(e);if(e instanceof ra){const n=e,i=this._getTypeInfo(n.format,n.attributes),o=new zn(n.name,t);return o.format=i,o.count=n.count,this._types.set(e,o),this._updateTypeInfo(o),o}if(e instanceof Ut){const n=e,i=new hs(n.name,t);i.startLine=n.startLine,i.endLine=n.endLine;for(const o of n.members){const u=this._getTypeInfo(o.type,o.attributes);i.members.push(new ha(o.name,u,o.attributes))}return this._types.set(e,i),this._updateTypeInfo(i),i}if(e instanceof Mr){const n=e,i=n.format instanceof Ft,o=n.format?i?this._getTypeInfo(n.format,null):new ir(n.format,null):null,u=new fa(n.name,o,t,n.access);return this._types.set(e,u),this._updateTypeInfo(u),u}if(e instanceof ta){const n=e,i=n.format?this._getTypeInfo(n.format,null):null,o=new fa(n.name,i,t,n.access);return this._types.set(e,o),this._updateTypeInfo(o),o}const r=new ir(e.name,t);return this._types.set(e,r),this._updateTypeInfo(r),r}_updateTypeInfo(e){var t,r;const n=this._getTypeSize(e);if(e.size=(t=n==null?void 0:n.size)!==null&&t!==void 0?t:0,e instanceof zn){const i=this._getTypeSize(e.format);e.stride=(r=i==null?void 0:i.size)!==null&&r!==void 0?r:0,this._updateTypeInfo(e.format)}e instanceof hs&&this._updateStructInfo(e)}_updateStructInfo(e){var t;let r=0,n=0,i=0,o=0;for(let u=0,l=e.members.length;u{const r=function(n,i,o){switch(i.resourceType){case xe.Uniform:case xe.Storage:case xe.StorageTexture:return $n(n,i.type,o);default:return{size:0,type:i.type.name}}}(s,t,0);return[t.name,{typeDefinition:r,group:t.group,binding:t.binding,size:r.size}]}))}function ma(s,e,t){return{fields:Object.fromEntries(e.members.map(r=>[r.name,{offset:r.offset,type:$n(s,r.type,0)}])),size:e.size,offset:t}}function Bd(s){var e;if(s.name.includes("depth"))return"depth";switch((e=s.format)==null?void 0:e.name){case"f32":return"float";case"i32":return"sint";case"u32":return"uint";default:throw new Error("unknown texture sample type")}}function ga(s){return s.name.includes("2d_array")?"2d-array":s.name.includes("cube_array")?"cube-array":s.name.includes("3d")?"3d":s.name.includes("1d")?"1d":s.name.includes("cube")?"cube":"2d"}function Ad(s){switch(s.access){case"read":return"read-only";case"write":return"write-only";case"read_write":return"read-write";default:throw new Error("unknonw storage texture access")}}function vd(s){return s.name.endsWith("_comparison")?"comparison":"filtering"}function wd(s,e){const{binding:t,access:r,type:n}=s;switch(s.resourceType){case xe.Uniform:return{binding:t,visibility:e,buffer:{...s.size&&{minBindingSize:s.size}}};case xe.Storage:return{binding:t,visibility:e,buffer:{type:r===""||r==="read"?"read-only-storage":"storage",...s.size&&{minBindingSize:s.size}}};case xe.Texture:{if(n.name==="texture_external")return{binding:t,visibility:e,externalTexture:{}};const i=n.name.includes("multisampled");return{binding:t,visibility:e,texture:{sampleType:Bd(n),viewDimension:ga(n),multisampled:i}}}case xe.Sampler:return{binding:t,visibility:e,sampler:{type:vd(n)}};case xe.StorageTexture:return{binding:t,visibility:e,storageTexture:{access:Ad(n),format:n.format.name,viewDimension:ga(n)}};default:throw new Error("unknown resource type")}}function jn(s,e){const t={};for(const r of s)t[r.name]={stage:e,resources:r.resources.map(n=>{const{name:i,group:o}=n;return{name:i,group:o,entry:wd(n,e)}})};return t}function kt(s){const e=new ht(s),t=Object.fromEntries(e.structs.map(u=>[u.name,ma(e,u,0)])),r=or(e,e.uniforms),n=or(e,e.storage.filter(u=>u.resourceType===xe.Storage)),i=or(e,e.storage.filter(u=>u.resourceType===xe.StorageTexture)),o=or(e,e.textures.filter(u=>u.type.name!=="texture_external"));return{externalTextures:or(e,e.textures.filter(u=>u.type.name==="texture_external")),samplers:or(e,e.samplers),structs:t,storages:n,storageTextures:i,textures:o,uniforms:r,entryPoints:{...jn(e.entry.vertex,GPUShaderStage.VERTEX),...jn(e.entry.fragment,GPUShaderStage.FRAGMENT),...jn(e.entry.compute,GPUShaderStage.COMPUTE)}}}function Kn(s,e=""){if(!s)throw new Error(e)}function $n(s,e,t){if(e.isArray){Kn(!e.isStruct,"struct array is invalid"),Kn(!e.isStruct,"template array is invalid");const r=e;return{size:r.size,elementType:$n(s,r.format,t),numElements:r.count}}if(e.isStruct)return Kn(!e.isTemplate,"template struct is invalid"),ma(s,e,t);{const r=e,n=e.isTemplate?`${r.name}<${r.format.name}>`:e.name;return{size:e.size,type:n}}}ht._typeInfo={f16:{align:2,size:2},i32:{align:4,size:4},u32:{align:4,size:4},f32:{align:4,size:4},atomic:{align:4,size:4},vec2:{align:8,size:8},vec3:{align:16,size:12},vec4:{align:16,size:16},mat2x2:{align:8,size:16},mat3x2:{align:8,size:24},mat4x2:{align:8,size:32},mat2x3:{align:16,size:32},mat3x3:{align:16,size:48},mat4x3:{align:16,size:64},mat2x4:{align:16,size:32},mat3x4:{align:16,size:48},mat4x4:{align:16,size:64}},ht._textureTypes=v.any_texture_type.map(s=>s.name),ht._samplerTypes=v.sampler_type.map(s=>s.name);const Cd=new Map([[Int8Array,{formats:["sint8","snorm8"],defaultForType:1}],[Uint8Array,{formats:["uint8","unorm8"],defaultForType:1}],[Int16Array,{formats:["sint16","snorm16"],defaultForType:1}],[Uint16Array,{formats:["uint16","unorm16"],defaultForType:1}],[Int32Array,{formats:["sint32","snorm32"],defaultForType:0}],[Uint32Array,{formats:["uint32","unorm32"],defaultForType:0}],[Float32Array,{formats:["float32","float32"],defaultForType:0}]]);new Map([...Cd.entries()].map(([s,{formats:[e,t]}])=>[[e,s],[t,s]]).flat());const Mt=class Mt{static getActiveRenderPassType(){return this.activeRenderPassType}static setActiveRenderPass(e,t){this.activeRenderPassType=e,this.activeRenderPassEncoder=t,this.currentlyBoundRenderPSO=null}static bindRenderPSO(e){var t;e!==this.currentlyBoundRenderPSO&&(this.currentlyBoundRenderPSO=e,(t=this.activeRenderPassEncoder)==null||t.setPipeline(e))}};Mt.ENABLE_DEBUG_GROUPS=!1,Mt.elapsedTimeMs=0,Mt.deltaTimeMs=0,Mt.frameIndex=0,Mt.depthStencilFormat="depth24plus-stencil8",Mt.prevTimeMs=0;let A=Mt;class Td{constructor(e,t){this.normal=e,this.d=t}normalize(){const e=F.len(this.normal);F.normalize(this.normal,this.normal),this.d/=e}checkIfBBoxIsInside(e){const t=this.normal[0]>=0?e.maxX:e.minX,r=this.normal[1]>=0?e.maxY:e.minY,n=this.normal[2]>=0?e.maxZ:e.minZ;return this.normal[0]*t+this.normal[1]*r+this.normal[2]*n+this.d>=0}}let ya={};const ba=new WeakMap,xa={metric:[{from:0,to:1e3,unit:"B",long:"bytes"},{from:1e3,to:1e6,unit:"kB",long:"kilobytes"},{from:1e6,to:1e9,unit:"MB",long:"megabytes"},{from:1e9,to:1e12,unit:"GB",long:"gigabytes"},{from:1e12,to:1e15,unit:"TB",long:"terabytes"},{from:1e15,to:1e18,unit:"PB",long:"petabytes"},{from:1e18,to:1e21,unit:"EB",long:"exabytes"},{from:1e21,to:1e24,unit:"ZB",long:"zettabytes"},{from:1e24,to:1e27,unit:"YB",long:"yottabytes"}],metric_octet:[{from:0,to:1e3,unit:"o",long:"octets"},{from:1e3,to:1e6,unit:"ko",long:"kilooctets"},{from:1e6,to:1e9,unit:"Mo",long:"megaoctets"},{from:1e9,to:1e12,unit:"Go",long:"gigaoctets"},{from:1e12,to:1e15,unit:"To",long:"teraoctets"},{from:1e15,to:1e18,unit:"Po",long:"petaoctets"},{from:1e18,to:1e21,unit:"Eo",long:"exaoctets"},{from:1e21,to:1e24,unit:"Zo",long:"zettaoctets"},{from:1e24,to:1e27,unit:"Yo",long:"yottaoctets"}],iec:[{from:0,to:Math.pow(1024,1),unit:"B",long:"bytes"},{from:Math.pow(1024,1),to:Math.pow(1024,2),unit:"KiB",long:"kibibytes"},{from:Math.pow(1024,2),to:Math.pow(1024,3),unit:"MiB",long:"mebibytes"},{from:Math.pow(1024,3),to:Math.pow(1024,4),unit:"GiB",long:"gibibytes"},{from:Math.pow(1024,4),to:Math.pow(1024,5),unit:"TiB",long:"tebibytes"},{from:Math.pow(1024,5),to:Math.pow(1024,6),unit:"PiB",long:"pebibytes"},{from:Math.pow(1024,6),to:Math.pow(1024,7),unit:"EiB",long:"exbibytes"},{from:Math.pow(1024,7),to:Math.pow(1024,8),unit:"ZiB",long:"zebibytes"},{from:Math.pow(1024,8),to:Math.pow(1024,9),unit:"YiB",long:"yobibytes"}],iec_octet:[{from:0,to:Math.pow(1024,1),unit:"o",long:"octets"},{from:Math.pow(1024,1),to:Math.pow(1024,2),unit:"Kio",long:"kibioctets"},{from:Math.pow(1024,2),to:Math.pow(1024,3),unit:"Mio",long:"mebioctets"},{from:Math.pow(1024,3),to:Math.pow(1024,4),unit:"Gio",long:"gibioctets"},{from:Math.pow(1024,4),to:Math.pow(1024,5),unit:"Tio",long:"tebioctets"},{from:Math.pow(1024,5),to:Math.pow(1024,6),unit:"Pio",long:"pebioctets"},{from:Math.pow(1024,6),to:Math.pow(1024,7),unit:"Eio",long:"exbioctets"},{from:Math.pow(1024,7),to:Math.pow(1024,8),unit:"Zio",long:"zebioctets"},{from:Math.pow(1024,8),to:Math.pow(1024,9),unit:"Yio",long:"yobioctets"}]};class Sd{constructor(e,t){t=Object.assign({units:"metric",precision:1,locale:void 0},ya,t),ba.set(this,t),Object.assign(xa,t.customUnits);const r=e<0?"-":"";e=Math.abs(e);const n=xa[t.units];if(!n)throw new Error(`Invalid units specified: ${t.units}`);{const i=n.find(o=>e>=o.from&&et!=e.id),e.parent=null,this.onChildRemove(e)}onChildAdd(e){var t;(t=this.parent)==null||t.onChildAdd(e)}onChildRemove(e){var t;(t=this.parent)==null||t.onChildRemove(e)}traverse(e,t=!0){if(e(this),t)for(const r of this.children)r.traverse(e,t)}findChild(e){if(e(this))return this;for(const t of this.children)if(t.findChild(e))return t}findChildByLabel(e){return this.findChild(({label:t})=>e===t)}findChildById(e){return this.findChild(({id:t})=>e===t)}preRender(e){}onRender(e){}postRender(e){}render(e){this.visible&&(this.preRender(e),this.onRender(e),this.postRender(e))}get worldPosition(){return this.getWorldPosition()}getWorldPosition(){return this._worldPosition[0]=this.worldMatrix[12],this._worldPosition[1]=this.worldMatrix[13],this._worldPosition[2]=this.worldMatrix[14],this._worldPosition}setPositionAsVec3(e){return F.clone(e,this._position),this.matrixNeedsUpdate=!0,this}setPosition(e,t,r){return this._position[0]=e,this._position[1]=t,this._position[2]=r,this.matrixNeedsUpdate=!0,this}setPositionX(e){return this._position[0]=e,this.matrixNeedsUpdate=!0,this}setPositionY(e){return this._position[1]=e,this.matrixNeedsUpdate=!0,this}setPositionZ(e){return this._position[2]=e,this.matrixNeedsUpdate=!0,this}get position(){return this.getPosition()}getPosition(){return this._position}getPositionX(){return this._position[0]}getPositionY(){return this._position[1]}getPositionZ(){return this._position[2]}setRotation(e,t,r){return this._rotation[0]=e,this._rotation[1]=t,this._rotation[2]=r,this.matrixNeedsUpdate=!0,this}setRotationX(e){return this._rotation[0]=e,this.matrixNeedsUpdate=!0,this}setRotationY(e){return this._rotation[1]=e,this.matrixNeedsUpdate=!0,this}setRotationZ(e){return this._rotation[2]=e,this.matrixNeedsUpdate=!0,this}get rotation(){return this.getRotation()}getRotation(){return this._rotation}getRotationX(){return this._rotation[0]}getRotationY(){return this._rotation[1]}getRotationZ(){return this._rotation[2]}setScale(e,t,r){return this._scale[0]=e,this._scale[1]=t,this._scale[2]=r,this.matrixNeedsUpdate=!0,this}setScaleX(e){return this._scale[0]=e,this.matrixNeedsUpdate=!0,this}setScaleY(e){return this._scale[1]=e,this.matrixNeedsUpdate=!0,this}setScaleZ(e){return this._scale[2]=e,this.matrixNeedsUpdate=!0,this}get scale(){return this.getScale()}getScale(){return this._scale}getScaleX(){return this._scale[0]}getScaleY(){return this._scale[1]}getScaleZ(){return this._scale[2]}}const Je=Object.freeze({get Position(){return 0},get Normal(){return 1},get TexCoord(){return 2},get Tangent(){return 3}}),ce=Object.freeze({get CameraPlusOptionalLights(){return 0},get Model(){return 1},get PBRTextures(){return 2},get InstanceInputs(){return 3}}),ft=Object.freeze({get NormalMetallicRoughness(){return 0},get ColorReflectance(){return 1},get Velocity(){return 2}}),ms=Object.freeze({get Default(){return 0}}),me=Object.freeze({get Albedo(){return 1},get Normal(){return 2},get MetallicRoughness(){return 3},get AO(){return 4}}),Y=Object.freeze({get VertexInput(){return` + + struct VertexInput { + @location(${Je.Position}) position: vec4f, + @location(${Je.Normal}) normal: vec3f, + @location(${Je.TexCoord}) uv: vec2f, + @location(${Je.Tangent}) tangent: vec4f, + }; + + `},get VertexOutput(){return` + + struct VertexOutput { + @builtin(position) position: vec4f, + @location(0) worldPosition: vec3f, + @location(1) viewNormal: vec3f, + @location(2) uv: vec2f, + @location(3) viewTangent: vec3f, + @location(4) viewBitangent: vec3f, + @location(5) currFrameClipPos: vec4f, + @location(6) prevFrameClipPos: vec4f, + @location(7) @interpolate(flat) instanceId: u32, + }; + + `},get InstanceInput(){return` + struct InstanceInput { + worldMatrix: mat4x4f, + metallic: f32, + roughness: f32, + }; + `},get ModelUniform(){return` + + struct ModelUniform { + worldMatrix: mat4x4f, + prevFrameWorldMatrix: mat4x4f, + normalMatrix: mat3x3f, + baseColor: vec3f, + isReflective: u32, + metallic: f32, + roughness: f32, + }; + + `},get Camera(){return` + + struct Camera { + position: vec3f, + projectionMatrix: mat4x4f, + viewMatrix: mat4x4f, + projectionViewMatrix: mat4x4f, + inverseProjectionViewMatrix: mat4x4f, + inverseViewMatrix: mat4x4f, + inverseProjectionMatrix: mat4x4f, + prevFrameProjectionViewMatrix: mat4x4f, + viewportWidth: u32, + viewportHeight: u32, + jitterOffset: vec2f, + }; + + @must_use + fn calcWorldPos( + camera: Camera, + coord: vec2f, + depth: f32 + ) -> vec3f { + let ndcX = coord.x / f32(camera.viewportWidth) * 2.0 - 1.0; + let ndcY = (1.0 - coord.y / f32(camera.viewportHeight)) * 2.0 - 1.0; + let clipPos = vec4f(ndcX, ndcY, depth, 1.0); + + let worldSpacePos = camera.inverseProjectionViewMatrix * clipPos; + return worldSpacePos.xyz / worldSpacePos.w; + } + + @must_use + fn calcViewSpacePos( + camera: Camera, + coord: vec2f, + depth: f32 + ) -> vec3f { + let ndcX = coord.x / f32(camera.viewportWidth) * 2.0 - 1.0; + let ndcY = (1.0 - coord.y / f32(camera.viewportHeight)) * 2.0 - 1.0; + let clipPos = vec4f(ndcX, ndcY, depth, 1.0); + + let viewSpacePos = camera.inverseProjectionMatrix * clipPos; + return viewSpacePos.xyz / viewSpacePos.w; + } + + `},get GBufferOutput(){return` + + struct GBufferOutput { + @location(${ft.NormalMetallicRoughness}) normalMetallicRoughness: vec4f, + @location(${ft.ColorReflectance}) color: vec4f, + @location(${ft.Velocity}) velocity: vec4f, + }; + + `},get AABB(){return` + struct AABB { + min: vec3f, + max: vec3f, + }; + `},get Particle(){return` + struct Particle { + radius: f32, + position: vec3f, + origPosition: vec3f, + velocity: vec3f, + lifeSpeed: f32, + life: f32 + }; + `},get Light(){return` + + struct Light { + lightType: u32, // 0 - Directional Light, 1 - Point Light, 2 - Ambient Light + intensity: f32, + radius: f32, + position: vec3f, + color: vec3f, + }; + + `},get Material(){return` + + struct Material { + metallic: f32, + albedo: vec3f, + roughness: f32, + ambientOcclusion: f32, + }; + + `},get ShadowCascade(){return` + struct ShadowCascade { + projViewMatrix: mat4x4, + distance: f32, + }; + `},get CommonHelpers(){return` + + const WORLD_UP = vec3f(0.0, 1.0, 0.0); + const WORLD_FORWARD = vec3f(0.0, 0.0, 1.0); + const PI: f32 = 3.1415; + const TWO_PI: f32 = 6.2831; + const HALF_PI: f32 = 1.5707; + const DELTA_PHI: f32 = 0.01745; + const DELTA_THETA: f32 = 0.01745; + + const CUBE_NORMALS: array, 6> = array, 6>( + vec3(1.0, 0.0, 0.0), + vec3(-1.0, 0.0, 0.0), + vec3(0.0, 1.0, 0.0), + vec3(0.0, -1.0, 0.0), + vec3(0.0, 0.0, 1.0), + vec3(0.0, 0.0, -1.0) + ); + + const CUBE_UPS: array, 6> = array, 6>( + vec3(0.0, 1.0, 0.0), + vec3(0.0, 1.0, 0.0), + vec3(0.0, 0.0, -1.0), + vec3(0.0, 0.0, 1.0), + vec3(0.0, 1.0, 0.0), + vec3(0.0, 1.0, 0.0) + ); + + const CUBE_ROTATIONS: array, 6> = array, 6>( + vec4(0.0, 1.0, 0.0, HALF_PI), + vec4(0.0, 1.0, 0.0, -HALF_PI), + vec4(1.0, 0.0, 0.0, -HALF_PI), + vec4(1.0, 0.0, 0.0, HALF_PI), + vec4(0.0, 0.0, 1.0, 0.0), + vec4(0.0, 1.0, 0.0, PI) + ); + `},get MathHelpers(){return` + + @must_use + fn rotateAxisAngle(inAxis: vec3f, angle: f32) -> mat3x3f { + let axis = normalize(inAxis); + let s = sin(angle); + let c = cos(angle); + let oc = 1.0 - c; + + return mat3x3f( + oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, + oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, + oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c + ); + } + + `}}),Aa=[[.5,.333333],[.25,.666667],[.75,.111111],[.125,.444444],[.625,.777778],[.375,.222222],[.875,.555556],[.0625,.888889],[.5625,.037037],[.3125,.37037],[.8125,.703704],[.1875,.148148],[.6875,.481481],[.4375,.814815],[.9375,.259259],[.03125,.592593]],ln=class ln extends ar{constructor(){super(),this.lookAt=F.fromValues(0,0,0),this.hasChangedSinceLastFrame=!0,this.projectionMatrix=Q.create(),this.inverseProjectionMatrix=Q.create(),this.viewMatrix=Q.create(),this.inverseViewMatrix=Q.create(),this.projectionViewMatrix=Q.create(),this.inverseProjectionViewMatrix=Q.create(),this._shouldJitter=!1,this._shouldJitterChanged=!1,this.prevFrameProjectionViewMatrix=Q.create(),this.frameCounter=0,this.frustumPlanes=[],this.hamiltonSequence=new Array(16).fill([]).map(()=>new Array(2).fill(0));const e=kt(Y.Camera);this.bufferUniformValues=vt(e.structs.Camera),this.bufferUniformValues.set({viewMatrix:this.viewMatrix,projectionMatrix:this.projectionMatrix,projectionViewMatrix:this.projectionViewMatrix}),this.gpuBuffer=A.device.createBuffer({size:this.bufferUniformValues.arrayBuffer.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,label:"Camera GPUBuffer"}),X.addBufferBytes(this.gpuBuffer);for(let t=0;t<6;t++)this.frustumPlanes.push(new Td(F.create(),0))}get shouldJitter(){return this._shouldJitter}set shouldJitter(e){this._shouldJitter=e,this._shouldJitterChanged=!0}set x(e){this.position[0]=e,this.bufferUniformValues.set({position:this.position})}get x(){return this.position[0]}set y(e){this.position[1]=e,this.bufferUniformValues.set({position:this.position})}get y(){return this.position[1]}set z(e){this.position[2]=e,this.bufferUniformValues.set({position:this.position})}get z(){return this.position[2]}get frustumCornersWorldSpace(){const e=this.inverseProjectionViewMatrix,t=[];for(let r=0;r<2;r++)for(let n=0;n<2;n++)for(let i=0;i<2;i++){const o=2*r-1,u=2*n-1,l=i,m=1,y=Sr.create(o,u,l,m);Sr.transformMat4(y,e,y),y[0]/=y[3],y[1]/=y[3],y[2]/=y[3],t.push(y)}return t}cullMeshes(e,t){let r=0;for(let n=0;n(s[s.Deferred=0]="Deferred",s[s.DirectionalAmbientLighting=1]="DirectionalAmbientLighting",s[s.PointLightsNonCulledLighting=2]="PointLightsNonCulledLighting",s[s.PointLightsStencilMask=3]="PointLightsStencilMask",s[s.PointLightsLighting=4]="PointLightsLighting",s[s.SSAO=5]="SSAO",s[s.SSAOBlur=6]="SSAOBlur",s[s.Skybox=7]="Skybox",s[s.Transparent=8]="Transparent",s[s.Shadow=9]="Shadow",s[s.MomentsShadow=10]="MomentsShadow",s[s.BlurMomentsShadow=11]="BlurMomentsShadow",s[s.EnvironmentCube=12]="EnvironmentCube",s[s.TAAResolve=13]="TAAResolve",s[s.CopyDepthForHiZ=14]="CopyDepthForHiZ",s[s.HiZ=15]="HiZ",s[s.Reflection=16]="Reflection",s[s.BloomDownsample=17]="BloomDownsample",s[s.BloomUpsample=18]="BloomUpsample",s[s.DebugBounds=19]="DebugBounds",s[s.Blit=20]="Blit",s))(V||{}),se=(s=>(s[s.CPUTotal=0]="CPUTotal",s[s.GPUTotal=1]="GPUTotal",s[s.FPS=2]="FPS",s[s.VRAM=3]="VRAM",s[s.VisibleMeshes=4]="VisibleMeshes",s[s.LightsCount=5]="LightsCount",s[s.DeferredRenderPass=6]="DeferredRenderPass",s[s.DirectionalAmbientLightingRenderPass=7]="DirectionalAmbientLightingRenderPass",s[s.PointLightsStencilMask=8]="PointLightsStencilMask",s[s.PointLightsLighting=9]="PointLightsLighting",s[s.SSAORenderPass=10]="SSAORenderPass",s[s.TransparentRenderPass=11]="TransparentRenderPass",s[s.ShadowRenderPass=12]="ShadowRenderPass",s[s.TAAResolveRenderPass=13]="TAAResolveRenderPass",s[s.ReflectionRenderPass=14]="ReflectionRenderPass",s[s.BlitRenderPass=15]="BlitRenderPass",s))(se||{}),Nt=(s=>(s[s.Directional=0]="Directional",s[s.Point=1]="Point",s[s.Ambient=2]="Ambient",s))(Nt||{});const Ed=new Map([[Nt.Directional,0],[Nt.Point,1],[Nt.Ambient,2]]);V.Deferred,V.DirectionalAmbientLighting,V.SSAO,V.Transparent,V.Shadow,V.TAAResolve,V.Reflection,V.Blit;const Md=[se.CPUTotal,se.FPS,se.VRAM,se.VisibleMeshes,se.LightsCount],Pr=new Map([[V.Deferred,"G-Buffer Render Pass"],[V.DirectionalAmbientLighting,"Directional + Ambient Render Pass"],[V.PointLightsStencilMask,"Point Lights Stencil Mask Pass"],[V.PointLightsLighting,"Point Lights LightingSystem"],[V.SSAO,"SSAO Render Pass"],[V.SSAOBlur,"SSAO Blur Render Pass"],[V.Skybox,"Skybox Render Pass"],[V.Transparent,"Transparent Render Pass"],[V.Shadow,"Shadow Render Pass"],[V.EnvironmentCube,"Environment Cube Pass"],[V.TAAResolve,"TAA Resolve Render Pass"],[V.CopyDepthForHiZ,"Copy Depth for Hi-Z Render Pass"],[V.HiZ,"Hi-Z Depth Render Pass"],[V.Reflection,"SSR Render Pass"],[V.DebugBounds,"Debug Bounds Render Pass"],[V.Blit,"Blit Render Pass"],[V.BloomDownsample,"Bloom Downsample Render Pass"],[V.BloomUpsample,"Bloom Upsample Render Pass"]]);class Pd{constructor(){this.passes=[],this.textureCache=new Map}destroy(){for(const e of this.passes)e.destroy();this.textureCache.clear()}setScene(e){this.scene=e}addPass(e){if(!this.passes.some(({type:t})=>t===e.type))return this.passes.push(e),this;{const t=Pr.get(e.type);console.warn(`RenderPass ${t} has already been added`)}}removePass(e){this.passes=this.passes.filter(({type:t})=>t!==e)}getPass(e){return this.passes.find(({type:t})=>t===e)}setTexture(e,t){this.textureCache.set(e,t)}getTexture(e){return this.textureCache.get(e)}async render(e){for(const t of this.passes){if(!t.enabled)continue;const r=t.inputTextureNames.map(i=>this.textureCache.get(i)),n=t.render(e,this.scene,r);t.outputTextureNames.forEach((i,o)=>{this.textureCache.set(i,n[o])})}}onFrameEnd(){for(const e of this.passes)e.onFrameEnd()}}class Yn{constructor(){this.c0=0,this.c1=0,this.c2=0,this.c3=0}set(e,t,r,n){this.c0=e,this.c1=r,this.c2=-3*e+3*t-2*r-n,this.c3=2*e-2*t+r+n}initCatmullRom(e,t,r,n,i){this.set(t,r,i*(r-e),i*(n-t))}initNonuniformCatmullRom(e,t,r,n,i,o,u){let l=(t-e)/i-(r-e)/(i+o)+(r-t)/o,m=(r-t)/o-(n-t)/(o+u)+(n-r)/u;l*=o,m*=o,this.set(t,r,l,m)}calc(e){const t=e*e,r=t*e;return this.c0+this.c1*e+this.c2*t+this.c3*r}}const va=new Yn,wa=new Yn,Ca=new Yn,wt=F.create();class Rd{constructor(e=[],t=!1,r=.5){this.points=e,this.closed=t,this.tension=r}getPoint(e,t=F.create()){const r=t,n=this.points.length,i=(n-(this.closed?0:1))*e;let o,u,l=Math.floor(i),m=i-l;this.closed?l+=l>0?0:(Math.floor(Math.abs(l)/n)+1)*n:m===0&&l===n-1&&(l=n-2,m=1),this.closed||l>0?o=this.points[(l-1)%n]:(F.sub(this.points[0],this.points[1],wt),F.add(wt,this.points[0],wt),o=wt);const y=this.points[l%n],d=this.points[(l+1)%n];this.closed||l+2=0)}()}const Ea="4.0.7";class Gd{constructor(e,t,r="sessionStorage"){this.storage=function(n){try{const i=window[n],o="__storage_test__";return i.setItem(o,o),i.removeItem(o),i}catch{return null}}(r),this.id=e,this.config=t,this._loadConfiguration()}getConfiguration(){return this.config}setConfiguration(e){if(Object.assign(this.config,e),this.storage){const t=JSON.stringify(this.config);this.storage.setItem(this.id,t)}}_loadConfiguration(){let e={};if(this.storage){const t=this.storage.getItem(this.id);e=t?JSON.parse(t):{}}return Object.assign(this.config,e),this}}var xs;(function(s){s[s.BLACK=30]="BLACK",s[s.RED=31]="RED",s[s.GREEN=32]="GREEN",s[s.YELLOW=33]="YELLOW",s[s.BLUE=34]="BLUE",s[s.MAGENTA=35]="MAGENTA",s[s.CYAN=36]="CYAN",s[s.WHITE=37]="WHITE",s[s.BRIGHT_BLACK=90]="BRIGHT_BLACK",s[s.BRIGHT_RED=91]="BRIGHT_RED",s[s.BRIGHT_GREEN=92]="BRIGHT_GREEN",s[s.BRIGHT_YELLOW=93]="BRIGHT_YELLOW",s[s.BRIGHT_BLUE=94]="BRIGHT_BLUE",s[s.BRIGHT_MAGENTA=95]="BRIGHT_MAGENTA",s[s.BRIGHT_CYAN=96]="BRIGHT_CYAN",s[s.BRIGHT_WHITE=97]="BRIGHT_WHITE"})(xs||(xs={}));function Ma(s){return typeof s!="string"?s:(s=s.toUpperCase(),xs[s]||xs.WHITE)}function qn(s,e){if(!s)throw new Error("Assertion failed")}function cr(){var e,t,r;let s;if(Wn()&&bs.performance)s=(t=(e=bs==null?void 0:bs.performance)==null?void 0:e.now)==null?void 0:t.call(e);else if("hrtime"in ur){const n=(r=ur==null?void 0:ur.hrtime)==null?void 0:r.call(ur);s=1e3*n[0]+n[1]/1e6}else s=Date.now();return s}const lr={debug:Wn()&&console.debug||console.log,log:console.log,info:console.info,warn:console.warn,error:console.error},Ld={enabled:!0,level:0};function dr(){}const Pa={},Ra={once:!0};class Qn{constructor({id:e}={id:""}){this.VERSION=Ea,this._startTs=cr(),this._deltaTs=cr(),this.userData={},this.LOG_THROTTLE_TIMEOUT=0,this.id=e,this.userData={},this._storage=new Gd(`__probe-${this.id}__`,Ld),this.timeStamp(`${this.id} started`),function(t,r=["constructor"]){const n=Object.getPrototypeOf(t),i=Object.getOwnPropertyNames(n),o=t;for(const u of i){const l=o[u];typeof l=="function"&&(r.find(m=>u===m)||(o[u]=l.bind(t)))}}(this),Object.seal(this)}set level(e){this.setLevel(e)}get level(){return this.getLevel()}isEnabled(){return this._storage.config.enabled}getLevel(){return this._storage.config.level}getTotal(){return Number((cr()-this._startTs).toPrecision(10))}getDelta(){return Number((cr()-this._deltaTs).toPrecision(10))}set priority(e){this.level=e}get priority(){return this.level}getPriority(){return this.level}enable(e=!0){return this._storage.setConfiguration({enabled:e}),this}setLevel(e){return this._storage.setConfiguration({level:e}),this}get(e){return this._storage.config[e]}set(e,t){this._storage.setConfiguration({[e]:t})}settings(){console.table?console.table(this._storage.config):console.log(this._storage.config)}assert(e,t){if(!e)throw new Error(t||"Assertion failed")}warn(e){return this._getLogFunction(0,e,lr.warn,arguments,Ra)}error(e){return this._getLogFunction(0,e,lr.error,arguments)}deprecated(e,t){return this.warn(`\`${e}\` is deprecated and will be removed in a later version. Use \`${t}\` instead`)}removed(e,t){return this.error(`\`${e}\` has been removed. Use \`${t}\` instead`)}probe(e,t){return this._getLogFunction(e,t,lr.log,arguments,{time:!0,once:!0})}log(e,t){return this._getLogFunction(e,t,lr.debug,arguments)}info(e,t){return this._getLogFunction(e,t,console.info,arguments)}once(e,t){return this._getLogFunction(e,t,lr.debug||lr.info,arguments,Ra)}table(e,t,r){return t?this._getLogFunction(e,t,console.table||dr,r&&[r],{tag:Od(t)}):dr}time(e,t){return this._getLogFunction(e,t,console.time?console.time:console.info)}timeEnd(e,t){return this._getLogFunction(e,t,console.timeEnd?console.timeEnd:console.info)}timeStamp(e,t){return this._getLogFunction(e,t,console.timeStamp||dr)}group(e,t,r={collapsed:!1}){const n=La({logLevel:e,message:t,opts:r}),{collapsed:i}=r;return n.method=(i?console.groupCollapsed:console.group)||console.info,this._getLogFunction(n)}groupCollapsed(e,t,r={}){return this.group(e,t,Object.assign({},r,{collapsed:!0}))}groupEnd(e){return this._getLogFunction(e,"",console.groupEnd||dr)}withGroup(e,t,r){this.group(e,t)();try{r()}finally{this.groupEnd(e)()}}trace(){console.trace&&console.trace()}_shouldLog(e){return this.isEnabled()&&this.getLevel()>=Ga(e)}_getLogFunction(e,t,r,n,i){if(this._shouldLog(e)){i=La({logLevel:e,message:t,args:n,opts:i}),qn(r=r||i.method),i.total=this.getTotal(),i.delta=this.getDelta(),this._deltaTs=cr();const o=i.tag||i.message;if(i.once&&o){if(Pa[o])return dr;Pa[o]=cr()}return t=function(u,l,m){if(typeof l=="string"){const y=m.time?function(d,x=8){const b=Math.max(x-d.length,0);return`${" ".repeat(b)}${d}`}(function(d){let x;return x=d<10?`${d.toFixed(2)}ms`:d<100?`${d.toFixed(1)}ms`:d<1e3?`${d.toFixed(0)}ms`:`${(d/1e3).toFixed(2)}s`,x}(m.total)):"";l=function(d,x,b){return Wn||typeof d!="string"||(x&&(d=`\x1B[${Ma(x)}m${d}\x1B[39m`),b&&(d=`\x1B[${Ma(b)+10}m${d}\x1B[49m`)),d}(l=m.time?`${u}: ${y} ${l}`:`${u}: ${l}`,m.color,m.background)}return l}(this.id,i.message,i),r.bind(console,t,...i.args)}return dr}}function Ga(s){if(!s)return 0;let e;switch(typeof s){case"number":e=s;break;case"object":e=s.logLevel||s.priority||0;break;default:return 0}return qn(Number.isFinite(e)&&e>=0),e}function La(s){const{logLevel:e,message:t}=s;s.logLevel=Ga(e);const r=s.args?Array.from(s.args):[];for(;r.length&&r.shift()!==t;);switch(typeof e){case"string":case"function":t!==void 0&&r.unshift(t),s.message=e;break;case"object":Object.assign(s,e)}typeof s.message=="function"&&(s.message=s.message());const n=typeof s.message;return qn(n==="string"||n==="object"),Object.assign(s,{args:r},s.opts)}function Od(s){for(const e in s)for(const t in s[e])return t||"untitled";return"empty"}Qn.VERSION=Ea;const Zn="4.3.2",Id=Zn[0]>="0"&&Zn[0]<="9"?`v${Zn}`:"",Dd=function(){const s=new Qn({id:"loaders.gl"});return globalThis.loaders=globalThis.loaders||{},globalThis.loaders.log=s,globalThis.loaders.version=Id,globalThis.probe=globalThis.probe||{},globalThis.probe.loaders=s,s}();function Fd(s,e){return Oa(s||{},e)}function Oa(s,e,t=0){if(t>3)return e;const r={...s};for(const[n,i]of Object.entries(e))i&&typeof i=="object"&&!Array.isArray(i)?r[n]=Oa(r[n]||{},e[n],t+1):r[n]=e[n];return r}const Ud=((sl=globalThis._loadersgl_)!=null&&sl.version||(globalThis._loadersgl_=globalThis._loadersgl_||{},globalThis._loadersgl_.version="4.3.2"),globalThis._loadersgl_.version);function mt(s,e){if(!s)throw new Error(e||"loaders.gl assertion failed.")}const ze=typeof process!="object"||String(process)!=="[object process]"||process.browser,ei=typeof importScripts=="function",kd=typeof window<"u"&&window.orientation!==void 0,Ia=typeof process<"u"&&process.version&&/v([0-9]*)/.exec(process.version);Ia&&parseFloat(Ia[1]);class Nd{constructor(e,t){ee(this,"name");ee(this,"workerThread");ee(this,"isRunning",!0);ee(this,"result");ee(this,"_resolve",()=>{});ee(this,"_reject",()=>{});this.name=e,this.workerThread=t,this.result=new Promise((r,n)=>{this._resolve=r,this._reject=n})}postMessage(e,t){this.workerThread.postMessage({source:"loaders.gl",type:e,payload:t})}done(e){mt(this.isRunning),this.isRunning=!1,this._resolve(e)}error(e){mt(this.isRunning),this.isRunning=!1,this._reject(e)}}class ti{terminate(){}}const ri=new Map;function Vd(s){mt(s.source&&!s.url||!s.source&&s.url);let e=ri.get(s.source||s.url);return e||(s.url&&(e=function(t){if(!t.startsWith("http"))return t;return Da((r=t,`try { + importScripts('${r}'); +} catch (error) { + console.error(error); + throw error; +}`));var r}(s.url),ri.set(s.url,e)),s.source&&(e=Da(s.source),ri.set(s.source,e))),mt(e),e}function Da(s){const e=new Blob([s],{type:"application/javascript"});return URL.createObjectURL(e)}function Fa(s,e=!0,t){const r=t||new Set;if(s){if(Ua(s))r.add(s);else if(Ua(s.buffer))r.add(s.buffer);else if(!ArrayBuffer.isView(s)){if(e&&typeof s=="object")for(const n in s)Fa(s[n],e,r)}}return t===void 0?Array.from(r):[]}function Ua(s){return!!s&&(s instanceof ArrayBuffer||typeof MessagePort<"u"&&s instanceof MessagePort||typeof ImageBitmap<"u"&&s instanceof ImageBitmap||typeof OffscreenCanvas<"u"&&s instanceof OffscreenCanvas)}const si=()=>{};class ni{constructor(e){ee(this,"name");ee(this,"source");ee(this,"url");ee(this,"terminated",!1);ee(this,"worker");ee(this,"onMessage");ee(this,"onError");ee(this,"_loadableURL","");const{name:t,source:r,url:n}=e;mt(r||n),this.name=t,this.source=r,this.url=n,this.onMessage=si,this.onError=i=>console.log(i),this.worker=ze?this._createBrowserWorker():this._createNodeWorker()}static isSupported(){return typeof Worker<"u"&&ze||ti!==void 0&&!ze}destroy(){this.onMessage=si,this.onError=si,this.worker.terminate(),this.terminated=!0}get isRunning(){return!!this.onMessage}postMessage(e,t){t=t||Fa(e),this.worker.postMessage(e,t)}_getErrorFromErrorEvent(e){let t="Failed to load ";return t+=`worker ${this.name} from ${this.url}. `,e.message&&(t+=`${e.message} in `),e.lineno&&(t+=`:${e.lineno}:${e.colno}`),new Error(t)}_createBrowserWorker(){this._loadableURL=Vd({source:this.source,url:this.url});const e=new Worker(this._loadableURL,{name:this.name});return e.onmessage=t=>{t.data?this.onMessage(t.data):this.onError(new Error("No data received"))},e.onerror=t=>{this.onError(this._getErrorFromErrorEvent(t)),this.terminated=!0},e.onmessageerror=t=>console.error(t),e}_createNodeWorker(){let e;if(this.url){const t=this.url.includes(":/")||this.url.startsWith("/")?this.url:`./${this.url}`;e=new ti(t,{eval:!1})}else{if(!this.source)throw new Error("no worker");e=new ti(this.source,{eval:!0})}return e.on("message",t=>{this.onMessage(t)}),e.on("error",t=>{this.onError(t)}),e.on("exit",t=>{}),e}}class Hd{constructor(e){ee(this,"name","unnamed");ee(this,"source");ee(this,"url");ee(this,"maxConcurrency",1);ee(this,"maxMobileConcurrency",1);ee(this,"onDebug",()=>{});ee(this,"reuseWorkers",!0);ee(this,"props",{});ee(this,"jobQueue",[]);ee(this,"idleQueue",[]);ee(this,"count",0);ee(this,"isDestroyed",!1);this.source=e.source,this.url=e.url,this.setProps(e)}static isSupported(){return ni.isSupported()}destroy(){this.idleQueue.forEach(e=>e.destroy()),this.isDestroyed=!0}setProps(e){this.props={...this.props,...e},e.name!==void 0&&(this.name=e.name),e.maxConcurrency!==void 0&&(this.maxConcurrency=e.maxConcurrency),e.maxMobileConcurrency!==void 0&&(this.maxMobileConcurrency=e.maxMobileConcurrency),e.reuseWorkers!==void 0&&(this.reuseWorkers=e.reuseWorkers),e.onDebug!==void 0&&(this.onDebug=e.onDebug)}async startJob(e,t=(n,i,o)=>n.done(o),r=(n,i)=>n.error(i)){const n=new Promise(i=>(this.jobQueue.push({name:e,onMessage:t,onError:r,onStart:i}),this));return this._startQueuedJob(),await n}async _startQueuedJob(){if(!this.jobQueue.length)return;const e=this._getAvailableWorker();if(!e)return;const t=this.jobQueue.shift();if(t){this.onDebug({message:"Starting job",name:t.name,workerThread:e,backlog:this.jobQueue.length});const r=new Nd(t.name,e);e.onMessage=n=>t.onMessage(r,n.type,n.payload),e.onError=n=>t.onError(r,n),t.onStart(r);try{await r.result}catch(n){console.error(`Worker exception: ${n}`)}finally{this.returnWorkerToQueue(e)}}}returnWorkerToQueue(e){!ze||this.isDestroyed||!this.reuseWorkers||this.count>this._getMaxConcurrency()?(e.destroy(),this.count--):this.idleQueue.push(e),this.isDestroyed||this._startQueuedJob()}_getAvailableWorker(){if(this.idleQueue.length>0)return this.idleQueue.shift()||null;if(this.count{}},Pt=class Pt{constructor(e){ee(this,"props");ee(this,"workerPools",new Map);this.props={...Jd},this.setProps(e),this.workerPools=new Map}static isSupported(){return ni.isSupported()}static getWorkerFarm(e={}){return Pt._workerFarm=Pt._workerFarm||new Pt({}),Pt._workerFarm.setProps(e),Pt._workerFarm}destroy(){for(const e of this.workerPools.values())e.destroy();this.workerPools=new Map}setProps(e){this.props={...this.props,...e};for(const t of this.workerPools.values())t.setProps(this._getWorkerPoolProps())}getWorkerPool(e){const{name:t,source:r,url:n}=e;let i=this.workerPools.get(t);return i||(i=new Hd({name:t,source:r,url:n}),i.setProps(this._getWorkerPoolProps()),this.workerPools.set(t,i)),i}_getWorkerPoolProps(){return{maxConcurrency:this.props.maxConcurrency,maxMobileConcurrency:this.props.maxMobileConcurrency,reuseWorkers:this.props.reuseWorkers,onDebug:this.props.onDebug}}};ee(Pt,"_workerFarm");let _s=Pt;const ii={};async function Vt(s,e=null,t={},r=null){return e&&(s=function(n,i,o={},u=null){if(!o.useLocalLibraries&&n.startsWith("http"))return n;u=u||n;const l=o.modules||{};return l[u]?l[u]:ze?o.CDN?(mt(o.CDN.startsWith("http")),`${o.CDN}/${i}@${Ud}/dist/libs/${u}`):ei?`../src/libs/${u}`:`modules/${i}/src/libs/${u}`:`modules/${i}/dist/libs/${u}`}(s,e,t,r)),ii[s]=ii[s]||async function(n){if(n.endsWith("wasm"))return await async function(o){const{readFileAsArrayBuffer:u}=globalThis.loaders||{};return ze||!u||o.startsWith("http")?await(await fetch(o)).arrayBuffer():await u(o)}(n);if(!ze)try{const{requireFromFile:o}=globalThis.loaders||{};return await(o==null?void 0:o(n))}catch(o){return console.error(o),null}if(ei)return importScripts(n);const i=await async function(o){const{readFileAsText:u}=globalThis.loaders||{};return ze||!u||o.startsWith("http")?await(await fetch(o)).text():await u(o)}(n);return function(o,u){if(!ze){const{requireFromString:m}=globalThis.loaders||{};return m==null?void 0:m(o,u)}if(ei)return eval.call(globalThis,o),null;const l=document.createElement("script");l.id=u;try{l.appendChild(document.createTextNode(o))}catch{l.text=o}return document.body.appendChild(l),null}(i,n)}(s),await ii[s]}async function zd(s,e,t,r,n){const i=s.id,o=function(y,d={}){const x=d[y.id]||{},b=ze?`${y.id}-worker.js`:`${y.id}-worker-node.js`;let _=x.workerUrl;if(_||y.id!=="compression"||(_=d.workerUrl),d._workerType==="test"&&(_=ze?`modules/${y.module}/dist/${b}`:`modules/${y.module}/src/workers/${y.id}-worker-node.ts`),!_){let C=y.version;C==="latest"&&(C="latest");const f=C?`@${C}`:"";_=`https://unpkg.com/@loaders.gl/${y.module}${f}/dist/${b}`}return mt(_),_}(s,t),u=_s.getWorkerFarm(t).getWorkerPool({name:i,url:o});t=JSON.parse(JSON.stringify(t)),r=JSON.parse(JSON.stringify(r||{}));const l=await u.startJob("process-on-worker",jd.bind(null,n));return l.postMessage("process",{input:e,options:t,context:r}),await(await l.result).result}async function jd(s,e,t,r){switch(t){case"done":e.done(r);break;case"error":e.error(new Error(r.error));break;case"process":const{id:n,input:i,options:o}=r;try{const u=await s(i,o);e.postMessage("done",{id:n,result:u})}catch(u){const l=u instanceof Error?u.message:"unknown error";e.postMessage("error",{id:n,error:l})}break;default:console.warn(`parse-with-worker unknown message ${t}`)}}function ka(s,e,t){if(s.byteLength<=e+t)return"";const r=new DataView(s);let n="";for(let i=0;io instanceof ArrayBuffer?new Uint8Array(o):o),r=t.reduce((o,u)=>o+u.byteLength,0),n=new Uint8Array(r);let i=0;for(const o of t)n.set(o,i),i+=o.byteLength;return n.buffer}(s)}function Na(s,e,t){const r=t!==void 0?new Uint8Array(s).subarray(e,e+t):new Uint8Array(s).subarray(e);return new Uint8Array(r).buffer}function Gr(s,e){return pt(s>=0),pt(e>0),s+(e-1)&~(e-1)}function Xd(s,e,t){let r;if(s instanceof ArrayBuffer)r=new Uint8Array(s);else{const n=s.byteOffset,i=s.byteLength;r=new Uint8Array(s.buffer||s.arrayBuffer,n,i)}return e.set(r,t),t+Gr(r.byteLength,4)}const Va={};function Ha(s){if((e=s)&&typeof e=="object"&&e.isBuffer)return s;var e;if(s instanceof ArrayBuffer)return s;if(ArrayBuffer.isView(s))return s.byteOffset===0&&s.byteLength===s.buffer.byteLength?s.buffer:s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength);if(typeof s=="string"){const t=s;return new TextEncoder().encode(t).buffer}if(s&&typeof s=="object"&&s._toArrayBuffer)return s._toArrayBuffer();throw new Error("toArrayBuffer")}function Ja(s){const e=s?s.lastIndexOf("/"):-1;return e>=0?s.substr(e+1):""}const Lr=s=>typeof s=="function",Or=s=>s!==null&&typeof s=="object",za=s=>Or(s)&&s.constructor==={}.constructor,Ht=s=>typeof Response<"u"&&s instanceof Response||s&&s.arrayBuffer&&s.text&&s.json,Jt=s=>typeof Blob<"u"&&s instanceof Blob,ja=s=>(e=>typeof ReadableStream<"u"&&e instanceof ReadableStream||Or(e)&&Lr(e.tee)&&Lr(e.cancel)&&Lr(e.getReader))(s)||(e=>Or(e)&&Lr(e.read)&&Lr(e.pipe)&&(t=>typeof t=="boolean")(e.readable))(s);class Yd extends Error{constructor(t,r){super(t);ee(this,"reason");ee(this,"url");ee(this,"response");this.reason=r.reason,this.url=r.url,this.response=r.response}}const Wd=/^data:([-\w.]+\/[-\w.+]+)(;|,)/,qd=/^([-\w.]+\/[-\w.+]+)/;function Ka(s,e){return s.toLowerCase()===e.toLowerCase()}function $a(s){const e=Wd.exec(s);return e?e[1]:""}const Xa=/\?.*/;function oi(s){return s.replace(Xa,"")}function Bs(s){return Ht(s)?s.url:Jt(s)?s.name||"":typeof s=="string"?s:""}function ai(s){if(Ht(s)){const e=s,t=e.headers.get("content-type")||"",r=oi(e.url);return function(n){const i=qd.exec(n);return i?i[1]:n}(t)||$a(r)}return Jt(s)?s.type||"":typeof s=="string"?$a(s):""}async function Ya(s){if(Ht(s))return s;const e={},t=function(u){return Ht(u)?u.headers["content-length"]||-1:Jt(u)?u.size:typeof u=="string"?u.length:u instanceof ArrayBuffer||ArrayBuffer.isView(u)?u.byteLength:-1}(s);t>=0&&(e["content-length"]=String(t));const r=Bs(s),n=ai(s);n&&(e["content-type"]=n);const i=await async function(u){if(typeof u=="string")return`data:,${u.slice(0,5)}`;if(u instanceof Blob){const m=u.slice(0,5);return await new Promise(y=>{const d=new FileReader;d.onload=x=>{var b;return y((b=x==null?void 0:x.target)==null?void 0:b.result)},d.readAsDataURL(m)})}return u instanceof ArrayBuffer?`data:base64,${function(m){let y="";const d=new Uint8Array(m);for(let x=0;x100?`${n.slice(0,100)}...`:n;const i={reason:t.statusText,url:t.url,response:t};try{const o=t.headers.get("Content-Type");i.reason=!t.bodyUsed&&(o!=null&&o.includes("application/json"))?await t.json():await t.text()}catch{}return new Yd(n,i)}(s)}async function Wa(s,e){var t,r;if(typeof s=="string"){const n=function(i){for(const o in Va)if(i.startsWith(o)){const u=Va[o];i=i.replace(o,u)}return i.startsWith("http://")||i.startsWith("https://")||(i=`${i}`),i}(s);return function(i){return!function(o){return o.startsWith("http:")||o.startsWith("https:")}(i)&&!function(o){return o.startsWith("data:")}(i)}(n)&&((t=globalThis.loaders)!=null&&t.fetchNode)?(r=globalThis.loaders)==null?void 0:r.fetchNode(n,e):await fetch(n,e)}return await Ya(s)}const qa=new Qn({id:"loaders.gl"});class Zd{log(){return()=>{}}info(){return()=>{}}warn(){return()=>{}}error(){return()=>{}}}const Qa={fetch:null,mimeType:void 0,nothrow:!1,log:new class{constructor(){ee(this,"console");this.console=console}log(...s){return this.console.log.bind(this.console,...s)}info(...s){return this.console.info.bind(this.console,...s)}warn(...s){return this.console.warn.bind(this.console,...s)}error(...s){return this.console.error.bind(this.console,...s)}},useLocalLibraries:!1,CDN:"https://unpkg.com/@loaders.gl",worker:!0,maxConcurrency:3,maxMobileConcurrency:1,reuseWorkers:ys,_nodeWorkers:!1,_workerType:"",limit:0,_limitMB:0,batchSize:"auto",batchDebounceMs:0,metadata:!1,transforms:[]},eh={throws:"nothrow",dataType:"(no longer used)",uri:"baseUri",method:"fetch.method",headers:"fetch.headers",body:"fetch.body",mode:"fetch.mode",credentials:"fetch.credentials",cache:"fetch.cache",redirect:"fetch.redirect",referrer:"fetch.referrer",referrerPolicy:"fetch.referrerPolicy",integrity:"fetch.integrity",keepalive:"fetch.keepalive",signal:"fetch.signal"};function Za(){globalThis.loaders=globalThis.loaders||{};const{loaders:s}=globalThis;return s._state||(s._state={}),s._state}function eu(){const s=Za();return s.globalOptions=s.globalOptions||{...Qa},s.globalOptions}function th(s,e,t,r){return t=t||[],function(n,i){tu(n,null,Qa,eh,i);for(const o of i){const u=n&&n[o.id]||{},l=o.options&&o.options[o.id]||{},m=o.deprecatedOptions&&o.deprecatedOptions[o.id]||{};tu(u,o.id,l,m,i)}}(s,t=Array.isArray(t)?t:[t]),function(n,i,o){const u=n.options||{},l={...u};return function(m,y){y&&!("baseUri"in m)&&(m.baseUri=y)}(l,o),l.log===null&&(l.log=new Zd),ru(l,eu()),ru(l,i),l}(e,s,r)}function tu(s,e,t,r,n){const i=e||"Top level",o=e?`${e}.`:"";for(const u in s){const l=!e&&Or(s[u]);if(!(u in t)&&!(u==="baseUri"&&!e)&&!(u==="workerUrl"&&e)){if(u in r)qa.warn(`${i} loader option '${o}${u}' no longer supported, use '${r[u]}'`)();else if(!l){const m=rh(u,n);qa.warn(`${i} loader option '${o}${u}' not recognized. ${m}`)()}}}}function rh(s,e){const t=s.toLowerCase();let r="";for(const n of e)for(const i in n.options){if(s===i)return`Did you mean '${n.id}.${i}'?`;const o=i.toLowerCase();(t.startsWith(o)||o.startsWith(t))&&(r=r||`Did you mean '${n.id}.${i}'?`)}return r}function ru(s,e){for(const t in e)if(t in e){const r=e[t];za(r)&&za(s[t])?s[t]={...s[t],...e[t]}:s[t]=e[t]}}function ui(s){return s?(Array.isArray(s)&&(s=s[0]),Array.isArray(s==null?void 0:s.extensions)):!1}function su(s){let e;return pt(s,"null loader"),pt(ui(s),"invalid loader"),Array.isArray(s)&&(e=s[1],s=s[0],s={...s,options:{...s.options,...e}}),(s!=null&&s.parseTextSync||s!=null&&s.parseText)&&(s.text=!0),s.text||(s.binary=!0),s}function sh(){return(()=>{const s=Za();return s.loaderRegistry=s.loaderRegistry||[],s.loaderRegistry})()}const nh=/\.([^.]+)$/;function nu(s,e=[],t,r){if(!iu(s))return null;if(e&&!Array.isArray(e))return su(e);let n=[];e&&(n=n.concat(e)),t!=null&&t.ignoreRegisteredLoaders||n.push(...sh()),function(o){for(const u of o)su(u)}(n);const i=function(o,u,l,m){const y=Bs(o),d=ai(o),x=oi(y)||(m==null?void 0:m.url);let b=null,_="";return l!=null&&l.mimeType&&(b=ci(u,l==null?void 0:l.mimeType),_=`match forced by supplied MIME type ${l==null?void 0:l.mimeType}`),b=b||function(C,f){const p=f&&nh.exec(f),a=p&&p[1];return a?function(c,h){h=h.toLowerCase();for(const g of c)for(const B of g.extensions)if(B.toLowerCase()===h)return g;return null}(C,a):null}(u,x),_=_||(b?`matched url ${x}`:""),b=b||ci(u,d),_=_||(b?`matched MIME type ${d}`:""),b=b||function(C,f){if(!f)return null;for(const p of C)if(typeof f=="string"){if(ih(f,p))return p}else if(ArrayBuffer.isView(f)){if(au(f.buffer,f.byteOffset,p))return p}else if(f instanceof ArrayBuffer&&au(f,0,p))return p;return null}(u,o),_=_||(b?`matched initial data ${uu(o)}`:""),l!=null&&l.fallbackMimeType&&(b=b||ci(u,l==null?void 0:l.fallbackMimeType),_=_||(b?`matched fallback MIME type ${d}`:"")),_&&Dd.log(1,`selectLoader selected ${b==null?void 0:b.name}: ${_}.`),b}(s,n,t,r);if(!i&&!(t!=null&&t.nothrow))throw new Error(ou(s));return i}function iu(s){return!(s instanceof Response&&s.status===204)}function ou(s){const e=Bs(s),t=ai(s);let r="No valid loader found (";r+=e?`${Ja(e)}, `:"no url provided, ",r+=`MIME type: ${t?`"${t}"`:"not provided"}, `;const n=s?uu(s):"";return r+=n?` first bytes: "${n}"`:"first bytes: not available",r+=")",r}function ci(s,e){var t;for(const r of s)if((t=r.mimeTypes)!=null&&t.some(n=>Ka(e,n))||Ka(e,`application/x.${r.id}`))return r;return null}function ih(s,e){return e.testText?e.testText(s):(Array.isArray(e.tests)?e.tests:[e.tests]).some(t=>s.startsWith(t))}function au(s,e,t){return(Array.isArray(t.tests)?t.tests:[t.tests]).some(r=>function(n,i,o,u){if(u instanceof ArrayBuffer)return function(l,m,y){if(y=y||l.byteLength,l.byteLengthi&&typeof i[Symbol.asyncIterator]=="function")(s))return async function(i){const o=[];for await(const u of i)o.push(u);return $d(...o)}(s);var n;throw new Error(lu)}function du(s,e){const t=eu(),r=s||t;return typeof r.fetch=="function"?r.fetch:Or(r.fetch)?n=>Wa(n,r.fetch):e!=null&&e.fetch?e==null?void 0:e.fetch:Wa}function ch(s,e,t){if(t)return t;const r={fetch:du(e,s),...s};if(r.url){const n=oi(r.url);r.baseUrl=n,r.queryString=function(i){const o=i.match(Xa);return o&&o[0]}(r.url),r.filename=Ja(n),r.baseUrl=function(i){const o=i?i.lastIndexOf("/"):-1;return o>=0?i.substr(0,o):""}(n)}return Array.isArray(r.loaders)||(r.loaders=null),r}async function di(s,e,t,r){!e||Array.isArray(e)||ui(e)||(r=void 0,t=e,e=void 0),t=t||{};const n=Bs(s=await s),i=function(u,l){if(u&&!Array.isArray(u))return u;let m;if(u&&(m=Array.isArray(u)?u:[u]),l&&l.loaders){const y=Array.isArray(l.loaders)?l.loaders:[l.loaders];m=m?[...m,...y]:y}return m&&m.length?m:void 0}(e,r),o=await async function(u,l=[],m,y){if(!iu(u))return null;let d=nu(u,l,{...m,nothrow:!0},y);if(d)return d;if(Jt(u)&&(d=nu(u=await u.slice(0,10).arrayBuffer(),l,m,y)),!d&&!(m!=null&&m.nothrow))throw new Error(ou(u));return d}(s,i,t);return o?(r=ch({url:n,_parse:di,loaders:i},t=th(t,o,i,n),r||null),await async function(u,l,m,y){if(function(x){mt(x,"no worker provided");const b=x.version}(u),m=Fd(u.options,m),Ht(l)){const x=l,{ok:b,redirected:_,status:C,statusText:f,type:p,url:a}=x,c=Object.fromEntries(x.headers.entries());y.response={headers:c,ok:b,redirected:_,status:C,statusText:f,type:p,url:a}}l=await uh(l,u,m);const d=u;if(d.parseTextSync&&typeof l=="string")return d.parseTextSync(l,m,y);if(function(x,b){return!!_s.isSupported()&&!(!ze&&!(b!=null&&b._nodeWorkers))&&x.worker&&(b==null?void 0:b.worker)}(u,m))return await zd(u,l,m,y,di);if(d.parseText&&typeof l=="string")return await d.parseText(l,m,y);if(d.parse)return await d.parse(l,m,y);throw mt(!d.parseSync),new Error(`${u.id} loader - no parser found and worker is disabled`)}(o,s,t,r)):null}function lh(s,e,t){const r=function(i){switch(i.constructor){case Int8Array:return"int8";case Uint8Array:case Uint8ClampedArray:return"uint8";case Int16Array:return"int16";case Uint16Array:return"uint16";case Int32Array:return"int32";case Uint32Array:return"uint32";case Float32Array:return"float32";case Float64Array:return"float64";default:return"null"}}(e.value),n=t||function(i){const o={};return"byteOffset"in i&&(o.byteOffset=i.byteOffset.toString(10)),"byteStride"in i&&(o.byteStride=i.byteStride.toString(10)),"normalized"in i&&(o.normalized=i.normalized.toString()),o}(e);return{name:s,type:{type:"fixed-size-list",listSize:e.size,children:[{name:"value",type:r}]},nullable:!1,metadata:n}}const dh=(nl=globalThis.loaders)==null?void 0:nl.parseImageNode,hi=typeof Image<"u",fi=typeof ImageBitmap<"u",hh=!!dh,pi=!!ys||hh;function fh(s){const e=function(t){return typeof ImageBitmap<"u"&&t instanceof ImageBitmap?"imagebitmap":typeof Image<"u"&&t instanceof Image?"image":t&&typeof t=="object"&&t.data&&t.width&&t.height?"data":null}(s);if(!e)throw new Error("Not an image");return e}function hu(s){switch(fh(s)){case"data":return s;case"image":case"imagebitmap":const e=document.createElement("canvas"),t=e.getContext("2d");if(!t)throw new Error("getImageData");return e.width=s.width,e.height=s.height,t.drawImage(s,0,0),t.getImageData(0,0,s.width,s.height);default:throw new Error("getImageData")}}const ph=/^data:image\/svg\+xml/,mh=/\.svg((\?|#).*)?$/;function mi(s){return s&&(ph.test(s)||mh.test(s))}function fu(s,e){if(mi(e))throw new Error("SVG cannot be parsed directly to imagebitmap");return new Blob([new Uint8Array(s)])}async function pu(s,e,t){const r=function(o,u){if(mi(u)){let l=new TextDecoder().decode(o);try{typeof unescape=="function"&&typeof encodeURIComponent=="function"&&(l=unescape(encodeURIComponent(l)))}catch(m){throw new Error(m.message)}return`data:image/svg+xml;base64,${btoa(l)}`}return fu(o,u)}(s,t),n=self.URL||self.webkitURL,i=typeof r!="string"&&n.createObjectURL(r);try{return await async function(o,u){const l=new Image;return l.src=o,u.image&&u.image.decode&&l.decode?(await l.decode(),l):await new Promise((m,y)=>{try{l.onload=()=>m(l),l.onerror=d=>{const x=d instanceof Error?d.message:"error";y(new Error(x))}}catch(d){y(d)}})}(i||r,e)}finally{i&&n.revokeObjectURL(i)}}const gh={};let mu=!0;async function yh(s,e,t){let r;mi(t)?r=await pu(s,e,t):r=fu(s,t);const n=e&&e.imagebitmap;return await async function(i,o=null){if(!function(u){for(const l in u||gh)return!1;return!0}(o)&&mu||(o=null),o)try{return await createImageBitmap(i,o)}catch(u){console.warn(u),mu=!1}return await createImageBitmap(i)}(r,n)}function bh(s){return function(e,t,r=0){const n=(i=t,[...i].map(o=>o.charCodeAt(0)));var i;for(let o=0;o=24&&r.getUint32(0,at)===2303741511?{mimeType:"image/png",width:r.getUint32(16,at),height:r.getUint32(20,at)}:null}(e)||function(t){const r=Dr(t);if(!(r.byteLength>=3&&r.getUint16(0,at)===65496&&r.getUint8(2)===255))return null;const{tableMarkers:i,sofMarkers:o}=function(){const l=new Set([65499,65476,65484,65501,65534]);for(let y=65504;y<65520;++y)l.add(y);return{tableMarkers:l,sofMarkers:new Set([65472,65473,65474,65475,65477,65478,65479,65481,65482,65483,65485,65486,65487,65502])}}();let u=2;for(;u+9=10&&r.getUint32(0,at)===1195984440?{mimeType:"image/gif",width:r.getUint16(6,Ir),height:r.getUint16(8,Ir)}:null}(e)||function(t){const r=Dr(t);return r.byteLength>=14&&r.getUint16(0,at)===16973&&r.getUint32(2,Ir)===r.byteLength?{mimeType:"image/bmp",width:r.getUint32(18,Ir),height:r.getUint32(22,Ir)}:null}(e)||function(t){const r=new Uint8Array(t instanceof DataView?t.buffer:t),n=bh(r);return n?{mimeType:n.mimeType,width:0,height:0}:null}(e)}function Dr(s){if(s instanceof DataView)return s;if(ArrayBuffer.isView(s))return new DataView(s.buffer);if(s instanceof ArrayBuffer)return new DataView(s);throw new Error("toDataView")}const xh={dataType:null,batchType:null,id:"image",module:"images",name:"Images",version:"4.3.2",mimeTypes:["image/png","image/jpeg","image/gif","image/webp","image/avif","image/bmp","image/vnd.microsoft.icon","image/svg+xml"],extensions:["png","jpg","jpeg","gif","webp","bmp","ico","svg","avif"],parse:async function(s,e,t){const r=((e=e||{}).image||{}).type||"auto",{url:n}=t||{};let i;switch(function(o){switch(o){case"auto":case"data":return function(){if(fi)return"imagebitmap";if(hi)return"image";if(pi)return"data";throw new Error("Install '@loaders.gl/polyfills' to parse images under Node.js")}();default:return function(u){switch(u){case"auto":return fi||hi||pi;case"imagebitmap":return fi;case"image":return hi;case"data":return pi;default:throw new Error(`@loaders.gl/images: image ${u} not supported in this environment`)}}(o),o}}(r)){case"imagebitmap":i=await yh(s,e,n);break;case"image":i=await pu(s,e,n);break;case"data":i=await async function(o){var m;const{mimeType:u}=gi(o)||{},l=(m=globalThis.loaders)==null?void 0:m.parseImageNode;return pt(l),await l(o,u)}(s);break;default:pt(!1)}return r==="data"&&(i=hu(i)),i},tests:[s=>!!gi(new DataView(s))],options:{image:{type:"auto",decode:!0}}},yi={};function _h(s){if(yi[s]===void 0){const e=ys?function(t){switch(t){case"image/avif":case"image/webp":return function(r){try{return document.createElement("canvas").toDataURL(r).indexOf(`data:${r}`)===0}catch{return!1}}(t);default:return!0}}(s):function(t){var o,u;const r=["image/png","image/jpeg","image/gif"],n=((o=globalThis.loaders)==null?void 0:o.imageFormatsNode)||r;return!!((u=globalThis.loaders)==null?void 0:u.parseImageNode)&&n.includes(t)}(s);yi[s]=e}return yi[s]}function Me(s,e){if(!s)throw new Error(e||"assert failed: gltf")}const gu={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},yu={5120:1,5121:1,5122:2,5123:2,5125:4,5126:4},bu=["SCALAR","VEC2","VEC3","VEC4"],Bh=[[Int8Array,5120],[Uint8Array,5121],[Int16Array,5122],[Uint16Array,5123],[Uint32Array,5125],[Float32Array,5126],[Float64Array,5130]],Ah=new Map(Bh),vh={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},wh={5120:1,5121:1,5122:2,5123:2,5125:4,5126:4},Ch={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array};function xu(s){return bu[s-1]||bu[0]}function As(s){const e=Ah.get(s.constructor);if(!e)throw new Error("Illegal typed array");return e}function bi(s,e){const t=Ch[s.componentType],r=vh[s.type],n=wh[s.componentType],i=s.count*r,o=s.count*r*n;return Me(o>=0&&o<=e.byteLength),{ArrayType:t,length:i,byteLength:o,componentByteSize:yu[s.componentType],numberOfComponentsInElement:gu[s.type]}}class _e{constructor(e){ee(this,"gltf");ee(this,"sourceBuffers");ee(this,"byteLength");this.gltf={json:(e==null?void 0:e.json)||{asset:{version:"2.0",generator:"loaders.gl"},buffers:[],extensions:{},extensionsRequired:[],extensionsUsed:[]},buffers:(e==null?void 0:e.buffers)||[],images:(e==null?void 0:e.images)||[]},this.sourceBuffers=[],this.byteLength=0,this.gltf.buffers&&this.gltf.buffers[0]&&(this.byteLength=this.gltf.buffers[0].byteLength,this.sourceBuffers=[this.gltf.buffers[0]])}get json(){return this.gltf.json}getApplicationData(e){return this.json[e]}getExtraData(e){return(this.json.extras||{})[e]}hasExtension(e){const t=this.getUsedExtensions().find(n=>n===e),r=this.getRequiredExtensions().find(n=>n===e);return typeof t=="string"||typeof r=="string"}getExtension(e){const t=this.getUsedExtensions().find(n=>n===e),r=this.json.extensions||{};return t?r[e]:null}getRequiredExtension(e){return this.getRequiredExtensions().find(r=>r===e)?this.getExtension(e):null}getRequiredExtensions(){return this.json.extensionsRequired||[]}getUsedExtensions(){return this.json.extensionsUsed||[]}getRemovedExtensions(){return this.json.extensionsRemoved||[]}getObjectExtension(e,t){return(e.extensions||{})[t]}getScene(e){return this.getObject("scenes",e)}getNode(e){return this.getObject("nodes",e)}getSkin(e){return this.getObject("skins",e)}getMesh(e){return this.getObject("meshes",e)}getMaterial(e){return this.getObject("materials",e)}getAccessor(e){return this.getObject("accessors",e)}getTexture(e){return this.getObject("textures",e)}getSampler(e){return this.getObject("samplers",e)}getImage(e){return this.getObject("images",e)}getBufferView(e){return this.getObject("bufferViews",e)}getBuffer(e){return this.getObject("buffers",e)}getObject(e,t){if(typeof t=="object")return t;const r=this.json[e]&&this.json[e][t];if(!r)throw new Error(`glTF file error: Could not find ${e}[${t}]`);return r}getTypedArrayForBufferView(e){const t=(e=this.getBufferView(e)).buffer,r=this.gltf.buffers[t];Me(r);const n=(e.byteOffset||0)+r.byteOffset;return new Uint8Array(r.arrayBuffer,n,e.byteLength)}getTypedArrayForAccessor(e){const t=this.getAccessor(e);return function(r,n,i){var a,c;const o=typeof i=="number"?(a=r.accessors)==null?void 0:a[i]:i;if(!o)throw new Error(`No gltf accessor ${JSON.stringify(i)}`);const u=(c=r.bufferViews)==null?void 0:c[o.bufferView||0];if(!u)throw new Error(`No gltf buffer view for accessor ${u}`);const{arrayBuffer:l,byteOffset:m}=n[u.buffer],y=(m||0)+(o.byteOffset||0)+(u.byteOffset||0),{ArrayType:d,length:x,componentByteSize:b,numberOfComponentsInElement:_}=bi(o,u),C=b*_,f=u.byteStride||C;if(u.byteStride===void 0||u.byteStride===C)return new d(l,y,x);const p=new d(x);for(let h=0;ht===e)||this.json.extensionsUsed.push(e)}registerRequiredExtension(e){this.registerUsedExtension(e),this.json.extensionsRequired=this.json.extensionsRequired||[],this.json.extensionsRequired.find(t=>t===e)||this.json.extensionsRequired.push(e)}removeExtension(e){var t;if((t=this.json.extensions)!=null&&t[e]){this.json.extensionsRemoved=this.json.extensionsRemoved||[];const r=this.json.extensionsRemoved;r.includes(e)||r.push(e)}this.json.extensions&&delete this.json.extensions[e],this.json.extensionsRequired&&this._removeStringFromArray(this.json.extensionsRequired,e),this.json.extensionsUsed&&this._removeStringFromArray(this.json.extensionsUsed,e)}setDefaultScene(e){this.json.scene=e}addScene(e){const{nodeIndices:t}=e;return this.json.scenes=this.json.scenes||[],this.json.scenes.push({nodes:t}),this.json.scenes.length-1}addNode(e){const{meshIndex:t,matrix:r}=e;this.json.nodes=this.json.nodes||[];const n={mesh:t};return r&&(n.matrix=r),this.json.nodes.push(n),this.json.nodes.length-1}addMesh(e){const{attributes:t,indices:r,material:n,mode:i=4}=e,o={primitives:[{attributes:this._addAttributes(t),mode:i}]};if(r){const u=this._addIndices(r);o.primitives[0].indices=u}return Number.isFinite(n)&&(o.primitives[0].material=n),this.json.meshes=this.json.meshes||[],this.json.meshes.push(o),this.json.meshes.length-1}addPointCloud(e){const t={primitives:[{attributes:this._addAttributes(e),mode:0}]};return this.json.meshes=this.json.meshes||[],this.json.meshes.push(t),this.json.meshes.length-1}addImage(e,t){const r=gi(e),n=t||(r==null?void 0:r.mimeType),i={bufferView:this.addBufferView(e),mimeType:n};return this.json.images=this.json.images||[],this.json.images.push(i),this.json.images.length-1}addBufferView(e,t=0,r=this.byteLength){const n=e.byteLength;Me(Number.isFinite(n)),this.sourceBuffers=this.sourceBuffers||[],this.sourceBuffers.push(e);const i={buffer:t,byteOffset:r,byteLength:n};return this.byteLength+=Gr(n,4),this.json.bufferViews=this.json.bufferViews||[],this.json.bufferViews.push(i),this.json.bufferViews.length-1}addAccessor(e,t){const r={bufferView:e,type:xu(t.size),componentType:t.componentType,count:t.count,max:t.max,min:t.min};return this.json.accessors=this.json.accessors||[],this.json.accessors.push(r),this.json.accessors.length-1}addBinaryBuffer(e,t={size:3}){const r=this.addBufferView(e);let n={min:t.min,max:t.max};n.min&&n.max||(n=this._getAccessorMinMax(e,t.size));const i={size:t.size,componentType:As(e),count:Math.round(e.length/t.size),min:n.min,max:n.max};return this.addAccessor(r,Object.assign(i,t))}addTexture(e){const{imageIndex:t}=e,r={source:t};return this.json.textures=this.json.textures||[],this.json.textures.push(r),this.json.textures.length-1}addMaterial(e){return this.json.materials=this.json.materials||[],this.json.materials.push(e),this.json.materials.length-1}createBinaryChunk(){var i,o;const e=this.byteLength,t=new ArrayBuffer(e),r=new Uint8Array(t);let n=0;for(const u of this.sourceBuffers||[])n=Xd(u,r,n);(o=(i=this.json)==null?void 0:i.buffers)!=null&&o[0]?this.json.buffers[0].byteLength=e:this.json.buffers=[{byteLength:e}],this.gltf.binary=t,this.sourceBuffers=[t],this.gltf.buffers=[{arrayBuffer:t,byteOffset:0,byteLength:t.byteLength}]}_removeStringFromArray(e,t){let r=!0;for(;r;){const n=e.indexOf(t);n>-1?e.splice(n,1):r=!1}}_addAttributes(e={}){const t={};for(const r in e){const n=e[r],i=this._getGltfAttributeName(r),o=this.addBinaryBuffer(n.value,n);t[i]=o}return t}_addIndices(e){return this.addBinaryBuffer(e,{size:1})}_getGltfAttributeName(e){switch(e.toLowerCase()){case"position":case"positions":case"vertices":return"POSITION";case"normal":case"normals":return"NORMAL";case"color":case"colors":return"COLOR_0";case"texcoord":case"texcoords":return"TEXCOORD_0";default:return e}}_getAccessorMinMax(e,t){const r={min:null,max:null};if(e.lengthx===y);d===-1&&(d=r.push(y)-1),i.push(d)}const o=new Uint32Array(i),u=s.gltf.buffers.push({arrayBuffer:o.buffer,byteOffset:o.byteOffset,byteLength:o.byteLength})-1,l=s.addBufferView(o,u,0),m=s.addAccessor(l,{size:1,componentType:As(o),count:o.length});n.attributes[e]=m}function Sh(s,e,t,r,n=[0]){const i={r:{offset:0,shift:0},g:{offset:1,shift:8},b:{offset:2,shift:16},a:{offset:3,shift:24}},o=t[r],u=t[r+1];let l=1;!e||e.indexOf("image/jpeg")===-1&&e.indexOf("image/png")===-1||(l=4);const m=function(d,x,b,_=1){const C=b.width,f=_u(d)*(C-1),p=Math.round(f),a=b.height,c=_u(x)*(a-1),h=Math.round(c),g=b.components?b.components:_;return(h*C+p)*g}(o,u,s,l);let y=0;for(const d of n){const x=typeof d=="number"?Object.values(i)[d]:i[d],b=m+x.offset,_=hu(s);if(_.data.length<=b)throw new Error(`${_.data.length} <= ${b}`);y|=_.data[b]<r)break;const m=u/n,y=l/n;i.push(s.slice(m,m+y))}return i}function Cu(s,e,t){const r=[];for(let n=0;n{if(i.data){const{accessorKey:u,index:l}=function(x){const b="_FEATURE_ID_",_=Object.keys(x).filter(p=>p.indexOf(b)===0);let C=-1;for(const p of _){const a=Number(p.substring(b.length));a>C&&(C=a)}return C++,{accessorKey:`${b}${C}`,index:C}}(e.attributes),m=new Uint32Array(i.data);r[o]={featureCount:m.length,propertyTable:i.propertyTable,attribute:l},s.gltf.buffers.push({arrayBuffer:m.buffer,byteOffset:m.byteOffset,byteLength:m.byteLength});const y=s.addBufferView(m),d=s.addAccessor(y,{size:1,componentType:As(m),count:m.length});e.attributes[u]=d}})}const Rh=Object.freeze(Object.defineProperty({__proto__:null,createExtMeshFeatures:function(s,e,t,r){e.extensions||(e.extensions={});let n=e.extensions[hr];n||(n={featureIds:[]},e.extensions[hr]=n);const{featureIds:i}=n,o={featureCount:t.length,propertyTable:r,data:t};i.push(o),s.addObjectExtension(e,hr,n)},decode:async function(s,e){(function(t,r){const n=t.gltf.json;if(n.meshes)for(const i of n.meshes)for(const o of i.primitives)Mh(t,o,r)})(new _e(s),e)},encode:function(s,e){const t=new _e(s);return function(r){const n=r.gltf.json.meshes;if(n)for(const i of n)for(const o of i.primitives)Ph(r,o)}(t),t.createBinaryChunk(),t.gltf},name:Eh},Symbol.toStringTag,{value:"Module"})),fr="EXT_structural_metadata",Gh=fr;function Lh(s,e){for(const t of s)if(t.class===e)return t;return null}function Oh(s,e,t,r){var o;if(!e)return;const n=(o=t.extensions)==null?void 0:o[fr],i=n==null?void 0:n.propertyTextures;if(i)for(const u of i)Ih(s,e[u],t,r)}function Ih(s,e,t,r){var i;if(!e.properties)return;r.dataAttributeNames||(r.dataAttributeNames=[]);const n=e.class;for(const o in e.properties){const u=`${n}_${o}`,l=(i=e.properties)==null?void 0:i[o];if(!l)continue;l.data||(l.data=[]);const m=l.data,y=_i(s,l,t);y!==null&&(vu(s,u,y,m,t),l.data=m,r.dataAttributeNames.push(u))}}function Dh(s,e,t){var i,o;const r=(i=e.classes)==null?void 0:i[t.class];if(!r)throw new Error(`Incorrect data in the EXT_structural_metadata extension: no schema class with name ${t.class}`);const n=t.count;for(const u in r.properties){const l=r.properties[u],m=(o=t.properties)==null?void 0:o[u];if(m){const y=Fh(s,e,l,n,m);m.data=y}}}function Fh(s,e,t,r,n){let i=[];const o=n.values,u=s.getTypedArrayForBufferView(o),l=function(y,d,x,b){return d.array&&d.count===void 0&&x.arrayOffsets!==void 0?vs(y,x.arrayOffsets,x.arrayOffsetType||"UINT32",b):null}(s,t,n,r),m=function(y,d,x){return d.stringOffsets!==void 0?vs(y,d.stringOffsets,d.stringOffsetType||"UINT32",x):null}(s,n,r);switch(t.type){case"SCALAR":case"VEC2":case"VEC3":case"VEC4":case"MAT2":case"MAT3":case"MAT4":i=function(y,d,x,b){const _=y.array,C=y.count,f=xi(y.type,y.componentType),p=x.byteLength/f;let a;return a=y.componentType?ws(x,y.type,y.componentType,p):x,_?b?wu(a,d,b,x.length,f):C?Cu(a,d,C):[]:a}(t,r,u,l);break;case"BOOLEAN":throw new Error(`Not implemented - classProperty.type=${t.type}`);case"STRING":i=Tu(r,u,l,m);break;case"ENUM":i=function(y,d,x,b,_){var g;const C=d.enumType;if(!C)throw new Error("Incorrect data in the EXT_structural_metadata extension: classProperty.enumType is not set for type ENUM");const f=(g=y.enums)==null?void 0:g[C];if(!f)throw new Error(`Incorrect data in the EXT_structural_metadata extension: schema.enums does't contain ${C}`);const p=f.valueType||"UINT16",a=xi(d.type,p),c=b.byteLength/a;let h=ws(b,d.type,p,c);if(h||(h=b),d.array){if(_)return function(w){const{valuesData:R,numberOfElements:U,arrayOffsets:k,valuesDataBytesLength:T,elementSize:S,enumEntry:P}=w,L=[];for(let D=0;DT)break;const K=Bi(R,O/S,H/S,P);L.push(K)}return L}({valuesData:h,numberOfElements:x,arrayOffsets:_,valuesDataBytesLength:b.length,elementSize:a,enumEntry:f});const B=d.count;return B?function(w,R,U,k){const T=[];for(let S=0;S{u(m).then(d=>{const{BasisFile:x,initializeBasis:b}=d;b(),y({BasisFile:x})})})}(i,o)}(s)),await Eu)}async function Pu(s){const e=s.modules||{};return e.basisEncoder?e.basisEncoder:(vi=vi||async function(t){let r=null,n=null;return[r,n]=await Promise.all([await Vt(ef,"textures",t),await Vt(tf,"textures",t)]),r=r||globalThis.BASIS,await function(i,o){const u={};return o&&(u.wasmBinary=o),new Promise(l=>{i(u).then(m=>{const{BasisFile:y,KTX2File:d,initializeBasis:x,BasisEncoder:b}=m;x(),l({BasisFile:y,KTX2File:d,BasisEncoder:b})})})}(r,n)}(s),await vi)}const rf=["","WEBKIT_","MOZ_"],Ru={WEBGL_compressed_texture_s3tc:"dxt",WEBGL_compressed_texture_s3tc_srgb:"dxt-srgb",WEBGL_compressed_texture_etc1:"etc1",WEBGL_compressed_texture_etc:"etc2",WEBGL_compressed_texture_pvrtc:"pvrtc",WEBGL_compressed_texture_atc:"atc",WEBGL_compressed_texture_astc:"astc",EXT_texture_compression_rgtc:"rgtc"};let Cs=null;function sf(s){if(!Cs){s=s||function(){try{return document.createElement("canvas").getContext("webgl")}catch{return null}}()||void 0,Cs=new Set;for(const e of rf)for(const t in Ru)if(s&&s.getExtension(`${e}${t}`)){const r=Ru[t];Cs.add(r)}}return Cs}const Pe=[171,75,84,88,32,50,48,187,13,10,26,10],nf={etc1:{basisFormat:0,compressed:!0,format:36196},etc2:{basisFormat:1,compressed:!0},bc1:{basisFormat:2,compressed:!0,format:33776},bc3:{basisFormat:3,compressed:!0,format:33779},bc4:{basisFormat:4,compressed:!0},bc5:{basisFormat:5,compressed:!0},"bc7-m6-opaque-only":{basisFormat:6,compressed:!0},"bc7-m5":{basisFormat:7,compressed:!0},"pvrtc1-4-rgb":{basisFormat:8,compressed:!0,format:35840},"pvrtc1-4-rgba":{basisFormat:9,compressed:!0,format:35842},"astc-4x4":{basisFormat:10,compressed:!0,format:37808},"atc-rgb":{basisFormat:11,compressed:!0},"atc-rgba-interpolated-alpha":{basisFormat:12,compressed:!0},rgba32:{basisFormat:13,compressed:!1},rgb565:{basisFormat:14,compressed:!1},bgr565:{basisFormat:15,compressed:!1},rgba4444:{basisFormat:16,compressed:!1}};function wi(s,e,t){const r=new s(new Uint8Array(e));try{if(!r.startTranscoding())throw new Error("Failed to start basis transcoding");const n=r.getNumImages(),i=[];for(let o=0;o20);const d=m.getUint32(y+0,pr),x=m.getUint32(y+4,pr);return y+=8,pt(x===0),Ci(l,m,y,d),y+=d,y+=Ti(l,m,y,l.header.byteLength),y}(s,n,t);case 2:return function(l,m,y,d){return pt(l.header.byteLength>20),function(x,b,_,C){for(;_+8<=x.header.byteLength;){const f=b.getUint32(_+0,pr),p=b.getUint32(_+4,pr);switch(_+=8,p){case cf:Ci(x,b,_,f);break;case lf:Ti(x,b,_,f);break;case 0:C.strict||Ci(x,b,_,f);break;case 1:C.strict||Ti(x,b,_,f)}_+=Gr(f,4)}}(l,m,y,d),y+l.header.byteLength}(s,n,t,{});default:throw new Error(`Invalid GLB version ${s.version}. Only supports version 1 and 2.`)}}function Ci(s,e,t,r){const n=new Uint8Array(e.buffer,t,r),i=new TextDecoder("utf8").decode(n);return s.json=JSON.parse(i),Gr(r,4)}function Ti(s,e,t,r){return s.header.hasBinChunk=!0,s.binChunks.push({byteOffset:t,byteLength:r,arrayBuffer:e.buffer}),Gr(r,4)}function Du(s,e){if(s.startsWith("data:")||s.startsWith("http:")||s.startsWith("https:"))return s;const t=e.baseUri||e.uri;if(!t)throw new Error(`'baseUri' must be provided to resolve relative url ${s}`);return t.substr(0,t.lastIndexOf("/")+1)+s}const hf="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",ff="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",pf=new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,3,2,0,0,5,3,1,0,1,12,1,0,10,22,2,12,0,65,0,65,0,65,0,252,10,0,0,11,7,0,65,0,253,15,26,11]),mf=new Uint8Array([32,0,65,253,3,1,2,34,4,106,6,5,11,8,7,20,13,33,12,16,128,9,116,64,19,113,127,15,10,21,22,14,255,66,24,54,136,107,18,23,192,26,114,118,132,17,77,101,130,144,27,87,131,44,45,74,156,154,70,167]),gf={0:"",1:"meshopt_decodeFilterOct",2:"meshopt_decodeFilterQuat",3:"meshopt_decodeFilterExp",NONE:"",OCTAHEDRAL:"meshopt_decodeFilterOct",QUATERNION:"meshopt_decodeFilterQuat",EXPONENTIAL:"meshopt_decodeFilterExp"},yf={0:"meshopt_decodeVertexBuffer",1:"meshopt_decodeIndexBuffer",2:"meshopt_decodeIndexSequence",ATTRIBUTES:"meshopt_decodeVertexBuffer",TRIANGLES:"meshopt_decodeIndexBuffer",INDICES:"meshopt_decodeIndexSequence"};async function bf(s,e,t,r,n,i="NONE"){const o=await async function(){return Si||(Si=async function(){let u=hf;WebAssembly.validate(pf)&&(u=ff,console.log("Warning: meshopt_decoder is using experimental SIMD support"));const l=await WebAssembly.instantiate(function(m){const y=new Uint8Array(m.length);for(let x=0;x96?b-71:b>64?b-65:b>47?b+4:b>46?63:62}let d=0;for(let x=0;xC?g:C,f=B>f?B:f,p=w>p?w:p}return[[x,b,_],[C,f,p]]}(l.attributes),y=function(d,x,b){const _=Uu(x.metadata),C=[],f=function(p){const a={};for(const c in p){const h=p[c];a[h.name||"undefined"]=h}return a}(x.attributes);for(const p in d){const a=Fu(p,d[p],f[p]);C.push(a)}if(b){const p=Fu("indices",b);C.push(p)}return{fields:C,metadata:_}}(l.attributes,u,l.indices);return{loader:"draco",loaderData:u,header:{vertexCount:i.num_points(),boundingBox:m},...l,schema:y}}finally{this.draco.destroy(r),i&&this.draco.destroy(i)}}_getDracoLoaderData(e,t,r){const n=this._getTopLevelMetadata(e),i=this._getDracoAttributes(e,r);return{geometry_type:t,num_attributes:e.num_attributes(),num_points:e.num_points(),num_faces:e instanceof this.draco.Mesh?e.num_faces():0,metadata:n,attributes:i}}_getDracoAttributes(e,t){const r={};for(let n=0;nthis.decoder[i]).includes(n)){const i=new this.draco.AttributeQuantizationTransform;try{if(i.InitFromAttribute(e))return{quantization_bits:i.quantization_bits(),range:i.range(),min_values:new Float32Array([1,2,3]).map(o=>i.min_value(o))}}finally{this.draco.destroy(i)}}return null}_getOctahedronTransform(e,t){const{octahedronAttributes:r=[]}=t,n=e.attribute_type();if(r.map(i=>this.decoder[i]).includes(n)){const i=new this.draco.AttributeQuantizationTransform;try{if(i.InitFromAttribute(e))return{quantization_bits:i.quantization_bits()}}finally{this.draco.destroy(i)}}return null}}const Ei="https://www.gstatic.com/draco/versioned/decoders/1.5.6",Es="draco_wasm_wrapper.js",Ms="draco_decoder.wasm",Ps="draco_decoder.js",Nu="draco_encoder.js",Mi={[Es]:`${Ei}/${Es}`,[Ms]:`${Ei}/${Ms}`,[Ps]:`${Ei}/${Ps}`,[Nu]:`https://raw.githubusercontent.com/google/draco/1.4.1/javascript/${Nu}`};let Pi;async function Sf(s){const e=s.modules||{};return e.draco3d?Pi||(Pi=e.draco3d.createDecoderModule({}).then(t=>({draco:t}))):Pi||(Pi=async function(t){let r,n;return(t.draco&&t.draco.decoderType)==="js"?r=await Vt(Mi[Ps],"draco",t,Ps):[r,n]=await Promise.all([await Vt(Mi[Es],"draco",t,Es),await Vt(Mi[Ms],"draco",t,Ms)]),r=r||globalThis.DracoDecoderModule,await function(i,o){const u={};return o&&(u.wasmBinary=o),new Promise(l=>{i({...u,onModuleLoaded:m=>l({draco:m})})})}(r,n)}(s)),await Pi}const Ef={...wf,parse:async function(s,e){const{draco:t}=await Sf(e),r=new Tf(t);try{return r.parseSync(s,e==null?void 0:e.draco)}finally{r.destroy()}}};function Vu(s){const{buffer:e,size:t,count:r}=function(n){let i=n,o=1,u=0;return n&&n.value&&(i=n.value,o=n.size||1),i&&(ArrayBuffer.isView(i)||(i=function(l,m,y=!1){return l?Array.isArray(l)?new m(l):y&&!(l instanceof m)?new m(l):l:null}(i,Float32Array)),u=i.length/o),{buffer:i,size:o,count:u}}(s);return{value:e,size:t,byteOffset:0,count:r,type:xu(t),componentType:As(e)}}const zt="KHR_draco_mesh_compression",Mf=zt;async function Pf(s,e,t,r){const n=s.getObjectExtension(e,zt);if(!n)return;const i=s.getTypedArrayForBufferView(n.bufferView),o=Na(i.buffer,i.byteOffset),u={...t};delete u["3d-tiles"];const l=await Ta(o,Ef,u,r),m=function(y){const d={};for(const x in y){const b=y[x];if(x!=="indices"){const _=Vu(b);d[x]=_}}return d}(l.attributes);for(const[y,d]of Object.entries(m))if(y in e.attributes){const x=e.attributes[y],b=s.getAccessor(x);b!=null&&b.min&&(b!=null&&b.max)&&(d.min=b.min,d.max=b.max)}e.attributes=m,l.indices&&(e.indices=Vu(l.indices)),s.removeObjectExtension(e,zt),function(y){if(!y.attributes&&Object.keys(y.attributes).length>0)throw new Error("glTF: Empty primitive detected: Draco decompression failure?")}(e)}function Rf(s,e,t=4,r,n){if(!r.DracoWriter)throw new Error("options.gltf.DracoWriter not provided")}function*Hu(s){for(const e of s.json.meshes||[])for(const t of e.primitives)yield t}const Gf=Object.freeze(Object.defineProperty({__proto__:null,decode:async function(s,e,t){var i;if(!((i=e==null?void 0:e.gltf)!=null&&i.decompressMeshes))return;const r=new _e(s),n=[];for(const o of Hu(r))r.getObjectExtension(o,zt)&&n.push(Pf(r,o,e,t));await Promise.all(n),r.removeExtension(zt)},encode:function(s,e={}){const t=new _e(s);for(const r of t.json.meshes||[])Rf(),t.addRequiredExtension(zt)},name:Mf,preprocess:function(s,e,t){const r=new _e(s);for(const n of Hu(r))r.getObjectExtension(n,zt)}},Symbol.toStringTag,{value:"Module"}));globalThis.mathgl=globalThis.mathgl||{config:{EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1}};const je=globalThis.mathgl.config;function Lf(s,{precision:e=je.precision}={}){return s=function(t){return Math.round(t/je.EPSILON)*je.EPSILON}(s),`${parseFloat(s.toPrecision(e))}`}function Rs(s){return Array.isArray(s)||ArrayBuffer.isView(s)&&!(s instanceof DataView)}function Ju(s,e,t){const r=je.EPSILON;try{if(s===e)return!0;if(Rs(s)&&Rs(e)){if(s.length!==e.length)return!1;for(let n=0;n0?", ":"")+Lf(this[r],e);return`${e.printTypes?this.constructor.name:""}[${t}]`}equals(e){if(!e||this.length!==e.length)return!1;for(let t=0;t=0&&e=0&&e0?this.copy([e,...t]):this.identity()}copy(e){return this[0]=e[0],this[1]=e[1],this[2]=e[2],this[3]=e[3],this[4]=e[4],this[5]=e[5],this[6]=e[6],this[7]=e[7],this[8]=e[8],this.check()}identity(){return this.copy(Ff)}fromObject(e){return this.check()}fromQuaternion(e){return function(t,r){const n=r[0],i=r[1],o=r[2],u=r[3],l=n+n,m=i+i,y=o+o,d=n*l,x=i*l,b=i*m,_=o*l,C=o*m,f=o*y,p=u*l,a=u*m,c=u*y;t[0]=1-b-f,t[3]=x-c,t[6]=_+a,t[1]=x+c,t[4]=1-d-f,t[7]=C-p,t[2]=_-a,t[5]=C+p,t[8]=1-d-b}(this,e),this.check()}set(e,t,r,n,i,o,u,l,m){return this[0]=e,this[1]=t,this[2]=r,this[3]=n,this[4]=i,this[5]=o,this[6]=u,this[7]=l,this[8]=m,this.check()}setRowMajor(e,t,r,n,i,o,u,l,m){return this[0]=e,this[1]=n,this[2]=u,this[3]=t,this[4]=i,this[5]=l,this[6]=r,this[7]=o,this[8]=m,this.check()}determinant(){return function(e){const t=e[0],r=e[1],n=e[2],i=e[3],o=e[4],u=e[5],l=e[6],m=e[7],y=e[8];return t*(y*o-u*m)+r*(-y*i+u*l)+n*(m*i-o*l)}(this)}transpose(){return function(e,t){if(e===t){const r=t[1],n=t[2],i=t[5];e[1]=t[3],e[2]=t[6],e[3]=r,e[5]=t[7],e[6]=n,e[7]=i}else e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8]}(this,this),this.check()}invert(){return function(e,t){const r=t[0],n=t[1],i=t[2],o=t[3],u=t[4],l=t[5],m=t[6],y=t[7],d=t[8],x=d*u-l*y,b=-d*o+l*m,_=y*o-u*m;let C=r*x+n*b+i*_;C&&(C=1/C,e[0]=x*C,e[1]=(-d*n+i*y)*C,e[2]=(l*n-i*u)*C,e[3]=b*C,e[4]=(d*r-i*m)*C,e[5]=(-l*r+i*o)*C,e[6]=_*C,e[7]=(-y*r+n*m)*C,e[8]=(u*r-n*o)*C)}(this,this),this.check()}multiplyLeft(e){return $u(this,e,this),this.check()}multiplyRight(e){return $u(this,this,e),this.check()}rotate(e){return function(t,r,n){const i=r[0],o=r[1],u=r[2],l=r[3],m=r[4],y=r[5],d=r[6],x=r[7],b=r[8],_=Math.sin(n),C=Math.cos(n);t[0]=C*i+_*l,t[1]=C*o+_*m,t[2]=C*u+_*y,t[3]=C*l-_*i,t[4]=C*m-_*o,t[5]=C*y-_*u,t[6]=d,t[7]=x,t[8]=b}(this,this,e),this.check()}scale(e){return Array.isArray(e)?Xu(this,this,e):Xu(this,this,[e,e]),this.check()}translate(e){return function(t,r,n){const i=r[0],o=r[1],u=r[2],l=r[3],m=r[4],y=r[5],d=r[6],x=r[7],b=r[8],_=n[0],C=n[1];t[0]=i,t[1]=o,t[2]=u,t[3]=l,t[4]=m,t[5]=y,t[6]=_*i+C*l+d,t[7]=_*o+C*m+x,t[8]=_*u+C*y+b}(this,this,e),this.check()}transform(e,t){let r;switch(e.length){case 2:r=function(n,i,o){const u=i[0],l=i[1];return n[0]=o[0]*u+o[3]*l+o[6],n[1]=o[1]*u+o[4]*l+o[7],n}(t||[-0,-0],e,this);break;case 3:r=Ku(t||[-0,-0,-0],e,this);break;case 4:r=function(n,i,o){const u=i[0],l=i[1],m=i[2];return n[0]=o[0]*u+o[3]*l+o[6]*m,n[1]=o[1]*u+o[4]*l+o[7]*m,n[2]=o[2]*u+o[5]*l+o[8]*m,n[3]=i[3],n}(t||[-0,-0,-0,-0],e,this);break;default:throw new Error("Illegal vector")}return Of(r,e.length),r}transformVector(e,t){return this.transform(e,t)}transformVector2(e,t){return this.transform(e,t)}transformVector3(e,t){return this.transform(e,t)}}let Os,Is=null;const Ds="KHR_texture_transform",Uf=Ds,Fs=new Gi,kf=new gr,Nf=new gr;function Vf(s,e){var i,o,u,l;const t=(i=e.json.materials)==null?void 0:i[s],r=[(o=t==null?void 0:t.pbrMetallicRoughness)==null?void 0:o.baseColorTexture,t==null?void 0:t.emissiveTexture,t==null?void 0:t.normalTexture,t==null?void 0:t.occlusionTexture,(u=t==null?void 0:t.pbrMetallicRoughness)==null?void 0:u.metallicRoughnessTexture],n=[];for(const m of r)m&&((l=m==null?void 0:m.extensions)!=null&&l[Ds])&&Hf(e,s,m,n)}function Hf(s,e,t,r){const n=function(o,u){var x;const l=(x=o.extensions)==null?void 0:x[Ds],{texCoord:m=0}=o,{texCoord:y=m}=l;if(!(u.findIndex(([b,_])=>b===m&&_===y)!==-1)){const b=function(_){const{offset:C=[0,0],rotation:f=0,scale:p=[1,1]}=_,a=new gr().set(1,0,0,0,1,0,C[0],C[1],1),c=kf.set(Math.cos(f),Math.sin(f),0,-Math.sin(f),Math.cos(f),0,0,0,1),h=Nf.set(p[0],0,0,0,p[1],0,0,0,1);return a.multiplyRight(c).multiplyRight(h)}(l);return m!==y&&(o.texCoord=y),u.push([m,y]),{originalTexCoord:m,texCoord:y,matrix:b}}return null}(t,r);if(!n)return;const i=s.json.meshes||[];for(const o of i)for(const u of o.primitives){const l=u.material;Number.isFinite(l)&&e===l&&Jf(s,u,n)}}function Jf(s,e,t){var u,l;const{originalTexCoord:r,texCoord:n,matrix:i}=t,o=e.attributes[`TEXCOORD_${r}`];if(Number.isFinite(o)){const m=(u=s.json.accessors)==null?void 0:u[o];if(m&&m.bufferView){const y=(l=s.json.bufferViews)==null?void 0:l[m.bufferView];if(y){const{arrayBuffer:d,byteOffset:x}=s.buffers[y.buffer],b=(x||0)+(m.byteOffset||0)+(y.byteOffset||0),{ArrayType:_,length:C}=bi(m,y),f=yu[m.componentType],p=gu[m.type],a=y.byteStride||f*p,c=new Float32Array(C);for(let h=0;h{s.uniforms[r].value&&!(r in t)&&(t[r]=s.uniforms[r].value)}),Object.keys(t).forEach(r=>{typeof t[r]=="object"&&t[r].index!==void 0&&(t[r].texture=e.getTexture(t[r].index))}),t}const Yu=[Hh,Rh,Bf,Af,vf,Gf,jf,Kf,Object.freeze(Object.defineProperty({__proto__:null,decode:async function(s){const e=new _e(s),{json:t}=e,r=e.getExtension(Ur);if(r){const n=function(i,o){const{programs:u=[],shaders:l=[],techniques:m=[]}=i,y=new TextDecoder;return l.forEach(d=>{if(!Number.isFinite(d.bufferView))throw new Error("KHR_techniques_webgl: no shader code");d.code=y.decode(o.getTypedArrayForBufferView(d.bufferView))}),u.forEach(d=>{d.fragmentShader=l[d.fragmentShader],d.vertexShader=l[d.vertexShader]}),m.forEach(d=>{d.program=u[d.program]}),m}(r,e);for(const i of t.materials||[]){const o=e.getObjectExtension(i,Ur);o&&(i.technique=Object.assign({},o,n[o.technique]),i.technique.values=Xf(i.technique,e)),e.removeObjectExtension(i,Ur)}e.removeExtension(Ur)}},encode:async function(s,e){},name:$f},Symbol.toStringTag,{value:"Module"})),zf,qh];function Wu(s,e){var r;const t=((r=e==null?void 0:e.gltf)==null?void 0:r.excludeExtensions)||{};return!(s in t&&!t[s])}const Oi="KHR_binary_glTF",qu={accessors:"accessor",animations:"animation",buffers:"buffer",bufferViews:"bufferView",images:"image",materials:"material",meshes:"mesh",nodes:"node",samplers:"sampler",scenes:"scene",skins:"skin",textures:"texture"},Yf={accessor:"accessors",animations:"animation",buffer:"buffers",bufferView:"bufferViews",image:"images",material:"materials",mesh:"meshes",node:"nodes",sampler:"samplers",scene:"scenes",skin:"skins",texture:"textures"};class Wf{constructor(){ee(this,"idToIndexMap",{animations:{},accessors:{},buffers:{},bufferViews:{},images:{},materials:{},meshes:{},nodes:{},samplers:{},scenes:{},skins:{},textures:{}});ee(this,"json")}normalize(e,t){this.json=e.json;const r=e.json;switch(r.asset&&r.asset.version){case"2.0":return;case void 0:case"1.0":break;default:return void console.warn(`glTF: Unknown version ${r.asset.version}`)}if(!t.normalize)throw new Error("glTF v1 is not supported.");console.warn("Converting glTF v1 to glTF v2 format. This is experimental and may fail."),this._addAsset(r),this._convertTopLevelObjectsToArrays(r),function(n){const i=new _e(n),{json:o}=i;for(const u of o.images||[]){const l=i.getObjectExtension(u,Oi);l&&Object.assign(u,l),i.removeObjectExtension(u,Oi)}o.buffers&&o.buffers[0]&&delete o.buffers[0].uri,i.removeExtension(Oi)}(e),this._convertObjectIdsToArrayIndices(r),this._updateObjects(r),this._updateMaterial(r)}_addAsset(e){e.asset=e.asset||{},e.asset.version="2.0",e.asset.generator=e.asset.generator||"Normalized to glTF 2.0 by loaders.gl"}_convertTopLevelObjectsToArrays(e){for(const t in qu)this._convertTopLevelObjectToArray(e,t)}_convertTopLevelObjectToArray(e,t){const r=e[t];if(r&&!Array.isArray(r)){e[t]=[];for(const n in r){const i=r[n];i.id=i.id||n;const o=e[t].length;e[t].push(i),this.idToIndexMap[t][n]=o}}}_convertObjectIdsToArrayIndices(e){for(const t in qu)this._convertIdsToIndices(e,t);"scene"in e&&(e.scene=this._convertIdToIndex(e.scene,"scene"));for(const t of e.textures)this._convertTextureIds(t);for(const t of e.meshes)this._convertMeshIds(t);for(const t of e.nodes)this._convertNodeIds(t);for(const t of e.scenes)this._convertSceneIds(t)}_convertTextureIds(e){e.source&&(e.source=this._convertIdToIndex(e.source,"image"))}_convertMeshIds(e){for(const t of e.primitives){const{attributes:r,indices:n,material:i}=t;for(const o in r)r[o]=this._convertIdToIndex(r[o],"accessor");n&&(t.indices=this._convertIdToIndex(n,"accessor")),i&&(t.material=this._convertIdToIndex(i,"material"))}}_convertNodeIds(e){e.children&&(e.children=e.children.map(t=>this._convertIdToIndex(t,"node"))),e.meshes&&(e.meshes=e.meshes.map(t=>this._convertIdToIndex(t,"mesh")))}_convertSceneIds(e){e.nodes&&(e.nodes=e.nodes.map(t=>this._convertIdToIndex(t,"node")))}_convertIdsToIndices(e,t){e[t]||(console.warn(`gltf v1: json doesn't contain attribute ${t}`),e[t]=[]);for(const r of e[t])for(const n in r){const i=r[n],o=this._convertIdToIndex(i,n);r[n]=o}}_convertIdToIndex(e,t){const r=Yf[t];if(r in this.idToIndexMap){const n=this.idToIndexMap[r][e];if(!Number.isFinite(n))throw new Error(`gltf v1: failed to resolve ${t} with id ${e}`);return n}return e}_updateObjects(e){for(const t of this.json.buffers)delete t.type}_updateMaterial(e){var t,r,n;for(const i of e.materials){i.pbrMetallicRoughness={baseColorFactor:[1,1,1,1],metallicFactor:1,roughnessFactor:1};const o=((t=i.values)==null?void 0:t.tex)||((r=i.values)==null?void 0:r.texture2d_0)||((n=i.values)==null?void 0:n.diffuseTex),u=e.textures.findIndex(l=>l.id===o);u!==-1&&(i.pbrMetallicRoughness.baseColorTexture={index:u})}}}async function qf(s,e,t=0,r,n){var i,o,u;return function(l,m,y,d){if(d.uri&&(l.baseUri=d.uri),m instanceof ArrayBuffer&&!function(_,C=0,f={}){const p=new DataView(_),{magic:a=Iu}=f,c=p.getUint32(C,!1);return c===a||c===Iu}(m,y,d)&&(m=new TextDecoder().decode(m)),typeof m=="string")l.json=Kd(m);else if(m instanceof ArrayBuffer){const _={};y=df(_,m,y,d.glb),Me(_.type==="glTF",`Invalid GLB magic string ${_.type}`),l._glb=_,l.json=_.json}else Me(!1,"GLTF: must be ArrayBuffer or string");const x=l.json.buffers||[];if(l.buffers=new Array(x.length).fill(null),l._glb&&l._glb.header.hasBinChunk){const{binChunks:_}=l._glb;l.buffers[0]={arrayBuffer:_[0].arrayBuffer,byteOffset:_[0].byteOffset,byteLength:_[0].byteLength}}const b=l.json.images||[];l.images=new Array(b.length).fill({})}(s,e,t,r),function(l,m={}){new Wf().normalize(l,m)}(s,{normalize:(i=r==null?void 0:r.gltf)==null?void 0:i.normalize}),function(l,m={},y){var x;const d=Yu.filter(b=>Wu(b.name,m));for(const b of d)(x=b.preprocess)==null||x.call(b,l,m,y)}(s,r,n),(o=r==null?void 0:r.gltf)!=null&&o.loadBuffers&&s.json.buffers&&await async function(l,m,y){var x,b;const d=l.json.buffers||[];for(let _=0;_Wu(b.name,m));for(const b of d)await((x=b.decode)==null?void 0:x.call(b,l,m,y))}(s,r,n),s}async function Qf(s,e,t,r,n){let i;if(e.uri&&!e.hasOwnProperty("bufferView")){const u=Du(e.uri,r),{fetch:l}=n;i=await(await l(u)).arrayBuffer(),e.bufferView={data:i}}if(Number.isFinite(e.bufferView)){const u=function(l,m,y){const d=l.bufferViews[y];Me(d);const x=m[d.buffer];Me(x);const b=(d.byteOffset||0)+x.byteOffset;return new Uint8Array(x.arrayBuffer,b,d.byteLength)}(s.json,s.buffers,e.bufferView);i=Na(u.buffer,u.byteOffset,u.byteLength)}Me(i,"glTF image has no data");let o=await Ta(i,[xh,uf],{...r,mimeType:e.mimeType,basis:r.basis||{format:Ou()}},n);o&&o[0]&&(o={compressed:!0,mipmaps:!1,width:o[0].width,height:o[0].height,data:o[0]}),s.images=s.images||[],s.images[t]=o}const Ii={dataType:null,batchType:null,name:"glTF",id:"gltf",module:"gltf",version:"4.3.2",extensions:["gltf","glb"],mimeTypes:["model/gltf+json","model/gltf-binary"],text:!0,binary:!0,tests:["glTF"],parse:async function(s,e={},t){(e={...Ii.options,...e}).gltf={...Ii.options.gltf,...e.gltf};const{byteOffset:r=0}=e;return await qf({},s,r,e,t)},options:{gltf:{normalize:!0,loadBuffers:!0,loadImages:!0,decompressMeshes:!0},log:console}},Zf={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},ep={5120:1,5121:1,5122:2,5123:2,5125:4,5126:4},Qu=10240,Zu=10241,ec=10242,tc=10243,rc=10497,tp=9729,rp=9986,sp={magFilter:Qu,minFilter:Zu,wrapS:ec,wrapT:tc},np={[Qu]:tp,[Zu]:rp,[ec]:rc,[tc]:rc};class ip{constructor(){ee(this,"baseUri","");ee(this,"jsonUnprocessed");ee(this,"json");ee(this,"buffers",[]);ee(this,"images",[])}postProcess(e,t={}){const{json:r,buffers:n=[],images:i=[]}=e,{baseUri:o=""}=e;return Me(r),this.baseUri=o,this.buffers=n,this.images=i,this.jsonUnprocessed=r,this.json=this._resolveTree(e.json,t),this.json}_resolveTree(e,t={}){const r={...e};return this.json=r,e.bufferViews&&(r.bufferViews=e.bufferViews.map((n,i)=>this._resolveBufferView(n,i))),e.images&&(r.images=e.images.map((n,i)=>this._resolveImage(n,i))),e.samplers&&(r.samplers=e.samplers.map((n,i)=>this._resolveSampler(n,i))),e.textures&&(r.textures=e.textures.map((n,i)=>this._resolveTexture(n,i))),e.accessors&&(r.accessors=e.accessors.map((n,i)=>this._resolveAccessor(n,i))),e.materials&&(r.materials=e.materials.map((n,i)=>this._resolveMaterial(n,i))),e.meshes&&(r.meshes=e.meshes.map((n,i)=>this._resolveMesh(n,i))),e.nodes&&(r.nodes=e.nodes.map((n,i)=>this._resolveNode(n,i)),r.nodes=r.nodes.map((n,i)=>this._resolveNodeChildren(n))),e.skins&&(r.skins=e.skins.map((n,i)=>this._resolveSkin(n,i))),e.scenes&&(r.scenes=e.scenes.map((n,i)=>this._resolveScene(n,i))),typeof this.json.scene=="number"&&r.scenes&&(r.scene=r.scenes[this.json.scene]),r}getScene(e){return this._get(this.json.scenes,e)}getNode(e){return this._get(this.json.nodes,e)}getSkin(e){return this._get(this.json.skins,e)}getMesh(e){return this._get(this.json.meshes,e)}getMaterial(e){return this._get(this.json.materials,e)}getAccessor(e){return this._get(this.json.accessors,e)}getCamera(e){return this._get(this.json.cameras,e)}getTexture(e){return this._get(this.json.textures,e)}getSampler(e){return this._get(this.json.samplers,e)}getImage(e){return this._get(this.json.images,e)}getBufferView(e){return this._get(this.json.bufferViews,e)}getBuffer(e){return this._get(this.json.buffers,e)}_get(e,t){if(typeof t=="object")return t;const r=e&&e[t];return r||console.warn(`glTF file error: Could not find ${e}[${t}]`),r}_resolveScene(e,t){return{...e,id:e.id||`scene-${t}`,nodes:(e.nodes||[]).map(r=>this.getNode(r))}}_resolveNode(e,t){const r={...e,id:(e==null?void 0:e.id)||`node-${t}`};return e.mesh!==void 0&&(r.mesh=this.getMesh(e.mesh)),e.camera!==void 0&&(r.camera=this.getCamera(e.camera)),e.skin!==void 0&&(r.skin=this.getSkin(e.skin)),e.meshes!==void 0&&e.meshes.length&&(r.mesh=e.meshes.reduce((n,i)=>{const o=this.getMesh(i);return n.id=o.id,n.primitives=n.primitives.concat(o.primitives),n},{primitives:[]})),r}_resolveNodeChildren(e){return e.children&&(e.children=e.children.map(t=>this.getNode(t))),e}_resolveSkin(e,t){const r=typeof e.inverseBindMatrices=="number"?this.getAccessor(e.inverseBindMatrices):void 0;return{...e,id:e.id||`skin-${t}`,inverseBindMatrices:r}}_resolveMesh(e,t){const r={...e,id:e.id||`mesh-${t}`,primitives:[]};return e.primitives&&(r.primitives=e.primitives.map(n=>{const i={...n,attributes:{},indices:void 0,material:void 0},o=n.attributes;for(const u in o)i.attributes[u]=this.getAccessor(o[u]);return n.indices!==void 0&&(i.indices=this.getAccessor(n.indices)),n.material!==void 0&&(i.material=this.getMaterial(n.material)),i})),r}_resolveMaterial(e,t){const r={...e,id:e.id||`material-${t}`};if(r.normalTexture&&(r.normalTexture={...r.normalTexture},r.normalTexture.texture=this.getTexture(r.normalTexture.index)),r.occlusionTexture&&(r.occlusionTexture={...r.occlusionTexture},r.occlusionTexture.texture=this.getTexture(r.occlusionTexture.index)),r.emissiveTexture&&(r.emissiveTexture={...r.emissiveTexture},r.emissiveTexture.texture=this.getTexture(r.emissiveTexture.index)),r.emissiveFactor||(r.emissiveFactor=r.emissiveTexture?[1,1,1]:[0,0,0]),r.pbrMetallicRoughness){r.pbrMetallicRoughness={...r.pbrMetallicRoughness};const n=r.pbrMetallicRoughness;n.baseColorTexture&&(n.baseColorTexture={...n.baseColorTexture},n.baseColorTexture.texture=this.getTexture(n.baseColorTexture.index)),n.metallicRoughnessTexture&&(n.metallicRoughnessTexture={...n.metallicRoughnessTexture},n.metallicRoughnessTexture.texture=this.getTexture(n.metallicRoughnessTexture.index))}return r}_resolveAccessor(e,t){const r=(n=e.componentType,ep[n]);var n;const i=(o=e.type,Zf[o]);var o;const u=r*i,l={...e,id:e.id||`accessor-${t}`,bytesPerComponent:r,components:i,bytesPerElement:u,value:void 0,bufferView:void 0,sparse:void 0};if(e.bufferView!==void 0&&(l.bufferView=this.getBufferView(e.bufferView)),l.bufferView){const m=l.bufferView.buffer,{ArrayType:y,byteLength:d}=bi(l,l.bufferView),x=(l.bufferView.byteOffset||0)+(l.byteOffset||0)+m.byteOffset;let b=m.arrayBuffer.slice(x,x+d);l.bufferView.byteStride&&(b=this._getValueFromInterleavedBuffer(m,x,l.bufferView.byteStride,l.bytesPerElement,l.count)),l.value=new y(b)}return l}_getValueFromInterleavedBuffer(e,t,r,n,i){const o=new Uint8Array(i*n);for(let u=0;uF.create()),y=new Array(t.length).fill(null).map(h=>F.create());for(const h of this.faces)a(h);let d=Number.POSITIVE_INFINITY,x=Number.POSITIVE_INFINITY,b=Number.POSITIVE_INFINITY,_=Number.NEGATIVE_INFINITY,C=Number.NEGATIVE_INFINITY,f=Number.NEGATIVE_INFINITY;for(let h=0;h{if(!m){const x=A.device.createBuffer({label:"Vertex Buffer Placeholder",size:1,usage:GPUBufferUsage.VERTEX});return this.vertexBufferOffsets.set(x,[0,1]),X.addBufferBytes(x),void this.vertexBuffers.push(x)}const y=m.bufferView,d=this.gpuBuffers.get(y.id);this.vertexBuffers.push(d),this.vertexBufferOffsets.set(d,[0,0])});const u=e.indices.bufferView,l=this.gpuBuffers.get(u.id);this.indexBufferOffsets[0]=e.indices.byteOffset,this.indexBufferOffsets[1]=e.indices.count*e.indices.bytesPerElement,this.indexCount=e.indices.count,this.indexBuffer=l}}const nc=new Map,Kt=WebGLRenderingContext;class Ke extends Ye{static get defaultNearestSampler(){return Di||(Di=this.createSampler({minFilter:"nearest",magFilter:"nearest"}),Di)}static get defaultSampler(){return Fi||(Fi=this.createSampler({minFilter:"linear",magFilter:"linear",mipmapFilter:"linear",maxAnisotropy:4}),Fi)}static createSampler(e){const t=structuredClone(e);t.label&&delete t.label;const r=JSON.stringify(t);let n;return(n=nc.get(r))||(n=A.device.createSampler(e),nc.set(r,n)),n}static getSamplerFromGltfSamplerDef(e){function t(n){switch(n){case Kt.CLAMP_TO_EDGE:return"clamp-to-edge";case Kt.MIRRORED_REPEAT:return"mirror-repeat";default:return"repeat"}}const r={addressModeU:t(e.wrapS),addressModeV:t(e.wrapT)};switch(e.magFilter&&e.magFilter!=Kt.LINEAR||(r.magFilter="linear"),e.minFilter){case Kt.LINEAR:case Kt.LINEAR_MIPMAP_NEAREST:r.minFilter="linear";break;case Kt.NEAREST_MIPMAP_LINEAR:r.mipmapFilter="linear";break;case Kt.LINEAR_MIPMAP_LINEAR:default:r.minFilter="linear",r.mipmapFilter="linear"}return r.maxAnisotropy=16,this.createSampler(r)}}function Ui(s,e){if(s[3]!==0){var t=(r=1,n=s[3]-136,r*Math.pow(2,n));e[0]=s[0]*t,e[1]=s[1]*t,e[2]=s[2]*t}else e[0]=e[1]=e[2]=0;var r,n}function ki(s,e){var t=s[0],r=s[1],n=s[2],i=Math.max(t,Math.max(r,n));if(i<9999999999999999e-48)e[0]=e[1]=e[2]=e[3]=0;else{var o=function(y){var d={f:y=Number(y),e:0};if(y!==0&&Number.isFinite(y)){for(var x=Math.abs(y),b=Math.log2||function(f){return Math.log(f)*Math.LOG2E},_=Math.max(-1023,Math.floor(b(x))+1),C=x*Math.pow(2,-_);C>=1;)C*=.5,_++;for(;C<.5;)C*=2,_--;y<0&&(C=-C),d.f=C,d.e=_}return d}(i),u=o.f,l=o.e,m=u/i*256;e[0]=t*m,e[1]=r*m,e[2]=n*m,e[3]=l+128}}function ic(s,e,t){var r=[];return function(n,i,o,u,l){if(!(o<=0||i<=0||!l)){var m=`#?RADIANCE +# Written by hdr.js +FORMAT=32-bit_rle_rgbe +EXPOSURE=1.0 + +-Y `+o+" +X "+i+` +`;m.split("").forEach(function(x){var b=x.charCodeAt(0);n.push(b)});for(var y=new Uint8Array(4*i),d=0;d>8,o[3]=255&e,e<8||e>=32768)for(i=0;i=e&&(y=e);i128&&(x=128),up(s,x,d.subarray(i)),i+=x;if(y+2127&&(x=127),cp(s,x,d[i]),i+=x}}}}}}function up(s,e,t){var r=255&e;if(!(e<=128))throw new Error("length is greater than 128");s.push(r);for(var n=0;nac||l>ac)return"Very large image (corrupt?)";var m=s[t],y=s[t+1],d=s[t+2],x=m!==2||y!==2||!!(128&d),b=new Float32Array(u*l*3);if(u<8||u>=32768||x)for(o=0;o0;)if((g=s[t++])>128){if(B=s[t++],(g-=128)>R)return"bad RLE data in HDR";for(var U=0;UR)return"bad RLE data in HDR";for(U=0;U"u"&&t("XMLHttpRequest is undefined, use HDRjs.read instead.");var r=new XMLHttpRequest;r.responseType="arraybuffer",r.onload=function(){if(r.status>=400)return t("Load successfully, but HTTP status code >= 400, status: "+r.status);var n=uc(new Uint8Array(r.response));typeof n=="string"?t(n):e(n)},r.onerror=function(n){t("Failed to load: "+s)},r.open("GET",s,!0),r.send()})},save:function(s,e,t,r){if(!(document!=null&&document.createElement)||!(URL!=null&&URL.createObjectURL))return console.warn("NO document.createElement or URL.createObjectURL"),!1;var n=ic(e,t,s),i=URL.createObjectURL(new Blob([n])),o=document.createElement("a");return o.href=i,o.download=r+".hdr",o.rel="noopener",setTimeout(function(){URL.revokeObjectURL(o.href)},4e4),setTimeout(function(){(function(u){try{u.dispatchEvent(new MouseEvent("click"))}catch{var l=document.createEvent("MouseEvents");l.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),u.dispatchEvent(l)}})(o)},0),!0},read:uc,write:ic,float2rgbe:ki,rgbe2float:Ui});const cc="vertexMain",lc="fragmentMain",dc=` + ${Y.VertexInput} + ${Y.VertexOutput} + + @group(0) @binding(0) var projViewMatrix: mat4x4f; + @group(0) @binding(1) var inTexture: texture_2d; + @group(0) @binding(2) var inSampler: sampler; + + const invAtan = vec2(0.1591, 0.3183); + fn SampleSphericalMap(v: vec3f) -> vec2f { + var uv = vec2f(atan(v.z / v.x), asin(v.y)); + uv *= invAtan; + uv += 0.5; + return uv; + } + + + @vertex + fn ${cc}(in: VertexInput) -> VertexOutput { + var out: VertexOutput; + out.position = projViewMatrix * in.position; + // hijack + out.viewNormal = in.position.xyz; + return out; + } + + @fragment + fn ${lc}(in: VertexOutput) -> @location(0) vec4f { + let uv = SampleSphericalMap(normalize(in.normal.rgb)); // make sure to normalize localPos + let color = textureSample(inTexture, inSampler, uv).rgb; + return vec4f(color, 1); + } +`;let Vs,Hs,Js,zs,js;const Ni=new Map([]),xt=class xt extends Ye{static pipelinesCount(){return this.renderPipelinesCount+this.computePipelinesCount}static get defaultCameraPlusLightsBindGroupLayout(){if(Hs)return Hs;const e=[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}];return Hs=A.device.createBindGroupLayout({label:"Camera + Lights GPUBindGroupLayout",entries:e}),Hs}static get defaultCameraBindGroupLayout(){if(Vs)return Vs;const e=[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{}}];return Vs=A.device.createBindGroupLayout({label:"Camera GPUBindGroupLayout",entries:e}),Vs}static get defaultModelBindGroupLayout(){if(Js)return Js;const e=[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{}}];return Js=A.device.createBindGroupLayout({label:"Model GPUBindGroupLayout",entries:e}),Js}static get defaultModelMaterialBindGroupLayout(){if(zs)return zs;const e=[{binding:ms.Default,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:me.Albedo,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}},{binding:me.Normal,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}},{binding:me.MetallicRoughness,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}}];return zs=A.device.createBindGroupLayout({label:"Model Textures GPUBindGroupLayout",entries:e}),zs}static get instancesBindGroupLayout(){if(js)return js;const e=[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}];return js=A.device.createBindGroupLayout({label:"Instance Models GPUBindGroupLayout",entries:e}),js}};xt.renderPipelinesCount=0,xt.computePipelinesCount=0,xt.createShaderModule=(e,t=`Shader Module #${Ni.size}`)=>{let r;return(r=Ni.get(e))||(r=A.device.createShaderModule({label:t,code:e}),Ni.set(e,r)),r},xt.createRenderPipeline=e=>{const t=A.device.createRenderPipeline(e);return xt.renderPipelinesCount++,t},xt.createComputePipeline=e=>{const t=A.device.createComputePipeline(e);return xt.computePipelinesCount++,t};let J=xt;class yr{constructor(e,t,r,n,i,o,u,l,m,y,d,x){this.indexV0=e,this.indexV1=t,this.indexV2=r,this.p0=n,this.p1=i,this.p2=o,this.n0=u,this.n1=l,this.v2=m,this.texCoord0=y,this.texCoord1=d,this.texCoord2=x,this.centroid=F.create(),this.computeCetroid()}computeCetroid(){this.centroid[0]=(this.p0[0]+this.p1[0]+this.p2[0])/3,this.centroid[1]=(this.p0[1]+this.p1[1]+this.p2[1])/3,this.centroid[2]=(this.p0[2]+this.p1[2]+this.p2[2])/3}getArea(){const e=F.sub(this.p2,this.p1),t=F.sub(this.p0,this.p1);return .5*F.len(F.cross(e,t))}}class hc extends Ns{constructor(e=1,t=1,r=1,n=1,i=1,o=1){super(),this.width=e,this.height=t,this.depth=r,this.widthSegments=n,this.heightSegments=i,this.depthSegments=o,n=Math.floor(n),i=Math.floor(i),o=Math.floor(o);const u=[],l=[],m=[],y=[];let d=0;function x(b,_,C,f,p,a,c,h,g,B){const w=a/g,R=c/B,U=a/2,k=c/2,T=h/2,S=g+1,P=B+1;let L=0;const D=F.create();for(let O=0;O0?1:-1,m.push(F.clone(D)),y.push(Ee.create(K/g,1-O/B)),L+=1}}for(let O=0;O; + @group(0) @binding(1) var outTexture: texture_storage_2d; + @group(0) @binding(2) var inOutTextureScaleFactor: u32; + + @compute @workgroup_size(8, 8) + fn ${fc}(@builtin(global_invocation_id) id: vec3u) { + let texSize = textureDimensions(inTexture, 0).xy; + if (any(id.xy > texSize.xy)) { + return; + } + + let inColor = textureLoad(inTexture, id.xy * inOutTextureScaleFactor, 0); + textureStore(outTexture, id.xy, inColor); + } +`,Vi="computeMipMap",pc=(s="rgba8unorm")=>` + @group(0) @binding(0) var prevMipLevel: texture_2d; + @group(0) @binding(1) var nextMipLevel: texture_storage_2d<${s}, write>; + + @compute @workgroup_size(8, 8) + fn ${Vi}(@builtin(global_invocation_id) id: vec3u) { + let offset = vec2(0, 1); + let color = ( + textureLoad(prevMipLevel, 2 * id.xy + offset.xx, 0) + + textureLoad(prevMipLevel, 2 * id.xy + offset.xy, 0) + + textureLoad(prevMipLevel, 2 * id.xy + offset.yx, 0) + + textureLoad(prevMipLevel, 2 * id.xy + offset.yy, 0) + ) * 0.25; + textureStore(nextMipLevel, id.xy, color); + } +`;function mc(s,e,t){const r=[{binding:0,resource:e[s-1]},{binding:1,resource:e[s]}];return A.device.createBindGroup({label:"Mip Generator Input Bind Group",layout:t,entries:r})}const Ar=class Ar extends Ye{static copyTextureView(e,t,r,n,i,o,u={viewDimension:"2d",sampleType:"unfilterable-float"},l={access:"write-only",format:"rgba16float",viewDimension:"2d"}){const m=A.device.createBuffer({label:"Copy Texture View Compute Tex Scale Factor Buffer",size:Uint32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM,mappedAtCreation:!0});X.addBufferBytes(m);const y=n/i;new Uint32Array(m.getMappedRange()).set(new Uint32Array([y])),m.unmap();const d=[{binding:0,visibility:GPUShaderStage.COMPUTE,texture:u},{binding:1,visibility:GPUShaderStage.COMPUTE,storageTexture:l},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{}}],x=A.device.createBindGroupLayout({label:"Copy Texture View Compute Bind Group Layout",entries:d}),b=[{binding:0,resource:t},{binding:1,resource:r},{binding:2,resource:{buffer:m}}],_=A.device.createBindGroup({layout:x,entries:b}),C=A.device.createPipelineLayout({label:"Copy Texture View Compute PSO Layout",bindGroupLayouts:[x]}),f=J.createComputePipeline({label:"Copy Texture View Compute PSO",layout:C,compute:{module:J.createShaderModule(fp),entryPoint:fc}});e.setPipeline(f),e.setBindGroup(0,_),e.dispatchWorkgroups(Math.ceil(i/8),Math.ceil(o/8),1)}};Ar.generateMipsForCubeTexture=e=>{if(e.depthOrArrayLayers!=6)return void console.error("Need a cube texture");const t=It(e.width,e.height),r={baseMipLevel:0,mipLevelCount:1,baseArrayLayer:0,arrayLayerCount:1,dimension:"2d",format:e.format},n=[],i=[];for(let d=0;d<6;d++){const x=[],b=[Ee.create(e.width,e.height)];for(let _=0;_0){const f=b[_-1],p=Ee.divScalar(f,2);b.push(p)}}n.push(x),i.push(b)}const o=[{binding:0,visibility:GPUShaderStage.COMPUTE,texture:{viewDimension:"2d"}},{binding:1,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:e.format,viewDimension:"2d"}}],u=A.device.createBindGroupLayout({label:"Mip Generator CubeTexture Input Bind Group Layout",entries:o}),l=J.createComputePipeline({label:"Compute Mip ComputePSO",layout:A.device.createPipelineLayout({label:"Compute Mip ComputePSO CubeTexture Layout",bindGroupLayouts:[u]}),compute:{entryPoint:Vi,module:J.createShaderModule(pc(e.format))}}),m=A.device.createCommandEncoder({label:"Mip Generate Command Encoder}"}),y=m.beginComputePass();y.setPipeline(l);for(let d=0;d<6;d++){const x=i[d],b=n[d];for(let _=1;_{},Ar.generateMipsFor2DTextureWithComputePSO=(e,t="Mipmapped 2D Texture")=>{const r=It(e.width,e.height),n={aspect:"all",baseMipLevel:0,mipLevelCount:1,baseArrayLayer:0,arrayLayerCount:1,dimension:"2d",format:e.format},i=[{binding:0,visibility:GPUShaderStage.COMPUTE,texture:{viewDimension:"2d"}},{binding:1,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:e.format,viewDimension:"2d"}}],o=A.device.createBindGroupLayout({label:"Mip Generator Input Bind Group Layout",entries:i}),u=J.createComputePipeline({label:"Compute Mip ComputePSO",layout:A.device.createPipelineLayout({label:"Compute Mip ComputePSO Layout",bindGroupLayouts:[o]}),compute:{entryPoint:Vi,module:J.createShaderModule(pc())}}),l=[],m=[Ee.create(e.width,e.height)];for(let x=0;x0){const _=m[x-1],C=Ee.divScalar(_,2);m.push(C)}}const y=A.device.createCommandEncoder({label:`Mip Generate Command Encoder for ${t}`}),d=y.beginComputePass();d.setPipeline(u);for(let x=1;x{const n=A.device.createTexture({label:r,format:"rgba16float",size:{width:e.width,height:e.height,depthOrArrayLayers:1},usage:t});return A.device.queue.writeTexture({texture:n,mipLevel:0},e.rgbaHalfFloat,{offset:0,bytesPerRow:e.width*Uint16Array.BYTES_PER_ELEMENT*4},{width:e.width,height:e.height,depthOrArrayLayers:1}),n};let $t=Ar,pp=0;const Zr=class Zr extends Ye{static createEmptyCubeTexture(e,t="Cube Texture "+pp++,r=!1,n="rgba16float",i=GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.COPY_DST){const o={label:t,dimension:"2d",size:{width:e,height:e,depthOrArrayLayers:6},usage:i,format:n};return r&&(o.mipLevelCount=It(e,e)),A.device.createTexture(o)}};Zr.cubeTextureFromIndividualHDRTextures=(e,t="Environment Cube Texture From Individual HDR Textures",r=512,n=!1)=>{const i=Zr.createEmptyCubeTexture(r,t,n),o=A.device.createCommandEncoder();A.ENABLE_DEBUG_GROUPS&&o.pushDebugGroup("Texture View Copy");const u=o.beginComputePass(),l=r;for(let m=0;m<6;m++)$t.copyTextureView(u,e[m].createView({}),i.createView({baseArrayLayer:m,arrayLayerCount:1,baseMipLevel:0,mipLevelCount:1,dimension:"2d"}),r,l,l);return u.end(),A.ENABLE_DEBUG_GROUPS&&o.popDebugGroup(),A.device.queue.submit([o.finish()]),n&&$t.generateMipsForCubeTexture(i),i},Zr.cubeTextureFromHDR=(e,t=512)=>{const r=A.device.createTexture({label:"Environment Cube Texture",dimension:"2d",size:{width:t,height:t,depthOrArrayLayers:6},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING,format:"rgba8unorm"}),n=new Xn(.5*Math.PI,1,.1,10);n.updateProjectionMatrix();const i=A.device.createBuffer({label:"HDR -> CubeMap Camera ProjView Matrix Buffer",size:16*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.UNIFORM});X.addBufferBytes(i);const o=[{binding:0,buffer:{type:"uniform"},visibility:GPUShaderStage.VERTEX},{binding:1,texture:{sampleType:"unfilterable-float"},visibility:GPUShaderStage.FRAGMENT},{binding:2,sampler:{type:"non-filtering"},visibility:GPUShaderStage.FRAGMENT}],u=A.device.createBindGroupLayout({label:"Environment Probe Camera Bind Group Layout",entries:o}),l=[{binding:0,resource:{buffer:i}},{binding:1,resource:e.createView()},{binding:2,resource:Ke.createSampler({})}],m=A.device.createBindGroup({label:"Environment Probe Camera Bind Group",layout:u,entries:l}),y=A.device.createCommandEncoder({label:"HDR Environment to Cube Map Command Encoder"}),d=[{loadOp:"load",storeOp:"store",view:null}],x=J.createRenderPipeline({label:"HDR To CubeMap Render PSO",layout:A.device.createPipelineLayout({bindGroupLayouts:[u]}),vertex:{module:J.createShaderModule(dc),entryPoint:cc,buffers:Be.defaultLayout},fragment:{module:J.createShaderModule(dc),entryPoint:lc,targets:[{format:"rgba8unorm"}]},primitive:{cullMode:"none"}}),b=new hc;for(let _=0;_<6;_++){d[0].view=r.createView({dimension:"2d",baseArrayLayer:_,arrayLayerCount:1});const C=F.add(n.position,Il[_]),f=Q.lookAt(n.position,C,Dl[_]),p=Q.mul(n.projectionMatrix,f);A.device.queue.writeBuffer(i,0,p);const a={label:`Draw Face ${_} Render Pass`,colorAttachments:d},c=y.beginRenderPass(a);c.setPipeline(x),c.setBindGroup(0,m),c.setIndexBuffer(b.indexBuffer,Ae.INDEX_FORMAT),c.setVertexBuffer(0,b.vertexBuffer),c.drawIndexed(b.indexCount),c.end()}return A.device.queue.submit([y.finish()]),r};let kr=Zr;const mp=new Uint8Array([0,32,8,40,2,34,10,42,48,16,56,24,50,18,58,26,12,44,4,36,14,46,6,38,60,28,52,20,62,30,54,22,3,35,11,43,1,33,9,41,51,19,59,27,49,17,57,25,15,47,7,39,13,45,5,37,63,31,55,23,61,29,53,21]),gc=new Uint8Array([255,204,255,204,255,204,255,204,204,255,204,255,204,255,204,255,255,204,255,204,255,204,255,204,204,255,204,255,204,255,204,255,255,204,255,204,255,204,255,204,204,255,204,255,204,255,204,255,255,204,255,204,255,204,255,204,204,255,204,255,204,255,204,255]);let Ks,Hi,Ji,Nr,$s;const Rt=class Rt extends Ye{static get dummyRGBA16FTexture(){return Hi||(Hi=A.device.createTexture({label:"Dummy 1x1 RGBA16F Texture",size:{width:1,height:1},format:"rgba16float",usage:GPUTextureUsage.TEXTURE_BINDING}),Hi)}static get dummyR16FTexture(){return Ji||(Ji=A.device.createTexture({label:"Dummy 1x1 R16F Texture",size:{width:1,height:1},format:"r16float",usage:GPUTextureUsage.TEXTURE_BINDING}),Ji)}static get dummyTexture(){return Ks||(Ks=A.device.createTexture({label:"Default Dummy 8x8 Texture",dimension:"2d",size:{width:8,height:8,depthOrArrayLayers:1},format:"r8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST}),A.device.queue.writeTexture({texture:Ks,mipLevel:0},gc,{offset:0,bytesPerRow:8*Uint8Array.BYTES_PER_ELEMENT},{width:8,height:8,depthOrArrayLayers:1}),Ks)}static get dummyCubeTexture(){if(Nr)return Nr;Nr=A.device.createTexture({label:"Default Dummy 8x8 Cube Texture",dimension:"2d",size:{width:8,height:8,depthOrArrayLayers:6},format:"r8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST});for(let e=0;e<6;e++)A.device.queue.writeTexture({texture:Nr,mipLevel:0,origin:{x:0,y:0,z:e}},gc,{offset:0,bytesPerRow:8},{width:8,height:8,depthOrArrayLayers:0});return Nr}static get bayerDitherPatternTexture(){return $s||($s=A.device.createTexture({label:"Bayer ordered dithered GPUTexture",dimension:"2d",size:{width:8,height:8,depthOrArrayLayers:1},format:"r8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST}),A.device.queue.writeTexture({texture:$s,mipLevel:0},mp,{offset:0,bytesPerRow:8},{width:8,height:8,depthOrArrayLayers:1}),$s)}};Rt.loadHDRImage=async e=>{const t=await dp.load(e),r=t.width*t.height,n={width:t.width,height:t.height,rgbaHalfFloat:new Uint16Array(t.width*t.height*4)};for(let i=0;i{const n=await Rt.loadHDRImage(e),i=await $t.createHDRTexture(n,t,r);return X.addTextureBytes(i),i},Rt.load6SeparateHDRFacesAsCubeMapTexture=async(e,t,r,n=null)=>{if(e.length!==6)return void console.error("Need 6 separate urls for 6 separate environment textures");const i=await Promise.all(e.map(u=>Rt.loadHDRTexture(u))),o=kr.cubeTextureFromIndividualHDRTextures(i,n,t,r);return X.addTextureBytes(o),o},Rt.loadTextureFromData=async(e,t="rgba8unorm",r=!0,n=!1,i=!1,o="Bitmap Texture")=>{const u=new Blob([e],{type:"image/png"}),l=await createImageBitmap(u,{colorSpaceConversion:"none"});let m=GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT;r&&(m|=GPUTextureUsage.STORAGE_BINDING);const y={label:o,dimension:"2d",size:{width:l.width,height:l.height,depthOrArrayLayers:1},format:t,usage:m};r&&(y.mipLevelCount=It(l.width,l.height));const d=A.device.createTexture(y);if(A.device.queue.copyExternalImageToTexture({source:l,flipY:n},{texture:d},{width:l.width,height:l.height}),!r)return X.addTextureBytes(d),d;if($t.generateMipsFor2DTextureWithComputePSO(d),X.addTextureBytes(d),i){const x=document.createElement("canvas"),b=x.getContext("2d");x.width=d.width/2,x.height=d.height/2,b.drawImage(l,0,0),x.style.setProperty("position","fixed"),x.style.setProperty("z-index","99"),x.style.setProperty("left","2rem"),x.style.setProperty("bottom","2rem"),x.style.setProperty("width",.1*d.width+"px"),x.style.setProperty("height",.1*d.height+"px"),x.dataset.debugLabel=`${o.toLowerCase()}`,document.body.appendChild(x)}return l.close(),d};let ge=Rt;class gp extends ar{constructor(e){super(),this.url=e,this.nodeMaterialIds=new Map([]),this.gpuSamplers=new Map,this.gpuTextures=new Map,this.gpuBuffers=new Map,this.updateWorldMatrix()}setMaterial(e,t=V.Deferred){return this.traverse(r=>{r instanceof Ae&&r.setMaterial(e,t)}),this}setIsReflective(e){return this.traverse(t=>{t instanceof Ae&&(t.materialProps.isReflective=e)}),this}setTextureForAll(e,t=1){return this.traverse(r=>{r instanceof Ae&&r.setTexture(e,t)}),this}setSampler(e){return this.traverse(t=>{t instanceof Ae&&t.setSampler(e)}),this}setTextureFor(e,t,r=1){const n=this.findChildByLabel(e);if(n instanceof Ae)return n.setTexture(t,r),this;console.error("Found child is not instance of a Drawable")}async load(){const e=[],t=async function(u,l,m){let y,d;Array.isArray(l)||ui(l)?(y=l,d=m):(y=[],d=l);const x=du(d);let b=u;return typeof u=="string"&&(b=await x(u)),Jt(u)&&(b=await x(u)),Array.isArray(y),await di(b,y,d)}(this.url,Ii);e.push(t);const r=(n=await t,new ip().postProcess(n,i));var n,i;const o=this.initGPUTexturesFrom(r.textures);return e.push(o),this.initGPUSamplersFrom(r.samplers),this.initGPUBuffersFrom(r.bufferViews),this.initMaterialsFrom(r.materials),this.initNodesFrom(r),Promise.all(e)}async initMaterialsFrom(e){for(const t of e){if(t.pbrMetallicRoughness&&t.pbrMetallicRoughness.baseColorTexture){const r=await this.gpuTextures.get(t.pbrMetallicRoughness.baseColorTexture.texture.id),n=this.nodeMaterialIds.get(t.id);for(const i of n)i.setTexture(r,me.Albedo);if(t.pbrMetallicRoughness.metallicRoughnessTexture){const i=await this.gpuTextures.get(t.pbrMetallicRoughness.metallicRoughnessTexture.texture.id),o=this.nodeMaterialIds.get(t.id);for(const u of o)u.setTexture(i,me.MetallicRoughness)}}if(t.normalTexture){const r=await this.gpuTextures.get(t.normalTexture.texture.id),n=this.nodeMaterialIds.get(t.id);for(const i of n)i.setTexture(r,me.Normal)}}}async initGPUTexturesFrom(e){const t=[];for(const r of e){const n=ge.loadTextureFromData(r.source.bufferView.data,"rgba8unorm",!0,!1,!1,`GLTF Texture: ${r.id}`);t.push(n),this.gpuTextures.set(r.id,n)}return Promise.all(t)}initGPUSamplersFrom(e){for(const t of e){const r=Ke.getSamplerFromGltfSamplerDef(t);this.gpuSamplers.set(t.id,r)}}initGPUBuffersFrom(e){for(const t of e){let r=0;t.target===34963&&(r|=GPUBufferUsage.INDEX),t.target===34962&&(r|=GPUBufferUsage.VERTEX);const n=4*Math.ceil(t.byteLength/4),i=A.device.createBuffer({label:t.id,mappedAtCreation:!0,size:n,usage:r});X.addBufferBytes(i),new Uint8Array(i.getMappedRange()).set(new Uint8Array(t.buffer.arrayBuffer,t.byteOffset,t.byteLength)),i.unmap(),this.gpuBuffers.set(t.id,i)}}initNodesFrom(e){var t,r,n,i;for(const o of e.nodes)if(o.mesh)for(const u of o.mesh.primitives){const l=new op(u,this.gpuBuffers),m=new Ae(l),y=F.create(),d=F.create(1,1,1),x=as.identity(),b=this.nodeMaterialIds.get(u.material.id)||[];b.push(m),this.nodeMaterialIds.set(u.material.id,b),u.material.pbrMetallicRoughness.baseColorTexture&&u.material.pbrMetallicRoughness.baseColorTexture.texture.source.uri.includes("5823059166183034438")?m.materialProps.isReflective=!0:m.materialProps.isReflective=!1,m.label=o.name??o.id;const _=(r=(t=u.attributes)==null?void 0:t.POSITION)==null?void 0:r.min;_&&m.boundingBox.setMinAABBfromGLTF(_);const C=(i=(n=u.attributes)==null?void 0:n.POSITION)==null?void 0:i.max;C&&m.boundingBox.setMaxAABBfromGLTF(C),o.translation&&F.set(o.translation[0],o.translation[1],o.translation[2],y),o.scale&&F.set(o.scale[0],o.scale[1],o.scale[2],d),o.rotation&&as.set(o.rotation[0],o.rotation[1],o.rotation[2],o.rotation[3],x),m.setCustomMatrixFromTRS(y,x,d),m.sampler=this.gpuSamplers.get("sampler-0"),this.addChild(m)}}}const yc="vertexMain",bc="fragmentMain",yp=` + ${Y.Camera} + + @group(${ce.CameraPlusOptionalLights}) @binding(0) var camera: Camera; + + @group(1) @binding(0) var linePointPositions: array; + + @vertex + fn ${yc}( + @builtin(vertex_index) vertexId: u32, + ) -> @builtin(position) vec4f { + let position = linePointPositions[vertexId]; + return camera.projectionViewMatrix * position; + } + + @fragment + fn ${bc}() -> @location(0) vec4f { + return vec4f(vec3f(1), 1); + } +`;class bp extends ar{constructor(e){super(),this.points=e,this.pointsGPUBuffer=A.device.createBuffer({label:"Line Points GPU Buffer",size:4*e.length*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0}),X.addBufferBytes(this.pointsGPUBuffer);const t=new Float32Array(this.pointsGPUBuffer.getMappedRange());for(let u=0;ur!==e.id;e instanceof Ae&&(e.isOpaque?(this.opaqueMeshes=this.opaqueMeshes.filter(t),this.culledOpaqueMeshes=this.culledOpaqueMeshes.filter(t)):(this.transparentMeshes=this.transparentMeshes.filter(t),this.culledTransparentMeshes=this.culledTransparentMeshes.filter(t)));for(const r of this.onGraphChangedCallbacks)r()}}const xc=` + // Van Der Corpus sequence + // @see http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + fn vdcSequence(inBits: u32) -> f32 { + var bits = inBits; + bits = (bits << 16u) | (bits >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + return f32(bits) * 2.3283064365386963e-10; // / 0x100000000 + } + + // Hammersley sequence + // @see http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html + fn hammersley(i: u32, N: u32) -> vec2f { + return vec2f(f32(i) / f32(N), vdcSequence(i)); + } + + // Based on Karis 2014 + // GGX NDF via importance sampling + fn importanceSampleGGX(Xi: vec2f, N: vec3f, roughness: f32) -> vec3f { + let alpha = roughness * roughness; + let alpha2 = alpha * alpha; + + let phi = TWO_PI * Xi.x; + let cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha2 - 1.0) * Xi.y)); + let sinTheta = sqrt(1.0 - cosTheta * cosTheta); + + // from spherical coordinates to cartesian coordinates + let H = vec3f(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta); + + // from tangent-space vector to world-space sample vector + + let up = select(WORLD_UP, WORLD_FORWARD, abs(N.z) < 0.999); + let tangent = normalize(cross(up, N)); + let bitangent = cross(N, tangent); + + return tangent * H.x + bitangent * H.y + N * H.z; + } + + fn GTR2(NdotH: f32, a: f32) -> f32 { + let a2 = a * a; + let t = 1.0 + (a2 - 1.0) * NdotH * NdotH; + return step(0.0, NdotH) * a2 / (PI * t * t); + } + + fn distributionGGX(NdotH: f32, roughness: f32) -> f32 { + return GTR2(NdotH, roughness * roughness); + } + + fn visibilitySmithGGXCorrelated(NdotV: f32, NdotL: f32, roughness: f32) -> f32 { + let a2 = roughness * roughness; + let oneMinusA2 = 1.0 - a2; + let ggxv = NdotL * sqrt(NdotV * NdotV * oneMinusA2 + a2); + let ggxl = NdotV * sqrt(NdotL * NdotL * oneMinusA2 + a2); + + let ggx = ggxv + ggxl; + if (ggx > 0.0) { + return 0.5 / ggx; + } + return 0.0; + } +`,_c="main",_p=` + ${Y.CommonHelpers} + + @group(0) @binding(0) var outTexture: texture_storage_2d; + + const SAMPLE_COUNT = 1024u; + + ${xc} + + // https://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf + // Karis 2014 + @must_use + fn integrate(NdotV: f32, roughness: f32) -> vec2f { + var V = vec3f(0.0); + V.x = sqrt(1.0 - NdotV * NdotV); // sin + V.y = 0.0; + V.z = NdotV; // cos + + // N points straight upwards for this integration + let N = vec3f(0.0, 0.0, 1.0); + + var A = 0.0; + var B = 0.0; + + for (var i = 0u; i < SAMPLE_COUNT; i++) { + let Xi = hammersley(i, SAMPLE_COUNT); + let H = importanceSampleGGX(Xi, N, roughness); + let L = 2.0 * dot(V, H) * H - V; + + let NdotL = saturate(L.z); + let NdotH = saturate(H.z); + let VdotH = saturate(dot(V, H)); + + if (NdotL > 0.0) { + let V_pdf = visibilitySmithGGXCorrelated(NdotV, NdotL, roughness) * VdotH * NdotL / NdotH; + let Fc = pow(1.0 - VdotH, 5.0); + A += (1.0 - Fc) * V_pdf; + B += Fc * V_pdf; + } + } + + return 4.0 * vec2f(A, B) / f32(SAMPLE_COUNT); + } + + @compute @workgroup_size(8, 8) + fn ${_c}(@builtin(global_invocation_id) id: vec3u) { + let texSize = textureDimensions(outTexture).xy; + if (any(id.xy >= texSize)) { + return; + } + + let size = vec2f(texSize.xy) - 1.0; + let uv = vec2f(id.xy) / size; + + let result = vec4f(integrate(uv.x, uv.y), 0, 0); + textureStore(outTexture, id.xy, result); + } +`;let Xs;const Bc=[{binding:0,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"rgba16float",viewDimension:"2d"}}],fn=class fn extends Ye{static get computePSO(){if(Xs)return Xs;const e=A.device.createBindGroupLayout({label:"BDRF Lut Compute PSO Bind Group Layout",entries:Bc});return Xs=A.device.createComputePipeline({label:"BDRF LUT Generate Compute PSO",compute:{module:J.createShaderModule(_p),entryPoint:_c},layout:A.device.createPipelineLayout({label:"BDRF LUT Generation Compute PSO Layout",bindGroupLayouts:[e]})}),Xs}};fn.encode=(e=512)=>{const t=A.device.createTexture({label:"BDRF LUT Texture",size:{width:e,height:e,depthOrArrayLayers:1},format:"rgba16float",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.COPY_DST,mipLevelCount:1}),r=A.device.createCommandEncoder({label:"BDRF LUT Generate Command Encoder"});A.ENABLE_DEBUG_GROUPS&&r.pushDebugGroup("BDRF LUT Generation");const n=r.beginComputePass({label:"BDRF LUT Generate Compute Pass"}),i=A.device.createBindGroupLayout({label:"BDRF Lut Compute PSO Bind Group Layout",entries:Bc}),o=[{binding:0,resource:t.createView()}],u=A.device.createBindGroup({label:"BDRF LUT Generate Input Bind Group",layout:i,entries:o}),l=(e+8-1)/8,m=(e+8-1)/8;return n.setPipeline(fn.computePSO),n.setBindGroup(0,u),n.dispatchWorkgroups(l,m,1),n.end(),A.ENABLE_DEBUG_GROUPS&&r.popDebugGroup(),A.device.queue.submit([r.finish()]),X.addTextureBytes(t),t};let zi=fn;const Ac="main",Bp=` + ${Y.CommonHelpers} + ${Y.MathHelpers} + + @group(0) @binding(0) var inTexture: texture_cube; + @group(0) @binding(1) var outTexture: texture_storage_2d; + @group(0) @binding(2) var cubeSampler: sampler; + @group(0) @binding(3) var face: u32; + + @compute @workgroup_size(8, 8) + fn ${Ac}(@builtin(global_invocation_id) id: vec3u) { + let texSize = textureDimensions(outTexture).xy; + if (any(id.xy >= texSize)) { + return; + } + + let size = vec2f(texSize.xy); + let uv = vec2f(id.xy) / size; + + var ruv = 2.0 * uv - 1.0; + ruv.y = ruv.y * -1; + + var irradiance = vec3f(0.0); + let rotation = CUBE_ROTATIONS[face]; + let N = normalize(vec3f(ruv, 1.0) * rotateAxisAngle(rotation.xyz, rotation.w)); + var UP = select(WORLD_UP, WORLD_FORWARD, abs(N.z) < 0.999); + let RIGHT = normalize(cross(UP, N)); + UP = cross(RIGHT, N); + + var sampleCount = 0u; + + for (var phi: f32 = 0.0; phi < TWO_PI; phi += DELTA_PHI) { + let sinPhi = sin(phi); + let cosPhi = cos(phi); + for (var theta: f32 = 0.0; theta < HALF_PI; theta += DELTA_THETA) { + let sinTheta = sin(theta); + let cosTheta = cos(theta); + + let tempVec = cosPhi * RIGHT + sinPhi * UP; + let sampleVector = cosTheta * N + sinTheta * tempVec; + + irradiance += textureSampleLevel(inTexture, cubeSampler, sampleVector, 2).rgb * cos(theta) * sin(theta); + sampleCount++; + } + } + + irradiance = PI * irradiance / f32(sampleCount); + textureStore(outTexture, id.xy, vec4f(irradiance, 1.0)); + } +`;let Ys;const vc=[{binding:0,texture:{viewDimension:"cube",sampleType:"float"},visibility:GPUShaderStage.COMPUTE},{binding:1,storageTexture:{access:"write-only",format:"rgba16float",viewDimension:"2d"},visibility:GPUShaderStage.COMPUTE},{binding:2,sampler:{},visibility:GPUShaderStage.COMPUTE},{binding:3,buffer:{},visibility:GPUShaderStage.COMPUTE}],pn=class pn extends Ye{static get computePSO(){if(Ys)return Ys;const e=A.device.createBindGroupLayout({label:"Diffuse IBL Compute PSO Bind Group Layout",entries:vc});return Ys=J.createComputePipeline({label:"Diffuse IBL Compute PSO",compute:{module:J.createShaderModule(Bp),entryPoint:Ac},layout:A.device.createPipelineLayout({label:"Diffuse IBL Compute PSO Layout",bindGroupLayouts:[e]})}),Ys}};pn.encode=(e,t=32)=>{if(e.depthOrArrayLayers!==6)return void console.error("Need cube texture as a source for IBL Diffuse");if(e.format!=="rgba16float")return void console.error("Only rgba16float cube textures supported for Diffuse IBL for now");const r=kr.createEmptyCubeTexture(t,"Diffuse IBL Texture",!0),n=A.device.createBindGroupLayout({label:"Diffuse IBL Compute PSO Bind Group Layout",entries:vc}),i=[{binding:0,resource:null},{binding:1,resource:null},{binding:2,resource:Ke.createSampler({addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",minFilter:"linear",magFilter:"linear"})},{binding:3,resource:{buffer:null}}],o=A.device.createCommandEncoder({label:"Diffuse IBL Command Encoder"}),u=o.beginComputePass({label:"Diffuse IBL Compute Pass"});A.ENABLE_DEBUG_GROUPS&&u.pushDebugGroup("Begin Diffuse IBL"),u.setPipeline(pn.computePSO);const l=e.createView({dimension:"cube"});for(let m=0;m<6;m++){const y=A.device.createBuffer({label:"Diffuse IBL Face GPUBuffer",size:Uint32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});X.addBufferBytes(y),new Uint32Array(y.getMappedRange()).set(new Uint32Array([m])),y.unmap();const d=r.createView({format:r.format,dimension:"2d",baseMipLevel:0,mipLevelCount:1,baseArrayLayer:m,arrayLayerCount:1});i[0].resource=l,i[1].resource=d,i[3].resource={buffer:y};const x=A.device.createBindGroup({layout:n,entries:i}),b=8,_=(r.width+b-1)/b,C=(r.height+b-1)/b;u.setBindGroup(0,x),u.dispatchWorkgroups(_,C,1)}return A.ENABLE_DEBUG_GROUPS&&u.popDebugGroup(),u.end(),A.device.queue.submit([o.finish()]),X.addTextureBytes(r),r};let ji=pn;const wc="main",Ap=` + ${Y.CommonHelpers} + ${Y.MathHelpers} + + @group(0) @binding(0) var inTexture: texture_cube; + @group(0) @binding(1) var outTexture: texture_storage_2d; + @group(0) @binding(2) var cubeSampler: sampler; + @group(0) @binding(3) var face: u32; + @group(0) @binding(4) var roughness: f32; + + const SAMPLE_COUNT: u32 = 1024; + + ${xc} + + @compute @workgroup_size(8, 8) + fn ${wc}(@builtin(global_invocation_id) id: vec3u) { + let texSize = textureDimensions(outTexture).xy; + if (any(id.xy >= texSize)) { + return; + } + + let size = vec2f(texSize.xy); + let uv = vec2f(id.xy) / size; + + var ruv = 2.0 * uv - 1.0; + ruv.y = ruv.y * -1; + + let rotation = CUBE_ROTATIONS[face]; + let N = normalize(vec3f(ruv, 1.0) * rotateAxisAngle(rotation.xyz, rotation.w)); + + let R = N; + let V = R; + + var prefilteredColor = vec3f(0.0); + var totalWeight = 0.0; + + for (var i = 0u; i < SAMPLE_COUNT; i++) { + // generates a sample vector that's biased towards the preferred alignment direction (importance sampling). + let Xi = hammersley(i, SAMPLE_COUNT); + let H = importanceSampleGGX(Xi, N, roughness); + let L = normalize(2.0 * dot(V, H) * H - V); + + let NdotL = max(dot(N, L), 0.0); + + if (NdotL > 0.0) { + // sample from the environment's mip level based on roughness/pdf + + let NdotH = max(dot(N, H), 0.0); + let HdotV = max(dot(H, V), 0.0); + let D = distributionGGX(NdotH, roughness); + let pdf = max((D * NdotH / (4.0 * HdotV)) + 0.0001, 0.0001); + + let resolution = f32(textureDimensions(inTexture).x); // resolution of source cubemap (per face) + let saTexel = 4.0 * PI / (6.0 * resolution * resolution); + let saSample = 1.0 / (f32(SAMPLE_COUNT) * pdf + 0.0001); + + let mipLevel = select(0.5 * log2(saSample / saTexel), 0.0, roughness == 0.0); + + prefilteredColor += textureSampleLevel(inTexture, cubeSampler, L, mipLevel).rgb * NdotL; + totalWeight += NdotL; + } + } + + prefilteredColor = prefilteredColor / totalWeight; + textureStore(outTexture, id.xy, vec4f(prefilteredColor, 1.0)); + } +`;let Ws;const Cc=[{binding:0,texture:{viewDimension:"cube",sampleType:"float"},visibility:GPUShaderStage.COMPUTE},{binding:1,storageTexture:{access:"write-only",format:"rgba16float",viewDimension:"2d"},visibility:GPUShaderStage.COMPUTE},{binding:2,sampler:{},visibility:GPUShaderStage.COMPUTE},{binding:3,buffer:{},visibility:GPUShaderStage.COMPUTE},{binding:4,buffer:{},visibility:GPUShaderStage.COMPUTE}],mn=class mn extends Ye{static get computePSO(){if(Ws)return Ws;const e=A.device.createBindGroupLayout({label:"Specular IBL Compute PSO Bind Group Layout",entries:Cc});return Ws=J.createComputePipeline({label:"Specular IBL Compute PSO",compute:{module:J.createShaderModule(Ap),entryPoint:wc},layout:A.device.createPipelineLayout({label:"Specular IBL Compute PSO",bindGroupLayouts:[e]})}),Ws}};mn.encode=(e,t=128)=>{if(e.depthOrArrayLayers!==6)return void console.error("Need cube texture as a source of IBL Specular");if(e.format!=="rgba16float")return void console.error("Only rgba16float cube textures supported for Specular IBL for now");const r=kr.createEmptyCubeTexture(t,"Specular IBL Texture",!0),n=e.createView({dimension:"cube"}),i=r.mipLevelCount,o=[{binding:0,resource:n},{binding:1,resource:null},{binding:2,resource:Ke.createSampler({minFilter:"linear",magFilter:"linear"})},{binding:3,resource:{buffer:null}},{binding:4,resource:{buffer:null}}],u=A.device.createCommandEncoder({label:"Specular IBL Command Encoder"});A.ENABLE_DEBUG_GROUPS&&u.pushDebugGroup("Begin Specular IBL Generation");const l=u.beginComputePass({label:"Specular IBL Compute Pass"});l.setPipeline(mn.computePSO);const m=A.device.createBindGroupLayout({label:"Specular IBL Compute PSO Bind Group Layout",entries:Cc});let y=t;for(let d=0;d(s[s.Normal=0]="Normal",s[s.AO=1]="AO",s[s.Metallic=2]="Metallic",s[s.Roughness=3]="Roughness",s[s.Reflectance=4]="Reflectance",s[s.Albedo=5]="Albedo",s[s.Depth=6]="Depth",s[s.Velocity=7]="Velocity",s[s.ShadowDepthCascade0=8]="ShadowDepthCascade0",s[s.ShadowDepthCascade1=9]="ShadowDepthCascade1",s[s.BDRF=10]="BDRF",s))(W||{});const Tt="fullscreenVertex",Yt=` + ${Y.VertexOutput} + + const pos = array( + vec2(-1.0, -1.0), vec2(3, -1.0), vec2(-1.0, 3), + ); + const uv = array( + vec2(0.0, 0.0), vec2(2.0, 0.0), vec2(0.0, 2.0) + ); + + @vertex + fn ${Tt}( + @builtin(vertex_index) vertexId: u32, + @builtin(instance_index) instanceId: u32, + ) -> VertexOutput { + var out: VertexOutput; + out.position = vec4f(pos[vertexId], 0.0, 1.0); + out.uv = uv[vertexId]; + out.instanceId = instanceId; + return out; + } +`,Lp=/#([^\s]*)(\s*)/gm;class Mc{constructor(e){ee(this,"elseIsValid",!0);ee(this,"branches",[]);this.pushBranch("if",e)}pushBranch(e,t){if(!this.elseIsValid)throw new Error(`#${e} not preceeded by an #if or #elif`);this.elseIsValid=e==="if"||e==="elif",this.branches.push({expression:!!t,string:""})}appendStringToCurrentBranch(...e){for(const t of e)this.branches[this.branches.length-1].string+=t}resolve(){for(const e of this.branches)if(e.expression)return e.string;return""}}function St(s,...e){const t=[];let r=new Mc(!0);r.elseIsValid=!1;const n=(i,o)=>{if(i.index+i[0].length!=o.length)throw new Error(`#${i[1]} must be immediately followed by a template expression (ie: \${value})`)};for(let i=0;ii&&r.appendStringToCurrentBranch(e[i])}if(t.length)throw new Error("Mismatched #if/#endif count");return r.resolve()}const jr=` + fn encodeNormal(n: vec3f) -> vec2f { + // return n.xy* 0.5 + 0.5; + let p = sqrt(n.z * 8 + 8); + return n.xy / p + 0.5; + } + + fn decodeNormal(enc: vec2f) -> vec3f { + + let fenc = enc * 4 - 2; + let f = dot(fenc, fenc); + let g = sqrt(1 - f / 4); + + return vec3f( + fenc * g, + 1 - f / 2 + ); + } +`,Pc="fragmentShaderDebugTexture",Op=new Map([[W.Albedo,"Albedo"],[W.Normal,"View-Space Normal"],[W.AO,"Screen-Space AO"],[W.Metallic,"Metallic"],[W.Roughness,"Roughness"],[W.Reflectance,"Reflectance"],[W.Depth,"Depth"],[W.Velocity,"Velocity"],[W.ShadowDepthCascade0,"Cascade #1"],[W.ShadowDepthCascade1,"Cascade #2"]]);class ct{constructor(e){this.type=e,this.$rootEl=document.createElement("div"),this.$headline=document.createElement("h4"),this.$canvas=document.createElement("canvas"),this.$rootEl.classList.add("debug-canvas-wrapper"),this.$canvas.classList.add("debug-canvas"),this.$headline.innerText=Op.get(e),this.$rootEl.appendChild(this.$headline),this.$rootEl.appendChild(this.$canvas),this.ctx=this.$canvas.getContext("webgpu"),this.ctx.configure({device:A.device,format:A.pixelFormat,usage:GPUTextureUsage.RENDER_ATTACHMENT});const t=[{format:A.pixelFormat}];var r;this.samplerTextureBindGroupLayoutEntries=[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:this.isDepthTexture?"depth":"float"}}],this.samplerTextureBindGroupLayout=A.device.createBindGroupLayout({label:"TextureDebugMesh Sampler + Texture GPUBindGroupLayout",entries:this.samplerTextureBindGroupLayoutEntries}),this.renderPSO=J.createRenderPipeline({label:`Debug Canvas ${e} Render PSO`,vertex:{module:J.createShaderModule(Yt),entryPoint:Tt},fragment:{module:J.createShaderModule((r=this.type,St` + ${Y.VertexOutput} + + ${jr} + + @group(0) @binding(0) var mySampler: sampler; + + #if ${r===W.Depth||r===W.ShadowDepthCascade0||r===W.ShadowDepthCascade1} + @group(0) @binding(1) var myTexture: texture_depth_2d; + #else + @group(0) @binding(1) var myTexture: texture_2d; + #endif + + @fragment + fn ${Pc}(in: VertexOutput) -> @location(0) vec4 { + var uv = in.uv; + uv.y = 1.0 - uv.y; + var color: vec4f; + #if ${r===W.Normal} + color = vec4f(decodeNormal(textureSample(myTexture, mySampler, uv).rg), 1.0); + // color = vec4f(textureSample(myTexture, mySampler, uv).rgb, 1.0); + #elif ${r===W.Metallic} + color = vec4f(textureSample(myTexture, mySampler, uv).bbb, 1.0); + #elif ${r===W.Roughness} + color = vec4f(textureSample(myTexture, mySampler, uv).aaa, 1.0); + #elif ${r===W.Reflectance} + color = vec4f(textureSample(myTexture, mySampler, uv).a, 0.0, 0.0, 1.0); + #elif ${r===W.Depth} + let depth = textureSample(myTexture, mySampler, uv); + + let near: f32 = 0.1; // Example near plane + let far: f32 = 20.0; // Example far plane + + // Linearize the depth (from clip space depth to linear depth) + let depth_linear = near * far / (far - depth * (far - near)); + + // Normalize the linear depth to [0, 1] (NDC space) + let depth_ndc = (depth_linear - near) / (far - near); + color = vec4f(vec3f(depth_ndc), 1); + + #elif ${r===W.ShadowDepthCascade0||r===W.ShadowDepthCascade1} + let depth = textureSample(myTexture, mySampler, uv); + + let near: f32 = 0.1; // Example near plane + let far: f32 = 1.0; // Example far plane + + // Linearize the depth (from clip space depth to linear depth) + let depth_linear = near * far / (far - depth * (far - near)); + + // Normalize the linear depth to [0, 1] (NDC space) + let depth_ndc = (depth_linear - near) / (far - near); + color = vec4f(vec3f(depth_ndc), 1); + #elif ${r===W.Velocity} + color = vec4f(textureSample(myTexture, mySampler, uv).rg * 100, 0, 1); + #elif ${r===W.BDRF} + color = vec4f(textureSample(myTexture, mySampler, in.uv).rg, 0, 1); + #elif ${r===W.Albedo} + color = vec4f(textureSample(myTexture, mySampler, uv).rgb, 1); + #elif ${r===W.AO} + color = vec4f(textureSample(myTexture, mySampler, uv).rrr, 1); + #else + color = textureSample(myTexture, mySampler, uv); + #endif + return color; + } +`)),entryPoint:Pc,targets:t},layout:A.device.createPipelineLayout({label:`Debug Canvas ${e} Render PSO Layout`,bindGroupLayouts:[this.samplerTextureBindGroupLayout]})}),this.renderPassDescriptor={label:`Debug Canvas ${e} Render Pass Descriptor`,colorAttachments:[{loadOp:"load",storeOp:"store",view:null}]}}get isDepthTexture(){return this.type===W.Depth||this.type===W.ShadowDepthCascade0||this.type===W.ShadowDepthCascade1}appendTo(e){e.appendChild(this.$rootEl)}setTexture(e,t=e.width,r=e.height){this.debugTexture=e,this.$canvas.width=t,this.$canvas.height=r;let n=0;this.type===W.ShadowDepthCascade0?n=0:this.type===W.ShadowDepthCascade1&&(n=1);const i=[{binding:0,resource:Ke.createSampler({magFilter:"linear",minFilter:"linear"})},{binding:1,resource:e.createView({aspect:this.isDepthTexture?"depth-only":"all",baseArrayLayer:n,dimension:"2d"})}];this.samplerTextureBindGroup=A.device.createBindGroup({layout:this.samplerTextureBindGroupLayout,entries:i})}render(e){if(!this.debugTexture)return;this.renderPassDescriptor.colorAttachments[0].view=this.ctx.getCurrentTexture().createView();const t=e.beginRenderPass(this.renderPassDescriptor);A.ENABLE_DEBUG_GROUPS&&t.pushDebugGroup(`Display Debug Texture ${this.type}`),t.setPipeline(this.renderPSO),t.setBindGroup(0,this.samplerTextureBindGroup),t.draw(3),A.ENABLE_DEBUG_GROUPS&&t.popDebugGroup(),t.end()}}var Xi=(s=>(s[s.GBuffer=0]="GBuffer",s[s.Shadow=1]="Shadow",s))(Xi||{});const Ip=new Map([[0,"G-Buffer Debug"],[1,"Shadows Debug"]]);class Zs{constructor(e){this.canvases=new Map,this.$root=Zs.createRootElement(),this.$main=document.createElement("div"),this.$main.classList.add("section");const t=document.createElement("h2");t.textContent=Ip.get(e),t.classList.add("section-headline"),this.$root.appendChild(t),this.$root.appendChild(this.$main)}static createRootElement(){const e=document.createElement("div");return e.classList.add("texture-debug-wrapper"),e}appendTo(e){e.appendChild(this.$root)}setTextureFor(e,t,r=.2*t.width,n=.2*t.height){return this.canvases.get(e).setTexture(t,r,n),this}render(e){for(const t of this.canvases.values())t.render(e)}}class Dp extends Zs{constructor(){super(Xi.GBuffer);const e=new ct(W.Albedo);e.appendTo(this.$main),this.canvases.set(W.Albedo,e);const t=new ct(W.Normal);t.appendTo(this.$main),this.canvases.set(W.Normal,t);const r=new ct(W.Metallic);r.appendTo(this.$main),this.canvases.set(W.Metallic,r);const n=new ct(W.Roughness);n.appendTo(this.$main),this.canvases.set(W.Roughness,n);const i=new ct(W.AO);i.appendTo(this.$main),this.canvases.set(W.AO,i);const o=new ct(W.Reflectance);o.appendTo(this.$main),this.canvases.set(W.Reflectance,o);const u=new ct(W.Depth);u.appendTo(this.$main),this.canvases.set(W.Depth,u);const l=new ct(W.Velocity);l.appendTo(this.$main),this.canvases.set(W.Velocity,l)}}class Fp extends Zs{constructor(){super(Xi.Shadow);const e=new ct(W.ShadowDepthCascade0);e.appendTo(this.$main),this.canvases.set(W.ShadowDepthCascade0,e);const t=new ct(W.ShadowDepthCascade1);t.appendTo(this.$main),this.canvases.set(W.ShadowDepthCascade1,t)}}const gn=class gn{constructor(){this.open=!1,this.$root=document.createElement("div"),this.$root.id=gn.ROOT_EL_ID,document.body.appendChild(this.$root),this.gbufferDebugSection=new Dp,this.gbufferDebugSection.appendTo(this.$root),this.shadowDebugSection=new Fp,this.shadowDebugSection.appendTo(this.$root)}reveal(){this.open=!0,this.$root.classList.add("open")}hide(){this.open=!1,this.$root.classList.remove("open")}scrollToShadowSection(){this.shadowDebugSection.$root.scrollIntoView({block:"start",inline:"nearest"})}scrollIntoGbufferSection(){this.gbufferDebugSection.$root.scrollIntoView({block:"start",inline:"nearest"})}setTextureGBufferSection(e,t,r=.2*t.width,n=.2*t.height){return this.open?(this.gbufferDebugSection.setTextureFor(e,t,r,n),this):this}setTextureShadowSection(e,t,r=.2*t.width,n=.2*t.height){return this.open?(this.shadowDebugSection.setTextureFor(e,t,r,n),this):this}render(e){this.open&&(this.gbufferDebugSection.render(e),this.shadowDebugSection.render(e))}};gn.ROOT_EL_ID="webgpu-debug-root";let Yi=gn;const Up=new Map([[se.CPUTotal,"cpu-total"],[se.GPUTotal,"gpu-total"],[se.FPS,"fps"],[se.VRAM,"vram"],[se.VisibleMeshes,"culled-meshes"],[se.LightsCount,"lights-count"],[se.DeferredRenderPass,"deferred"],[se.DirectionalAmbientLightingRenderPass,"directional-ambient-light"],[se.PointLightsStencilMask,"point-lights-stencil-mask"],[se.PointLightsLighting,"point-lights-lighting"],[se.SSAORenderPass,"ssao"],[se.TransparentRenderPass,"transparent"],[se.ShadowRenderPass,"shadow"],[se.TAAResolveRenderPass,"taa-resolve"],[se.ReflectionRenderPass,"reflection"],[se.BlitRenderPass,"blit"]]),kp=new Map([[se.CPUTotal,"CPU"],[se.GPUTotal,"GPU"],[se.FPS,"FPS"],[se.VRAM,"VRAM Usage"],[se.VisibleMeshes,"Visible Meshes"],[se.LightsCount,"Lights Count"],[se.DeferredRenderPass,"G-Buffer Render Pass"],[se.DirectionalAmbientLightingRenderPass,"Directional + Ambient Render Pass"],[se.PointLightsStencilMask,"Point Lights Stencil Mask Pass"],[se.PointLightsLighting,"Point Lights Render Pass"],[se.SSAORenderPass,"SSAO Render Pass"],[se.TransparentRenderPass,"Transparent Render Pass"],[se.ShadowRenderPass,"Directional Shadow Render Pass"],[se.TAAResolveRenderPass,"TAA Resolve Render Pass"],[se.ReflectionRenderPass,"Reflection Render Pass"],[se.BlitRenderPass,"Blit Render Pass"]]),_o=class _o{constructor(){this.$renderPassTimingDisplayEls=new Map,this.$root=document.createElement("div"),this.$root.id="timings-debug-container",this.$root.classList.add("fadable","hidden"),document.body.appendChild(this.$root);for(const e of Md){const t=Up.get(e),r=document.createElement("div");r.id=`${t}-debug-timing`,r.classList.add("timing-container"),this.$root.appendChild(r);const n=document.createElement("div");n.classList.add("timing-label"),n.innerText=`${kp.get(e)}:`,r.appendChild(n);const i=document.createElement("div");i.classList.add("timing-value"),r.appendChild(i);const o={root:r,label:n,value:i};this.$renderPassTimingDisplayEls.set(e,o)}}toggleVisibility(){this.$root.classList.toggle("hidden")}setDisplayValue(e,t){return this.$renderPassTimingDisplayEls.get(e).value.innerText=t,this}};_o.NOT_AVAILABLE_STR="N/A";let Wi=_o;const Np=vt(kt(Y.Light).structs.Light);class br extends ar{constructor(e){super(),this.lightType=e,this._color=F.create(1,1,0),this._intensity=1;const t=kt(Y.Light);this.lightsStorageView=vt(t.structs.Light),this.lightsStorageView.set({color:this._color,position:this.position,lightType:Ed.get(e),intensity:1})}static get STRUCT_BYTE_SIZE(){return Np.arrayBuffer.byteLength}get intensity(){return this._intensity}set intensity(e){this._intensity=e,this.lightsStorageView.set({intensity:e})}get color(){return this.getColor()}set color(e){this.setColor(e[0],e[1],e[2])}setColor(e,t,r){this._color[0]=e,this._color[1]=t,this._color[2]=r,this.lightsStorageView.set({color:this._color})}setColorAsVec3(e){F.copy(e,this._color),this.lightsStorageView.set({color:this._color})}getColor(){return this._color}setPosition(e,t,r){return super.setPosition(e,t,r),this.lightsStorageView.set({position:this.position}),this}setPositionAsVec3(e){return super.setPositionAsVec3(e),this.lightsStorageView.set({position:this.position}),this}setPositionX(e){return super.setPositionX(e),this.lightsStorageView.set({position:this.position}),this}setPositionY(e){return super.setPositionY(e),this.lightsStorageView.set({position:this.position}),this}setPositionZ(e){return super.setPositionZ(e),this.lightsStorageView.set({position:this.position}),this}}class qi extends br{constructor(){super(Nt.Directional)}}class Wt extends br{get radius(){return this._radius}set radius(e){this._radius=e,this.lightsStorageView.set({radius:e})}constructor(){super(Nt.Point),this.intensity=1,this.radius=1}}class gt extends Wt{static get bindGroupLayout(){if(this._bindGroupLayout)return this._bindGroupLayout;const e=[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{}}];return this._bindGroupLayout=A.device.createBindGroupLayout({label:"Camera Face Culled Point Light Bind Group Layout",entries:e}),this._bindGroupLayout}updateGPUBuffer(){A.device.queue.writeBuffer(this.gpuBuffer,0,this.lightsStorageView.arrayBuffer)}constructor(){super(),this.gpuBuffer=A.device.createBuffer({label:"Camera Face Culled Point Light GPU Buffer",size:br.STRUCT_BYTE_SIZE,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),X.addBufferBytes(this.gpuBuffer),this.lightsStorageView.set({type:1,intensity:1,radius:1,color:F.create(1,1,1),position:F.create(0,1,0)}),this.updateGPUBuffer();const e=[{binding:0,resource:{buffer:this.gpuBuffer}}];this.bindGroup=A.device.createBindGroup({label:"Camera Face Culled Point Light Bind Group",entries:e,layout:gt.bindGroupLayout})}}class Vp{constructor(){this.pointLights=[],this.cameraFaceCulledPointLights=[],this.directionalLights=[],this.allLights=[]}get lightsCount(){return this.allLights.length}get pointLightsCount(){return this.pointLights.length}get directionalLightsCount(){return this.directionalLights.length}updateGPUBuffer(){if(!this.allLights.length)return void console.warn("No lights, skip creating GPUBuffer");this.gpuBuffer&&(X.removeBufferBytes(this.gpuBuffer),this.gpuBuffer.destroy()),this.gpuBuffer=A.device.createBuffer({label:"Lights GPU Buffer",size:br.STRUCT_BYTE_SIZE*this.allLights.length,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.STORAGE}),X.addBufferBytes(this.gpuBuffer);let e=0;for(let t=0;tr.id!==e.id;return e instanceof gt?this.cameraFaceCulledPointLights=this.cameraFaceCulledPointLights.filter(t):e instanceof Wt?this.pointLights=this.pointLights.filter(t):e instanceof qi&&(this.directionalLights=this.directionalLights.filter(t)),this.allLights=this.allLights.filter(t),this}render(e){throw new Error("Needs implementation")}}const qt=vt(kt(Y.Particle).structs.Particle),Ze=class Ze{constructor({radius:e,position:t,velocity:r,lifeSpeed:n,life:i}={radius:1,position:F.create(0,3,0),velocity:F.create(0,1,0),lifeSpeed:1,life:0}){this.radius=e,this.position=t,this.origPosition=t,this.velocity=r,this.lifeSpeed=n,this.life=i}};Ze.STRUCT_BYTE_SIZE=qt.arrayBuffer.byteLength,Ze.STRUCT_FLOATS_COUNT=Ze.STRUCT_BYTE_SIZE/Float32Array.BYTES_PER_ELEMENT,Ze.RADIUS_OFFSET=qt.views.radius.byteOffset/Float32Array.BYTES_PER_ELEMENT,Ze.POSITION_OFFSET=qt.views.position.byteOffset/Float32Array.BYTES_PER_ELEMENT,Ze.ORIG_POSITION_OFFSET=qt.views.origPosition.byteOffset/Float32Array.BYTES_PER_ELEMENT,Ze.VELOCITY_OFFSET=qt.views.velocity.byteOffset/Float32Array.BYTES_PER_ELEMENT,Ze.LIFE_OFFSET=qt.views.life.byteOffset/Float32Array.BYTES_PER_ELEMENT,Ze.LIFE_SPEED_OFFSET=qt.views.lifeSpeed.byteOffset/Float32Array.BYTES_PER_ELEMENT;let Qe=Ze;const Rc="vertexMain",Gc="fragMain",Hp=` + ${Y.Particle} + ${Y.Light} + ${Y.Camera} + + struct VertexOut { + @builtin(position) position: vec4f, + @location(0) uv: vec2f, + @location(1) @interpolate(flat) instanceId: u32, + }; + + @group(0) @binding(0) var camera: Camera; + + @group(1) @binding(0) var particles: array; + @group(1) @binding(1) var lights: array; + + override ANIMATED_PARTICLES_OFFSET_START: u32; + override CURVE_PARTICLES_OFFSET: u32; + + const positions = array( + vec2f(-1.0, -1.0), + vec2f(1.0, -1.0), + vec2f(-1.0, 1.0), + vec2f(1.0, 1.0), + ); + + const uvs = array( + vec2f(0.0, 1.0), + vec2f(1.0, 1.0), + vec2f(0.0, 0.0), + vec2f(1.0, 0.0), + ); + + @vertex + fn ${Rc}( + @builtin(vertex_index) vertexId: u32, + @builtin(instance_index) instanceId: u32, + ) -> VertexOut { + let p = particles[instanceId]; + let particlePosition = p.position; + let particleRadius = select(p.radius - p.radius * p.life, p.radius, instanceId >= CURVE_PARTICLES_OFFSET); + // let particleRadius = p.radius; + let uv = uvs[vertexId]; + var out: VertexOut; + out.position = camera.projectionViewMatrix * vec4f(particlePosition, 1); + let aspect = f32(camera.viewportWidth) / f32(camera.viewportHeight); + out.position += vec4f(positions[vertexId].xy * vec2f(particleRadius, particleRadius * aspect), 0, 0); + out.instanceId = instanceId; + out.uv = uv; + return out; + } + + @fragment + fn ${Gc}( + in: VertexOut + ) -> @location(0) vec4f { + let light = &lights[in.instanceId + ANIMATED_PARTICLES_OFFSET_START]; + let d = distance(in.uv, vec2f(0.5)); + let mask = 1.0 - smoothstep(0.2, 0.5, d); + if (mask < 0.2) { + discard; + } + let lightColor = light.color; + return vec4f(light.color * mask * 0.8, 1); + } +`,Lc="updatePointLights",Jp=` + ${Y.Particle} + ${Y.Light} + + struct SimSettings { + time: f32, + timeDelta: f32, + }; + + @group(0) @binding(0) var particles: array; + @group(0) @binding(1) var lights: array; + @group(0) @binding(2) var simSettings: SimSettings; + @group(0) @binding(3) var linePointPositions: array; + @group(0) @binding(4) var fireParticlesRevealFactor: f32; + + override WORKGROUP_SIZE_X: u32; + override WORKGROUP_SIZE_Y: u32; + override ANIMATED_PARTICLES_OFFSET_START: u32; + override FIREWORK_PARTICLES_OFFSET: u32; + override FIREWORK_PARTICLES_COUNT: u32; + override CURVE_PARTICLES_OFFSET: u32; + override CURVE_PARTICLES_COUNT: u32; + override CURVE_POSITIONS_COUNT: u32; + + @must_use + fn noise(p: vec3f) -> f32 { + return fract( + sin(dot(p, vec3f(12.9898, 78.233, 45.164))) * 43758.5453 + ); + } + + @must_use + fn random(seed: f32) -> f32 { + return fract(sin(seed * 12.9898) * 43758.5453); + } + + // Curl noise for more natural 3D fluid-like motion + fn curlNoise(p: vec3) -> vec3 { + let eps = 0.1; + + let nx = noise(p + vec3(eps, 0.0, 0.0)); + let ny = noise(p + vec3(0.0, eps, 0.0)); + let nz = noise(p + vec3(0.0, 0.0, eps)); + + let x = ny - noise(p - vec3(eps, 0.0, 0.0)); + let y = nz - noise(p - vec3(0.0, eps, 0.0)); + let z = nx - noise(p - vec3(0.0, 0.0, eps)); + + return vec3(x, y, z) / (2.0 * eps); + } + + fn interpolateLinePoint(t: f32) -> vec3f { + let totalCount = CURVE_POSITIONS_COUNT; + let segmentLength = 1.0 / f32(totalCount - 1u); + let baseIndex = u32(t / segmentLength); + let localT = fract(t / segmentLength); + let safeIndex = min(baseIndex, totalCount - 2u); + let start = linePointPositions[safeIndex]; + let end = linePointPositions[safeIndex + 1u]; + return mix(start, end, localT).xyz; + } + + @compute @workgroup_size(WORKGROUP_SIZE_X, WORKGROUP_SIZE_Y, 1) + fn ${Lc}( + @builtin(global_invocation_id) tid : vec3u + ) { + let idx = tid.x; + let particle = &particles[idx]; + let light = &lights[idx + ANIMATED_PARTICLES_OFFSET_START]; + + particle.life += particle.lifeSpeed * simSettings.timeDelta; + + if (particle.life >= 1) { + particle.position = particle.origPosition; + particle.life = 0; + } + + if (idx >= FIREWORK_PARTICLES_OFFSET && idx < FIREWORK_PARTICLES_COUNT) { + let turbulence = curlNoise( + particle.position * 0.05 + + vec3(0.0, simSettings.time * 0.05, 0.0) + ) * 0.2; + particle.position += (particle.velocity + turbulence) * simSettings.timeDelta; + light.intensity = saturate((1 - particle.life) * fireParticlesRevealFactor); + particle.radius = 0.025 * fireParticlesRevealFactor; + // light.radius *= fireParticlesRevealFactor; + // light.intensity *= fireParticlesRevealFactor; + } + + if (idx >= CURVE_PARTICLES_OFFSET && idx < CURVE_PARTICLES_OFFSET + CURVE_PARTICLES_COUNT) { + particle.position = interpolateLinePoint(particle.life) + particle.velocity; + } + + if (idx >= CURVE_PARTICLES_OFFSET + CURVE_PARTICLES_COUNT) { + particle.position = vec3f( + particle.life * 15 - 7.5, + cos(particle.life + particle.life * particle.velocity.y * 30) * 1.2 + 3.5, + sin(particle.life + particle.life * particle.velocity.y * 30) * 1.075 + particle.velocity.x + ); + let fadeIn = smoothstep(0.0, 0.1, particle.life); + let fadeOut = 1.0 - smoothstep(0.9, 1.0, particle.life); + light.intensity = 0.5 * fadeIn * fadeOut; + light.radius = 1 * fadeIn * fadeOut; + } + light.position = particle.position; + + } +`,en=[F.create(3.9,3,.9),F.create(3.9,3,-1.5),F.create(-4.95,3,.9),F.create(-4.95,3,-1.5)],zp=[F.create(3.9,3,1.15),F.create(3.9,3,-1.75),F.create(-4.95,3,1.15),F.create(-4.95,3,-1.75)],Kr=F.scale(F.create(1,.01,.01),10),de=class de extends Vp{constructor(e){super(),this.particles=[],this.mainFireLights=[],this.particlesSimSettingsArr=new Float32Array(2).fill(0),this.render2ndFloorParticles=!0;const t=new qi;t.setPositionAsVec3(Sc),t.setColor(.2156,.2627,.3333),t.intensity=0,this.addLight(t),this.mainDirLight=t;const r=new gt;r.radius=0,r.intensity=0,r.setPositionAsVec3(en[0]),r.setColorAsVec3(Kr),r.updateGPUBuffer(),this.addLight(r),this.mainFireLights.push(r);const n=new gt;n.radius=0,n.intensity=0,n.setPositionAsVec3(en[1]),n.setColorAsVec3(Kr),n.updateGPUBuffer(),this.addLight(n),this.mainFireLights.push(n);const i=new gt;i.intensity=0,i.radius=0,i.setPositionAsVec3(en[2]),i.setColorAsVec3(Kr),i.updateGPUBuffer(),this.addLight(i),this.mainFireLights.push(i);const o=new gt;o.intensity=0,o.radius=0,o.setPositionAsVec3(en[3]),o.setColorAsVec3(Kr),o.updateGPUBuffer(),this.addLight(o),this.mainFireLights.push(o);for(let p=0;p camera: Camera; + @group(1) @binding(0) var inTexture: texture_cube; + @group(1) @binding(1) var inSampler: sampler; + @group(1) @binding(2) var bayerDitherTexture: texture_2d; + @group(1) @binding(3) var bayerDitherSampler: sampler; + + @vertex + fn ${Oc}(in: VertexInput) -> VertexOutput { + var out: VertexOutput; + + var viewMatrix = camera.viewMatrix; + viewMatrix[3] = vec4f(0, 0, 0, 1); + let projViewMatrix = camera.projectionMatrix * viewMatrix; + let position = in.position; + out.position = (projViewMatrix * position).xyww; + // hijack to compute uvs for frag shader + out.viewNormal = 0.5 * (in.position.xyz + vec3(1.0, 1.0, 1.0)); + out.uv = in.uv; + return out; + } + + @fragment + fn ${Ic}(in: VertexOutput) -> @location(0) vec4f { + var cubemapVec = in.viewNormal - vec3(0.5); + var color = textureSampleLevel(inTexture, inSampler, cubemapVec, 4); //7.8); + let o = textureSample(bayerDitherTexture, bayerDitherSampler, in.position.xy / 8.0).r / 32.0 - (1.0 / 128.0); + color.r += o; + color.g += o; + color.b += o; + return vec4f(color.rgb, 1.0); + } +`;class jp extends Ns{constructor(e=1,t=1,r=1,n=1){super(),this.width=e,this.height=t,this.widthSegments=r,this.heightSegments=n;const i=.5*e,o=.5*t,u=r+1,l=n+1,m=Math.floor(r),y=Math.floor(n),d=e/r,x=t/n,b=[],_=[],C=[],f=[];for(let p=0;p0){p.push(h,g,w);const K=_[h],$=_[g],j=_[w],z=C[h],q=C[g],Z=C[w],te=f[h],re=f[g],fe=f[w],pe=new yr(h,g,w,K,$,j,z,q,Z,te,re,fe);this.faces.push(pe)}(a!==r-1||l; + @group(0) @binding(1) var sceneTexture: texture_2d; + @group(0) @binding(2) var bloomMixFactor: f32; + @group(0) @binding(3) var time: f32; + @group(0) @binding(4) var revealFactor: f32; + + @must_use + fn ACESFilm(x: vec3f) -> vec3f { + let v = x; + let a = 2.51f; + let b = 0.03f; + let c = 2.43f; + let d = 0.59f; + let e = 0.14f; + return saturate((v * (a * x + b)) / (x * (c * x + d) + e)); + } + + fn rand (co: vec2f) -> f32 { + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); + } + + fn transition(p: vec2f, progress: f32, fromColor: vec3f, toColor: vec3f) -> vec3f { + let size = vec2(10.0); + let smoothness = 0.5; + let r = rand(floor(size * p)); + let m = smoothstep(0.0, -smoothness, r - (progress * (1.0 + smoothness))); + return mix(fromColor, toColor, m); + } + + @fragment + fn ${Uc}(@builtin(position) coord : vec4f) -> @location(0) vec4f { + var bloomColor = textureLoad(bloomTexture, vec2i(floor(coord.xy)), 0).xyz; + var color = textureLoad(sceneTexture, vec2i(floor(coord.xy)), 0).xyz; + + let texSize = vec2f(textureDimensions(sceneTexture)); + // bloomColor = select(color, bloomColor, bloomColor.r > 0.); + + color = mix(color, bloomColor, bloomMixFactor); + // color = mix(color, bloomColor, 1); + + color = ACESFilm(color.rgb); + color = pow(color, vec3f(1.0 / 2.2)); + + let uv = coord.xy / texSize; + let aspect = texSize.x / texSize.y; + let timeFactor = 1.0; + let noise = vec3f(rand(vec2f(uv.x + time * timeFactor, uv.y * aspect + time * timeFactor))) * 0.1; + color = transition(uv, revealFactor, noise, color); + return vec4f(vec3(color), 1.0); + } +`,Gt=class Gt extends Se{async destroy(){super.destroy(),await A.device.queue.onSubmittedWorkDone(),X.removeBufferBytes(this.bloomMixFactorBuffer),X.removeBufferBytes(this.timeBuffer),X.removeBufferBytes(this.revealFactorBuffer),this.bloomMixFactorBuffer.destroy(),this.timeBuffer.destroy(),this.revealFactorBuffer.destroy()}set bloomEnabled(e){A.device.queue.writeBuffer(this.bloomMixFactorBuffer,0,new Float32Array([e?Gt.BLOOM_MIX_FACTOR:0]))}revealWithAnimation(e=500,t="quad_Out"){new us({durationMS:e,easeName:t,onUpdate:r=>{this.updateRevealFactor(r)}}).start()}updateRevealFactor(e){A.device.queue.writeBuffer(this.revealFactorBuffer,0,new Float32Array([e]))}constructor(e,t,r=!1){super(V.Blit,e,t);const n=J.createShaderModule(Yt),i=J.createShaderModule($p),o=[{format:"bgra8unorm"}],u=[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,buffer:{}},{binding:3,visibility:GPUShaderStage.FRAGMENT,buffer:{}},{binding:4,visibility:GPUShaderStage.FRAGMENT,buffer:{}}];if(this.texturesBindGroupLayout=A.device.createBindGroupLayout({label:"GBuffer Textures Bind Group",entries:u}),!Gt.renderPSO){const l={layout:A.device.createPipelineLayout({bindGroupLayouts:[this.texturesBindGroupLayout]}),vertex:{module:n,entryPoint:Tt},fragment:{module:i,entryPoint:Uc,targets:o},primitive:{topology:"triangle-list",cullMode:"back"}};Gt.renderPSO=J.createRenderPipeline(l)}this.bloomMixFactorBuffer=A.device.createBuffer({label:"Bloom Mix Factor GPU Buffer",size:1*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),X.addBufferBytes(this.bloomMixFactorBuffer),new Float32Array(this.bloomMixFactorBuffer.getMappedRange()).set([Gt.BLOOM_MIX_FACTOR]),this.bloomMixFactorBuffer.unmap(),this.timeBuffer=A.device.createBuffer({label:"Bloom Elapsed Time Buffer",size:1*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),X.addBufferBytes(this.timeBuffer),this.revealFactorBuffer=A.device.createBuffer({label:"Blit Loading Reveal Factor Buffer",size:1*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),X.addBufferBytes(this.revealFactorBuffer),new Float32Array(this.revealFactorBuffer.getMappedRange()).set([r?1:0]),this.revealFactorBuffer.unmap()}createRenderPassDescriptor(){return this.renderPassDescriptor?this.renderPassDescriptor:(this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({colorAttachments:[{view:null,loadOp:"load",storeOp:"store"}],label:"Blit Pass"}),this.renderPassDescriptor)}render(e,t,r){if(!this.inputTextureViews.length){r.length===1?(this.inputTextureViews.push(ge.dummyRGBA16FTexture.createView()),this.inputTextureViews.push(r[0].createView())):(this.inputTextureViews.push(r[0].createView()),this.inputTextureViews.push(r[1].createView()));const o=[{binding:0,resource:this.inputTextureViews[0]},{binding:1,resource:this.inputTextureViews[1]},{binding:2,resource:{buffer:this.bloomMixFactorBuffer}},{binding:3,resource:{buffer:this.timeBuffer}},{binding:4,resource:{buffer:this.revealFactorBuffer}}];this.textureBindGroup=A.device.createBindGroup({layout:this.texturesBindGroupLayout,entries:o})}A.device.queue.writeBuffer(this.timeBuffer,0,new Float32Array([A.elapsedTimeMs]));const n=this.createRenderPassDescriptor();n.colorAttachments[0].view=A.canvasContext.getCurrentTexture().createView();const i=e.beginRenderPass(n);return A.setActiveRenderPass(this.type,i),A.bindRenderPSO(Gt.renderPSO),i.setBindGroup(0,this.textureBindGroup),i.draw(6),i.end(),this.postRender(e),[]}};Gt.BLOOM_MIX_FACTOR=.035;let so=Gt;const kc="main",Xp=` + @group(0) @binding(0) var srcTexture: texture_2d; + @group(0) @binding(1) var outTexture: texture_storage_2d; + @group(0) @binding(2) var srcSampler: sampler; + + override WORKGROUP_SIZE_X: u32; + override WORKGROUP_SIZE_Y: u32; + + @compute @workgroup_size(WORKGROUP_SIZE_X, WORKGROUP_SIZE_Y) + fn ${kc}( + @builtin(global_invocation_id) tid : vec3u, + ) { + let outTexSize = textureDimensions(outTexture); + + if (any(tid.xy >= outTexSize)) { + return; + } + + let srcTexSize = vec2f(textureDimensions(srcTexture)); + + let texelSize = vec2f(1.0) / srcTexSize; + let x = texelSize.x; + let y = texelSize.y; + + let texCoords = vec2f((f32(tid.x) + 0.5) / f32(outTexSize.x), (f32(tid.y) + 0.5) / f32(outTexSize.y)); + + // Take 13 samples around current texel: + // a - b - c + // - j - k - + // d - e - f + // - l - m - + // g - h - i + // === ('e' is the current texel) === + let a = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x - 2 * x, texCoords.y + 2 * y), 0).rgb; + let b = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x, texCoords.y + 2 * y), 0).rgb; + let c = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x + 2 * x, texCoords.y + 2 * y), 0).rgb; + + let d = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x - 2 * x, texCoords.y), 0).rgb; + let e = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x, texCoords.y), 0).rgb; + let f = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x + 2 * x, texCoords.y), 0).rgb; + + let g = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x - 2 * x, texCoords.y - 2 * y), 0).rgb; + let h = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x, texCoords.y - 2 * y), 0).rgb; + let i = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x + 2 * x, texCoords.y - 2 * y), 0).rgb; + + let j = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x - x, texCoords.y + y), 0).rgb; + let k = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x + x, texCoords.y + y), 0).rgb; + let l = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x - x, texCoords.y - y), 0).rgb; + let m = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x + x, texCoords.y - y), 0).rgb; + + // Apply weighted distribution: + // 0.5 + 0.125 + 0.125 + 0.125 + 0.125 = 1 + // a,b,d,e * 0.125 + // b,c,e,f * 0.125 + // d,e,g,h * 0.125 + // e,f,h,i * 0.125 + // j,k,l,m * 0.5 + // This shows 5 square areas that are being sampled. But some of them overlap, + // so to have an energy preserving downsample we need to make some adjustments. + // The weights are the distributed, so that the sum of j,k,l,m (e.g.) + // contribute 0.5 to the final color output. The code below is written + // to effectively yield this sum. We get: + // 0.125*5 + 0.03125*4 + 0.0625*4 = 1 + var downsample = e * 0.125; + downsample += (a + c + g + i) * 0.03125; + downsample += (b + d + f + h) * 0.0625; + downsample += (j + k + l + m) * 0.125; + + textureStore(outTexture, tid.xy, vec4f(downsample, 1.0)); + // textureStore(outTexture, tid.xy, vec4f(texCoords, 0.0, 1.0)); + } +`,et=class et extends Se{constructor(e,t){super(V.BloomDownsample,e,t),this.mipLevelCount=It(e,t),this.outTextures.push(A.device.createTexture({label:"Bloom Downscale Texture",size:{width:e,height:t},usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.COPY_DST,format:"rgba16float",mipLevelCount:this.mipLevelCount})),X.addTextureBytes(this.outTextures[0]),this.sampler=Ke.createSampler({label:"Bloom Downscale Sampler",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",minFilter:"linear",magFilter:"linear"});const r=[{binding:0,texture:{},visibility:GPUShaderStage.COMPUTE},{binding:1,storageTexture:{format:"rgba16float"},visibility:GPUShaderStage.COMPUTE},{binding:2,sampler:{},visibility:GPUShaderStage.COMPUTE}];this.bindGroupLayout=A.device.createBindGroupLayout({label:"Bloom Downscale Bind Group Layout",entries:r}),et.computePSO||(et.computePSO=J.createComputePipeline({label:"Bloom Downscale Render PSO",layout:A.device.createPipelineLayout({label:"Bloom Downscale Render PSO Layout",bindGroupLayouts:[this.bindGroupLayout]}),compute:{entryPoint:kc,module:J.createShaderModule(Xp),constants:{WORKGROUP_SIZE_X:et.COMPUTE_WORKGROUP_SIZE_X,WORKGROUP_SIZE_Y:et.COMPUTE_WORKGROUP_SIZE_Y}}}))}render(e,t,r){e.copyTextureToTexture({texture:r[0],mipLevel:0},{texture:this.outTextures[0],mipLevel:0},{width:this.width,height:this.height});const n=[{binding:0,resource:null},{binding:1,resource:null},{binding:2,resource:this.sampler}],i=e.beginComputePass({label:"Bloom Downscale Compute Pass"});i.setPipeline(et.computePSO);for(let o=1;o; + @group(0) @binding(1) var srcSampler: sampler; + @group(0) @binding(2) var filterRadius: f32; + + @fragment + fn ${Nc}( + in: VertexOutput + ) -> @location(0) vec4f { + let srcSize = vec2f(textureDimensions(srcTexture)); + let aspect = srcSize.x / srcSize.y; + + let x = filterRadius; + let y = filterRadius * aspect; + + let texCoord = vec2f(in.uv.x, 1 - in.uv.y); + + let a = textureSample(srcTexture, srcSampler, vec2f(texCoord.x - x, texCoord.y + y)).rgb; + let b = textureSample(srcTexture, srcSampler, vec2f(texCoord.x, texCoord.y + y)).rgb; + let c = textureSample(srcTexture, srcSampler, vec2f(texCoord.x + x, texCoord.y + y)).rgb; + + let d = textureSample(srcTexture, srcSampler, vec2f(texCoord.x - x, texCoord.y)).rgb; + let e = textureSample(srcTexture, srcSampler, vec2f(texCoord.x, texCoord.y)).rgb; + let f = textureSample(srcTexture, srcSampler, vec2f(texCoord.x + x, texCoord.y)).rgb; + + let g = textureSample(srcTexture, srcSampler, vec2(texCoord.x - x, texCoord.y - y)).rgb; + let h = textureSample(srcTexture, srcSampler, vec2(texCoord.x, texCoord.y - y)).rgb; + let i = textureSample(srcTexture, srcSampler, vec2(texCoord.x + x, texCoord.y - y)).rgb; + + var upsample = e * 4.0; + upsample += (b + d + f + h) * 2.0; + upsample += (a + c + g + i); + upsample *= 1.0 / 16.0; + + return vec4f(upsample, 1.0); + } +`;class $r extends Se{async destroy(){super.destroy(),await A.device.queue.onSubmittedWorkDone(),X.removeBufferBytes(this.filterRadiusBuffer),this.filterRadiusBuffer.destroy()}set bloomFilterRadius(e){A.device.queue.writeBuffer(this.filterRadiusBuffer,0,new Float32Array([e]))}constructor(e,t){super(V.BloomUpsample,e,t),this.sampler=Ke.createSampler({label:"Bloom Downscale Sampler",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",minFilter:"linear",magFilter:"linear"}),this.filterRadiusBuffer=A.device.createBuffer({label:"Bloom Upscale Filter Radius GPU Buffer",size:1*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),X.addBufferBytes(this.filterRadiusBuffer),new Float32Array(this.filterRadiusBuffer.getMappedRange()).set([.0035]),this.filterRadiusBuffer.unmap();const r=[{binding:0,texture:{},visibility:GPUShaderStage.FRAGMENT},{binding:1,sampler:{},visibility:GPUShaderStage.FRAGMENT},{binding:2,buffer:{},visibility:GPUShaderStage.FRAGMENT}];this.bindGroupLayout=A.device.createBindGroupLayout({label:"Bloom Upscale Bind Group Layout",entries:r});const n=[{format:"rgba16float",blend:{color:{operation:"add",srcFactor:"one",dstFactor:"one"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one"}}}];$r.renderPSO||($r.renderPSO=J.createRenderPipeline({label:"Bloom Upscale Render PSO",layout:A.device.createPipelineLayout({label:"Bloom Upscale Render PSO Layout",bindGroupLayouts:[this.bindGroupLayout]}),vertex:{entryPoint:Tt,module:J.createShaderModule(Yt)},fragment:{entryPoint:Nc,module:J.createShaderModule(Yp),targets:n}}))}render(e,t,r){const n=[{binding:0,resource:null},{binding:1,resource:this.sampler},{binding:2,resource:{buffer:this.filterRadiusBuffer}}],i={colorAttachments:[{loadOp:"load",storeOp:"store",view:null}]};for(let o=Math.ceil(.5*It(r[0].width,r[0].height))-1;o>0;o--){i.label=`Bloom Upscale Mip Level ${o}`,i.colorAttachments[0].view=r[0].createView({baseMipLevel:o-1,mipLevelCount:1});const u=e.beginRenderPass(i);u.setPipeline($r.renderPSO),n[0].resource=r[0].createView({baseMipLevel:o,mipLevelCount:1});const l=A.device.createBindGroup({label:`Bloom Upscale Bind Group for Mip ${o}`,entries:n,layout:this.bindGroupLayout});u.setBindGroup(0,l),u.draw(3),u.end()}return this.postRender(e),r}}const Vc=s=>St` + @must_use + fn DistributionGGX(viewSpaceNormal: vec3f, H: vec3f, roughness: f32) -> f32 { + let a = roughness*roughness; + let a2 = a*a; + let NdotH = max(dot(viewSpaceNormal, H), 0.0); + let NdotH2 = NdotH*NdotH; + + let nom = a2; + var denom = (NdotH2 * (a2 - 1.0) + 1.0); + denom = PI * denom * denom + 0.0001; + + return nom / denom; +} + + @must_use + fn GeometrySchlickGGX(NdotV: f32, roughness: f32) -> f32 { + let r = (roughness + 1.0); + let k = (r * r) / 8; + + let nom = NdotV; + let denom = NdotV * (1.0 - k) + k + 0.0001; + return nom / denom; + } + + @must_use + fn GeometrySmith(viewSpaceNormal: vec3f, V: vec3f, L: vec3f, roughness: f32) -> f32 { + let NdotV = max(dot(viewSpaceNormal, V), 0.0); + let NdotL = max(dot(viewSpaceNormal, L), 0.0); + let ggx2 = GeometrySchlickGGX(NdotV, roughness); + let ggx1 = GeometrySchlickGGX(NdotL, roughness); + return ggx1 * ggx2; + } + + @must_use + fn FresnelSchlick(cosTheta: f32, F0: vec3f) -> vec3f { + return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0); + } + + @must_use + fn FresnelSchlickRoughness(cosTheta: f32, F0: vec3f, roughness: f32) -> vec3f { + return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0); + } + + @must_use + fn PBRLighting( + material: Material, + instanceId: u32, + viewSpacePos: vec3f, + viewSpaceNormal: vec3f, + V: vec3f, + shadow: f32, + opacity: f32, + #if ${s===V.PointLightsNonCulledLighting} + lightPosition: vec3f, + lightRadius: f32, + lightColor: vec3f, + lightIntensity: f32, + #elif ${s===V.DirectionalAmbientLighting} + diffuseIBLTexture: texture_cube, + specularIBLTexture: texture_cube, + bdrfLutTexture: texture_2d, + envTexSampler: sampler, + #endif + ) -> vec4f { + let albedo = material.albedo; + let F0 = mix(vec3f(0.04), albedo, material.metallic); + + var Lo = vec3f(0.0); + let albedoOverPi = albedo / PI; + + let roughness = material.roughness; + let roughnessSq = roughness * roughness; + let roughnessQuad = roughnessSq * roughnessSq; + + let metallic = material.metallic; + + #if ${s===V.DirectionalAmbientLighting} + let light = &lightsBuffer[instanceId]; + // let isPointLight = light.lightType == ${Nt.Point}; + let lightViewSpacePos = (camera.viewMatrix * vec4f(light.position, 0.0)).xyz; + + let lightColor = light.color; + let lightIntensity = light.intensity; + let L = normalize(lightViewSpacePos); + let attenuation = 1.0; + + // return vec4f(vec3f(shadow), 1.0) + + #elif ${s===V.PointLightsLighting} + let light = &lightsBuffer[instanceId]; + let lightColor = light.color; + let lightIntensity = light.intensity; + let lightViewSpacePos = (camera.viewMatrix * vec4f(light.position, 1.0)).xyz; + let dist = lightViewSpacePos.xyz - viewSpacePos.xyz; + let d = length(dist); + var attenuation = 1 - smoothstep(0.0, light.radius, d); + attenuation *= attenuation; + let L = normalize(dist); + #elif ${s===V.PointLightsNonCulledLighting} + let lightViewSpacePos = (camera.viewMatrix * vec4f(lightPosition, 1)).xyz; + let dist = lightViewSpacePos.xyz - viewSpacePos.xyz; + let d = length(dist); + var attenuation = 1 - smoothstep(0.0, lightRadius, d); + attenuation *= attenuation; + let L = normalize(dist); + #endif + + + let H = normalize(V + L); + + let radiance = lightColor * attenuation * lightIntensity; + + let NDF = DistributionGGX(viewSpaceNormal, H, roughnessQuad); + let G = GeometrySmith(viewSpaceNormal, V, L, roughness); + var F = FresnelSchlick(max(dot(H, V), 0.0), F0); + + let numerator = NDF * G * F; + // let denominator = 4.0 * (NdotV * NdotL, 0.0001); // + 0.0001 to prevent divide by zero + let denominator = 4.0 * max(dot(viewSpaceNormal, V), 0.0) * max(dot(viewSpaceNormal, L), 0.0) + 0.0001; // + 0.0001 to prevent divide by zero + + var specular = numerator / denominator; + + // kS is equal to Fresnel + var kS = F; + // for energy conservation, the diffuse and specular light can't + // be above 1.0 (unless the surface emits light); to preserve this + // relationship the diffuse component (kD) should equal 1.0 - kS. + var kD = vec3f(1.0 - kS); + // multiply kD by the inverse metalness such that only non-metals + // have diffuse lighting, or a linear blend if partly metal (pure metals + // have no diffuse light). + kD *= 1.0 - metallic; + + let NdotL = max(dot(viewSpaceNormal, L), 0.0); + + // add to outgoing radiance Lo + Lo += (kD * albedoOverPi + specular) * radiance * NdotL * shadow; // * light.opacity; // note that we already multiplied the BRDF by the Fresnel + + #if ${s===V.DirectionalAmbientLighting} + let worldSpaceNorm = (camera.inverseViewMatrix * vec4f(viewSpaceNormal, 0)).xyz; + let worldSpaceV = (camera.inverseViewMatrix * vec4f(V, 0)).xyz; + let irradiance = textureSampleLevel(diffuseIBLTexture, envTexSampler, worldSpaceNorm, 0).rgb; + kS = FresnelSchlickRoughness(max(dot(viewSpaceNormal, V), 0.0), F0, roughness); + kD = 1.0 - kS; + kD *= 1.0 - metallic; + // let ambientIBL = kD * irradiance; + // let ambientFactor = 0.2; + + let R = reflect(-worldSpaceV, worldSpaceNorm); + let MAX_REFLECTION_LOD = 8.0; + let prefilteredColor = vec3f( + textureSampleLevel( + specularIBLTexture, + envTexSampler, + R, + material.roughness * MAX_REFLECTION_LOD + ).rgb + ); + + let uv = vec2f(max(dot(worldSpaceNorm, worldSpaceV), 0.0), roughness); + let envBDRF = textureSample(bdrfLutTexture, envTexSampler, uv).rg; + specular = prefilteredColor * (F * envBDRF.x + envBDRF.y); + // specular = mix(specular, specular * 0.2, 1 - shadow); + + let diffuse = irradiance * albedo; + let ambient = (kD * diffuse + specular * metallic) * material.ambientOcclusion; + + // let ambient = vec3f(0.03) * albedo * material.ambientOcclusion; + + var color = ambient + Lo; + #else + var color = Lo; + #endif + + return vec4f(color, opacity); + } +`,Ge=class Ge extends Se{constructor(e,t,r){super(V.Shadow,t,r),this.sceneDirectionalLight=e,this.type=V.Shadow,this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({colorAttachments:[],depthStencilAttachment:{view:null,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"},label:"Shadow Render Pass Cascade #0"}),this.outTextures.push(A.device.createTexture({label:"Directional Shadow Depth Texture",format:"depth32float",size:{width:Ge.TEXTURE_SIZE,height:Ge.TEXTURE_SIZE,depthOrArrayLayers:Ge.TEXTURE_CASCADES_COUNT},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING})),X.addTextureBytes(this.outTextures[0]),this.shadowTextureCascade0=this.outTextures[0].createView({baseArrayLayer:0,arrayLayerCount:1,dimension:"2d"}),this.shadowTextureCascade1=this.outTextures[0].createView({baseArrayLayer:1,arrayLayerCount:1,dimension:"2d"});const n=kt(Y.Camera);this.shadowCameraCascade0BufferUniformValues=vt(n.structs.Camera),this.shadowCameraCascade1BufferUniformValues=vt(n.structs.Camera),this.shadowCameraCascade0GPUBuffer=A.device.createBuffer({label:"Shadow Camera GPU Buffer Cascade #0",size:this.shadowCameraCascade0BufferUniformValues.arrayBuffer.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),X.addBufferBytes(this.shadowCameraCascade0GPUBuffer),this.shadowCameraCascade1GPUBuffer=A.device.createBuffer({label:"Shadow Camera GPU Buffer Cascade #1",size:this.shadowCameraCascade1BufferUniformValues.arrayBuffer.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),X.addBufferBytes(this.shadowCameraCascade1GPUBuffer),this.shadowCameraCascade0BindGroup=A.device.createBindGroup({label:"Shadow Camera Bind Group Cascade #0",layout:J.defaultCameraBindGroupLayout,entries:[{binding:0,resource:{buffer:this.shadowCameraCascade0GPUBuffer}}]}),this.shadowCameraCascade1BindGroup=A.device.createBindGroup({label:"Shadow Camera Bind Group Cascade #1",layout:J.defaultCameraBindGroupLayout,entries:[{binding:0,resource:{buffer:this.shadowCameraCascade1GPUBuffer}}]});const i=kt(Y.ShadowCascade);this.shadowCascadeView=vt(i.structs.ShadowCascade),this.shadowCascadesBuffer=A.device.createBuffer({label:"Directional Shadow Cascade ProjView Matrices",size:Ge.TEXTURE_CASCADES_COUNT*this.shadowCascadeView.arrayBuffer.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),X.addBufferBytes(this.shadowCascadesBuffer)}set shadowMapSize(e){const t=this.outTextures[0];this.outTextures[0]=A.device.createTexture({label:"Directional Shadow Depth Texture",format:"depth32float",size:{width:e,height:e,depthOrArrayLayers:Ge.TEXTURE_CASCADES_COUNT},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),this.shadowTextureCascade0=this.outTextures[0].createView({baseArrayLayer:0,arrayLayerCount:1,dimension:"2d"}),this.shadowTextureCascade1=this.outTextures[0].createView({baseArrayLayer:1,arrayLayerCount:1,dimension:"2d"}),X.addTextureBytes(this.outTextures[0]),A.device.queue.onSubmittedWorkDone().then(()=>{X.removeTextureBytes(t),t.destroy()})}async destroy(){super.destroy(),await A.device.queue.onSubmittedWorkDone(),X.removeBufferBytes(this.shadowCascadesBuffer),X.removeBufferBytes(this.shadowCameraCascade0GPUBuffer),X.removeBufferBytes(this.shadowCameraCascade1GPUBuffer),this.shadowCascadesBuffer.destroy(),this.shadowCameraCascade0GPUBuffer.destroy(),this.shadowCameraCascade1GPUBuffer.destroy()}setCamera(e){return this.camera=e,this}getLightSpaceMatrix(){const e=this.camera.frustumCornersWorldSpace,t=F.create(0,0,0);for(let f=0;f{return St` + ${Y.VertexOutput} + ${Y.Light} + ${Y.Camera} + ${Y.Material} + ${Y.ShadowCascade} + ${Y.CommonHelpers} + ${Y.MathHelpers} + + ${Vc(s)} + ${` + + @must_use + fn ShadowLayerIdxCalculate( + worldPos: vec3f, + camera: Camera, + shadowCascades: array + ) -> i32 { + let fragPosViewSpace = camera.viewMatrix * vec4f(worldPos, 1.0); + let depthValue = abs(fragPosViewSpace.z); + + var layer: i32 = -1; + let cascadesCount: i32 = 2; + for (var i: i32 = 0; i < cascadesCount; i++) { + if (depthValue < shadowCascades[i].distance) { + layer = i; + break; + } + } + + if (layer == -1) { + layer = 1; + } + return layer; + } + + fn ShadowCalculate( + worldPos: vec3f, + N: vec3f, + lightPosition: vec3f, + camera: Camera, + shadowTextureWidth: f32, + shadowTextureHeight: f32, + shadowCascades: array, + shadowDepthTexture: texture_depth_2d_array, + shadowDepthSampler: sampler_comparison + ) -> f32 { + + let layer = ShadowLayerIdxCalculate( + worldPos, + camera, + shadowCascades + ); + let fragPosLightSpace = shadowCascades[layer].projViewMatrix * vec4f(worldPos, 1.0); + + // perform perspective divide + var projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w; + projCoords.x = projCoords.x * 0.5 + 0.5; + projCoords.y = projCoords.y * 0.5 + 0.5; + projCoords.y = 1 - projCoords.y; + let uv = projCoords.xy; + + var shadow = 0.0; + + let texelSize = 1 / vec2f(shadowTextureWidth, shadowTextureHeight); + + for (var y = -2; y <= 2; y++) { + for (var x = -2; x <= 2; x++) { + let uv = projCoords.xy + vec2f(f32(x), f32(y)) * texelSize; + let pcfDepth = textureSampleCompareLevel( + shadowDepthTexture, + shadowDepthSampler, + uv, + layer, + projCoords.z + ); + shadow += pcfDepth; + } + } + + shadow /= 16; + + return shadow; + } +`} + ${jr} + + struct LightSettings { + debugLights: f32, + debugShadowCascadeLayer: f32 + }; + + #if ${s===V.DirectionalAmbientLighting} + const SHADOW_MAP_SIZE: f32 = ${tn.TEXTURE_SIZE}; + #endif + + ${e=s,St` + @group(0) @binding(0) var normalTexture: texture_2d; + @group(0) @binding(1) var colorTexture: texture_2d; + @group(0) @binding(2) var depthTexture: texture_depth_2d; + @group(0) @binding(3) var aoTexture: texture_2d; + @group(0) @binding(4) var camera: Camera; + + #if ${e===V.PointLightsLighting||e===V.PointLightsStencilMask||e===V.DirectionalAmbientLighting} + @group(0) @binding(5) var lightsBuffer: array; + @group(0) @binding(6) var debugLightsInfo: LightSettings; + #endif + + #if ${e===V.PointLightsNonCulledLighting} + @group(1) @binding(0) var cameraCulledPointLight: Light; + #endif + + #if ${e===V.DirectionalAmbientLighting} + @group(1) @binding(0) var shadowCascades: array; + @group(1) @binding(1) var shadowMapSampler: sampler_comparison; + @group(1) @binding(2) var shadowDepthTexture: texture_depth_2d_array; + @group(1) @binding(3) var diffuseIBLTexture: texture_cube; + @group(1) @binding(4) var specularIBLTexture: texture_cube; + @group(1) @binding(5) var bdrfLutTexture: texture_2d; + @group(1) @binding(6) var envTexSampler: sampler; + @group(1) @binding(7) var ssaoMixFactor: f32; + #endif +`} + + @fragment + fn ${rn}( + in: VertexOutput + ) -> @location(0) vec4f { + let coord = in.position; + let pixelCoords = vec2i(floor(coord.xy)); + let encodedN = textureLoad(normalTexture, pixelCoords, 0).rg; + let metallic = textureLoad(normalTexture, pixelCoords, 0).b; + let roughness = textureLoad(normalTexture, pixelCoords, 0).a; + let viewSpaceNormal = decodeNormal(encodedN); + + let albedo = textureLoad(colorTexture, pixelCoords, 0).xyz; + let depth = textureLoad(depthTexture, pixelCoords, 0); + + let aoPixelCoords = vec2i(floor(coord.xy)); + let ao = textureLoad(aoTexture, aoPixelCoords, 0).r; + // return vec4f(ao, ao, ao, 1); + + // return vec4f(viewSpaceNormal, 1.0); + + + var material = Material(); + material.albedo = albedo; + material.roughness = roughness; + // return vec4f(vec3f(1 - metallic), 1); + material.metallic = metallic; + // material.ambientOcclusion = select(1.0, ao, pixelCoords.x > i32(textureDimensions(normalTexture).x / 2)); + + #if ${s===V.DirectionalAmbientLighting} + material.ambientOcclusion = mix(1.0, ao, ssaoMixFactor); + // return vec4f(ao, 0, 0, 1); + #endif + + let viewSpacePos = calcViewSpacePos(camera, coord.xy, depth); + + let V = normalize(-viewSpacePos); + + #if ${s===V.DirectionalAmbientLighting} + let worldSpacePos = calcWorldPos(camera, coord.xy, depth); + let shadowLayerIdx = ShadowLayerIdxCalculate(worldSpacePos, camera, shadowCascades); + let r = select(0.0, 1.0, shadowLayerIdx == 0); + let g = select(0.0, 1.0, shadowLayerIdx == 1); + let b = select(0.0, 1.0, shadowLayerIdx == 2); + if (debugLightsInfo.debugShadowCascadeLayer == 1) { + material.albedo = vec3f(r, g, b); + } + // TODO: Directional light is expected to be at index 0 + // Write a better mechanism for quering it + let lightPosition = (camera.viewMatrix * (vec4f(lightsBuffer[0].position, 0))).xyz; + // let shadow = 1.0; + let shadow = ShadowCalculate( + worldSpacePos, + viewSpaceNormal, + lightPosition, + camera, + SHADOW_MAP_SIZE, + SHADOW_MAP_SIZE, + shadowCascades, + shadowDepthTexture, + shadowMapSampler + ); + #else + let shadow = 1.0; + #endif + + let opacity = 1.0; + + var color = PBRLighting( + material, + in.instanceId, + viewSpacePos, + viewSpaceNormal, + V, + shadow, + opacity, + #if ${s===V.PointLightsNonCulledLighting} + cameraCulledPointLight.position, + cameraCulledPointLight.radius, + cameraCulledPointLight.color, + cameraCulledPointLight.intensity, + #elif ${s==V.DirectionalAmbientLighting} + diffuseIBLTexture, + specularIBLTexture, + bdrfLutTexture, + envTexSampler + #endif + ); + + #if ${s===V.PointLightsLighting} + let debugColor = vec4f(1.0, 0.0, 0.0, 1.0); + return mix(color, debugColor, debugLightsInfo.debugLights); + #else + return color; + #endif + } +`;var e},Bo=class Bo extends Se{constructor(e,t,r){super(e,t,r),this.gbufferCommonBindGroupLayoutEntries=[],this.gbufferTexturesBindGroupEntries=[],this._debugLightsMask=!1,this._debugShadowCascadeLayer=!1,this.gbufferCommonBindGroupLayoutEntries.push({binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{}}),this.gbufferCommonBindGroupLayoutEntries.push({binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}}),this.gbufferCommonBindGroupLayoutEntries.push({binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth"}}),this.gbufferCommonBindGroupLayoutEntries.push({binding:3,visibility:GPUShaderStage.FRAGMENT,texture:{}}),this.gbufferCommonBindGroupLayoutEntries.push({binding:4,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}),e!==V.PointLightsLighting&&e!==V.DirectionalAmbientLighting&&e!==V.PointLightsStencilMask||(this.gbufferCommonBindGroupLayoutEntries.push({binding:5,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}),this.gbufferCommonBindGroupLayoutEntries.push({binding:6,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}})),this.gbufferCommonBindGroupLayout=A.device.createBindGroupLayout({label:"GBuffer Textures Bind Group",entries:this.gbufferCommonBindGroupLayoutEntries}),this.debugLightsBuffer=A.device.createBuffer({label:"Debug Lights GPUBuffer",size:4*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),X.addBufferBytes(this.debugLightsBuffer),new Float32Array(this.debugLightsBuffer.getMappedRange()).set(new Float32Array([0,0])),this.debugLightsBuffer.unmap(),this.gbufferTexturesBindGroupEntries.push({binding:0,resource:null}),this.gbufferTexturesBindGroupEntries.push({binding:1,resource:null}),this.gbufferTexturesBindGroupEntries.push({binding:2,resource:null}),this.gbufferTexturesBindGroupEntries.push({binding:3,resource:null}),this.gbufferTexturesBindGroupEntries.push({binding:4,resource:{buffer:null}}),e!==V.DirectionalAmbientLighting&&e!==V.PointLightsLighting&&e!==V.PointLightsStencilMask||(this.gbufferTexturesBindGroupEntries.push({binding:5,resource:{buffer:null}}),this.gbufferTexturesBindGroupEntries.push({binding:6,resource:{buffer:this.debugLightsBuffer}}))}set debugLightsMask(e){this._debugLightsMask=e,this.updateLightSettingsBuffer()}set debugShadowCascadeLayer(e){this._debugShadowCascadeLayer=e,this.updateLightSettingsBuffer()}updateLightSettingsBuffer(){A.device.queue.writeBuffer(this.debugLightsBuffer,0,new Float32Array([this._debugLightsMask?1:0,this._debugShadowCascadeLayer?1:0]))}updateGbufferBindGroupEntryAt(e,t){return this.gbufferTexturesBindGroupEntries[e].resource=t,this}recreateGBufferTexturesBindGroup(){this.gbufferTexturesBindGroup=A.device.createBindGroup({label:"G-Buffer Textures Input Bind Group",layout:this.gbufferCommonBindGroupLayout,entries:this.gbufferTexturesBindGroupEntries})}};Bo.RENDER_TARGETS=[{format:"rgba16float",blend:{color:{srcFactor:"one",dstFactor:"one",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one",operation:"add"}}}];let xr=Bo;class _r extends xr{constructor(e,t,r){super(V.DirectionalAmbientLighting,t,r),this.shadowCascadesBuffer=e,this.dirLightShadowBindGroupEntries=[],this.shadowSampler=Ke.createSampler({minFilter:"linear",magFilter:"linear",mipmapFilter:"linear",compare:"less"}),this.envSampler=Ke.createSampler({minFilter:"linear",magFilter:"linear",mipmapFilter:"linear"}),this.ssaoMixBuffer=A.device.createBuffer({label:"Ambient SSAO Mix Factor Buffer",usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,size:1*Float32Array.BYTES_PER_ELEMENT,mappedAtCreation:!0}),X.addBufferBytes(this.ssaoMixBuffer),new Float32Array(this.ssaoMixBuffer.getMappedRange()).set([1]),this.ssaoMixBuffer.unmap();const n=[{binding:0,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"comparison"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:3,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"cube"}},{binding:4,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"cube"}},{binding:5,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"2d"}},{binding:6,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:7,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}];this.dirLightShadowBindGroupLayout=A.device.createBindGroupLayout({label:"Direcional Light Shadow Bind Group Layout",entries:n});const i=A.device.createPipelineLayout({label:"Dir Light PSO Layout",bindGroupLayouts:[this.gbufferCommonBindGroupLayout,this.dirLightShadowBindGroupLayout]});if(this.dirLightShadowBindGroupEntries=[{binding:0,resource:{buffer:this.shadowCascadesBuffer}},{binding:1,resource:this.shadowSampler},{binding:2,resource:ge.dummyTexture.createView({})},{binding:3,resource:ge.dummyCubeTexture.createView({dimension:"cube"})},{binding:4,resource:ge.dummyCubeTexture.createView({dimension:"cube"})},{binding:5,resource:ge.dummyTexture.createView({})},{binding:6,resource:this.envSampler},{binding:7,resource:{buffer:this.ssaoMixBuffer}}],!_r.renderPSO){const o={label:"Directional Light Render PSO",layout:i,vertex:{module:J.createShaderModule(Yt,"Fullscreen Vertex Shader Module"),entryPoint:Tt},fragment:{module:J.createShaderModule(io(V.DirectionalAmbientLighting),"Directional Light Pass Shader Module"),entryPoint:rn,targets:_r.RENDER_TARGETS},depthStencil:{format:A.depthStencilFormat,depthWriteEnabled:!1}};_r.renderPSO=J.createRenderPipeline(o)}this.outTextures.push(A.device.createTexture({dimension:"2d",format:"rgba16float",mipLevelCount:1,sampleCount:1,size:{width:t,height:r,depthOrArrayLayers:1},usage:GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,label:"GBuffer Result Texture"})),X.addTextureBytes(this.outTextures[0]),this.outTextureView=this.outTextures[0].createView()}set ssaoMixFactor(e){A.device.queue.writeBuffer(this.ssaoMixBuffer,0,new Float32Array([e]))}setDiffuseIBLTexture(e){return this.dirLightShadowBindGroupEntries[3].resource=e.createView({dimension:"cube"}),this.recreateDirLightShadowBindGroup(),this}setSpecularIBLTexture(e){return this.dirLightShadowBindGroupEntries[4].resource=e.createView({dimension:"cube"}),this.recreateDirLightShadowBindGroup(),this}setBDRFLutTexture(e){return this.dirLightShadowBindGroupEntries[5].resource=e.createView({dimension:"2d"}),this.recreateDirLightShadowBindGroup(),this}createRenderPassDescriptor(){if(this.renderPassDescriptor)return this.renderPassDescriptor;const e=[{view:this.outTextureView,loadOp:"clear",clearValue:[0,0,0,1],storeOp:"store"}];return this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({label:"Directional + Ambient Render Pass",colorAttachments:e,depthStencilAttachment:{depthReadOnly:!0,stencilReadOnly:!1,view:this.inputTextureViews[3],stencilLoadOp:"load",stencilStoreOp:"store"}}),this.renderPassDescriptor}recreateDirLightShadowBindGroup(){this.dirLightShadowBindGroup=A.device.createBindGroup({label:"Directional Ambient LightingSystem G-Buffer Directional Shadow Input Bind Group",layout:this.dirLightShadowBindGroupLayout,entries:this.dirLightShadowBindGroupEntries})}render(e,t,r){if(!this.inputTextureViews.length){this.inputTextureViews.push(r[0].createView()),this.inputTextureViews.push(r[1].createView()),this.inputTextureViews.push(r[2].createView({aspect:"depth-only"})),this.inputTextureViews.push(r[2].createView({aspect:"all"})),this.inputTextureViews.push(r[3].createView({dimension:"2d-array"}));let i=r[4];i||(i=ge.dummyR16FTexture),this.inputTextureViews.push(i.createView()),this.updateGbufferBindGroupEntryAt(0,this.inputTextureViews[0]).updateGbufferBindGroupEntryAt(1,this.inputTextureViews[1]).updateGbufferBindGroupEntryAt(2,this.inputTextureViews[2]).updateGbufferBindGroupEntryAt(3,this.inputTextureViews[5]).updateGbufferBindGroupEntryAt(4,{buffer:this.camera.gpuBuffer}).updateGbufferBindGroupEntryAt(5,{buffer:t.lightingManager.gpuBuffer}).recreateGBufferTexturesBindGroup(),this.dirLightShadowBindGroupEntries[2].resource=this.inputTextureViews[4],this.recreateDirLightShadowBindGroup()}const n=e.beginRenderPass(this.createRenderPassDescriptor());return A.setActiveRenderPass(this.type,n),A.ENABLE_DEBUG_GROUPS&&n.pushDebugGroup("Begin Directional + Ambient LightingSystem"),A.bindRenderPSO(_r.renderPSO),n.setBindGroup(0,this.gbufferTexturesBindGroup),n.setBindGroup(1,this.dirLightShadowBindGroup),n.draw(3),A.ENABLE_DEBUG_GROUPS&&n.popDebugGroup(),n.end(),this.postRender(e),this.outTextures}}class Wp extends Se{constructor(e,t){super(V.Deferred,e,t),this.outTextures.push(A.device.createTexture({dimension:"2d",format:"rgba16float",mipLevelCount:1,sampleCount:1,size:{width:e,height:t,depthOrArrayLayers:1},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,label:"Normal + Metallic + Roughness + GBuffer Texture"})),this.outTextures.push(A.device.createTexture({dimension:"2d",format:"bgra8unorm",mipLevelCount:1,sampleCount:1,size:{width:e,height:t,depthOrArrayLayers:1},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,label:"Color + Reflectance GBuffer Texture"})),this.outTextures.push(A.device.createTexture({dimension:"2d",format:"rg16float",mipLevelCount:1,sampleCount:1,size:{width:e,height:t,depthOrArrayLayers:1},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,label:"Velocity GBuffer Texture"})),this.outTextures.push(A.device.createTexture({dimension:"2d",format:A.depthStencilFormat,mipLevelCount:1,sampleCount:1,size:{width:e,height:t,depthOrArrayLayers:1},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,label:"Depth + Stencil GBuffer Texture"}));for(const r of this.outTextures)X.addTextureBytes(r)}createRenderPassDescriptor(){if(this.renderPassDescriptor)return this.renderPassDescriptor;const e=[{view:this.outTextures[ft.NormalMetallicRoughness].createView(),loadOp:"clear",clearValue:[0,0,0,0],storeOp:"store"},{view:this.outTextures[ft.ColorReflectance].createView(),loadOp:"clear",clearValue:[0,0,0,0],storeOp:"store"},{view:this.outTextures[ft.Velocity].createView(),loadOp:"clear",clearValue:[0,0,0,0],storeOp:"store"}];return this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({colorAttachments:e,depthStencilAttachment:{view:this.outTextures[3].createView(),depthLoadOp:"clear",depthStoreOp:"store",depthClearValue:1,stencilLoadOp:"clear",stencilStoreOp:"store",stencilClearValue:0},label:"GBuffer Render Pass"}),this.renderPassDescriptor}render(e,t,r){const n=this.createRenderPassDescriptor(),i=e.beginRenderPass(n);return A.setActiveRenderPass(this.type,i),A.ENABLE_DEBUG_GROUPS&&i.pushDebugGroup("Render G-Buffer"),i.setBindGroup(ce.CameraPlusOptionalLights,this.cameraBindGroup),i.setStencilReference(128),t.renderOpaqueNodes(i,this.camera),A.ENABLE_DEBUG_GROUPS&&i.popDebugGroup(),i.end(),this.postRender(e),this.outTextures}}const Hc="copyDepth",qp=` + + @group(0) @binding(0) var sourceDepth: texture_depth_2d; + @group(0) @binding(1) var destDepth: texture_storage_2d; + + override WORKGROUP_SIZE_X: u32; + override WORKGROUP_SIZE_Y: u32; + + @compute @workgroup_size(WORKGROUP_SIZE_X, WORKGROUP_SIZE_Y) + fn ${Hc}( + @builtin(global_invocation_id) pos : vec3u + ) { + let texSize = textureDimensions(sourceDepth); + + if (any(pos.xy > texSize)) { + return; + } + + let src = textureLoad(sourceDepth, pos.xy, 0); + textureStore(destDepth, pos.xy, vec4f(src)); + } + +`,tt=class tt extends Se{constructor(e,t){super(V.CopyDepthForHiZ,e,t);const r=[{binding:0,texture:{sampleType:"depth"},visibility:GPUShaderStage.COMPUTE},{binding:1,storageTexture:{access:"write-only",format:"r32float",viewDimension:"2d"},visibility:GPUShaderStage.COMPUTE}];this.bindGroupLayout=A.device.createBindGroupLayout({label:"Hi-Z Copy Depth Bind Group Layout",entries:r}),tt.computePSO||(tt.computePSO=J.createComputePipeline({label:"Hi-Z Copy Depth Compute PSO",layout:A.device.createPipelineLayout({label:"Hi-Z Copy Depth Compute PSO Layout",bindGroupLayouts:[this.bindGroupLayout]}),compute:{entryPoint:Hc,module:J.createShaderModule(qp,"Hi-Z Depth Copy Compute Shader Module"),constants:{WORKGROUP_SIZE_X:tt.COMPUTE_WORKGROUP_SIZE_X,WORKGROUP_SIZE_Y:tt.COMPUTE_WORKGROUP_SIZE_Y}}})),this.outTextures.push(A.device.createTexture({label:"Hi-Z Depth Texture",size:{width:e,height:t},usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING,format:"r32float",mipLevelCount:It(e,t)})),X.addTextureBytes(this.outTextures[0])}createComputePassDescriptor(){return this.computePassDescriptor||(this.computePassDescriptor={label:"Copy Hi-Z Depth Compute Pass"}),this.computePassDescriptor}render(e,t,r){if(!this.inputTextureViews.length){this.inputTextureViews.push(r[0].createView({aspect:"depth-only"}));const u=[{binding:0,resource:this.inputTextureViews[0]},{binding:1,resource:this.outTextures[0].createView({baseMipLevel:0,mipLevelCount:1})}];this.bindGroup=A.device.createBindGroup({label:"Hi-Z Depth Copy Bind Group",layout:this.bindGroupLayout,entries:u})}const n=e.beginComputePass(this.createComputePassDescriptor());n.setPipeline(tt.computePSO),n.setBindGroup(0,this.bindGroup);const i=Math.ceil(this.outTextures[0].width/tt.COMPUTE_WORKGROUP_SIZE_X),o=Math.ceil(this.outTextures[0].height/tt.COMPUTE_WORKGROUP_SIZE_Y);return n.dispatchWorkgroups(i,o,1),n.end(),this.postRender(e),this.outTextures}};tt.COMPUTE_WORKGROUP_SIZE_X=8,tt.COMPUTE_WORKGROUP_SIZE_Y=8;let oo=tt;const Jc="computeHiZMips",Qp=` + @group(0) @binding(0) var prevMipLevel: texture_2d; + @group(0) @binding(1) var nextMipLevel: texture_storage_2d; + + override WORKGROUP_SIZE_X: u32; + override WORKGROUP_SIZE_Y: u32; + + @compute @workgroup_size(WORKGROUP_SIZE_X, WORKGROUP_SIZE_Y) + fn ${Jc}(@builtin(global_invocation_id) pos : vec3u) { + let texSize = textureDimensions(prevMipLevel); + if (any(pos.xy > texSize)) { + return; + } + + let depthDim = vec2f(textureDimensions(prevMipLevel).xy); + let outDepthDim = vec2f(textureDimensions(nextMipLevel).xy); + + let ratio = depthDim / outDepthDim; + + let vReadCoord = vec2u(pos.x << 1, pos.y << 1); + let vWriteCoord = pos.xy; + + let depthSamples = vec4f( + textureLoad(prevMipLevel, vReadCoord, 0).r, + textureLoad(prevMipLevel, vReadCoord + vec2u(1, 0), 0).r, + textureLoad(prevMipLevel, vReadCoord + vec2u(0, 1), 0).r, + textureLoad(prevMipLevel, vReadCoord + vec2u(1, 1), 0).r + ); + + var minDepth = min( + depthSamples.x, + min( + depthSamples.y, + min(depthSamples.z, depthSamples.w) + ) + ); + + let needExtraSampleX = ratio.x > 2.01; + let needExtraSampleY = ratio.y > 2.01; + + minDepth = select( + minDepth, + min( + minDepth, + min( + textureLoad(prevMipLevel, vReadCoord + vec2u(2, 0), 0).r, + textureLoad(prevMipLevel, vReadCoord + vec2u(2, 1), 0).r + ) + ), + needExtraSampleX + ); + minDepth = select( + minDepth, + min( + minDepth, + min( + textureLoad(prevMipLevel, vReadCoord + vec2u(0, 2), 0).r, + textureLoad(prevMipLevel, vReadCoord + vec2u(1, 2), 0).r + ) + ), + needExtraSampleY + ); + minDepth = select( + minDepth, + min( + minDepth, + textureLoad(prevMipLevel, vReadCoord + vec2u(2, 2), 0).r + ), + needExtraSampleX && needExtraSampleY + ); + + textureStore(nextMipLevel, pos.xy, vec4f(minDepth)); + + } +`,Le=class Le extends Se{constructor(e,t){super(V.HiZ,e,t),this.mipTexSizes=[],this.mipTexViews=[];const r=[{binding:0,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"unfilterable-float"}},{binding:1,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"r32float",viewDimension:"2d"}}];this.bindGroupLayout=A.device.createBindGroupLayout({label:"Hi-Z Bind Group Layout",entries:r}),Le.computePSO||(Le.computePSO=J.createComputePipeline({label:"Hi-Z Compute PSO",layout:A.device.createPipelineLayout({label:"Hi-Z Compute PSO Layout",bindGroupLayouts:[this.bindGroupLayout]}),compute:{entryPoint:Jc,module:J.createShaderModule(Qp,"Compute Hi-Z Shader Module"),constants:{WORKGROUP_SIZE_X:Le.COMPUTE_WORKGROUP_SIZE_X,WORKGROUP_SIZE_Y:Le.COMPUTE_WORKGROUP_SIZE_Y}}}))}createComputePassDescriptor(){return this.computePassDescriptor||(this.computePassDescriptor={label:"Hi-Z Depth Mip Compute Pass"}),this.computePassDescriptor}render(e,t,r){const n=r[0].mipLevelCount,i=r[0].width,o=r[0].height;if(!this.mipTexSizes.length){this.mipTexSizes.push(Ee.create(i,o));for(let y=1;ySt` + + ${Y.VertexInput} + ${Y.VertexOutput} + ${Y.Camera} + ${Y.Light} + + #if ${s===V.PointLightsStencilMask} + @group(0) @binding(0) var camera: Camera; + @group(0) @binding(1) var lightsBuffer: array; + #else + @group(0) @binding(0) var normalTexture: texture_2d; + @group(0) @binding(1) var colorTexture: texture_2d; + @group(0) @binding(2) var depthTexture: texture_depth_2d; + @group(0) @binding(3) var aoTexture: texture_2d; + @group(0) @binding(4) var camera: Camera; + #endif + + #if ${s===V.PointLightsLighting||s===V.DirectionalAmbientLighting} + @group(0) @binding(5) var lightsBuffer: array; + @group(0) @binding(6) var debugLights: f32; + #endif + + #if ${s===V.PointLightsNonCulledLighting} + + @group(1) @binding(0) var cameraCulledPointLight: Light; + + #endif + + @vertex + fn ${sn}( + @builtin(instance_index) instanceId: u32, + in: VertexInput + ) -> VertexOutput { + #if ${s===V.PointLightsNonCulledLighting} + let light = cameraCulledPointLight; + let trueInstanceId = 0u; + #else + let trueInstanceId = instanceId; + let light = lightsBuffer[trueInstanceId]; + #endif + + var position = in.position; + position *= vec4f(vec3f(light.radius), 1.0); + position += vec4f(light.position, 0.0); + let pos = camera.projectionViewMatrix * position; + + var out: VertexOutput; + out.position = pos; + out.instanceId = trueInstanceId; + return out; + } +`;class Xr extends xr{setCamera(e){return this.camera=e,this.lightsMaskBindGroupEntries[0].resource={buffer:e.gpuBuffer},this}setLightsBuffer(e){return this.lightsMaskBindGroupEntries[1].resource={buffer:e},this}updateLightsMaskBindGroup(){return this.lightsMaskBindGroup=A.device.createBindGroup({layout:this.lightsMaskBindGroupLayout,entries:this.lightsMaskBindGroupEntries}),this}constructor(e,t){super(V.PointLightsStencilMask,e,t),this.lightsMaskBindGroupEntries=[{binding:0,resource:null},{binding:1,resource:null}];const r=[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}];if(this.lightsMaskBindGroupLayout=A.device.createBindGroupLayout({label:"Light Masking Bind Group",entries:r}),!Xr.renderPSO){const n={label:"Point Light Mask PSO",layout:A.device.createPipelineLayout({label:"Point Lights Mask Render PSO Layout",bindGroupLayouts:[this.lightsMaskBindGroupLayout]}),vertex:{module:J.createShaderModule(uo(V.PointLightsStencilMask),"Point Light Mask Pass Vertex Shader"),entryPoint:sn,buffers:Be.defaultLayout,constants:{}},depthStencil:{format:A.depthStencilFormat,depthWriteEnabled:!1,depthCompare:"less-equal",stencilReadMask:0,stencilWriteMask:255,stencilBack:{compare:"always",depthFailOp:"increment-wrap",failOp:"keep",passOp:"keep"},stencilFront:{compare:"always",depthFailOp:"decrement-wrap",failOp:"keep",passOp:"keep"}},primitive:{cullMode:"none"}};Xr.renderPSO=J.createRenderPipeline(n)}}createRenderPassDescriptor(){return this.renderPassDescriptor||(this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({label:"Point Lights Mask Stencil Pass",colorAttachments:[],depthStencilAttachment:{view:this.inputTextureViews[0],depthLoadOp:"load",depthStoreOp:"store",stencilLoadOp:"clear",stencilStoreOp:"store",stencilClearValue:0}})),this.renderPassDescriptor}render(e,t,r){this.inputTextureViews.length||this.inputTextureViews.push(r[0].createView());const n=e.beginRenderPass(this.createRenderPassDescriptor());return A.setActiveRenderPass(this.type,n),A.ENABLE_DEBUG_GROUPS&&n.pushDebugGroup("Point Lights Stencil Mask"),A.bindRenderPSO(Xr.renderPSO),n.setStencilReference(128),n.setBindGroup(0,this.lightsMaskBindGroup),n.setVertexBuffer(0,lt.pointLightSphereGeometry.vertexBuffers[0]),n.setIndexBuffer(lt.pointLightSphereGeometry.indexBuffer,Ae.INDEX_FORMAT),n.drawIndexed(lt.pointLightSphereGeometry.indexCount,t.lightingManager.pointLightsCount,0,0,1),A.ENABLE_DEBUG_GROUPS&&n.popDebugGroup(),n.end(),this.postRender(e),[r[0]]}}const Oe=class Oe extends xr{constructor(e,t){if(super(V.PointLightsNonCulledLighting,e,t),!Oe.frontFaceCullRenderPSO||!Oe.backFaceCullRenderPSO){const r=A.device.createPipelineLayout({label:"Render Non-Instanced Non-Culled Point Lights PSO Layout",bindGroupLayouts:[this.gbufferCommonBindGroupLayout,gt.bindGroupLayout]}),n={label:Oe.FRONT_FACE_RENDER_PSO_LABEL,layout:r,vertex:{module:J.createShaderModule(uo(V.PointLightsNonCulledLighting),"Non-Instanced Non-Culled Point Lights Vertex Shader"),entryPoint:sn,buffers:Be.defaultLayout},fragment:{module:J.createShaderModule(io(V.PointLightsNonCulledLighting)),entryPoint:rn,targets:Oe.RENDER_TARGETS},depthStencil:{format:A.depthStencilFormat,depthWriteEnabled:!1},primitive:{cullMode:"back"}};Oe.frontFaceCullRenderPSO=J.createRenderPipeline(n),n.label=Oe.BACK_FACE_RENDER_PSO_LABEL,n.primitive.cullMode="front",Oe.backFaceCullRenderPSO=J.createRenderPipeline(n)}}createRenderPassDescriptor(){if(this.renderPassDescriptor)return this.renderPassDescriptor;const e=[{view:this.inputTextureViews[4],loadOp:"load",storeOp:"store"}];return this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({label:"Non-Instanced Non-Culled Point Lights Render Pass",colorAttachments:e,depthStencilAttachment:{depthReadOnly:!0,stencilReadOnly:!0,view:this.inputTextureViews[2]}}),this.renderPassDescriptor}render(e,t,r){if(!this.inputTextureViews.length){this.inputTextureViews.push(r[0].createView()),this.inputTextureViews.push(r[1].createView()),this.inputTextureViews.push(r[2].createView({aspect:"all"})),this.inputTextureViews.push(r[2].createView({aspect:"depth-only"})),this.inputTextureViews.push(r[3].createView());let y=r[4];y||(y=ge.dummyR16FTexture),this.inputTextureViews.push(y.createView()),this.updateGbufferBindGroupEntryAt(0,this.inputTextureViews[0]).updateGbufferBindGroupEntryAt(1,this.inputTextureViews[1]).updateGbufferBindGroupEntryAt(2,this.inputTextureViews[3]).updateGbufferBindGroupEntryAt(3,this.inputTextureViews[5]).updateGbufferBindGroupEntryAt(4,{buffer:this.camera.gpuBuffer}).recreateGBufferTexturesBindGroup()}const n=e.beginRenderPass(this.createRenderPassDescriptor()),i=lt.pointLightSphereGeometry.indexBuffer,o=lt.pointLightSphereGeometry.vertexBuffers[0],u=lt.pointLightSphereGeometry.indexCount;n.setIndexBuffer(i,Ae.INDEX_FORMAT),n.setVertexBuffer(0,o),n.setBindGroup(0,this.gbufferTexturesBindGroup);let l=!1,m=!1;for(const y of t.lightingManager.cameraFaceCulledPointLights)F.dist(y.position,this.camera.position)>y.radius+.1?(l||n.setPipeline(Oe.frontFaceCullRenderPSO),l=!0,m=!1):(m||n.setPipeline(Oe.backFaceCullRenderPSO),l=!1,m=!0),n.setBindGroup(1,y.bindGroup),n.drawIndexed(u);return n.end(),this.postRender(e),[r[3]]}};Oe.FRONT_FACE_RENDER_PSO_LABEL="Render Non-Instanced Non-Culled Point Lights Front Face PSO Descriptor",Oe.BACK_FACE_RENDER_PSO_LABEL="Render Non-Instanced Non-Culled Point Lights Back Face PSO Descriptor";let co=Oe;class Br extends xr{constructor(e,t){super(V.PointLightsLighting,e,t);const r=A.device.createPipelineLayout({label:"Render Lights PSO Layout",bindGroupLayouts:[this.gbufferCommonBindGroupLayout]}),n={compare:"less",failOp:"keep",depthFailOp:"keep",passOp:"keep"};if(!Br.renderPSO){const i={label:"Point Light Render PSO",layout:r,vertex:{module:J.createShaderModule(uo(V.PointLightsLighting),"Point Light Render Pass Vertex Shader"),entryPoint:sn,buffers:Be.defaultLayout,constants:{}},fragment:{module:J.createShaderModule(io(V.PointLightsLighting),"Point Light Render Pass Fragment Shader"),entryPoint:rn,targets:Br.RENDER_TARGETS},depthStencil:{format:A.depthStencilFormat,depthWriteEnabled:!1,depthCompare:"less-equal",stencilReadMask:255,stencilWriteMask:0,stencilBack:n,stencilFront:n},primitive:{cullMode:"back"}};Br.renderPSO=J.createRenderPipeline(i)}}createRenderPassDescriptor(){if(this.renderPassDescriptor)return this.renderPassDescriptor;const e=[{view:this.inputTextureViews[4],loadOp:"load",storeOp:"store"}];return this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({label:"Point Lights Render Pass",colorAttachments:e,depthStencilAttachment:{depthReadOnly:!0,stencilReadOnly:!1,view:this.inputTextureViews[2],stencilLoadOp:"load",stencilStoreOp:"store"}}),this.renderPassDescriptor}render(e,t,r){if(!this.inputTextureViews.length){this.inputTextureViews.push(r[0].createView()),this.inputTextureViews.push(r[1].createView()),this.inputTextureViews.push(r[2].createView({aspect:"all"})),this.inputTextureViews.push(r[2].createView({aspect:"depth-only"})),this.inputTextureViews.push(r[3].createView());let i=r[4];i||(i=ge.dummyR16FTexture),this.inputTextureViews.push(i.createView()),this.updateGbufferBindGroupEntryAt(0,this.inputTextureViews[0]).updateGbufferBindGroupEntryAt(1,this.inputTextureViews[1]).updateGbufferBindGroupEntryAt(2,this.inputTextureViews[3]).updateGbufferBindGroupEntryAt(3,this.inputTextureViews[5]).updateGbufferBindGroupEntryAt(4,{buffer:this.camera.gpuBuffer}).updateGbufferBindGroupEntryAt(5,{buffer:t.lightingManager.gpuBuffer}).recreateGBufferTexturesBindGroup()}const n=e.beginRenderPass(this.createRenderPassDescriptor());return A.setActiveRenderPass(this.type,n),A.ENABLE_DEBUG_GROUPS&&n.pushDebugGroup("Begin Point LightingSystem"),A.bindRenderPSO(Br.renderPSO),n.setBindGroup(0,this.gbufferTexturesBindGroup),n.setVertexBuffer(0,lt.pointLightSphereGeometry.vertexBuffers[0]),n.setIndexBuffer(lt.pointLightSphereGeometry.indexBuffer,Ae.INDEX_FORMAT),n.drawIndexed(lt.pointLightSphereGeometry.indexCount,t.lightingManager.pointLightsCount,0,0,1),A.ENABLE_DEBUG_GROUPS&&n.popDebugGroup(),n.end(),this.postRender(e),[r[3]]}}const zc="main",rt=class rt extends Se{constructor(e,t){super(V.Reflection,e,t),this._maxIterations=150,this._debugMissedIntersections=!1,this._isHiZ=!0;const r=[{binding:0,visibility:GPUShaderStage.COMPUTE,texture:{}},{binding:1,visibility:GPUShaderStage.COMPUTE,texture:{}},{binding:2,visibility:GPUShaderStage.COMPUTE,texture:{}},{binding:3,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"unfilterable-float"}},{binding:4,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"rgba16float",viewDimension:"2d"}},{binding:5,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:6,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}}];var n;this.bindGroupLayout=A.device.createBindGroupLayout({label:"Reflection Pass ComputePSO Bind Group Layout",entries:r}),rt.computePSO||(rt.computePSO=J.createComputePipeline({label:"Reflection Pass Compute PSO",layout:A.device.createPipelineLayout({label:"Reflection PASS ComputePSO Layout",bindGroupLayouts:[this.bindGroupLayout]}),compute:{entryPoint:zc,module:J.createShaderModule((n="rgba16float",` + ${Y.Camera} + + struct SSRSettings { + isHiZ: i32, + maxIterations: i32, + debugMissedIntersections: i32 + }; + + @group(0) @binding(0) var sceneTexture: texture_2d; + @group(0) @binding(1) var normalMetallicRoughnessTexture: texture_2d; + @group(0) @binding(2) var albedoReflectanceTexture: texture_2d; + @group(0) @binding(3) var depthTexture: texture_2d; + @group(0) @binding(4) var outTexture: texture_storage_2d<${n}, write>; + @group(0) @binding(5) var camera: Camera; + @group(0) @binding(6) var settings: SSRSettings; + + override WORKGROUP_SIZE_X: u32; + override WORKGROUP_SIZE_Y: u32; + + ${jr} + + const MAX_THICKNESS = 0.001; + + fn ComputePosAndReflection( + tid: vec2u, + viewNormal: vec3f, + projectionMatrix: mat4x4f, + inverseProjectionMatrix: mat4x4f, + viewportWidth: u32, + viewportHeight: u32, + depthTexture: texture_2d, + outSamplePosInTexSpace: ptr, + outReflDirInTexSpace: ptr, + outMaxDistance: ptr + ) { + let sampleDepth = textureLoad(depthTexture, tid, 0).r; + var samplePosClipSpace = vec4f( + ((f32(tid.x) + 0.5) / f32(viewportWidth)) * 2 - 1.0, + ((f32(tid.y) + 0.5) / f32(viewportHeight)) * 2 - 1.0, + sampleDepth, + 1 + ); + samplePosClipSpace.y *= -1; + var samplePosViewSpace = inverseProjectionMatrix * samplePosClipSpace; + samplePosViewSpace /= samplePosViewSpace.w; + let vCamToSampleViewSpace = normalize(samplePosViewSpace.xyz); + let vReflectionViewSpace = vec4f(reflect(vCamToSampleViewSpace.xyz, viewNormal.xyz), 0.0); + + var vReflectionEndPosViewSpace = samplePosViewSpace + vReflectionViewSpace * 1000; + // vReflectionEndPosViewSpace /= select(1.0, vReflectionEndPosViewSpace.z, vReflectionEndPosViewSpace.z > 0.0); + var vReflectionEndPosClipSpace = projectionMatrix * vec4f(vReflectionEndPosViewSpace.xyz, 1.0); + vReflectionEndPosClipSpace /= vReflectionEndPosClipSpace.w; + + let vReflectionDir = normalize((vReflectionEndPosClipSpace - samplePosClipSpace).xyz); + + // transform to texture space + (*outSamplePosInTexSpace) = vec3f( + samplePosClipSpace.xy * vec2f(0.5, -0.5) + vec2f(0.5, 0.5), + samplePosClipSpace.z + ); + + (*outReflDirInTexSpace) = vec3f( + vReflectionDir.xy * vec2f(0.5, -0.5), + vReflectionDir.z + ); + + (*outMaxDistance) = select(-outSamplePosInTexSpace.x / outReflDirInTexSpace.x, (1 - outSamplePosInTexSpace.x) / outReflDirInTexSpace.x, outReflDirInTexSpace.x >= 0); + (*outMaxDistance) = min(*outMaxDistance, select((1 - outSamplePosInTexSpace.y) / outReflDirInTexSpace.y, -outSamplePosInTexSpace.y / outReflDirInTexSpace.y, outReflDirInTexSpace.y < 0)); + (*outMaxDistance) = min(*outMaxDistance, select((1 - outSamplePosInTexSpace.z) / outReflDirInTexSpace.z, -outSamplePosInTexSpace.z / outReflDirInTexSpace.z, outReflDirInTexSpace.z < 0)); + } + + @must_use + fn FindIntersectionLinear( + samplePosInTexSpace: vec3f, + reflDirInTexSpace: vec3f, + maxTraceDistance: f32, + viewportWidth: u32, + viewportHeight: u32, + depthTexture: texture_2d, + intersection: ptr + ) -> f32 { + let vReflectionEndPosTexSpace = samplePosInTexSpace + reflDirInTexSpace * maxTraceDistance; + var dp = vReflectionEndPosTexSpace.xyz - samplePosInTexSpace.xyz; + let viewSize = vec2f(f32(viewportWidth), f32(viewportHeight)); + let sampleScreenPos = vec2i(samplePosInTexSpace.xy * viewSize); + let endPosScreenPos = vec2i(vReflectionEndPosTexSpace.xy * viewSize); + let dp2 = endPosScreenPos - sampleScreenPos; + let maxDist = max(abs(dp2.x), abs(dp2.y)); + dp /= f32(maxDist); + + var rayPosTexSpace = vec4f(samplePosInTexSpace.xyz + dp, 0); + let rayDirTexSpace = vec4f(dp.xyz, 0); + let rayPosStartTexSpace = rayPosTexSpace; + + var hitIndex = -1; + for (var i = 0; i < maxDist && i < settings.maxIterations; i += 4) { + let rayPosTexSpace0 = rayPosTexSpace + rayDirTexSpace * 0; + let rayPosTexSpace1 = rayPosTexSpace + rayDirTexSpace * 1; + let rayPosTexSpace2 = rayPosTexSpace + rayDirTexSpace * 2; + let rayPosTexSpace3 = rayPosTexSpace + rayDirTexSpace * 3; + + let depth0 = textureLoad(depthTexture, vec2u(rayPosTexSpace0.xy * viewSize), 0).r; + let depth1 = textureLoad(depthTexture, vec2u(rayPosTexSpace1.xy * viewSize), 0).r; + let depth2 = textureLoad(depthTexture, vec2u(rayPosTexSpace2.xy * viewSize), 0).r; + let depth3 = textureLoad(depthTexture, vec2u(rayPosTexSpace3.xy * viewSize), 0).r; + + var thickness = 0.0; + + thickness = rayPosTexSpace0.z - depth0; + hitIndex = select(hitIndex, i + 0, thickness >= 0 && thickness < MAX_THICKNESS); + + thickness = rayPosTexSpace1.z - depth1; + hitIndex = select(hitIndex, i + 1, thickness >= 0 && thickness < MAX_THICKNESS); + + thickness = rayPosTexSpace2.z - depth2; + hitIndex = select(hitIndex, i + 2, thickness >= 0 && thickness < MAX_THICKNESS); + + thickness = rayPosTexSpace3.z - depth3; + hitIndex = select(hitIndex, i + 3, thickness >= 0 && thickness < MAX_THICKNESS); + + if (hitIndex != -1) { + break; + } + + rayPosTexSpace = rayPosTexSpace3 + rayDirTexSpace; + } + + let intersected = hitIndex >= 0; + (*intersection) = rayPosStartTexSpace.xyz + rayDirTexSpace.xyz * f32(hitIndex); + + return select(0.0, 1.0, intersected); + } + + @must_use + fn getCellCount(mipLevel: i32, depthTexture: texture_2d) -> vec2f { + return vec2f(textureDimensions(depthTexture, mipLevel)); + } + + @must_use + fn getCell(pos: vec2f, cell_count: vec2f) -> vec2f { + return vec2f(floor(pos * cell_count)); + } + + @must_use + fn intersectDepthPlane(o: vec3f, d: vec3f, z: f32) -> vec3f { + return o + d * z; + } + + @must_use + fn intersectCellBoundary( + o: vec3f, + d: vec3f, + cell: vec2f, + cellCount: vec2f, + crossStep: vec2f, + crossOffset: vec2f + ) -> vec3f { + var intersection = vec3f(0.0); + + let index = cell + crossStep; + var boundary = index / cellCount; + boundary += crossOffset; + + var delta = boundary - o.xy; + delta /= d.xy; + let t = min(delta.x, delta.y); + + intersection = intersectDepthPlane(o, d, t); + + return intersection; + } + + @must_use + fn getMinimumDepthPlane( + p: vec2f, + mipLevel: i32, + depthTexture: texture_2d + ) -> f32 { + return textureLoad(depthTexture, vec2u(p), mipLevel).r; + } + + @must_use + fn crossedCellBoundary(oldCellIndex: vec2f, newCellIndex: vec2f) -> bool { + return (oldCellIndex.x != newCellIndex.x) || (oldCellIndex.y != newCellIndex.y); + } + + @must_use + fn FindIntersectionHiZ( + samplePosInTexSpace: vec3f, + reflDirInTexSpace: vec3f, + maxTraceDistance: f32, + viewportWidth: u32, + viewportHeight: u32, + depthTexture: texture_2d, + intersection: ptr + ) -> f32 { + let viewSize = vec2f(f32(viewportWidth), f32(viewportHeight)); + let maxLevel = textureNumLevels(depthTexture) - 1; + + var crossStep = vec2f( + select(-1.0, 1.0, reflDirInTexSpace.x >= 0), + select(-1.0, 1.0, reflDirInTexSpace.y >= 0) + ); + let crossOffset = crossStep / viewSize / 128.0; + crossStep = saturate(crossStep); + + var ray = samplePosInTexSpace.xyz; + let minZ = ray.z; + let maxZ = ray.z + reflDirInTexSpace.z * maxTraceDistance; + let deltaZ = (maxZ - minZ); + + let o = ray; + let d = reflDirInTexSpace * maxTraceDistance; + + let startLevel = 2; + let stopLevel = 0; + + let startCellCount = getCellCount(startLevel, depthTexture); + + let rayCell = getCell(ray.xy, startCellCount); + ray = intersectCellBoundary( + o, + d, + rayCell, + startCellCount, + crossStep, + crossOffset * 64 + ); + + var level = startLevel; + var iter = 0; + let isBackwardRay = reflDirInTexSpace.z < 0; + let rayDir = select(1.0, -1.0, isBackwardRay); + + while(level >= stopLevel && ray.z * rayDir <= maxZ * rayDir && iter < settings.maxIterations) { + let cellCount = getCellCount(level, depthTexture); + let oldCellIdx = getCell(ray.xy, cellCount); + let cellMinZ = getMinimumDepthPlane((oldCellIdx + 0.5), level, depthTexture); + let tmpRay = select( + ray, + intersectDepthPlane(o, d, (cellMinZ - minZ) / deltaZ), + (cellMinZ > ray.z) && !isBackwardRay + ); + let newCellIdx = getCell(tmpRay.xy, cellCount); + + let thickness = select(0, (ray.z - cellMinZ), level == 0); + let crossed = (isBackwardRay && (cellMinZ > ray.z)) || + (thickness > (MAX_THICKNESS)) || + crossedCellBoundary(oldCellIdx, newCellIdx); + ray = select( + tmpRay, + intersectCellBoundary(o, d, oldCellIdx, cellCount, crossStep, crossOffset), + crossed + ); + level = select( + level - 1, + min(i32(maxLevel), level + 1), + crossed + ); + + iter++; + } + + let intersected = (level < stopLevel); + (*intersection) = ray; + + let intensity = select(0.0, 1.0, intersected); + + return intensity; + } + + @must_use + fn ComputeReflectionColor( + intensity: f32, + intersection: vec3f, + viewportWidth: u32, + viewportHeight: u32, + sceneTexture: texture_2d + ) -> vec4f { + let viewSize = vec2f(f32(viewportWidth), f32(viewportHeight)); + let texCoords = vec2u(intersection.xy * viewSize); + let ssrColor = textureLoad(sceneTexture, texCoords, 0); + return ssrColor; + } + + @compute @workgroup_size(WORKGROUP_SIZE_X, WORKGROUP_SIZE_Y) + fn ${zc}(@builtin(global_invocation_id) globalInvocationId : vec3u,) { + let pos = globalInvocationId.xy; + + let encodedN = textureLoad(normalMetallicRoughnessTexture, pos, 0).rg; + let N = decodeNormal(encodedN); + let sceneColor = textureLoad(sceneTexture, pos, 0); + let reflectanceMask = textureLoad(albedoReflectanceTexture, pos, 0).a; + + var reflectionColor = vec4f(0); + var intensity = 0.0; + + let isReflectance = reflectanceMask != 0; + if (isReflectance) { + var samplePosInTexSpace = vec3f(0); + var reflDirInTexSpace = vec3f(0); + var maxTraceDistance = 0.0; + + ComputePosAndReflection( + pos.xy, + N, + camera.projectionMatrix, + camera.inverseProjectionMatrix, + camera.viewportWidth, + camera.viewportHeight, + depthTexture, + &samplePosInTexSpace, + &reflDirInTexSpace, + &maxTraceDistance + ); + + var intersection = vec3f(0); + + if (settings.isHiZ == 1) { + intensity = FindIntersectionHiZ( + samplePosInTexSpace, + reflDirInTexSpace, + maxTraceDistance, + camera.viewportWidth, + camera.viewportHeight, + depthTexture, + &intersection + ); + } else { + intensity = FindIntersectionLinear( + samplePosInTexSpace, + reflDirInTexSpace, + maxTraceDistance, + camera.viewportWidth, + camera.viewportHeight, + depthTexture, + &intersection + ); + } + + reflectionColor = ComputeReflectionColor( + intensity, + intersection, + camera.viewportWidth, + camera.viewportHeight, + sceneTexture + ); + } + + let combinedColor = sceneColor + reflectionColor; + let finalColor = select( + combinedColor, + mix( + select(combinedColor, vec4f(0, 1, 0, 1), isReflectance), + combinedColor, + intensity + ), + settings.debugMissedIntersections == 1 + ); + + textureStore(outTexture, pos, finalColor); + + } +`)),constants:{WORKGROUP_SIZE_X:rt.COMPUTE_WORKGROUP_SIZE_X,WORKGROUP_SIZE_Y:rt.COMPUTE_WORKGROUP_SIZE_Y}}})),this.settingsBuffer=A.device.createBuffer({label:"SSR Settings Buffer",size:4*Uint32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),X.addBufferBytes(this.settingsBuffer),new Int32Array(this.settingsBuffer.getMappedRange()).set(new Int32Array([this._isHiZ?1:0,this._maxIterations,this._debugMissedIntersections?1:0])),this.settingsBuffer.unmap(),this.outTextures.push(A.device.createTexture({label:"Reflection Texture",size:{width:e,height:t,depthOrArrayLayers:1},format:"rgba16float",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.COPY_SRC})),X.addTextureBytes(this.outTextures[0])}set maxIterations(e){this._maxIterations=e,this.updateSettingsBuffer()}set debugMissedIntersections(e){this._debugMissedIntersections=e,this.updateSettingsBuffer()}set isHiZ(e){this._isHiZ=e,this.updateSettingsBuffer()}updateSettingsBuffer(){A.device.queue.writeBuffer(this.settingsBuffer,0,new Int32Array([this._isHiZ?1:0,this._maxIterations,this._debugMissedIntersections?1:0]))}async destroy(){super.destroy(),await A.device.queue.onSubmittedWorkDone(),X.removeBufferBytes(this.settingsBuffer),this.settingsBuffer.destroy()}setCamera(e){return this.camera=e,this}createComputePassDescriptor(){return this.computePassDescriptor||(this.computePassDescriptor={label:"Reflection Compute Pass Encoder"}),this.computePassDescriptor}render(e,t,r){if(!this.inputTextureViews.length){this.inputTextureViews.push(r[0].createView()),this.inputTextureViews.push(r[1].createView()),this.inputTextureViews.push(r[2].createView()),this.inputTextureViews.push(r[3].createView());const u=[{binding:0,resource:this.inputTextureViews[0]},{binding:1,resource:this.inputTextureViews[1]},{binding:2,resource:this.inputTextureViews[2]},{binding:3,resource:this.inputTextureViews[3]},{binding:4,resource:this.outTextures[0].createView()},{binding:5,resource:{buffer:this.camera.gpuBuffer}},{binding:6,resource:{buffer:this.settingsBuffer}}];this.bindGroup=A.device.createBindGroup({label:"Compute Reflections Bind Group",entries:u,layout:this.bindGroupLayout})}const n=e.beginComputePass(this.createComputePassDescriptor());A.ENABLE_DEBUG_GROUPS&&n.pushDebugGroup("Begin Reflection Compute Pass"),n.setPipeline(rt.computePSO),n.setBindGroup(0,this.bindGroup);const i=Math.ceil(this.outTextures[0].width/rt.COMPUTE_WORKGROUP_SIZE_X),o=Math.ceil(this.outTextures[0].height/rt.COMPUTE_WORKGROUP_SIZE_Y);return n.dispatchWorkgroups(i,o,1),A.ENABLE_DEBUG_GROUPS&&n.popDebugGroup(),n.end(),this.postRender(e),this.outTextures}};rt.COMPUTE_WORKGROUP_SIZE_X=8,rt.COMPUTE_WORKGROUP_SIZE_Y=8;let lo=rt;const jc="fragBlurSSAO",Zp=` + ${Y.Camera} + ${Y.VertexOutput} + + @group(0) @binding(0) var ssaoTexture: texture_2d; + + @fragment + fn ${jc}(in: VertexOutput) -> @location(0) vec4f { + let coord = in.position; + let pixelCoords = vec2i(floor(coord.xy)); + var result = 0.0; + for (var y = -2; y < 2; y++) { + for (var x = -2; x < 2; x++) { + let offset = pixelCoords + vec2i(x, y); + result += textureLoad(ssaoTexture, offset, 0).r; + } + } + return vec4f(result / 16.0, 0, 0, 1); + } +`;class Yr extends Se{constructor(e,t){super(V.SSAOBlur,e,t);const r=[{format:"r16float"}],n=[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"unfilterable-float"}}];this.bindGroupLayout=A.device.createBindGroupLayout({label:"SSAO Blur Input Bind Group",entries:n}),Yr.renderPSO||(Yr.renderPSO=J.createRenderPipeline({label:"SSAO Blur RenderPSO",layout:A.device.createPipelineLayout({label:"SSAO Blur RenderPSO Layout",bindGroupLayouts:[this.bindGroupLayout]}),vertex:{module:J.createShaderModule(Yt),entryPoint:Tt},fragment:{module:J.createShaderModule(Zp),entryPoint:jc,targets:r}})),this.outTextures.push(A.device.createTexture({dimension:"2d",format:"r16float",mipLevelCount:1,sampleCount:1,size:{width:e,height:t,depthOrArrayLayers:1},usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT,label:"SSAO Blurred Texture"})),X.addTextureBytes(this.outTextures[0]),this.outTextureView=this.outTextures[0].createView()}createRenderPassDescriptor(){if(this.renderPassDescriptor)return this.renderPassDescriptor;const e=[{loadOp:"load",storeOp:"store",view:this.outTextureView}];return this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({label:"SSAO Blur Render Pass Descriptor",colorAttachments:e}),this.renderPassDescriptor}render(e,t,r){if(!this.inputTextureViews.length){this.inputTextureViews.push(r[0].createView());const i=[{binding:0,resource:this.inputTextureViews[0]}];this.bindGroup=A.device.createBindGroup({label:"SSAO Blur Bind Group",entries:i,layout:this.bindGroupLayout})}const n=e.beginRenderPass(this.createRenderPassDescriptor());return A.ENABLE_DEBUG_GROUPS&&n.pushDebugGroup("Begin SSAO Blur"),n.setBindGroup(0,this.bindGroup),n.setPipeline(Yr.renderPSO),n.draw(3),A.ENABLE_DEBUG_GROUPS&&n.popDebugGroup(),n.end(),this.postRender(e),this.outTextures}}const Kc="fragSSAO",em=` + ${Y.Camera} + ${Y.VertexOutput} + ${Y.MathHelpers} + + ${jr} + + struct Settings { + kernelSize: u32, + radius: f32, + strength: f32 + }; + + @group(0) @binding(0) var normalMetallicRoughnessTex: texture_2d; + @group(0) @binding(1) var depthTexture: texture_depth_2d; + @group(0) @binding(2) var noiseTexture: texture_2d; + @group(0) @binding(3) var kernelBuffer: array; + @group(0) @binding(4) var camera: Camera; + @group(0) @binding(5) var settings: Settings; + + @fragment + fn ${Kc}( + in: VertexOutput + ) -> @location(0) vec4f { + let coord = in.position; + let pixelCoords = vec2i(floor(coord.xy)); + let encodedN = textureLoad(normalMetallicRoughnessTex, pixelCoords, 0).rg; + let viewNormal = decodeNormal(encodedN); + let centerDepth = textureLoad(depthTexture, pixelCoords, 0); + let viewSpacePos = calcViewSpacePos(camera, coord.xy, centerDepth); + + let noiseScale = vec2i(textureDimensions(noiseTexture).xy); + let sampleCoords = pixelCoords % noiseScale; + var randomVec = textureLoad(noiseTexture, sampleCoords, 0).rgb * 2 - 1; + randomVec = (camera.viewMatrix * vec4f(randomVec, 0)).xyz; + + let viewTangent = normalize(randomVec - viewNormal * dot(randomVec, viewNormal)); + let viewBitangent = cross(viewNormal, viewTangent); + let TBN = mat3x3f(viewTangent, viewBitangent, viewNormal); + + let kernelSize = settings.kernelSize; + let radius = settings.radius; + + var occlusion = 0.0; + + let screenSize = vec2i(textureDimensions(depthTexture).xy); + + for (var i = 0u; i < kernelSize; i++) { + var viewSamplePos = TBN * kernelBuffer[i].xyz; + viewSamplePos = viewSpacePos + viewSamplePos * radius; + + let viewSampleDir = normalize(viewSamplePos - viewSpacePos); + let NdotS = max(dot(viewNormal, viewSampleDir), 0.0); + + let clipPos = camera.projectionMatrix * vec4f(viewSamplePos, 1.0); + let ndcPos = clipPos.xy / clipPos.w; + + let screenCoord = vec2i(vec2f(ndcPos.x * 0.5 + 0.5, -ndcPos.y * 0.5 + 0.5) * vec2f(screenSize)); + + var sampleDepth = textureLoad(depthTexture, screenCoord, 0); + sampleDepth = calcViewSpacePos(camera, vec2f(screenCoord), sampleDepth).z; + + let rangeCheck = smoothstep(0.1, 1.0, radius / abs(viewSpacePos.z - sampleDepth)); + + occlusion += select(0.0, 1.0, sampleDepth > viewSamplePos.z) * rangeCheck * NdotS; + } + + occlusion = 1 - (occlusion / f32(kernelSize)); + let finalOcclusion = pow(occlusion, settings.strength); + + return vec4f(finalOcclusion); + } +`,ve=class ve extends Se{constructor(e,t){if(super(V.SSAO,e,t),this.gbufferTexturesBindGroupEntries=[],this.startKernelSize=64,this._kernelSize=128,this._radius=.5,this._strength=1,!ve.kernelBuffer){const o=this.kernelSize,u=new Float32Array(4*o);for(let l=0;l; + @group(0) @binding(1) var velocityTexture: texture_2d; + @group(0) @binding(2) var historyTexture: texture_2d; + @group(0) @binding(3) var historyMixFactor: f32; + + @fragment + fn ${$c}(@builtin(position) coord: vec4f) -> @location(0) vec4f { + let pixelCoords = vec2i(floor(coord.xy)); + let currColor = textureLoad(colorTexture, pixelCoords, 0).xyz; + let velocity = textureLoad(velocityTexture, pixelCoords, 0).xy; + let prevousPixelPos = vec2i(floor(coord.xy - velocity)); + + var history = textureLoad(historyTexture, prevousPixelPos, 0).xyz; + + let nearColor0 = textureLoad(colorTexture, pixelCoords + vec2i(1, 0), 0).xyz; + let nearColor1 = textureLoad(colorTexture, pixelCoords + vec2i(0, 1), 0).xyz; + let nearColor2 = textureLoad(colorTexture, pixelCoords + vec2i(-1, 0), 0).xyz; + let nearColor3 = textureLoad(colorTexture, pixelCoords + vec2i(0, -1), 0).xyz; + + let boxMin = min(currColor, min(nearColor0, min(nearColor1, min(nearColor2, nearColor3)))); + let boxMax = max(currColor, max(nearColor0, max(nearColor1, max(nearColor2, nearColor3))));; + + history = clamp(history, boxMin, boxMax); + + var color = vec4f(mix(currColor, history, historyMixFactor), 1.0); + + return color; + } +`,Lt=class Lt extends Se{constructor(e,t){super(V.TAAResolve,e,t),this.historyReset=!1;const r=J.createShaderModule(Yt),n=J.createShaderModule(rm),i=[{format:"rgba16float"}],o=[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:3,visibility:GPUShaderStage.FRAGMENT,buffer:{}}];if(this.texturesBindGroupLayout=A.device.createBindGroupLayout({label:"TAA Resolve Input Textures Bind Group",entries:o}),!Lt.renderPSO){const u={layout:A.device.createPipelineLayout({bindGroupLayouts:[this.texturesBindGroupLayout]}),vertex:{module:r,entryPoint:Tt},fragment:{module:n,entryPoint:$c,targets:i},primitive:{topology:"triangle-list",cullMode:"back"}};Lt.renderPSO=J.createRenderPipeline(u)}this.outTextures.push(A.device.createTexture({dimension:"2d",format:"rgba16float",mipLevelCount:1,sampleCount:1,size:{width:e,height:t,depthOrArrayLayers:1},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.COPY_SRC,label:"TAA Resolve Texture"})),this.outTextureView=this.outTextures[0].createView(),X.addTextureBytes(this.outTextures[0]),this.sourceCopyTextureInfo={texture:this.outTextures[0],mipLevel:0,origin:{x:0,y:0,z:0}},this.outTextures.push(A.device.createTexture({dimension:"2d",format:"rgba16float",mipLevelCount:1,sampleCount:1,size:{width:e,height:t,depthOrArrayLayers:1},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST,label:"TAA Resolve Texture"})),this.historyTextureView=this.outTextures[1].createView(),X.addTextureBytes(this.outTextures[1]),this.destCopyTextureInfo={texture:this.outTextures[1],mipLevel:0,origin:{x:0,y:0,z:0}},this.copyTextureExtend={width:e,height:t,depthOrArrayLayers:1},this.historyMixFactorBuffer=A.device.createBuffer({label:"TAA History Mix Factor Buffer",size:1*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),new Float32Array(this.historyMixFactorBuffer.getMappedRange()).set([Lt.HISTORY_MIX_FACTOR]),X.addBufferBytes(this.historyMixFactorBuffer),this.historyMixFactorBuffer.unmap()}async destroy(){super.destroy(),await A.device.queue.onSubmittedWorkDone(),X.removeBufferBytes(this.historyMixFactorBuffer),this.historyMixFactorBuffer.destroy()}resetHistory(){this.historyReset=!0,A.device.queue.writeBuffer(this.historyMixFactorBuffer,0,new Float32Array([0]))}createRenderPassDescriptor(){if(this.renderPassDescriptor)return this.renderPassDescriptor;const e=[{view:this.outTextureView,loadOp:"load",storeOp:"store"}];return this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({label:"TAA Resolve Pass",colorAttachments:e}),this.renderPassDescriptor}render(e,t,r){if(!this.inputTextureViews.length){this.inputTextureViews.push(r[0].createView()),this.inputTextureViews.push(r[1].createView());const o=[{binding:0,resource:this.inputTextureViews[0]},{binding:1,resource:this.inputTextureViews[1]},{binding:2,resource:this.historyTextureView},{binding:3,resource:{buffer:this.historyMixFactorBuffer}}];this.textureBindGroup=A.device.createBindGroup({layout:this.texturesBindGroupLayout,entries:o})}const n=this.createRenderPassDescriptor(),i=e.beginRenderPass(n);return A.setActiveRenderPass(this.type,i),A.bindRenderPSO(Lt.renderPSO),i.setBindGroup(0,this.textureBindGroup),i.draw(3),i.end(),e.copyTextureToTexture(this.sourceCopyTextureInfo,this.destCopyTextureInfo,this.copyTextureExtend),this.postRender(e),this.historyReset&&(A.device.queue.onSubmittedWorkDone().then(()=>{A.device.queue.writeBuffer(this.historyMixFactorBuffer,0,new Float32Array([Lt.HISTORY_MIX_FACTOR]))}),this.historyReset=!1),this.outTextures}};Lt.HISTORY_MIX_FACTOR=.9;let fo=Lt;class sm extends Se{constructor(e,t){super(V.Transparent,e,t)}setCamera(e){return this.camera=e,this}createRenderPassDescriptor(){if(this.renderPassDescriptor)return this.renderPassDescriptor;const e=[{view:this.inputTextureViews[0],loadOp:"load",storeOp:"store"}];return this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({label:"Transparent Render Pass",colorAttachments:e,depthStencilAttachment:{view:this.inputTextureViews[1],depthLoadOp:"load",depthStoreOp:"store",stencilReadOnly:!0}}),this.renderPassDescriptor}render(e,t,r){this.inputTextureViews.length||(this.inputTextureViews.push(r[0].createView()),this.inputTextureViews.push(r[1].createView()));const n=e.beginRenderPass(this.createRenderPassDescriptor());return A.setActiveRenderPass(this.type,n),A.ENABLE_DEBUG_GROUPS&&n.pushDebugGroup("Render Transparent Nodes"),this.cameraBindGroup=A.device.createBindGroup({label:"Camera Bind Group for: Transparent Pass",layout:J.defaultCameraPlusLightsBindGroupLayout,entries:[{binding:0,resource:{buffer:this.camera.gpuBuffer}},{binding:1,resource:{buffer:t.lightingManager.gpuBuffer}}]}),n.setBindGroup(ce.CameraPlusOptionalLights,this.cameraBindGroup),t.lightingManager.render(n),t.renderDebugMeshes(n),A.ENABLE_DEBUG_GROUPS&&n.popDebugGroup(),n.end(),this.postRender(e),r}}const Wr="deferredPBRFrag",nn=({hasPBRTextures:s=!1,isInstanced:e=!1}={})=>St` + ${Y.Camera} + ${Y.VertexOutput} + ${Y.GBufferOutput} + ${Y.ModelUniform} + ${Y.InstanceInput} + + @group(${ce.CameraPlusOptionalLights}) @binding(0) var camera: Camera; + @group(${ce.Model}) @binding(0) var model: ModelUniform; + + @group(${ce.PBRTextures}) @binding(${ms.Default}) var texSampler: sampler; + @group(${ce.PBRTextures}) @binding(${me.Albedo}) var albedoTexture: texture_2d; + @group(${ce.PBRTextures}) @binding(${me.Normal}) var normalTexture: texture_2d; + @group(${ce.PBRTextures}) @binding(${me.MetallicRoughness}) var metallicRoughnessTexture: texture_2d; + + #if ${e} + @group(${ce.InstanceInputs}) @binding(0) var instanceInputs: array; + #endif + + ${jr} + + @fragment + fn ${Wr}(in: VertexOutput) -> GBufferOutput { + let uv = in.uv; + + var viewSpaceN = normalize(in.viewNormal); + let viewSpaceT = normalize(in.viewTangent); + let viewSpaceB = normalize(in.viewBitangent); + let viewSpaceTBN = mat3x3f(viewSpaceT, viewSpaceB, viewSpaceN); + + // var textureNormal = textureSampleLevel(normalTexture, texSampler, uv, 5.0).rgb * 2 - 1; + let textureNormal = textureSample(normalTexture, texSampler, uv).rgb * 2 - 1; + + if (${s}) { + viewSpaceN = normalize(viewSpaceTBN * textureNormal); + } + + var color = model.baseColor; + if (${s}) { + let texColor = textureSample(albedoTexture, texSampler, uv); + if (texColor.a < 0.2) { + discard; + } + color = texColor.rgb; + } + + var out: GBufferOutput; + + #if ${e} + var metallic = instanceInputs[in.instanceId].metallic; + var roughness = instanceInputs[in.instanceId].roughness; + #else + var metallic = model.metallic; + var roughness = model.roughness; + #endif + + + if (${s}) { + let metallicRoughness = textureSample(metallicRoughnessTexture, texSampler, uv).rgb; + metallic = metallicRoughness.b; + roughness = metallicRoughness.g; + } + + out.normalMetallicRoughness = vec4f( + encodeNormal(viewSpaceN), + metallic, + roughness + ); + + out.color = vec4f(color, f32(model.isReflective)); + + var oldPos = in.prevFrameClipPos; + var newPos = in.currFrameClipPos; + + oldPos /= oldPos.w; + oldPos.x = (oldPos.x+1)/2.0; + oldPos.y = (oldPos.y+1)/2.0; + oldPos.y = 1 - oldPos.y; + + newPos /= newPos.w; + newPos.x = (newPos.x+1)/2.0; + newPos.y = (newPos.y+1)/2.0; + newPos.y = 1 - newPos.y; + + out.velocity = vec4f((newPos - oldPos).xy, 0, 1); + + return out; + } +`,Xc="forwardPBRFrag",nm=({hasPBRTextures:s=!1,isInstanced:e=!1}={})=>St` + ${Y.Camera} + ${Y.VertexOutput} + ${Y.GBufferOutput} + ${Y.ModelUniform} + ${Y.Material} + ${Y.InstanceInput} + ${Y.CommonHelpers} + ${Y.Light} + + @group(${ce.CameraPlusOptionalLights}) @binding(0) var camera: Camera; + @group(${ce.CameraPlusOptionalLights}) @binding(1) var lightsBuffer: array; + + @group(${ce.Model}) @binding(0) var model: ModelUniform; + + @group(${ce.PBRTextures}) @binding(${ms.Default}) var texSampler: sampler; + @group(${ce.PBRTextures}) @binding(${me.Albedo}) var albedoTexture: texture_2d; + @group(${ce.PBRTextures}) @binding(${me.Normal}) var normalTexture: texture_2d; + @group(${ce.PBRTextures}) @binding(${me.MetallicRoughness}) var metallicRoughnessTexture: texture_2d; + + #if ${e} + @group(${ce.InstanceInputs}) @binding(0) var instanceInputs: array; + #endif + + ${Vc({isDeferred:!1,hasIBL:!1})} + + @fragment + fn ${Xc}(in: VertexOutput) -> @location(0) vec4f { + let uv = in.uv; + + var N = normalize(in.viewNormal); + let T = normalize(in.viewTangent); + let B = normalize(in.viewBitangent); + let TBN = mat3x3f(T, B, N); + let textureNormal = textureSample(normalTexture, texSampler, uv).rgb * 2 - 1; + if (${s}) { + N = normalize(TBN * textureNormal); + } + + #if ${e} + var metallic = instanceInputs[in.instanceId].metallic; + var roughness = instanceInputs[in.instanceId].roughness; + #else + var metallic = model.metallic; + var roughness = model.roughness; + #endif + + if (${s}) { + let metallicRoughness = textureSample(metallicRoughnessTexture, texSampler, uv).rgb; + metallic = metallicRoughness.b; + roughness = metallicRoughness.g; + } + + let modelTexColor = textureSample(albedoTexture, texSampler, uv).rgb; + var color = vec4f(model.baseColor, 1); + if (${s}) { + color = textureSample(albedoTexture, texSampler, uv); + } + + // if (color.a < 0.01) { + // discard; + // } + + var material = Material(); + material.albedo = color.rgb; + material.roughness = roughness; + // return vec4f(vec3f(1 - metallic), 1); + material.metallic = metallic; + material.ambientOcclusion = 1.0; + + let V = normalize(camera.position - in.worldPosition); + + return PBRLighting( + material, + 0, + in.worldPosition, + N, + V, + 1, + color.a + ); + } +`,bt="vertexMain",Et=({isInstanced:s,isShadow:e}={isInstanced:!1,isShadow:!1})=>St` + ${Y.VertexInput} + ${Y.VertexOutput} + ${Y.ModelUniform} + ${Y.Camera} + ${Y.InstanceInput} + + @group(${ce.CameraPlusOptionalLights}) @binding(0) var camera: Camera; + @group(${ce.Model}) @binding(0) var model: ModelUniform; + + @group(${ce.PBRTextures}) @binding(${me.Albedo}) var albedoTexture: texture_2d; + @group(${ce.PBRTextures}) @binding(${me.Normal}) var normalTexture: texture_2d; + + #if ${s} + @group(${ce.InstanceInputs}) @binding(0) var instanceInputs: array; + #endif + + @vertex + fn ${bt}( + @builtin(instance_index) instanceId: u32, + in: VertexInput + ) -> VertexOutput { + var position = in.position; + + var worldMatrix: mat4x4f; + + #if ${!e} + var prevWorldMatrix: mat4x4f; + #endif + + #if ${s} + worldMatrix = instanceInputs[instanceId].worldMatrix * model.worldMatrix; + #if ${!e} + prevWorldMatrix = instanceInputs[instanceId].worldMatrix * model.prevFrameWorldMatrix; + #endif + #else + worldMatrix = model.worldMatrix; + #if ${!e} + prevWorldMatrix = model.prevFrameWorldMatrix; + #endif + #endif + + var out: VertexOutput; + let worldPosition = worldMatrix * in.position; + #if ${e} + out.position = camera.projectionViewMatrix * worldPosition; + #else + out.position = camera.projectionViewMatrix * worldPosition; + out.worldPosition = worldPosition.xyz; + + // var jitterOffset = camera.jitterOffset; + // jitterOffset.x = ((jitterOffset.x - 0.5) / f32(camera.viewportWidth)) * 2; + // jitterOffset.y = ((jitterOffset.y - 0.5) / f32(camera.viewportHeight)) * 2; + + out.position += vec4f(camera.jitterOffset * out.position.w, 0, 0); + + out.currFrameClipPos = out.position; + out.prevFrameClipPos = camera.prevFrameProjectionViewMatrix * prevWorldMatrix * in.position; + + let viewSpaceNormMatrix = mat3x3f( + camera.viewMatrix[0].xyz, + camera.viewMatrix[1].xyz, + camera.viewMatrix[2].xyz + ) * model.normalMatrix; + + let viewTangent = normalize(viewSpaceNormMatrix * in.tangent.xyz); + let viewNormal = normalize(viewSpaceNormMatrix * in.normal); + let viewBitangent = normalize(cross(viewNormal, viewTangent)) * in.tangent.w; + + out.viewTangent = viewTangent; + out.viewBitangent = viewBitangent; + out.viewNormal = viewNormal; + out.instanceId = instanceId; + out.uv = in.uv; + #endif + + return out; + } + `;let on,an,un,po,mo,go,yo,bo;const Yc=Object.freeze({get defaultGLTFTransparentPBRMaterial(){return bo||(bo=new yt({debugLabel:"Forward Pass Default PBR Material",vertexShaderSrc:Et(),vertexShaderEntryFn:bt,vertexBuffers:Be.defaultGLTFLayout,fragmentShaderSrc:nm({hasPBRTextures:!0}),fragmentShaderEntryFn:Xc,targets:[{format:"rgba16float",blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}],bindGroupLayouts:[J.defaultCameraPlusLightsBindGroupLayout,J.defaultModelBindGroupLayout,J.defaultModelMaterialBindGroupLayout],depthStencilState:{format:Qt.depthStencilFormat,depthWriteEnabled:!0,depthCompare:"less"},primitive:{cullMode:"none"}}),bo)},get defaultDeferredPBRMaterial(){if(on)return on;const s={compare:"always",failOp:"keep",depthFailOp:"keep",passOp:"replace"};return on=new yt({debugLabel:"Deferred Pass Default PBR Material",vertexShaderSrc:Et(),vertexShaderEntryFn:bt,vertexBuffers:Be.defaultLayout,fragmentShaderSrc:nn(),fragmentShaderEntryFn:Wr,constants:{},targets:Xt,depthStencilState:{format:Qt.depthStencilFormat,depthWriteEnabled:!0,depthCompare:"less",stencilReadMask:0,stencilWriteMask:255,stencilBack:s,stencilFront:s}}),on},get defaultGLTFDeferredPBRMaterial(){if(an)return an;const s={compare:"always",failOp:"keep",depthFailOp:"keep",passOp:"replace"};return an=new yt({debugLabel:"Deferred Pass Default PBR Material",vertexShaderSrc:Et(),vertexShaderEntryFn:bt,vertexBuffers:Be.defaultGLTFLayout,fragmentShaderSrc:nn(),fragmentShaderEntryFn:Wr,constants:{},targets:Xt,depthStencilState:{format:Qt.depthStencilFormat,depthWriteEnabled:!0,depthCompare:"less",stencilReadMask:0,stencilWriteMask:255,stencilBack:s,stencilFront:s}}),an},get defaultGLTFTexturedDeferredMaterial(){if(un)return un;const s={compare:"always",failOp:"keep",depthFailOp:"keep",passOp:"replace"};return un=new yt({debugLabel:"Default Textured Deferred PBR",vertexShaderSrc:Et(),vertexShaderEntryFn:bt,vertexBuffers:Be.defaultGLTFLayout,fragmentShaderSrc:nn({hasPBRTextures:!0}),fragmentShaderEntryFn:Wr,constants:{},targets:Xt,depthStencilState:{format:Qt.depthStencilFormat,depthWriteEnabled:!0,depthCompare:"less",stencilReadMask:0,stencilWriteMask:255,stencilBack:s,stencilFront:s}}),un},get defaultDeferredInstancedMaterial(){return po||(po=new yt({debugLabel:"Material",vertexShaderSrc:Et({isInstanced:!0}),vertexShaderEntryFn:bt,fragmentShaderSrc:nn(),fragmentShaderEntryFn:Wr,bindGroupLayouts:[J.defaultCameraBindGroupLayout,J.defaultModelBindGroupLayout,J.instancesBindGroupLayout],targets:Xt}),po)},get defaultShadowMaterial(){return go||(go=new yt({debugLabel:"Default Shadow Material",vertexShaderSrc:Et(),vertexShaderEntryFn:bt,vertexBuffers:Be.defaultLayout}),go)},get defaultGLTFShadowMaterial(){return mo||(mo=new yt({debugLabel:"Default Shadow Material",vertexShaderSrc:Et({isShadow:!0}),vertexShaderEntryFn:bt,vertexBuffers:Be.defaultGLTFLayout,primitive:{cullMode:"front"},depthStencilState:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}),mo)},get defaultInstancedShadowMaterial(){return yo||(yo=new yt({debugLabel:"Default Shadow Material",vertexShaderSrc:Et({isInstanced:!0}),vertexShaderEntryFn:bt,bindGroupLayouts:[J.defaultCameraBindGroupLayout,J.defaultModelBindGroupLayout,J.defaultModelMaterialBindGroupLayout,J.instancesBindGroupLayout],depthStencilState:{format:"depth24plus",depthWriteEnabled:!0,depthCompare:"less"}}),yo)}}),yn=class yn extends A{constructor(){super(),this.scene=new xp,this.cpuAverage=new Rr,this.gpuAverage=new Rr,this.fpsDisplayAverage=new Rr,this.resizeCounter=0,this.viewportWidth=0,this.viewportHeight=0,this._ssaoEnabled=!0,this.enableAnimation=!0,this._ssrEnabled=!0,this._bloomEnabled=!0,this.mainCamera=new Xn(70,1,.1,100),this.mainCamera.shouldJitter=!0,this.mainCamera.setPositionAsVec3(Ec),this.mainCamera.setLookAt(0,2,0),this.mainCamera.updateViewMatrix(),this.mainCameraCtrl=new Fn(this.mainCamera,document.body,A.$canvas),this.mainCameraCtrl.startTick(),this.debugCamera=new Xn(70,1,.1,100),this.debugCamera.setPosition(6,12,1),this.debugCamera.setLookAt(0,7,0),this.debugCamera.updateViewMatrix();const e=new Rd(Pp,!0).getPoints(240);this.lightingManager=new Qi(e),this.scene.lightingManager=this.lightingManager,this.texturesDebugContainer=new Yi,this.timingDebugContainer=new Wi,this.scene.skybox=new Kp;const t=new gp(Sl);this.scene.addChild(t),t.setPositionY(2).updateWorldMatrix(),Promise.all([ge.load6SeparateHDRFacesAsCubeMapTexture(Mp,512,!0,"Skybox Faces"),t.load()]).then(([r])=>{this.envDiffuseTexture=ji.encode(r),this.envSpecularTexture=Ki.encode(r,256),this.envBdrfLutTexture=zi.encode(),$t.generateMipsForCubeTexture(this.envDiffuseTexture),this.scene.skybox.setTexture(this.envDiffuseTexture),this.renderPassComposer.getPass(V.DirectionalAmbientLighting).setDiffuseIBLTexture(this.envDiffuseTexture).setSpecularIBLTexture(this.envSpecularTexture).setBDRFLutTexture(this.envBdrfLutTexture),X.removeTextureBytes(r),r.destroy(),t.setMaterial(Yc.defaultGLTFTexturedDeferredMaterial).setMaterial(Yc.defaultGLTFShadowMaterial,V.Shadow),setTimeout(()=>{document.getElementById("loader").classList.toggle("faded"),new us({durationMS:1500,delayMS:100,easeName:"sine_InOut",onUpdate:n=>{const i=F.lerp(Sc,Rp,n),o=jo(0,2,n);this.sunPositionX=i[0],this.sunPositionY=i[1],this.sunPositionZ=i[2],this.sunIntensity=o},onComplete:()=>{}}).start(),new us({durationMS:500,delayMS:1e3,easeName:"quad_Out",onUpdate:n=>{this.lightingManager.fireParticlesRevealFactor=n},onComplete:()=>{document.getElementById("logo").classList.toggle("faded"),this.mainCameraCtrl.revealTouchControls(),this.onIntroAnimComplete&&this.onIntroAnimComplete()}}).start(),new us({durationMS:1800,easeName:"quad_Out",onUpdate:n=>{this.mainCamera.setPositionAsVec3(F.lerp(Ec,Gp,n)).updateViewMatrix()},onComplete:()=>{}}).start(),this.renderPassComposer.getPass(V.Blit).revealWithAnimation(800)},500)})}set sunPositionX(e){this.lightingManager.sunPositionX=e}set sunPositionY(e){this.lightingManager.sunPositionY=e}set sunPositionZ(e){this.lightingManager.sunPositionZ=e}set sunIntensity(e){this.lightingManager.sunIntensity=e}set ssaoEnabled(e){this._ssaoEnabled=e,this.recreateRenderComposer()}set ssaoKernelSize(e){this.renderPassComposer.getPass(V.SSAO).kernelSize=e}set ssaoRadius(e){this.renderPassComposer.getPass(V.SSAO).radius=e}set ssaoStrength(e){this.renderPassComposer.getPass(V.SSAO).strength=e}set enableTAA(e){this.mainCamera.shouldJitter=e;const t=this.renderPassComposer.getPass(V.TAAResolve),r=this.renderPassComposer.getPass(V.BloomDownsample),n=this.renderPassComposer.getPass(V.Blit);t.enabled=e,e&&t.resetHistory(),r.resetInputs().addInputTexture(e?Jr:Qs),n.resetInputs().addInputTextures([zr,e?Jr:Qs])}set debugGBuffer(e){e?(this.texturesDebugContainer.scrollIntoGbufferSection(),this.texturesDebugContainer.reveal()):this.texturesDebugContainer.hide()}set debugShadowMap(e){e?(this.texturesDebugContainer.scrollToShadowSection(),this.texturesDebugContainer.reveal()):this.texturesDebugContainer.hide()}set shadowMapSize(e){const t=this.renderPassComposer.getPass(V.Shadow);this.renderPassComposer.getPass(V.DirectionalAmbientLighting).resetInputs().addInputTextures([ut,Ct,Te,Tc,Vr]),t.shadowMapSize=e}set debugShadowCascadeIndex(e){this.renderPassComposer.getPass(V.DirectionalAmbientLighting).debugShadowCascadeLayer=e}set debugLightsMask(e){this.renderPassComposer.getPass(V.PointLightsLighting).debugLightsMask=e}set render2ndFloorPoints(e){this.lightingManager.render2ndFloorParticles=e}set ssrIsHiZ(e){this.renderPassComposer.getPass(V.Reflection).isHiZ=e,this.renderPassComposer.getPass(V.HiZ).enabled=e}set ssrMaxIterations(e){this.renderPassComposer.getPass(V.Reflection).maxIterations=e}set debugMissedSSR(e){this.renderPassComposer.getPass(V.Reflection).debugMissedIntersections=e}set ssrEnabled(e){this._ssrEnabled=e,this.recreateRenderComposer()}set bloomEnabled(e){this._bloomEnabled=e,this.recreateRenderComposer()}set bloomFilterRadius(e){this.renderPassComposer.getPass(V.BloomUpsample).bloomFilterRadius=e}set debugBoundingBoxes(e){this.renderPassComposer.getPass(V.DebugBounds).enabled=e}set debugMovementCurve(e){this.curveMoveLine.visible=e}toggleStatsVisibility(){this.timingDebugContainer.toggleVisibility()}recreateRenderComposer(e=this.viewportWidth,t=this.viewportHeight){var R;(R=this.renderPassComposer)==null||R.destroy(),this.renderPassComposer=new Pd,this.renderPassComposer.setScene(this.scene);const r=new tn(this.lightingManager.mainDirLight,e,t).addOutputTexture(Vr).setCamera(this.mainCamera),n=new Wp(e,t).setCamera(this.mainCamera).addOutputTextures([ut,Ct,$i,Te]);let i,o;this._ssaoEnabled&&(i=new ho(e,t).addInputTextures([ut,Te]).addOutputTexture(Hr).setCamera(this.mainCamera),o=new Yr(e,t).addInputTexture(Hr).addOutputTexture(Tc));const u=[ut,Ct,Te,Vr];this._ssaoEnabled&&u.push(Hr);const l=new _r(r.shadowCascadesBuffer,e,t).setCamera(this.mainCamera).addInputTextures(u).addOutputTexture(qe);l.ssaoMixFactor=this._ssaoEnabled?1:0,this.envDiffuseTexture&&l.setDiffuseIBLTexture(this.envDiffuseTexture),this.envSpecularTexture&&l.setSpecularIBLTexture(this.envSpecularTexture),this.envBdrfLutTexture&&l.setBDRFLutTexture(this.envBdrfLutTexture);const m=[ut,Ct,Te,qe];this._ssaoEnabled&&m.push(Hr);const y=new co(e,t).setCamera(this.mainCamera).addInputTextures(m).addOutputTexture(qe),d=new Xr(e,t).setCamera(this.mainCamera).addInputTextures([Te]).addOutputTexture(Te).setLightsBuffer(this.lightingManager.gpuBuffer).updateLightsMaskBindGroup(),x=[ut,Ct,Te,qe];this._ssaoEnabled&&x.push(Hr);const b=new Br(e,t).setCamera(this.mainCamera).addInputTextures(x).addOutputTexture(qe),_=new sm(e,t).setCamera(this.mainCamera).addInputTextures([qe,Te]).addOutputTextures([qe,Te]),C=new tm(e,t).setCamera(this.mainCamera).addInputTextures([qe,Te]).addOutputTextures([qe,Te]);let f,p,a;this._ssrEnabled&&(f=new oo(e,t).addInputTexture(Te).addOutputTexture(qs),p=new ao(e,t).addInputTexture(qs).addOutputTexture(qs),a=new lo(e,t).setCamera(this.mainCamera).addInputTextures([qe,ut,Ct,qs]).addOutputTexture(Qs));const c=new fo(e,t).addInputTextures([this._ssrEnabled?Qs:qe,$i]).addOutputTexture(Jr);let h,g;this._bloomEnabled&&(h=new no(e,t).addInputTexture(Jr).addOutputTexture(zr),g=new $r(e,t).addInputTexture(zr).addOutputTexture(zr));const B=[];this._bloomEnabled&&B.push(zr),B.push(Jr);const w=new so(e,t,this.resizeCounter>0).addInputTextures(B);w.bloomEnabled=this._bloomEnabled,this.renderPassComposer.addPass(r).addPass(n),this._ssaoEnabled&&this.renderPassComposer.addPass(i).addPass(o),this.renderPassComposer.addPass(l).addPass(y).addPass(d).addPass(b).addPass(_).addPass(C),this._ssrEnabled&&this.renderPassComposer.addPass(f).addPass(p).addPass(a),this.renderPassComposer.addPass(c),this._bloomEnabled&&this.renderPassComposer.addPass(h).addPass(g),this.renderPassComposer.addPass(w)}resize(e,t){this.viewportWidth=e,this.viewportHeight=t,this.debugCamera.onResize(e,t),this.mainCamera.onResize(e,t),this.recreateRenderComposer(e,t),this.resizeCounter++}async renderFrame(e){const t=.001*(e-A.elapsedTimeMs),r=t-A.prevTimeMs;A.prevTimeMs=t,A.elapsedTimeMs+=this.enableAnimation?r:0,A.deltaTimeMs=this.enableAnimation?Math.min(r,.5):0;const n=performance.now();this.debugCamera.onFrameStart(),this.mainCamera.onFrameStart();const i=A.device.createCommandEncoder({label:"Frame Command Encoder"});this.lightingManager.update(i),this.renderPassComposer.render(i),this.texturesDebugContainer.setTextureGBufferSection(W.Albedo,this.renderPassComposer.getTexture(Ct)).setTextureGBufferSection(W.Normal,this.renderPassComposer.getTexture(ut)).setTextureGBufferSection(W.Metallic,this.renderPassComposer.getTexture(ut)).setTextureGBufferSection(W.Roughness,this.renderPassComposer.getTexture(ut)).setTextureGBufferSection(W.Reflectance,this.renderPassComposer.getTexture(Ct)).setTextureGBufferSection(W.Depth,this.renderPassComposer.getTexture(Te)).setTextureGBufferSection(W.Velocity,this.renderPassComposer.getTexture($i)).setTextureShadowSection(W.ShadowDepthCascade0,this.renderPassComposer.getTexture(Vr)).setTextureShadowSection(W.ShadowDepthCascade1,this.renderPassComposer.getTexture(Vr)).render(i),A.device.queue.submit([i.finish()]),this.renderPassComposer.onFrameEnd(),this.mainCamera.onFrameEnd(),this.debugCamera.onFrameEnd();const o=performance.now()-n;if(A.supportsGPUTimestampQuery){const[y,d]=await Promise.all([this.renderPassComposer.getPass(V.Shadow).getTimingResult(),this.renderPassComposer.getPass(V.Blit).getTimingResult()]),x=y.timings,b=(d.timings[1]-x[0])/1e6;this.gpuAverage.addSample(b)}this.cpuAverage.addSample(o),this.fpsDisplayAverage.addSample(1/r);const u=this.cpuAverage.get(),l=this.fpsDisplayAverage.get(),m=this.gpuAverage.get();this.mainCameraCtrl.speed=l>70?20:40,A.supportsGPUTimestampQuery&&this.timingDebugContainer.setDisplayValue(se.GPUTotal,m>0?`${m.toFixed(1)}ms`:"N/A"),this.timingDebugContainer.setDisplayValue(se.CPUTotal,u!==0?`${u.toFixed(1)}ms`:"N/A").setDisplayValue(se.FPS,l!==0?`${l.toFixed(1)}ms`:"N/A").setDisplayValue(se.VRAM,X.getFormattedSize()).setDisplayValue(se.VisibleMeshes,`${this.scene.visibleNodesCount} / ${this.scene.nodesCount}`).setDisplayValue(se.LightsCount,this.lightingManager.lightsCount.toString()),A.frameIndex++}};yn.initialize=async e=>{if(!navigator.gpu)return;const t=await navigator.gpu.requestAdapter();return A.$canvas=e,A.canvasContext=e.getContext("webgpu"),A.pixelFormat=navigator.gpu.getPreferredCanvasFormat(),A.device=await t.requestDevice({requiredFeatures:[]}),A.supportsGPUTimestampQuery=!1,A.canvasContext.configure({device:A.device,format:A.pixelFormat,usage:GPUTextureUsage.RENDER_ATTACHMENT}),new yn};let Qt=yn;const qr=document.getElementById("c"),ue=await Qt.initialize(qr);if(ue===void 0){document.getElementById("no-webgpu-wrapper").style.setProperty("display","block"),document.getElementById("loader").classList.toggle("faded");const s=document.createElement("img");s.src="no-webgpu.png",document.getElementById("no-webgpu-preview").appendChild(s)}const ie={"Play Animation":!0,"Performance Stats":!1,"Enable TAA":!0,"Debug G-Buffer":!1,"Debug Shadow Map":!1,"Debug Shadow Cascades":!1,"Shadow Map Size":2048,"Debug Point Lights Mask":!1,"Render 2nd Floor Points":!0,"Enable SSR":!0,"SSR Method":"hi-z","SSR Max Iterations":30,"Debug No Info Rays":!1,"Sun Intensity":2,"Sun Position X":.1,"Sun Position Y":100,"Sun Position Z":.1,"Debug Skybox":!0,"Enable Bloom":!0,"Bloom Filter Radius":.0035,"Enable SSAO":!0,"SSAO Kernel Size":64,"SSAO Radius":.5,"SSAO Strength":2},Qr=new Rr(2e3);let Wc=0,qc=!1,Qc=!1,cn=!1,Zc=!1,el=!1;function tl(){const s=innerWidth,e=innerHeight,t=Math.min(devicePixelRatio,1.5);qr.width=s*t,qr.height=e*t,qr.style.setProperty("width",`${s}px`),qr.style.setProperty("height",`${e}px`),ue.resize(s*t,e*t)}function rl(){document.getElementById("logo").classList.toggle("faded"),document.getElementById("timings-debug-container").classList.toggle("faded")}ue.onIntroAnimComplete=function(){const s=new Bl({width:270});s.close(),s.add(ie,"Play Animation").onChange(l=>{ue.enableAnimation=l}),s.add(ie,"Performance Stats").onChange(()=>{ue.toggleStatsVisibility()}),s.add(ie,"Debug G-Buffer").onChange(l=>{ue.debugGBuffer=l,rl(),l&&ie["Debug Shadow Map"]&&(ie["Debug Shadow Map"]=!1)}).listen();const e=s.addFolder("Lighting");e.open(),e.add(ie,"Sun Intensity",0,100).onChange(l=>{ue.sunIntensity=l}),e.add(ie,"Sun Position X",-60,60,.5).onChange(l=>{ue.sunPositionZ=l}),e.add(ie,"Sun Position Z",-150,150,.5).onChange(l=>{ue.sunPositionX=l});const t=s.addFolder("Shadow");t.open(),t.add(ie,"Debug Shadow Map").onChange(l=>{ue.debugShadowMap=l,rl(),l&&ie["Debug G-Buffer"]&&(ie["Debug G-Buffer"]=!1)}).listen(),t.add(ie,"Shadow Map Size",[512,1024,2048,4096]).onChange(l=>{ue.shadowMapSize=parseInt(l)}),t.add(ie,"Debug Shadow Cascades").onChange(l=>{ue.debugShadowCascadeIndex=l});let r=ie["Enable Bloom"];e.add(ie,"Debug Point Lights Mask").onChange(l=>{l?(r=ie["Enable Bloom"],ie["Enable Bloom"]=!1,cn=!0,ue.bloomEnabled=!1):r&&(ie["Enable Bloom"]=!0,cn=!0,ue.bloomEnabled=!0),ue.debugLightsMask=l}),e.add(ie,"Render 2nd Floor Points").onChange(l=>{ue.render2ndFloorPoints=l});const n=s.addFolder("Screen space Ambient Occlusion");n.open(),n.add(ie,"Enable SSAO").onChange(l=>{el=!0,ue.ssaoEnabled=l}),n.add(ie,"SSAO Kernel Size",8,128,1).onChange(l=>{ue.ssaoKernelSize=l}),n.add(ie,"SSAO Radius",0,1).onChange(l=>{ue.ssaoRadius=l}),n.add(ie,"SSAO Strength",0,5).onChange(l=>{ue.ssaoStrength=l});const i=s.addFolder("Screen space Reflections");i.open(),i.add(ie,"Enable SSR").onChange(l=>{ue.ssrEnabled=l,qc=!0}),i.add(ie,"SSR Method",["hi-z","linear"]).onChange(l=>{ue.ssrIsHiZ=l==="hi-z"}),i.add(ie,"SSR Max Iterations",0,1500,1).onChange(l=>{ue.ssrMaxIterations=l}),i.add(ie,"Debug No Info Rays").onChange(l=>{ue.debugMissedSSR=l});const o=s.addFolder("Bloom");o.open(),o.add(ie,"Enable Bloom").onChange(l=>{cn=!0,ue.bloomEnabled=l}).listen(),o.add(ie,"Bloom Filter Radius",.001,.005,5e-4).onChange(l=>{ue.bloomFilterRadius=l});const u=s.addFolder("Anti-Aliasing");u.open(),u.add(ie,"Enable TAA").onChange(l=>{ue.enableTAA=l})},requestAnimationFrame(function s(){const e=performance.now(),t=(e-Wc)/1e3;Wc=e,Qr.addSample(1/t);const r=Qr.get();ie["Enable SSR"]&&!qc&&Qr.getSamplesCount()>70&&r<60&&(console.log("1. performance too low. disabling ssr"),ie["Enable SSR"]=!1,ue.ssrEnabled=!1,Qc=!0),ie["Enable Bloom"]&&!cn&&Qc&&Qr.getSamplesCount()>70&&r<60&&(console.log("2. performance still too low. disabling bloom"),ie["Enable Bloom"]=!1,ue.bloomEnabled=!1,Zc=!0),ie["Enable SSAO"]&&!el&&Zc&&Qr.getSamplesCount()>70&&r<60&&(console.log("3. performance still too low. disabling ssao"),ie["Enable SSAO"]=!1,ue.ssaoEnabled=!1),ue.renderFrame(e),requestAnimationFrame(s)}),window.addEventListener("resize",tl),tl()})(); diff --git a/docs/assets/index-BZLAT-kz.js.gz b/docs/assets/index-BZLAT-kz.js.gz new file mode 100644 index 0000000..659cd5f Binary files /dev/null and b/docs/assets/index-BZLAT-kz.js.gz differ diff --git a/docs/assets/index-CYLuyR0P.js b/docs/assets/index-CYLuyR0P.js deleted file mode 100644 index 0916451..0000000 --- a/docs/assets/index-CYLuyR0P.js +++ /dev/null @@ -1,2287 +0,0 @@ -var Wp=Object.defineProperty;var $p=(ke,$e,qe)=>$e in ke?Wp(ke,$e,{enumerable:!0,configurable:!0,writable:!0,value:qe}):ke[$e]=qe;var ee=(ke,$e,qe)=>$p(ke,typeof $e!="symbol"?$e+"":$e,qe);(async()=>{var zc,jc;function ke(s,e){var t=s.__state.conversionName.toString(),r=Math.round(s.r),n=Math.round(s.g),i=Math.round(s.b),o=s.a,u=Math.round(s.h),l=s.s.toFixed(1),m=s.v.toFixed(1);if(e||t==="THREE_CHAR_HEX"||t==="SIX_CHAR_HEX"){for(var b=s.hex.toString(16);b.length<6;)b="0"+b;return"#"+b}return t==="CSS_RGB"?"rgb("+r+","+n+","+i+")":t==="CSS_RGBA"?"rgba("+r+","+n+","+i+","+o+")":t==="HEX"?"0x"+s.hex.toString(16):t==="RGB_ARRAY"?"["+r+","+n+","+i+"]":t==="RGBA_ARRAY"?"["+r+","+n+","+i+","+o+"]":t==="RGB_OBJ"?"{r:"+r+",g:"+n+",b:"+i+"}":t==="RGBA_OBJ"?"{r:"+r+",g:"+n+",b:"+i+",a:"+o+"}":t==="HSV_OBJ"?"{h:"+u+",s:"+l+",v:"+m+"}":t==="HSVA_OBJ"?"{h:"+u+",s:"+l+",v:"+m+",a:"+o+"}":"unknown format"}(function(){const s=document.createElement("link").relList;if(!(s&&s.supports&&s.supports("modulepreload"))){for(const t of document.querySelectorAll('link[rel="modulepreload"]'))e(t);new MutationObserver(t=>{for(const r of t)if(r.type==="childList")for(const n of r.addedNodes)n.tagName==="LINK"&&n.rel==="modulepreload"&&e(n)}).observe(document,{childList:!0,subtree:!0})}function e(t){if(t.ep)return;t.ep=!0;const r=function(n){const i={};return n.integrity&&(i.integrity=n.integrity),n.referrerPolicy&&(i.referrerPolicy=n.referrerPolicy),n.crossOrigin==="use-credentials"?i.credentials="include":n.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}(t);fetch(t.href,r)}})();var $e=Array.prototype.forEach,qe=Array.prototype.slice,V={BREAK:{},extend:function(s){return this.each(qe.call(arguments,1),function(e){(this.isObject(e)?Object.keys(e):[]).forEach((function(t){this.isUndefined(e[t])||(s[t]=e[t])}).bind(this))},this),s},defaults:function(s){return this.each(qe.call(arguments,1),function(e){(this.isObject(e)?Object.keys(e):[]).forEach((function(t){this.isUndefined(s[t])&&(s[t]=e[t])}).bind(this))},this),s},compose:function(){var s=qe.call(arguments);return function(){for(var e=qe.call(arguments),t=s.length-1;t>=0;t--)e=[s[t].apply(this,e)];return e[0]}},each:function(s,e,t){if(s){if($e&&s.forEach&&s.forEach===$e)s.forEach(e,t);else if(s.length===s.length+0){var r,n=void 0;for(n=0,r=s.length;n1?V.toArray(arguments):arguments[0];return V.each($c,function(e){if(e.litmus(s))return V.each(e.conversions,function(t,r){if(br=t.read(s),Kr===!1&&br!==!1)return Kr=br,br.conversionName=r,br.conversion=t,V.BREAK}),V.BREAK}),Kr},po=void 0,Xr={hsv_to_rgb:function(s,e,t){var r=Math.floor(s/60)%6,n=s/60-Math.floor(s/60),i=t*(1-e),o=t*(1-n*e),u=t*(1-(1-n)*e),l=[[t,u,i],[o,t,i],[i,t,u],[i,o,t],[u,i,t],[t,i,o]][r];return{r:255*l[0],g:255*l[1],b:255*l[2]}},rgb_to_hsv:function(s,e,t){var r=Math.min(s,e,t),n=Math.max(s,e,t),i=n-r,o=void 0;return n===0?{h:NaN,s:0,v:0}:(o=s===n?(e-t)/i:e===n?2+(t-s)/i:4+(s-e)/i,(o/=6)<0&&(o+=1),{h:360*o,s:i/n,v:n/255})},rgb_to_hex:function(s,e,t){var r=this.hex_with_component(0,2,s);return r=this.hex_with_component(r,1,e),r=this.hex_with_component(r,0,t)},component_from_hex:function(s,e){return s>>8*e&255},hex_with_component:function(s,e,t){return t<<(po=8*e)|s&~(255<-1?e.length-e.indexOf(".")-1:0}var bo=function(){function s(e,t,r){ze(this,s);var n=gt(this,(s.__proto__||Object.getPrototypeOf(s)).call(this,e,t)),i=r||{};return n.__min=i.min,n.__max=i.max,n.__step=i.step,V.isUndefined(n.__step)?n.initialValue===0?n.__impliedStep=1:n.__impliedStep=Math.pow(10,Math.floor(Math.log(Math.abs(n.initialValue))/Math.LN10))/10:n.__impliedStep=n.__step,n.__precision=yo(n.__impliedStep),n}return mt(s,Mt),je(s,[{key:"setValue",value:function(e){var t=e;return this.__min!==void 0&&tthis.__max&&(t=this.__max),this.__step!==void 0&&t%this.__step!=0&&(t=Math.round(t/this.__step)*this.__step),pt(s.prototype.__proto__||Object.getPrototypeOf(s.prototype),"setValue",this).call(this,t)}},{key:"min",value:function(e){return this.__min=e,this}},{key:"max",value:function(e){return this.__max=e,this}},{key:"step",value:function(e){return this.__step=e,this.__impliedStep=e,this.__precision=yo(e),this}}]),s}(),Yr=function(){function s(e,t,r){ze(this,s);var n=gt(this,(s.__proto__||Object.getPrototypeOf(s)).call(this,e,t,r));n.__truncationSuspended=!1;var i=n,o=void 0;function u(){i.__onFinishChange&&i.__onFinishChange.call(i,i.getValue())}function l(b){var d=o-b.clientY;i.setValue(i.getValue()+d*i.__impliedStep),o=b.clientY}function m(){I.unbind(window,"mousemove",l),I.unbind(window,"mouseup",m),u()}return n.__input=document.createElement("input"),n.__input.setAttribute("type","text"),I.bind(n.__input,"change",function(){var b=parseFloat(i.__input.value);V.isNaN(b)||i.setValue(b)}),I.bind(n.__input,"blur",function(){u()}),I.bind(n.__input,"mousedown",function(b){I.bind(window,"mousemove",l),I.bind(window,"mouseup",m),o=b.clientY}),I.bind(n.__input,"keydown",function(b){b.keyCode===13&&(i.__truncationSuspended=!0,this.blur(),i.__truncationSuspended=!1,u())}),n.updateDisplay(),n.domElement.appendChild(n.__input),n}return mt(s,bo),je(s,[{key:"updateDisplay",value:function(){var e,t,r;return this.__input.value=this.__truncationSuspended?this.getValue():(e=this.getValue(),t=this.__precision,r=Math.pow(10,t),Math.round(e*r)/r),pt(s.prototype.__proto__||Object.getPrototypeOf(s.prototype),"updateDisplay",this).call(this)}}]),s}();function xo(s,e,t,r,n){return r+(s-e)/(t-e)*(n-r)}var _n=function(){function s(e,t,r,n,i){ze(this,s);var o=gt(this,(s.__proto__||Object.getPrototypeOf(s)).call(this,e,t,{min:r,max:n,step:i})),u=o;function l(x){x.preventDefault();var g=u.__background.getBoundingClientRect();return u.setValue(xo(x.clientX,g.left,g.right,u.__min,u.__max)),!1}function m(){I.unbind(window,"mousemove",l),I.unbind(window,"mouseup",m),u.__onFinishChange&&u.__onFinishChange.call(u,u.getValue())}function b(x){var g=x.touches[0].clientX,_=u.__background.getBoundingClientRect();u.setValue(xo(g,_.left,_.right,u.__min,u.__max))}function d(){I.unbind(window,"touchmove",b),I.unbind(window,"touchend",d),u.__onFinishChange&&u.__onFinishChange.call(u,u.getValue())}return o.__background=document.createElement("div"),o.__foreground=document.createElement("div"),I.bind(o.__background,"mousedown",function(x){document.activeElement.blur(),I.bind(window,"mousemove",l),I.bind(window,"mouseup",m),l(x)}),I.bind(o.__background,"touchstart",function(x){x.touches.length===1&&(I.bind(window,"touchmove",b),I.bind(window,"touchend",d),b(x))}),I.addClass(o.__background,"slider"),I.addClass(o.__foreground,"slider-fg"),o.updateDisplay(),o.__background.appendChild(o.__foreground),o.domElement.appendChild(o.__background),o}return mt(s,bo),je(s,[{key:"updateDisplay",value:function(){var e=(this.getValue()-this.__min)/(this.__max-this.__min);return this.__foreground.style.width=100*e+"%",pt(s.prototype.__proto__||Object.getPrototypeOf(s.prototype),"updateDisplay",this).call(this)}}]),s}(),_o=function(){function s(e,t,r){ze(this,s);var n=gt(this,(s.__proto__||Object.getPrototypeOf(s)).call(this,e,t)),i=n;return n.__button=document.createElement("div"),n.__button.innerHTML=r===void 0?"Fire":r,I.bind(n.__button,"click",function(o){return o.preventDefault(),i.fire(),!1}),I.addClass(n.__button,"button"),n.domElement.appendChild(n.__button),n}return mt(s,Mt),je(s,[{key:"fire",value:function(){this.__onChange&&this.__onChange.call(this),this.getValue().call(this.object),this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}}]),s}(),An=function(){function s(e,t){ze(this,s);var r=gt(this,(s.__proto__||Object.getPrototypeOf(s)).call(this,e,t));r.__color=new ye(r.getValue()),r.__temp=new ye(0);var n=r;r.domElement=document.createElement("div"),I.makeSelectable(r.domElement,!1),r.__selector=document.createElement("div"),r.__selector.className="selector",r.__saturation_field=document.createElement("div"),r.__saturation_field.className="saturation-field",r.__field_knob=document.createElement("div"),r.__field_knob.className="field-knob",r.__field_knob_border="2px solid ",r.__hue_knob=document.createElement("div"),r.__hue_knob.className="hue-knob",r.__hue_field=document.createElement("div"),r.__hue_field.className="hue-field",r.__input=document.createElement("input"),r.__input.type="text",r.__input_textShadow="0 1px 1px ",I.bind(r.__input,"keydown",function(w){w.keyCode===13&&d.call(this)}),I.bind(r.__input,"blur",d),I.bind(r.__selector,"mousedown",function(){I.addClass(this,"drag").bind(window,"mouseup",function(){I.removeClass(n.__selector,"drag")})}),I.bind(r.__selector,"touchstart",function(){I.addClass(this,"drag").bind(window,"touchend",function(){I.removeClass(n.__selector,"drag")})});var i,o=document.createElement("div");function u(w){g(w),I.bind(window,"mousemove",g),I.bind(window,"touchmove",g),I.bind(window,"mouseup",m),I.bind(window,"touchend",m)}function l(w){_(w),I.bind(window,"mousemove",_),I.bind(window,"touchmove",_),I.bind(window,"mouseup",b),I.bind(window,"touchend",b)}function m(){I.unbind(window,"mousemove",g),I.unbind(window,"touchmove",g),I.unbind(window,"mouseup",m),I.unbind(window,"touchend",m),x()}function b(){I.unbind(window,"mousemove",_),I.unbind(window,"touchmove",_),I.unbind(window,"mouseup",b),I.unbind(window,"touchend",b),x()}function d(){var w=yn(this.value);w!==!1?(n.__color.__state=w,n.setValue(n.__color.toOriginal())):this.value=n.__color.toString()}function x(){n.__onFinishChange&&n.__onFinishChange.call(n,n.__color.toOriginal())}function g(w){w.type.indexOf("touch")===-1&&w.preventDefault();var f=n.__saturation_field.getBoundingClientRect(),p=w.touches&&w.touches[0]||w,a=p.clientX,c=p.clientY,h=(a-f.left)/(f.right-f.left),y=1-(c-f.top)/(f.bottom-f.top);return y>1?y=1:y<0&&(y=0),h>1?h=1:h<0&&(h=0),n.__color.v=y,n.__color.s=h,n.setValue(n.__color.toOriginal()),!1}function _(w){w.type.indexOf("touch")===-1&&w.preventDefault();var f=n.__hue_field.getBoundingClientRect(),p=1-((w.touches&&w.touches[0]||w).clientY-f.top)/(f.bottom-f.top);return p>1?p=1:p<0&&(p=0),n.__color.h=360*p,n.setValue(n.__color.toOriginal()),!1}return V.extend(r.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"}),V.extend(r.__field_knob.style,{position:"absolute",width:"12px",height:"12px",border:r.__field_knob_border+(r.__color.v<.5?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1}),V.extend(r.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1}),V.extend(r.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"}),V.extend(o.style,{width:"100%",height:"100%",background:"none"}),Ao(o,"top","rgba(0,0,0,0)","#000"),V.extend(r.__hue_field.style,{width:"15px",height:"100px",border:"1px solid #555",cursor:"ns-resize",position:"absolute",top:"3px",right:"3px"}),(i=r.__hue_field).style.background="",i.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);",i.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",i.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",i.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",i.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",V.extend(r.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:r.__input_textShadow+"rgba(0,0,0,0.7)"}),I.bind(r.__saturation_field,"mousedown",u),I.bind(r.__saturation_field,"touchstart",u),I.bind(r.__field_knob,"mousedown",u),I.bind(r.__field_knob,"touchstart",u),I.bind(r.__hue_field,"mousedown",l),I.bind(r.__hue_field,"touchstart",l),r.__saturation_field.appendChild(o),r.__selector.appendChild(r.__field_knob),r.__selector.appendChild(r.__saturation_field),r.__selector.appendChild(r.__hue_field),r.__hue_field.appendChild(r.__hue_knob),r.domElement.appendChild(r.__input),r.domElement.appendChild(r.__selector),r.updateDisplay(),r}return mt(s,Mt),je(s,[{key:"updateDisplay",value:function(){var e=yn(this.getValue());if(e!==!1){var t=!1;V.each(ye.COMPONENTS,function(i){if(!V.isUndefined(e[i])&&!V.isUndefined(this.__color.__state[i])&&e[i]!==this.__color.__state[i])return t=!0,{}},this),t&&V.extend(this.__color.__state,e)}V.extend(this.__temp.__state,this.__color.__state),this.__temp.a=1;var r=this.__color.v<.5||this.__color.s>.5?255:0,n=255-r;V.extend(this.__field_knob.style,{marginLeft:100*this.__color.s-7+"px",marginTop:100*(1-this.__color.v)-7+"px",backgroundColor:this.__temp.toHexString(),border:this.__field_knob_border+"rgb("+r+","+r+","+r+")"}),this.__hue_knob.style.marginTop=100*(1-this.__color.h/360)+"px",this.__temp.s=1,this.__temp.v=1,Ao(this.__saturation_field,"left","#fff",this.__temp.toHexString()),this.__input.value=this.__color.toString(),V.extend(this.__input.style,{backgroundColor:this.__color.toHexString(),color:"rgb("+r+","+r+","+r+")",textShadow:this.__input_textShadow+"rgba("+n+","+n+","+n+",.7)"})}}]),s}(),tl=["-moz-","-o-","-webkit-","-ms-",""];function Ao(s,e,t,r){s.style.background="",V.each(tl,function(n){s.style.cssText+="background: "+n+"linear-gradient("+e+", "+t+" 0%, "+r+" 100%); "})}var rl=function(s,e){var t=e||document,r=document.createElement("style");r.type="text/css",r.innerHTML=s;var n=t.getElementsByTagName("head")[0];try{n.appendChild(r)}catch{}},sl=function(s,e){var t=s[e];return V.isArray(arguments[2])||V.isObject(arguments[2])?new Zc(s,e,arguments[2]):V.isNumber(t)?V.isNumber(arguments[2])&&V.isNumber(arguments[3])?V.isNumber(arguments[4])?new _n(s,e,arguments[2],arguments[3],arguments[4]):new _n(s,e,arguments[2],arguments[3]):V.isNumber(arguments[4])?new Yr(s,e,{min:arguments[2],max:arguments[3],step:arguments[4]}):new Yr(s,e,{min:arguments[2],max:arguments[3]}):V.isString(t)?new el(s,e):V.isFunction(t)?new _o(s,e,""):V.isBoolean(t)?new go(s,e):null},nl=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(s){setTimeout(s,1e3/60)},il=function(){function s(){ze(this,s),this.backgroundElement=document.createElement("div"),V.extend(this.backgroundElement.style,{backgroundColor:"rgba(0,0,0,0.8)",top:0,left:0,display:"none",zIndex:"1000",opacity:0,WebkitTransition:"opacity 0.2s linear",transition:"opacity 0.2s linear"}),I.makeFullscreen(this.backgroundElement),this.backgroundElement.style.position="fixed",this.domElement=document.createElement("div"),V.extend(this.domElement.style,{position:"fixed",display:"none",zIndex:"1001",opacity:0,WebkitTransition:"-webkit-transform 0.2s ease-out, opacity 0.2s linear",transition:"transform 0.2s ease-out, opacity 0.2s linear"}),document.body.appendChild(this.backgroundElement),document.body.appendChild(this.domElement);var e=this;I.bind(this.backgroundElement,"click",function(){e.hide()})}return je(s,[{key:"show",value:function(){var e=this;this.backgroundElement.style.display="block",this.domElement.style.display="block",this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)",this.layout(),V.defer(function(){e.backgroundElement.style.opacity=1,e.domElement.style.opacity=1,e.domElement.style.webkitTransform="scale(1)"})}},{key:"hide",value:function(){var e=this,t=function r(){e.domElement.style.display="none",e.backgroundElement.style.display="none",I.unbind(e.domElement,"webkitTransitionEnd",r),I.unbind(e.domElement,"transitionend",r),I.unbind(e.domElement,"oTransitionEnd",r)};I.bind(this.domElement,"webkitTransitionEnd",t),I.bind(this.domElement,"transitionend",t),I.bind(this.domElement,"oTransitionEnd",t),this.backgroundElement.style.opacity=0,this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)"}},{key:"layout",value:function(){this.domElement.style.left=window.innerWidth/2-I.getWidth(this.domElement)/2+"px",this.domElement.style.top=window.innerHeight/2-I.getHeight(this.domElement)/2+"px"}}]),s}(),ol=function(s){if(typeof window<"u"){var e=document.createElement("style");return e.setAttribute("type","text/css"),e.innerHTML=s,document.head.appendChild(e),s}}(`.dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li>*{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .cr.function .property-name{width:100%}.dg .c{float:left;width:60%;position:relative}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:7px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .cr.color{overflow:visible}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.color{border-left:3px solid}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2FA1D6}.dg .cr.number input[type=text]{color:#2FA1D6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2FA1D6;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda} -`);rl(ol);var xr="Default",_r=function(){try{return!!window.localStorage}catch{return!1}}(),Wr=void 0,Bo=!0,Wt=void 0,Bn=!1,vo=[],le=function s(e){var t=this,r=e||{};this.domElement=document.createElement("div"),this.__ul=document.createElement("ul"),this.domElement.appendChild(this.__ul),I.addClass(this.domElement,"dg"),this.__folders={},this.__controllers=[],this.__rememberedObjects=[],this.__rememberedObjectIndecesToControllers=[],this.__listening=[],r=V.defaults(r,{closeOnTop:!1,autoPlace:!0,width:s.DEFAULT_WIDTH}),r=V.defaults(r,{resizable:r.autoPlace,hideable:r.autoPlace}),V.isUndefined(r.load)?r.load={preset:xr}:r.preset&&(r.load.preset=r.preset),V.isUndefined(r.parent)&&r.hideable&&vo.push(this),r.resizable=V.isUndefined(r.parent)&&r.resizable,r.autoPlace&&V.isUndefined(r.scrollable)&&(r.scrollable=!0);var n,i=_r&&localStorage.getItem($t(this,"isLocal"))==="true",o=void 0,u=void 0;if(Object.defineProperties(this,{parent:{get:function(){return r.parent}},scrollable:{get:function(){return r.scrollable}},autoPlace:{get:function(){return r.autoPlace}},closeOnTop:{get:function(){return r.closeOnTop}},preset:{get:function(){return t.parent?t.getRoot().preset:r.load.preset},set:function(b){t.parent?t.getRoot().preset=b:r.load.preset=b,function(d){for(var x=0;x1){var w=d.__li.nextElementSibling;return d.remove(),Ar(m,d.object,d.property,{before:w,factoryArgs:[V.toArray(arguments)]})}if(V.isArray(_)||V.isObject(_)){var f=d.__li.nextElementSibling;return d.remove(),Ar(m,d.object,d.property,{before:f,factoryArgs:[_]})}},name:function(_){return d.__li.firstElementChild.firstElementChild.innerHTML=_,d},listen:function(){return d.__gui.listen(d),d},remove:function(){return d.__gui.remove(d),d}}),d instanceof _n){var x=new Yr(d.object,d.property,{min:d.__min,max:d.__max,step:d.__step});V.each(["updateDisplay","onChange","onFinishChange","step","min","max"],function(_){var w=d[_],f=x[_];d[_]=x[_]=function(){var p=Array.prototype.slice.call(arguments);return f.apply(x,p),w.apply(d,p)}}),I.addClass(b,"has-slider"),d.domElement.insertBefore(x.domElement,d.domElement.firstElementChild)}else if(d instanceof Yr){var g=function(_){if(V.isNumber(d.__min)&&V.isNumber(d.__max)){var w=d.__li.firstElementChild.firstElementChild.innerHTML,f=d.__gui.__listening.indexOf(d)>-1;d.remove();var p=Ar(m,d.object,d.property,{before:d.__li.nextElementSibling,factoryArgs:[d.__min,d.__max,d.__step]});return p.name(w),f&&p.listen(),p}return _};d.min=V.compose(g,d.min),d.max=V.compose(g,d.max)}else d instanceof go?(I.bind(b,"click",function(){I.fakeEvent(d.__checkbox,"click")}),I.bind(d.__checkbox,"click",function(_){_.stopPropagation()})):d instanceof _o?(I.bind(b,"click",function(){I.fakeEvent(d.__button,"click")}),I.bind(b,"mouseover",function(){I.addClass(d.__button,"hover")}),I.bind(b,"mouseout",function(){I.removeClass(d.__button,"hover")})):d instanceof An&&(I.addClass(b,"color"),d.updateDisplay=V.compose(function(_){return b.style.borderLeftColor=d.__color.toString(),_},d.updateDisplay),d.updateDisplay());d.setValue=V.compose(function(_){return m.getRoot().__preset_select&&d.isModified()&&wn(m.getRoot(),!0),_},d.setValue)}(s,l,n),s.__controllers.push(n),n}function $t(s,e){return document.location.href+"."+e}function Cn(s,e,t){var r=document.createElement("option");r.innerHTML=e,r.value=e,s.__preset_select.appendChild(r),t&&(s.__preset_select.selectedIndex=s.__preset_select.length-1)}function To(s,e){e.style.display=s.useLocalStorage?"block":"none"}function al(s){var e=void 0;function t(i){return i.preventDefault(),s.width+=e-i.clientX,s.onResize(),e=i.clientX,!1}function r(){I.removeClass(s.__closeButton,le.CLASS_DRAG),I.unbind(window,"mousemove",t),I.unbind(window,"mouseup",r)}function n(i){return i.preventDefault(),e=i.clientX,I.addClass(s.__closeButton,le.CLASS_DRAG),I.bind(window,"mousemove",t),I.bind(window,"mouseup",r),!1}s.__resize_handle=document.createElement("div"),V.extend(s.__resize_handle.style,{width:"6px",marginLeft:"-3px",height:"200px",cursor:"ew-resize",position:"absolute"}),I.bind(s.__resize_handle,"mousedown",n),I.bind(s.__closeButton,"mousedown",n),s.domElement.insertBefore(s.__resize_handle,s.domElement.firstElementChild)}function Tn(s,e){s.domElement.style.width=e+"px",s.__save_row&&s.autoPlace&&(s.__save_row.style.width=e+"px"),s.__closeButton&&(s.__closeButton.style.width=e+"px")}function $r(s,e){var t={};return V.each(s.__rememberedObjects,function(r,n){var i={},o=s.__rememberedObjectIndecesToControllers[n];V.each(o,function(u,l){i[l]=e?u.initialValue:u.getValue()}),t[n]=i}),t}function So(s){s.length!==0&&nl.call(window,function(){So(s)}),V.each(s,function(e){e.updateDisplay()})}le.toggleHide=function(){Bn=!Bn,V.each(vo,function(s){s.domElement.style.display=Bn?"none":""})},le.CLASS_AUTO_PLACE="a",le.CLASS_AUTO_PLACE_CONTAINER="ac",le.CLASS_MAIN="main",le.CLASS_CONTROLLER_ROW="cr",le.CLASS_TOO_TALL="taller-than-window",le.CLASS_CLOSED="closed",le.CLASS_CLOSE_BUTTON="close-button",le.CLASS_CLOSE_TOP="close-top",le.CLASS_CLOSE_BOTTOM="close-bottom",le.CLASS_DRAG="drag",le.DEFAULT_WIDTH=245,le.TEXT_CLOSED="Close Controls",le.TEXT_OPEN="Open Controls",le._keydownHandler=function(s){document.activeElement.type==="text"||s.which!==72&&s.keyCode!==72||le.toggleHide()},I.bind(window,"keydown",le._keydownHandler,!1),V.extend(le.prototype,{add:function(s,e){return Ar(this,s,e,{factoryArgs:Array.prototype.slice.call(arguments,2)})},addColor:function(s,e){return Ar(this,s,e,{color:!0})},remove:function(s){this.__ul.removeChild(s.__li),this.__controllers.splice(this.__controllers.indexOf(s),1);var e=this;V.defer(function(){e.onResize()})},destroy:function(){if(this.parent)throw new Error("Only the root GUI should be removed with .destroy(). For subfolders, use gui.removeFolder(folder) instead.");this.autoPlace&&Wt.removeChild(this.domElement);var s=this;V.each(this.__folders,function(e){s.removeFolder(e)}),I.unbind(window,"keydown",le._keydownHandler,!1),wo(this)},addFolder:function(s){if(this.__folders[s]!==void 0)throw new Error('You already have a folder in this GUI by the name "'+s+'"');var e={name:s,parent:this};e.autoPlace=this.autoPlace,this.load&&this.load.folders&&this.load.folders[s]&&(e.closed=this.load.folders[s].closed,e.load=this.load.folders[s]);var t=new le(e);this.__folders[s]=t;var r=vn(this,t.domElement);return I.addClass(r,"folder"),t},removeFolder:function(s){this.__ul.removeChild(s.domElement.parentElement),delete this.__folders[s.name],this.load&&this.load.folders&&this.load.folders[s.name]&&delete this.load.folders[s.name],wo(s);var e=this;V.each(s.__folders,function(t){s.removeFolder(t)}),V.defer(function(){e.onResize()})},open:function(){this.closed=!1},close:function(){this.closed=!0},hide:function(){this.domElement.style.display="none"},show:function(){this.domElement.style.display=""},onResize:function(){var s=this.getRoot();if(s.scrollable){var e=I.getOffset(s.__ul).top,t=0;V.each(s.__ul.childNodes,function(r){s.autoPlace&&r===s.__save_row||(t+=I.getHeight(r))}),window.innerHeight-e-20 - - Here's the new load parameter for your GUI's constructor: - - - -
- - Automatically save - values to localStorage on exit. - -
The values saved to localStorage will - override those passed to dat.GUI's constructor. This makes it - easier to work incrementally, but localStorage is fragile, - and your friends may not see the same values you do. - -
- -
- -`),this.parent)throw new Error("You can only call remember on a top level GUI.");var s=this;V.each(Array.prototype.slice.call(arguments),function(e){s.__rememberedObjects.length===0&&function(t){var r=t.__save_row=document.createElement("li");I.addClass(t.domElement,"has-save"),t.__ul.insertBefore(r,t.__ul.firstChild),I.addClass(r,"save-row");var n=document.createElement("span");n.innerHTML=" ",I.addClass(n,"button gears");var i=document.createElement("span");i.innerHTML="Save",I.addClass(i,"button"),I.addClass(i,"save");var o=document.createElement("span");o.innerHTML="New",I.addClass(o,"button"),I.addClass(o,"save-as");var u=document.createElement("span");u.innerHTML="Revert",I.addClass(u,"button"),I.addClass(u,"revert");var l=t.__preset_select=document.createElement("select");if(t.load&&t.load.remembered?V.each(t.load.remembered,function(x,g){Cn(t,g,g===t.preset)}):Cn(t,xr,!1),I.bind(l,"change",function(){for(var x=0;x0&&(s.preset=this.preset,s.remembered||(s.remembered={}),s.remembered[this.preset]=$r(this)),s.folders={},V.each(this.__folders,function(e,t){s.folders[t]=e.getSaveObject()}),s},save:function(){this.load.remembered||(this.load.remembered={}),this.load.remembered[this.preset]=$r(this),wn(this,!1),this.saveToLocalStorageIfPossible()},saveAs:function(s){this.load.remembered||(this.load.remembered={},this.load.remembered[xr]=$r(this,!0)),this.load.remembered[s]=$r(this),this.preset=s,Cn(this,s,!0),this.saveToLocalStorageIfPossible()},revert:function(s){V.each(this.__controllers,function(e){this.getRoot().load.remembered?Co(s||this.getRoot(),e):e.setValue(e.initialValue),e.__onFinishChange&&e.__onFinishChange.call(e,e.getValue())},this),V.each(this.__folders,function(e){e.revert(e)}),s||wn(this.getRoot(),!1)},listen:function(s){var e=this.__listening.length===0;this.__listening.push(s),e&&So(this.__listening)},updateDisplay:function(){V.each(this.__controllers,function(s){s.updateDisplay()}),V.each(this.__folders,function(s){s.updateDisplay()})}});var ul=le;const cl=(Eo=Array,Mo=s=>s.fill(0),class extends Eo{constructor(...s){super(...s),Mo(this)}});var Eo,Mo;let ne=1e-6;const Po=new Map;function Ro(s){let e=Po.get(s);return e||(e=function(t){function r(a=0,c=0){const h=new t(2);return a!==void 0&&(h[0]=a,c!==void 0&&(h[1]=c)),h}function n(a,c,h){const y=h??new t(2);return y[0]=a[0]-c[0],y[1]=a[1]-c[1],y}function i(a,c,h,y){const A=y??new t(2);return A[0]=a[0]+h*(c[0]-a[0]),A[1]=a[1]+h*(c[1]-a[1]),A}function o(a,c,h){const y=h??new t(2);return y[0]=a[0]*c,y[1]=a[1]*c,y}function u(a,c){const h=c??new t(2);return h[0]=1/a[0],h[1]=1/a[1],h}function l(a,c){return a[0]*c[0]+a[1]*c[1]}function m(a){const c=a[0],h=a[1];return Math.sqrt(c*c+h*h)}function b(a){const c=a[0],h=a[1];return c*c+h*h}function d(a,c){const h=a[0]-c[0],y=a[1]-c[1];return Math.sqrt(h*h+y*y)}function x(a,c){const h=a[0]-c[0],y=a[1]-c[1];return h*h+y*y}function g(a,c){const h=c??new t(2),y=a[0],A=a[1],C=Math.sqrt(y*y+A*A);return C>1e-5?(h[0]=y/C,h[1]=A/C):(h[0]=0,h[1]=0),h}function _(a,c){const h=c??new t(2);return h[0]=a[0],h[1]=a[1],h}function w(a,c,h){const y=h??new t(2);return y[0]=a[0]*c[0],y[1]=a[1]*c[1],y}function f(a,c,h){const y=h??new t(2);return y[0]=a[0]/c[0],y[1]=a[1]/c[1],y}function p(a,c,h){const y=h??new t(2);return g(a,y),o(y,c,y)}return{create:r,fromValues:r,set:function(a,c,h){const y=h??new t(2);return y[0]=a,y[1]=c,y},ceil:function(a,c){const h=c??new t(2);return h[0]=Math.ceil(a[0]),h[1]=Math.ceil(a[1]),h},floor:function(a,c){const h=c??new t(2);return h[0]=Math.floor(a[0]),h[1]=Math.floor(a[1]),h},round:function(a,c){const h=c??new t(2);return h[0]=Math.round(a[0]),h[1]=Math.round(a[1]),h},clamp:function(a,c=0,h=1,y){const A=y??new t(2);return A[0]=Math.min(h,Math.max(c,a[0])),A[1]=Math.min(h,Math.max(c,a[1])),A},add:function(a,c,h){const y=h??new t(2);return y[0]=a[0]+c[0],y[1]=a[1]+c[1],y},addScaled:function(a,c,h,y){const A=y??new t(2);return A[0]=a[0]+c[0]*h,A[1]=a[1]+c[1]*h,A},angle:function(a,c){const h=a[0],y=a[1],A=c[0],C=c[1],R=Math.sqrt(h*h+y*y)*Math.sqrt(A*A+C*C),U=R&&l(a,c)/R;return Math.acos(U)},subtract:n,sub:n,equalsApproximately:function(a,c){return Math.abs(a[0]-c[0])c?p(a,c,y):_(a,y)},midpoint:function(a,c,h){return i(a,c,.5,h??new t(2))}}}(s),Po.set(s,e)),e}const Go=new Map;function qr(s){let e=Go.get(s);return e||(e=function(t){function r(a,c,h){const y=new t(3);return a!==void 0&&(y[0]=a,c!==void 0&&(y[1]=c,h!==void 0&&(y[2]=h))),y}function n(a,c,h){const y=h??new t(3);return y[0]=a[0]-c[0],y[1]=a[1]-c[1],y[2]=a[2]-c[2],y}function i(a,c,h,y){const A=y??new t(3);return A[0]=a[0]+h*(c[0]-a[0]),A[1]=a[1]+h*(c[1]-a[1]),A[2]=a[2]+h*(c[2]-a[2]),A}function o(a,c,h){const y=h??new t(3);return y[0]=a[0]*c,y[1]=a[1]*c,y[2]=a[2]*c,y}function u(a,c){const h=c??new t(3);return h[0]=1/a[0],h[1]=1/a[1],h[2]=1/a[2],h}function l(a,c){return a[0]*c[0]+a[1]*c[1]+a[2]*c[2]}function m(a){const c=a[0],h=a[1],y=a[2];return Math.sqrt(c*c+h*h+y*y)}function b(a){const c=a[0],h=a[1],y=a[2];return c*c+h*h+y*y}function d(a,c){const h=a[0]-c[0],y=a[1]-c[1],A=a[2]-c[2];return Math.sqrt(h*h+y*y+A*A)}function x(a,c){const h=a[0]-c[0],y=a[1]-c[1],A=a[2]-c[2];return h*h+y*y+A*A}function g(a,c){const h=c??new t(3),y=a[0],A=a[1],C=a[2],R=Math.sqrt(y*y+A*A+C*C);return R>1e-5?(h[0]=y/R,h[1]=A/R,h[2]=C/R):(h[0]=0,h[1]=0,h[2]=0),h}function _(a,c){const h=c??new t(3);return h[0]=a[0],h[1]=a[1],h[2]=a[2],h}function w(a,c,h){const y=h??new t(3);return y[0]=a[0]*c[0],y[1]=a[1]*c[1],y[2]=a[2]*c[2],y}function f(a,c,h){const y=h??new t(3);return y[0]=a[0]/c[0],y[1]=a[1]/c[1],y[2]=a[2]/c[2],y}function p(a,c,h){const y=h??new t(3);return g(a,y),o(y,c,y)}return{create:r,fromValues:r,set:function(a,c,h,y){const A=y??new t(3);return A[0]=a,A[1]=c,A[2]=h,A},ceil:function(a,c){const h=c??new t(3);return h[0]=Math.ceil(a[0]),h[1]=Math.ceil(a[1]),h[2]=Math.ceil(a[2]),h},floor:function(a,c){const h=c??new t(3);return h[0]=Math.floor(a[0]),h[1]=Math.floor(a[1]),h[2]=Math.floor(a[2]),h},round:function(a,c){const h=c??new t(3);return h[0]=Math.round(a[0]),h[1]=Math.round(a[1]),h[2]=Math.round(a[2]),h},clamp:function(a,c=0,h=1,y){const A=y??new t(3);return A[0]=Math.min(h,Math.max(c,a[0])),A[1]=Math.min(h,Math.max(c,a[1])),A[2]=Math.min(h,Math.max(c,a[2])),A},add:function(a,c,h){const y=h??new t(3);return y[0]=a[0]+c[0],y[1]=a[1]+c[1],y[2]=a[2]+c[2],y},addScaled:function(a,c,h,y){const A=y??new t(3);return A[0]=a[0]+c[0]*h,A[1]=a[1]+c[1]*h,A[2]=a[2]+c[2]*h,A},angle:function(a,c){const h=a[0],y=a[1],A=a[2],C=c[0],R=c[1],U=c[2],k=Math.sqrt(h*h+y*y+A*A)*Math.sqrt(C*C+R*R+U*U),T=k&&l(a,c)/k;return Math.acos(T)},subtract:n,sub:n,equalsApproximately:function(a,c){return Math.abs(a[0]-c[0])c?p(a,c,y):_(a,y)},midpoint:function(a,c,h){return i(a,c,.5,h??new t(3))}}}(s),Go.set(s,e)),e}const Lo=new Map;function ll(s){let e=Lo.get(s);return e||(e=function(t){const r=Ro(t),n=qr(t);function i(d,x){const g=x??new t(12);return g[0]=d[0],g[1]=d[1],g[2]=d[2],g[4]=d[4],g[5]=d[5],g[6]=d[6],g[8]=d[8],g[9]=d[9],g[10]=d[10],g}function o(d){const x=d??new t(12);return x[0]=1,x[1]=0,x[2]=0,x[4]=0,x[5]=1,x[6]=0,x[8]=0,x[9]=0,x[10]=1,x}function u(d,x){const g=x??new t(12),_=d[0],w=d[1],f=d[2],p=d[4],a=d[5],c=d[6],h=d[8],y=d[9],A=d[10],C=A*a-c*y,R=-A*p+c*h,U=y*p-a*h,k=1/(_*C+w*R+f*U);return g[0]=C*k,g[1]=(-A*w+f*y)*k,g[2]=(c*w-f*a)*k,g[4]=R*k,g[5]=(A*_-f*h)*k,g[6]=(-c*_+f*p)*k,g[8]=U*k,g[9]=(-y*_+w*h)*k,g[10]=(a*_-w*p)*k,g}function l(d,x,g){const _=g??new t(12),w=d[0],f=d[1],p=d[2],a=d[4],c=d[5],h=d[6],y=d[8],A=d[9],C=d[10],R=x[0],U=x[1],k=x[2],T=x[4],S=x[5],P=x[6],L=x[8],F=x[9],O=x[10];return _[0]=w*R+a*U+y*k,_[1]=f*R+c*U+A*k,_[2]=p*R+h*U+C*k,_[4]=w*T+a*S+y*P,_[5]=f*T+c*S+A*P,_[6]=p*T+h*S+C*P,_[8]=w*L+a*F+y*O,_[9]=f*L+c*F+A*O,_[10]=p*L+h*F+C*O,_}function m(d,x){const g=x??new t(12),_=Math.cos(d),w=Math.sin(d);return g[0]=_,g[1]=w,g[2]=0,g[4]=-w,g[5]=_,g[6]=0,g[8]=0,g[9]=0,g[10]=1,g}function b(d,x,g){const _=g??new t(12),w=d[0],f=d[1],p=d[2],a=d[4],c=d[5],h=d[6],y=Math.cos(x),A=Math.sin(x);return _[0]=y*w+A*a,_[1]=y*f+A*c,_[2]=y*p+A*h,_[4]=y*a-A*w,_[5]=y*c-A*f,_[6]=y*h-A*p,d!==_&&(_[8]=d[8],_[9]=d[9],_[10]=d[10]),_}return{clone:i,create:function(d,x,g,_,w,f,p,a,c){const h=new t(12);return h[3]=0,h[7]=0,h[11]=0,d!==void 0&&(h[0]=d,x!==void 0&&(h[1]=x,g!==void 0&&(h[2]=g,_!==void 0&&(h[4]=_,w!==void 0&&(h[5]=w,f!==void 0&&(h[6]=f,p!==void 0&&(h[8]=p,a!==void 0&&(h[9]=a,c!==void 0&&(h[10]=c))))))))),h},set:function(d,x,g,_,w,f,p,a,c,h){const y=h??new t(12);return y[0]=d,y[1]=x,y[2]=g,y[3]=0,y[4]=_,y[5]=w,y[6]=f,y[7]=0,y[8]=p,y[9]=a,y[10]=c,y[11]=0,y},fromMat4:function(d,x){const g=x??new t(12);return g[0]=d[0],g[1]=d[1],g[2]=d[2],g[3]=0,g[4]=d[4],g[5]=d[5],g[6]=d[6],g[7]=0,g[8]=d[8],g[9]=d[9],g[10]=d[10],g[11]=0,g},fromQuat:function(d,x){const g=x??new t(12),_=d[0],w=d[1],f=d[2],p=d[3],a=_+_,c=w+w,h=f+f,y=_*a,A=w*a,C=w*c,R=f*a,U=f*c,k=f*h,T=p*a,S=p*c,P=p*h;return g[0]=1-C-k,g[1]=A+P,g[2]=R-S,g[3]=0,g[4]=A-P,g[5]=1-y-k,g[6]=U+T,g[7]=0,g[8]=R+S,g[9]=U-T,g[10]=1-y-C,g[11]=0,g},negate:function(d,x){const g=x??new t(12);return g[0]=-d[0],g[1]=-d[1],g[2]=-d[2],g[4]=-d[4],g[5]=-d[5],g[6]=-d[6],g[8]=-d[8],g[9]=-d[9],g[10]=-d[10],g},copy:i,equalsApproximately:function(d,x){return Math.abs(d[0]-x[0])ne){const pe=Math.acos(fe),ge=Math.sin(pe);j=Math.sin((1-P)*pe)/ge,z=Math.sin(P*pe)/ge}else j=1-P,z=P;return F[0]=j*O+z*q,F[1]=j*H+z*Z,F[2]=j*K+z*te,F[3]=j*X+z*re,F}function b(T,S){const P=S??new t(4);return P[0]=T[0],P[1]=T[1],P[2]=T[2],P[3]=T[3],P}const d=b;function x(T,S,P){const L=P??new t(4);return L[0]=T[0]-S[0],L[1]=T[1]-S[1],L[2]=T[2]-S[2],L[3]=T[3]-S[3],L}const g=x;function _(T,S,P){const L=P??new t(4);return L[0]=T[0]*S,L[1]=T[1]*S,L[2]=T[2]*S,L[3]=T[3]*S,L}const w=_;function f(T,S){return T[0]*S[0]+T[1]*S[1]+T[2]*S[2]+T[3]*S[3]}function p(T){const S=T[0],P=T[1],L=T[2],F=T[3];return Math.sqrt(S*S+P*P+L*L+F*F)}const a=p;function c(T){const S=T[0],P=T[1],L=T[2],F=T[3];return S*S+P*P+L*L+F*F}const h=c;function y(T,S){const P=S??new t(4),L=T[0],F=T[1],O=T[2],H=T[3],K=Math.sqrt(L*L+F*F+O*O+H*H);return K>1e-5?(P[0]=L/K,P[1]=F/K,P[2]=O/K,P[3]=H/K):(P[0]=0,P[1]=0,P[2]=0,P[3]=1),P}const A=r.create(),C=r.create(),R=r.create(),U=new t(4),k=new t(4);return{create:n,fromValues:i,set:function(T,S,P,L,F){const O=F??new t(4);return O[0]=T,O[1]=S,O[2]=P,O[3]=L,O},fromAxisAngle:o,toAxisAngle:function(T,S){const P=S??r.create(3),L=2*Math.acos(T[3]),F=Math.sin(.5*L);return F>ne?(P[0]=T[0]/F,P[1]=T[1]/F,P[2]=T[2]/F):(P[0]=1,P[1]=0,P[2]=0),{angle:L,axis:P}},angle:function(T,S){const P=f(T,S);return Math.acos(2*P*P-1)},multiply:u,mul:l,rotateX:function(T,S,P){const L=P??new t(4),F=.5*S,O=T[0],H=T[1],K=T[2],X=T[3],j=Math.sin(F),z=Math.cos(F);return L[0]=O*z+X*j,L[1]=H*z+K*j,L[2]=K*z-H*j,L[3]=X*z-O*j,L},rotateY:function(T,S,P){const L=P??new t(4),F=.5*S,O=T[0],H=T[1],K=T[2],X=T[3],j=Math.sin(F),z=Math.cos(F);return L[0]=O*z-K*j,L[1]=H*z+X*j,L[2]=K*z+O*j,L[3]=X*z-H*j,L},rotateZ:function(T,S,P){const L=P??new t(4),F=.5*S,O=T[0],H=T[1],K=T[2],X=T[3],j=Math.sin(F),z=Math.cos(F);return L[0]=O*z+H*j,L[1]=H*z-O*j,L[2]=K*z+X*j,L[3]=X*z-K*j,L},slerp:m,inverse:function(T,S){const P=S??new t(4),L=T[0],F=T[1],O=T[2],H=T[3],K=L*L+F*F+O*O+H*H,X=K?1/K:0;return P[0]=-L*X,P[1]=-F*X,P[2]=-O*X,P[3]=H*X,P},conjugate:function(T,S){const P=S??new t(4);return P[0]=-T[0],P[1]=-T[1],P[2]=-T[2],P[3]=T[3],P},fromMat:function(T,S){const P=S??new t(4),L=T[0]+T[5]+T[10];if(L>0){const F=Math.sqrt(L+1);P[3]=.5*F;const O=.5/F;P[0]=(T[6]-T[9])*O,P[1]=(T[8]-T[2])*O,P[2]=(T[1]-T[4])*O}else{let F=0;T[5]>T[0]&&(F=1),T[10]>T[4*F+F]&&(F=2);const O=(F+1)%3,H=(F+2)%3,K=Math.sqrt(T[4*F+F]-T[4*O+O]-T[4*H+H]+1);P[F]=.5*K;const X=.5/K;P[3]=(T[4*O+H]-T[4*H+O])*X,P[O]=(T[4*O+F]+T[4*F+O])*X,P[H]=(T[4*H+F]+T[4*F+H])*X}return P},fromEuler:function(T,S,P,L,F){const O=F??new t(4),H=.5*T,K=.5*S,X=.5*P,j=Math.sin(H),z=Math.cos(H),q=Math.sin(K),Z=Math.cos(K),te=Math.sin(X),re=Math.cos(X);switch(L){case"xyz":O[0]=j*Z*re+z*q*te,O[1]=z*q*re-j*Z*te,O[2]=z*Z*te+j*q*re,O[3]=z*Z*re-j*q*te;break;case"xzy":O[0]=j*Z*re-z*q*te,O[1]=z*q*re-j*Z*te,O[2]=z*Z*te+j*q*re,O[3]=z*Z*re+j*q*te;break;case"yxz":O[0]=j*Z*re+z*q*te,O[1]=z*q*re-j*Z*te,O[2]=z*Z*te-j*q*re,O[3]=z*Z*re+j*q*te;break;case"yzx":O[0]=j*Z*re+z*q*te,O[1]=z*q*re+j*Z*te,O[2]=z*Z*te-j*q*re,O[3]=z*Z*re-j*q*te;break;case"zxy":O[0]=j*Z*re-z*q*te,O[1]=z*q*re+j*Z*te,O[2]=z*Z*te+j*q*re,O[3]=z*Z*re-j*q*te;break;case"zyx":O[0]=j*Z*re-z*q*te,O[1]=z*q*re+j*Z*te,O[2]=z*Z*te-j*q*re,O[3]=z*Z*re+j*q*te;break;default:throw new Error(`Unknown rotation order: ${L}`)}return O},copy:b,clone:d,add:function(T,S,P){const L=P??new t(4);return L[0]=T[0]+S[0],L[1]=T[1]+S[1],L[2]=T[2]+S[2],L[3]=T[3]+S[3],L},subtract:x,sub:g,mulScalar:_,scale:w,divScalar:function(T,S,P){const L=P??new t(4);return L[0]=T[0]/S,L[1]=T[1]/S,L[2]=T[2]/S,L[3]=T[3]/S,L},dot:f,lerp:function(T,S,P,L){const F=L??new t(4);return F[0]=T[0]+P*(S[0]-T[0]),F[1]=T[1]+P*(S[1]-T[1]),F[2]=T[2]+P*(S[2]-T[2]),F[3]=T[3]+P*(S[3]-T[3]),F},length:p,len:a,lengthSq:c,lenSq:h,normalize:y,equalsApproximately:function(T,S){return Math.abs(T[0]-S[0]).999999?(L[0]=0,L[1]=0,L[2]=0,L[3]=1,L):(r.cross(T,S,A),L[0]=A[0],L[1]=A[1],L[2]=A[2],L[3]=1+F,y(L,L))},sqlerp:function(T,S,P,L,F,O){const H=O??new t(4);return m(T,L,F,U),m(S,P,F,k),m(U,k,2*F*(1-F),H),H}}}(s),Io.set(s,e)),e}const Fo=new Map;function fl(s){let e=Fo.get(s);return e||(e=function(t){function r(p,a,c,h){const y=new t(4);return p!==void 0&&(y[0]=p,a!==void 0&&(y[1]=a,c!==void 0&&(y[2]=c,h!==void 0&&(y[3]=h)))),y}function n(p,a,c){const h=c??new t(4);return h[0]=p[0]-a[0],h[1]=p[1]-a[1],h[2]=p[2]-a[2],h[3]=p[3]-a[3],h}function i(p,a,c,h){const y=h??new t(4);return y[0]=p[0]+c*(a[0]-p[0]),y[1]=p[1]+c*(a[1]-p[1]),y[2]=p[2]+c*(a[2]-p[2]),y[3]=p[3]+c*(a[3]-p[3]),y}function o(p,a,c){const h=c??new t(4);return h[0]=p[0]*a,h[1]=p[1]*a,h[2]=p[2]*a,h[3]=p[3]*a,h}function u(p,a){const c=a??new t(4);return c[0]=1/p[0],c[1]=1/p[1],c[2]=1/p[2],c[3]=1/p[3],c}function l(p){const a=p[0],c=p[1],h=p[2],y=p[3];return Math.sqrt(a*a+c*c+h*h+y*y)}function m(p){const a=p[0],c=p[1],h=p[2],y=p[3];return a*a+c*c+h*h+y*y}function b(p,a){const c=p[0]-a[0],h=p[1]-a[1],y=p[2]-a[2],A=p[3]-a[3];return Math.sqrt(c*c+h*h+y*y+A*A)}function d(p,a){const c=p[0]-a[0],h=p[1]-a[1],y=p[2]-a[2],A=p[3]-a[3];return c*c+h*h+y*y+A*A}function x(p,a){const c=a??new t(4),h=p[0],y=p[1],A=p[2],C=p[3],R=Math.sqrt(h*h+y*y+A*A+C*C);return R>1e-5?(c[0]=h/R,c[1]=y/R,c[2]=A/R,c[3]=C/R):(c[0]=0,c[1]=0,c[2]=0,c[3]=0),c}function g(p,a){const c=a??new t(4);return c[0]=p[0],c[1]=p[1],c[2]=p[2],c[3]=p[3],c}function _(p,a,c){const h=c??new t(4);return h[0]=p[0]*a[0],h[1]=p[1]*a[1],h[2]=p[2]*a[2],h[3]=p[3]*a[3],h}function w(p,a,c){const h=c??new t(4);return h[0]=p[0]/a[0],h[1]=p[1]/a[1],h[2]=p[2]/a[2],h[3]=p[3]/a[3],h}function f(p,a,c){const h=c??new t(4);return x(p,h),o(h,a,h)}return{create:r,fromValues:r,set:function(p,a,c,h,y){const A=y??new t(4);return A[0]=p,A[1]=a,A[2]=c,A[3]=h,A},ceil:function(p,a){const c=a??new t(4);return c[0]=Math.ceil(p[0]),c[1]=Math.ceil(p[1]),c[2]=Math.ceil(p[2]),c[3]=Math.ceil(p[3]),c},floor:function(p,a){const c=a??new t(4);return c[0]=Math.floor(p[0]),c[1]=Math.floor(p[1]),c[2]=Math.floor(p[2]),c[3]=Math.floor(p[3]),c},round:function(p,a){const c=a??new t(4);return c[0]=Math.round(p[0]),c[1]=Math.round(p[1]),c[2]=Math.round(p[2]),c[3]=Math.round(p[3]),c},clamp:function(p,a=0,c=1,h){const y=h??new t(4);return y[0]=Math.min(c,Math.max(a,p[0])),y[1]=Math.min(c,Math.max(a,p[1])),y[2]=Math.min(c,Math.max(a,p[2])),y[3]=Math.min(c,Math.max(a,p[3])),y},add:function(p,a,c){const h=c??new t(4);return h[0]=p[0]+a[0],h[1]=p[1]+a[1],h[2]=p[2]+a[2],h[3]=p[3]+a[3],h},addScaled:function(p,a,c,h){const y=h??new t(4);return y[0]=p[0]+a[0]*c,y[1]=p[1]+a[1]*c,y[2]=p[2]+a[2]*c,y[3]=p[3]+a[3]*c,y},subtract:n,sub:n,equalsApproximately:function(p,a){return Math.abs(p[0]-a[0])a?f(p,a,h):g(p,h)},midpoint:function(p,a,c){return i(p,a,.5,c??new t(4))}}}(s),Fo.set(s,e)),e}function Sn(s,e,t,r,n,i){return{mat3:ll(s),mat4:dl(e),quat:hl(t),vec2:Ro(r),vec3:qr(n),vec4:fl(i)}}const{mat3:Qr,mat4:Q,quat:Zr,vec2:Se,vec3:D,vec4:Br}=Sn(Float32Array,Float32Array,Float32Array,Float32Array,Float32Array,Float32Array);Sn(Float64Array,Float64Array,Float64Array,Float64Array,Float64Array,Float64Array),Sn(cl,Array,Array,Array,Array,Array);const pl=""+new URL("Sponza-Eg7MFCLQ.gltf",import.meta.url).href;class Ze{constructor(){throw new Error(`${this.constructor.name} is non-instantiable`)}}class qt extends Ze{static linear(e){return e}static quad_In(e){return e*e}static quad_Out(e){return e*(2-e)}static quad_InOut(e){return(e*=2)<1?.5*e*e:-.5*(--e*(e-2)-1)}static cubic_In(e){return e*e*e}static cubic_Out(e){return--e*e*e+1}static cubic_InOut(e){return(e*=2)<1?.5*e*e*e:.5*((e-=2)*e*e+2)}static quart_In(e){return e*e*e*e}static quart_Out(e){return 1- --e*e*e*e}static quart_InOut(e){return(e*=2)<1?.5*e*e*e*e:-.5*((e-=2)*e*e*e-2)}static quint_In(e){return e*e*e*e*e}static quint_Out(e){return--e*e*e*e*e+1}static quint_InOut(e){return(e*=2)<1?.5*e*e*e*e*e:.5*((e-=2)*e*e*e*e+2)}static sine_In(e){return 1-Math.cos(e*Math.PI/2)}static sine_Out(e){return Math.sin(e*Math.PI/2)}static sine_InOut(e){return .5*(1-Math.cos(Math.PI*e))}static exp_In(e){return e===0?0:Math.pow(1024,e-1)}static exp_Out(e){return e===1?1:1-Math.pow(2,-10*e)}static exp_InOut(e){return e===0||e===1?e:(e*=2)<1?.5*Math.pow(1024,e-1):.5*(2-Math.pow(2,-10*(e-1)))}static circ_In(e){return 1-Math.sqrt(1-e*e)}static circ_Out(e){return Math.sqrt(1- --e*e)}static circ_InOut(e){return(e*=2)<1?-.5*(Math.sqrt(1-e*e)-1):.5*(Math.sqrt(1-(e-=2)*e)+1)}static elastic_In(e){return e===0||e===1?e:-Math.pow(2,10*(e-1))*Math.sin(5*(e-1.1)*Math.PI)}static elastic_Out(e){return e===0||e===1?e:Math.pow(2,-10*e)*Math.sin(5*(e-.1)*Math.PI)+1}static elastic_InOut(e){return e===0||e===1?e:(e*=2)<1?-.5*Math.pow(2,10*(e-1))*Math.sin(5*(e-1.1)*Math.PI):.5*Math.pow(2,-10*(e-1))*Math.sin(5*(e-1.1)*Math.PI)+1}static back_In(e){return e*e*(2.70158*e-1.70158)}static back_Out(e){return--e*e*(2.70158*e+1.70158)+1}static back_InOut(e){const t=2.5949095;return(e*=2)<1?e*e*((t+1)*e-t)*.5:.5*((e-=2)*e*((t+1)*e+t)+2)}static bounce_In(e){return 1-qt.bounce_Out(1-e)}static bounce_Out(e){return e<1/2.75?7.5625*e*e:e<2/2.75?7.5625*(e-=1.5/2.75)*e+.75:e<2.5/2.75?7.5625*(e-=2.25/2.75)*e+.9375:7.5625*(e-=2.625/2.75)*e+.984375}static bounce_InOut(e){return e<.5?.5*qt.bounce_In(2*e):.5*qt.bounce_Out(2*e-1)+.5}}class es{constructor({durationMS:e,delayMS:t=0,easeName:r="linear",onUpdate:n,onComplete:i=()=>{}}){this.startMS=0,this.update=()=>{this.rafID=window.requestAnimationFrame(this.update);let o=(performance.now()-this.startMS)/this.durationMS;o<0?o=0:o>1&&(o=1);const u=this.easeFunc(o);this.onUpdate(u,o),o>=1&&(this.onComplete(),this.stop())},this.durationMS=e,this.delayMS=t,this.easeFunc=qt[r],this.onUpdate=n,this.onComplete=i}start(){const e=()=>{this.startMS=performance.now(),this.rafID=window.requestAnimationFrame(this.update),clearTimeout(this.delayID)};return this.delayMS?this.delayID=window.setTimeout(e,this.delayMS):e(),this}stop(){return window.clearTimeout(this.delayID),window.cancelAnimationFrame(this.rafID),this.rafID=-1,this}setEase(e){return this.easeFunc=qt[e],this}}const vt=class vt{static getActiveRenderPassType(){return this.activeRenderPassType}static setActiveRenderPass(e,t){this.activeRenderPassType=e,this.activeRenderPassEncoder=t,this.currentlyBoundRenderPSO=null}static bindRenderPSO(e){var t;e!==this.currentlyBoundRenderPSO&&(this.currentlyBoundRenderPSO=e,(t=this.activeRenderPassEncoder)==null||t.setPipeline(e))}};vt.ENABLE_DEBUG_GROUPS=!1,vt.elapsedTimeMs=0,vt.deltaTimeMs=0,vt.frameIndex=0,vt.depthStencilFormat="depth24plus-stencil8",vt.prevTimeMs=0;let B=vt;const we=D.create(),ml=87,gl=83,yl=65,bl=68,xl=69,_l=81,En="ontouchstart"in window||navigator.maxTouchPoints>0,oe=class oe{constructor(e,t=document.body,r=t){this.camera=e,this.keyboardDomElement=t,this.mouseDomElement=r,this.angles=Se.create(0,.5*-Math.PI),this.viewMat=Q.create(),this.rotMat=Q.identity(),this.lastX=0,this.lastY=0,this.presedKeys=new Array(128),this.rafId=-1,this.speed=40,this.touchMoveX=.5*-oe.TOUCHMOVE_HANDLE_SIZE,this.touchMoveY=.5*-oe.TOUCHMOVE_HANDLE_SIZE,this.touchMoveTargetX=.5*-oe.TOUCHMOVE_HANDLE_SIZE,this.touchMoveTargetY=.5*-oe.TOUCHMOVE_HANDLE_SIZE,this.touchMoveAngle=0,this.touchLookX=.5*-oe.TOUCHMOVE_HANDLE_SIZE,this.touchLookY=.5*-oe.TOUCHMOVE_HANDLE_SIZE,this.touchLookTargetX=.5*-oe.TOUCHMOVE_HANDLE_SIZE,this.touchLookTargetY=.5*-oe.TOUCHMOVE_HANDLE_SIZE,this.touchLookAngle=0,this.isTouchMoveActive=!1,this.isTouchLookActive=!1,this.onLookHandleTouchStart=()=>{},this.onLookHandleTouchMove=n=>{n.preventDefault();const i=n.targetTouches[0].clientX,o=n.targetTouches[0].clientY,u=innerWidth-24-.5*oe.TOUCHMOVE_ROOT_SIZE-i,l=innerHeight-24-.5*oe.TOUCHMOVE_ROOT_SIZE-o,m=Math.min(Math.sqrt(u*u+l*l),60),b=Math.atan2(-l,-u),d=Math.cos(b)*m-.5*oe.TOUCHMOVE_HANDLE_SIZE,x=Math.sin(b)*m-.5*oe.TOUCHMOVE_HANDLE_SIZE;this.touchLookTargetX=d,this.touchLookTargetY=x,this.touchLookAngle=b,this.isTouchLookActive=!0},this.onLookHandleTouchEnd=()=>{this.touchLookTargetX=.5*-oe.TOUCHMOVE_HANDLE_SIZE,this.touchLookTargetY=.5*-oe.TOUCHMOVE_HANDLE_SIZE,this.isTouchLookActive=!1},this.onMoveHandleTouchStart=()=>{},this.onMoveHandleTouchEnd=()=>{this.touchMoveTargetX=.5*-oe.TOUCHMOVE_HANDLE_SIZE,this.touchMoveTargetY=.5*-oe.TOUCHMOVE_HANDLE_SIZE,this.isTouchMoveActive=!1},this.onMoveHandleTouchMove=n=>{n.preventDefault();const i=n.targetTouches[0].clientX,o=n.targetTouches[0].clientY,u=24+.5*oe.TOUCHMOVE_ROOT_SIZE-i,l=innerHeight-24-.5*oe.TOUCHMOVE_ROOT_SIZE-o,m=Math.min(Math.sqrt(u*u+l*l),60),b=Math.atan2(-l,-u),d=Math.cos(b)*m-.5*oe.TOUCHMOVE_HANDLE_SIZE,x=Math.sin(b)*m-.5*oe.TOUCHMOVE_HANDLE_SIZE;this.touchMoveTargetX=d,this.touchMoveTargetY=x,this.touchMoveAngle=b,this.isTouchMoveActive=!0},this.update=n=>{var l,m;const i=.001*this.speed;D.set(0,0,0,we);const o=B.deltaTimeMs;if(En){if(this.touchMoveX+=(this.touchMoveTargetX-this.touchMoveX)*o*5,this.touchMoveY+=(this.touchMoveTargetY-this.touchMoveY)*o*5,(l=this.$touchMoveHandle)==null||l.style.setProperty("transform",`translate3d(${this.touchMoveX}px, ${this.touchMoveY}px, 0)`),this.touchLookX+=(this.touchLookTargetX-this.touchLookX)*o*5,this.touchLookY+=(this.touchLookTargetY-this.touchLookY)*o*5,(m=this.$touchLookHandle)==null||m.style.setProperty("transform",`translate3d(${this.touchLookX}px, ${this.touchLookY}px, 0)`),this.isTouchLookActive){const b=Math.cos(this.touchLookAngle),d=Math.sin(this.touchLookAngle);this.rotateView(.03*b,.03*d)}if(this.isTouchMoveActive){const b=Math.cos(this.touchMoveAngle),d=Math.sin(this.touchMoveAngle);we[0]=.05*b,we[2]=.05*d}}else(this.presedKeys[ml]||this.presedKeys[38])&&(we[2]-=i),(this.presedKeys[gl]||this.presedKeys[40])&&(we[2]+=i),(this.presedKeys[yl]||this.presedKeys[37])&&(we[0]-=i),(this.presedKeys[bl]||this.presedKeys[39])&&(we[0]+=i),this.presedKeys[xl]&&(we[1]+=i),this.presedKeys[_l]&&(we[1]-=i);we[0]===0&&we[1]===0&&we[2]===0||(D.transformMat4(we,this.rotMat,we),D.add(this.position,we,this.position));const u=this.viewMat;Q.identity(u),Q.rotateX(u,this.angles[0],u),Q.rotateY(u,this.angles[1],u),Q.translate(u,D.negate(this.position),u),this.camera.setPosition(this.position[0],this.position[1],this.position[2]),this.camera.updateViewMatrixWithMat(u),this.rafId=requestAnimationFrame(this.update)},this.onMouseDown=n=>{this.lastX=n.pageX,this.lastY=n.pageY,this.mouseDomElement.addEventListener("mousemove",this.onMouseMove)},this.onMouseUp=()=>{this.mouseDomElement.removeEventListener("mousemove",this.onMouseMove)},this.onMouseMove=n=>{const i=n.pageX-this.lastX,o=n.pageY-this.lastY;this.lastX=n.pageX,this.lastY=n.pageY,this.rotateView(.0075*i,.005*o)},this.onKeyDown=n=>{this.presedKeys[n.keyCode]=!0},this.onKeyUp=n=>{this.presedKeys[n.keyCode]=!1},this.position=e.position,t.addEventListener("keydown",this.onKeyDown),t.addEventListener("keyup",this.onKeyUp),r.addEventListener("mousedown",this.onMouseDown),r.addEventListener("mouseup",this.onMouseUp),this.rotateView(.0075,.005),En&&(this.$touchMoveRoot=document.createElement("div"),this.$touchMoveRoot.style.setProperty("position","fixed"),this.$touchMoveRoot.style.setProperty("left","24px"),this.$touchMoveRoot.style.setProperty("bottom","24px"),this.$touchMoveRoot.style.setProperty("width",`${oe.TOUCHMOVE_ROOT_SIZE}px`),this.$touchMoveRoot.style.setProperty("height",`${oe.TOUCHMOVE_ROOT_SIZE}px`),this.$touchMoveRoot.style.setProperty("border-radius","50%"),this.$touchMoveRoot.style.setProperty("border","2px solid white"),this.$touchMoveRoot.style.setProperty("z-index","9999"),this.$touchMoveRoot.style.setProperty("transition","opacity 0.125s ease"),this.$touchMoveRoot.style.setProperty("opacity","0"),this.$touchMoveHandle=document.createElement("div"),this.$touchMoveHandle.style.setProperty("width",`${oe.TOUCHMOVE_HANDLE_SIZE}px`),this.$touchMoveHandle.style.setProperty("height",`${oe.TOUCHMOVE_HANDLE_SIZE}px`),this.$touchMoveHandle.style.setProperty("position","absolute"),this.$touchMoveHandle.style.setProperty("left","50%"),this.$touchMoveHandle.style.setProperty("top","50%"),this.$touchMoveHandle.style.setProperty("background-color","rgba(255, 255, 255, 0.72)"),this.$touchMoveHandle.style.setProperty("border-radius","50%"),this.$touchMoveRoot.appendChild(this.$touchMoveHandle),document.body.appendChild(this.$touchMoveRoot),this.$touchLookRoot=document.createElement("div"),this.$touchLookRoot.style.setProperty("position","fixed"),this.$touchLookRoot.style.setProperty("bottom","24px"),this.$touchLookRoot.style.setProperty("right","24px"),this.$touchLookRoot.style.setProperty("width",`${oe.TOUCHMOVE_ROOT_SIZE}px`),this.$touchLookRoot.style.setProperty("height",`${oe.TOUCHMOVE_ROOT_SIZE}px`),this.$touchLookRoot.style.setProperty("border","2px solid white"),this.$touchLookRoot.style.setProperty("border-radius","50%"),this.$touchLookRoot.style.setProperty("z-index","9999"),this.$touchLookRoot.style.setProperty("transition","opacity 0.125s ease"),this.$touchLookRoot.style.setProperty("opacity","0"),document.body.appendChild(this.$touchLookRoot),this.$touchLookHandle=document.createElement("div"),this.$touchLookHandle.style.setProperty("width",`${oe.TOUCHMOVE_HANDLE_SIZE}px`),this.$touchLookHandle.style.setProperty("height",`${oe.TOUCHMOVE_HANDLE_SIZE}px`),this.$touchLookHandle.style.setProperty("position","absolute"),this.$touchLookHandle.style.setProperty("left","50%"),this.$touchLookHandle.style.setProperty("top","50%"),this.$touchLookHandle.style.setProperty("background-color","rgba(255, 255, 255, 0.72)"),this.$touchLookHandle.style.setProperty("border-radius","50%"),this.$touchLookRoot.appendChild(this.$touchLookHandle),this.$touchMoveHandle.addEventListener("touchstart",this.onMoveHandleTouchStart),this.$touchMoveHandle.addEventListener("touchmove",this.onMoveHandleTouchMove),this.$touchMoveHandle.addEventListener("touchend",this.onMoveHandleTouchEnd),this.$touchMoveHandle.addEventListener("touchcancel",this.onMoveHandleTouchEnd),this.$touchLookHandle.addEventListener("touchstart",this.onLookHandleTouchStart),this.$touchLookHandle.addEventListener("touchmove",this.onLookHandleTouchMove),this.$touchLookHandle.addEventListener("touchend",this.onLookHandleTouchEnd),this.$touchLookHandle.addEventListener("touchcancel",this.onLookHandleTouchEnd))}revealTouchControls(){En&&(this.$touchMoveRoot.style.setProperty("opacity","1"),this.$touchLookRoot.style.setProperty("opacity","1"))}startTick(){this.rafId=requestAnimationFrame(this.update)}endTick(){cancelAnimationFrame(this.rafId)}rotateView(e,t){if(e||t){for(this.angles[1]+=e;this.angles[1]<0;)this.angles[1]+=2*Math.PI;for(;this.angles[1]>=2*Math.PI;)this.angles[1]-=2*Math.PI;this.angles[0]+=t,this.angles[0]<.5*-Math.PI&&(this.angles[0]=.5*-Math.PI),this.angles[0]>.5*Math.PI&&(this.angles[0]=.5*Math.PI),Q.identity(this.rotMat),Q.rotateY(this.rotMat,-this.angles[1],this.rotMat),Q.rotateX(this.rotMat,-this.angles[0],this.rotMat)}}};oe.TOUCHMOVE_ROOT_SIZE=120,oe.TOUCHMOVE_HANDLE_SIZE=90;let Mn=oe;const Do=(s,e,t)=>s+t*(e-s),Pt=(s,e)=>{const t=Math.max(s,e);return 1+Math.log2(t)|0},Al=Q.identity(),Bl=[[1,0,0],[-1,0,0],[0,1,0],[0,-1,0],[0,0,1],[0,0,-1]],vl=[[0,1,0],[0,1,0],[0,0,-1],[0,0,1],[0,1,0],[0,1,0]],Uo=new Float32Array(1),wl=new Int32Array(Uo.buffer),ts=s=>{Uo[0]=s;const e=wl[0];let t=e>>16&32768,r=e>>12&2047;const n=e>>23&255;return n<103?t:n>142?(t|=31744,t|=(n==255?0:1)&&8388607&e,t):n<113?(r|=2048,t|=(r>>114-n)+(r>>113-n&1),t):(t|=n-112<<10|r>>1,t+=1&r,t)},Pn=(s,e)=>((s+e-1)/e|0)*e,ko=s=>s&&typeof s.length=="number"&&s.buffer instanceof ArrayBuffer&&typeof s.byteLength=="number",ie={i32:{numElements:1,align:4,size:4,type:"i32",View:Int32Array},u32:{numElements:1,align:4,size:4,type:"u32",View:Uint32Array},f32:{numElements:1,align:4,size:4,type:"f32",View:Float32Array},f16:{numElements:1,align:2,size:2,type:"u16",View:Uint16Array},vec2f:{numElements:2,align:8,size:8,type:"f32",View:Float32Array},vec2i:{numElements:2,align:8,size:8,type:"i32",View:Int32Array},vec2u:{numElements:2,align:8,size:8,type:"u32",View:Uint32Array},vec2h:{numElements:2,align:4,size:4,type:"u16",View:Uint16Array},vec3i:{numElements:3,align:16,size:12,type:"i32",View:Int32Array},vec3u:{numElements:3,align:16,size:12,type:"u32",View:Uint32Array},vec3f:{numElements:3,align:16,size:12,type:"f32",View:Float32Array},vec3h:{numElements:3,align:8,size:6,type:"u16",View:Uint16Array},vec4i:{numElements:4,align:16,size:16,type:"i32",View:Int32Array},vec4u:{numElements:4,align:16,size:16,type:"u32",View:Uint32Array},vec4f:{numElements:4,align:16,size:16,type:"f32",View:Float32Array},vec4h:{numElements:4,align:8,size:8,type:"u16",View:Uint16Array},mat2x2f:{numElements:4,align:8,size:16,type:"f32",View:Float32Array},mat2x2h:{numElements:4,align:4,size:8,type:"u16",View:Uint16Array},mat3x2f:{numElements:6,align:8,size:24,type:"f32",View:Float32Array},mat3x2h:{numElements:6,align:4,size:12,type:"u16",View:Uint16Array},mat4x2f:{numElements:8,align:8,size:32,type:"f32",View:Float32Array},mat4x2h:{numElements:8,align:4,size:16,type:"u16",View:Uint16Array},mat2x3f:{numElements:8,align:16,size:32,pad:[3,1],type:"f32",View:Float32Array},mat2x3h:{numElements:8,align:8,size:16,pad:[3,1],type:"u16",View:Uint16Array},mat3x3f:{numElements:12,align:16,size:48,pad:[3,1],type:"f32",View:Float32Array},mat3x3h:{numElements:12,align:8,size:24,pad:[3,1],type:"u16",View:Uint16Array},mat4x3f:{numElements:16,align:16,size:64,pad:[3,1],type:"f32",View:Float32Array},mat4x3h:{numElements:16,align:8,size:32,pad:[3,1],type:"u16",View:Uint16Array},mat2x4f:{numElements:8,align:16,size:32,type:"f32",View:Float32Array},mat2x4h:{numElements:8,align:8,size:16,type:"u16",View:Uint16Array},mat3x4f:{numElements:12,align:16,size:48,pad:[3,1],type:"f32",View:Float32Array},mat3x4h:{numElements:12,align:8,size:24,pad:[3,1],type:"u16",View:Uint16Array},mat4x4f:{numElements:16,align:16,size:64,type:"f32",View:Float32Array},mat4x4h:{numElements:16,align:8,size:32,type:"u16",View:Uint16Array},bool:{numElements:0,align:1,size:0,type:"bool",View:Uint32Array}},Qt={...ie,"atomic":ie.i32,"atomic":ie.u32,"vec2":ie.vec2i,"vec2":ie.vec2u,"vec2":ie.vec2f,"vec2":ie.vec2h,"vec3":ie.vec3i,"vec3":ie.vec3u,"vec3":ie.vec3f,"vec3":ie.vec3h,"vec4":ie.vec4i,"vec4":ie.vec4u,"vec4":ie.vec4f,"vec4":ie.vec4h,"mat2x2":ie.mat2x2f,"mat2x2":ie.mat2x2h,"mat3x2":ie.mat3x2f,"mat3x2":ie.mat3x2h,"mat4x2":ie.mat4x2f,"mat4x2":ie.mat4x2h,"mat2x3":ie.mat2x3f,"mat2x3":ie.mat2x3h,"mat3x3":ie.mat3x3f,"mat3x3":ie.mat3x3h,"mat4x3":ie.mat4x3f,"mat4x3":ie.mat4x3h,"mat2x4":ie.mat2x4f,"mat2x4":ie.mat2x4h,"mat3x4":ie.mat3x4f,"mat3x4":ie.mat3x4h,"mat4x4":ie.mat4x4f,"mat4x4":ie.mat4x4h},Cl=(No=Qt,Object.keys(No));var No;function Vo(s,e,t,r){const{size:n,type:i}=s;try{const{View:o,align:u}=Qt[i],l=r!==void 0,m=l?Pn(n,u):n,b=m/o.BYTES_PER_ELEMENT;return new o(e,t,b*(l?r===0?(e.byteLength-t)/m:r:1))}catch{throw new Error(`unknown type: ${i}`)}}function Tl(s,e,t){const r=t||0,n=new ArrayBuffer(function(o){const u=o;if(u.elementType)return u.size;{const l=o,m=u.numElements||1;if(l.fields)return o.size*m;{const b=o,{align:d}=Qt[b.type];return m>1?Pn(o.size,d)*m:o.size}}}(s)),i=(o,u)=>{const l=o,m=l.elementType;if(m){if(function(d){return!d.fields&&!d.elementType}(m)&&Qt[m.type].flatten)return Vo(m,n,u,l.numElements);{const{size:d}=Ho(o),x=l.numElements===0?(n.byteLength-u)/d:l.numElements;return b=g=>i(m,u+d*g),new Array(x).fill(0).map((g,_)=>b(_))}}if(typeof o=="string")throw Error("unreachable");{const d=o.fields;if(d){const x={};for(const[g,{type:_,offset:w}]of Object.entries(d))x[g]=i(_,u+w);return x}return Vo(o,n,u)}var b};return{views:i(s,r),arrayBuffer:n}}function Rn(s,e){if(s!==void 0)if(ko(e)){const t=e;if(t.length===1&&typeof s=="number")t[0]=s;else if(Array.isArray(s[0])||ko(s[0])){const r=s[0].length,n=r===3?4:r;for(let i=0;i{Rn(r,t[n])})}else{const t=e;for(const[r,n]of Object.entries(s)){const i=t[r];i&&Rn(n,i)}}}function yt(s,e,t=0){const r=s,n=Tl(r.group===void 0?s:r.typeDefinition,0,t);return{...n,set(i){Rn(i,n.views)}}}function Gn(s){const e=s.elementType;if(e)return Gn(e);const t=s.fields;if(t)return Object.values(t).reduce((i,{type:o})=>Math.max(i,Gn(o)),0);const{type:r}=s,{align:n}=Qt[r];return n}function Ho(s){const e=s.elementType;if(e){const r=e.size,n=Gn(e);return{unalignedSize:r,align:n,size:Pn(r,n)}}const t=s.fields;if(t){const r=Object.values(t).pop();if(r.type.size===0)return Ho(r.type)}return{size:0,unalignedSize:0,align:1}}(function(s=[],e){const t=new Set;for(const r of Cl){const n=Qt[r];t.has(n)||(t.add(n),n.flatten=s.includes(r)?e:!e)}})();class Sl{constructor(){this.constants=new Map,this.aliases=new Map,this.structs=new Map}}let ot=class{constructor(){}get isAstNode(){return!0}get astNodeType(){return""}evaluate(s){throw new Error("Cannot evaluate node")}evaluateString(s){return this.evaluate(s).toString()}search(s){}searchBlock(s,e){if(s){e(rs.instance);for(const t of s)t instanceof Array?this.searchBlock(t,e):t.search(e);e(ss.instance)}}};class rs extends ot{}rs.instance=new rs;class ss extends ot{}ss.instance=new ss;class he extends ot{constructor(){super()}}let Ln=class extends he{constructor(s,e,t,r,n,i){super(),this.calls=new Set,this.name=s,this.args=e,this.returnType=t,this.body=r,this.startLine=n,this.endLine=i}get astNodeType(){return"function"}search(s){this.searchBlock(this.body,s)}};class El extends he{constructor(e){super(),this.expression=e}get astNodeType(){return"staticAssert"}search(e){this.expression.search(e)}}class Ml extends he{constructor(e,t){super(),this.condition=e,this.body=t}get astNodeType(){return"while"}search(e){this.condition.search(e),this.searchBlock(this.body,e)}}class Pl extends he{constructor(e){super(),this.body=e}get astNodeType(){return"continuing"}search(e){this.searchBlock(this.body,e)}}class Rl extends he{constructor(e,t,r,n){super(),this.init=e,this.condition=t,this.increment=r,this.body=n}get astNodeType(){return"for"}search(e){var t,r,n;(t=this.init)===null||t===void 0||t.search(e),(r=this.condition)===null||r===void 0||r.search(e),(n=this.increment)===null||n===void 0||n.search(e),this.searchBlock(this.body,e)}}class Rt extends he{constructor(e,t,r,n,i){super(),this.name=e,this.type=t,this.storage=r,this.access=n,this.value=i}get astNodeType(){return"var"}search(e){var t;e(this),(t=this.value)===null||t===void 0||t.search(e)}}class Jo extends he{constructor(e,t,r){super(),this.name=e,this.type=t,this.value=r}get astNodeType(){return"override"}search(e){var t;(t=this.value)===null||t===void 0||t.search(e)}}class On extends he{constructor(e,t,r,n,i){super(),this.name=e,this.type=t,this.storage=r,this.access=n,this.value=i}get astNodeType(){return"let"}search(e){var t;e(this),(t=this.value)===null||t===void 0||t.search(e)}}class zo extends he{constructor(e,t,r,n,i){super(),this.name=e,this.type=t,this.storage=r,this.access=n,this.value=i}get astNodeType(){return"const"}evaluate(e){return this.value.evaluate(e)}search(e){var t;e(this),(t=this.value)===null||t===void 0||t.search(e)}}var Zt,vr,G,E,be;(function(s){s.increment="++",s.decrement="--"})(Zt||(Zt={})),function(s){s.parse=function(e){const t=e;if(t=="parse")throw new Error("Invalid value for IncrementOperator");return s[t]}}(Zt||(Zt={}));class Gl extends he{constructor(e,t){super(),this.operator=e,this.variable=t}get astNodeType(){return"increment"}search(e){this.variable.search(e)}}(function(s){s.assign="=",s.addAssign="+=",s.subtractAssin="-=",s.multiplyAssign="*=",s.divideAssign="/=",s.moduloAssign="%=",s.andAssign="&=",s.orAssign="|=",s.xorAssign="^=",s.shiftLeftAssign="<<=",s.shiftRightAssign=">>="})(vr||(vr={})),function(s){s.parse=function(e){const t=e;if(t=="parse")throw new Error("Invalid value for AssignOperator");return t}}(vr||(vr={}));class Ll extends he{constructor(e,t,r){super(),this.operator=e,this.variable=t,this.value=r}get astNodeType(){return"assign"}search(e){this.variable.search(e),this.value.search(e)}}class jo extends he{constructor(e,t){super(),this.name=e,this.args=t}get astNodeType(){return"call"}search(e){for(const t of this.args)t.search(e);e(this)}}class Ol extends he{constructor(e,t){super(),this.body=e,this.continuing=t}get astNodeType(){return"loop"}}class Il extends he{constructor(e,t){super(),this.condition=e,this.body=t}get astNodeType(){return"body"}}class Fl extends he{constructor(e,t,r,n){super(),this.condition=e,this.body=t,this.elseif=r,this.else=n}get astNodeType(){return"if"}search(e){this.condition.search(e),this.searchBlock(this.body,e),this.searchBlock(this.elseif,e),this.searchBlock(this.else,e)}}class Dl extends he{constructor(e){super(),this.value=e}get astNodeType(){return"return"}search(e){var t;(t=this.value)===null||t===void 0||t.search(e)}}class Ul extends he{constructor(e){super(),this.name=e}get astNodeType(){return"enable"}}class kl extends he{constructor(e){super(),this.extensions=e}get astNodeType(){return"requires"}}class Nl extends he{constructor(e,t){super(),this.severity=e,this.rule=t}get astNodeType(){return"diagnostic"}}class Ko extends he{constructor(e,t){super(),this.name=e,this.type=t}get astNodeType(){return"alias"}}class Vl extends he{constructor(){super()}get astNodeType(){return"discard"}}class Hl extends he{constructor(){super()}get astNodeType(){return"break"}}class Jl extends he{constructor(){super()}get astNodeType(){return"continue"}}class Gt extends he{constructor(e){super(),this.name=e}get astNodeType(){return"type"}get isStruct(){return!1}get isArray(){return!1}}class Lt extends Gt{constructor(e,t,r,n){super(e),this.members=t,this.startLine=r,this.endLine=n}get astNodeType(){return"struct"}get isStruct(){return!0}getMemberIndex(e){for(let t=0;t":return this.left.evaluate(e)>this.right.evaluate(e)?1:0;case"<=":return this.left.evaluate(e)<=this.right.evaluate(e)?1:0;case">=":return this.left.evaluate(e)>=this.right.evaluate(e)?1:0;case"&&":return this.left.evaluate(e)&&this.right.evaluate(e)?1:0;case"||":return this.left.evaluate(e)||this.right.evaluate(e)?1:0;default:throw new Error(`Unknown operator ${this.operator}`)}}search(e){this.left.search(e),this.right.search(e)}}class ta extends ot{constructor(){super()}}class Wl extends ta{constructor(e,t){super(),this.selector=e,this.body=t}get astNodeType(){return"case"}search(e){this.searchBlock(this.body,e)}}class $l extends ta{constructor(e){super(),this.body=e}get astNodeType(){return"default"}search(e){this.searchBlock(this.body,e)}}class ql extends ot{constructor(e,t,r){super(),this.name=e,this.type=t,this.attributes=r}get astNodeType(){return"argument"}}class Ql extends ot{constructor(e,t){super(),this.condition=e,this.body=t}get astNodeType(){return"elseif"}search(e){this.condition.search(e),this.searchBlock(this.body,e)}}class Zl extends ot{constructor(e,t,r){super(),this.name=e,this.type=t,this.attributes=r}get astNodeType(){return"member"}}class ra extends ot{constructor(e,t){super(),this.name=e,this.value=t}get astNodeType(){return"attribute"}}(function(s){s[s.token=0]="token",s[s.keyword=1]="keyword",s[s.reserved=2]="reserved"})(E||(E={}));class M{constructor(e,t,r){this.name=e,this.type=t,this.rule=r}toString(){return this.name}}class v{}G=v,v.none=new M("",E.reserved,""),v.eof=new M("EOF",E.token,""),v.reserved={asm:new M("asm",E.reserved,"asm"),bf16:new M("bf16",E.reserved,"bf16"),do:new M("do",E.reserved,"do"),enum:new M("enum",E.reserved,"enum"),f16:new M("f16",E.reserved,"f16"),f64:new M("f64",E.reserved,"f64"),handle:new M("handle",E.reserved,"handle"),i8:new M("i8",E.reserved,"i8"),i16:new M("i16",E.reserved,"i16"),i64:new M("i64",E.reserved,"i64"),mat:new M("mat",E.reserved,"mat"),premerge:new M("premerge",E.reserved,"premerge"),regardless:new M("regardless",E.reserved,"regardless"),typedef:new M("typedef",E.reserved,"typedef"),u8:new M("u8",E.reserved,"u8"),u16:new M("u16",E.reserved,"u16"),u64:new M("u64",E.reserved,"u64"),unless:new M("unless",E.reserved,"unless"),using:new M("using",E.reserved,"using"),vec:new M("vec",E.reserved,"vec"),void:new M("void",E.reserved,"void")},v.keywords={array:new M("array",E.keyword,"array"),atomic:new M("atomic",E.keyword,"atomic"),bool:new M("bool",E.keyword,"bool"),f32:new M("f32",E.keyword,"f32"),i32:new M("i32",E.keyword,"i32"),mat2x2:new M("mat2x2",E.keyword,"mat2x2"),mat2x3:new M("mat2x3",E.keyword,"mat2x3"),mat2x4:new M("mat2x4",E.keyword,"mat2x4"),mat3x2:new M("mat3x2",E.keyword,"mat3x2"),mat3x3:new M("mat3x3",E.keyword,"mat3x3"),mat3x4:new M("mat3x4",E.keyword,"mat3x4"),mat4x2:new M("mat4x2",E.keyword,"mat4x2"),mat4x3:new M("mat4x3",E.keyword,"mat4x3"),mat4x4:new M("mat4x4",E.keyword,"mat4x4"),ptr:new M("ptr",E.keyword,"ptr"),sampler:new M("sampler",E.keyword,"sampler"),sampler_comparison:new M("sampler_comparison",E.keyword,"sampler_comparison"),struct:new M("struct",E.keyword,"struct"),texture_1d:new M("texture_1d",E.keyword,"texture_1d"),texture_2d:new M("texture_2d",E.keyword,"texture_2d"),texture_2d_array:new M("texture_2d_array",E.keyword,"texture_2d_array"),texture_3d:new M("texture_3d",E.keyword,"texture_3d"),texture_cube:new M("texture_cube",E.keyword,"texture_cube"),texture_cube_array:new M("texture_cube_array",E.keyword,"texture_cube_array"),texture_multisampled_2d:new M("texture_multisampled_2d",E.keyword,"texture_multisampled_2d"),texture_storage_1d:new M("texture_storage_1d",E.keyword,"texture_storage_1d"),texture_storage_2d:new M("texture_storage_2d",E.keyword,"texture_storage_2d"),texture_storage_2d_array:new M("texture_storage_2d_array",E.keyword,"texture_storage_2d_array"),texture_storage_3d:new M("texture_storage_3d",E.keyword,"texture_storage_3d"),texture_depth_2d:new M("texture_depth_2d",E.keyword,"texture_depth_2d"),texture_depth_2d_array:new M("texture_depth_2d_array",E.keyword,"texture_depth_2d_array"),texture_depth_cube:new M("texture_depth_cube",E.keyword,"texture_depth_cube"),texture_depth_cube_array:new M("texture_depth_cube_array",E.keyword,"texture_depth_cube_array"),texture_depth_multisampled_2d:new M("texture_depth_multisampled_2d",E.keyword,"texture_depth_multisampled_2d"),texture_external:new M("texture_external",E.keyword,"texture_external"),u32:new M("u32",E.keyword,"u32"),vec2:new M("vec2",E.keyword,"vec2"),vec3:new M("vec3",E.keyword,"vec3"),vec4:new M("vec4",E.keyword,"vec4"),bitcast:new M("bitcast",E.keyword,"bitcast"),block:new M("block",E.keyword,"block"),break:new M("break",E.keyword,"break"),case:new M("case",E.keyword,"case"),continue:new M("continue",E.keyword,"continue"),continuing:new M("continuing",E.keyword,"continuing"),default:new M("default",E.keyword,"default"),diagnostic:new M("diagnostic",E.keyword,"diagnostic"),discard:new M("discard",E.keyword,"discard"),else:new M("else",E.keyword,"else"),enable:new M("enable",E.keyword,"enable"),fallthrough:new M("fallthrough",E.keyword,"fallthrough"),false:new M("false",E.keyword,"false"),fn:new M("fn",E.keyword,"fn"),for:new M("for",E.keyword,"for"),function:new M("function",E.keyword,"function"),if:new M("if",E.keyword,"if"),let:new M("let",E.keyword,"let"),const:new M("const",E.keyword,"const"),loop:new M("loop",E.keyword,"loop"),while:new M("while",E.keyword,"while"),private:new M("private",E.keyword,"private"),read:new M("read",E.keyword,"read"),read_write:new M("read_write",E.keyword,"read_write"),return:new M("return",E.keyword,"return"),requires:new M("requires",E.keyword,"requires"),storage:new M("storage",E.keyword,"storage"),switch:new M("switch",E.keyword,"switch"),true:new M("true",E.keyword,"true"),alias:new M("alias",E.keyword,"alias"),type:new M("type",E.keyword,"type"),uniform:new M("uniform",E.keyword,"uniform"),var:new M("var",E.keyword,"var"),override:new M("override",E.keyword,"override"),workgroup:new M("workgroup",E.keyword,"workgroup"),write:new M("write",E.keyword,"write"),r8unorm:new M("r8unorm",E.keyword,"r8unorm"),r8snorm:new M("r8snorm",E.keyword,"r8snorm"),r8uint:new M("r8uint",E.keyword,"r8uint"),r8sint:new M("r8sint",E.keyword,"r8sint"),r16uint:new M("r16uint",E.keyword,"r16uint"),r16sint:new M("r16sint",E.keyword,"r16sint"),r16float:new M("r16float",E.keyword,"r16float"),rg8unorm:new M("rg8unorm",E.keyword,"rg8unorm"),rg8snorm:new M("rg8snorm",E.keyword,"rg8snorm"),rg8uint:new M("rg8uint",E.keyword,"rg8uint"),rg8sint:new M("rg8sint",E.keyword,"rg8sint"),r32uint:new M("r32uint",E.keyword,"r32uint"),r32sint:new M("r32sint",E.keyword,"r32sint"),r32float:new M("r32float",E.keyword,"r32float"),rg16uint:new M("rg16uint",E.keyword,"rg16uint"),rg16sint:new M("rg16sint",E.keyword,"rg16sint"),rg16float:new M("rg16float",E.keyword,"rg16float"),rgba8unorm:new M("rgba8unorm",E.keyword,"rgba8unorm"),rgba8unorm_srgb:new M("rgba8unorm_srgb",E.keyword,"rgba8unorm_srgb"),rgba8snorm:new M("rgba8snorm",E.keyword,"rgba8snorm"),rgba8uint:new M("rgba8uint",E.keyword,"rgba8uint"),rgba8sint:new M("rgba8sint",E.keyword,"rgba8sint"),bgra8unorm:new M("bgra8unorm",E.keyword,"bgra8unorm"),bgra8unorm_srgb:new M("bgra8unorm_srgb",E.keyword,"bgra8unorm_srgb"),rgb10a2unorm:new M("rgb10a2unorm",E.keyword,"rgb10a2unorm"),rg11b10float:new M("rg11b10float",E.keyword,"rg11b10float"),rg32uint:new M("rg32uint",E.keyword,"rg32uint"),rg32sint:new M("rg32sint",E.keyword,"rg32sint"),rg32float:new M("rg32float",E.keyword,"rg32float"),rgba16uint:new M("rgba16uint",E.keyword,"rgba16uint"),rgba16sint:new M("rgba16sint",E.keyword,"rgba16sint"),rgba16float:new M("rgba16float",E.keyword,"rgba16float"),rgba32uint:new M("rgba32uint",E.keyword,"rgba32uint"),rgba32sint:new M("rgba32sint",E.keyword,"rgba32sint"),rgba32float:new M("rgba32float",E.keyword,"rgba32float"),static_assert:new M("static_assert",E.keyword,"static_assert")},v.tokens={decimal_float_literal:new M("decimal_float_literal",E.token,/((-?[0-9]*\.[0-9]+|-?[0-9]+\.[0-9]*)((e|E)(\+|-)?[0-9]+)?f?)|(-?[0-9]+(e|E)(\+|-)?[0-9]+f?)|([0-9]+f)/),hex_float_literal:new M("hex_float_literal",E.token,/-?0x((([0-9a-fA-F]*\.[0-9a-fA-F]+|[0-9a-fA-F]+\.[0-9a-fA-F]*)((p|P)(\+|-)?[0-9]+f?)?)|([0-9a-fA-F]+(p|P)(\+|-)?[0-9]+f?))/),int_literal:new M("int_literal",E.token,/-?0x[0-9a-fA-F]+|0i?|-?[1-9][0-9]*i?/),uint_literal:new M("uint_literal",E.token,/0x[0-9a-fA-F]+u|0u|[1-9][0-9]*u/),ident:new M("ident",E.token,/[_a-zA-Z][0-9a-zA-Z_]*/),and:new M("and",E.token,"&"),and_and:new M("and_and",E.token,"&&"),arrow:new M("arrow ",E.token,"->"),attr:new M("attr",E.token,"@"),attr_left:new M("attr_left",E.token,"[["),attr_right:new M("attr_right",E.token,"]]"),forward_slash:new M("forward_slash",E.token,"/"),bang:new M("bang",E.token,"!"),bracket_left:new M("bracket_left",E.token,"["),bracket_right:new M("bracket_right",E.token,"]"),brace_left:new M("brace_left",E.token,"{"),brace_right:new M("brace_right",E.token,"}"),colon:new M("colon",E.token,":"),comma:new M("comma",E.token,","),equal:new M("equal",E.token,"="),equal_equal:new M("equal_equal",E.token,"=="),not_equal:new M("not_equal",E.token,"!="),greater_than:new M("greater_than",E.token,">"),greater_than_equal:new M("greater_than_equal",E.token,">="),shift_right:new M("shift_right",E.token,">>"),less_than:new M("less_than",E.token,"<"),less_than_equal:new M("less_than_equal",E.token,"<="),shift_left:new M("shift_left",E.token,"<<"),modulo:new M("modulo",E.token,"%"),minus:new M("minus",E.token,"-"),minus_minus:new M("minus_minus",E.token,"--"),period:new M("period",E.token,"."),plus:new M("plus",E.token,"+"),plus_plus:new M("plus_plus",E.token,"++"),or:new M("or",E.token,"|"),or_or:new M("or_or",E.token,"||"),paren_left:new M("paren_left",E.token,"("),paren_right:new M("paren_right",E.token,")"),semicolon:new M("semicolon",E.token,";"),star:new M("star",E.token,"*"),tilde:new M("tilde",E.token,"~"),underscore:new M("underscore",E.token,"_"),xor:new M("xor",E.token,"^"),plus_equal:new M("plus_equal",E.token,"+="),minus_equal:new M("minus_equal",E.token,"-="),times_equal:new M("times_equal",E.token,"*="),division_equal:new M("division_equal",E.token,"/="),modulo_equal:new M("modulo_equal",E.token,"%="),and_equal:new M("and_equal",E.token,"&="),or_equal:new M("or_equal",E.token,"|="),xor_equal:new M("xor_equal",E.token,"^="),shift_right_equal:new M("shift_right_equal",E.token,">>="),shift_left_equal:new M("shift_left_equal",E.token,"<<=")},v.simpleTokens={"@":G.tokens.attr,"{":G.tokens.brace_left,"}":G.tokens.brace_right,":":G.tokens.colon,",":G.tokens.comma,"(":G.tokens.paren_left,")":G.tokens.paren_right,";":G.tokens.semicolon},v.literalTokens={"&":G.tokens.and,"&&":G.tokens.and_and,"->":G.tokens.arrow,"[[":G.tokens.attr_left,"]]":G.tokens.attr_right,"/":G.tokens.forward_slash,"!":G.tokens.bang,"[":G.tokens.bracket_left,"]":G.tokens.bracket_right,"=":G.tokens.equal,"==":G.tokens.equal_equal,"!=":G.tokens.not_equal,">":G.tokens.greater_than,">=":G.tokens.greater_than_equal,">>":G.tokens.shift_right,"<":G.tokens.less_than,"<=":G.tokens.less_than_equal,"<<":G.tokens.shift_left,"%":G.tokens.modulo,"-":G.tokens.minus,"--":G.tokens.minus_minus,".":G.tokens.period,"+":G.tokens.plus,"++":G.tokens.plus_plus,"|":G.tokens.or,"||":G.tokens.or_or,"*":G.tokens.star,"~":G.tokens.tilde,_:G.tokens.underscore,"^":G.tokens.xor,"+=":G.tokens.plus_equal,"-=":G.tokens.minus_equal,"*=":G.tokens.times_equal,"/=":G.tokens.division_equal,"%=":G.tokens.modulo_equal,"&=":G.tokens.and_equal,"|=":G.tokens.or_equal,"^=":G.tokens.xor_equal,">>=":G.tokens.shift_right_equal,"<<=":G.tokens.shift_left_equal},v.regexTokens={decimal_float_literal:G.tokens.decimal_float_literal,hex_float_literal:G.tokens.hex_float_literal,int_literal:G.tokens.int_literal,uint_literal:G.tokens.uint_literal,ident:G.tokens.ident},v.storage_class=[G.keywords.function,G.keywords.private,G.keywords.workgroup,G.keywords.uniform,G.keywords.storage],v.access_mode=[G.keywords.read,G.keywords.write,G.keywords.read_write],v.sampler_type=[G.keywords.sampler,G.keywords.sampler_comparison],v.sampled_texture_type=[G.keywords.texture_1d,G.keywords.texture_2d,G.keywords.texture_2d_array,G.keywords.texture_3d,G.keywords.texture_cube,G.keywords.texture_cube_array],v.multisampled_texture_type=[G.keywords.texture_multisampled_2d],v.storage_texture_type=[G.keywords.texture_storage_1d,G.keywords.texture_storage_2d,G.keywords.texture_storage_2d_array,G.keywords.texture_storage_3d],v.depth_texture_type=[G.keywords.texture_depth_2d,G.keywords.texture_depth_2d_array,G.keywords.texture_depth_cube,G.keywords.texture_depth_cube_array,G.keywords.texture_depth_multisampled_2d],v.texture_external_type=[G.keywords.texture_external],v.any_texture_type=[...G.sampled_texture_type,...G.multisampled_texture_type,...G.storage_texture_type,...G.depth_texture_type,...G.texture_external_type],v.texel_format=[G.keywords.r8unorm,G.keywords.r8snorm,G.keywords.r8uint,G.keywords.r8sint,G.keywords.r16uint,G.keywords.r16sint,G.keywords.r16float,G.keywords.rg8unorm,G.keywords.rg8snorm,G.keywords.rg8uint,G.keywords.rg8sint,G.keywords.r32uint,G.keywords.r32sint,G.keywords.r32float,G.keywords.rg16uint,G.keywords.rg16sint,G.keywords.rg16float,G.keywords.rgba8unorm,G.keywords.rgba8unorm_srgb,G.keywords.rgba8snorm,G.keywords.rgba8uint,G.keywords.rgba8sint,G.keywords.bgra8unorm,G.keywords.bgra8unorm_srgb,G.keywords.rgb10a2unorm,G.keywords.rg11b10float,G.keywords.rg32uint,G.keywords.rg32sint,G.keywords.rg32float,G.keywords.rgba16uint,G.keywords.rgba16sint,G.keywords.rgba16float,G.keywords.rgba32uint,G.keywords.rgba32sint,G.keywords.rgba32float],v.const_literal=[G.tokens.int_literal,G.tokens.uint_literal,G.tokens.decimal_float_literal,G.tokens.hex_float_literal,G.keywords.true,G.keywords.false],v.literal_or_ident=[G.tokens.ident,G.tokens.int_literal,G.tokens.uint_literal,G.tokens.decimal_float_literal,G.tokens.hex_float_literal],v.element_count_expression=[G.tokens.int_literal,G.tokens.uint_literal,G.tokens.ident],v.template_types=[G.keywords.vec2,G.keywords.vec3,G.keywords.vec4,G.keywords.mat2x2,G.keywords.mat2x3,G.keywords.mat2x4,G.keywords.mat3x2,G.keywords.mat3x3,G.keywords.mat3x4,G.keywords.mat4x2,G.keywords.mat4x3,G.keywords.mat4x4,G.keywords.atomic,G.keywords.bitcast,...G.any_texture_type],v.attribute_name=[G.tokens.ident,G.keywords.block,G.keywords.diagnostic],v.assignment_operators=[G.tokens.equal,G.tokens.plus_equal,G.tokens.minus_equal,G.tokens.times_equal,G.tokens.division_equal,G.tokens.modulo_equal,G.tokens.and_equal,G.tokens.or_equal,G.tokens.xor_equal,G.tokens.shift_right_equal,G.tokens.shift_left_equal],v.increment_operators=[G.tokens.plus_plus,G.tokens.minus_minus];class sa{constructor(e,t,r){this.type=e,this.lexeme=t,this.line=r}toString(){return this.lexeme}isTemplateType(){return v.template_types.indexOf(this.type)!=-1}isArrayType(){return this.type==v.keywords.array}isArrayOrTemplateType(){return this.isArrayType()||this.isTemplateType()}}class ed{constructor(e){this._tokens=[],this._start=0,this._current=0,this._line=1,this._source=e??""}scanTokens(){for(;!this._isAtEnd();)if(this._start=this._current,!this.scanToken())throw`Invalid syntax at line ${this._line}`;return this._tokens.push(new sa(v.eof,"",this._line)),this._tokens}scanToken(){let e=this._advance();if(e==` -`)return this._line++,!0;if(this._isWhitespace(e))return!0;if(e=="/"){if(this._peekAhead()=="/"){for(;e!=` -`;){if(this._isAtEnd())return!0;e=this._advance()}return this._line++,!0}if(this._peekAhead()=="*"){this._advance();let o=1;for(;o>0;){if(this._isAtEnd())return!0;if(e=this._advance(),e==` -`)this._line++;else if(e=="*"){if(this._peekAhead()=="/"&&(this._advance(),o--,o==0))return!0}else e=="/"&&this._peekAhead()=="*"&&(this._advance(),o++)}return!0}}const t=v.simpleTokens[e];if(t)return this._addToken(t),!0;let r=v.none;const n=this._isAlpha(e),i=e==="_";if(this._isAlphaNumeric(e)){let o=this._peekAhead();for(;this._isAlphaNumeric(o);)e+=this._advance(),o=this._peekAhead()}if(n){const o=v.keywords[e];if(o)return this._addToken(o),!0}if(n||i)return this._addToken(v.tokens.ident),!0;for(;;){let o=this._findType(e);const u=this._peekAhead();if(e==">"&&(u==">"||u=="=")){let l=!1,m=this._tokens.length-1;for(let b=0;b<5&&m>=0;++b,--m)if(this._tokens[m].type===v.tokens.less_than){m>0&&this._tokens[m-1].isArrayOrTemplateType()&&(l=!0);break}if(l)return this._addToken(o),!0}if(o===v.none){let l=e,m=0;const b=2;for(let d=0;d=this._source.length}_isAlpha(e){return e>="a"&&e<="z"||e>="A"&&e<="Z"}_isAlphaNumeric(e){return e>="a"&&e<="z"||e>="A"&&e<="Z"||e=="_"||e>="0"&&e<="9"}_isWhitespace(e){return e==" "||e==" "||e=="\r"}_advance(e=0){let t=this._source[this._current];return e=e||0,e++,this._current+=e,t}_peekAhead(e=0){return e=e||0,this._current+e>=this._source.length?"\0":this._source[this._current+e]}_addToken(e){const t=this._source.substring(this._start,this._current);this._tokens.push(new sa(e,t,this._line))}}class td{constructor(){this._tokens=[],this._current=0,this._currentLine=0,this._context=new Sl,this._deferArrayCountEval=[]}parse(e){this._initialize(e),this._deferArrayCountEval.length=0;const t=[];for(;!this._isAtEnd();){const r=this._global_decl_or_directive();if(!r)break;t.push(r)}if(this._deferArrayCountEval.length>0){for(const r of this._deferArrayCountEval){const n=r.arrayType,i=r.countNode;if(i instanceof In){const o=i.name,u=this._context.constants.get(o);if(u)try{const l=u.evaluate(this._context);n.count=l}catch{}}}this._deferArrayCountEval.length=0}return t}_initialize(e){if(e)if(typeof e=="string"){const t=new ed(e);this._tokens=t.scanTokens()}else this._tokens=e;else this._tokens=[];this._current=0}_error(e,t){return{token:e,message:t,toString:function(){return`${t}`}}}_isAtEnd(){return this._current>=this._tokens.length||this._peek().type==v.eof}_match(e){if(e instanceof M)return!!this._check(e)&&(this._advance(),!0);for(let t=0,r=e.length;t'.");const n=this._paren_expression();return new jl(r,n)}const e=this._type_decl(),t=this._argument_expression_list();return new Kl(e,t)}_argument_expression_list(){if(!this._match(v.tokens.paren_left))return null;const e=[];do{if(this._check(v.tokens.paren_right))break;const t=this._short_circuit_or_expression();e.push(t)}while(this._match(v.tokens.comma));return this._consume(v.tokens.paren_right,"Expected ')' for agument list"),e}_optional_paren_expression(){this._match(v.tokens.paren_left);const e=this._short_circuit_or_expression();return this._match(v.tokens.paren_right),new Zo([e])}_paren_expression(){this._consume(v.tokens.paren_left,"Expected '('.");const e=this._short_circuit_or_expression();return this._consume(v.tokens.paren_right,"Expected ')'."),new Zo([e])}_struct_decl(){if(!this._match(v.keywords.struct))return null;const e=this._currentLine,t=this._consume(v.tokens.ident,"Expected name for struct.").toString();this._consume(v.tokens.brace_left,"Expected '{' for struct body.");const r=[];for(;!this._check(v.tokens.brace_right);){const o=this._attribute(),u=this._consume(v.tokens.ident,"Expected variable name.").toString();this._consume(v.tokens.colon,"Expected ':' for struct member type.");const l=this._attribute(),m=this._type_decl();m!=null&&(m.attributes=l),this._check(v.tokens.brace_right)?this._match(v.tokens.comma):this._consume(v.tokens.comma,"Expected ',' for struct member."),r.push(new Zl(u,m,o))}this._consume(v.tokens.brace_right,"Expected '}' after struct body.");const n=this._currentLine,i=new Lt(t,r,e,n);return this._context.structs.set(t,i),i}_global_variable_decl(){const e=this._variable_decl();return e&&this._match(v.tokens.equal)&&(e.value=this._const_expression()),e}_override_variable_decl(){const e=this._override_decl();return e&&this._match(v.tokens.equal)&&(e.value=this._const_expression()),e}_global_const_decl(){if(!this._match(v.keywords.const))return null;const e=this._consume(v.tokens.ident,"Expected variable name");let t=null;if(this._match(v.tokens.colon)){const i=this._attribute();t=this._type_decl(),t!=null&&(t.attributes=i)}let r=null;if(this._match(v.tokens.equal)){const i=this._short_circuit_or_expression();if(i instanceof er)r=i;else if(i instanceof qo&&i.initializer instanceof er)r=i.initializer;else try{const o=i.evaluate(this._context);r=new Qo(o)}catch{r=i}}const n=new zo(e.toString(),t,"","",r);return this._context.constants.set(n.name,n),n}_global_let_decl(){if(!this._match(v.keywords.let))return null;const e=this._consume(v.tokens.ident,"Expected variable name");let t=null;if(this._match(v.tokens.colon)){const n=this._attribute();t=this._type_decl(),t!=null&&(t.attributes=n)}let r=null;return this._match(v.tokens.equal)&&(r=this._const_expression()),new On(e.toString(),t,"","",r)}_const_expression(){if(this._match(v.const_literal))return new Wo(this._previous().toString());const e=this._type_decl();this._consume(v.tokens.paren_left,"Expected '('.");let t=[];for(;!this._check(v.tokens.paren_right)&&(t.push(this._const_expression()),this._check(v.tokens.comma));)this._advance();return this._consume(v.tokens.paren_right,"Expected ')'."),new er(e,t)}_variable_decl(){if(!this._match(v.keywords.var))return null;let e="",t="";this._match(v.tokens.less_than)&&(e=this._consume(v.storage_class,"Expected storage_class.").toString(),this._match(v.tokens.comma)&&(t=this._consume(v.access_mode,"Expected access_mode.").toString()),this._consume(v.tokens.greater_than,"Expected '>'."));const r=this._consume(v.tokens.ident,"Expected variable name");let n=null;if(this._match(v.tokens.colon)){const i=this._attribute();n=this._type_decl(),n!=null&&(n.attributes=i)}return new Rt(r.toString(),n,e,t,null)}_override_decl(){if(!this._match(v.keywords.override))return null;const e=this._consume(v.tokens.ident,"Expected variable name");let t=null;if(this._match(v.tokens.colon)){const r=this._attribute();t=this._type_decl(),t!=null&&(t.attributes=r)}return new Jo(e.toString(),t,null)}_diagnostic(){this._consume(v.tokens.paren_left,"Expected '('");const e=this._consume(v.tokens.ident,"Expected severity control name.");this._consume(v.tokens.comma,"Expected ','");const t=this._consume(v.tokens.ident,"Expected diagnostic rule name.");return this._consume(v.tokens.paren_right,"Expected ')'"),new Nl(e.toString(),t.toString())}_enable_directive(){const e=this._consume(v.tokens.ident,"identity expected.");return new Ul(e.toString())}_requires_directive(){const e=[this._consume(v.tokens.ident,"identity expected.").toString()];for(;this._match(v.tokens.comma);){const t=this._consume(v.tokens.ident,"identity expected.");e.push(t.toString())}return new kl(e)}_type_alias(){const e=this._consume(v.tokens.ident,"identity expected.");this._consume(v.tokens.equal,"Expected '=' for type alias.");let t=this._type_decl();if(t===null)throw this._error(this._peek(),"Expected Type for Alias.");this._context.aliases.has(t.name)&&(t=this._context.aliases.get(t.name).type);const r=new Ko(e.toString(),t);return this._context.aliases.set(r.name,r),r}_type_decl(){if(this._check([v.tokens.ident,...v.texel_format,v.keywords.bool,v.keywords.f32,v.keywords.i32,v.keywords.u32])){const r=this._advance(),n=r.toString();return this._context.structs.has(n)?this._context.structs.get(n):this._context.aliases.has(n)?this._context.aliases.get(n).type:new Gt(r.toString())}let e=this._texture_sampler_types();if(e)return e;if(this._check(v.template_types)){let r=this._advance().toString(),n=null,i=null;return this._match(v.tokens.less_than)&&(n=this._type_decl(),i=null,this._match(v.tokens.comma)&&(i=this._consume(v.access_mode,"Expected access_mode for pointer").toString()),this._consume(v.tokens.greater_than,"Expected '>' for type.")),new Xo(r,n,i)}if(this._match(v.keywords.ptr)){let r=this._previous().toString();this._consume(v.tokens.less_than,"Expected '<' for pointer.");const n=this._consume(v.storage_class,"Expected storage_class for pointer");this._consume(v.tokens.comma,"Expected ',' for pointer.");const i=this._type_decl();let o=null;return this._match(v.tokens.comma)&&(o=this._consume(v.access_mode,"Expected access_mode for pointer").toString()),this._consume(v.tokens.greater_than,"Expected '>' for pointer."),new zl(r,n.toString(),i,o)}const t=this._attribute();if(this._match(v.keywords.array)){let r=null,n=-1;const i=this._previous();let o=null;if(this._match(v.tokens.less_than)){r=this._type_decl(),this._context.aliases.has(r.name)&&(r=this._context.aliases.get(r.name).type);let l="";if(this._match(v.tokens.comma)){o=this._shift_expression();try{l=o.evaluate(this._context).toString(),o=null}catch{l="1"}}this._consume(v.tokens.greater_than,"Expected '>' for array."),n=l?parseInt(l):0}const u=new Yo(i.toString(),t,r,n);return o&&this._deferArrayCountEval.push({arrayType:u,countNode:o}),u}return null}_texture_sampler_types(){if(this._match(v.sampler_type))return new wr(this._previous().toString(),null,null);if(this._match(v.depth_texture_type))return new wr(this._previous().toString(),null,null);if(this._match(v.sampled_texture_type)||this._match(v.multisampled_texture_type)){const e=this._previous();this._consume(v.tokens.less_than,"Expected '<' for sampler type.");const t=this._type_decl();return this._consume(v.tokens.greater_than,"Expected '>' for sampler type."),new wr(e.toString(),t,null)}if(this._match(v.storage_texture_type)){const e=this._previous();this._consume(v.tokens.less_than,"Expected '<' for sampler type.");const t=this._consume(v.texel_format,"Invalid texel format.").toString();this._consume(v.tokens.comma,"Expected ',' after texel format.");const r=this._consume(v.access_mode,"Expected access mode for storage texture type.").toString();return this._consume(v.tokens.greater_than,"Expected '>' for sampler type."),new wr(e.toString(),t,r)}return null}_attribute(){let e=[];for(;this._match(v.tokens.attr);){const t=this._consume(v.attribute_name,"Expected attribute name"),r=new ra(t.toString(),null);if(this._match(v.tokens.paren_left)){if(r.value=this._consume(v.literal_or_ident,"Expected attribute value").toString(),this._check(v.tokens.comma)){this._advance();do{const n=this._consume(v.literal_or_ident,"Expected attribute value").toString();r.value instanceof Array||(r.value=[r.value]),r.value.push(n)}while(this._match(v.tokens.comma))}this._consume(v.tokens.paren_right,"Expected ')'")}e.push(r)}for(;this._match(v.tokens.attr_left);){if(!this._check(v.tokens.attr_right))do{const t=this._consume(v.attribute_name,"Expected attribute name"),r=new ra(t.toString(),null);if(this._match(v.tokens.paren_left)){if(r.value=[this._consume(v.literal_or_ident,"Expected attribute value").toString()],this._check(v.tokens.comma)){this._advance();do{const n=this._consume(v.literal_or_ident,"Expected attribute value").toString();r.value.push(n)}while(this._match(v.tokens.comma))}this._consume(v.tokens.paren_right,"Expected ')'")}e.push(r)}while(this._match(v.tokens.comma));this._consume(v.tokens.attr_right,"Expected ']]' after attribute declarations")}return e.length==0?null:e}}class tr{constructor(e,t){this.name=e,this.attributes=t,this.size=0}get isArray(){return!1}get isStruct(){return!1}get isTemplate(){return!1}}class na{constructor(e,t,r){this.name=e,this.type=t,this.attributes=r,this.offset=0,this.size=0}get isArray(){return this.type.isArray}get isStruct(){return this.type.isStruct}get isTemplate(){return this.type.isTemplate}get align(){return this.type.isStruct?this.type.align:0}get members(){return this.type.isStruct?this.type.members:null}get format(){return this.type.isArray||this.type.isTemplate?this.type.format:null}get count(){return this.type.isArray?this.type.count:0}get stride(){return this.type.isArray?this.type.stride:this.size}}class ns extends tr{constructor(e,t){super(e,t),this.members=[],this.align=0,this.startLine=-1,this.endLine=-1,this.inUse=!1}get isStruct(){return!0}}class Fn extends tr{constructor(e,t){super(e,t),this.count=0,this.stride=0}get isArray(){return!0}}class ia extends tr{constructor(e,t,r,n){super(e,r),this.format=t,this.access=n}get isTemplate(){return!0}}(function(s){s[s.Uniform=0]="Uniform",s[s.Storage=1]="Storage",s[s.Texture=2]="Texture",s[s.Sampler=3]="Sampler",s[s.StorageTexture=4]="StorageTexture"})(be||(be={}));class is{constructor(e,t,r,n,i,o,u){this.name=e,this.type=t,this.group=r,this.binding=n,this.attributes=i,this.resourceType=o,this.access=u}get isArray(){return this.type.isArray}get isStruct(){return this.type.isStruct}get isTemplate(){return this.type.isTemplate}get size(){return this.type.size}get align(){return this.type.isStruct?this.type.align:0}get members(){return this.type.isStruct?this.type.members:null}get format(){return this.type.isArray||this.type.isTemplate?this.type.format:null}get count(){return this.type.isArray?this.type.count:0}get stride(){return this.type.isArray?this.type.stride:this.size}}class rd{constructor(e,t){this.name=e,this.type=t}}class os{constructor(e,t){this.align=e,this.size=t}}class sd{constructor(e,t,r,n){this.name=e,this.type=t,this.locationType=r,this.location=n,this.interpolation=null}}class oa{constructor(e,t,r,n){this.name=e,this.type=t,this.locationType=r,this.location=n}}class nd{constructor(e,t=null){this.stage=null,this.inputs=[],this.outputs=[],this.resources=[],this.startLine=-1,this.endLine=-1,this.inUse=!1,this.calls=new Set,this.name=e,this.stage=t}}class id{constructor(){this.vertex=[],this.fragment=[],this.compute=[]}}class od{constructor(e,t,r,n){this.name=e,this.type=t,this.attributes=r,this.id=n}}class ad{constructor(e){this.resources=null,this.inUse=!1,this.info=null,this.node=e}}class at{constructor(e){this.uniforms=[],this.storage=[],this.textures=[],this.samplers=[],this.aliases=[],this.overrides=[],this.structs=[],this.entry=new id,this.functions=[],this._types=new Map,this._functions=new Map,e&&this.update(e)}_isStorageTexture(e){return e.name=="texture_storage_1d"||e.name=="texture_storage_2d"||e.name=="texture_storage_2d_array"||e.name=="texture_storage_3d"}update(e){const t=new td().parse(e);for(const r of t)r instanceof Ln&&this._functions.set(r.name,new ad(r));for(const r of t)if(r instanceof Lt){const n=this._getTypeInfo(r,null);n instanceof ns&&this.structs.push(n)}for(const r of t)if(r instanceof Ko)this.aliases.push(this._getAliasInfo(r));else if(r instanceof Jo){const n=r,i=this._getAttributeNum(n.attributes,"id",0),o=n.type!=null?this._getTypeInfo(n.type,n.attributes):null;this.overrides.push(new od(n.name,o,n.attributes,i))}else if(this._isUniformVar(r)){const n=r,i=this._getAttributeNum(n.attributes,"group",0),o=this._getAttributeNum(n.attributes,"binding",0),u=this._getTypeInfo(n.type,n.attributes),l=new is(n.name,u,i,o,n.attributes,be.Uniform,n.access);this.uniforms.push(l)}else if(this._isStorageVar(r)){const n=r,i=this._getAttributeNum(n.attributes,"group",0),o=this._getAttributeNum(n.attributes,"binding",0),u=this._getTypeInfo(n.type,n.attributes),l=this._isStorageTexture(u),m=new is(n.name,u,i,o,n.attributes,l?be.StorageTexture:be.Storage,n.access);this.storage.push(m)}else if(this._isTextureVar(r)){const n=r,i=this._getAttributeNum(n.attributes,"group",0),o=this._getAttributeNum(n.attributes,"binding",0),u=this._getTypeInfo(n.type,n.attributes),l=this._isStorageTexture(u),m=new is(n.name,u,i,o,n.attributes,l?be.StorageTexture:be.Texture,n.access);l?this.storage.push(m):this.textures.push(m)}else if(this._isSamplerVar(r)){const n=r,i=this._getAttributeNum(n.attributes,"group",0),o=this._getAttributeNum(n.attributes,"binding",0),u=this._getTypeInfo(n.type,n.attributes),l=new is(n.name,u,i,o,n.attributes,be.Sampler,n.access);this.samplers.push(l)}else if(r instanceof Ln){const n=this._getAttribute(r,"vertex"),i=this._getAttribute(r,"fragment"),o=this._getAttribute(r,"compute"),u=n||i||o,l=new nd(r.name,u==null?void 0:u.name);l.startLine=r.startLine,l.endLine=r.endLine,this.functions.push(l),this._functions.get(r.name).info=l,u&&(this._functions.get(r.name).inUse=!0,l.inUse=!0,l.resources=this._findResources(r,!!u),l.inputs=this._getInputs(r.args),l.outputs=this._getOutputs(r.returnType),this.entry[u.name].push(l))}for(const r of this._functions.values())r.info&&(r.info.inUse=r.inUse,this._addCalls(r.node,r.info.calls));for(const r of this.uniforms)this._markStructsInUse(r.type);for(const r of this.storage)this._markStructsInUse(r.type)}_markStructsInUse(e){if(e.isStruct){e.inUse=!0;for(const t of e.members)this._markStructsInUse(t.type)}else if(e.isArray)this._markStructsInUse(e.format);else if(e.isTemplate)this._markStructsInUse(e.format);else{const t=this._getAlias(e.name);t&&this._markStructsInUse(t)}}_addCalls(e,t){var r;for(const n of e.calls){const i=(r=this._functions.get(n.name))===null||r===void 0?void 0:r.info;i&&t.add(i)}}findResource(e,t){for(const r of this.uniforms)if(r.group==e&&r.binding==t)return r;for(const r of this.storage)if(r.group==e&&r.binding==t)return r;for(const r of this.textures)if(r.group==e&&r.binding==t)return r;for(const r of this.samplers)if(r.group==e&&r.binding==t)return r;return null}_findResource(e){for(const t of this.uniforms)if(t.name==e)return t;for(const t of this.storage)if(t.name==e)return t;for(const t of this.textures)if(t.name==e)return t;for(const t of this.samplers)if(t.name==e)return t;return null}_markStructsFromAST(e){const t=this._getTypeInfo(e,null);this._markStructsInUse(t)}_findResources(e,t){const r=[],n=this,i=[];return e.search(o=>{if(o instanceof rs)i.push({});else if(o instanceof ss)i.pop();else if(o instanceof Rt){const u=o;t&&u.type!==null&&this._markStructsFromAST(u.type),i.length>0&&(i[i.length-1][u.name]=u)}else if(o instanceof er){const u=o;t&&u.type!==null&&this._markStructsFromAST(u.type)}else if(o instanceof On){const u=o;t&&u.type!==null&&this._markStructsFromAST(u.type),i.length>0&&(i[i.length-1][u.name]=u)}else if(o instanceof In){const u=o;if(i.length>0&&i[i.length-1][u.name])return;const l=n._findResource(u.name);l&&r.push(l)}else if(o instanceof $o){const u=o,l=n._functions.get(u.name);l&&(t&&(l.inUse=!0),e.calls.add(l.node),l.resources===null&&(l.resources=n._findResources(l.node,t)),r.push(...l.resources))}else if(o instanceof jo){const u=o,l=n._functions.get(u.name);l&&(t&&(l.inUse=!0),e.calls.add(l.node),l.resources===null&&(l.resources=n._findResources(l.node,t)),r.push(...l.resources))}}),[...new Map(r.map(o=>[o.name,o])).values()]}getBindGroups(){const e=[];function t(r,n){r>=e.length&&(e.length=r+1),e[r]===void 0&&(e[r]=[]),n>=e[r].length&&(e[r].length=n+1)}for(const r of this.uniforms)t(r.group,r.binding),e[r.group][r.binding]=r;for(const r of this.storage)t(r.group,r.binding),e[r.group][r.binding]=r;for(const r of this.textures)t(r.group,r.binding),e[r.group][r.binding]=r;for(const r of this.samplers)t(r.group,r.binding),e[r.group][r.binding]=r;return e}_getOutputs(e,t=void 0){if(t===void 0&&(t=[]),e instanceof Lt)this._getStructOutputs(e,t);else{const r=this._getOutputInfo(e);r!==null&&t.push(r)}return t}_getStructOutputs(e,t){for(const r of e.members)if(r.type instanceof Lt)this._getStructOutputs(r.type,t);else{const n=this._getAttribute(r,"location")||this._getAttribute(r,"builtin");if(n!==null){const i=this._getTypeInfo(r.type,r.type.attributes),o=this._parseInt(n.value),u=new oa(r.name,i,n.name,o);t.push(u)}}}_getOutputInfo(e){const t=this._getAttribute(e,"location")||this._getAttribute(e,"builtin");if(t!==null){const r=this._getTypeInfo(e,e.attributes),n=this._parseInt(t.value);return new oa("",r,t.name,n)}return null}_getInputs(e,t=void 0){t===void 0&&(t=[]);for(const r of e)if(r.type instanceof Lt)this._getStructInputs(r.type,t);else{const n=this._getInputInfo(r);n!==null&&t.push(n)}return t}_getStructInputs(e,t){for(const r of e.members)if(r.type instanceof Lt)this._getStructInputs(r.type,t);else{const n=this._getInputInfo(r);n!==null&&t.push(n)}}_getInputInfo(e){const t=this._getAttribute(e,"location")||this._getAttribute(e,"builtin");if(t!==null){const r=this._getAttribute(e,"interpolation"),n=this._getTypeInfo(e.type,e.attributes),i=this._parseInt(t.value),o=new sd(e.name,n,t.name,i);return r!==null&&(o.interpolation=this._parseString(r.value)),o}return null}_parseString(e){return e instanceof Array&&(e=e[0]),e}_parseInt(e){e instanceof Array&&(e=e[0]);const t=parseInt(e);return isNaN(t)?e:t}_getAlias(e){for(const t of this.aliases)if(t.name==e)return t.type;return null}_getAliasInfo(e){return new rd(e.name,this._getTypeInfo(e.type,null))}_getTypeInfo(e,t){if(this._types.has(e))return this._types.get(e);if(e instanceof Yo){const n=e,i=this._getTypeInfo(n.format,n.attributes),o=new Fn(n.name,t);return o.format=i,o.count=n.count,this._types.set(e,o),this._updateTypeInfo(o),o}if(e instanceof Lt){const n=e,i=new ns(n.name,t);i.startLine=n.startLine,i.endLine=n.endLine;for(const o of n.members){const u=this._getTypeInfo(o.type,o.attributes);i.members.push(new na(o.name,u,o.attributes))}return this._types.set(e,i),this._updateTypeInfo(i),i}if(e instanceof wr){const n=e,i=n.format instanceof Gt,o=n.format?i?this._getTypeInfo(n.format,null):new tr(n.format,null):null,u=new ia(n.name,o,t,n.access);return this._types.set(e,u),this._updateTypeInfo(u),u}if(e instanceof Xo){const n=e,i=n.format?this._getTypeInfo(n.format,null):null,o=new ia(n.name,i,t,n.access);return this._types.set(e,o),this._updateTypeInfo(o),o}const r=new tr(e.name,t);return this._types.set(e,r),this._updateTypeInfo(r),r}_updateTypeInfo(e){var t,r;const n=this._getTypeSize(e);if(e.size=(t=n==null?void 0:n.size)!==null&&t!==void 0?t:0,e instanceof Fn){const i=this._getTypeSize(e.format);e.stride=(r=i==null?void 0:i.size)!==null&&r!==void 0?r:0,this._updateTypeInfo(e.format)}e instanceof ns&&this._updateStructInfo(e)}_updateStructInfo(e){var t;let r=0,n=0,i=0,o=0;for(let u=0,l=e.members.length;u{const r=function(n,i,o){switch(i.resourceType){case be.Uniform:case be.Storage:case be.StorageTexture:return kn(n,i.type,o);default:return{size:0,type:i.type.name}}}(s,t,0);return[t.name,{typeDefinition:r,group:t.group,binding:t.binding,size:r.size}]}))}function aa(s,e,t){return{fields:Object.fromEntries(e.members.map(r=>[r.name,{offset:r.offset,type:kn(s,r.type,0)}])),size:e.size,offset:t}}function ud(s){var e;if(s.name.includes("depth"))return"depth";switch((e=s.format)==null?void 0:e.name){case"f32":return"float";case"i32":return"sint";case"u32":return"uint";default:throw new Error("unknown texture sample type")}}function ua(s){return s.name.includes("2d_array")?"2d-array":s.name.includes("cube_array")?"cube-array":s.name.includes("3d")?"3d":s.name.includes("1d")?"1d":s.name.includes("cube")?"cube":"2d"}function cd(s){switch(s.access){case"read":return"read-only";case"write":return"write-only";case"read_write":return"read-write";default:throw new Error("unknonw storage texture access")}}function ld(s){return s.name.endsWith("_comparison")?"comparison":"filtering"}function dd(s,e){const{binding:t,access:r,type:n}=s;switch(s.resourceType){case be.Uniform:return{binding:t,visibility:e,buffer:{...s.size&&{minBindingSize:s.size}}};case be.Storage:return{binding:t,visibility:e,buffer:{type:r===""||r==="read"?"read-only-storage":"storage",...s.size&&{minBindingSize:s.size}}};case be.Texture:{if(n.name==="texture_external")return{binding:t,visibility:e,externalTexture:{}};const i=n.name.includes("multisampled");return{binding:t,visibility:e,texture:{sampleType:ud(n),viewDimension:ua(n),multisampled:i}}}case be.Sampler:return{binding:t,visibility:e,sampler:{type:ld(n)}};case be.StorageTexture:return{binding:t,visibility:e,storageTexture:{access:cd(n),format:n.format.name,viewDimension:ua(n)}};default:throw new Error("unknown resource type")}}function Dn(s,e){const t={};for(const r of s)t[r.name]={stage:e,resources:r.resources.map(n=>{const{name:i,group:o}=n;return{name:i,group:o,entry:dd(n,e)}})};return t}function Ot(s){const e=new at(s),t=Object.fromEntries(e.structs.map(u=>[u.name,aa(e,u,0)])),r=rr(e,e.uniforms),n=rr(e,e.storage.filter(u=>u.resourceType===be.Storage)),i=rr(e,e.storage.filter(u=>u.resourceType===be.StorageTexture)),o=rr(e,e.textures.filter(u=>u.type.name!=="texture_external"));return{externalTextures:rr(e,e.textures.filter(u=>u.type.name==="texture_external")),samplers:rr(e,e.samplers),structs:t,storages:n,storageTextures:i,textures:o,uniforms:r,entryPoints:{...Dn(e.entry.vertex,GPUShaderStage.VERTEX),...Dn(e.entry.fragment,GPUShaderStage.FRAGMENT),...Dn(e.entry.compute,GPUShaderStage.COMPUTE)}}}function Un(s,e=""){if(!s)throw new Error(e)}function kn(s,e,t){if(e.isArray){Un(!e.isStruct,"struct array is invalid"),Un(!e.isStruct,"template array is invalid");const r=e;return{size:r.size,elementType:kn(s,r.format,t),numElements:r.count}}if(e.isStruct)return Un(!e.isTemplate,"template struct is invalid"),aa(s,e,t);{const r=e,n=e.isTemplate?`${r.name}<${r.format.name}>`:e.name;return{size:e.size,type:n}}}at._typeInfo={f16:{align:2,size:2},i32:{align:4,size:4},u32:{align:4,size:4},f32:{align:4,size:4},atomic:{align:4,size:4},vec2:{align:8,size:8},vec3:{align:16,size:12},vec4:{align:16,size:16},mat2x2:{align:8,size:16},mat3x2:{align:8,size:24},mat4x2:{align:8,size:32},mat2x3:{align:16,size:32},mat3x3:{align:16,size:48},mat4x3:{align:16,size:64},mat2x4:{align:16,size:32},mat3x4:{align:16,size:48},mat4x4:{align:16,size:64}},at._textureTypes=v.any_texture_type.map(s=>s.name),at._samplerTypes=v.sampler_type.map(s=>s.name);const hd=new Map([[Int8Array,{formats:["sint8","snorm8"],defaultForType:1}],[Uint8Array,{formats:["uint8","unorm8"],defaultForType:1}],[Int16Array,{formats:["sint16","snorm16"],defaultForType:1}],[Uint16Array,{formats:["uint16","unorm16"],defaultForType:1}],[Int32Array,{formats:["sint32","snorm32"],defaultForType:0}],[Uint32Array,{formats:["uint32","unorm32"],defaultForType:0}],[Float32Array,{formats:["float32","float32"],defaultForType:0}]]);new Map([...hd.entries()].map(([s,{formats:[e,t]}])=>[[e,s],[t,s]]).flat());class fd{constructor(e,t){this.normal=e,this.d=t}normalize(){const e=D.len(this.normal);D.normalize(this.normal,this.normal),this.d/=e}checkIfBBoxIsInside(e){const t=this.normal[0]>=0?e.maxX:e.minX,r=this.normal[1]>=0?e.maxY:e.minY,n=this.normal[2]>=0?e.maxZ:e.minZ;return this.normal[0]*t+this.normal[1]*r+this.normal[2]*n+this.d>=0}}let ca={};const la=new WeakMap,da={metric:[{from:0,to:1e3,unit:"B",long:"bytes"},{from:1e3,to:1e6,unit:"kB",long:"kilobytes"},{from:1e6,to:1e9,unit:"MB",long:"megabytes"},{from:1e9,to:1e12,unit:"GB",long:"gigabytes"},{from:1e12,to:1e15,unit:"TB",long:"terabytes"},{from:1e15,to:1e18,unit:"PB",long:"petabytes"},{from:1e18,to:1e21,unit:"EB",long:"exabytes"},{from:1e21,to:1e24,unit:"ZB",long:"zettabytes"},{from:1e24,to:1e27,unit:"YB",long:"yottabytes"}],metric_octet:[{from:0,to:1e3,unit:"o",long:"octets"},{from:1e3,to:1e6,unit:"ko",long:"kilooctets"},{from:1e6,to:1e9,unit:"Mo",long:"megaoctets"},{from:1e9,to:1e12,unit:"Go",long:"gigaoctets"},{from:1e12,to:1e15,unit:"To",long:"teraoctets"},{from:1e15,to:1e18,unit:"Po",long:"petaoctets"},{from:1e18,to:1e21,unit:"Eo",long:"exaoctets"},{from:1e21,to:1e24,unit:"Zo",long:"zettaoctets"},{from:1e24,to:1e27,unit:"Yo",long:"yottaoctets"}],iec:[{from:0,to:Math.pow(1024,1),unit:"B",long:"bytes"},{from:Math.pow(1024,1),to:Math.pow(1024,2),unit:"KiB",long:"kibibytes"},{from:Math.pow(1024,2),to:Math.pow(1024,3),unit:"MiB",long:"mebibytes"},{from:Math.pow(1024,3),to:Math.pow(1024,4),unit:"GiB",long:"gibibytes"},{from:Math.pow(1024,4),to:Math.pow(1024,5),unit:"TiB",long:"tebibytes"},{from:Math.pow(1024,5),to:Math.pow(1024,6),unit:"PiB",long:"pebibytes"},{from:Math.pow(1024,6),to:Math.pow(1024,7),unit:"EiB",long:"exbibytes"},{from:Math.pow(1024,7),to:Math.pow(1024,8),unit:"ZiB",long:"zebibytes"},{from:Math.pow(1024,8),to:Math.pow(1024,9),unit:"YiB",long:"yobibytes"}],iec_octet:[{from:0,to:Math.pow(1024,1),unit:"o",long:"octets"},{from:Math.pow(1024,1),to:Math.pow(1024,2),unit:"Kio",long:"kibioctets"},{from:Math.pow(1024,2),to:Math.pow(1024,3),unit:"Mio",long:"mebioctets"},{from:Math.pow(1024,3),to:Math.pow(1024,4),unit:"Gio",long:"gibioctets"},{from:Math.pow(1024,4),to:Math.pow(1024,5),unit:"Tio",long:"tebioctets"},{from:Math.pow(1024,5),to:Math.pow(1024,6),unit:"Pio",long:"pebioctets"},{from:Math.pow(1024,6),to:Math.pow(1024,7),unit:"Eio",long:"exbioctets"},{from:Math.pow(1024,7),to:Math.pow(1024,8),unit:"Zio",long:"zebioctets"},{from:Math.pow(1024,8),to:Math.pow(1024,9),unit:"Yio",long:"yobioctets"}]};class pd{constructor(e,t){t=Object.assign({units:"metric",precision:1,locale:void 0},ca,t),la.set(this,t),Object.assign(da,t.customUnits);const r=e<0?"-":"";e=Math.abs(e);const n=da[t.units];if(!n)throw new Error(`Invalid units specified: ${t.units}`);{const i=n.find(o=>e>=o.from&&et!=e.id),e.parent=null,this.onChildRemove(e)}onChildAdd(e){var t;(t=this.parent)==null||t.onChildAdd(e)}onChildRemove(e){var t;(t=this.parent)==null||t.onChildRemove(e)}traverse(e,t=!0){if(e(this),t)for(const r of this.children)r.traverse(e,t)}findChild(e){if(e(this))return this;for(const t of this.children)if(t.findChild(e))return t}findChildByLabel(e){return this.findChild(({label:t})=>e===t)}findChildById(e){return this.findChild(({id:t})=>e===t)}preRender(e){}onRender(e){}postRender(e){}render(e){this.visible&&(this.preRender(e),this.onRender(e),this.postRender(e))}get worldPosition(){return this.getWorldPosition()}getWorldPosition(){return this._worldPosition[0]=this.worldMatrix[12],this._worldPosition[1]=this.worldMatrix[13],this._worldPosition[2]=this.worldMatrix[14],this._worldPosition}setPositionAsVec3(e){return D.clone(e,this._position),this.matrixNeedsUpdate=!0,this}setPosition(e,t,r){return this._position[0]=e,this._position[1]=t,this._position[2]=r,this.matrixNeedsUpdate=!0,this}setPositionX(e){return this._position[0]=e,this.matrixNeedsUpdate=!0,this}setPositionY(e){return this._position[1]=e,this.matrixNeedsUpdate=!0,this}setPositionZ(e){return this._position[2]=e,this.matrixNeedsUpdate=!0,this}get position(){return this.getPosition()}getPosition(){return this._position}getPositionX(){return this._position[0]}getPositionY(){return this._position[1]}getPositionZ(){return this._position[2]}setRotation(e,t,r){return this._rotation[0]=e,this._rotation[1]=t,this._rotation[2]=r,this.matrixNeedsUpdate=!0,this}setRotationX(e){return this._rotation[0]=e,this.matrixNeedsUpdate=!0,this}setRotationY(e){return this._rotation[1]=e,this.matrixNeedsUpdate=!0,this}setRotationZ(e){return this._rotation[2]=e,this.matrixNeedsUpdate=!0,this}get rotation(){return this.getRotation()}getRotation(){return this._rotation}getRotationX(){return this._rotation[0]}getRotationY(){return this._rotation[1]}getRotationZ(){return this._rotation[2]}setScale(e,t,r){return this._scale[0]=e,this._scale[1]=t,this._scale[2]=r,this.matrixNeedsUpdate=!0,this}setScaleX(e){return this._scale[0]=e,this.matrixNeedsUpdate=!0,this}setScaleY(e){return this._scale[1]=e,this.matrixNeedsUpdate=!0,this}setScaleZ(e){return this._scale[2]=e,this.matrixNeedsUpdate=!0,this}get scale(){return this.getScale()}getScale(){return this._scale}getScaleX(){return this._scale[0]}getScaleY(){return this._scale[1]}getScaleZ(){return this._scale[2]}}const Ne=Object.freeze({get Position(){return 0},get Normal(){return 1},get TexCoord(){return 2},get Tangent(){return 3}}),ue=Object.freeze({get CameraPlusOptionalLights(){return 0},get Model(){return 1},get PBRTextures(){return 2},get InstanceInputs(){return 3}}),ut=Object.freeze({get NormalMetallicRoughness(){return 0},get ColorReflectance(){return 1},get Velocity(){return 2}}),as=Object.freeze({get Default(){return 0}}),me=Object.freeze({get Albedo(){return 1},get Normal(){return 2},get MetallicRoughness(){return 3},get AO(){return 4}}),W=Object.freeze({get VertexInput(){return` - - struct VertexInput { - @location(${Ne.Position}) position: vec4f, - @location(${Ne.Normal}) normal: vec3f, - @location(${Ne.TexCoord}) uv: vec2f, - @location(${Ne.Tangent}) tangent: vec4f, - }; - - `},get VertexOutput(){return` - - struct VertexOutput { - @builtin(position) position: vec4f, - @location(0) worldPosition: vec3f, - @location(1) viewNormal: vec3f, - @location(2) uv: vec2f, - @location(3) viewTangent: vec3f, - @location(4) viewBitangent: vec3f, - @location(5) currFrameClipPos: vec4f, - @location(6) prevFrameClipPos: vec4f, - @location(7) @interpolate(flat) instanceId: u32, - }; - - `},get InstanceInput(){return` - struct InstanceInput { - worldMatrix: mat4x4f, - metallic: f32, - roughness: f32, - }; - `},get ModelUniform(){return` - - struct ModelUniform { - worldMatrix: mat4x4f, - prevFrameWorldMatrix: mat4x4f, - normalMatrix: mat3x3f, - baseColor: vec3f, - isReflective: u32, - metallic: f32, - roughness: f32, - }; - - `},get Camera(){return` - - struct Camera { - position: vec3f, - projectionMatrix: mat4x4f, - viewMatrix: mat4x4f, - projectionViewMatrix: mat4x4f, - inverseProjectionViewMatrix: mat4x4f, - inverseViewMatrix: mat4x4f, - inverseProjectionMatrix: mat4x4f, - prevFrameProjectionViewMatrix: mat4x4f, - viewportWidth: u32, - viewportHeight: u32, - jitterOffset: vec2f, - }; - - @must_use - fn calcWorldPos( - camera: Camera, - coord: vec2f, - depth: f32 - ) -> vec3f { - let ndcX = coord.x / f32(camera.viewportWidth) * 2.0 - 1.0; - let ndcY = (1.0 - coord.y / f32(camera.viewportHeight)) * 2.0 - 1.0; - let clipPos = vec4f(ndcX, ndcY, depth, 1.0); - - let worldSpacePos = camera.inverseProjectionViewMatrix * clipPos; - return worldSpacePos.xyz / worldSpacePos.w; - } - - @must_use - fn calcViewSpacePos( - camera: Camera, - coord: vec2f, - depth: f32 - ) -> vec3f { - let ndcX = coord.x / f32(camera.viewportWidth) * 2.0 - 1.0; - let ndcY = (1.0 - coord.y / f32(camera.viewportHeight)) * 2.0 - 1.0; - let clipPos = vec4f(ndcX, ndcY, depth, 1.0); - - let viewSpacePos = camera.inverseProjectionMatrix * clipPos; - return viewSpacePos.xyz / viewSpacePos.w; - } - - `},get GBufferOutput(){return` - - struct GBufferOutput { - @location(${ut.NormalMetallicRoughness}) normalMetallicRoughness: vec4f, - @location(${ut.ColorReflectance}) color: vec4f, - @location(${ut.Velocity}) velocity: vec4f, - }; - - `},get AABB(){return` - struct AABB { - min: vec3f, - max: vec3f, - }; - `},get Particle(){return` - struct Particle { - radius: f32, - position: vec3f, - origPosition: vec3f, - velocity: vec3f, - lifeSpeed: f32, - life: f32 - }; - `},get Light(){return` - - struct Light { - lightType: u32, // 0 - Directional Light, 1 - Point Light, 2 - Ambient Light - intensity: f32, - radius: f32, - position: vec3f, - color: vec3f, - }; - - `},get Material(){return` - - struct Material { - metallic: f32, - albedo: vec3f, - roughness: f32, - ambientOcclusion: f32, - }; - - `},get ShadowCascade(){return` - struct ShadowCascade { - projViewMatrix: mat4x4, - distance: f32, - }; - `},get CommonHelpers(){return` - - const WORLD_UP = vec3f(0.0, 1.0, 0.0); - const WORLD_FORWARD = vec3f(0.0, 0.0, 1.0); - const PI: f32 = 3.1415; - const TWO_PI: f32 = 6.2831; - const HALF_PI: f32 = 1.5707; - const DELTA_PHI: f32 = 0.01745; - const DELTA_THETA: f32 = 0.01745; - - const CUBE_NORMALS: array, 6> = array, 6>( - vec3(1.0, 0.0, 0.0), - vec3(-1.0, 0.0, 0.0), - vec3(0.0, 1.0, 0.0), - vec3(0.0, -1.0, 0.0), - vec3(0.0, 0.0, 1.0), - vec3(0.0, 0.0, -1.0) - ); - - const CUBE_UPS: array, 6> = array, 6>( - vec3(0.0, 1.0, 0.0), - vec3(0.0, 1.0, 0.0), - vec3(0.0, 0.0, -1.0), - vec3(0.0, 0.0, 1.0), - vec3(0.0, 1.0, 0.0), - vec3(0.0, 1.0, 0.0) - ); - - const CUBE_ROTATIONS: array, 6> = array, 6>( - vec4(0.0, 1.0, 0.0, HALF_PI), - vec4(0.0, 1.0, 0.0, -HALF_PI), - vec4(1.0, 0.0, 0.0, -HALF_PI), - vec4(1.0, 0.0, 0.0, HALF_PI), - vec4(0.0, 0.0, 1.0, 0.0), - vec4(0.0, 1.0, 0.0, PI) - ); - `},get MathHelpers(){return` - - @must_use - fn rotateAxisAngle(inAxis: vec3f, angle: f32) -> mat3x3f { - let axis = normalize(inAxis); - let s = sin(angle); - let c = cos(angle); - let oc = 1.0 - c; - - return mat3x3f( - oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, - oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, - oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c - ); - } - - `}}),pa=[[.5,.333333],[.25,.666667],[.75,.111111],[.125,.444444],[.625,.777778],[.375,.222222],[.875,.555556],[.0625,.888889],[.5625,.037037],[.3125,.37037],[.8125,.703704],[.1875,.148148],[.6875,.481481],[.4375,.814815],[.9375,.259259],[.03125,.592593]],tn=class tn extends sr{constructor(){super(),this.lookAt=D.fromValues(0,0,0),this.hasChangedSinceLastFrame=!0,this.projectionMatrix=Q.create(),this.inverseProjectionMatrix=Q.create(),this.viewMatrix=Q.create(),this.inverseViewMatrix=Q.create(),this.projectionViewMatrix=Q.create(),this.inverseProjectionViewMatrix=Q.create(),this._shouldJitter=!1,this._shouldJitterChanged=!1,this.prevFrameProjectionViewMatrix=Q.create(),this.frameCounter=0,this.frustumPlanes=[],this.hamiltonSequence=new Array(16).fill([]).map(()=>new Array(2).fill(0));const e=Ot(W.Camera);this.bufferUniformValues=yt(e.structs.Camera),this.bufferUniformValues.set({viewMatrix:this.viewMatrix,projectionMatrix:this.projectionMatrix,projectionViewMatrix:this.projectionViewMatrix}),this.gpuBuffer=B.device.createBuffer({size:this.bufferUniformValues.arrayBuffer.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,label:"Camera GPUBuffer"}),Y.addBufferBytes(this.gpuBuffer);for(let t=0;t<6;t++)this.frustumPlanes.push(new fd(D.create(),0))}get shouldJitter(){return this._shouldJitter}set shouldJitter(e){this._shouldJitter=e,this._shouldJitterChanged=!0}set x(e){this.position[0]=e,this.bufferUniformValues.set({position:this.position})}get x(){return this.position[0]}set y(e){this.position[1]=e,this.bufferUniformValues.set({position:this.position})}get y(){return this.position[1]}set z(e){this.position[2]=e,this.bufferUniformValues.set({position:this.position})}get z(){return this.position[2]}get frustumCornersWorldSpace(){const e=this.inverseProjectionViewMatrix,t=[];for(let r=0;r<2;r++)for(let n=0;n<2;n++)for(let i=0;i<2;i++){const o=2*r-1,u=2*n-1,l=i,m=1,b=Br.create(o,u,l,m);Br.transformMat4(b,e,b),b[0]/=b[3],b[1]/=b[3],b[2]/=b[3],t.push(b)}return t}cullMeshes(e,t){let r=0;for(let n=0;n(s[s.Deferred=0]="Deferred",s[s.DirectionalAmbientLighting=1]="DirectionalAmbientLighting",s[s.PointLightsNonCulledLighting=2]="PointLightsNonCulledLighting",s[s.PointLightsStencilMask=3]="PointLightsStencilMask",s[s.PointLightsLighting=4]="PointLightsLighting",s[s.SSAO=5]="SSAO",s[s.SSAOBlur=6]="SSAOBlur",s[s.Skybox=7]="Skybox",s[s.Transparent=8]="Transparent",s[s.Shadow=9]="Shadow",s[s.MomentsShadow=10]="MomentsShadow",s[s.BlurMomentsShadow=11]="BlurMomentsShadow",s[s.EnvironmentCube=12]="EnvironmentCube",s[s.TAAResolve=13]="TAAResolve",s[s.CopyDepthForHiZ=14]="CopyDepthForHiZ",s[s.HiZ=15]="HiZ",s[s.Reflection=16]="Reflection",s[s.BloomDownsample=17]="BloomDownsample",s[s.BloomUpsample=18]="BloomUpsample",s[s.DebugBounds=19]="DebugBounds",s[s.Blit=20]="Blit",s))(N||{}),se=(s=>(s[s.CPUTotal=0]="CPUTotal",s[s.GPUTotal=1]="GPUTotal",s[s.FPS=2]="FPS",s[s.VRAM=3]="VRAM",s[s.VisibleMeshes=4]="VisibleMeshes",s[s.LightsCount=5]="LightsCount",s[s.DeferredRenderPass=6]="DeferredRenderPass",s[s.DirectionalAmbientLightingRenderPass=7]="DirectionalAmbientLightingRenderPass",s[s.PointLightsStencilMask=8]="PointLightsStencilMask",s[s.PointLightsLighting=9]="PointLightsLighting",s[s.SSAORenderPass=10]="SSAORenderPass",s[s.TransparentRenderPass=11]="TransparentRenderPass",s[s.ShadowRenderPass=12]="ShadowRenderPass",s[s.TAAResolveRenderPass=13]="TAAResolveRenderPass",s[s.ReflectionRenderPass=14]="ReflectionRenderPass",s[s.BlitRenderPass=15]="BlitRenderPass",s))(se||{}),It=(s=>(s[s.Directional=0]="Directional",s[s.Point=1]="Point",s[s.Ambient=2]="Ambient",s))(It||{});const md=new Map([[It.Directional,0],[It.Point,1],[It.Ambient,2]]);N.Deferred,N.DirectionalAmbientLighting,N.SSAO,N.Transparent,N.Shadow,N.TAAResolve,N.Reflection,N.Blit;const gd=[se.CPUTotal,se.FPS,se.VRAM,se.VisibleMeshes,se.LightsCount],Cr=new Map([[N.Deferred,"G-Buffer Render Pass"],[N.DirectionalAmbientLighting,"Directional + Ambient Render Pass"],[N.PointLightsStencilMask,"Point Lights Stencil Mask Pass"],[N.PointLightsLighting,"Point Lights LightingSystem"],[N.SSAO,"SSAO Render Pass"],[N.SSAOBlur,"SSAO Blur Render Pass"],[N.Skybox,"Skybox Render Pass"],[N.Transparent,"Transparent Render Pass"],[N.Shadow,"Shadow Render Pass"],[N.EnvironmentCube,"Environment Cube Pass"],[N.TAAResolve,"TAA Resolve Render Pass"],[N.CopyDepthForHiZ,"Copy Depth for Hi-Z Render Pass"],[N.HiZ,"Hi-Z Depth Render Pass"],[N.Reflection,"SSR Render Pass"],[N.DebugBounds,"Debug Bounds Render Pass"],[N.Blit,"Blit Render Pass"],[N.BloomDownsample,"Bloom Downsample Render Pass"],[N.BloomUpsample,"Bloom Upsample Render Pass"]]);class yd{constructor(){this.passes=[],this.textureCache=new Map}destroy(){for(const e of this.passes)e.destroy();this.textureCache.clear()}setScene(e){this.scene=e}addPass(e){if(!this.passes.some(({type:t})=>t===e.type))return this.passes.push(e),this;{const t=Cr.get(e.type);console.warn(`RenderPass ${t} has already been added`)}}removePass(e){this.passes=this.passes.filter(({type:t})=>t!==e)}getPass(e){return this.passes.find(({type:t})=>t===e)}setTexture(e,t){this.textureCache.set(e,t)}getTexture(e){return this.textureCache.get(e)}async render(e){for(const t of this.passes){if(!t.enabled)continue;const r=t.inputTextureNames.map(i=>this.textureCache.get(i)),n=t.render(e,this.scene,r);t.outputTextureNames.forEach((i,o)=>{this.textureCache.set(i,n[o])})}}onFrameEnd(){for(const e of this.passes)e.onFrameEnd()}}class Vn{constructor(){this.c0=0,this.c1=0,this.c2=0,this.c3=0}set(e,t,r,n){this.c0=e,this.c1=r,this.c2=-3*e+3*t-2*r-n,this.c3=2*e-2*t+r+n}initCatmullRom(e,t,r,n,i){this.set(t,r,i*(r-e),i*(n-t))}initNonuniformCatmullRom(e,t,r,n,i,o,u){let l=(t-e)/i-(r-e)/(i+o)+(r-t)/o,m=(r-t)/o-(n-t)/(o+u)+(n-r)/u;l*=o,m*=o,this.set(t,r,l,m)}calc(e){const t=e*e,r=t*e;return this.c0+this.c1*e+this.c2*t+this.c3*r}}const ma=new Vn,ga=new Vn,ya=new Vn,bt=D.create();class bd{constructor(e=[],t=!1,r=.5){this.points=e,this.closed=t,this.tension=r}getPoint(e,t=D.create()){const r=t,n=this.points.length,i=(n-(this.closed?0:1))*e;let o,u,l=Math.floor(i),m=i-l;this.closed?l+=l>0?0:(Math.floor(Math.abs(l)/n)+1)*n:m===0&&l===n-1&&(l=n-2,m=1),this.closed||l>0?o=this.points[(l-1)%n]:(D.sub(this.points[0],this.points[1],bt),D.add(bt,this.points[0],bt),o=bt);const b=this.points[l%n],d=this.points[(l+1)%n];this.closed||l+2=0)}()}const _a="4.0.7";class xd{constructor(e,t,r="sessionStorage"){this.storage=function(n){try{const i=window[n],o="__storage_test__";return i.setItem(o,o),i.removeItem(o),i}catch{return null}}(r),this.id=e,this.config=t,this._loadConfiguration()}getConfiguration(){return this.config}setConfiguration(e){if(Object.assign(this.config,e),this.storage){const t=JSON.stringify(this.config);this.storage.setItem(this.id,t)}}_loadConfiguration(){let e={};if(this.storage){const t=this.storage.getItem(this.id);e=t?JSON.parse(t):{}}return Object.assign(this.config,e),this}}var hs;(function(s){s[s.BLACK=30]="BLACK",s[s.RED=31]="RED",s[s.GREEN=32]="GREEN",s[s.YELLOW=33]="YELLOW",s[s.BLUE=34]="BLUE",s[s.MAGENTA=35]="MAGENTA",s[s.CYAN=36]="CYAN",s[s.WHITE=37]="WHITE",s[s.BRIGHT_BLACK=90]="BRIGHT_BLACK",s[s.BRIGHT_RED=91]="BRIGHT_RED",s[s.BRIGHT_GREEN=92]="BRIGHT_GREEN",s[s.BRIGHT_YELLOW=93]="BRIGHT_YELLOW",s[s.BRIGHT_BLUE=94]="BRIGHT_BLUE",s[s.BRIGHT_MAGENTA=95]="BRIGHT_MAGENTA",s[s.BRIGHT_CYAN=96]="BRIGHT_CYAN",s[s.BRIGHT_WHITE=97]="BRIGHT_WHITE"})(hs||(hs={}));function Aa(s){return typeof s!="string"?s:(s=s.toUpperCase(),hs[s]||hs.WHITE)}function Jn(s,e){if(!s)throw new Error("Assertion failed")}function ir(){var e,t,r;let s;if(Hn()&&ds.performance)s=(t=(e=ds==null?void 0:ds.performance)==null?void 0:e.now)==null?void 0:t.call(e);else if("hrtime"in nr){const n=(r=nr==null?void 0:nr.hrtime)==null?void 0:r.call(nr);s=1e3*n[0]+n[1]/1e6}else s=Date.now();return s}const or={debug:Hn()&&console.debug||console.log,log:console.log,info:console.info,warn:console.warn,error:console.error},_d={enabled:!0,level:0};function ar(){}const Ba={},va={once:!0};class zn{constructor({id:e}={id:""}){this.VERSION=_a,this._startTs=ir(),this._deltaTs=ir(),this.userData={},this.LOG_THROTTLE_TIMEOUT=0,this.id=e,this.userData={},this._storage=new xd(`__probe-${this.id}__`,_d),this.timeStamp(`${this.id} started`),function(t,r=["constructor"]){const n=Object.getPrototypeOf(t),i=Object.getOwnPropertyNames(n),o=t;for(const u of i){const l=o[u];typeof l=="function"&&(r.find(m=>u===m)||(o[u]=l.bind(t)))}}(this),Object.seal(this)}set level(e){this.setLevel(e)}get level(){return this.getLevel()}isEnabled(){return this._storage.config.enabled}getLevel(){return this._storage.config.level}getTotal(){return Number((ir()-this._startTs).toPrecision(10))}getDelta(){return Number((ir()-this._deltaTs).toPrecision(10))}set priority(e){this.level=e}get priority(){return this.level}getPriority(){return this.level}enable(e=!0){return this._storage.setConfiguration({enabled:e}),this}setLevel(e){return this._storage.setConfiguration({level:e}),this}get(e){return this._storage.config[e]}set(e,t){this._storage.setConfiguration({[e]:t})}settings(){console.table?console.table(this._storage.config):console.log(this._storage.config)}assert(e,t){if(!e)throw new Error(t||"Assertion failed")}warn(e){return this._getLogFunction(0,e,or.warn,arguments,va)}error(e){return this._getLogFunction(0,e,or.error,arguments)}deprecated(e,t){return this.warn(`\`${e}\` is deprecated and will be removed in a later version. Use \`${t}\` instead`)}removed(e,t){return this.error(`\`${e}\` has been removed. Use \`${t}\` instead`)}probe(e,t){return this._getLogFunction(e,t,or.log,arguments,{time:!0,once:!0})}log(e,t){return this._getLogFunction(e,t,or.debug,arguments)}info(e,t){return this._getLogFunction(e,t,console.info,arguments)}once(e,t){return this._getLogFunction(e,t,or.debug||or.info,arguments,va)}table(e,t,r){return t?this._getLogFunction(e,t,console.table||ar,r&&[r],{tag:Ad(t)}):ar}time(e,t){return this._getLogFunction(e,t,console.time?console.time:console.info)}timeEnd(e,t){return this._getLogFunction(e,t,console.timeEnd?console.timeEnd:console.info)}timeStamp(e,t){return this._getLogFunction(e,t,console.timeStamp||ar)}group(e,t,r={collapsed:!1}){const n=Ca({logLevel:e,message:t,opts:r}),{collapsed:i}=r;return n.method=(i?console.groupCollapsed:console.group)||console.info,this._getLogFunction(n)}groupCollapsed(e,t,r={}){return this.group(e,t,Object.assign({},r,{collapsed:!0}))}groupEnd(e){return this._getLogFunction(e,"",console.groupEnd||ar)}withGroup(e,t,r){this.group(e,t)();try{r()}finally{this.groupEnd(e)()}}trace(){console.trace&&console.trace()}_shouldLog(e){return this.isEnabled()&&this.getLevel()>=wa(e)}_getLogFunction(e,t,r,n,i){if(this._shouldLog(e)){i=Ca({logLevel:e,message:t,args:n,opts:i}),Jn(r=r||i.method),i.total=this.getTotal(),i.delta=this.getDelta(),this._deltaTs=ir();const o=i.tag||i.message;if(i.once&&o){if(Ba[o])return ar;Ba[o]=ir()}return t=function(u,l,m){if(typeof l=="string"){const b=m.time?function(d,x=8){const g=Math.max(x-d.length,0);return`${" ".repeat(g)}${d}`}(function(d){let x;return x=d<10?`${d.toFixed(2)}ms`:d<100?`${d.toFixed(1)}ms`:d<1e3?`${d.toFixed(0)}ms`:`${(d/1e3).toFixed(2)}s`,x}(m.total)):"";l=function(d,x,g){return Hn||typeof d!="string"||(x&&(d=`\x1B[${Aa(x)}m${d}\x1B[39m`),g&&(d=`\x1B[${Aa(g)+10}m${d}\x1B[49m`)),d}(l=m.time?`${u}: ${b} ${l}`:`${u}: ${l}`,m.color,m.background)}return l}(this.id,i.message,i),r.bind(console,t,...i.args)}return ar}}function wa(s){if(!s)return 0;let e;switch(typeof s){case"number":e=s;break;case"object":e=s.logLevel||s.priority||0;break;default:return 0}return Jn(Number.isFinite(e)&&e>=0),e}function Ca(s){const{logLevel:e,message:t}=s;s.logLevel=wa(e);const r=s.args?Array.from(s.args):[];for(;r.length&&r.shift()!==t;);switch(typeof e){case"string":case"function":t!==void 0&&r.unshift(t),s.message=e;break;case"object":Object.assign(s,e)}typeof s.message=="function"&&(s.message=s.message());const n=typeof s.message;return Jn(n==="string"||n==="object"),Object.assign(s,{args:r},s.opts)}function Ad(s){for(const e in s)for(const t in s[e])return t||"untitled";return"empty"}zn.VERSION=_a;const jn="4.3.2",Bd=jn[0]>="0"&&jn[0]<="9"?`v${jn}`:"",vd=function(){const s=new zn({id:"loaders.gl"});return globalThis.loaders=globalThis.loaders||{},globalThis.loaders.log=s,globalThis.loaders.version=Bd,globalThis.probe=globalThis.probe||{},globalThis.probe.loaders=s,s}();function wd(s,e){return Ta(s||{},e)}function Ta(s,e,t=0){if(t>3)return e;const r={...s};for(const[n,i]of Object.entries(e))i&&typeof i=="object"&&!Array.isArray(i)?r[n]=Ta(r[n]||{},e[n],t+1):r[n]=e[n];return r}const Cd=((zc=globalThis._loadersgl_)!=null&&zc.version||(globalThis._loadersgl_=globalThis._loadersgl_||{},globalThis._loadersgl_.version="4.3.2"),globalThis._loadersgl_.version);function lt(s,e){if(!s)throw new Error(e||"loaders.gl assertion failed.")}const Ve=typeof process!="object"||String(process)!=="[object process]"||process.browser,Kn=typeof importScripts=="function",Td=typeof window<"u"&&window.orientation!==void 0,Sa=typeof process<"u"&&process.version&&/v([0-9]*)/.exec(process.version);Sa&&parseFloat(Sa[1]);class Sd{constructor(e,t){ee(this,"name");ee(this,"workerThread");ee(this,"isRunning",!0);ee(this,"result");ee(this,"_resolve",()=>{});ee(this,"_reject",()=>{});this.name=e,this.workerThread=t,this.result=new Promise((r,n)=>{this._resolve=r,this._reject=n})}postMessage(e,t){this.workerThread.postMessage({source:"loaders.gl",type:e,payload:t})}done(e){lt(this.isRunning),this.isRunning=!1,this._resolve(e)}error(e){lt(this.isRunning),this.isRunning=!1,this._reject(e)}}class Xn{terminate(){}}const Yn=new Map;function Ed(s){lt(s.source&&!s.url||!s.source&&s.url);let e=Yn.get(s.source||s.url);return e||(s.url&&(e=function(t){if(!t.startsWith("http"))return t;return Ea((r=t,`try { - importScripts('${r}'); -} catch (error) { - console.error(error); - throw error; -}`));var r}(s.url),Yn.set(s.url,e)),s.source&&(e=Ea(s.source),Yn.set(s.source,e))),lt(e),e}function Ea(s){const e=new Blob([s],{type:"application/javascript"});return URL.createObjectURL(e)}function Ma(s,e=!0,t){const r=t||new Set;if(s){if(Pa(s))r.add(s);else if(Pa(s.buffer))r.add(s.buffer);else if(!ArrayBuffer.isView(s)){if(e&&typeof s=="object")for(const n in s)Ma(s[n],e,r)}}return t===void 0?Array.from(r):[]}function Pa(s){return!!s&&(s instanceof ArrayBuffer||typeof MessagePort<"u"&&s instanceof MessagePort||typeof ImageBitmap<"u"&&s instanceof ImageBitmap||typeof OffscreenCanvas<"u"&&s instanceof OffscreenCanvas)}const Wn=()=>{};class $n{constructor(e){ee(this,"name");ee(this,"source");ee(this,"url");ee(this,"terminated",!1);ee(this,"worker");ee(this,"onMessage");ee(this,"onError");ee(this,"_loadableURL","");const{name:t,source:r,url:n}=e;lt(r||n),this.name=t,this.source=r,this.url=n,this.onMessage=Wn,this.onError=i=>console.log(i),this.worker=Ve?this._createBrowserWorker():this._createNodeWorker()}static isSupported(){return typeof Worker<"u"&&Ve||Xn!==void 0&&!Ve}destroy(){this.onMessage=Wn,this.onError=Wn,this.worker.terminate(),this.terminated=!0}get isRunning(){return!!this.onMessage}postMessage(e,t){t=t||Ma(e),this.worker.postMessage(e,t)}_getErrorFromErrorEvent(e){let t="Failed to load ";return t+=`worker ${this.name} from ${this.url}. `,e.message&&(t+=`${e.message} in `),e.lineno&&(t+=`:${e.lineno}:${e.colno}`),new Error(t)}_createBrowserWorker(){this._loadableURL=Ed({source:this.source,url:this.url});const e=new Worker(this._loadableURL,{name:this.name});return e.onmessage=t=>{t.data?this.onMessage(t.data):this.onError(new Error("No data received"))},e.onerror=t=>{this.onError(this._getErrorFromErrorEvent(t)),this.terminated=!0},e.onmessageerror=t=>console.error(t),e}_createNodeWorker(){let e;if(this.url){const t=this.url.includes(":/")||this.url.startsWith("/")?this.url:`./${this.url}`;e=new Xn(t,{eval:!1})}else{if(!this.source)throw new Error("no worker");e=new Xn(this.source,{eval:!0})}return e.on("message",t=>{this.onMessage(t)}),e.on("error",t=>{this.onError(t)}),e.on("exit",t=>{}),e}}class Md{constructor(e){ee(this,"name","unnamed");ee(this,"source");ee(this,"url");ee(this,"maxConcurrency",1);ee(this,"maxMobileConcurrency",1);ee(this,"onDebug",()=>{});ee(this,"reuseWorkers",!0);ee(this,"props",{});ee(this,"jobQueue",[]);ee(this,"idleQueue",[]);ee(this,"count",0);ee(this,"isDestroyed",!1);this.source=e.source,this.url=e.url,this.setProps(e)}static isSupported(){return $n.isSupported()}destroy(){this.idleQueue.forEach(e=>e.destroy()),this.isDestroyed=!0}setProps(e){this.props={...this.props,...e},e.name!==void 0&&(this.name=e.name),e.maxConcurrency!==void 0&&(this.maxConcurrency=e.maxConcurrency),e.maxMobileConcurrency!==void 0&&(this.maxMobileConcurrency=e.maxMobileConcurrency),e.reuseWorkers!==void 0&&(this.reuseWorkers=e.reuseWorkers),e.onDebug!==void 0&&(this.onDebug=e.onDebug)}async startJob(e,t=(n,i,o)=>n.done(o),r=(n,i)=>n.error(i)){const n=new Promise(i=>(this.jobQueue.push({name:e,onMessage:t,onError:r,onStart:i}),this));return this._startQueuedJob(),await n}async _startQueuedJob(){if(!this.jobQueue.length)return;const e=this._getAvailableWorker();if(!e)return;const t=this.jobQueue.shift();if(t){this.onDebug({message:"Starting job",name:t.name,workerThread:e,backlog:this.jobQueue.length});const r=new Sd(t.name,e);e.onMessage=n=>t.onMessage(r,n.type,n.payload),e.onError=n=>t.onError(r,n),t.onStart(r);try{await r.result}catch(n){console.error(`Worker exception: ${n}`)}finally{this.returnWorkerToQueue(e)}}}returnWorkerToQueue(e){!Ve||this.isDestroyed||!this.reuseWorkers||this.count>this._getMaxConcurrency()?(e.destroy(),this.count--):this.idleQueue.push(e),this.isDestroyed||this._startQueuedJob()}_getAvailableWorker(){if(this.idleQueue.length>0)return this.idleQueue.shift()||null;if(this.count{}},wt=class wt{constructor(e){ee(this,"props");ee(this,"workerPools",new Map);this.props={...Pd},this.setProps(e),this.workerPools=new Map}static isSupported(){return $n.isSupported()}static getWorkerFarm(e={}){return wt._workerFarm=wt._workerFarm||new wt({}),wt._workerFarm.setProps(e),wt._workerFarm}destroy(){for(const e of this.workerPools.values())e.destroy();this.workerPools=new Map}setProps(e){this.props={...this.props,...e};for(const t of this.workerPools.values())t.setProps(this._getWorkerPoolProps())}getWorkerPool(e){const{name:t,source:r,url:n}=e;let i=this.workerPools.get(t);return i||(i=new Md({name:t,source:r,url:n}),i.setProps(this._getWorkerPoolProps()),this.workerPools.set(t,i)),i}_getWorkerPoolProps(){return{maxConcurrency:this.props.maxConcurrency,maxMobileConcurrency:this.props.maxMobileConcurrency,reuseWorkers:this.props.reuseWorkers,onDebug:this.props.onDebug}}};ee(wt,"_workerFarm");let fs=wt;const qn={};async function Ft(s,e=null,t={},r=null){return e&&(s=function(n,i,o={},u=null){if(!o.useLocalLibraries&&n.startsWith("http"))return n;u=u||n;const l=o.modules||{};return l[u]?l[u]:Ve?o.CDN?(lt(o.CDN.startsWith("http")),`${o.CDN}/${i}@${Cd}/dist/libs/${u}`):Kn?`../src/libs/${u}`:`modules/${i}/src/libs/${u}`:`modules/${i}/dist/libs/${u}`}(s,e,t,r)),qn[s]=qn[s]||async function(n){if(n.endsWith("wasm"))return await async function(o){const{readFileAsArrayBuffer:u}=globalThis.loaders||{};return Ve||!u||o.startsWith("http")?await(await fetch(o)).arrayBuffer():await u(o)}(n);if(!Ve)try{const{requireFromFile:o}=globalThis.loaders||{};return await(o==null?void 0:o(n))}catch(o){return console.error(o),null}if(Kn)return importScripts(n);const i=await async function(o){const{readFileAsText:u}=globalThis.loaders||{};return Ve||!u||o.startsWith("http")?await(await fetch(o)).text():await u(o)}(n);return function(o,u){if(!Ve){const{requireFromString:m}=globalThis.loaders||{};return m==null?void 0:m(o,u)}if(Kn)return eval.call(globalThis,o),null;const l=document.createElement("script");l.id=u;try{l.appendChild(document.createTextNode(o))}catch{l.text=o}return document.body.appendChild(l),null}(i,n)}(s),await qn[s]}async function Rd(s,e,t,r,n){const i=s.id,o=function(b,d={}){const x=d[b.id]||{},g=Ve?`${b.id}-worker.js`:`${b.id}-worker-node.js`;let _=x.workerUrl;if(_||b.id!=="compression"||(_=d.workerUrl),d._workerType==="test"&&(_=Ve?`modules/${b.module}/dist/${g}`:`modules/${b.module}/src/workers/${b.id}-worker-node.ts`),!_){let w=b.version;w==="latest"&&(w="latest");const f=w?`@${w}`:"";_=`https://unpkg.com/@loaders.gl/${b.module}${f}/dist/${g}`}return lt(_),_}(s,t),u=fs.getWorkerFarm(t).getWorkerPool({name:i,url:o});t=JSON.parse(JSON.stringify(t)),r=JSON.parse(JSON.stringify(r||{}));const l=await u.startJob("process-on-worker",Gd.bind(null,n));return l.postMessage("process",{input:e,options:t,context:r}),await(await l.result).result}async function Gd(s,e,t,r){switch(t){case"done":e.done(r);break;case"error":e.error(new Error(r.error));break;case"process":const{id:n,input:i,options:o}=r;try{const u=await s(i,o);e.postMessage("done",{id:n,result:u})}catch(u){const l=u instanceof Error?u.message:"unknown error";e.postMessage("error",{id:n,error:l})}break;default:console.warn(`parse-with-worker unknown message ${t}`)}}function Ra(s,e,t){if(s.byteLength<=e+t)return"";const r=new DataView(s);let n="";for(let i=0;io instanceof ArrayBuffer?new Uint8Array(o):o),r=t.reduce((o,u)=>o+u.byteLength,0),n=new Uint8Array(r);let i=0;for(const o of t)n.set(o,i),i+=o.byteLength;return n.buffer}(s)}function Ga(s,e,t){const r=t!==void 0?new Uint8Array(s).subarray(e,e+t):new Uint8Array(s).subarray(e);return new Uint8Array(r).buffer}function Tr(s,e){return ct(s>=0),ct(e>0),s+(e-1)&~(e-1)}function Id(s,e,t){let r;if(s instanceof ArrayBuffer)r=new Uint8Array(s);else{const n=s.byteOffset,i=s.byteLength;r=new Uint8Array(s.buffer||s.arrayBuffer,n,i)}return e.set(r,t),t+Tr(r.byteLength,4)}const La={};function Oa(s){if((e=s)&&typeof e=="object"&&e.isBuffer)return s;var e;if(s instanceof ArrayBuffer)return s;if(ArrayBuffer.isView(s))return s.byteOffset===0&&s.byteLength===s.buffer.byteLength?s.buffer:s.buffer.slice(s.byteOffset,s.byteOffset+s.byteLength);if(typeof s=="string"){const t=s;return new TextEncoder().encode(t).buffer}if(s&&typeof s=="object"&&s._toArrayBuffer)return s._toArrayBuffer();throw new Error("toArrayBuffer")}function Ia(s){const e=s?s.lastIndexOf("/"):-1;return e>=0?s.substr(e+1):""}const Sr=s=>typeof s=="function",Er=s=>s!==null&&typeof s=="object",Fa=s=>Er(s)&&s.constructor==={}.constructor,Dt=s=>typeof Response<"u"&&s instanceof Response||s&&s.arrayBuffer&&s.text&&s.json,Ut=s=>typeof Blob<"u"&&s instanceof Blob,Da=s=>(e=>typeof ReadableStream<"u"&&e instanceof ReadableStream||Er(e)&&Sr(e.tee)&&Sr(e.cancel)&&Sr(e.getReader))(s)||(e=>Er(e)&&Sr(e.read)&&Sr(e.pipe)&&(t=>typeof t=="boolean")(e.readable))(s);class Fd extends Error{constructor(t,r){super(t);ee(this,"reason");ee(this,"url");ee(this,"response");this.reason=r.reason,this.url=r.url,this.response=r.response}}const Dd=/^data:([-\w.]+\/[-\w.+]+)(;|,)/,Ud=/^([-\w.]+\/[-\w.+]+)/;function Ua(s,e){return s.toLowerCase()===e.toLowerCase()}function ka(s){const e=Dd.exec(s);return e?e[1]:""}const Na=/\?.*/;function Qn(s){return s.replace(Na,"")}function ps(s){return Dt(s)?s.url:Ut(s)?s.name||"":typeof s=="string"?s:""}function Zn(s){if(Dt(s)){const e=s,t=e.headers.get("content-type")||"",r=Qn(e.url);return function(n){const i=Ud.exec(n);return i?i[1]:n}(t)||ka(r)}return Ut(s)?s.type||"":typeof s=="string"?ka(s):""}async function Va(s){if(Dt(s))return s;const e={},t=function(u){return Dt(u)?u.headers["content-length"]||-1:Ut(u)?u.size:typeof u=="string"?u.length:u instanceof ArrayBuffer||ArrayBuffer.isView(u)?u.byteLength:-1}(s);t>=0&&(e["content-length"]=String(t));const r=ps(s),n=Zn(s);n&&(e["content-type"]=n);const i=await async function(u){if(typeof u=="string")return`data:,${u.slice(0,5)}`;if(u instanceof Blob){const m=u.slice(0,5);return await new Promise(b=>{const d=new FileReader;d.onload=x=>{var g;return b((g=x==null?void 0:x.target)==null?void 0:g.result)},d.readAsDataURL(m)})}return u instanceof ArrayBuffer?`data:base64,${function(m){let b="";const d=new Uint8Array(m);for(let x=0;x100?`${n.slice(0,100)}...`:n;const i={reason:t.statusText,url:t.url,response:t};try{const o=t.headers.get("Content-Type");i.reason=!t.bodyUsed&&(o!=null&&o.includes("application/json"))?await t.json():await t.text()}catch{}return new Fd(n,i)}(s)}async function Ha(s,e){var t,r;if(typeof s=="string"){const n=function(i){for(const o in La)if(i.startsWith(o)){const u=La[o];i=i.replace(o,u)}return i.startsWith("http://")||i.startsWith("https://")||(i=`${i}`),i}(s);return function(i){return!function(o){return o.startsWith("http:")||o.startsWith("https:")}(i)&&!function(o){return o.startsWith("data:")}(i)}(n)&&((t=globalThis.loaders)!=null&&t.fetchNode)?(r=globalThis.loaders)==null?void 0:r.fetchNode(n,e):await fetch(n,e)}return await Va(s)}const Ja=new zn({id:"loaders.gl"});class Nd{log(){return()=>{}}info(){return()=>{}}warn(){return()=>{}}error(){return()=>{}}}const za={fetch:null,mimeType:void 0,nothrow:!1,log:new class{constructor(){ee(this,"console");this.console=console}log(...s){return this.console.log.bind(this.console,...s)}info(...s){return this.console.info.bind(this.console,...s)}warn(...s){return this.console.warn.bind(this.console,...s)}error(...s){return this.console.error.bind(this.console,...s)}},useLocalLibraries:!1,CDN:"https://unpkg.com/@loaders.gl",worker:!0,maxConcurrency:3,maxMobileConcurrency:1,reuseWorkers:ls,_nodeWorkers:!1,_workerType:"",limit:0,_limitMB:0,batchSize:"auto",batchDebounceMs:0,metadata:!1,transforms:[]},Vd={throws:"nothrow",dataType:"(no longer used)",uri:"baseUri",method:"fetch.method",headers:"fetch.headers",body:"fetch.body",mode:"fetch.mode",credentials:"fetch.credentials",cache:"fetch.cache",redirect:"fetch.redirect",referrer:"fetch.referrer",referrerPolicy:"fetch.referrerPolicy",integrity:"fetch.integrity",keepalive:"fetch.keepalive",signal:"fetch.signal"};function ja(){globalThis.loaders=globalThis.loaders||{};const{loaders:s}=globalThis;return s._state||(s._state={}),s._state}function Ka(){const s=ja();return s.globalOptions=s.globalOptions||{...za},s.globalOptions}function Hd(s,e,t,r){return t=t||[],function(n,i){Xa(n,null,za,Vd,i);for(const o of i){const u=n&&n[o.id]||{},l=o.options&&o.options[o.id]||{},m=o.deprecatedOptions&&o.deprecatedOptions[o.id]||{};Xa(u,o.id,l,m,i)}}(s,t=Array.isArray(t)?t:[t]),function(n,i,o){const u=n.options||{},l={...u};return function(m,b){b&&!("baseUri"in m)&&(m.baseUri=b)}(l,o),l.log===null&&(l.log=new Nd),Ya(l,Ka()),Ya(l,i),l}(e,s,r)}function Xa(s,e,t,r,n){const i=e||"Top level",o=e?`${e}.`:"";for(const u in s){const l=!e&&Er(s[u]);if(!(u in t)&&!(u==="baseUri"&&!e)&&!(u==="workerUrl"&&e)){if(u in r)Ja.warn(`${i} loader option '${o}${u}' no longer supported, use '${r[u]}'`)();else if(!l){const m=Jd(u,n);Ja.warn(`${i} loader option '${o}${u}' not recognized. ${m}`)()}}}}function Jd(s,e){const t=s.toLowerCase();let r="";for(const n of e)for(const i in n.options){if(s===i)return`Did you mean '${n.id}.${i}'?`;const o=i.toLowerCase();(t.startsWith(o)||o.startsWith(t))&&(r=r||`Did you mean '${n.id}.${i}'?`)}return r}function Ya(s,e){for(const t in e)if(t in e){const r=e[t];Fa(r)&&Fa(s[t])?s[t]={...s[t],...e[t]}:s[t]=e[t]}}function ei(s){return s?(Array.isArray(s)&&(s=s[0]),Array.isArray(s==null?void 0:s.extensions)):!1}function Wa(s){let e;return ct(s,"null loader"),ct(ei(s),"invalid loader"),Array.isArray(s)&&(e=s[1],s=s[0],s={...s,options:{...s.options,...e}}),(s!=null&&s.parseTextSync||s!=null&&s.parseText)&&(s.text=!0),s.text||(s.binary=!0),s}function zd(){return(()=>{const s=ja();return s.loaderRegistry=s.loaderRegistry||[],s.loaderRegistry})()}const jd=/\.([^.]+)$/;function $a(s,e=[],t,r){if(!qa(s))return null;if(e&&!Array.isArray(e))return Wa(e);let n=[];e&&(n=n.concat(e)),t!=null&&t.ignoreRegisteredLoaders||n.push(...zd()),function(o){for(const u of o)Wa(u)}(n);const i=function(o,u,l,m){const b=ps(o),d=Zn(o),x=Qn(b)||(m==null?void 0:m.url);let g=null,_="";return l!=null&&l.mimeType&&(g=ti(u,l==null?void 0:l.mimeType),_=`match forced by supplied MIME type ${l==null?void 0:l.mimeType}`),g=g||function(w,f){const p=f&&jd.exec(f),a=p&&p[1];return a?function(c,h){h=h.toLowerCase();for(const y of c)for(const A of y.extensions)if(A.toLowerCase()===h)return y;return null}(w,a):null}(u,x),_=_||(g?`matched url ${x}`:""),g=g||ti(u,d),_=_||(g?`matched MIME type ${d}`:""),g=g||function(w,f){if(!f)return null;for(const p of w)if(typeof f=="string"){if(Kd(f,p))return p}else if(ArrayBuffer.isView(f)){if(Za(f.buffer,f.byteOffset,p))return p}else if(f instanceof ArrayBuffer&&Za(f,0,p))return p;return null}(u,o),_=_||(g?`matched initial data ${eu(o)}`:""),l!=null&&l.fallbackMimeType&&(g=g||ti(u,l==null?void 0:l.fallbackMimeType),_=_||(g?`matched fallback MIME type ${d}`:"")),_&&vd.log(1,`selectLoader selected ${g==null?void 0:g.name}: ${_}.`),g}(s,n,t,r);if(!i&&!(t!=null&&t.nothrow))throw new Error(Qa(s));return i}function qa(s){return!(s instanceof Response&&s.status===204)}function Qa(s){const e=ps(s),t=Zn(s);let r="No valid loader found (";r+=e?`${Ia(e)}, `:"no url provided, ",r+=`MIME type: ${t?`"${t}"`:"not provided"}, `;const n=s?eu(s):"";return r+=n?` first bytes: "${n}"`:"first bytes: not available",r+=")",r}function ti(s,e){var t;for(const r of s)if((t=r.mimeTypes)!=null&&t.some(n=>Ua(e,n))||Ua(e,`application/x.${r.id}`))return r;return null}function Kd(s,e){return e.testText?e.testText(s):(Array.isArray(e.tests)?e.tests:[e.tests]).some(t=>s.startsWith(t))}function Za(s,e,t){return(Array.isArray(t.tests)?t.tests:[t.tests]).some(r=>function(n,i,o,u){if(u instanceof ArrayBuffer)return function(l,m,b){if(b=b||l.byteLength,l.byteLengthi&&typeof i[Symbol.asyncIterator]=="function")(s))return async function(i){const o=[];for await(const u of i)o.push(u);return Od(...o)}(s);var n;throw new Error(ru)}function su(s,e){const t=Ka(),r=s||t;return typeof r.fetch=="function"?r.fetch:Er(r.fetch)?n=>Ha(n,r.fetch):e!=null&&e.fetch?e==null?void 0:e.fetch:Ha}function $d(s,e,t){if(t)return t;const r={fetch:su(e,s),...s};if(r.url){const n=Qn(r.url);r.baseUrl=n,r.queryString=function(i){const o=i.match(Na);return o&&o[0]}(r.url),r.filename=Ia(n),r.baseUrl=function(i){const o=i?i.lastIndexOf("/"):-1;return o>=0?i.substr(0,o):""}(n)}return Array.isArray(r.loaders)||(r.loaders=null),r}async function si(s,e,t,r){!e||Array.isArray(e)||ei(e)||(r=void 0,t=e,e=void 0),t=t||{};const n=ps(s=await s),i=function(u,l){if(u&&!Array.isArray(u))return u;let m;if(u&&(m=Array.isArray(u)?u:[u]),l&&l.loaders){const b=Array.isArray(l.loaders)?l.loaders:[l.loaders];m=m?[...m,...b]:b}return m&&m.length?m:void 0}(e,r),o=await async function(u,l=[],m,b){if(!qa(u))return null;let d=$a(u,l,{...m,nothrow:!0},b);if(d)return d;if(Ut(u)&&(d=$a(u=await u.slice(0,10).arrayBuffer(),l,m,b)),!d&&!(m!=null&&m.nothrow))throw new Error(Qa(u));return d}(s,i,t);return o?(r=$d({url:n,_parse:si,loaders:i},t=Hd(t,o,i,n),r||null),await async function(u,l,m,b){if(function(x){lt(x,"no worker provided");const g=x.version}(u),m=wd(u.options,m),Dt(l)){const x=l,{ok:g,redirected:_,status:w,statusText:f,type:p,url:a}=x,c=Object.fromEntries(x.headers.entries());b.response={headers:c,ok:g,redirected:_,status:w,statusText:f,type:p,url:a}}l=await Wd(l,u,m);const d=u;if(d.parseTextSync&&typeof l=="string")return d.parseTextSync(l,m,b);if(function(x,g){return!!fs.isSupported()&&!(!Ve&&!(g!=null&&g._nodeWorkers))&&x.worker&&(g==null?void 0:g.worker)}(u,m))return await Rd(u,l,m,b,si);if(d.parseText&&typeof l=="string")return await d.parseText(l,m,b);if(d.parse)return await d.parse(l,m,b);throw lt(!d.parseSync),new Error(`${u.id} loader - no parser found and worker is disabled`)}(o,s,t,r)):null}function qd(s,e,t){const r=function(i){switch(i.constructor){case Int8Array:return"int8";case Uint8Array:case Uint8ClampedArray:return"uint8";case Int16Array:return"int16";case Uint16Array:return"uint16";case Int32Array:return"int32";case Uint32Array:return"uint32";case Float32Array:return"float32";case Float64Array:return"float64";default:return"null"}}(e.value),n=t||function(i){const o={};return"byteOffset"in i&&(o.byteOffset=i.byteOffset.toString(10)),"byteStride"in i&&(o.byteStride=i.byteStride.toString(10)),"normalized"in i&&(o.normalized=i.normalized.toString()),o}(e);return{name:s,type:{type:"fixed-size-list",listSize:e.size,children:[{name:"value",type:r}]},nullable:!1,metadata:n}}const Qd=(jc=globalThis.loaders)==null?void 0:jc.parseImageNode,ni=typeof Image<"u",ii=typeof ImageBitmap<"u",Zd=!!Qd,oi=!!ls||Zd;function eh(s){const e=function(t){return typeof ImageBitmap<"u"&&t instanceof ImageBitmap?"imagebitmap":typeof Image<"u"&&t instanceof Image?"image":t&&typeof t=="object"&&t.data&&t.width&&t.height?"data":null}(s);if(!e)throw new Error("Not an image");return e}function nu(s){switch(eh(s)){case"data":return s;case"image":case"imagebitmap":const e=document.createElement("canvas"),t=e.getContext("2d");if(!t)throw new Error("getImageData");return e.width=s.width,e.height=s.height,t.drawImage(s,0,0),t.getImageData(0,0,s.width,s.height);default:throw new Error("getImageData")}}const th=/^data:image\/svg\+xml/,rh=/\.svg((\?|#).*)?$/;function ai(s){return s&&(th.test(s)||rh.test(s))}function iu(s,e){if(ai(e))throw new Error("SVG cannot be parsed directly to imagebitmap");return new Blob([new Uint8Array(s)])}async function ou(s,e,t){const r=function(o,u){if(ai(u)){let l=new TextDecoder().decode(o);try{typeof unescape=="function"&&typeof encodeURIComponent=="function"&&(l=unescape(encodeURIComponent(l)))}catch(m){throw new Error(m.message)}return`data:image/svg+xml;base64,${btoa(l)}`}return iu(o,u)}(s,t),n=self.URL||self.webkitURL,i=typeof r!="string"&&n.createObjectURL(r);try{return await async function(o,u){const l=new Image;return l.src=o,u.image&&u.image.decode&&l.decode?(await l.decode(),l):await new Promise((m,b)=>{try{l.onload=()=>m(l),l.onerror=d=>{const x=d instanceof Error?d.message:"error";b(new Error(x))}}catch(d){b(d)}})}(i||r,e)}finally{i&&n.revokeObjectURL(i)}}const sh={};let au=!0;async function nh(s,e,t){let r;ai(t)?r=await ou(s,e,t):r=iu(s,t);const n=e&&e.imagebitmap;return await async function(i,o=null){if(!function(u){for(const l in u||sh)return!1;return!0}(o)&&au||(o=null),o)try{return await createImageBitmap(i,o)}catch(u){console.warn(u),au=!1}return await createImageBitmap(i)}(r,n)}function ih(s){return function(e,t,r=0){const n=(i=t,[...i].map(o=>o.charCodeAt(0)));var i;for(let o=0;o=24&&r.getUint32(0,tt)===2303741511?{mimeType:"image/png",width:r.getUint32(16,tt),height:r.getUint32(20,tt)}:null}(e)||function(t){const r=Pr(t);if(!(r.byteLength>=3&&r.getUint16(0,tt)===65496&&r.getUint8(2)===255))return null;const{tableMarkers:i,sofMarkers:o}=function(){const l=new Set([65499,65476,65484,65501,65534]);for(let b=65504;b<65520;++b)l.add(b);return{tableMarkers:l,sofMarkers:new Set([65472,65473,65474,65475,65477,65478,65479,65481,65482,65483,65485,65486,65487,65502])}}();let u=2;for(;u+9=10&&r.getUint32(0,tt)===1195984440?{mimeType:"image/gif",width:r.getUint16(6,Mr),height:r.getUint16(8,Mr)}:null}(e)||function(t){const r=Pr(t);return r.byteLength>=14&&r.getUint16(0,tt)===16973&&r.getUint32(2,Mr)===r.byteLength?{mimeType:"image/bmp",width:r.getUint32(18,Mr),height:r.getUint32(22,Mr)}:null}(e)||function(t){const r=new Uint8Array(t instanceof DataView?t.buffer:t),n=ih(r);return n?{mimeType:n.mimeType,width:0,height:0}:null}(e)}function Pr(s){if(s instanceof DataView)return s;if(ArrayBuffer.isView(s))return new DataView(s.buffer);if(s instanceof ArrayBuffer)return new DataView(s);throw new Error("toDataView")}const oh={dataType:null,batchType:null,id:"image",module:"images",name:"Images",version:"4.3.2",mimeTypes:["image/png","image/jpeg","image/gif","image/webp","image/avif","image/bmp","image/vnd.microsoft.icon","image/svg+xml"],extensions:["png","jpg","jpeg","gif","webp","bmp","ico","svg","avif"],parse:async function(s,e,t){const r=((e=e||{}).image||{}).type||"auto",{url:n}=t||{};let i;switch(function(o){switch(o){case"auto":case"data":return function(){if(ii)return"imagebitmap";if(ni)return"image";if(oi)return"data";throw new Error("Install '@loaders.gl/polyfills' to parse images under Node.js")}();default:return function(u){switch(u){case"auto":return ii||ni||oi;case"imagebitmap":return ii;case"image":return ni;case"data":return oi;default:throw new Error(`@loaders.gl/images: image ${u} not supported in this environment`)}}(o),o}}(r)){case"imagebitmap":i=await nh(s,e,n);break;case"image":i=await ou(s,e,n);break;case"data":i=await async function(o){var m;const{mimeType:u}=ui(o)||{},l=(m=globalThis.loaders)==null?void 0:m.parseImageNode;return ct(l),await l(o,u)}(s);break;default:ct(!1)}return r==="data"&&(i=nu(i)),i},tests:[s=>!!ui(new DataView(s))],options:{image:{type:"auto",decode:!0}}},ci={};function ah(s){if(ci[s]===void 0){const e=ls?function(t){switch(t){case"image/avif":case"image/webp":return function(r){try{return document.createElement("canvas").toDataURL(r).indexOf(`data:${r}`)===0}catch{return!1}}(t);default:return!0}}(s):function(t){var o,u;const r=["image/png","image/jpeg","image/gif"],n=((o=globalThis.loaders)==null?void 0:o.imageFormatsNode)||r;return!!((u=globalThis.loaders)==null?void 0:u.parseImageNode)&&n.includes(t)}(s);ci[s]=e}return ci[s]}function Ee(s,e){if(!s)throw new Error(e||"assert failed: gltf")}const uu={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},cu={5120:1,5121:1,5122:2,5123:2,5125:4,5126:4},lu=["SCALAR","VEC2","VEC3","VEC4"],uh=[[Int8Array,5120],[Uint8Array,5121],[Int16Array,5122],[Uint16Array,5123],[Uint32Array,5125],[Float32Array,5126],[Float64Array,5130]],ch=new Map(uh),lh={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},dh={5120:1,5121:1,5122:2,5123:2,5125:4,5126:4},hh={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array};function du(s){return lu[s-1]||lu[0]}function ms(s){const e=ch.get(s.constructor);if(!e)throw new Error("Illegal typed array");return e}function li(s,e){const t=hh[s.componentType],r=lh[s.type],n=dh[s.componentType],i=s.count*r,o=s.count*r*n;return Ee(o>=0&&o<=e.byteLength),{ArrayType:t,length:i,byteLength:o,componentByteSize:cu[s.componentType],numberOfComponentsInElement:uu[s.type]}}class xe{constructor(e){ee(this,"gltf");ee(this,"sourceBuffers");ee(this,"byteLength");this.gltf={json:(e==null?void 0:e.json)||{asset:{version:"2.0",generator:"loaders.gl"},buffers:[],extensions:{},extensionsRequired:[],extensionsUsed:[]},buffers:(e==null?void 0:e.buffers)||[],images:(e==null?void 0:e.images)||[]},this.sourceBuffers=[],this.byteLength=0,this.gltf.buffers&&this.gltf.buffers[0]&&(this.byteLength=this.gltf.buffers[0].byteLength,this.sourceBuffers=[this.gltf.buffers[0]])}get json(){return this.gltf.json}getApplicationData(e){return this.json[e]}getExtraData(e){return(this.json.extras||{})[e]}hasExtension(e){const t=this.getUsedExtensions().find(n=>n===e),r=this.getRequiredExtensions().find(n=>n===e);return typeof t=="string"||typeof r=="string"}getExtension(e){const t=this.getUsedExtensions().find(n=>n===e),r=this.json.extensions||{};return t?r[e]:null}getRequiredExtension(e){return this.getRequiredExtensions().find(r=>r===e)?this.getExtension(e):null}getRequiredExtensions(){return this.json.extensionsRequired||[]}getUsedExtensions(){return this.json.extensionsUsed||[]}getRemovedExtensions(){return this.json.extensionsRemoved||[]}getObjectExtension(e,t){return(e.extensions||{})[t]}getScene(e){return this.getObject("scenes",e)}getNode(e){return this.getObject("nodes",e)}getSkin(e){return this.getObject("skins",e)}getMesh(e){return this.getObject("meshes",e)}getMaterial(e){return this.getObject("materials",e)}getAccessor(e){return this.getObject("accessors",e)}getTexture(e){return this.getObject("textures",e)}getSampler(e){return this.getObject("samplers",e)}getImage(e){return this.getObject("images",e)}getBufferView(e){return this.getObject("bufferViews",e)}getBuffer(e){return this.getObject("buffers",e)}getObject(e,t){if(typeof t=="object")return t;const r=this.json[e]&&this.json[e][t];if(!r)throw new Error(`glTF file error: Could not find ${e}[${t}]`);return r}getTypedArrayForBufferView(e){const t=(e=this.getBufferView(e)).buffer,r=this.gltf.buffers[t];Ee(r);const n=(e.byteOffset||0)+r.byteOffset;return new Uint8Array(r.arrayBuffer,n,e.byteLength)}getTypedArrayForAccessor(e){const t=this.getAccessor(e);return function(r,n,i){var a,c;const o=typeof i=="number"?(a=r.accessors)==null?void 0:a[i]:i;if(!o)throw new Error(`No gltf accessor ${JSON.stringify(i)}`);const u=(c=r.bufferViews)==null?void 0:c[o.bufferView||0];if(!u)throw new Error(`No gltf buffer view for accessor ${u}`);const{arrayBuffer:l,byteOffset:m}=n[u.buffer],b=(m||0)+(o.byteOffset||0)+(u.byteOffset||0),{ArrayType:d,length:x,componentByteSize:g,numberOfComponentsInElement:_}=li(o,u),w=g*_,f=u.byteStride||w;if(u.byteStride===void 0||u.byteStride===w)return new d(l,b,x);const p=new d(x);for(let h=0;ht===e)||this.json.extensionsUsed.push(e)}registerRequiredExtension(e){this.registerUsedExtension(e),this.json.extensionsRequired=this.json.extensionsRequired||[],this.json.extensionsRequired.find(t=>t===e)||this.json.extensionsRequired.push(e)}removeExtension(e){var t;if((t=this.json.extensions)!=null&&t[e]){this.json.extensionsRemoved=this.json.extensionsRemoved||[];const r=this.json.extensionsRemoved;r.includes(e)||r.push(e)}this.json.extensions&&delete this.json.extensions[e],this.json.extensionsRequired&&this._removeStringFromArray(this.json.extensionsRequired,e),this.json.extensionsUsed&&this._removeStringFromArray(this.json.extensionsUsed,e)}setDefaultScene(e){this.json.scene=e}addScene(e){const{nodeIndices:t}=e;return this.json.scenes=this.json.scenes||[],this.json.scenes.push({nodes:t}),this.json.scenes.length-1}addNode(e){const{meshIndex:t,matrix:r}=e;this.json.nodes=this.json.nodes||[];const n={mesh:t};return r&&(n.matrix=r),this.json.nodes.push(n),this.json.nodes.length-1}addMesh(e){const{attributes:t,indices:r,material:n,mode:i=4}=e,o={primitives:[{attributes:this._addAttributes(t),mode:i}]};if(r){const u=this._addIndices(r);o.primitives[0].indices=u}return Number.isFinite(n)&&(o.primitives[0].material=n),this.json.meshes=this.json.meshes||[],this.json.meshes.push(o),this.json.meshes.length-1}addPointCloud(e){const t={primitives:[{attributes:this._addAttributes(e),mode:0}]};return this.json.meshes=this.json.meshes||[],this.json.meshes.push(t),this.json.meshes.length-1}addImage(e,t){const r=ui(e),n=t||(r==null?void 0:r.mimeType),i={bufferView:this.addBufferView(e),mimeType:n};return this.json.images=this.json.images||[],this.json.images.push(i),this.json.images.length-1}addBufferView(e,t=0,r=this.byteLength){const n=e.byteLength;Ee(Number.isFinite(n)),this.sourceBuffers=this.sourceBuffers||[],this.sourceBuffers.push(e);const i={buffer:t,byteOffset:r,byteLength:n};return this.byteLength+=Tr(n,4),this.json.bufferViews=this.json.bufferViews||[],this.json.bufferViews.push(i),this.json.bufferViews.length-1}addAccessor(e,t){const r={bufferView:e,type:du(t.size),componentType:t.componentType,count:t.count,max:t.max,min:t.min};return this.json.accessors=this.json.accessors||[],this.json.accessors.push(r),this.json.accessors.length-1}addBinaryBuffer(e,t={size:3}){const r=this.addBufferView(e);let n={min:t.min,max:t.max};n.min&&n.max||(n=this._getAccessorMinMax(e,t.size));const i={size:t.size,componentType:ms(e),count:Math.round(e.length/t.size),min:n.min,max:n.max};return this.addAccessor(r,Object.assign(i,t))}addTexture(e){const{imageIndex:t}=e,r={source:t};return this.json.textures=this.json.textures||[],this.json.textures.push(r),this.json.textures.length-1}addMaterial(e){return this.json.materials=this.json.materials||[],this.json.materials.push(e),this.json.materials.length-1}createBinaryChunk(){var i,o;const e=this.byteLength,t=new ArrayBuffer(e),r=new Uint8Array(t);let n=0;for(const u of this.sourceBuffers||[])n=Id(u,r,n);(o=(i=this.json)==null?void 0:i.buffers)!=null&&o[0]?this.json.buffers[0].byteLength=e:this.json.buffers=[{byteLength:e}],this.gltf.binary=t,this.sourceBuffers=[t],this.gltf.buffers=[{arrayBuffer:t,byteOffset:0,byteLength:t.byteLength}]}_removeStringFromArray(e,t){let r=!0;for(;r;){const n=e.indexOf(t);n>-1?e.splice(n,1):r=!1}}_addAttributes(e={}){const t={};for(const r in e){const n=e[r],i=this._getGltfAttributeName(r),o=this.addBinaryBuffer(n.value,n);t[i]=o}return t}_addIndices(e){return this.addBinaryBuffer(e,{size:1})}_getGltfAttributeName(e){switch(e.toLowerCase()){case"position":case"positions":case"vertices":return"POSITION";case"normal":case"normals":return"NORMAL";case"color":case"colors":return"COLOR_0";case"texcoord":case"texcoords":return"TEXCOORD_0";default:return e}}_getAccessorMinMax(e,t){const r={min:null,max:null};if(e.lengthx===b);d===-1&&(d=r.push(b)-1),i.push(d)}const o=new Uint32Array(i),u=s.gltf.buffers.push({arrayBuffer:o.buffer,byteOffset:o.byteOffset,byteLength:o.byteLength})-1,l=s.addBufferView(o,u,0),m=s.addAccessor(l,{size:1,componentType:ms(o),count:o.length});n.attributes[e]=m}function ph(s,e,t,r,n=[0]){const i={r:{offset:0,shift:0},g:{offset:1,shift:8},b:{offset:2,shift:16},a:{offset:3,shift:24}},o=t[r],u=t[r+1];let l=1;!e||e.indexOf("image/jpeg")===-1&&e.indexOf("image/png")===-1||(l=4);const m=function(d,x,g,_=1){const w=g.width,f=hu(d)*(w-1),p=Math.round(f),a=g.height,c=hu(x)*(a-1),h=Math.round(c),y=g.components?g.components:_;return(h*w+p)*y}(o,u,s,l);let b=0;for(const d of n){const x=typeof d=="number"?Object.values(i)[d]:i[d],g=m+x.offset,_=nu(s);if(_.data.length<=g)throw new Error(`${_.data.length} <= ${g}`);b|=_.data[g]<r)break;const m=u/n,b=l/n;i.push(s.slice(m,m+b))}return i}function yu(s,e,t){const r=[];for(let n=0;n{if(i.data){const{accessorKey:u,index:l}=function(x){const g="_FEATURE_ID_",_=Object.keys(x).filter(p=>p.indexOf(g)===0);let w=-1;for(const p of _){const a=Number(p.substring(g.length));a>w&&(w=a)}return w++,{accessorKey:`${g}${w}`,index:w}}(e.attributes),m=new Uint32Array(i.data);r[o]={featureCount:m.length,propertyTable:i.propertyTable,attribute:l},s.gltf.buffers.push({arrayBuffer:m.buffer,byteOffset:m.byteOffset,byteLength:m.byteLength});const b=s.addBufferView(m),d=s.addAccessor(b,{size:1,componentType:ms(m),count:m.length});e.attributes[u]=d}})}const bh=Object.freeze(Object.defineProperty({__proto__:null,createExtMeshFeatures:function(s,e,t,r){e.extensions||(e.extensions={});let n=e.extensions[ur];n||(n={featureIds:[]},e.extensions[ur]=n);const{featureIds:i}=n,o={featureCount:t.length,propertyTable:r,data:t};i.push(o),s.addObjectExtension(e,ur,n)},decode:async function(s,e){(function(t,r){const n=t.gltf.json;if(n.meshes)for(const i of n.meshes)for(const o of i.primitives)gh(t,o,r)})(new xe(s),e)},encode:function(s,e){const t=new xe(s);return function(r){const n=r.gltf.json.meshes;if(n)for(const i of n)for(const o of i.primitives)yh(r,o)}(t),t.createBinaryChunk(),t.gltf},name:mh},Symbol.toStringTag,{value:"Module"})),cr="EXT_structural_metadata",xh=cr;function _h(s,e){for(const t of s)if(t.class===e)return t;return null}function Ah(s,e,t,r){var o;if(!e)return;const n=(o=t.extensions)==null?void 0:o[cr],i=n==null?void 0:n.propertyTextures;if(i)for(const u of i)Bh(s,e[u],t,r)}function Bh(s,e,t,r){var i;if(!e.properties)return;r.dataAttributeNames||(r.dataAttributeNames=[]);const n=e.class;for(const o in e.properties){const u=`${n}_${o}`,l=(i=e.properties)==null?void 0:i[o];if(!l)continue;l.data||(l.data=[]);const m=l.data,b=hi(s,l,t);b!==null&&(mu(s,u,b,m,t),l.data=m,r.dataAttributeNames.push(u))}}function vh(s,e,t){var i,o;const r=(i=e.classes)==null?void 0:i[t.class];if(!r)throw new Error(`Incorrect data in the EXT_structural_metadata extension: no schema class with name ${t.class}`);const n=t.count;for(const u in r.properties){const l=r.properties[u],m=(o=t.properties)==null?void 0:o[u];if(m){const b=wh(s,e,l,n,m);m.data=b}}}function wh(s,e,t,r,n){let i=[];const o=n.values,u=s.getTypedArrayForBufferView(o),l=function(b,d,x,g){return d.array&&d.count===void 0&&x.arrayOffsets!==void 0?gs(b,x.arrayOffsets,x.arrayOffsetType||"UINT32",g):null}(s,t,n,r),m=function(b,d,x){return d.stringOffsets!==void 0?gs(b,d.stringOffsets,d.stringOffsetType||"UINT32",x):null}(s,n,r);switch(t.type){case"SCALAR":case"VEC2":case"VEC3":case"VEC4":case"MAT2":case"MAT3":case"MAT4":i=function(b,d,x,g){const _=b.array,w=b.count,f=di(b.type,b.componentType),p=x.byteLength/f;let a;return a=b.componentType?ys(x,b.type,b.componentType,p):x,_?g?gu(a,d,g,x.length,f):w?yu(a,d,w):[]:a}(t,r,u,l);break;case"BOOLEAN":throw new Error(`Not implemented - classProperty.type=${t.type}`);case"STRING":i=bu(r,u,l,m);break;case"ENUM":i=function(b,d,x,g,_){var y;const w=d.enumType;if(!w)throw new Error("Incorrect data in the EXT_structural_metadata extension: classProperty.enumType is not set for type ENUM");const f=(y=b.enums)==null?void 0:y[w];if(!f)throw new Error(`Incorrect data in the EXT_structural_metadata extension: schema.enums does't contain ${w}`);const p=f.valueType||"UINT16",a=di(d.type,p),c=g.byteLength/a;let h=ys(g,d.type,p,c);if(h||(h=g),d.array){if(_)return function(C){const{valuesData:R,numberOfElements:U,arrayOffsets:k,valuesDataBytesLength:T,elementSize:S,enumEntry:P}=C,L=[];for(let F=0;FT)break;const K=fi(R,O/S,H/S,P);L.push(K)}return L}({valuesData:h,numberOfElements:x,arrayOffsets:_,valuesDataBytesLength:g.length,elementSize:a,enumEntry:f});const A=d.count;return A?function(C,R,U,k){const T=[];for(let S=0;S{u(m).then(d=>{const{BasisFile:x,initializeBasis:g}=d;g(),b({BasisFile:x})})})}(i,o)}(s)),await _u)}async function Bu(s){const e=s.modules||{};return e.basisEncoder?e.basisEncoder:(mi=mi||async function(t){let r=null,n=null;return[r,n]=await Promise.all([await Ft(Vh,"textures",t),await Ft(Hh,"textures",t)]),r=r||globalThis.BASIS,await function(i,o){const u={};return o&&(u.wasmBinary=o),new Promise(l=>{i(u).then(m=>{const{BasisFile:b,KTX2File:d,initializeBasis:x,BasisEncoder:g}=m;x(),l({BasisFile:b,KTX2File:d,BasisEncoder:g})})})}(r,n)}(s),await mi)}const Jh=["","WEBKIT_","MOZ_"],vu={WEBGL_compressed_texture_s3tc:"dxt",WEBGL_compressed_texture_s3tc_srgb:"dxt-srgb",WEBGL_compressed_texture_etc1:"etc1",WEBGL_compressed_texture_etc:"etc2",WEBGL_compressed_texture_pvrtc:"pvrtc",WEBGL_compressed_texture_atc:"atc",WEBGL_compressed_texture_astc:"astc",EXT_texture_compression_rgtc:"rgtc"};let bs=null;function zh(s){if(!bs){s=s||function(){try{return document.createElement("canvas").getContext("webgl")}catch{return null}}()||void 0,bs=new Set;for(const e of Jh)for(const t in vu)if(s&&s.getExtension(`${e}${t}`)){const r=vu[t];bs.add(r)}}return bs}const Me=[171,75,84,88,32,50,48,187,13,10,26,10],jh={etc1:{basisFormat:0,compressed:!0,format:36196},etc2:{basisFormat:1,compressed:!0},bc1:{basisFormat:2,compressed:!0,format:33776},bc3:{basisFormat:3,compressed:!0,format:33779},bc4:{basisFormat:4,compressed:!0},bc5:{basisFormat:5,compressed:!0},"bc7-m6-opaque-only":{basisFormat:6,compressed:!0},"bc7-m5":{basisFormat:7,compressed:!0},"pvrtc1-4-rgb":{basisFormat:8,compressed:!0,format:35840},"pvrtc1-4-rgba":{basisFormat:9,compressed:!0,format:35842},"astc-4x4":{basisFormat:10,compressed:!0,format:37808},"atc-rgb":{basisFormat:11,compressed:!0},"atc-rgba-interpolated-alpha":{basisFormat:12,compressed:!0},rgba32:{basisFormat:13,compressed:!1},rgb565:{basisFormat:14,compressed:!1},bgr565:{basisFormat:15,compressed:!1},rgba4444:{basisFormat:16,compressed:!1}};function gi(s,e,t){const r=new s(new Uint8Array(e));try{if(!r.startTranscoding())throw new Error("Failed to start basis transcoding");const n=r.getNumImages(),i=[];for(let o=0;o20);const d=m.getUint32(b+0,lr),x=m.getUint32(b+4,lr);return b+=8,ct(x===0),yi(l,m,b,d),b+=d,b+=bi(l,m,b,l.header.byteLength),b}(s,n,t);case 2:return function(l,m,b,d){return ct(l.header.byteLength>20),function(x,g,_,w){for(;_+8<=x.header.byteLength;){const f=g.getUint32(_+0,lr),p=g.getUint32(_+4,lr);switch(_+=8,p){case Wh:yi(x,g,_,f);break;case $h:bi(x,g,_,f);break;case 0:w.strict||yi(x,g,_,f);break;case 1:w.strict||bi(x,g,_,f)}_+=Tr(f,4)}}(l,m,b,d),b+l.header.byteLength}(s,n,t,{});default:throw new Error(`Invalid GLB version ${s.version}. Only supports version 1 and 2.`)}}function yi(s,e,t,r){const n=new Uint8Array(e.buffer,t,r),i=new TextDecoder("utf8").decode(n);return s.json=JSON.parse(i),Tr(r,4)}function bi(s,e,t,r){return s.header.hasBinChunk=!0,s.binChunks.push({byteOffset:t,byteLength:r,arrayBuffer:e.buffer}),Tr(r,4)}function Eu(s,e){if(s.startsWith("data:")||s.startsWith("http:")||s.startsWith("https:"))return s;const t=e.baseUri||e.uri;if(!t)throw new Error(`'baseUri' must be provided to resolve relative url ${s}`);return t.substr(0,t.lastIndexOf("/")+1)+s}const Qh="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",Zh="B9h9z9tFBBBF8dL9gBB9gLaaaaaFa9gEaaaB9gGaaB9gFaFaEQSBBFBFFGEGEGIILF9wFFFLEFBFKNFaFCx/aFMO/LFVK9tv9t9vq95GBt9f9f939h9z9t9f9j9h9s9s9f9jW9vq9zBBp9tv9z9o9v9wW9f9kv9j9v9kv9WvqWv94h919m9mvqBG8Z9tv9z9o9v9wW9f9kv9j9v9kv9J9u9kv94h919m9mvqBIy9tv9z9o9v9wW9f9kv9j9v9kv9J9u9kv949TvZ91v9u9jvBLn9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9P9jWBKi9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9R919hWBNn9tv9z9o9v9wW9f9kv9j9v9kv69p9sWvq9F949wBcI9z9iqlBMc/j9JSIBTEM9+FLa8jUUUUBCTlRBCBRFEXCBRGCBREEXABCNJAGJAECUaAFAGrCFZHIy86BBAEAIJREAGCFJHGCN9HQBMAFCx+YUUBJAE86BBAFCEWCxkUUBJAB8pEN83EBAFCFJHFCUG9HQBMMkRIbaG97FaK978jUUUUBCU/KBlHL8kUUUUBC9+RKGXAGCFJAI9LQBCaRKAE2BBC+gF9HQBALAEAIJHOAGlAG/8cBBCUoBAG9uC/wgBZHKCUGAKCUG9JyRNAECFJRKCBRVGXEXAVAF9PQFANAFAVlAVANJAF9JyRcGXGXAG9FQBAcCbJHIC9wZHMCE9sRSAMCFWRQAICIrCEJCGrRfCBRbEXAKRTCBRtGXEXGXAOATlAf9PQBCBRKSLMALCU/CBJAtAM9sJRmATAfJRKCBREGXAMCoB9JQBAOAKlC/gB9JQBCBRIEXAmAIJREGXGXGXGXGXATAICKrJ2BBHYCEZfIBFGEBMAECBDtDMIBSEMAEAKDBBIAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnHPCGD+MFAPDQBTFtGmEYIPLdKeOnC0+G+MiDtD9OHdCEDbD8jHPD8dBhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBAeCx+YUUBJDBBBHnAnDQBBBBBBBBBBBBBBBBAPD8dFhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIBAKCIJAnDeBJAeCx+YUUBJ2BBJRKSGMAEAKDBBNAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnC+P+e+8/4BDtD9OHdCbDbD8jHPD8dBhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBAeCx+YUUBJDBBBHnAnDQBBBBBBBBBBBBBBBBAPD8dFhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIBAKCNJAnDeBJAeCx+YUUBJ2BBJRKSFMAEAKDBBBDMIBAKCTJRKMGXGXGXGXGXAYCGrCEZfIBFGEBMAECBDtDMITSEMAEAKDBBIAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnHPCGD+MFAPDQBTFtGmEYIPLdKeOnC0+G+MiDtD9OHdCEDbD8jHPD8dBhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBAeCx+YUUBJDBBBHnAnDQBBBBBBBBBBBBBBBBAPD8dFhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMITAKCIJAnDeBJAeCx+YUUBJ2BBJRKSGMAEAKDBBNAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnC+P+e+8/4BDtD9OHdCbDbD8jHPD8dBhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBAeCx+YUUBJDBBBHnAnDQBBBBBBBBBBBBBBBBAPD8dFhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMITAKCNJAnDeBJAeCx+YUUBJ2BBJRKSFMAEAKDBBBDMITAKCTJRKMGXGXGXGXGXAYCIrCEZfIBFGEBMAECBDtDMIASEMAEAKDBBIAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnHPCGD+MFAPDQBTFtGmEYIPLdKeOnC0+G+MiDtD9OHdCEDbD8jHPD8dBhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBAeCx+YUUBJDBBBHnAnDQBBBBBBBBBBBBBBBBAPD8dFhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIAAKCIJAnDeBJAeCx+YUUBJ2BBJRKSGMAEAKDBBNAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnC+P+e+8/4BDtD9OHdCbDbD8jHPD8dBhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBAeCx+YUUBJDBBBHnAnDQBBBBBBBBBBBBBBBBAPD8dFhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIAAKCNJAnDeBJAeCx+YUUBJ2BBJRKSFMAEAKDBBBDMIAAKCTJRKMGXGXGXGXGXAYCKrfIBFGEBMAECBDtDMI8wSEMAEAKDBBIAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnHPCGD+MFAPDQBTFtGmEYIPLdKeOnC0+G+MiDtD9OHdCEDbD8jHPD8dBhUg/8/4/w/goB9+h84k7HYCEWCxkUUBJDBEBAYCx+YUUBJDBBBHnAnDQBBBBBBBBBBBBBBBBAPD8dFhUg/8/4/w/goB9+h84k7HYCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMI8wAKCIJAnDeBJAYCx+YUUBJ2BBJRKSGMAEAKDBBNAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnC+P+e+8/4BDtD9OHdCbDbD8jHPD8dBhUg/8/4/w/goB9+h84k7HYCEWCxkUUBJDBEBAYCx+YUUBJDBBBHnAnDQBBBBBBBBBBBBBBBBAPD8dFhUg/8/4/w/goB9+h84k7HYCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMI8wAKCNJAnDeBJAYCx+YUUBJ2BBJRKSFMAEAKDBBBDMI8wAKCTJRKMAICoBJREAICUFJAM9LQFAERIAOAKlC/fB9LQBMMGXAEAM9PQBAECErRIEXGXAOAKlCi9PQBCBRKSOMAmAEJRYGXGXGXGXGXATAECKrJ2BBAICKZrCEZfIBFGEBMAYCBDtDMIBSEMAYAKDBBIAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnHPCGD+MFAPDQBTFtGmEYIPLdKeOnC0+G+MiDtD9OHdCEDbD8jHPD8dBhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBAeCx+YUUBJDBBBHnAnDQBBBBBBBBBBBBBBBBAPD8dFhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIBAKCIJAnDeBJAeCx+YUUBJ2BBJRKSGMAYAKDBBNAKDBBBHPCID+MFAPDQBTFtGmEYIPLdKeOnC+P+e+8/4BDtD9OHdCbDbD8jHPD8dBhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBAeCx+YUUBJDBBBHnAnDQBBBBBBBBBBBBBBBBAPD8dFhUg/8/4/w/goB9+h84k7HeCEWCxkUUBJDBEBD9uDQBFGEILKOTtmYPdenDfAdAPD9SDMIBAKCNJAnDeBJAeCx+YUUBJ2BBJRKSFMAYAKDBBBDMIBAKCTJRKMAICGJRIAECTJHEAM9JQBMMGXAK9FQBAKRTAtCFJHtCI6QGSFMMCBRKSEMGXAM9FQBALCUGJAbJREALAbJDBGBRnCBRYEXAEALCU/CBJAYJHIDBIBHdCFD9tAdCFDbHPD9OD9hD9RHdAIAMJDBIBHiCFD9tAiAPD9OD9hD9RHiDQBTFtGmEYIPLdKeOnH8ZAIAQJDBIBHpCFD9tApAPD9OD9hD9RHpAIASJDBIBHyCFD9tAyAPD9OD9hD9RHyDQBTFtGmEYIPLdKeOnH8cDQBFTtGEmYILPdKOenHPAPDQBFGEBFGEBFGEBFGEAnD9uHnDyBjGBAEAGJHIAnAPAPDQILKOILKOILKOILKOD9uHnDyBjGBAIAGJHIAnAPAPDQNVcMNVcMNVcMNVcMD9uHnDyBjGBAIAGJHIAnAPAPDQSQfbSQfbSQfbSQfbD9uHnDyBjGBAIAGJHIAnA8ZA8cDQNVi8ZcMpySQ8c8dfb8e8fHPAPDQBFGEBFGEBFGEBFGED9uHnDyBjGBAIAGJHIAnAPAPDQILKOILKOILKOILKOD9uHnDyBjGBAIAGJHIAnAPAPDQNVcMNVcMNVcMNVcMD9uHnDyBjGBAIAGJHIAnAPAPDQSQfbSQfbSQfbSQfbD9uHnDyBjGBAIAGJHIAnAdAiDQNiV8ZcpMyS8cQ8df8eb8fHdApAyDQNiV8ZcpMyS8cQ8df8eb8fHiDQBFTtGEmYILPdKOenHPAPDQBFGEBFGEBFGEBFGED9uHnDyBjGBAIAGJHIAnAPAPDQILKOILKOILKOILKOD9uHnDyBjGBAIAGJHIAnAPAPDQNVcMNVcMNVcMNVcMD9uHnDyBjGBAIAGJHIAnAPAPDQSQfbSQfbSQfbSQfbD9uHnDyBjGBAIAGJHIAnAdAiDQNVi8ZcMpySQ8c8dfb8e8fHPAPDQBFGEBFGEBFGEBFGED9uHnDyBjGBAIAGJHIAnAPAPDQILKOILKOILKOILKOD9uHnDyBjGBAIAGJHIAnAPAPDQNVcMNVcMNVcMNVcMD9uHnDyBjGBAIAGJHIAnAPAPDQSQfbSQfbSQfbSQfbD9uHnDyBjGBAIAGJREAYCTJHYAM9JQBMMAbCIJHbAG9JQBMMABAVAG9sJALCUGJAcAG9s/8cBBALALCUGJAcCaJAG9sJAG/8cBBMAcCBAKyAVJRVAKQBMC9+RKSFMCBC99AOAKlAGCAAGCA9Ly6yRKMALCU/KBJ8kUUUUBAKMNBT+BUUUBM+KmFTa8jUUUUBCoFlHL8kUUUUBC9+RKGXAFCE9uHOCtJAI9LQBCaRKAE2BBHNC/wFZC/gF9HQBANCbZHVCF9LQBALCoBJCgFCUF/8MBALC84Jha83EBALC8wJha83EBALC8oJha83EBALCAJha83EBALCiJha83EBALCTJha83EBALha83ENALha83EBAEAIJC9wJRcAECFJHNAOJRMGXAF9FQBCQCbAVCF6yRSABRECBRVCBRQCBRfCBRICBRKEXGXAMAcuQBC9+RKSEMGXGXAN2BBHOC/vF9LQBALCoBJAOCIrCa9zAKJCbZCEWJHb8oGIRTAb8oGBRtGXAOCbZHbAS9PQBALAOCa9zAIJCbZCGWJ8oGBAVAbyROAb9FRbGXGXAGCG9HQBABAt87FBABCIJAO87FBABCGJAT87FBSFMAEAtjGBAECNJAOjGBAECIJATjGBMAVAbJRVALCoBJAKCEWJHmAOjGBAmATjGIALAICGWJAOjGBALCoBJAKCFJCbZHKCEWJHTAtjGBATAOjGIAIAbJRIAKCFJRKSGMGXGXAbCb6QBAQAbJAbC989zJCFJRQSFMAM1BBHbCgFZROGXGXAbCa9MQBAMCFJRMSFMAM1BFHbCgBZCOWAOCgBZqROGXAbCa9MQBAMCGJRMSFMAM1BGHbCgBZCfWAOqROGXAbCa9MQBAMCEJRMSFMAM1BEHbCgBZCdWAOqROGXAbCa9MQBAMCIJRMSFMAM2BIC8cWAOqROAMCLJRMMAOCFrCBAOCFZl9zAQJRQMGXGXAGCG9HQBABAt87FBABCIJAQ87FBABCGJAT87FBSFMAEAtjGBAECNJAQjGBAECIJATjGBMALCoBJAKCEWJHOAQjGBAOATjGIALAICGWJAQjGBALCoBJAKCFJCbZHKCEWJHOAtjGBAOAQjGIAICFJRIAKCFJRKSFMGXAOCDF9LQBALAIAcAOCbZJ2BBHbCIrHTlCbZCGWJ8oGBAVCFJHtATyROALAIAblCbZCGWJ8oGBAtAT9FHmJHtAbCbZHTyRbAT9FRTGXGXAGCG9HQBABAV87FBABCIJAb87FBABCGJAO87FBSFMAEAVjGBAECNJAbjGBAECIJAOjGBMALAICGWJAVjGBALCoBJAKCEWJHYAOjGBAYAVjGIALAICFJHICbZCGWJAOjGBALCoBJAKCFJCbZCEWJHYAbjGBAYAOjGIALAIAmJCbZHICGWJAbjGBALCoBJAKCGJCbZHKCEWJHOAVjGBAOAbjGIAKCFJRKAIATJRIAtATJRVSFMAVCBAM2BBHYyHTAOC/+F6HPJROAYCbZRtGXGXAYCIrHmQBAOCFJRbSFMAORbALAIAmlCbZCGWJ8oGBROMGXGXAtQBAbCFJRVSFMAbRVALAIAYlCbZCGWJ8oGBRbMGXGXAP9FQBAMCFJRYSFMAM1BFHYCgFZRTGXGXAYCa9MQBAMCGJRYSFMAM1BGHYCgBZCOWATCgBZqRTGXAYCa9MQBAMCEJRYSFMAM1BEHYCgBZCfWATqRTGXAYCa9MQBAMCIJRYSFMAM1BIHYCgBZCdWATqRTGXAYCa9MQBAMCLJRYSFMAMCKJRYAM2BLC8cWATqRTMATCFrCBATCFZl9zAQJHQRTMGXGXAmCb6QBAYRPSFMAY1BBHMCgFZROGXGXAMCa9MQBAYCFJRPSFMAY1BFHMCgBZCOWAOCgBZqROGXAMCa9MQBAYCGJRPSFMAY1BGHMCgBZCfWAOqROGXAMCa9MQBAYCEJRPSFMAY1BEHMCgBZCdWAOqROGXAMCa9MQBAYCIJRPSFMAYCLJRPAY2BIC8cWAOqROMAOCFrCBAOCFZl9zAQJHQROMGXGXAtCb6QBAPRMSFMAP1BBHMCgFZRbGXGXAMCa9MQBAPCFJRMSFMAP1BFHMCgBZCOWAbCgBZqRbGXAMCa9MQBAPCGJRMSFMAP1BGHMCgBZCfWAbqRbGXAMCa9MQBAPCEJRMSFMAP1BEHMCgBZCdWAbqRbGXAMCa9MQBAPCIJRMSFMAPCLJRMAP2BIC8cWAbqRbMAbCFrCBAbCFZl9zAQJHQRbMGXGXAGCG9HQBABAT87FBABCIJAb87FBABCGJAO87FBSFMAEATjGBAECNJAbjGBAECIJAOjGBMALCoBJAKCEWJHYAOjGBAYATjGIALAICGWJATjGBALCoBJAKCFJCbZCEWJHYAbjGBAYAOjGIALAICFJHICbZCGWJAOjGBALCoBJAKCGJCbZCEWJHOATjGBAOAbjGIALAIAm9FAmCb6qJHICbZCGWJAbjGBAIAt9FAtCb6qJRIAKCEJRKMANCFJRNABCKJRBAECSJREAKCbZRKAICbZRIAfCEJHfAF9JQBMMCBC99AMAc6yRKMALCoFJ8kUUUUBAKM/tIFGa8jUUUUBCTlRLC9+RKGXAFCLJAI9LQBCaRKAE2BBC/+FZC/QF9HQBALhB83ENAECFJRKAEAIJC98JREGXAF9FQBGXAGCG6QBEXGXAKAE9JQBC9+bMAK1BBHGCgFZRIGXGXAGCa9MQBAKCFJRKSFMAK1BFHGCgBZCOWAICgBZqRIGXAGCa9MQBAKCGJRKSFMAK1BGHGCgBZCfWAIqRIGXAGCa9MQBAKCEJRKSFMAK1BEHGCgBZCdWAIqRIGXAGCa9MQBAKCIJRKSFMAK2BIC8cWAIqRIAKCLJRKMALCNJAICFZCGWqHGAICGrCBAICFrCFZl9zAG8oGBJHIjGBABAIjGBABCIJRBAFCaJHFQBSGMMEXGXAKAE9JQBC9+bMAK1BBHGCgFZRIGXGXAGCa9MQBAKCFJRKSFMAK1BFHGCgBZCOWAICgBZqRIGXAGCa9MQBAKCGJRKSFMAK1BGHGCgBZCfWAIqRIGXAGCa9MQBAKCEJRKSFMAK1BEHGCgBZCdWAIqRIGXAGCa9MQBAKCIJRKSFMAK2BIC8cWAIqRIAKCLJRKMABAICGrCBAICFrCFZl9zALCNJAICFZCGWqHI8oGBJHG87FBAIAGjGBABCGJRBAFCaJHFQBMMCBC99AKAE6yRKMAKM/xLGEaK978jUUUUBCAlHE8kUUUUBGXGXAGCI9HQBGXAFC98ZHI9FQBABRGCBRLEXAGAGDBBBHKCiD+rFCiD+sFD/6FHOAKCND+rFCiD+sFD/6FAOD/gFAKCTD+rFCiD+sFD/6FHND/gFD/kFD/lFHVCBDtD+2FHcAOCUUUU94DtHMD9OD9RD/kFHO9DBB/+hDYAOAOD/mFAVAVD/mFANAcANAMD9OD9RD/kFHOAOD/mFD/kFD/kFD/jFD/nFHND/mF9DBBX9LDYHcD/kFCgFDtD9OAKCUUU94DtD9OD9QAOAND/mFAcD/kFCND+rFCU/+EDtD9OD9QAVAND/mFAcD/kFCTD+rFCUU/8ODtD9OD9QDMBBAGCTJRGALCIJHLAI9JQBMMAIAF9PQFAEAFCEZHLCGWHGqCBCTAGl/8MBAEABAICGWJHIAG/8cBBGXAL9FQBAEAEDBIBHKCiD+rFCiD+sFD/6FHOAKCND+rFCiD+sFD/6FAOD/gFAKCTD+rFCiD+sFD/6FHND/gFD/kFD/lFHVCBDtD+2FHcAOCUUUU94DtHMD9OD9RD/kFHO9DBB/+hDYAOAOD/mFAVAVD/mFANAcANAMD9OD9RD/kFHOAOD/mFD/kFD/kFD/jFD/nFHND/mF9DBBX9LDYHcD/kFCgFDtD9OAKCUUU94DtD9OD9QAOAND/mFAcD/kFCND+rFCU/+EDtD9OD9QAVAND/mFAcD/kFCTD+rFCUU/8ODtD9OD9QDMIBMAIAEAG/8cBBSFMABAFC98ZHGT+HUUUBAGAF9PQBAEAFCEZHICEWHLJCBCAALl/8MBAEABAGCEWJHGAL/8cBBAEAIT+HUUUBAGAEAL/8cBBMAECAJ8kUUUUBM+yEGGaO97GXAF9FQBCBRGEXABCTJHEAEDBBBHICBDtHLCUU98D8cFCUU98D8cEHKD9OABDBBBHOAIDQILKOSQfbPden8c8d8e8fCggFDtD9OD/6FAOAIDQBFGENVcMTtmYi8ZpyHICTD+sFD/6FHND/gFAICTD+rFCTD+sFD/6FHVD/gFD/kFD/lFHI9DB/+g6DYAVAIALD+2FHLAVCUUUU94DtHcD9OD9RD/kFHVAVD/mFAIAID/mFANALANAcD9OD9RD/kFHIAID/mFD/kFD/kFD/jFD/nFHND/mF9DBBX9LDYHLD/kFCTD+rFAVAND/mFALD/kFCggEDtD9OD9QHVAIAND/mFALD/kFCaDbCBDnGCBDnECBDnKCBDnOCBDncCBDnMCBDnfCBDnbD9OHIDQNVi8ZcMpySQ8c8dfb8e8fD9QDMBBABAOAKD9OAVAIDQBFTtGEmYILPdKOenD9QDMBBABCAJRBAGCIJHGAF9JQBMMM94FEa8jUUUUBCAlHE8kUUUUBABAFC98ZHIT+JUUUBGXAIAF9PQBAEAFCEZHLCEWHFJCBCAAFl/8MBAEABAICEWJHBAF/8cBBAEALT+JUUUBABAEAF/8cBBMAECAJ8kUUUUBM/hEIGaF97FaL978jUUUUBCTlRGGXAF9FQBCBREEXAGABDBBBHIABCTJHLDBBBHKDQILKOSQfbPden8c8d8e8fHOCTD+sFHNCID+rFDMIBAB9DBBU8/DY9D/zI818/DYANCEDtD9QD/6FD/nFHNAIAKDQBFGENVcMTtmYi8ZpyHICTD+rFCTD+sFD/6FD/mFHKAKD/mFANAICTD+sFD/6FD/mFHVAVD/mFANAOCTD+rFCTD+sFD/6FD/mFHOAOD/mFD/kFD/kFD/lFCBDtD+4FD/jF9DB/+g6DYHND/mF9DBBX9LDYHID/kFCggEDtHcD9OAVAND/mFAID/kFCTD+rFD9QHVAOAND/mFAID/kFCTD+rFAKAND/mFAID/kFAcD9OD9QHNDQBFTtGEmYILPdKOenHID8dBAGDBIBDyB+t+J83EBABCNJAID8dFAGDBIBDyF+t+J83EBALAVANDQNVi8ZcMpySQ8c8dfb8e8fHND8dBAGDBIBDyG+t+J83EBABCiJAND8dFAGDBIBDyE+t+J83EBABCAJRBAECIJHEAF9JQBMMM/3FGEaF978jUUUUBCoBlREGXAGCGrAF9sHIC98ZHL9FQBCBRGABRFEXAFAFDBBBHKCND+rFCND+sFD/6FAKCiD+sFCnD+rFCUUU/8EDtD+uFD/mFDMBBAFCTJRFAGCIJHGAL9JQBMMGXALAI9PQBAEAICEZHGCGWHFqCBCoBAFl/8MBAEABALCGWJHLAF/8cBBGXAG9FQBAEAEDBIBHKCND+rFCND+sFD/6FAKCiD+sFCnD+rFCUUU/8EDtD+uFD/mFDMIBMALAEAF/8cBBMM9TFEaCBCB8oGUkUUBHFABCEJC98ZJHBjGUkUUBGXGXAB8/BCTWHGuQBCaREABAGlCggEJCTrXBCa6QFMAFREMAEMMMFBCUNMIT9tBB",ef=new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,3,2,0,0,5,3,1,0,1,12,1,0,10,22,2,12,0,65,0,65,0,65,0,252,10,0,0,11,7,0,65,0,253,15,26,11]),tf=new Uint8Array([32,0,65,253,3,1,2,34,4,106,6,5,11,8,7,20,13,33,12,16,128,9,116,64,19,113,127,15,10,21,22,14,255,66,24,54,136,107,18,23,192,26,114,118,132,17,77,101,130,144,27,87,131,44,45,74,156,154,70,167]),rf={0:"",1:"meshopt_decodeFilterOct",2:"meshopt_decodeFilterQuat",3:"meshopt_decodeFilterExp",NONE:"",OCTAHEDRAL:"meshopt_decodeFilterOct",QUATERNION:"meshopt_decodeFilterQuat",EXPONENTIAL:"meshopt_decodeFilterExp"},sf={0:"meshopt_decodeVertexBuffer",1:"meshopt_decodeIndexBuffer",2:"meshopt_decodeIndexSequence",ATTRIBUTES:"meshopt_decodeVertexBuffer",TRIANGLES:"meshopt_decodeIndexBuffer",INDICES:"meshopt_decodeIndexSequence"};async function nf(s,e,t,r,n,i="NONE"){const o=await async function(){return xi||(xi=async function(){let u=Qh;WebAssembly.validate(ef)&&(u=Zh,console.log("Warning: meshopt_decoder is using experimental SIMD support"));const l=await WebAssembly.instantiate(function(m){const b=new Uint8Array(m.length);for(let x=0;x96?g-71:g>64?g-65:g>47?g+4:g>46?63:62}let d=0;for(let x=0;xw?y:w,f=A>f?A:f,p=C>p?C:p}return[[x,g,_],[w,f,p]]}(l.attributes),b=function(d,x,g){const _=Pu(x.metadata),w=[],f=function(p){const a={};for(const c in p){const h=p[c];a[h.name||"undefined"]=h}return a}(x.attributes);for(const p in d){const a=Mu(p,d[p],f[p]);w.push(a)}if(g){const p=Mu("indices",g);w.push(p)}return{fields:w,metadata:_}}(l.attributes,u,l.indices);return{loader:"draco",loaderData:u,header:{vertexCount:i.num_points(),boundingBox:m},...l,schema:b}}finally{this.draco.destroy(r),i&&this.draco.destroy(i)}}_getDracoLoaderData(e,t,r){const n=this._getTopLevelMetadata(e),i=this._getDracoAttributes(e,r);return{geometry_type:t,num_attributes:e.num_attributes(),num_points:e.num_points(),num_faces:e instanceof this.draco.Mesh?e.num_faces():0,metadata:n,attributes:i}}_getDracoAttributes(e,t){const r={};for(let n=0;nthis.decoder[i]).includes(n)){const i=new this.draco.AttributeQuantizationTransform;try{if(i.InitFromAttribute(e))return{quantization_bits:i.quantization_bits(),range:i.range(),min_values:new Float32Array([1,2,3]).map(o=>i.min_value(o))}}finally{this.draco.destroy(i)}}return null}_getOctahedronTransform(e,t){const{octahedronAttributes:r=[]}=t,n=e.attribute_type();if(r.map(i=>this.decoder[i]).includes(n)){const i=new this.draco.AttributeQuantizationTransform;try{if(i.InitFromAttribute(e))return{quantization_bits:i.quantization_bits()}}finally{this.draco.destroy(i)}}return null}}const _i="https://www.gstatic.com/draco/versioned/decoders/1.5.6",As="draco_wasm_wrapper.js",Bs="draco_decoder.wasm",vs="draco_decoder.js",Gu="draco_encoder.js",Ai={[As]:`${_i}/${As}`,[Bs]:`${_i}/${Bs}`,[vs]:`${_i}/${vs}`,[Gu]:`https://raw.githubusercontent.com/google/draco/1.4.1/javascript/${Gu}`};let Bi;async function pf(s){const e=s.modules||{};return e.draco3d?Bi||(Bi=e.draco3d.createDecoderModule({}).then(t=>({draco:t}))):Bi||(Bi=async function(t){let r,n;return(t.draco&&t.draco.decoderType)==="js"?r=await Ft(Ai[vs],"draco",t,vs):[r,n]=await Promise.all([await Ft(Ai[As],"draco",t,As),await Ft(Ai[Bs],"draco",t,Bs)]),r=r||globalThis.DracoDecoderModule,await function(i,o){const u={};return o&&(u.wasmBinary=o),new Promise(l=>{i({...u,onModuleLoaded:m=>l({draco:m})})})}(r,n)}(s)),await Bi}const mf={...df,parse:async function(s,e){const{draco:t}=await pf(e),r=new ff(t);try{return r.parseSync(s,e==null?void 0:e.draco)}finally{r.destroy()}}};function Lu(s){const{buffer:e,size:t,count:r}=function(n){let i=n,o=1,u=0;return n&&n.value&&(i=n.value,o=n.size||1),i&&(ArrayBuffer.isView(i)||(i=function(l,m,b=!1){return l?Array.isArray(l)?new m(l):b&&!(l instanceof m)?new m(l):l:null}(i,Float32Array)),u=i.length/o),{buffer:i,size:o,count:u}}(s);return{value:e,size:t,byteOffset:0,count:r,type:du(t),componentType:ms(e)}}const kt="KHR_draco_mesh_compression",gf=kt;async function yf(s,e,t,r){const n=s.getObjectExtension(e,kt);if(!n)return;const i=s.getTypedArrayForBufferView(n.bufferView),o=Ga(i.buffer,i.byteOffset),u={...t};delete u["3d-tiles"];const l=await ba(o,mf,u,r),m=function(b){const d={};for(const x in b){const g=b[x];if(x!=="indices"){const _=Lu(g);d[x]=_}}return d}(l.attributes);for(const[b,d]of Object.entries(m))if(b in e.attributes){const x=e.attributes[b],g=s.getAccessor(x);g!=null&&g.min&&(g!=null&&g.max)&&(d.min=g.min,d.max=g.max)}e.attributes=m,l.indices&&(e.indices=Lu(l.indices)),s.removeObjectExtension(e,kt),function(b){if(!b.attributes&&Object.keys(b.attributes).length>0)throw new Error("glTF: Empty primitive detected: Draco decompression failure?")}(e)}function bf(s,e,t=4,r,n){if(!r.DracoWriter)throw new Error("options.gltf.DracoWriter not provided")}function*Ou(s){for(const e of s.json.meshes||[])for(const t of e.primitives)yield t}const xf=Object.freeze(Object.defineProperty({__proto__:null,decode:async function(s,e,t){var i;if(!((i=e==null?void 0:e.gltf)!=null&&i.decompressMeshes))return;const r=new xe(s),n=[];for(const o of Ou(r))r.getObjectExtension(o,kt)&&n.push(yf(r,o,e,t));await Promise.all(n),r.removeExtension(kt)},encode:function(s,e={}){const t=new xe(s);for(const r of t.json.meshes||[])bf(),t.addRequiredExtension(kt)},name:gf,preprocess:function(s,e,t){const r=new xe(s);for(const n of Ou(r))r.getObjectExtension(n,kt)}},Symbol.toStringTag,{value:"Module"}));globalThis.mathgl=globalThis.mathgl||{config:{EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1}};const He=globalThis.mathgl.config;function _f(s,{precision:e=He.precision}={}){return s=function(t){return Math.round(t/He.EPSILON)*He.EPSILON}(s),`${parseFloat(s.toPrecision(e))}`}function ws(s){return Array.isArray(s)||ArrayBuffer.isView(s)&&!(s instanceof DataView)}function Iu(s,e,t){const r=He.EPSILON;try{if(s===e)return!0;if(ws(s)&&ws(e)){if(s.length!==e.length)return!1;for(let n=0;n0?", ":"")+_f(this[r],e);return`${e.printTypes?this.constructor.name:""}[${t}]`}equals(e){if(!e||this.length!==e.length)return!1;for(let t=0;t=0&&e=0&&e0?this.copy([e,...t]):this.identity()}copy(e){return this[0]=e[0],this[1]=e[1],this[2]=e[2],this[3]=e[3],this[4]=e[4],this[5]=e[5],this[6]=e[6],this[7]=e[7],this[8]=e[8],this.check()}identity(){return this.copy(wf)}fromObject(e){return this.check()}fromQuaternion(e){return function(t,r){const n=r[0],i=r[1],o=r[2],u=r[3],l=n+n,m=i+i,b=o+o,d=n*l,x=i*l,g=i*m,_=o*l,w=o*m,f=o*b,p=u*l,a=u*m,c=u*b;t[0]=1-g-f,t[3]=x-c,t[6]=_+a,t[1]=x+c,t[4]=1-d-f,t[7]=w-p,t[2]=_-a,t[5]=w+p,t[8]=1-d-g}(this,e),this.check()}set(e,t,r,n,i,o,u,l,m){return this[0]=e,this[1]=t,this[2]=r,this[3]=n,this[4]=i,this[5]=o,this[6]=u,this[7]=l,this[8]=m,this.check()}setRowMajor(e,t,r,n,i,o,u,l,m){return this[0]=e,this[1]=n,this[2]=u,this[3]=t,this[4]=i,this[5]=l,this[6]=r,this[7]=o,this[8]=m,this.check()}determinant(){return function(e){const t=e[0],r=e[1],n=e[2],i=e[3],o=e[4],u=e[5],l=e[6],m=e[7],b=e[8];return t*(b*o-u*m)+r*(-b*i+u*l)+n*(m*i-o*l)}(this)}transpose(){return function(e,t){if(e===t){const r=t[1],n=t[2],i=t[5];e[1]=t[3],e[2]=t[6],e[3]=r,e[5]=t[7],e[6]=n,e[7]=i}else e[0]=t[0],e[1]=t[3],e[2]=t[6],e[3]=t[1],e[4]=t[4],e[5]=t[7],e[6]=t[2],e[7]=t[5],e[8]=t[8]}(this,this),this.check()}invert(){return function(e,t){const r=t[0],n=t[1],i=t[2],o=t[3],u=t[4],l=t[5],m=t[6],b=t[7],d=t[8],x=d*u-l*b,g=-d*o+l*m,_=b*o-u*m;let w=r*x+n*g+i*_;w&&(w=1/w,e[0]=x*w,e[1]=(-d*n+i*b)*w,e[2]=(l*n-i*u)*w,e[3]=g*w,e[4]=(d*r-i*m)*w,e[5]=(-l*r+i*o)*w,e[6]=_*w,e[7]=(-b*r+n*m)*w,e[8]=(u*r-n*o)*w)}(this,this),this.check()}multiplyLeft(e){return ku(this,e,this),this.check()}multiplyRight(e){return ku(this,this,e),this.check()}rotate(e){return function(t,r,n){const i=r[0],o=r[1],u=r[2],l=r[3],m=r[4],b=r[5],d=r[6],x=r[7],g=r[8],_=Math.sin(n),w=Math.cos(n);t[0]=w*i+_*l,t[1]=w*o+_*m,t[2]=w*u+_*b,t[3]=w*l-_*i,t[4]=w*m-_*o,t[5]=w*b-_*u,t[6]=d,t[7]=x,t[8]=g}(this,this,e),this.check()}scale(e){return Array.isArray(e)?Nu(this,this,e):Nu(this,this,[e,e]),this.check()}translate(e){return function(t,r,n){const i=r[0],o=r[1],u=r[2],l=r[3],m=r[4],b=r[5],d=r[6],x=r[7],g=r[8],_=n[0],w=n[1];t[0]=i,t[1]=o,t[2]=u,t[3]=l,t[4]=m,t[5]=b,t[6]=_*i+w*l+d,t[7]=_*o+w*m+x,t[8]=_*u+w*b+g}(this,this,e),this.check()}transform(e,t){let r;switch(e.length){case 2:r=function(n,i,o){const u=i[0],l=i[1];return n[0]=o[0]*u+o[3]*l+o[6],n[1]=o[1]*u+o[4]*l+o[7],n}(t||[-0,-0],e,this);break;case 3:r=Uu(t||[-0,-0,-0],e,this);break;case 4:r=function(n,i,o){const u=i[0],l=i[1],m=i[2];return n[0]=o[0]*u+o[3]*l+o[6]*m,n[1]=o[1]*u+o[4]*l+o[7]*m,n[2]=o[2]*u+o[5]*l+o[8]*m,n[3]=i[3],n}(t||[-0,-0,-0,-0],e,this);break;default:throw new Error("Illegal vector")}return Af(r,e.length),r}transformVector(e,t){return this.transform(e,t)}transformVector2(e,t){return this.transform(e,t)}transformVector3(e,t){return this.transform(e,t)}}let Ss,Es=null;const Ms="KHR_texture_transform",Cf=Ms,Ps=new wi,Tf=new hr,Sf=new hr;function Ef(s,e){var i,o,u,l;const t=(i=e.json.materials)==null?void 0:i[s],r=[(o=t==null?void 0:t.pbrMetallicRoughness)==null?void 0:o.baseColorTexture,t==null?void 0:t.emissiveTexture,t==null?void 0:t.normalTexture,t==null?void 0:t.occlusionTexture,(u=t==null?void 0:t.pbrMetallicRoughness)==null?void 0:u.metallicRoughnessTexture],n=[];for(const m of r)m&&((l=m==null?void 0:m.extensions)!=null&&l[Ms])&&Mf(e,s,m,n)}function Mf(s,e,t,r){const n=function(o,u){var x;const l=(x=o.extensions)==null?void 0:x[Ms],{texCoord:m=0}=o,{texCoord:b=m}=l;if(!(u.findIndex(([g,_])=>g===m&&_===b)!==-1)){const g=function(_){const{offset:w=[0,0],rotation:f=0,scale:p=[1,1]}=_,a=new hr().set(1,0,0,0,1,0,w[0],w[1],1),c=Tf.set(Math.cos(f),Math.sin(f),0,-Math.sin(f),Math.cos(f),0,0,0,1),h=Sf.set(p[0],0,0,0,p[1],0,0,0,1);return a.multiplyRight(c).multiplyRight(h)}(l);return m!==b&&(o.texCoord=b),u.push([m,b]),{originalTexCoord:m,texCoord:b,matrix:g}}return null}(t,r);if(!n)return;const i=s.json.meshes||[];for(const o of i)for(const u of o.primitives){const l=u.material;Number.isFinite(l)&&e===l&&Pf(s,u,n)}}function Pf(s,e,t){var u,l;const{originalTexCoord:r,texCoord:n,matrix:i}=t,o=e.attributes[`TEXCOORD_${r}`];if(Number.isFinite(o)){const m=(u=s.json.accessors)==null?void 0:u[o];if(m&&m.bufferView){const b=(l=s.json.bufferViews)==null?void 0:l[m.bufferView];if(b){const{arrayBuffer:d,byteOffset:x}=s.buffers[b.buffer],g=(x||0)+(m.byteOffset||0)+(b.byteOffset||0),{ArrayType:_,length:w}=li(m,b),f=cu[m.componentType],p=uu[m.type],a=b.byteStride||f*p,c=new Float32Array(w);for(let h=0;h{s.uniforms[r].value&&!(r in t)&&(t[r]=s.uniforms[r].value)}),Object.keys(t).forEach(r=>{typeof t[r]=="object"&&t[r].index!==void 0&&(t[r].texture=e.getTexture(t[r].index))}),t}const Vu=[Mh,bh,uf,cf,lf,xf,Gf,Lf,Object.freeze(Object.defineProperty({__proto__:null,decode:async function(s){const e=new xe(s),{json:t}=e,r=e.getExtension(Gr);if(r){const n=function(i,o){const{programs:u=[],shaders:l=[],techniques:m=[]}=i,b=new TextDecoder;return l.forEach(d=>{if(!Number.isFinite(d.bufferView))throw new Error("KHR_techniques_webgl: no shader code");d.code=b.decode(o.getTypedArrayForBufferView(d.bufferView))}),u.forEach(d=>{d.fragmentShader=l[d.fragmentShader],d.vertexShader=l[d.vertexShader]}),m.forEach(d=>{d.program=u[d.program]}),m}(r,e);for(const i of t.materials||[]){const o=e.getObjectExtension(i,Gr);o&&(i.technique=Object.assign({},o,n[o.technique]),i.technique.values=If(i.technique,e)),e.removeObjectExtension(i,Gr)}e.removeExtension(Gr)}},encode:async function(s,e){},name:Of},Symbol.toStringTag,{value:"Module"})),Rf,Uh];function Hu(s,e){var r;const t=((r=e==null?void 0:e.gltf)==null?void 0:r.excludeExtensions)||{};return!(s in t&&!t[s])}const Ti="KHR_binary_glTF",Ju={accessors:"accessor",animations:"animation",buffers:"buffer",bufferViews:"bufferView",images:"image",materials:"material",meshes:"mesh",nodes:"node",samplers:"sampler",scenes:"scene",skins:"skin",textures:"texture"},Ff={accessor:"accessors",animations:"animation",buffer:"buffers",bufferView:"bufferViews",image:"images",material:"materials",mesh:"meshes",node:"nodes",sampler:"samplers",scene:"scenes",skin:"skins",texture:"textures"};class Df{constructor(){ee(this,"idToIndexMap",{animations:{},accessors:{},buffers:{},bufferViews:{},images:{},materials:{},meshes:{},nodes:{},samplers:{},scenes:{},skins:{},textures:{}});ee(this,"json")}normalize(e,t){this.json=e.json;const r=e.json;switch(r.asset&&r.asset.version){case"2.0":return;case void 0:case"1.0":break;default:return void console.warn(`glTF: Unknown version ${r.asset.version}`)}if(!t.normalize)throw new Error("glTF v1 is not supported.");console.warn("Converting glTF v1 to glTF v2 format. This is experimental and may fail."),this._addAsset(r),this._convertTopLevelObjectsToArrays(r),function(n){const i=new xe(n),{json:o}=i;for(const u of o.images||[]){const l=i.getObjectExtension(u,Ti);l&&Object.assign(u,l),i.removeObjectExtension(u,Ti)}o.buffers&&o.buffers[0]&&delete o.buffers[0].uri,i.removeExtension(Ti)}(e),this._convertObjectIdsToArrayIndices(r),this._updateObjects(r),this._updateMaterial(r)}_addAsset(e){e.asset=e.asset||{},e.asset.version="2.0",e.asset.generator=e.asset.generator||"Normalized to glTF 2.0 by loaders.gl"}_convertTopLevelObjectsToArrays(e){for(const t in Ju)this._convertTopLevelObjectToArray(e,t)}_convertTopLevelObjectToArray(e,t){const r=e[t];if(r&&!Array.isArray(r)){e[t]=[];for(const n in r){const i=r[n];i.id=i.id||n;const o=e[t].length;e[t].push(i),this.idToIndexMap[t][n]=o}}}_convertObjectIdsToArrayIndices(e){for(const t in Ju)this._convertIdsToIndices(e,t);"scene"in e&&(e.scene=this._convertIdToIndex(e.scene,"scene"));for(const t of e.textures)this._convertTextureIds(t);for(const t of e.meshes)this._convertMeshIds(t);for(const t of e.nodes)this._convertNodeIds(t);for(const t of e.scenes)this._convertSceneIds(t)}_convertTextureIds(e){e.source&&(e.source=this._convertIdToIndex(e.source,"image"))}_convertMeshIds(e){for(const t of e.primitives){const{attributes:r,indices:n,material:i}=t;for(const o in r)r[o]=this._convertIdToIndex(r[o],"accessor");n&&(t.indices=this._convertIdToIndex(n,"accessor")),i&&(t.material=this._convertIdToIndex(i,"material"))}}_convertNodeIds(e){e.children&&(e.children=e.children.map(t=>this._convertIdToIndex(t,"node"))),e.meshes&&(e.meshes=e.meshes.map(t=>this._convertIdToIndex(t,"mesh")))}_convertSceneIds(e){e.nodes&&(e.nodes=e.nodes.map(t=>this._convertIdToIndex(t,"node")))}_convertIdsToIndices(e,t){e[t]||(console.warn(`gltf v1: json doesn't contain attribute ${t}`),e[t]=[]);for(const r of e[t])for(const n in r){const i=r[n],o=this._convertIdToIndex(i,n);r[n]=o}}_convertIdToIndex(e,t){const r=Ff[t];if(r in this.idToIndexMap){const n=this.idToIndexMap[r][e];if(!Number.isFinite(n))throw new Error(`gltf v1: failed to resolve ${t} with id ${e}`);return n}return e}_updateObjects(e){for(const t of this.json.buffers)delete t.type}_updateMaterial(e){var t,r,n;for(const i of e.materials){i.pbrMetallicRoughness={baseColorFactor:[1,1,1,1],metallicFactor:1,roughnessFactor:1};const o=((t=i.values)==null?void 0:t.tex)||((r=i.values)==null?void 0:r.texture2d_0)||((n=i.values)==null?void 0:n.diffuseTex),u=e.textures.findIndex(l=>l.id===o);u!==-1&&(i.pbrMetallicRoughness.baseColorTexture={index:u})}}}async function Uf(s,e,t=0,r,n){var i,o,u;return function(l,m,b,d){if(d.uri&&(l.baseUri=d.uri),m instanceof ArrayBuffer&&!function(_,w=0,f={}){const p=new DataView(_),{magic:a=Su}=f,c=p.getUint32(w,!1);return c===a||c===Su}(m,b,d)&&(m=new TextDecoder().decode(m)),typeof m=="string")l.json=Ld(m);else if(m instanceof ArrayBuffer){const _={};b=qh(_,m,b,d.glb),Ee(_.type==="glTF",`Invalid GLB magic string ${_.type}`),l._glb=_,l.json=_.json}else Ee(!1,"GLTF: must be ArrayBuffer or string");const x=l.json.buffers||[];if(l.buffers=new Array(x.length).fill(null),l._glb&&l._glb.header.hasBinChunk){const{binChunks:_}=l._glb;l.buffers[0]={arrayBuffer:_[0].arrayBuffer,byteOffset:_[0].byteOffset,byteLength:_[0].byteLength}}const g=l.json.images||[];l.images=new Array(g.length).fill({})}(s,e,t,r),function(l,m={}){new Df().normalize(l,m)}(s,{normalize:(i=r==null?void 0:r.gltf)==null?void 0:i.normalize}),function(l,m={},b){var x;const d=Vu.filter(g=>Hu(g.name,m));for(const g of d)(x=g.preprocess)==null||x.call(g,l,m,b)}(s,r,n),(o=r==null?void 0:r.gltf)!=null&&o.loadBuffers&&s.json.buffers&&await async function(l,m,b){var x,g;const d=l.json.buffers||[];for(let _=0;_Hu(g.name,m));for(const g of d)await((x=g.decode)==null?void 0:x.call(g,l,m,b))}(s,r,n),s}async function kf(s,e,t,r,n){let i;if(e.uri&&!e.hasOwnProperty("bufferView")){const u=Eu(e.uri,r),{fetch:l}=n;i=await(await l(u)).arrayBuffer(),e.bufferView={data:i}}if(Number.isFinite(e.bufferView)){const u=function(l,m,b){const d=l.bufferViews[b];Ee(d);const x=m[d.buffer];Ee(x);const g=(d.byteOffset||0)+x.byteOffset;return new Uint8Array(x.arrayBuffer,g,d.byteLength)}(s.json,s.buffers,e.bufferView);i=Ga(u.buffer,u.byteOffset,u.byteLength)}Ee(i,"glTF image has no data");let o=await ba(i,[oh,Yh],{...r,mimeType:e.mimeType,basis:r.basis||{format:Tu()}},n);o&&o[0]&&(o={compressed:!0,mipmaps:!1,width:o[0].width,height:o[0].height,data:o[0]}),s.images=s.images||[],s.images[t]=o}const Si={dataType:null,batchType:null,name:"glTF",id:"gltf",module:"gltf",version:"4.3.2",extensions:["gltf","glb"],mimeTypes:["model/gltf+json","model/gltf-binary"],text:!0,binary:!0,tests:["glTF"],parse:async function(s,e={},t){(e={...Si.options,...e}).gltf={...Si.options.gltf,...e.gltf};const{byteOffset:r=0}=e;return await Uf({},s,r,e,t)},options:{gltf:{normalize:!0,loadBuffers:!0,loadImages:!0,decompressMeshes:!0},log:console}},Nf={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},Vf={5120:1,5121:1,5122:2,5123:2,5125:4,5126:4},zu=10240,ju=10241,Ku=10242,Xu=10243,Yu=10497,Hf=9729,Jf=9986,zf={magFilter:zu,minFilter:ju,wrapS:Ku,wrapT:Xu},jf={[zu]:Hf,[ju]:Jf,[Ku]:Yu,[Xu]:Yu};class Kf{constructor(){ee(this,"baseUri","");ee(this,"jsonUnprocessed");ee(this,"json");ee(this,"buffers",[]);ee(this,"images",[])}postProcess(e,t={}){const{json:r,buffers:n=[],images:i=[]}=e,{baseUri:o=""}=e;return Ee(r),this.baseUri=o,this.buffers=n,this.images=i,this.jsonUnprocessed=r,this.json=this._resolveTree(e.json,t),this.json}_resolveTree(e,t={}){const r={...e};return this.json=r,e.bufferViews&&(r.bufferViews=e.bufferViews.map((n,i)=>this._resolveBufferView(n,i))),e.images&&(r.images=e.images.map((n,i)=>this._resolveImage(n,i))),e.samplers&&(r.samplers=e.samplers.map((n,i)=>this._resolveSampler(n,i))),e.textures&&(r.textures=e.textures.map((n,i)=>this._resolveTexture(n,i))),e.accessors&&(r.accessors=e.accessors.map((n,i)=>this._resolveAccessor(n,i))),e.materials&&(r.materials=e.materials.map((n,i)=>this._resolveMaterial(n,i))),e.meshes&&(r.meshes=e.meshes.map((n,i)=>this._resolveMesh(n,i))),e.nodes&&(r.nodes=e.nodes.map((n,i)=>this._resolveNode(n,i)),r.nodes=r.nodes.map((n,i)=>this._resolveNodeChildren(n))),e.skins&&(r.skins=e.skins.map((n,i)=>this._resolveSkin(n,i))),e.scenes&&(r.scenes=e.scenes.map((n,i)=>this._resolveScene(n,i))),typeof this.json.scene=="number"&&r.scenes&&(r.scene=r.scenes[this.json.scene]),r}getScene(e){return this._get(this.json.scenes,e)}getNode(e){return this._get(this.json.nodes,e)}getSkin(e){return this._get(this.json.skins,e)}getMesh(e){return this._get(this.json.meshes,e)}getMaterial(e){return this._get(this.json.materials,e)}getAccessor(e){return this._get(this.json.accessors,e)}getCamera(e){return this._get(this.json.cameras,e)}getTexture(e){return this._get(this.json.textures,e)}getSampler(e){return this._get(this.json.samplers,e)}getImage(e){return this._get(this.json.images,e)}getBufferView(e){return this._get(this.json.bufferViews,e)}getBuffer(e){return this._get(this.json.buffers,e)}_get(e,t){if(typeof t=="object")return t;const r=e&&e[t];return r||console.warn(`glTF file error: Could not find ${e}[${t}]`),r}_resolveScene(e,t){return{...e,id:e.id||`scene-${t}`,nodes:(e.nodes||[]).map(r=>this.getNode(r))}}_resolveNode(e,t){const r={...e,id:(e==null?void 0:e.id)||`node-${t}`};return e.mesh!==void 0&&(r.mesh=this.getMesh(e.mesh)),e.camera!==void 0&&(r.camera=this.getCamera(e.camera)),e.skin!==void 0&&(r.skin=this.getSkin(e.skin)),e.meshes!==void 0&&e.meshes.length&&(r.mesh=e.meshes.reduce((n,i)=>{const o=this.getMesh(i);return n.id=o.id,n.primitives=n.primitives.concat(o.primitives),n},{primitives:[]})),r}_resolveNodeChildren(e){return e.children&&(e.children=e.children.map(t=>this.getNode(t))),e}_resolveSkin(e,t){const r=typeof e.inverseBindMatrices=="number"?this.getAccessor(e.inverseBindMatrices):void 0;return{...e,id:e.id||`skin-${t}`,inverseBindMatrices:r}}_resolveMesh(e,t){const r={...e,id:e.id||`mesh-${t}`,primitives:[]};return e.primitives&&(r.primitives=e.primitives.map(n=>{const i={...n,attributes:{},indices:void 0,material:void 0},o=n.attributes;for(const u in o)i.attributes[u]=this.getAccessor(o[u]);return n.indices!==void 0&&(i.indices=this.getAccessor(n.indices)),n.material!==void 0&&(i.material=this.getMaterial(n.material)),i})),r}_resolveMaterial(e,t){const r={...e,id:e.id||`material-${t}`};if(r.normalTexture&&(r.normalTexture={...r.normalTexture},r.normalTexture.texture=this.getTexture(r.normalTexture.index)),r.occlusionTexture&&(r.occlusionTexture={...r.occlusionTexture},r.occlusionTexture.texture=this.getTexture(r.occlusionTexture.index)),r.emissiveTexture&&(r.emissiveTexture={...r.emissiveTexture},r.emissiveTexture.texture=this.getTexture(r.emissiveTexture.index)),r.emissiveFactor||(r.emissiveFactor=r.emissiveTexture?[1,1,1]:[0,0,0]),r.pbrMetallicRoughness){r.pbrMetallicRoughness={...r.pbrMetallicRoughness};const n=r.pbrMetallicRoughness;n.baseColorTexture&&(n.baseColorTexture={...n.baseColorTexture},n.baseColorTexture.texture=this.getTexture(n.baseColorTexture.index)),n.metallicRoughnessTexture&&(n.metallicRoughnessTexture={...n.metallicRoughnessTexture},n.metallicRoughnessTexture.texture=this.getTexture(n.metallicRoughnessTexture.index))}return r}_resolveAccessor(e,t){const r=(n=e.componentType,Vf[n]);var n;const i=(o=e.type,Nf[o]);var o;const u=r*i,l={...e,id:e.id||`accessor-${t}`,bytesPerComponent:r,components:i,bytesPerElement:u,value:void 0,bufferView:void 0,sparse:void 0};if(e.bufferView!==void 0&&(l.bufferView=this.getBufferView(e.bufferView)),l.bufferView){const m=l.bufferView.buffer,{ArrayType:b,byteLength:d}=li(l,l.bufferView),x=(l.bufferView.byteOffset||0)+(l.byteOffset||0)+m.byteOffset;let g=m.arrayBuffer.slice(x,x+d);l.bufferView.byteStride&&(g=this._getValueFromInterleavedBuffer(m,x,l.bufferView.byteStride,l.bytesPerElement,l.count)),l.value=new b(g)}return l}_getValueFromInterleavedBuffer(e,t,r,n,i){const o=new Uint8Array(i*n);for(let u=0;uD.create()),b=new Array(t.length).fill(null).map(h=>D.create());for(const h of this.faces)a(h);let d=Number.POSITIVE_INFINITY,x=Number.POSITIVE_INFINITY,g=Number.POSITIVE_INFINITY,_=Number.NEGATIVE_INFINITY,w=Number.NEGATIVE_INFINITY,f=Number.NEGATIVE_INFINITY;for(let h=0;h{if(!m){const x=B.device.createBuffer({label:"Vertex Buffer Placeholder",size:1,usage:GPUBufferUsage.VERTEX});return this.vertexBufferOffsets.set(x,[0,1]),Y.addBufferBytes(x),void this.vertexBuffers.push(x)}const b=m.bufferView,d=this.gpuBuffers.get(b.id);this.vertexBuffers.push(d),this.vertexBufferOffsets.set(d,[0,0])});const u=e.indices.bufferView,l=this.gpuBuffers.get(u.id);this.indexBufferOffsets[0]=e.indices.byteOffset,this.indexBufferOffsets[1]=e.indices.count*e.indices.bytesPerElement,this.indexCount=e.indices.count,this.indexBuffer=l}}const $u=new Map,Vt=WebGLRenderingContext;class Je extends Ze{static get defaultNearestSampler(){return Ei||(Ei=this.createSampler({minFilter:"nearest",magFilter:"nearest"}),Ei)}static get defaultSampler(){return Mi||(Mi=this.createSampler({minFilter:"linear",magFilter:"linear",mipmapFilter:"linear",maxAnisotropy:4}),Mi)}static createSampler(e){const t=structuredClone(e);t.label&&delete t.label;const r=JSON.stringify(t);let n;return(n=$u.get(r))||(n=B.device.createSampler(e),$u.set(r,n)),n}static getSamplerFromGltfSamplerDef(e){function t(n){switch(n){case Vt.CLAMP_TO_EDGE:return"clamp-to-edge";case Vt.MIRRORED_REPEAT:return"mirror-repeat";default:return"repeat"}}const r={addressModeU:t(e.wrapS),addressModeV:t(e.wrapT)};switch(e.magFilter&&e.magFilter!=Vt.LINEAR||(r.magFilter="linear"),e.minFilter){case Vt.LINEAR:case Vt.LINEAR_MIPMAP_NEAREST:r.minFilter="linear";break;case Vt.NEAREST_MIPMAP_LINEAR:r.mipmapFilter="linear";break;case Vt.LINEAR_MIPMAP_LINEAR:default:r.minFilter="linear",r.mipmapFilter="linear"}return r.maxAnisotropy=16,this.createSampler(r)}}function Pi(s,e){if(s[3]!==0){var t=(r=1,n=s[3]-136,r*Math.pow(2,n));e[0]=s[0]*t,e[1]=s[1]*t,e[2]=s[2]*t}else e[0]=e[1]=e[2]=0;var r,n}function Ri(s,e){var t=s[0],r=s[1],n=s[2],i=Math.max(t,Math.max(r,n));if(i<9999999999999999e-48)e[0]=e[1]=e[2]=e[3]=0;else{var o=function(b){var d={f:b=Number(b),e:0};if(b!==0&&Number.isFinite(b)){for(var x=Math.abs(b),g=Math.log2||function(f){return Math.log(f)*Math.LOG2E},_=Math.max(-1023,Math.floor(g(x))+1),w=x*Math.pow(2,-_);w>=1;)w*=.5,_++;for(;w<.5;)w*=2,_--;b<0&&(w=-w),d.f=w,d.e=_}return d}(i),u=o.f,l=o.e,m=u/i*256;e[0]=t*m,e[1]=r*m,e[2]=n*m,e[3]=l+128}}function qu(s,e,t){var r=[];return function(n,i,o,u,l){if(!(o<=0||i<=0||!l)){var m=`#?RADIANCE -# Written by hdr.js -FORMAT=32-bit_rle_rgbe -EXPOSURE=1.0 - --Y `+o+" +X "+i+` -`;m.split("").forEach(function(x){var g=x.charCodeAt(0);n.push(g)});for(var b=new Uint8Array(4*i),d=0;d>8,o[3]=255&e,e<8||e>=32768)for(i=0;i=e&&(b=e);i128&&(x=128),Wf(s,x,d.subarray(i)),i+=x;if(b+2127&&(x=127),$f(s,x,d[i]),i+=x}}}}}}function Wf(s,e,t){var r=255&e;if(!(e<=128))throw new Error("length is greater than 128");s.push(r);for(var n=0;nZu||l>Zu)return"Very large image (corrupt?)";var m=s[t],b=s[t+1],d=s[t+2],x=m!==2||b!==2||!!(128&d),g=new Float32Array(u*l*3);if(u<8||u>=32768||x)for(o=0;o0;)if((y=s[t++])>128){if(A=s[t++],(y-=128)>R)return"bad RLE data in HDR";for(var U=0;UR)return"bad RLE data in HDR";for(U=0;U"u"&&t("XMLHttpRequest is undefined, use HDRjs.read instead.");var r=new XMLHttpRequest;r.responseType="arraybuffer",r.onload=function(){if(r.status>=400)return t("Load successfully, but HTTP status code >= 400, status: "+r.status);var n=ec(new Uint8Array(r.response));typeof n=="string"?t(n):e(n)},r.onerror=function(n){t("Failed to load: "+s)},r.open("GET",s,!0),r.send()})},save:function(s,e,t,r){if(!(document!=null&&document.createElement)||!(URL!=null&&URL.createObjectURL))return console.warn("NO document.createElement or URL.createObjectURL"),!1;var n=qu(e,t,s),i=URL.createObjectURL(new Blob([n])),o=document.createElement("a");return o.href=i,o.download=r+".hdr",o.rel="noopener",setTimeout(function(){URL.revokeObjectURL(o.href)},4e4),setTimeout(function(){(function(u){try{u.dispatchEvent(new MouseEvent("click"))}catch{var l=document.createEvent("MouseEvents");l.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),u.dispatchEvent(l)}})(o)},0),!0},read:ec,write:qu,float2rgbe:Ri,rgbe2float:Pi});const tc="vertexMain",rc="fragmentMain",sc=` - ${W.VertexInput} - ${W.VertexOutput} - - @group(0) @binding(0) var projViewMatrix: mat4x4f; - @group(0) @binding(1) var inTexture: texture_2d; - @group(0) @binding(2) var inSampler: sampler; - - const invAtan = vec2(0.1591, 0.3183); - fn SampleSphericalMap(v: vec3f) -> vec2f { - var uv = vec2f(atan(v.z / v.x), asin(v.y)); - uv *= invAtan; - uv += 0.5; - return uv; - } - - - @vertex - fn ${tc}(in: VertexInput) -> VertexOutput { - var out: VertexOutput; - out.position = projViewMatrix * in.position; - // hijack - out.viewNormal = in.position.xyz; - return out; - } - - @fragment - fn ${rc}(in: VertexOutput) -> @location(0) vec4f { - let uv = SampleSphericalMap(normalize(in.normal.rgb)); // make sure to normalize localPos - let color = textureSample(inTexture, inSampler, uv).rgb; - return vec4f(color, 1); - } -`;let Os,Is,Fs,Ds,Us;const Gi=new Map([]),J={get defaultCameraPlusLightsBindGroupLayout(){if(Is)return Is;const s=[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{}},{binding:1,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}];return Is=B.device.createBindGroupLayout({label:"Camera + Lights GPUBindGroupLayout",entries:s}),Is},get defaultCameraBindGroupLayout(){if(Os)return Os;const s=[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{}}];return Os=B.device.createBindGroupLayout({label:"Camera GPUBindGroupLayout",entries:s}),Os},get defaultModelBindGroupLayout(){if(Fs)return Fs;const s=[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{}}];return Fs=B.device.createBindGroupLayout({label:"Model GPUBindGroupLayout",entries:s}),Fs},get defaultModelMaterialBindGroupLayout(){if(Ds)return Ds;const s=[{binding:as.Default,visibility:GPUShaderStage.FRAGMENT,sampler:{}},{binding:me.Albedo,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}},{binding:me.Normal,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}},{binding:me.MetallicRoughness,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"float"}}];return Ds=B.device.createBindGroupLayout({label:"Model Textures GPUBindGroupLayout",entries:s}),Ds},get instancesBindGroupLayout(){if(Us)return Us;const s=[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}];return Us=B.device.createBindGroupLayout({label:"Instance Models GPUBindGroupLayout",entries:s}),Us},createShaderModule:(s,e=`Shader Module #${Gi.size}`)=>{let t;return(t=Gi.get(s))||(t=B.device.createShaderModule({label:e,code:s}),Gi.set(s,t)),t},createRenderPipeline:s=>B.device.createRenderPipeline(s),createComputePipeline:s=>B.device.createComputePipeline(s)};class fr{constructor(e,t,r,n,i,o,u,l,m,b,d,x){this.indexV0=e,this.indexV1=t,this.indexV2=r,this.p0=n,this.p1=i,this.p2=o,this.n0=u,this.n1=l,this.v2=m,this.texCoord0=b,this.texCoord1=d,this.texCoord2=x,this.centroid=D.create(),this.computeCetroid()}computeCetroid(){this.centroid[0]=(this.p0[0]+this.p1[0]+this.p2[0])/3,this.centroid[1]=(this.p0[1]+this.p1[1]+this.p2[1])/3,this.centroid[2]=(this.p0[2]+this.p1[2]+this.p2[2])/3}getArea(){const e=D.sub(this.p2,this.p1),t=D.sub(this.p0,this.p1);return .5*D.len(D.cross(e,t))}}class nc extends Ls{constructor(e=1,t=1,r=1,n=1,i=1,o=1){super(),this.width=e,this.height=t,this.depth=r,this.widthSegments=n,this.heightSegments=i,this.depthSegments=o,n=Math.floor(n),i=Math.floor(i),o=Math.floor(o);const u=[],l=[],m=[],b=[];let d=0;function x(g,_,w,f,p,a,c,h,y,A){const C=a/y,R=c/A,U=a/2,k=c/2,T=h/2,S=y+1,P=A+1;let L=0;const F=D.create();for(let O=0;O0?1:-1,m.push(D.clone(F)),b.push(Se.create(K/y,1-O/A)),L+=1}}for(let O=0;O; - @group(0) @binding(1) var outTexture: texture_storage_2d; - @group(0) @binding(2) var inOutTextureScaleFactor: u32; - - @compute @workgroup_size(8, 8) - fn ${ic}(@builtin(global_invocation_id) id: vec3u) { - let texSize = textureDimensions(inTexture, 0).xy; - if (any(id.xy > texSize.xy)) { - return; - } - - let inColor = textureLoad(inTexture, id.xy * inOutTextureScaleFactor, 0); - textureStore(outTexture, id.xy, inColor); - } -`,Li="computeMipMap",oc=(s="rgba8unorm")=>` - @group(0) @binding(0) var prevMipLevel: texture_2d; - @group(0) @binding(1) var nextMipLevel: texture_storage_2d<${s}, write>; - - @compute @workgroup_size(8, 8) - fn ${Li}(@builtin(global_invocation_id) id: vec3u) { - let offset = vec2(0, 1); - let color = ( - textureLoad(prevMipLevel, 2 * id.xy + offset.xx, 0) + - textureLoad(prevMipLevel, 2 * id.xy + offset.xy, 0) + - textureLoad(prevMipLevel, 2 * id.xy + offset.yx, 0) + - textureLoad(prevMipLevel, 2 * id.xy + offset.yy, 0) - ) * 0.25; - textureStore(nextMipLevel, id.xy, color); - } -`;function ac(s,e,t){const r=[{binding:0,resource:e[s-1]},{binding:1,resource:e[s]}];return B.device.createBindGroup({label:"Mip Generator Input Bind Group",layout:t,entries:r})}const yr=class yr extends Ze{static copyTextureView(e,t,r,n,i,o,u={viewDimension:"2d",sampleType:"unfilterable-float"},l={access:"write-only",format:"rgba16float",viewDimension:"2d"}){const m=B.device.createBuffer({label:"Copy Texture View Compute Tex Scale Factor Buffer",size:Uint32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM,mappedAtCreation:!0});Y.addBufferBytes(m);const b=n/i;new Uint32Array(m.getMappedRange()).set(new Uint32Array([b])),m.unmap();const d=[{binding:0,visibility:GPUShaderStage.COMPUTE,texture:u},{binding:1,visibility:GPUShaderStage.COMPUTE,storageTexture:l},{binding:2,visibility:GPUShaderStage.COMPUTE,buffer:{}}],x=B.device.createBindGroupLayout({label:"Copy Texture View Compute Bind Group Layout",entries:d}),g=[{binding:0,resource:t},{binding:1,resource:r},{binding:2,resource:{buffer:m}}],_=B.device.createBindGroup({layout:x,entries:g}),w=B.device.createPipelineLayout({label:"Copy Texture View Compute PSO Layout",bindGroupLayouts:[x]}),f=J.createComputePipeline({label:"Copy Texture View Compute PSO",layout:w,compute:{module:J.createShaderModule(ep),entryPoint:ic}});e.setPipeline(f),e.setBindGroup(0,_),e.dispatchWorkgroups(Math.ceil(i/8),Math.ceil(o/8),1)}};yr.generateMipsForCubeTexture=e=>{if(e.depthOrArrayLayers!=6)return void console.error("Need a cube texture");const t=Pt(e.width,e.height),r={baseMipLevel:0,mipLevelCount:1,baseArrayLayer:0,arrayLayerCount:1,dimension:"2d",format:e.format},n=[],i=[];for(let d=0;d<6;d++){const x=[],g=[Se.create(e.width,e.height)];for(let _=0;_0){const f=g[_-1],p=Se.divScalar(f,2);g.push(p)}}n.push(x),i.push(g)}const o=[{binding:0,visibility:GPUShaderStage.COMPUTE,texture:{viewDimension:"2d"}},{binding:1,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:e.format,viewDimension:"2d"}}],u=B.device.createBindGroupLayout({label:"Mip Generator CubeTexture Input Bind Group Layout",entries:o}),l=J.createComputePipeline({label:"Compute Mip ComputePSO",layout:B.device.createPipelineLayout({label:"Compute Mip ComputePSO CubeTexture Layout",bindGroupLayouts:[u]}),compute:{entryPoint:Li,module:J.createShaderModule(oc(e.format))}}),m=B.device.createCommandEncoder({label:"Mip Generate Command Encoder}"}),b=m.beginComputePass();b.setPipeline(l);for(let d=0;d<6;d++){const x=i[d],g=n[d];for(let _=1;_{},yr.generateMipsFor2DTextureWithComputePSO=(e,t="Mipmapped 2D Texture")=>{const r=Pt(e.width,e.height),n={aspect:"all",baseMipLevel:0,mipLevelCount:1,baseArrayLayer:0,arrayLayerCount:1,dimension:"2d",format:e.format},i=[{binding:0,visibility:GPUShaderStage.COMPUTE,texture:{viewDimension:"2d"}},{binding:1,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:e.format,viewDimension:"2d"}}],o=B.device.createBindGroupLayout({label:"Mip Generator Input Bind Group Layout",entries:i}),u=J.createComputePipeline({label:"Compute Mip ComputePSO",layout:B.device.createPipelineLayout({label:"Compute Mip ComputePSO Layout",bindGroupLayouts:[o]}),compute:{entryPoint:Li,module:J.createShaderModule(oc())}}),l=[],m=[Se.create(e.width,e.height)];for(let x=0;x0){const _=m[x-1],w=Se.divScalar(_,2);m.push(w)}}const b=B.device.createCommandEncoder({label:`Mip Generate Command Encoder for ${t}`}),d=b.beginComputePass();d.setPipeline(u);for(let x=1;x{const n=B.device.createTexture({label:r,format:"rgba16float",size:{width:e.width,height:e.height,depthOrArrayLayers:1},usage:t});return B.device.queue.writeTexture({texture:n,mipLevel:0},e.rgbaHalfFloat,{offset:0,bytesPerRow:e.width*Uint16Array.BYTES_PER_ELEMENT*4},{width:e.width,height:e.height,depthOrArrayLayers:1}),n};let Ht=yr,tp=0;const Jr=class Jr extends Ze{static createEmptyCubeTexture(e,t="Cube Texture "+tp++,r=!1,n="rgba16float",i=GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.COPY_DST){const o={label:t,dimension:"2d",size:{width:e,height:e,depthOrArrayLayers:6},usage:i,format:n};return r&&(o.mipLevelCount=Pt(e,e)),B.device.createTexture(o)}};Jr.cubeTextureFromIndividualHDRTextures=(e,t="Environment Cube Texture From Individual HDR Textures",r=512,n=!1)=>{const i=Jr.createEmptyCubeTexture(r,t,n),o=B.device.createCommandEncoder();B.ENABLE_DEBUG_GROUPS&&o.pushDebugGroup("Texture View Copy");const u=o.beginComputePass(),l=r;for(let m=0;m<6;m++)Ht.copyTextureView(u,e[m].createView({}),i.createView({baseArrayLayer:m,arrayLayerCount:1,baseMipLevel:0,mipLevelCount:1,dimension:"2d"}),r,l,l);return u.end(),B.ENABLE_DEBUG_GROUPS&&o.popDebugGroup(),B.device.queue.submit([o.finish()]),n&&Ht.generateMipsForCubeTexture(i),i},Jr.cubeTextureFromHDR=(e,t=512)=>{const r=B.device.createTexture({label:"Environment Cube Texture",dimension:"2d",size:{width:t,height:t,depthOrArrayLayers:6},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING,format:"rgba8unorm"}),n=new Nn(.5*Math.PI,1,.1,10);n.updateProjectionMatrix();const i=B.device.createBuffer({label:"HDR -> CubeMap Camera ProjView Matrix Buffer",size:16*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.UNIFORM});Y.addBufferBytes(i);const o=[{binding:0,buffer:{type:"uniform"},visibility:GPUShaderStage.VERTEX},{binding:1,texture:{sampleType:"unfilterable-float"},visibility:GPUShaderStage.FRAGMENT},{binding:2,sampler:{type:"non-filtering"},visibility:GPUShaderStage.FRAGMENT}],u=B.device.createBindGroupLayout({label:"Environment Probe Camera Bind Group Layout",entries:o}),l=[{binding:0,resource:{buffer:i}},{binding:1,resource:e.createView()},{binding:2,resource:Je.createSampler({})}],m=B.device.createBindGroup({label:"Environment Probe Camera Bind Group",layout:u,entries:l}),b=B.device.createCommandEncoder({label:"HDR Environment to Cube Map Command Encoder"}),d=[{loadOp:"load",storeOp:"store",view:null}],x=J.createRenderPipeline({label:"HDR To CubeMap Render PSO",layout:B.device.createPipelineLayout({bindGroupLayouts:[u]}),vertex:{module:J.createShaderModule(sc),entryPoint:tc,buffers:_e.defaultLayout},fragment:{module:J.createShaderModule(sc),entryPoint:rc,targets:[{format:"rgba8unorm"}]},primitive:{cullMode:"none"}}),g=new nc;for(let _=0;_<6;_++){d[0].view=r.createView({dimension:"2d",baseArrayLayer:_,arrayLayerCount:1});const w=D.add(n.position,Bl[_]),f=Q.lookAt(n.position,w,vl[_]),p=Q.mul(n.projectionMatrix,f);B.device.queue.writeBuffer(i,0,p);const a={label:`Draw Face ${_} Render Pass`,colorAttachments:d},c=b.beginRenderPass(a);c.setPipeline(x),c.setBindGroup(0,m),c.setIndexBuffer(g.indexBuffer,Ae.INDEX_FORMAT),c.setVertexBuffer(0,g.vertexBuffer),c.drawIndexed(g.indexCount),c.end()}return B.device.queue.submit([b.finish()]),r};let Lr=Jr;const rp=new Uint8Array([0,32,8,40,2,34,10,42,48,16,56,24,50,18,58,26,12,44,4,36,14,46,6,38,60,28,52,20,62,30,54,22,3,35,11,43,1,33,9,41,51,19,59,27,49,17,57,25,15,47,7,39,13,45,5,37,63,31,55,23,61,29,53,21]),uc=new Uint8Array([255,204,255,204,255,204,255,204,204,255,204,255,204,255,204,255,255,204,255,204,255,204,255,204,204,255,204,255,204,255,204,255,255,204,255,204,255,204,255,204,204,255,204,255,204,255,204,255,255,204,255,204,255,204,255,204,204,255,204,255,204,255,204,255]);let ks,Or,Ns;const Ct=class Ct extends Ze{static get dummyTexture(){return ks||(ks=B.device.createTexture({label:"Default Dummy 8x8 Texture",dimension:"2d",size:{width:8,height:8,depthOrArrayLayers:1},format:"r8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST}),B.device.queue.writeTexture({texture:ks,mipLevel:0},uc,{offset:0,bytesPerRow:8},{width:8,height:8,depthOrArrayLayers:1}),ks)}static get dummyCubeTexture(){if(Or)return Or;Or=B.device.createTexture({label:"Default Dummy 8x8 Cube Texture",dimension:"2d",size:{width:8,height:8,depthOrArrayLayers:6},format:"r8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST});for(let e=0;e<6;e++)B.device.queue.writeTexture({texture:Or,mipLevel:0,origin:{x:0,y:0,z:e}},uc,{offset:0,bytesPerRow:8},{width:8,height:8,depthOrArrayLayers:0});return Or}static get bayerDitherPatternTexture(){return Ns||(Ns=B.device.createTexture({label:"Bayer ordered dithered GPUTexture",dimension:"2d",size:{width:8,height:8,depthOrArrayLayers:1},format:"r8unorm",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST}),B.device.queue.writeTexture({texture:Ns,mipLevel:0},rp,{offset:0,bytesPerRow:8},{width:8,height:8,depthOrArrayLayers:1}),Ns)}};Ct.loadHDRImage=async e=>{const t=await Qf.load(e),r=t.width*t.height,n={width:t.width,height:t.height,rgbaHalfFloat:new Uint16Array(t.width*t.height*4)};for(let i=0;i{const n=await Ct.loadHDRImage(e),i=await Ht.createHDRTexture(n,t,r);return Y.addTextureBytes(i),i},Ct.load6SeparateHDRFacesAsCubeMapTexture=async(e,t,r,n=null)=>{if(e.length!==6)return void console.error("Need 6 separate urls for 6 separate environment textures");const i=await Promise.all(e.map(u=>Ct.loadHDRTexture(u))),o=Lr.cubeTextureFromIndividualHDRTextures(i,n,t,r);return Y.addTextureBytes(o),o},Ct.loadTextureFromData=async(e,t="rgba8unorm",r=!0,n=!1,i=!1,o="Bitmap Texture")=>{const u=new Blob([e],{type:"image/png"}),l=await createImageBitmap(u,{colorSpaceConversion:"none"});let m=GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT;r&&(m|=GPUTextureUsage.STORAGE_BINDING);const b={label:o,dimension:"2d",size:{width:l.width,height:l.height,depthOrArrayLayers:1},format:t,usage:m};r&&(b.mipLevelCount=Pt(l.width,l.height));const d=B.device.createTexture(b);if(B.device.queue.copyExternalImageToTexture({source:l,flipY:n},{texture:d},{width:l.width,height:l.height}),!r)return Y.addTextureBytes(d),d;Ht.generateMipsFor2DTextureWithComputePSO(d),Y.addTextureBytes(d);const x=document.createElement("canvas"),g=x.getContext("2d");return x.width=d.width/2,x.height=d.height/2,g.drawImage(l,0,0),i&&(x.style.setProperty("position","fixed"),x.style.setProperty("z-index","99"),x.style.setProperty("left","2rem"),x.style.setProperty("bottom","2rem"),x.style.setProperty("width",.1*d.width+"px"),x.style.setProperty("height",.1*d.height+"px"),x.dataset.debugLabel=`${o.toLowerCase()}`,document.body.appendChild(x)),l.close(),d};let Be=Ct;class sp extends sr{constructor(e){super(),this.url=e,this.nodeMaterialIds=new Map([]),this.gpuSamplers=new Map,this.gpuTextures=new Map,this.gpuBuffers=new Map,this.updateWorldMatrix()}setMaterial(e,t=N.Deferred){return this.traverse(r=>{r instanceof Ae&&r.setMaterial(e,t)}),this}setIsReflective(e){return this.traverse(t=>{t instanceof Ae&&(t.materialProps.isReflective=e)}),this}setTextureForAll(e,t=1){return this.traverse(r=>{r instanceof Ae&&r.setTexture(e,t)}),this}setSampler(e){return this.traverse(t=>{t instanceof Ae&&t.setSampler(e)}),this}setTextureFor(e,t,r=1){const n=this.findChildByLabel(e);if(n instanceof Ae)return n.setTexture(t,r),this;console.error("Found child is not instance of a Drawable")}async load(){const e=[],t=async function(u,l,m){let b,d;Array.isArray(l)||ei(l)?(b=l,d=m):(b=[],d=l);const x=su(d);let g=u;return typeof u=="string"&&(g=await x(u)),Ut(u)&&(g=await x(u)),Array.isArray(b),await si(g,b,d)}(this.url,Si);e.push(t);const r=(n=await t,new Kf().postProcess(n,i));var n,i;const o=this.initGPUTexturesFrom(r.textures);return e.push(o),this.initGPUSamplersFrom(r.samplers),this.initGPUBuffersFrom(r.bufferViews),this.initMaterialsFrom(r.materials),this.initNodesFrom(r),Promise.all(e)}async initMaterialsFrom(e){for(const t of e){if(t.pbrMetallicRoughness&&t.pbrMetallicRoughness.baseColorTexture){const r=await this.gpuTextures.get(t.pbrMetallicRoughness.baseColorTexture.texture.id),n=this.nodeMaterialIds.get(t.id);for(const i of n)i.setTexture(r,me.Albedo);if(t.pbrMetallicRoughness.metallicRoughnessTexture){const i=await this.gpuTextures.get(t.pbrMetallicRoughness.metallicRoughnessTexture.texture.id),o=this.nodeMaterialIds.get(t.id);for(const u of o)u.setTexture(i,me.MetallicRoughness)}}if(t.normalTexture){const r=await this.gpuTextures.get(t.normalTexture.texture.id),n=this.nodeMaterialIds.get(t.id);for(const i of n)i.setTexture(r,me.Normal)}}}async initGPUTexturesFrom(e){const t=[];for(const r of e){const n=Be.loadTextureFromData(r.source.bufferView.data,"rgba8unorm",!0,!1,!1,`GLTF Texture: ${r.id}`);t.push(n),this.gpuTextures.set(r.id,n)}return Promise.all(t)}initGPUSamplersFrom(e){for(const t of e){const r=Je.getSamplerFromGltfSamplerDef(t);this.gpuSamplers.set(t.id,r)}}initGPUBuffersFrom(e){for(const t of e){let r=0;t.target===34963&&(r|=GPUBufferUsage.INDEX),t.target===34962&&(r|=GPUBufferUsage.VERTEX);const n=4*Math.ceil(t.byteLength/4),i=B.device.createBuffer({label:t.id,mappedAtCreation:!0,size:n,usage:r});Y.addBufferBytes(i),new Uint8Array(i.getMappedRange()).set(new Uint8Array(t.buffer.arrayBuffer,t.byteOffset,t.byteLength)),i.unmap(),this.gpuBuffers.set(t.id,i)}}initNodesFrom(e){var t,r,n,i;for(const o of e.nodes)if(o.mesh)for(const u of o.mesh.primitives){const l=new Xf(u,this.gpuBuffers),m=new Ae(l),b=D.create(),d=D.create(1,1,1),x=Zr.identity(),g=this.nodeMaterialIds.get(u.material.id)||[];g.push(m),this.nodeMaterialIds.set(u.material.id,g),u.material.pbrMetallicRoughness.baseColorTexture&&u.material.pbrMetallicRoughness.baseColorTexture.texture.source.uri.includes("5823059166183034438")?m.materialProps.isReflective=!0:m.materialProps.isReflective=!1,m.label=o.name??o.id;const _=(r=(t=u.attributes)==null?void 0:t.POSITION)==null?void 0:r.min;_&&m.boundingBox.setMinAABBfromGLTF(_);const w=(i=(n=u.attributes)==null?void 0:n.POSITION)==null?void 0:i.max;w&&m.boundingBox.setMaxAABBfromGLTF(w),o.translation&&D.set(o.translation[0],o.translation[1],o.translation[2],b),o.scale&&D.set(o.scale[0],o.scale[1],o.scale[2],d),o.rotation&&Zr.set(o.rotation[0],o.rotation[1],o.rotation[2],o.rotation[3],x),m.setCustomMatrixFromTRS(b,x,d),m.sampler=this.gpuSamplers.get("sampler-0"),this.addChild(m)}}}const cc="vertexMain",lc="fragmentMain",np=` - ${W.Camera} - - @group(${ue.CameraPlusOptionalLights}) @binding(0) var camera: Camera; - - @group(1) @binding(0) var linePointPositions: array; - - @vertex - fn ${cc}( - @builtin(vertex_index) vertexId: u32, - ) -> @builtin(position) vec4f { - let position = linePointPositions[vertexId]; - return camera.projectionViewMatrix * position; - } - - @fragment - fn ${lc}() -> @location(0) vec4f { - return vec4f(vec3f(1), 1); - } -`;class ip extends sr{constructor(e){super(),this.points=e,this.pointsGPUBuffer=B.device.createBuffer({label:"Line Points GPU Buffer",size:4*e.length*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.STORAGE,mappedAtCreation:!0}),Y.addBufferBytes(this.pointsGPUBuffer);const t=new Float32Array(this.pointsGPUBuffer.getMappedRange());for(let u=0;ur!==e.id;e instanceof Ae&&(e.isOpaque?(this.opaqueMeshes=this.opaqueMeshes.filter(t),this.culledOpaqueMeshes=this.culledOpaqueMeshes.filter(t)):(this.transparentMeshes=this.transparentMeshes.filter(t),this.culledTransparentMeshes=this.culledTransparentMeshes.filter(t)));for(const r of this.onGraphChangedCallbacks)r()}}const dc=` - // Van Der Corpus sequence - // @see http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html - fn vdcSequence(inBits: u32) -> f32 { - var bits = inBits; - bits = (bits << 16u) | (bits >> 16u); - bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); - bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); - bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); - bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); - return f32(bits) * 2.3283064365386963e-10; // / 0x100000000 - } - - // Hammersley sequence - // @see http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html - fn hammersley(i: u32, N: u32) -> vec2f { - return vec2f(f32(i) / f32(N), vdcSequence(i)); - } - - // Based on Karis 2014 - // GGX NDF via importance sampling - fn importanceSampleGGX(Xi: vec2f, N: vec3f, roughness: f32) -> vec3f { - let alpha = roughness * roughness; - let alpha2 = alpha * alpha; - - let phi = TWO_PI * Xi.x; - let cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha2 - 1.0) * Xi.y)); - let sinTheta = sqrt(1.0 - cosTheta * cosTheta); - - // from spherical coordinates to cartesian coordinates - let H = vec3f(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta); - - // from tangent-space vector to world-space sample vector - - let up = select(WORLD_UP, WORLD_FORWARD, abs(N.z) < 0.999); - let tangent = normalize(cross(up, N)); - let bitangent = cross(N, tangent); - - return tangent * H.x + bitangent * H.y + N * H.z; - } - - fn GTR2(NdotH: f32, a: f32) -> f32 { - let a2 = a * a; - let t = 1.0 + (a2 - 1.0) * NdotH * NdotH; - return step(0.0, NdotH) * a2 / (PI * t * t); - } - - fn distributionGGX(NdotH: f32, roughness: f32) -> f32 { - return GTR2(NdotH, roughness * roughness); - } - - fn visibilitySmithGGXCorrelated(NdotV: f32, NdotL: f32, roughness: f32) -> f32 { - let a2 = roughness * roughness; - let oneMinusA2 = 1.0 - a2; - let ggxv = NdotL * sqrt(NdotV * NdotV * oneMinusA2 + a2); - let ggxl = NdotV * sqrt(NdotL * NdotL * oneMinusA2 + a2); - - let ggx = ggxv + ggxl; - if (ggx > 0.0) { - return 0.5 / ggx; - } - return 0.0; - } -`,hc="main",ap=` - ${W.CommonHelpers} - - @group(0) @binding(0) var outTexture: texture_storage_2d; - - const SAMPLE_COUNT = 1024u; - - ${dc} - - // https://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf - // Karis 2014 - @must_use - fn integrate(NdotV: f32, roughness: f32) -> vec2f { - var V = vec3f(0.0); - V.x = sqrt(1.0 - NdotV * NdotV); // sin - V.y = 0.0; - V.z = NdotV; // cos - - // N points straight upwards for this integration - let N = vec3f(0.0, 0.0, 1.0); - - var A = 0.0; - var B = 0.0; - - for (var i = 0u; i < SAMPLE_COUNT; i++) { - let Xi = hammersley(i, SAMPLE_COUNT); - let H = importanceSampleGGX(Xi, N, roughness); - let L = 2.0 * dot(V, H) * H - V; - - let NdotL = saturate(L.z); - let NdotH = saturate(H.z); - let VdotH = saturate(dot(V, H)); - - if (NdotL > 0.0) { - let V_pdf = visibilitySmithGGXCorrelated(NdotV, NdotL, roughness) * VdotH * NdotL / NdotH; - let Fc = pow(1.0 - VdotH, 5.0); - A += (1.0 - Fc) * V_pdf; - B += Fc * V_pdf; - } - } - - return 4.0 * vec2f(A, B) / f32(SAMPLE_COUNT); - } - - @compute @workgroup_size(8, 8) - fn ${hc}(@builtin(global_invocation_id) id: vec3u) { - let texSize = textureDimensions(outTexture).xy; - if (any(id.xy >= texSize)) { - return; - } - - let size = vec2f(texSize.xy) - 1.0; - let uv = vec2f(id.xy) / size; - - let result = vec4f(integrate(uv.x, uv.y), 0, 0); - textureStore(outTexture, id.xy, result); - } -`;let Vs;const fc=[{binding:0,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"rgba16float",viewDimension:"2d"}}],nn=class nn extends Ze{static get computePSO(){if(Vs)return Vs;const e=B.device.createBindGroupLayout({label:"BDRF Lut Compute PSO Bind Group Layout",entries:fc});return Vs=B.device.createComputePipeline({label:"BDRF LUT Generate Compute PSO",compute:{module:J.createShaderModule(ap),entryPoint:hc},layout:B.device.createPipelineLayout({label:"BDRF LUT Generation Compute PSO Layout",bindGroupLayouts:[e]})}),Vs}};nn.encode=(e=512)=>{const t=B.device.createTexture({label:"BDRF LUT Texture",size:{width:e,height:e,depthOrArrayLayers:1},format:"rgba16float",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.COPY_DST,mipLevelCount:1}),r=B.device.createCommandEncoder({label:"BDRF LUT Generate Command Encoder"});B.ENABLE_DEBUG_GROUPS&&r.pushDebugGroup("BDRF LUT Generation");const n=r.beginComputePass({label:"BDRF LUT Generate Compute Pass"}),i=B.device.createBindGroupLayout({label:"BDRF Lut Compute PSO Bind Group Layout",entries:fc}),o=[{binding:0,resource:t.createView()}],u=B.device.createBindGroup({label:"BDRF LUT Generate Input Bind Group",layout:i,entries:o}),l=(e+8-1)/8,m=(e+8-1)/8;return n.setPipeline(nn.computePSO),n.setBindGroup(0,u),n.dispatchWorkgroups(l,m,1),n.end(),B.ENABLE_DEBUG_GROUPS&&r.popDebugGroup(),B.device.queue.submit([r.finish()]),Y.addTextureBytes(t),t};let Oi=nn;const pc="main",up=` - ${W.CommonHelpers} - ${W.MathHelpers} - - @group(0) @binding(0) var inTexture: texture_cube; - @group(0) @binding(1) var outTexture: texture_storage_2d; - @group(0) @binding(2) var cubeSampler: sampler; - @group(0) @binding(3) var face: u32; - - @compute @workgroup_size(8, 8) - fn ${pc}(@builtin(global_invocation_id) id: vec3u) { - let texSize = textureDimensions(outTexture).xy; - if (any(id.xy >= texSize)) { - return; - } - - let size = vec2f(texSize.xy); - let uv = vec2f(id.xy) / size; - - var ruv = 2.0 * uv - 1.0; - ruv.y = ruv.y * -1; - - var irradiance = vec3f(0.0); - let rotation = CUBE_ROTATIONS[face]; - let N = normalize(vec3f(ruv, 1.0) * rotateAxisAngle(rotation.xyz, rotation.w)); - var UP = select(WORLD_UP, WORLD_FORWARD, abs(N.z) < 0.999); - let RIGHT = normalize(cross(UP, N)); - UP = cross(RIGHT, N); - - var sampleCount = 0u; - - for (var phi: f32 = 0.0; phi < TWO_PI; phi += DELTA_PHI) { - let sinPhi = sin(phi); - let cosPhi = cos(phi); - for (var theta: f32 = 0.0; theta < HALF_PI; theta += DELTA_THETA) { - let sinTheta = sin(theta); - let cosTheta = cos(theta); - - let tempVec = cosPhi * RIGHT + sinPhi * UP; - let sampleVector = cosTheta * N + sinTheta * tempVec; - - irradiance += textureSampleLevel(inTexture, cubeSampler, sampleVector, 2).rgb * cos(theta) * sin(theta); - sampleCount++; - } - } - - irradiance = PI * irradiance / f32(sampleCount); - textureStore(outTexture, id.xy, vec4f(irradiance, 1.0)); - } -`;let Hs;const mc=[{binding:0,texture:{viewDimension:"cube",sampleType:"float"},visibility:GPUShaderStage.COMPUTE},{binding:1,storageTexture:{access:"write-only",format:"rgba16float",viewDimension:"2d"},visibility:GPUShaderStage.COMPUTE},{binding:2,sampler:{},visibility:GPUShaderStage.COMPUTE},{binding:3,buffer:{},visibility:GPUShaderStage.COMPUTE}],on=class on extends Ze{static get computePSO(){if(Hs)return Hs;const e=B.device.createBindGroupLayout({label:"Diffuse IBL Compute PSO Bind Group Layout",entries:mc});return Hs=J.createComputePipeline({label:"Diffuse IBL Compute PSO",compute:{module:J.createShaderModule(up),entryPoint:pc},layout:B.device.createPipelineLayout({label:"Diffuse IBL Compute PSO Layout",bindGroupLayouts:[e]})}),Hs}};on.encode=(e,t=32)=>{if(e.depthOrArrayLayers!==6)return void console.error("Need cube texture as a source for IBL Diffuse");if(e.format!=="rgba16float")return void console.error("Only rgba16float cube textures supported for Diffuse IBL for now");const r=Lr.createEmptyCubeTexture(t,"Diffuse IBL Texture",!0),n=B.device.createBindGroupLayout({label:"Diffuse IBL Compute PSO Bind Group Layout",entries:mc}),i=[{binding:0,resource:null},{binding:1,resource:null},{binding:2,resource:Je.createSampler({addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",minFilter:"linear",magFilter:"linear"})},{binding:3,resource:{buffer:null}}],o=B.device.createCommandEncoder({label:"Diffuse IBL Command Encoder"}),u=o.beginComputePass({label:"Diffuse IBL Compute Pass"});B.ENABLE_DEBUG_GROUPS&&u.pushDebugGroup("Begin Diffuse IBL"),u.setPipeline(on.computePSO);const l=e.createView({dimension:"cube"});for(let m=0;m<6;m++){const b=B.device.createBuffer({label:"Diffuse IBL Face GPUBuffer",size:Uint32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0});Y.addBufferBytes(b),new Uint32Array(b.getMappedRange()).set(new Uint32Array([m])),b.unmap();const d=r.createView({format:r.format,dimension:"2d",baseMipLevel:0,mipLevelCount:1,baseArrayLayer:m,arrayLayerCount:1});i[0].resource=l,i[1].resource=d,i[3].resource={buffer:b};const x=B.device.createBindGroup({layout:n,entries:i}),g=8,_=(r.width+g-1)/g,w=(r.height+g-1)/g;u.setBindGroup(0,x),u.dispatchWorkgroups(_,w,1)}return B.ENABLE_DEBUG_GROUPS&&u.popDebugGroup(),u.end(),B.device.queue.submit([o.finish()]),Y.addTextureBytes(r),r};let Ii=on;const gc="main",cp=` - ${W.CommonHelpers} - ${W.MathHelpers} - - @group(0) @binding(0) var inTexture: texture_cube; - @group(0) @binding(1) var outTexture: texture_storage_2d; - @group(0) @binding(2) var cubeSampler: sampler; - @group(0) @binding(3) var face: u32; - @group(0) @binding(4) var roughness: f32; - - const SAMPLE_COUNT: u32 = 1024; - - ${dc} - - @compute @workgroup_size(8, 8) - fn ${gc}(@builtin(global_invocation_id) id: vec3u) { - let texSize = textureDimensions(outTexture).xy; - if (any(id.xy >= texSize)) { - return; - } - - let size = vec2f(texSize.xy); - let uv = vec2f(id.xy) / size; - - var ruv = 2.0 * uv - 1.0; - ruv.y = ruv.y * -1; - - let rotation = CUBE_ROTATIONS[face]; - let N = normalize(vec3f(ruv, 1.0) * rotateAxisAngle(rotation.xyz, rotation.w)); - - let R = N; - let V = R; - - var prefilteredColor = vec3f(0.0); - var totalWeight = 0.0; - - for (var i = 0u; i < SAMPLE_COUNT; i++) { - // generates a sample vector that's biased towards the preferred alignment direction (importance sampling). - let Xi = hammersley(i, SAMPLE_COUNT); - let H = importanceSampleGGX(Xi, N, roughness); - let L = normalize(2.0 * dot(V, H) * H - V); - - let NdotL = max(dot(N, L), 0.0); - - if (NdotL > 0.0) { - // sample from the environment's mip level based on roughness/pdf - - let NdotH = max(dot(N, H), 0.0); - let HdotV = max(dot(H, V), 0.0); - let D = distributionGGX(NdotH, roughness); - let pdf = max((D * NdotH / (4.0 * HdotV)) + 0.0001, 0.0001); - - let resolution = f32(textureDimensions(inTexture).x); // resolution of source cubemap (per face) - let saTexel = 4.0 * PI / (6.0 * resolution * resolution); - let saSample = 1.0 / (f32(SAMPLE_COUNT) * pdf + 0.0001); - - let mipLevel = select(0.5 * log2(saSample / saTexel), 0.0, roughness == 0.0); - - prefilteredColor += textureSampleLevel(inTexture, cubeSampler, L, mipLevel).rgb * NdotL; - totalWeight += NdotL; - } - } - - prefilteredColor = prefilteredColor / totalWeight; - textureStore(outTexture, id.xy, vec4f(prefilteredColor, 1.0)); - } -`;let Js;const yc=[{binding:0,texture:{viewDimension:"cube",sampleType:"float"},visibility:GPUShaderStage.COMPUTE},{binding:1,storageTexture:{access:"write-only",format:"rgba16float",viewDimension:"2d"},visibility:GPUShaderStage.COMPUTE},{binding:2,sampler:{},visibility:GPUShaderStage.COMPUTE},{binding:3,buffer:{},visibility:GPUShaderStage.COMPUTE},{binding:4,buffer:{},visibility:GPUShaderStage.COMPUTE}],an=class an extends Ze{static get computePSO(){if(Js)return Js;const e=B.device.createBindGroupLayout({label:"Specular IBL Compute PSO Bind Group Layout",entries:yc});return Js=J.createComputePipeline({label:"Specular IBL Compute PSO",compute:{module:J.createShaderModule(cp),entryPoint:gc},layout:B.device.createPipelineLayout({label:"Specular IBL Compute PSO",bindGroupLayouts:[e]})}),Js}};an.encode=(e,t=128)=>{if(e.depthOrArrayLayers!==6)return void console.error("Need cube texture as a source of IBL Specular");if(e.format!=="rgba16float")return void console.error("Only rgba16float cube textures supported for Specular IBL for now");const r=Lr.createEmptyCubeTexture(t,"Specular IBL Texture",!0),n=e.createView({dimension:"cube"}),i=r.mipLevelCount,o=[{binding:0,resource:n},{binding:1,resource:null},{binding:2,resource:Je.createSampler({minFilter:"linear",magFilter:"linear"})},{binding:3,resource:{buffer:null}},{binding:4,resource:{buffer:null}}],u=B.device.createCommandEncoder({label:"Specular IBL Command Encoder"});B.ENABLE_DEBUG_GROUPS&&u.pushDebugGroup("Begin Specular IBL Generation");const l=u.beginComputePass({label:"Specular IBL Compute Pass"});l.setPipeline(an.computePSO);const m=B.device.createBindGroupLayout({label:"Specular IBL Compute PSO Bind Group Layout",entries:yc});let b=t;for(let d=0;d(s[s.Normal=0]="Normal",s[s.AO=1]="AO",s[s.Metallic=2]="Metallic",s[s.Roughness=3]="Roughness",s[s.Reflectance=4]="Reflectance",s[s.Albedo=5]="Albedo",s[s.Depth=6]="Depth",s[s.Velocity=7]="Velocity",s[s.ShadowDepthCascade0=8]="ShadowDepthCascade0",s[s.ShadowDepthCascade1=9]="ShadowDepthCascade1",s[s.BDRF=10]="BDRF",s))($||{});const lp=""+new URL("nx-DA81WUUi.hdr",import.meta.url).href,dp=""+new URL("ny-BiQjxcWx.hdr",import.meta.url).href,hp=""+new URL("nz-BP-ItiR-.hdr",import.meta.url).href,fp=""+new URL("px-DYiCDBPi.hdr",import.meta.url).href,pp=""+new URL("py-CfjHNeO0.hdr",import.meta.url).href,mp=""+new URL("pz-DN7hTcVy.hdr",import.meta.url).href,rt="normal+metallic+roughness texture",xt="albedo+reflectance texture",zs="velocity texture",Ce="depth texture",Ir="directional light depth texture",bc="ssao texture",pr="ssao blur texture",Xe="lighting texture",Fr="taa resolve texture",js="hi-z depth texture",Dr="computed reflections texture",Ur="bloom downscale texture",Jt=new Array(3);Jt[ut.NormalMetallicRoughness]={format:"rgba16float"},Jt[ut.ColorReflectance]={format:"bgra8unorm"},Jt[ut.Velocity]={format:"rg16float"};const gp=[lp,dp,hp,fp,pp,mp],yp=[D.create(5.5,7.5,3.25),D.create(4,6.5,.5),D.create(2.5,6.5,3.25),D.create(1,7.5,.5),D.create(-.5,7.5,3.25),D.create(-2,6.5,.5),D.create(-3.5,6.5,3.25),D.create(-5,7.5,.5),D.create(-6.5,7.5,3.25),D.create(-7.75,6.5,.5),D.create(-10.5,7.5,-.125),D.create(-7.75,7.5,-1),D.create(-6.5,6.5,-4),D.create(-5,6.5,-1),D.create(-3.5,7.5,-4),D.create(-2,7.5,-1),D.create(-.5,6.5,-4),D.create(1,6.5,-1),D.create(2.5,7.5,-4),D.create(4,7.5,-1),D.create(5.5,6.5,-4),D.create(6.5,6.5,-1),D.create(9,6.5,-1),D.create(9.5,7.5,-.125),D.create(9,6.5,.7),D.create(6,6.5,1),D.create(6,7.5,3.25)],xc=D.create(3,20,3),bp=D.create(.1,20,.1),_c=D.create(9.7,3.4,-.35),xp=D.create(9.3,3.4,-.35),_t="fullscreenVertex",zt=` - ${W.VertexOutput} - - const pos = array( - vec2(-1.0, -1.0), vec2(3, -1.0), vec2(-1.0, 3), - ); - const uv = array( - vec2(0.0, 0.0), vec2(2.0, 0.0), vec2(0.0, 2.0) - ); - - @vertex - fn ${_t}( - @builtin(vertex_index) vertexId: u32, - @builtin(instance_index) instanceId: u32, - ) -> VertexOutput { - var out: VertexOutput; - out.position = vec4f(pos[vertexId], 0.0, 1.0); - out.uv = uv[vertexId]; - out.instanceId = instanceId; - return out; - } -`,_p=/#([^\s]*)(\s*)/gm;class Ac{constructor(e){ee(this,"elseIsValid",!0);ee(this,"branches",[]);this.pushBranch("if",e)}pushBranch(e,t){if(!this.elseIsValid)throw new Error(`#${e} not preceeded by an #if or #elif`);this.elseIsValid=e==="if"||e==="elif",this.branches.push({expression:!!t,string:""})}appendStringToCurrentBranch(...e){for(const t of e)this.branches[this.branches.length-1].string+=t}resolve(){for(const e of this.branches)if(e.expression)return e.string;return""}}function At(s,...e){const t=[];let r=new Ac(!0);r.elseIsValid=!1;const n=(i,o)=>{if(i.index+i[0].length!=o.length)throw new Error(`#${i[1]} must be immediately followed by a template expression (ie: \${value})`)};for(let i=0;ii&&r.appendStringToCurrentBranch(e[i])}if(t.length)throw new Error("Mismatched #if/#endif count");return r.resolve()}const kr=` - fn encodeNormal(n: vec3f) -> vec2f { - // return n.xy* 0.5 + 0.5; - let p = sqrt(n.z * 8 + 8); - return n.xy / p + 0.5; - } - - fn decodeNormal(enc: vec2f) -> vec3f { - - let fenc = enc * 4 - 2; - let f = dot(fenc, fenc); - let g = sqrt(1 - f / 4); - - return vec3f( - fenc * g, - 1 - f / 2 - ); - } -`,Bc="fragmentShaderDebugTexture",Ap=new Map([[$.Albedo,"Albedo"],[$.Normal,"View-Space Normal"],[$.AO,"Screen-Space AO"],[$.Metallic,"Metallic"],[$.Roughness,"Roughness"],[$.Reflectance,"Reflectance"],[$.Depth,"Depth"],[$.Velocity,"Velocity"],[$.ShadowDepthCascade0,"Cascade #1"],[$.ShadowDepthCascade1,"Cascade #2"]]);class st{constructor(e){this.type=e,this.$rootEl=document.createElement("div"),this.$headline=document.createElement("h4"),this.$canvas=document.createElement("canvas"),this.$rootEl.classList.add("debug-canvas-wrapper"),this.$canvas.classList.add("debug-canvas"),this.$headline.innerText=Ap.get(e),this.$rootEl.appendChild(this.$headline),this.$rootEl.appendChild(this.$canvas),this.ctx=this.$canvas.getContext("webgpu"),this.ctx.configure({device:B.device,format:B.pixelFormat,usage:GPUTextureUsage.RENDER_ATTACHMENT});const t=[{format:B.pixelFormat}];var r;this.samplerTextureBindGroupLayoutEntries=[{binding:0,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:this.isDepthTexture?"depth":"float"}}],this.samplerTextureBindGroupLayout=B.device.createBindGroupLayout({label:"TextureDebugMesh Sampler + Texture GPUBindGroupLayout",entries:this.samplerTextureBindGroupLayoutEntries}),this.renderPSO=J.createRenderPipeline({label:`Debug Canvas ${e} Render PSO`,vertex:{module:J.createShaderModule(zt),entryPoint:_t},fragment:{module:J.createShaderModule((r=this.type,At` - ${W.VertexOutput} - - ${kr} - - @group(0) @binding(0) var mySampler: sampler; - - #if ${r===$.Depth||r===$.ShadowDepthCascade0||r===$.ShadowDepthCascade1} - @group(0) @binding(1) var myTexture: texture_depth_2d; - #else - @group(0) @binding(1) var myTexture: texture_2d; - #endif - - @fragment - fn ${Bc}(in: VertexOutput) -> @location(0) vec4 { - var uv = in.uv; - uv.y = 1.0 - uv.y; - var color: vec4f; - #if ${r===$.Normal} - color = vec4f(decodeNormal(textureSample(myTexture, mySampler, uv).rg), 1.0); - // color = vec4f(textureSample(myTexture, mySampler, uv).rgb, 1.0); - #elif ${r===$.Metallic} - color = vec4f(textureSample(myTexture, mySampler, uv).bbb, 1.0); - #elif ${r===$.Roughness} - color = vec4f(textureSample(myTexture, mySampler, uv).aaa, 1.0); - #elif ${r===$.Reflectance} - color = vec4f(textureSample(myTexture, mySampler, uv).a, 0.0, 0.0, 1.0); - #elif ${r===$.Depth} - let depth = textureSample(myTexture, mySampler, uv); - - let near: f32 = 0.1; // Example near plane - let far: f32 = 20.0; // Example far plane - - // Linearize the depth (from clip space depth to linear depth) - let depth_linear = near * far / (far - depth * (far - near)); - - // Normalize the linear depth to [0, 1] (NDC space) - let depth_ndc = (depth_linear - near) / (far - near); - color = vec4f(vec3f(depth_ndc), 1); - - #elif ${r===$.ShadowDepthCascade0||r===$.ShadowDepthCascade1} - let depth = textureSample(myTexture, mySampler, uv); - - let near: f32 = 0.1; // Example near plane - let far: f32 = 1.0; // Example far plane - - // Linearize the depth (from clip space depth to linear depth) - let depth_linear = near * far / (far - depth * (far - near)); - - // Normalize the linear depth to [0, 1] (NDC space) - let depth_ndc = (depth_linear - near) / (far - near); - color = vec4f(vec3f(depth_ndc), 1); - #elif ${r===$.Velocity} - color = vec4f(textureSample(myTexture, mySampler, uv).rg * 100, 0, 1); - #elif ${r===$.BDRF} - color = vec4f(textureSample(myTexture, mySampler, in.uv).rg, 0, 1); - #elif ${r===$.Albedo} - color = vec4f(textureSample(myTexture, mySampler, uv).rgb, 1); - #elif ${r===$.AO} - color = vec4f(textureSample(myTexture, mySampler, uv).rrr, 1); - #else - color = textureSample(myTexture, mySampler, uv); - #endif - return color; - } -`)),entryPoint:Bc,targets:t},layout:B.device.createPipelineLayout({label:`Debug Canvas ${e} Render PSO Layout`,bindGroupLayouts:[this.samplerTextureBindGroupLayout]})}),this.renderPassDescriptor={label:`Debug Canvas ${e} Render Pass Descriptor`,colorAttachments:[{loadOp:"load",storeOp:"store",view:null}]}}get isDepthTexture(){return this.type===$.Depth||this.type===$.ShadowDepthCascade0||this.type===$.ShadowDepthCascade1}appendTo(e){e.appendChild(this.$rootEl)}setTexture(e,t=e.width,r=e.height){this.debugTexture=e,this.$canvas.width=t,this.$canvas.height=r;let n=0;this.type===$.ShadowDepthCascade0?n=0:this.type===$.ShadowDepthCascade1&&(n=1);const i=[{binding:0,resource:Je.createSampler({magFilter:"linear",minFilter:"linear"})},{binding:1,resource:e.createView({aspect:this.isDepthTexture?"depth-only":"all",baseArrayLayer:n,dimension:"2d"})}];this.samplerTextureBindGroup=B.device.createBindGroup({layout:this.samplerTextureBindGroupLayout,entries:i})}render(e){if(!this.debugTexture)return;this.renderPassDescriptor.colorAttachments[0].view=this.ctx.getCurrentTexture().createView();const t=e.beginRenderPass(this.renderPassDescriptor);B.ENABLE_DEBUG_GROUPS&&t.pushDebugGroup(`Display Debug Texture ${this.type}`),t.setPipeline(this.renderPSO),t.setBindGroup(0,this.samplerTextureBindGroup),t.draw(3),B.ENABLE_DEBUG_GROUPS&&t.popDebugGroup(),t.end()}}var Di=(s=>(s[s.GBuffer=0]="GBuffer",s[s.Shadow=1]="Shadow",s))(Di||{});const Bp=new Map([[0,"G-Buffer Debug"],[1,"Shadows Debug"]]);class Ks{constructor(e){this.canvases=new Map,this.$root=Ks.createRootElement(),this.$main=document.createElement("div"),this.$main.classList.add("section");const t=document.createElement("h2");t.textContent=Bp.get(e),t.classList.add("section-headline"),this.$root.appendChild(t),this.$root.appendChild(this.$main)}static createRootElement(){const e=document.createElement("div");return e.classList.add("texture-debug-wrapper"),e}appendTo(e){e.appendChild(this.$root)}setTextureFor(e,t,r=.2*t.width,n=.2*t.height){return this.canvases.get(e).setTexture(t,r,n),this}render(e){for(const t of this.canvases.values())t.render(e)}}class vp extends Ks{constructor(){super(Di.GBuffer);const e=new st($.Albedo);e.appendTo(this.$main),this.canvases.set($.Albedo,e);const t=new st($.Normal);t.appendTo(this.$main),this.canvases.set($.Normal,t);const r=new st($.Metallic);r.appendTo(this.$main),this.canvases.set($.Metallic,r);const n=new st($.Roughness);n.appendTo(this.$main),this.canvases.set($.Roughness,n);const i=new st($.AO);i.appendTo(this.$main),this.canvases.set($.AO,i);const o=new st($.Reflectance);o.appendTo(this.$main),this.canvases.set($.Reflectance,o);const u=new st($.Depth);u.appendTo(this.$main),this.canvases.set($.Depth,u);const l=new st($.Velocity);l.appendTo(this.$main),this.canvases.set($.Velocity,l)}}class wp extends Ks{constructor(){super(Di.Shadow);const e=new st($.ShadowDepthCascade0);e.appendTo(this.$main),this.canvases.set($.ShadowDepthCascade0,e);const t=new st($.ShadowDepthCascade1);t.appendTo(this.$main),this.canvases.set($.ShadowDepthCascade1,t)}}const un=class un{constructor(){this.open=!1,this.$root=document.createElement("div"),this.$root.id=un.ROOT_EL_ID,document.body.appendChild(this.$root),this.gbufferDebugSection=new vp,this.gbufferDebugSection.appendTo(this.$root),this.shadowDebugSection=new wp,this.shadowDebugSection.appendTo(this.$root)}reveal(){this.open=!0,this.$root.classList.add("open")}hide(){this.open=!1,this.$root.classList.remove("open")}scrollToShadowSection(){this.shadowDebugSection.$root.scrollIntoView({block:"start",inline:"nearest"})}scrollIntoGbufferSection(){this.gbufferDebugSection.$root.scrollIntoView({block:"start",inline:"nearest"})}setTextureGBufferSection(e,t,r=.2*t.width,n=.2*t.height){return this.open?(this.gbufferDebugSection.setTextureFor(e,t,r,n),this):this}setTextureShadowSection(e,t,r=.2*t.width,n=.2*t.height){return this.open?(this.shadowDebugSection.setTextureFor(e,t,r,n),this):this}render(e){this.open&&(this.gbufferDebugSection.render(e),this.shadowDebugSection.render(e))}};un.ROOT_EL_ID="webgpu-debug-root";let Ui=un;const Cp=new Map([[se.CPUTotal,"cpu-total"],[se.GPUTotal,"gpu-total"],[se.FPS,"fps"],[se.VRAM,"vram"],[se.VisibleMeshes,"culled-meshes"],[se.LightsCount,"lights-count"],[se.DeferredRenderPass,"deferred"],[se.DirectionalAmbientLightingRenderPass,"directional-ambient-light"],[se.PointLightsStencilMask,"point-lights-stencil-mask"],[se.PointLightsLighting,"point-lights-lighting"],[se.SSAORenderPass,"ssao"],[se.TransparentRenderPass,"transparent"],[se.ShadowRenderPass,"shadow"],[se.TAAResolveRenderPass,"taa-resolve"],[se.ReflectionRenderPass,"reflection"],[se.BlitRenderPass,"blit"]]),Tp=new Map([[se.CPUTotal,"CPU"],[se.GPUTotal,"GPU"],[se.FPS,"FPS"],[se.VRAM,"VRAM Usage"],[se.VisibleMeshes,"Visible Meshes"],[se.LightsCount,"Lights Count"],[se.DeferredRenderPass,"G-Buffer Render Pass"],[se.DirectionalAmbientLightingRenderPass,"Directional + Ambient Render Pass"],[se.PointLightsStencilMask,"Point Lights Stencil Mask Pass"],[se.PointLightsLighting,"Point Lights Render Pass"],[se.SSAORenderPass,"SSAO Render Pass"],[se.TransparentRenderPass,"Transparent Render Pass"],[se.ShadowRenderPass,"Directional Shadow Render Pass"],[se.TAAResolveRenderPass,"TAA Resolve Render Pass"],[se.ReflectionRenderPass,"Reflection Render Pass"],[se.BlitRenderPass,"Blit Render Pass"]]),lo=class lo{constructor(){this.$renderPassTimingDisplayEls=new Map,this.$root=document.createElement("div"),this.$root.id="timings-debug-container",this.$root.classList.add("fadable","hidden"),document.body.appendChild(this.$root);for(const e of gd){const t=Cp.get(e),r=document.createElement("div");r.id=`${t}-debug-timing`,r.classList.add("timing-container"),this.$root.appendChild(r);const n=document.createElement("div");n.classList.add("timing-label"),n.innerText=`${Tp.get(e)}:`,r.appendChild(n);const i=document.createElement("div");i.classList.add("timing-value"),r.appendChild(i);const o={root:r,label:n,value:i};this.$renderPassTimingDisplayEls.set(e,o)}}toggleVisibility(){this.$root.classList.toggle("hidden")}setDisplayValue(e,t){return this.$renderPassTimingDisplayEls.get(e).value.innerText=t,this}};lo.NOT_AVAILABLE_STR="N/A";let ki=lo;const Sp=yt(Ot(W.Light).structs.Light);class mr extends sr{constructor(e){super(),this.lightType=e,this._color=D.create(1,1,0),this._intensity=1;const t=Ot(W.Light);this.lightsStorageView=yt(t.structs.Light),this.lightsStorageView.set({color:this._color,position:this.position,lightType:md.get(e),intensity:1})}static get STRUCT_BYTE_SIZE(){return Sp.arrayBuffer.byteLength}get intensity(){return this._intensity}set intensity(e){this._intensity=e,this.lightsStorageView.set({intensity:e})}get color(){return this.getColor()}set color(e){this.setColor(e[0],e[1],e[2])}setColor(e,t,r){this._color[0]=e,this._color[1]=t,this._color[2]=r,this.lightsStorageView.set({color:this._color})}setColorAsVec3(e){D.copy(e,this._color),this.lightsStorageView.set({color:this._color})}getColor(){return this._color}setPosition(e,t,r){return super.setPosition(e,t,r),this.lightsStorageView.set({position:this.position}),this}setPositionAsVec3(e){return super.setPositionAsVec3(e),this.lightsStorageView.set({position:this.position}),this}setPositionX(e){return super.setPositionX(e),this.lightsStorageView.set({position:this.position}),this}setPositionY(e){return super.setPositionY(e),this.lightsStorageView.set({position:this.position}),this}setPositionZ(e){return super.setPositionZ(e),this.lightsStorageView.set({position:this.position}),this}}class Ni extends mr{constructor(){super(It.Directional)}}class jt extends mr{get radius(){return this._radius}set radius(e){this._radius=e,this.lightsStorageView.set({radius:e})}constructor(){super(It.Point),this.intensity=1,this.radius=1}}class dt extends jt{static get bindGroupLayout(){if(this._bindGroupLayout)return this._bindGroupLayout;const e=[{binding:0,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{}}];return this._bindGroupLayout=B.device.createBindGroupLayout({label:"Camera Face Culled Point Light Bind Group Layout",entries:e}),this._bindGroupLayout}updateGPUBuffer(){B.device.queue.writeBuffer(this.gpuBuffer,0,this.lightsStorageView.arrayBuffer)}constructor(){super(),this.gpuBuffer=B.device.createBuffer({label:"Camera Face Culled Point Light GPU Buffer",size:mr.STRUCT_BYTE_SIZE,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),Y.addBufferBytes(this.gpuBuffer),this.lightsStorageView.set({type:1,intensity:1,radius:1,color:D.create(1,1,1),position:D.create(0,1,0)}),this.updateGPUBuffer();const e=[{binding:0,resource:{buffer:this.gpuBuffer}}];this.bindGroup=B.device.createBindGroup({label:"Camera Face Culled Point Light Bind Group",entries:e,layout:dt.bindGroupLayout})}}class Ep{constructor(){this.pointLights=[],this.cameraFaceCulledPointLights=[],this.directionalLights=[],this.allLights=[]}get lightsCount(){return this.allLights.length}get pointLightsCount(){return this.pointLights.length}get directionalLightsCount(){return this.directionalLights.length}updateGPUBuffer(){if(!this.allLights.length)return void console.warn("No lights, skip creating GPUBuffer");this.gpuBuffer&&(Y.removeBufferBytes(this.gpuBuffer),this.gpuBuffer.destroy()),this.gpuBuffer=B.device.createBuffer({label:"Lights GPU Buffer",size:mr.STRUCT_BYTE_SIZE*this.allLights.length,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.STORAGE}),Y.addBufferBytes(this.gpuBuffer);let e=0;for(let t=0;tr.id!==e.id;return e instanceof dt?this.cameraFaceCulledPointLights=this.cameraFaceCulledPointLights.filter(t):e instanceof jt?this.pointLights=this.pointLights.filter(t):e instanceof Ni&&(this.directionalLights=this.directionalLights.filter(t)),this.allLights=this.allLights.filter(t),this}render(e){throw new Error("Needs implementation")}}const Kt=yt(Ot(W.Particle).structs.Particle),We=class We{constructor({radius:e,position:t,velocity:r,lifeSpeed:n,life:i}={radius:1,position:D.create(0,3,0),velocity:D.create(0,1,0),lifeSpeed:1,life:0}){this.radius=e,this.position=t,this.origPosition=t,this.velocity=r,this.lifeSpeed=n,this.life=i}};We.STRUCT_BYTE_SIZE=Kt.arrayBuffer.byteLength,We.STRUCT_FLOATS_COUNT=We.STRUCT_BYTE_SIZE/Float32Array.BYTES_PER_ELEMENT,We.RADIUS_OFFSET=Kt.views.radius.byteOffset/Float32Array.BYTES_PER_ELEMENT,We.POSITION_OFFSET=Kt.views.position.byteOffset/Float32Array.BYTES_PER_ELEMENT,We.ORIG_POSITION_OFFSET=Kt.views.origPosition.byteOffset/Float32Array.BYTES_PER_ELEMENT,We.VELOCITY_OFFSET=Kt.views.velocity.byteOffset/Float32Array.BYTES_PER_ELEMENT,We.LIFE_OFFSET=Kt.views.life.byteOffset/Float32Array.BYTES_PER_ELEMENT,We.LIFE_SPEED_OFFSET=Kt.views.lifeSpeed.byteOffset/Float32Array.BYTES_PER_ELEMENT;let Ye=We;const vc="vertexMain",wc="fragMain",Mp=` - ${W.Particle} - ${W.Light} - ${W.Camera} - - struct VertexOut { - @builtin(position) position: vec4f, - @location(0) uv: vec2f, - @location(1) @interpolate(flat) instanceId: u32, - }; - - @group(0) @binding(0) var camera: Camera; - - @group(1) @binding(0) var particles: array; - @group(1) @binding(1) var lights: array; - - override ANIMATED_PARTICLES_OFFSET_START: u32; - override CURVE_PARTICLES_OFFSET: u32; - - const positions = array( - vec2f(-1.0, -1.0), - vec2f(1.0, -1.0), - vec2f(-1.0, 1.0), - vec2f(1.0, 1.0), - ); - - const uvs = array( - vec2f(0.0, 1.0), - vec2f(1.0, 1.0), - vec2f(0.0, 0.0), - vec2f(1.0, 0.0), - ); - - @vertex - fn ${vc}( - @builtin(vertex_index) vertexId: u32, - @builtin(instance_index) instanceId: u32, - ) -> VertexOut { - let p = particles[instanceId]; - let particlePosition = p.position; - let particleRadius = select(p.radius - p.radius * p.life, p.radius, instanceId >= CURVE_PARTICLES_OFFSET); - // let particleRadius = p.radius; - let uv = uvs[vertexId]; - var out: VertexOut; - out.position = camera.projectionViewMatrix * vec4f(particlePosition, 1); - let aspect = f32(camera.viewportWidth) / f32(camera.viewportHeight); - out.position += vec4f(positions[vertexId].xy * vec2f(particleRadius, particleRadius * aspect), 0, 0); - out.instanceId = instanceId; - out.uv = uv; - return out; - } - - @fragment - fn ${wc}( - in: VertexOut - ) -> @location(0) vec4f { - let light = &lights[in.instanceId + ANIMATED_PARTICLES_OFFSET_START]; - let d = distance(in.uv, vec2f(0.5)); - let mask = 1.0 - smoothstep(0.2, 0.5, d); - if (mask < 0.2) { - discard; - } - let lightColor = light.color; - return vec4f(light.color * mask * 0.8, 1); - } -`,Cc="updatePointLights",Pp=` - ${W.Particle} - ${W.Light} - - struct SimSettings { - time: f32, - timeDelta: f32, - }; - - @group(0) @binding(0) var particles: array; - @group(0) @binding(1) var lights: array; - @group(0) @binding(2) var simSettings: SimSettings; - @group(0) @binding(3) var linePointPositions: array; - @group(0) @binding(4) var fireParticlesRevealFactor: f32; - - override WORKGROUP_SIZE_X: u32; - override WORKGROUP_SIZE_Y: u32; - override ANIMATED_PARTICLES_OFFSET_START: u32; - override FIREWORK_PARTICLES_OFFSET: u32; - override FIREWORK_PARTICLES_COUNT: u32; - override CURVE_PARTICLES_OFFSET: u32; - override CURVE_PARTICLES_COUNT: u32; - override CURVE_POSITIONS_COUNT: u32; - - @must_use - fn noise(p: vec3f) -> f32 { - return fract( - sin(dot(p, vec3f(12.9898, 78.233, 45.164))) * 43758.5453 - ); - } - - @must_use - fn random(seed: f32) -> f32 { - return fract(sin(seed * 12.9898) * 43758.5453); - } - - // Curl noise for more natural 3D fluid-like motion - fn curlNoise(p: vec3) -> vec3 { - let eps = 0.1; - - let nx = noise(p + vec3(eps, 0.0, 0.0)); - let ny = noise(p + vec3(0.0, eps, 0.0)); - let nz = noise(p + vec3(0.0, 0.0, eps)); - - let x = ny - noise(p - vec3(eps, 0.0, 0.0)); - let y = nz - noise(p - vec3(0.0, eps, 0.0)); - let z = nx - noise(p - vec3(0.0, 0.0, eps)); - - return vec3(x, y, z) / (2.0 * eps); - } - - fn interpolateLinePoint(t: f32) -> vec3f { - let totalCount = CURVE_POSITIONS_COUNT; - let segmentLength = 1.0 / f32(totalCount - 1u); - let baseIndex = u32(t / segmentLength); - let localT = fract(t / segmentLength); - let safeIndex = min(baseIndex, totalCount - 2u); - let start = linePointPositions[safeIndex]; - let end = linePointPositions[safeIndex + 1u]; - return mix(start, end, localT).xyz; - } - - @compute @workgroup_size(WORKGROUP_SIZE_X, WORKGROUP_SIZE_Y, 1) - fn ${Cc}( - @builtin(global_invocation_id) tid : vec3u - ) { - let idx = tid.x; - let particle = &particles[idx]; - let light = &lights[idx + ANIMATED_PARTICLES_OFFSET_START]; - - particle.life += particle.lifeSpeed * simSettings.timeDelta; - - if (particle.life >= 1) { - particle.position = particle.origPosition; - particle.life = 0; - } - - if (idx >= FIREWORK_PARTICLES_OFFSET && idx < FIREWORK_PARTICLES_COUNT) { - let turbulence = curlNoise( - particle.position * 0.05 + - vec3(0.0, simSettings.time * 0.05, 0.0) - ) * 0.2; - particle.position += (particle.velocity + turbulence) * simSettings.timeDelta; - light.intensity = saturate((1 - particle.life) * fireParticlesRevealFactor); - particle.radius = 0.025 * fireParticlesRevealFactor; - // light.radius *= fireParticlesRevealFactor; - // light.intensity *= fireParticlesRevealFactor; - } - - if (idx >= CURVE_PARTICLES_OFFSET && idx < CURVE_PARTICLES_OFFSET + CURVE_PARTICLES_COUNT) { - particle.position = interpolateLinePoint(particle.life) + particle.velocity; - } - - if (idx >= CURVE_PARTICLES_OFFSET + CURVE_PARTICLES_COUNT) { - particle.position = vec3f( - particle.life * 15 - 7.5, - cos(particle.life + particle.life * particle.velocity.y * 30) * 1.2 + 3.5, - sin(particle.life + particle.life * particle.velocity.y * 30) * 1.075 + particle.velocity.x - ); - let fadeIn = smoothstep(0.0, 0.1, particle.life); - let fadeOut = 1.0 - smoothstep(0.9, 1.0, particle.life); - light.intensity = 0.5 * fadeIn * fadeOut; - light.radius = 1 * fadeIn * fadeOut; - } - light.position = particle.position; - - } -`,Xs=[D.create(3.9,3,.9),D.create(3.9,3,-1.5),D.create(-4.95,3,.9),D.create(-4.95,3,-1.5)],Rp=[D.create(3.9,3,1.15),D.create(3.9,3,-1.75),D.create(-4.95,3,1.15),D.create(-4.95,3,-1.75)],Nr=D.scale(D.create(1,.01,.01),10),de=class de extends Ep{constructor(e){super(),this.particles=[],this.mainFireLights=[],this.particlesSimSettingsArr=new Float32Array(2).fill(0),this.render2ndFloorParticles=!0;const t=new Ni;t.setPositionAsVec3(xc),t.setColor(.2156,.2627,.3333),t.intensity=0,this.addLight(t),this.mainDirLight=t;const r=new dt;r.radius=0,r.intensity=0,r.setPositionAsVec3(Xs[0]),r.setColorAsVec3(Nr),r.updateGPUBuffer(),this.addLight(r),this.mainFireLights.push(r);const n=new dt;n.radius=0,n.intensity=0,n.setPositionAsVec3(Xs[1]),n.setColorAsVec3(Nr),n.updateGPUBuffer(),this.addLight(n),this.mainFireLights.push(n);const i=new dt;i.intensity=0,i.radius=0,i.setPositionAsVec3(Xs[2]),i.setColorAsVec3(Nr),i.updateGPUBuffer(),this.addLight(i),this.mainFireLights.push(i);const o=new dt;o.intensity=0,o.radius=0,o.setPositionAsVec3(Xs[3]),o.setColorAsVec3(Nr),o.updateGPUBuffer(),this.addLight(o),this.mainFireLights.push(o);for(let p=0;p camera: Camera; - @group(1) @binding(0) var inTexture: texture_cube; - @group(1) @binding(1) var inSampler: sampler; - @group(1) @binding(2) var bayerDitherTexture: texture_2d; - @group(1) @binding(3) var bayerDitherSampler: sampler; - - @vertex - fn ${Tc}(in: VertexInput) -> VertexOutput { - var out: VertexOutput; - - var viewMatrix = camera.viewMatrix; - viewMatrix[3] = vec4f(0, 0, 0, 1); - let projViewMatrix = camera.projectionMatrix * viewMatrix; - let position = in.position; - out.position = (projViewMatrix * position).xyww; - // hijack to compute uvs for frag shader - out.viewNormal = 0.5 * (in.position.xyz + vec3(1.0, 1.0, 1.0)); - out.uv = in.uv; - return out; - } - - @fragment - fn ${Sc}(in: VertexOutput) -> @location(0) vec4f { - var cubemapVec = in.viewNormal - vec3(0.5); - var color = textureSampleLevel(inTexture, inSampler, cubemapVec, 4); //7.8); - let o = textureSample(bayerDitherTexture, bayerDitherSampler, in.position.xy / 8.0).r / 32.0 - (1.0 / 128.0); - color.r += o; - color.g += o; - color.b += o; - return vec4f(color.rgb, 1.0); - } -`;class Gp extends Ls{constructor(e=1,t=1,r=1,n=1){super(),this.width=e,this.height=t,this.widthSegments=r,this.heightSegments=n;const i=.5*e,o=.5*t,u=r+1,l=n+1,m=Math.floor(r),b=Math.floor(n),d=e/r,x=t/n,g=[],_=[],w=[],f=[];for(let p=0;p0){p.push(h,y,C);const K=_[h],X=_[y],j=_[C],z=w[h],q=w[y],Z=w[C],te=f[h],re=f[y],fe=f[C],pe=new fr(h,y,C,K,X,j,z,q,Z,te,re,fe);this.faces.push(pe)}(a!==r-1||l; - @group(0) @binding(1) var sceneTexture: texture_2d; - @group(0) @binding(2) var bloomMixFactor: f32; - @group(0) @binding(3) var time: f32; - @group(0) @binding(4) var revealFactor: f32; - - @must_use - fn ACESFilm(x: vec3f) -> vec3f { - let v = x; - let a = 2.51f; - let b = 0.03f; - let c = 2.43f; - let d = 0.59f; - let e = 0.14f; - return saturate((v * (a * x + b)) / (x * (c * x + d) + e)); - } - - fn rand (co: vec2f) -> f32 { - return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); - } - - fn transition(p: vec2f, progress: f32, fromColor: vec3f, toColor: vec3f) -> vec3f { - let size = vec2(10.0); - let smoothness = 0.5; - let r = rand(floor(size * p)); - let m = smoothstep(0.0, -smoothness, r - (progress * (1.0 + smoothness))); - return mix(fromColor, toColor, m); - } - - @fragment - fn ${Pc}(@builtin(position) coord : vec4f) -> @location(0) vec4f { - var bloomColor = textureLoad(bloomTexture, vec2i(floor(coord.xy)), 0).xyz; - var color = textureLoad(sceneTexture, vec2i(floor(coord.xy)), 0).xyz; - - let texSize = vec2f(textureDimensions(sceneTexture)); - // bloomColor = select(color, bloomColor, bloomColor.r > 0.); - - color = mix(color, bloomColor, bloomMixFactor); - // color = mix(color, bloomColor, 1); - - color = ACESFilm(color.rgb); - color = pow(color, vec3f(1.0 / 2.2)); - - let uv = coord.xy / texSize; - let aspect = texSize.x / texSize.y; - let timeFactor = 1.0; - let noise = vec3f(rand(vec2f(uv.x + time * timeFactor, uv.y * aspect + time * timeFactor))) * 0.1; - color = transition(uv, revealFactor, noise, color); - return vec4f(vec3(color), 1.0); - } -`,zr=class zr extends Te{async destroy(){super.destroy(),await B.device.queue.onSubmittedWorkDone(),Y.removeBufferBytes(this.bloomMixFactorBuffer),Y.removeBufferBytes(this.timeBuffer),Y.removeBufferBytes(this.revealFactorBuffer),this.bloomMixFactorBuffer.destroy(),this.timeBuffer.destroy(),this.revealFactorBuffer.destroy()}set bloomEnabled(e){B.device.queue.writeBuffer(this.bloomMixFactorBuffer,0,new Float32Array([e?zr.BLOOM_MIX_FACTOR:0]))}revealWithAnimation(e=500,t="quad_Out"){new es({durationMS:e,easeName:t,onUpdate:r=>{this.updateRevealFactor(r)}}).start()}updateRevealFactor(e){B.device.queue.writeBuffer(this.revealFactorBuffer,0,new Float32Array([e]))}constructor(e,t,r=!1){super(N.Blit,e,t);const n=J.createShaderModule(zt),i=J.createShaderModule(Op),o=[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,buffer:{}},{binding:3,visibility:GPUShaderStage.FRAGMENT,buffer:{}},{binding:4,visibility:GPUShaderStage.FRAGMENT,buffer:{}}];this.texturesBindGroupLayout=B.device.createBindGroupLayout({label:"GBuffer Textures Bind Group",entries:o});const u={layout:B.device.createPipelineLayout({bindGroupLayouts:[this.texturesBindGroupLayout]}),vertex:{module:n,entryPoint:_t},fragment:{module:i,entryPoint:Pc,targets:[{format:"bgra8unorm"}]},primitive:{topology:"triangle-list",cullMode:"back"}};this.renderPSO=J.createRenderPipeline(u),this.bloomMixFactorBuffer=B.device.createBuffer({label:"Bloom Mix Factor GPU Buffer",size:1*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),Y.addBufferBytes(this.bloomMixFactorBuffer),new Float32Array(this.bloomMixFactorBuffer.getMappedRange()).set([zr.BLOOM_MIX_FACTOR]),this.bloomMixFactorBuffer.unmap(),this.timeBuffer=B.device.createBuffer({label:"Bloom Elapsed Time Buffer",size:1*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),Y.addBufferBytes(this.timeBuffer),this.revealFactorBuffer=B.device.createBuffer({label:"Blit Loading Reveal Factor Buffer",size:1*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),Y.addBufferBytes(this.revealFactorBuffer),new Float32Array(this.revealFactorBuffer.getMappedRange()).set([r?1:0]),this.revealFactorBuffer.unmap()}createRenderPassDescriptor(){return this.renderPassDescriptor?this.renderPassDescriptor:(this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({colorAttachments:[{view:null,loadOp:"load",storeOp:"store"}],label:"Blit Pass"}),this.renderPassDescriptor)}render(e,t,r){if(!this.inputTextureViews.length){this.inputTextureViews.push(r[0].createView()),this.inputTextureViews.push(r[1].createView());const o=[{binding:0,resource:this.inputTextureViews[0]},{binding:1,resource:this.inputTextureViews[1]},{binding:2,resource:{buffer:this.bloomMixFactorBuffer}},{binding:3,resource:{buffer:this.timeBuffer}},{binding:4,resource:{buffer:this.revealFactorBuffer}}];this.textureBindGroup=B.device.createBindGroup({layout:this.texturesBindGroupLayout,entries:o})}B.device.queue.writeBuffer(this.timeBuffer,0,new Float32Array([B.elapsedTimeMs]));const n=this.createRenderPassDescriptor();n.colorAttachments[0].view=B.canvasContext.getCurrentTexture().createView();const i=e.beginRenderPass(n);return B.setActiveRenderPass(this.type,i),B.bindRenderPSO(this.renderPSO),i.setBindGroup(0,this.textureBindGroup),i.draw(6),i.end(),this.postRender(e),[]}};zr.BLOOM_MIX_FACTOR=.035;let Ki=zr;const Rc="main",Ip=` - @group(0) @binding(0) var srcTexture: texture_2d; - @group(0) @binding(1) var outTexture: texture_storage_2d; - @group(0) @binding(2) var srcSampler: sampler; - - override WORKGROUP_SIZE_X: u32; - override WORKGROUP_SIZE_Y: u32; - - @compute @workgroup_size(WORKGROUP_SIZE_X, WORKGROUP_SIZE_Y) - fn ${Rc}( - @builtin(global_invocation_id) tid : vec3u, - ) { - let outTexSize = textureDimensions(outTexture); - - if (any(tid.xy >= outTexSize)) { - return; - } - - let srcTexSize = vec2f(textureDimensions(srcTexture)); - - let texelSize = vec2f(1.0) / srcTexSize; - let x = texelSize.x; - let y = texelSize.y; - - let texCoords = vec2f((f32(tid.x) + 0.5) / f32(outTexSize.x), (f32(tid.y) + 0.5) / f32(outTexSize.y)); - - // Take 13 samples around current texel: - // a - b - c - // - j - k - - // d - e - f - // - l - m - - // g - h - i - // === ('e' is the current texel) === - let a = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x - 2 * x, texCoords.y + 2 * y), 0).rgb; - let b = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x, texCoords.y + 2 * y), 0).rgb; - let c = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x + 2 * x, texCoords.y + 2 * y), 0).rgb; - - let d = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x - 2 * x, texCoords.y), 0).rgb; - let e = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x, texCoords.y), 0).rgb; - let f = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x + 2 * x, texCoords.y), 0).rgb; - - let g = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x - 2 * x, texCoords.y - 2 * y), 0).rgb; - let h = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x, texCoords.y - 2 * y), 0).rgb; - let i = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x + 2 * x, texCoords.y - 2 * y), 0).rgb; - - let j = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x - x, texCoords.y + y), 0).rgb; - let k = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x + x, texCoords.y + y), 0).rgb; - let l = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x - x, texCoords.y - y), 0).rgb; - let m = textureSampleLevel(srcTexture, srcSampler, vec2(texCoords.x + x, texCoords.y - y), 0).rgb; - - // Apply weighted distribution: - // 0.5 + 0.125 + 0.125 + 0.125 + 0.125 = 1 - // a,b,d,e * 0.125 - // b,c,e,f * 0.125 - // d,e,g,h * 0.125 - // e,f,h,i * 0.125 - // j,k,l,m * 0.5 - // This shows 5 square areas that are being sampled. But some of them overlap, - // so to have an energy preserving downsample we need to make some adjustments. - // The weights are the distributed, so that the sum of j,k,l,m (e.g.) - // contribute 0.5 to the final color output. The code below is written - // to effectively yield this sum. We get: - // 0.125*5 + 0.03125*4 + 0.0625*4 = 1 - var downsample = e * 0.125; - downsample += (a + c + g + i) * 0.03125; - downsample += (b + d + f + h) * 0.0625; - downsample += (j + k + l + m) * 0.125; - - textureStore(outTexture, tid.xy, vec4f(downsample, 1.0)); - // textureStore(outTexture, tid.xy, vec4f(texCoords, 0.0, 1.0)); - } -`,Tt=class Tt extends Te{constructor(e,t){super(N.BloomDownsample,e,t),this.mipLevelCount=Pt(e,t),this.outTextures.push(B.device.createTexture({label:"Bloom Downscale Texture",size:{width:e,height:t},usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.COPY_DST,format:"rgba16float",mipLevelCount:this.mipLevelCount})),Y.addTextureBytes(this.outTextures[0]),this.sampler=Je.createSampler({label:"Bloom Downscale Sampler",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",minFilter:"linear",magFilter:"linear"});const r=[{binding:0,texture:{},visibility:GPUShaderStage.COMPUTE},{binding:1,storageTexture:{format:"rgba16float"},visibility:GPUShaderStage.COMPUTE},{binding:2,sampler:{},visibility:GPUShaderStage.COMPUTE}];this.bindGroupLayout=B.device.createBindGroupLayout({label:"Bloom Downscale Bind Group Layout",entries:r}),this.computePSO=J.createComputePipeline({label:"Bloom Downscale Render PSO",layout:B.device.createPipelineLayout({label:"Bloom Downscale Render PSO Layout",bindGroupLayouts:[this.bindGroupLayout]}),compute:{entryPoint:Rc,module:J.createShaderModule(Ip),constants:{WORKGROUP_SIZE_X:Tt.COMPUTE_WORKGROUP_SIZE_X,WORKGROUP_SIZE_Y:Tt.COMPUTE_WORKGROUP_SIZE_Y}}})}render(e,t,r){e.copyTextureToTexture({texture:r[0],mipLevel:0},{texture:this.outTextures[0],mipLevel:0},{width:this.width,height:this.height});const n=[{binding:0,resource:null},{binding:1,resource:null},{binding:2,resource:this.sampler}],i=e.beginComputePass({label:"Bloom Downscale Compute Pass"});i.setPipeline(this.computePSO);for(let o=1;o; - @group(0) @binding(1) var srcSampler: sampler; - @group(0) @binding(2) var filterRadius: f32; - - @fragment - fn ${Gc}( - in: VertexOutput - ) -> @location(0) vec4f { - let srcSize = vec2f(textureDimensions(srcTexture)); - let aspect = srcSize.x / srcSize.y; - - let x = filterRadius; - let y = filterRadius * aspect; - - let texCoord = vec2f(in.uv.x, 1 - in.uv.y); - - let a = textureSample(srcTexture, srcSampler, vec2f(texCoord.x - x, texCoord.y + y)).rgb; - let b = textureSample(srcTexture, srcSampler, vec2f(texCoord.x, texCoord.y + y)).rgb; - let c = textureSample(srcTexture, srcSampler, vec2f(texCoord.x + x, texCoord.y + y)).rgb; - - let d = textureSample(srcTexture, srcSampler, vec2f(texCoord.x - x, texCoord.y)).rgb; - let e = textureSample(srcTexture, srcSampler, vec2f(texCoord.x, texCoord.y)).rgb; - let f = textureSample(srcTexture, srcSampler, vec2f(texCoord.x + x, texCoord.y)).rgb; - - let g = textureSample(srcTexture, srcSampler, vec2(texCoord.x - x, texCoord.y - y)).rgb; - let h = textureSample(srcTexture, srcSampler, vec2(texCoord.x, texCoord.y - y)).rgb; - let i = textureSample(srcTexture, srcSampler, vec2(texCoord.x + x, texCoord.y - y)).rgb; - - var upsample = e * 4.0; - upsample += (b + d + f + h) * 2.0; - upsample += (a + c + g + i); - upsample *= 1.0 / 16.0; - - return vec4f(upsample, 1.0); - } -`;class Dp extends Te{async destroy(){super.destroy(),await B.device.queue.onSubmittedWorkDone(),Y.removeBufferBytes(this.filterRadiusBuffer),this.filterRadiusBuffer.destroy()}set bloomFilterRadius(e){B.device.queue.writeBuffer(this.filterRadiusBuffer,0,new Float32Array([e]))}constructor(e,t){super(N.BloomUpsample,e,t),this.sampler=Je.createSampler({label:"Bloom Downscale Sampler",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",minFilter:"linear",magFilter:"linear"}),this.filterRadiusBuffer=B.device.createBuffer({label:"Bloom Upscale Filter Radius GPU Buffer",size:1*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),Y.addBufferBytes(this.filterRadiusBuffer),new Float32Array(this.filterRadiusBuffer.getMappedRange()).set([.0035]),this.filterRadiusBuffer.unmap();const r=[{binding:0,texture:{},visibility:GPUShaderStage.FRAGMENT},{binding:1,sampler:{},visibility:GPUShaderStage.FRAGMENT},{binding:2,buffer:{},visibility:GPUShaderStage.FRAGMENT}];this.bindGroupLayout=B.device.createBindGroupLayout({label:"Bloom Upscale Bind Group Layout",entries:r}),this.renderPSO=J.createRenderPipeline({label:"Bloom Upscale Render PSO",layout:B.device.createPipelineLayout({label:"Bloom Upscale Render PSO Layout",bindGroupLayouts:[this.bindGroupLayout]}),vertex:{entryPoint:_t,module:J.createShaderModule(zt)},fragment:{entryPoint:Gc,module:J.createShaderModule(Fp),targets:[{format:"rgba16float",blend:{color:{operation:"add",srcFactor:"one",dstFactor:"one"},alpha:{operation:"add",srcFactor:"one",dstFactor:"one"}}}]}})}render(e,t,r){const n=[{binding:0,resource:null},{binding:1,resource:this.sampler},{binding:2,resource:{buffer:this.filterRadiusBuffer}}],i={colorAttachments:[{loadOp:"load",storeOp:"store",view:null}]};for(let o=Math.ceil(.5*Pt(r[0].width,r[0].height))-1;o>0;o--){i.label=`Bloom Upscale Mip Level ${o}`,i.colorAttachments[0].view=r[0].createView({baseMipLevel:o-1,mipLevelCount:1});const u=e.beginRenderPass(i);u.setPipeline(this.renderPSO),n[0].resource=r[0].createView({baseMipLevel:o,mipLevelCount:1});const l=B.device.createBindGroup({label:`Bloom Upscale Bind Group for Mip ${o}`,entries:n,layout:this.bindGroupLayout});u.setBindGroup(0,l),u.draw(3),u.end()}return this.postRender(e),r}}const Lc=s=>At` - @must_use - fn DistributionGGX(viewSpaceNormal: vec3f, H: vec3f, roughness: f32) -> f32 { - let a = roughness*roughness; - let a2 = a*a; - let NdotH = max(dot(viewSpaceNormal, H), 0.0); - let NdotH2 = NdotH*NdotH; - - let nom = a2; - var denom = (NdotH2 * (a2 - 1.0) + 1.0); - denom = PI * denom * denom + 0.0001; - - return nom / denom; -} - - @must_use - fn GeometrySchlickGGX(NdotV: f32, roughness: f32) -> f32 { - let r = (roughness + 1.0); - let k = (r * r) / 8; - - let nom = NdotV; - let denom = NdotV * (1.0 - k) + k + 0.0001; - return nom / denom; - } - - @must_use - fn GeometrySmith(viewSpaceNormal: vec3f, V: vec3f, L: vec3f, roughness: f32) -> f32 { - let NdotV = max(dot(viewSpaceNormal, V), 0.0); - let NdotL = max(dot(viewSpaceNormal, L), 0.0); - let ggx2 = GeometrySchlickGGX(NdotV, roughness); - let ggx1 = GeometrySchlickGGX(NdotL, roughness); - return ggx1 * ggx2; - } - - @must_use - fn FresnelSchlick(cosTheta: f32, F0: vec3f) -> vec3f { - return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0); - } - - @must_use - fn FresnelSchlickRoughness(cosTheta: f32, F0: vec3f, roughness: f32) -> vec3f { - return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0); - } - - @must_use - fn PBRLighting( - material: Material, - instanceId: u32, - viewSpacePos: vec3f, - viewSpaceNormal: vec3f, - V: vec3f, - shadow: f32, - opacity: f32, - #if ${s===N.PointLightsNonCulledLighting} - lightPosition: vec3f, - lightRadius: f32, - lightColor: vec3f, - lightIntensity: f32, - #elif ${s===N.DirectionalAmbientLighting} - diffuseIBLTexture: texture_cube, - specularIBLTexture: texture_cube, - bdrfLutTexture: texture_2d, - envTexSampler: sampler, - #endif - ) -> vec4f { - let albedo = material.albedo; - let F0 = mix(vec3f(0.04), albedo, material.metallic); - - var Lo = vec3f(0.0); - let albedoOverPi = albedo / PI; - - let roughness = material.roughness; - let roughnessSq = roughness * roughness; - let roughnessQuad = roughnessSq * roughnessSq; - - let metallic = material.metallic; - - #if ${s===N.DirectionalAmbientLighting} - let light = &lightsBuffer[instanceId]; - // let isPointLight = light.lightType == ${It.Point}; - let lightViewSpacePos = (camera.viewMatrix * vec4f(light.position, 0.0)).xyz; - - let lightColor = light.color; - let lightIntensity = light.intensity; - let L = normalize(lightViewSpacePos); - let attenuation = 1.0; - - // return vec4f(vec3f(shadow), 1.0) - - #elif ${s===N.PointLightsLighting} - let light = &lightsBuffer[instanceId]; - let lightColor = light.color; - let lightIntensity = light.intensity; - let lightViewSpacePos = (camera.viewMatrix * vec4f(light.position, 1.0)).xyz; - let dist = lightViewSpacePos.xyz - viewSpacePos.xyz; - let d = length(dist); - var attenuation = 1 - smoothstep(0.0, light.radius, d); - attenuation *= attenuation; - let L = normalize(dist); - #elif ${s===N.PointLightsNonCulledLighting} - let lightViewSpacePos = (camera.viewMatrix * vec4f(lightPosition, 1)).xyz; - let dist = lightViewSpacePos.xyz - viewSpacePos.xyz; - let d = length(dist); - var attenuation = 1 - smoothstep(0.0, lightRadius, d); - attenuation *= attenuation; - let L = normalize(dist); - #endif - - - let H = normalize(V + L); - - let radiance = lightColor * attenuation * lightIntensity; - - let NDF = DistributionGGX(viewSpaceNormal, H, roughnessQuad); - let G = GeometrySmith(viewSpaceNormal, V, L, roughness); - var F = FresnelSchlick(max(dot(H, V), 0.0), F0); - - let numerator = NDF * G * F; - // let denominator = 4.0 * (NdotV * NdotL, 0.0001); // + 0.0001 to prevent divide by zero - let denominator = 4.0 * max(dot(viewSpaceNormal, V), 0.0) * max(dot(viewSpaceNormal, L), 0.0) + 0.0001; // + 0.0001 to prevent divide by zero - - var specular = numerator / denominator; - - // kS is equal to Fresnel - var kS = F; - // for energy conservation, the diffuse and specular light can't - // be above 1.0 (unless the surface emits light); to preserve this - // relationship the diffuse component (kD) should equal 1.0 - kS. - var kD = vec3f(1.0 - kS); - // multiply kD by the inverse metalness such that only non-metals - // have diffuse lighting, or a linear blend if partly metal (pure metals - // have no diffuse light). - kD *= 1.0 - metallic; - - let NdotL = max(dot(viewSpaceNormal, L), 0.0); - - // add to outgoing radiance Lo - Lo += (kD * albedoOverPi + specular) * radiance * NdotL * shadow; // * light.opacity; // note that we already multiplied the BRDF by the Fresnel - - #if ${s===N.DirectionalAmbientLighting} - let worldSpaceNorm = (camera.inverseViewMatrix * vec4f(viewSpaceNormal, 0)).xyz; - let worldSpaceV = (camera.inverseViewMatrix * vec4f(V, 0)).xyz; - let irradiance = textureSampleLevel(diffuseIBLTexture, envTexSampler, worldSpaceNorm, 0).rgb; - kS = FresnelSchlickRoughness(max(dot(viewSpaceNormal, V), 0.0), F0, roughness); - kD = 1.0 - kS; - kD *= 1.0 - metallic; - // let ambientIBL = kD * irradiance; - // let ambientFactor = 0.2; - - let R = reflect(-worldSpaceV, worldSpaceNorm); - let MAX_REFLECTION_LOD = 8.0; - let prefilteredColor = vec3f( - textureSampleLevel( - specularIBLTexture, - envTexSampler, - R, - material.roughness * MAX_REFLECTION_LOD - ).rgb - ); - - let uv = vec2f(max(dot(worldSpaceNorm, worldSpaceV), 0.0), roughness); - let envBDRF = textureSample(bdrfLutTexture, envTexSampler, uv).rg; - specular = prefilteredColor * (F * envBDRF.x + envBDRF.y); - // specular = mix(specular, specular * 0.2, 1 - shadow); - - let diffuse = irradiance * albedo; - let ambient = (kD * diffuse + specular * metallic) * material.ambientOcclusion; - - // let ambient = vec3f(0.03) * albedo * material.ambientOcclusion; - - var color = ambient + Lo; - #else - var color = Lo; - #endif - - return vec4f(color, opacity); - } -`,Re=class Re extends Te{constructor(e,t,r){super(N.Shadow,t,r),this.sceneDirectionalLight=e,this.type=N.Shadow,this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({colorAttachments:[],depthStencilAttachment:{view:null,depthClearValue:1,depthLoadOp:"clear",depthStoreOp:"store"},label:"Shadow Render Pass Cascade #0"}),this.outTextures.push(B.device.createTexture({label:"Directional Shadow Depth Texture",format:"depth32float",size:{width:Re.TEXTURE_SIZE,height:Re.TEXTURE_SIZE,depthOrArrayLayers:Re.TEXTURE_CASCADES_COUNT},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING})),Y.addTextureBytes(this.outTextures[0]),this.shadowTextureCascade0=this.outTextures[0].createView({baseArrayLayer:0,arrayLayerCount:1,dimension:"2d"}),this.shadowTextureCascade1=this.outTextures[0].createView({baseArrayLayer:1,arrayLayerCount:1,dimension:"2d"});const n=Ot(W.Camera);this.shadowCameraCascade0BufferUniformValues=yt(n.structs.Camera),this.shadowCameraCascade1BufferUniformValues=yt(n.structs.Camera),this.shadowCameraCascade0GPUBuffer=B.device.createBuffer({label:"Shadow Camera GPU Buffer Cascade #0",size:this.shadowCameraCascade0BufferUniformValues.arrayBuffer.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),Y.addBufferBytes(this.shadowCameraCascade0GPUBuffer),this.shadowCameraCascade1GPUBuffer=B.device.createBuffer({label:"Shadow Camera GPU Buffer Cascade #1",size:this.shadowCameraCascade1BufferUniformValues.arrayBuffer.byteLength,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),Y.addBufferBytes(this.shadowCameraCascade1GPUBuffer),this.shadowCameraCascade0BindGroup=B.device.createBindGroup({label:"Shadow Camera Bind Group Cascade #0",layout:J.defaultCameraBindGroupLayout,entries:[{binding:0,resource:{buffer:this.shadowCameraCascade0GPUBuffer}}]}),this.shadowCameraCascade1BindGroup=B.device.createBindGroup({label:"Shadow Camera Bind Group Cascade #1",layout:J.defaultCameraBindGroupLayout,entries:[{binding:0,resource:{buffer:this.shadowCameraCascade1GPUBuffer}}]});const i=Ot(W.ShadowCascade);this.shadowCascadeView=yt(i.structs.ShadowCascade),this.shadowCascadesBuffer=B.device.createBuffer({label:"Directional Shadow Cascade ProjView Matrices",size:Re.TEXTURE_CASCADES_COUNT*this.shadowCascadeView.arrayBuffer.byteLength,usage:GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_DST}),Y.addBufferBytes(this.shadowCascadesBuffer)}set shadowMapSize(e){const t=this.outTextures[0];this.outTextures[0]=B.device.createTexture({label:"Directional Shadow Depth Texture",format:"depth32float",size:{width:e,height:e,depthOrArrayLayers:Re.TEXTURE_CASCADES_COUNT},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),this.shadowTextureCascade0=this.outTextures[0].createView({baseArrayLayer:0,arrayLayerCount:1,dimension:"2d"}),this.shadowTextureCascade1=this.outTextures[0].createView({baseArrayLayer:1,arrayLayerCount:1,dimension:"2d"}),Y.addTextureBytes(this.outTextures[0]),B.device.queue.onSubmittedWorkDone().then(()=>{Y.removeTextureBytes(t),t.destroy()})}async destroy(){super.destroy(),await B.device.queue.onSubmittedWorkDone(),Y.removeBufferBytes(this.shadowCascadesBuffer),Y.removeBufferBytes(this.shadowCameraCascade0GPUBuffer),Y.removeBufferBytes(this.shadowCameraCascade1GPUBuffer),this.shadowCascadesBuffer.destroy(),this.shadowCameraCascade0GPUBuffer.destroy(),this.shadowCameraCascade1GPUBuffer.destroy()}setCamera(e){return this.camera=e,this}getLightSpaceMatrix(){const e=this.camera.frustumCornersWorldSpace,t=D.create(0,0,0);for(let f=0;f{return At` - ${W.VertexOutput} - ${W.Light} - ${W.Camera} - ${W.Material} - ${W.ShadowCascade} - ${W.CommonHelpers} - ${W.MathHelpers} - - ${Lc(s)} - ${` - - @must_use - fn ShadowLayerIdxCalculate( - worldPos: vec3f, - camera: Camera, - shadowCascades: array - ) -> i32 { - let fragPosViewSpace = camera.viewMatrix * vec4f(worldPos, 1.0); - let depthValue = abs(fragPosViewSpace.z); - - var layer: i32 = -1; - let cascadesCount: i32 = 2; - for (var i: i32 = 0; i < cascadesCount; i++) { - if (depthValue < shadowCascades[i].distance) { - layer = i; - break; - } - } - - if (layer == -1) { - layer = 1; - } - return layer; - } - - fn ShadowCalculate( - worldPos: vec3f, - N: vec3f, - lightPosition: vec3f, - camera: Camera, - shadowTextureWidth: f32, - shadowTextureHeight: f32, - shadowCascades: array, - shadowDepthTexture: texture_depth_2d_array, - shadowDepthSampler: sampler_comparison - ) -> f32 { - - let layer = ShadowLayerIdxCalculate( - worldPos, - camera, - shadowCascades - ); - let fragPosLightSpace = shadowCascades[layer].projViewMatrix * vec4f(worldPos, 1.0); - - // perform perspective divide - var projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w; - projCoords.x = projCoords.x * 0.5 + 0.5; - projCoords.y = projCoords.y * 0.5 + 0.5; - projCoords.y = 1 - projCoords.y; - let uv = projCoords.xy; - - var shadow = 0.0; - - let texelSize = 1 / vec2f(shadowTextureWidth, shadowTextureHeight); - - for (var y = -2; y <= 2; y++) { - for (var x = -2; x <= 2; x++) { - let uv = projCoords.xy + vec2f(f32(x), f32(y)) * texelSize; - let pcfDepth = textureSampleCompareLevel( - shadowDepthTexture, - shadowDepthSampler, - uv, - layer, - projCoords.z - ); - shadow += pcfDepth; - } - } - - shadow /= 16; - - return shadow; - } -`} - ${kr} - - struct LightSettings { - debugLights: f32, - debugShadowCascadeLayer: f32 - }; - - #if ${s===N.DirectionalAmbientLighting} - const SHADOW_MAP_SIZE: f32 = ${Ys.TEXTURE_SIZE}; - #endif - - ${e=s,At` - @group(0) @binding(0) var normalTexture: texture_2d; - @group(0) @binding(1) var colorTexture: texture_2d; - @group(0) @binding(2) var depthTexture: texture_depth_2d; - @group(0) @binding(3) var aoTexture: texture_2d; - @group(0) @binding(4) var camera: Camera; - - #if ${e===N.PointLightsLighting||e===N.PointLightsStencilMask||e===N.DirectionalAmbientLighting} - @group(0) @binding(5) var lightsBuffer: array; - @group(0) @binding(6) var debugLightsInfo: LightSettings; - #endif - - #if ${e===N.PointLightsNonCulledLighting} - @group(1) @binding(0) var cameraCulledPointLight: Light; - #endif - - #if ${e===N.DirectionalAmbientLighting} - @group(1) @binding(0) var shadowCascades: array; - @group(1) @binding(1) var shadowMapSampler: sampler_comparison; - @group(1) @binding(2) var shadowDepthTexture: texture_depth_2d_array; - @group(1) @binding(3) var diffuseIBLTexture: texture_cube; - @group(1) @binding(4) var specularIBLTexture: texture_cube; - @group(1) @binding(5) var bdrfLutTexture: texture_2d; - @group(1) @binding(6) var envTexSampler: sampler; - @group(1) @binding(7) var ssaoMixFactor: f32; - #endif -`} - - @fragment - fn ${Ws}( - in: VertexOutput - ) -> @location(0) vec4f { - let coord = in.position; - let pixelCoords = vec2i(floor(coord.xy)); - let encodedN = textureLoad(normalTexture, pixelCoords, 0).rg; - let metallic = textureLoad(normalTexture, pixelCoords, 0).b; - let roughness = textureLoad(normalTexture, pixelCoords, 0).a; - let viewSpaceNormal = decodeNormal(encodedN); - - let albedo = textureLoad(colorTexture, pixelCoords, 0).xyz; - let depth = textureLoad(depthTexture, pixelCoords, 0); - - let aoPixelCoords = vec2i(floor(coord.xy)); - let ao = textureLoad(aoTexture, aoPixelCoords, 0).r; - // return vec4f(ao, ao, ao, 1); - - // return vec4f(viewSpaceNormal, 1.0); - - - var material = Material(); - material.albedo = albedo; - material.roughness = roughness; - // return vec4f(vec3f(1 - metallic), 1); - material.metallic = metallic; - // material.ambientOcclusion = select(1.0, ao, pixelCoords.x > i32(textureDimensions(normalTexture).x / 2)); - - #if ${s===N.DirectionalAmbientLighting} - material.ambientOcclusion = mix(1.0, ao, ssaoMixFactor); - #endif - - let viewSpacePos = calcViewSpacePos(camera, coord.xy, depth); - - let V = normalize(-viewSpacePos); - - #if ${s===N.DirectionalAmbientLighting} - let worldSpacePos = calcWorldPos(camera, coord.xy, depth); - let shadowLayerIdx = ShadowLayerIdxCalculate(worldSpacePos, camera, shadowCascades); - let r = select(0.0, 1.0, shadowLayerIdx == 0); - let g = select(0.0, 1.0, shadowLayerIdx == 1); - let b = select(0.0, 1.0, shadowLayerIdx == 2); - if (debugLightsInfo.debugShadowCascadeLayer == 1) { - material.albedo = vec3f(r, g, b); - } - // TODO: Directional light is expected to be at index 0 - // Write a better mechanism for quering it - let lightPosition = (camera.viewMatrix * (vec4f(lightsBuffer[0].position, 0))).xyz; - // let shadow = 1.0; - let shadow = ShadowCalculate( - worldSpacePos, - viewSpaceNormal, - lightPosition, - camera, - SHADOW_MAP_SIZE, - SHADOW_MAP_SIZE, - shadowCascades, - shadowDepthTexture, - shadowMapSampler - ); - #else - let shadow = 1.0; - #endif - - let opacity = 1.0; - - var color = PBRLighting( - material, - in.instanceId, - viewSpacePos, - viewSpaceNormal, - V, - shadow, - opacity, - #if ${s===N.PointLightsNonCulledLighting} - cameraCulledPointLight.position, - cameraCulledPointLight.radius, - cameraCulledPointLight.color, - cameraCulledPointLight.intensity, - #elif ${s==N.DirectionalAmbientLighting} - diffuseIBLTexture, - specularIBLTexture, - bdrfLutTexture, - envTexSampler - #endif - ); - - #if ${s===N.PointLightsLighting} - let debugColor = vec4f(1.0, 0.0, 0.0, 1.0); - return mix(color, debugColor, debugLightsInfo.debugLights); - #else - return color; - #endif - } -`;var e},ho=class ho extends Te{constructor(e,t,r){super(e,t,r),this.gbufferCommonBindGroupLayoutEntries=[],this.gbufferTexturesBindGroupEntries=[],this._debugLightsMask=!1,this._debugShadowCascadeLayer=!1,this.gbufferCommonBindGroupLayoutEntries.push({binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{}}),this.gbufferCommonBindGroupLayoutEntries.push({binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}}),this.gbufferCommonBindGroupLayoutEntries.push({binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth"}}),this.gbufferCommonBindGroupLayoutEntries.push({binding:3,visibility:GPUShaderStage.FRAGMENT,texture:{}}),this.gbufferCommonBindGroupLayoutEntries.push({binding:4,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}),e!==N.PointLightsLighting&&e!==N.DirectionalAmbientLighting&&e!==N.PointLightsStencilMask||(this.gbufferCommonBindGroupLayoutEntries.push({binding:5,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}}),this.gbufferCommonBindGroupLayoutEntries.push({binding:6,visibility:GPUShaderStage.VERTEX|GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}})),this.gbufferCommonBindGroupLayout=B.device.createBindGroupLayout({label:"GBuffer Textures Bind Group",entries:this.gbufferCommonBindGroupLayoutEntries}),this.debugLightsBuffer=B.device.createBuffer({label:"Debug Lights GPUBuffer",size:4*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),Y.addBufferBytes(this.debugLightsBuffer),new Float32Array(this.debugLightsBuffer.getMappedRange()).set(new Float32Array([0,0])),this.debugLightsBuffer.unmap(),this.gbufferTexturesBindGroupEntries.push({binding:0,resource:null}),this.gbufferTexturesBindGroupEntries.push({binding:1,resource:null}),this.gbufferTexturesBindGroupEntries.push({binding:2,resource:null}),this.gbufferTexturesBindGroupEntries.push({binding:3,resource:null}),this.gbufferTexturesBindGroupEntries.push({binding:4,resource:{buffer:null}}),e!==N.DirectionalAmbientLighting&&e!==N.PointLightsLighting&&e!==N.PointLightsStencilMask||(this.gbufferTexturesBindGroupEntries.push({binding:5,resource:{buffer:null}}),this.gbufferTexturesBindGroupEntries.push({binding:6,resource:{buffer:this.debugLightsBuffer}}))}set debugLightsMask(e){this._debugLightsMask=e,this.updateLightSettingsBuffer()}set debugShadowCascadeLayer(e){this._debugShadowCascadeLayer=e,this.updateLightSettingsBuffer()}updateLightSettingsBuffer(){B.device.queue.writeBuffer(this.debugLightsBuffer,0,new Float32Array([this._debugLightsMask?1:0,this._debugShadowCascadeLayer?1:0]))}updateGbufferBindGroupEntryAt(e,t){return this.gbufferTexturesBindGroupEntries[e].resource=t,this}recreateGBufferTexturesBindGroup(){this.gbufferTexturesBindGroup=B.device.createBindGroup({label:"G-Buffer Textures Input Bind Group",layout:this.gbufferCommonBindGroupLayout,entries:this.gbufferTexturesBindGroupEntries})}};ho.RENDER_TARGETS=[{format:"rgba16float",blend:{color:{srcFactor:"one",dstFactor:"one",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one",operation:"add"}}}];let gr=ho;class Wi extends gr{constructor(e,t,r){super(N.DirectionalAmbientLighting,t,r),this.shadowCascadesBuffer=e,this.dirLightShadowBindGroupEntries=[],this.shadowSampler=Je.createSampler({minFilter:"linear",magFilter:"linear",mipmapFilter:"linear",compare:"less"}),this.envSampler=Je.createSampler({minFilter:"linear",magFilter:"linear",mipmapFilter:"linear"}),this.ssaoMixBuffer=B.device.createBuffer({label:"Ambient SSAO Mix Factor Buffer",usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,size:1*Float32Array.BYTES_PER_ELEMENT,mappedAtCreation:!0}),Y.addBufferBytes(this.ssaoMixBuffer),new Float32Array(this.ssaoMixBuffer.getMappedRange()).set([1]),this.ssaoMixBuffer.unmap();const n=[{binding:0,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"read-only-storage"}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"comparison"}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"depth",viewDimension:"2d-array"}},{binding:3,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"cube"}},{binding:4,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"cube"}},{binding:5,visibility:GPUShaderStage.FRAGMENT,texture:{viewDimension:"2d"}},{binding:6,visibility:GPUShaderStage.FRAGMENT,sampler:{type:"filtering"}},{binding:7,visibility:GPUShaderStage.FRAGMENT,buffer:{type:"uniform"}}];this.dirLightShadowBindGroupLayout=B.device.createBindGroupLayout({label:"Direcional Light Shadow Bind Group Layout",entries:n});const i=B.device.createPipelineLayout({label:"Dir Light PSO Layout",bindGroupLayouts:[this.gbufferCommonBindGroupLayout,this.dirLightShadowBindGroupLayout]});this.dirLightShadowBindGroupEntries=[{binding:0,resource:{buffer:this.shadowCascadesBuffer}},{binding:1,resource:this.shadowSampler},{binding:2,resource:Be.dummyTexture.createView({})},{binding:3,resource:Be.dummyCubeTexture.createView({dimension:"cube"})},{binding:4,resource:Be.dummyCubeTexture.createView({dimension:"cube"})},{binding:5,resource:Be.dummyTexture.createView({})},{binding:6,resource:this.envSampler},{binding:7,resource:{buffer:this.ssaoMixBuffer}}];const o={label:"Directional Light Render PSO",layout:i,vertex:{module:J.createShaderModule(zt,"Fullscreen Vertex Shader Module"),entryPoint:_t},fragment:{module:J.createShaderModule(Yi(N.DirectionalAmbientLighting),"Directional Light Pass Shader Module"),entryPoint:Ws,targets:Wi.RENDER_TARGETS},depthStencil:{format:B.depthStencilFormat,depthWriteEnabled:!1}};this.renderPSO=J.createRenderPipeline(o),this.outTextures.push(B.device.createTexture({dimension:"2d",format:"rgba16float",mipLevelCount:1,sampleCount:1,size:{width:t,height:r,depthOrArrayLayers:1},usage:GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,label:"GBuffer Result Texture"})),Y.addTextureBytes(this.outTextures[0]),this.outTextureView=this.outTextures[0].createView()}set ssaoMixFactor(e){B.device.queue.writeBuffer(this.ssaoMixBuffer,0,new Float32Array([e]))}setDiffuseIBLTexture(e){return this.dirLightShadowBindGroupEntries[3].resource=e.createView({dimension:"cube"}),this.recreateDirLightShadowBindGroup(),this}setSpecularIBLTexture(e){return this.dirLightShadowBindGroupEntries[4].resource=e.createView({dimension:"cube"}),this.recreateDirLightShadowBindGroup(),this}setBDRFLutTexture(e){return this.dirLightShadowBindGroupEntries[5].resource=e.createView({dimension:"2d"}),this.recreateDirLightShadowBindGroup(),this}createRenderPassDescriptor(){if(this.renderPassDescriptor)return this.renderPassDescriptor;const e=[{view:this.outTextureView,loadOp:"clear",clearValue:[0,0,0,1],storeOp:"store"}];return this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({label:"Directional + Ambient Render Pass",colorAttachments:e,depthStencilAttachment:{depthReadOnly:!0,stencilReadOnly:!1,view:this.inputTextureViews[3],stencilLoadOp:"load",stencilStoreOp:"store"}}),this.renderPassDescriptor}recreateDirLightShadowBindGroup(){this.dirLightShadowBindGroup=B.device.createBindGroup({label:"Directional Ambient LightingSystem G-Buffer Directional Shadow Input Bind Group",layout:this.dirLightShadowBindGroupLayout,entries:this.dirLightShadowBindGroupEntries})}render(e,t,r){this.inputTextureViews.length||(this.inputTextureViews.push(r[0].createView()),this.inputTextureViews.push(r[1].createView()),this.inputTextureViews.push(r[2].createView({aspect:"depth-only"})),this.inputTextureViews.push(r[2].createView({aspect:"all"})),this.inputTextureViews.push(r[3].createView()),this.inputTextureViews.push(r[4].createView({dimension:"2d-array"})),this.updateGbufferBindGroupEntryAt(0,this.inputTextureViews[0]).updateGbufferBindGroupEntryAt(1,this.inputTextureViews[1]).updateGbufferBindGroupEntryAt(2,this.inputTextureViews[2]).updateGbufferBindGroupEntryAt(3,this.inputTextureViews[4]).updateGbufferBindGroupEntryAt(4,{buffer:this.camera.gpuBuffer}).updateGbufferBindGroupEntryAt(5,{buffer:t.lightingManager.gpuBuffer}).recreateGBufferTexturesBindGroup(),this.dirLightShadowBindGroupEntries[2].resource=this.inputTextureViews[5],this.recreateDirLightShadowBindGroup());const n=e.beginRenderPass(this.createRenderPassDescriptor());return B.setActiveRenderPass(this.type,n),B.ENABLE_DEBUG_GROUPS&&n.pushDebugGroup("Begin Directional + Ambient LightingSystem"),B.bindRenderPSO(this.renderPSO),n.setBindGroup(0,this.gbufferTexturesBindGroup),n.setBindGroup(1,this.dirLightShadowBindGroup),n.draw(3),B.ENABLE_DEBUG_GROUPS&&n.popDebugGroup(),n.end(),this.postRender(e),this.outTextures}}class Up extends Te{constructor(e,t){super(N.Deferred,e,t),this.outTextures.push(B.device.createTexture({dimension:"2d",format:"rgba16float",mipLevelCount:1,sampleCount:1,size:{width:e,height:t,depthOrArrayLayers:1},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,label:"Normal + Metallic + Roughness + GBuffer Texture"})),this.outTextures.push(B.device.createTexture({dimension:"2d",format:"bgra8unorm",mipLevelCount:1,sampleCount:1,size:{width:e,height:t,depthOrArrayLayers:1},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,label:"Color + Reflectance GBuffer Texture"})),this.outTextures.push(B.device.createTexture({dimension:"2d",format:"rg16float",mipLevelCount:1,sampleCount:1,size:{width:e,height:t,depthOrArrayLayers:1},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,label:"Velocity GBuffer Texture"})),this.outTextures.push(B.device.createTexture({dimension:"2d",format:B.depthStencilFormat,mipLevelCount:1,sampleCount:1,size:{width:e,height:t,depthOrArrayLayers:1},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING,label:"Depth + Stencil GBuffer Texture"}));for(const r of this.outTextures)Y.addTextureBytes(r)}createRenderPassDescriptor(){if(this.renderPassDescriptor)return this.renderPassDescriptor;const e=[{view:this.outTextures[ut.NormalMetallicRoughness].createView(),loadOp:"clear",clearValue:[0,0,0,0],storeOp:"store"},{view:this.outTextures[ut.ColorReflectance].createView(),loadOp:"clear",clearValue:[0,0,0,0],storeOp:"store"},{view:this.outTextures[ut.Velocity].createView(),loadOp:"clear",clearValue:[0,0,0,0],storeOp:"store"}];return this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({colorAttachments:e,depthStencilAttachment:{view:this.outTextures[3].createView(),depthLoadOp:"clear",depthStoreOp:"store",depthClearValue:1,stencilLoadOp:"clear",stencilStoreOp:"store",stencilClearValue:0},label:"GBuffer Render Pass"}),this.renderPassDescriptor}render(e,t,r){const n=this.createRenderPassDescriptor(),i=e.beginRenderPass(n);return B.setActiveRenderPass(this.type,i),B.ENABLE_DEBUG_GROUPS&&i.pushDebugGroup("Render G-Buffer"),i.setBindGroup(ue.CameraPlusOptionalLights,this.cameraBindGroup),i.setStencilReference(128),t.renderOpaqueNodes(i,this.camera),B.ENABLE_DEBUG_GROUPS&&i.popDebugGroup(),i.end(),this.postRender(e),this.outTextures}}const Oc="copyDepth",kp=` - - @group(0) @binding(0) var sourceDepth: texture_depth_2d; - @group(0) @binding(1) var destDepth: texture_storage_2d; - - override WORKGROUP_SIZE_X: u32; - override WORKGROUP_SIZE_Y: u32; - - @compute @workgroup_size(WORKGROUP_SIZE_X, WORKGROUP_SIZE_Y) - fn ${Oc}( - @builtin(global_invocation_id) pos : vec3u - ) { - let texSize = textureDimensions(sourceDepth); - - if (any(pos.xy > texSize)) { - return; - } - - let src = textureLoad(sourceDepth, pos.xy, 0); - textureStore(destDepth, pos.xy, vec4f(src)); - } - -`,St=class St extends Te{constructor(e,t){super(N.CopyDepthForHiZ,e,t);const r=[{binding:0,texture:{sampleType:"depth"},visibility:GPUShaderStage.COMPUTE},{binding:1,storageTexture:{access:"write-only",format:"r32float",viewDimension:"2d"},visibility:GPUShaderStage.COMPUTE}];this.bindGroupLayout=B.device.createBindGroupLayout({label:"Hi-Z Copy Depth Bind Group Layout",entries:r}),this.computePSO=J.createComputePipeline({label:"Hi-Z Copy Depth Compute PSO",layout:B.device.createPipelineLayout({label:"Hi-Z Copy Depth Compute PSO Layout",bindGroupLayouts:[this.bindGroupLayout]}),compute:{entryPoint:Oc,module:J.createShaderModule(kp,"Hi-Z Depth Copy Compute Shader Module"),constants:{WORKGROUP_SIZE_X:St.COMPUTE_WORKGROUP_SIZE_X,WORKGROUP_SIZE_Y:St.COMPUTE_WORKGROUP_SIZE_Y}}}),this.outTextures.push(B.device.createTexture({label:"Hi-Z Depth Texture",size:{width:e,height:t},usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING,format:"r32float",mipLevelCount:Pt(e,t)})),Y.addTextureBytes(this.outTextures[0])}createComputePassDescriptor(){return this.computePassDescriptor||(this.computePassDescriptor={label:"Copy Hi-Z Depth Compute Pass"}),this.computePassDescriptor}render(e,t,r){if(!this.inputTextureViews.length){this.inputTextureViews.push(r[0].createView({aspect:"depth-only"}));const u=[{binding:0,resource:this.inputTextureViews[0]},{binding:1,resource:this.outTextures[0].createView({baseMipLevel:0,mipLevelCount:1})}];this.bindGroup=B.device.createBindGroup({label:"Hi-Z Depth Copy Bind Group",layout:this.bindGroupLayout,entries:u})}const n=e.beginComputePass(this.createComputePassDescriptor());n.setPipeline(this.computePSO),n.setBindGroup(0,this.bindGroup);const i=Math.ceil(this.outTextures[0].width/St.COMPUTE_WORKGROUP_SIZE_X),o=Math.ceil(this.outTextures[0].height/St.COMPUTE_WORKGROUP_SIZE_Y);return n.dispatchWorkgroups(i,o,1),n.end(),this.postRender(e),this.outTextures}};St.COMPUTE_WORKGROUP_SIZE_X=8,St.COMPUTE_WORKGROUP_SIZE_Y=8;let $i=St;const Ic="computeHiZMips",Np=` - @group(0) @binding(0) var prevMipLevel: texture_2d; - @group(0) @binding(1) var nextMipLevel: texture_storage_2d; - - override WORKGROUP_SIZE_X: u32; - override WORKGROUP_SIZE_Y: u32; - - @compute @workgroup_size(WORKGROUP_SIZE_X, WORKGROUP_SIZE_Y) - fn ${Ic}(@builtin(global_invocation_id) pos : vec3u) { - let texSize = textureDimensions(prevMipLevel); - if (any(pos.xy > texSize)) { - return; - } - - let depthDim = vec2f(textureDimensions(prevMipLevel).xy); - let outDepthDim = vec2f(textureDimensions(nextMipLevel).xy); - - let ratio = depthDim / outDepthDim; - - let vReadCoord = vec2u(pos.x << 1, pos.y << 1); - let vWriteCoord = pos.xy; - - let depthSamples = vec4f( - textureLoad(prevMipLevel, vReadCoord, 0).r, - textureLoad(prevMipLevel, vReadCoord + vec2u(1, 0), 0).r, - textureLoad(prevMipLevel, vReadCoord + vec2u(0, 1), 0).r, - textureLoad(prevMipLevel, vReadCoord + vec2u(1, 1), 0).r - ); - - var minDepth = min( - depthSamples.x, - min( - depthSamples.y, - min(depthSamples.z, depthSamples.w) - ) - ); - - let needExtraSampleX = ratio.x > 2.01; - let needExtraSampleY = ratio.y > 2.01; - - minDepth = select( - minDepth, - min( - minDepth, - min( - textureLoad(prevMipLevel, vReadCoord + vec2u(2, 0), 0).r, - textureLoad(prevMipLevel, vReadCoord + vec2u(2, 1), 0).r - ) - ), - needExtraSampleX - ); - minDepth = select( - minDepth, - min( - minDepth, - min( - textureLoad(prevMipLevel, vReadCoord + vec2u(0, 2), 0).r, - textureLoad(prevMipLevel, vReadCoord + vec2u(1, 2), 0).r - ) - ), - needExtraSampleY - ); - minDepth = select( - minDepth, - min( - minDepth, - textureLoad(prevMipLevel, vReadCoord + vec2u(2, 2), 0).r - ), - needExtraSampleX && needExtraSampleY - ); - - textureStore(nextMipLevel, pos.xy, vec4f(minDepth)); - - } -`,it=class it extends Te{constructor(e,t){super(N.HiZ,e,t),this.mipTexSizes=[],this.mipTexViews=[];const r=[{binding:0,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"unfilterable-float"}},{binding:1,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"r32float",viewDimension:"2d"}}];this.bindGroupLayout=B.device.createBindGroupLayout({label:"Hi-Z Bind Group Layout",entries:r}),this.computePSO=J.createComputePipeline({label:"Hi-Z Compute PSO",layout:B.device.createPipelineLayout({label:"Hi-Z Compute PSO Layout",bindGroupLayouts:[this.bindGroupLayout]}),compute:{entryPoint:Ic,module:J.createShaderModule(Np,"Compute Hi-Z Shader Module"),constants:{WORKGROUP_SIZE_X:it.COMPUTE_WORKGROUP_SIZE_X,WORKGROUP_SIZE_Y:it.COMPUTE_WORKGROUP_SIZE_Y}}})}createComputePassDescriptor(){return this.computePassDescriptor||(this.computePassDescriptor={label:"Hi-Z Depth Mip Compute Pass"}),this.computePassDescriptor}render(e,t,r){const n=r[0].mipLevelCount,i=r[0].width,o=r[0].height;if(!this.mipTexSizes.length){this.mipTexSizes.push(Se.create(i,o));for(let b=1;bAt` - - ${W.VertexInput} - ${W.VertexOutput} - ${W.Camera} - ${W.Light} - - #if ${s===N.PointLightsStencilMask} - @group(0) @binding(0) var camera: Camera; - @group(0) @binding(1) var lightsBuffer: array; - #else - @group(0) @binding(0) var normalTexture: texture_2d; - @group(0) @binding(1) var colorTexture: texture_2d; - @group(0) @binding(2) var depthTexture: texture_depth_2d; - @group(0) @binding(3) var aoTexture: texture_2d; - @group(0) @binding(4) var camera: Camera; - #endif - - #if ${s===N.PointLightsLighting||s===N.DirectionalAmbientLighting} - @group(0) @binding(5) var lightsBuffer: array; - @group(0) @binding(6) var debugLights: f32; - #endif - - #if ${s===N.PointLightsNonCulledLighting} - - @group(1) @binding(0) var cameraCulledPointLight: Light; - - #endif - - @vertex - fn ${$s}( - @builtin(instance_index) instanceId: u32, - in: VertexInput - ) -> VertexOutput { - #if ${s===N.PointLightsNonCulledLighting} - let light = cameraCulledPointLight; - let trueInstanceId = 0u; - #else - let trueInstanceId = instanceId; - let light = lightsBuffer[trueInstanceId]; - #endif - - var position = in.position; - position *= vec4f(vec3f(light.radius), 1.0); - position += vec4f(light.position, 0.0); - let pos = camera.projectionViewMatrix * position; - - var out: VertexOutput; - out.position = pos; - out.instanceId = trueInstanceId; - return out; - } -`;class Vp extends gr{setCamera(e){return this.camera=e,this.lightsMaskBindGroupEntries[0].resource={buffer:e.gpuBuffer},this}setLightsBuffer(e){return this.lightsMaskBindGroupEntries[1].resource={buffer:e},this}updateLightsMaskBindGroup(){return this.lightsMaskBindGroup=B.device.createBindGroup({layout:this.lightsMaskBindGroupLayout,entries:this.lightsMaskBindGroupEntries}),this}constructor(e,t){super(N.PointLightsStencilMask,e,t),this.lightsMaskBindGroupEntries=[{binding:0,resource:null},{binding:1,resource:null}];const r=[{binding:0,visibility:GPUShaderStage.VERTEX,buffer:{type:"uniform"}},{binding:1,visibility:GPUShaderStage.VERTEX,buffer:{type:"read-only-storage"}}];this.lightsMaskBindGroupLayout=B.device.createBindGroupLayout({label:"Light Masking Bind Group",entries:r});const n={label:"Point Light Mask PSO",layout:B.device.createPipelineLayout({label:"Point Lights Mask Render PSO Layout",bindGroupLayouts:[this.lightsMaskBindGroupLayout]}),vertex:{module:J.createShaderModule(Qi(N.PointLightsStencilMask),"Point Light Mask Pass Vertex Shader"),entryPoint:$s,buffers:_e.defaultLayout,constants:{}},depthStencil:{format:B.depthStencilFormat,depthWriteEnabled:!1,depthCompare:"less-equal",stencilReadMask:0,stencilWriteMask:255,stencilBack:{compare:"always",depthFailOp:"increment-wrap",failOp:"keep",passOp:"keep"},stencilFront:{compare:"always",depthFailOp:"decrement-wrap",failOp:"keep",passOp:"keep"}},primitive:{cullMode:"none"}};this.renderPSO=J.createRenderPipeline(n)}createRenderPassDescriptor(){return this.renderPassDescriptor||(this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({label:"Point Lights Mask Stencil Pass",colorAttachments:[],depthStencilAttachment:{view:this.inputTextureViews[0],depthLoadOp:"load",depthStoreOp:"store",stencilLoadOp:"clear",stencilStoreOp:"store",stencilClearValue:0}})),this.renderPassDescriptor}render(e,t,r){this.inputTextureViews.length||this.inputTextureViews.push(r[0].createView());const n=e.beginRenderPass(this.createRenderPassDescriptor());return B.setActiveRenderPass(this.type,n),B.ENABLE_DEBUG_GROUPS&&n.pushDebugGroup("Point Lights Stencil Mask"),B.bindRenderPSO(this.renderPSO),n.setStencilReference(128),n.setBindGroup(0,this.lightsMaskBindGroup),n.setVertexBuffer(0,nt.pointLightSphereGeometry.vertexBuffers[0]),n.setIndexBuffer(nt.pointLightSphereGeometry.indexBuffer,Ae.INDEX_FORMAT),n.drawIndexed(nt.pointLightSphereGeometry.indexCount,t.lightingManager.pointLightsCount,0,0,1),B.ENABLE_DEBUG_GROUPS&&n.popDebugGroup(),n.end(),this.postRender(e),[r[0]]}}const Yt=class Yt extends gr{constructor(e,t){super(N.PointLightsNonCulledLighting,e,t);const r=B.device.createPipelineLayout({label:"Render Non-Instanced Non-Culled Point Lights PSO Layout",bindGroupLayouts:[this.gbufferCommonBindGroupLayout,dt.bindGroupLayout]}),n={label:Yt.FRONT_FACE_RENDER_PSO_LABEL,layout:r,vertex:{module:J.createShaderModule(Qi(N.PointLightsNonCulledLighting),"Non-Instanced Non-Culled Point Lights Vertex Shader"),entryPoint:$s,buffers:_e.defaultLayout},fragment:{module:J.createShaderModule(Yi(N.PointLightsNonCulledLighting)),entryPoint:Ws,targets:Yt.RENDER_TARGETS},depthStencil:{format:B.depthStencilFormat,depthWriteEnabled:!1},primitive:{cullMode:"back"}};this.frontFaceCullRenderPSO=J.createRenderPipeline(n),n.label=Yt.BACK_FACE_RENDER_PSO_LABEL,n.primitive.cullMode="front",this.backFaceCullRenderPSO=J.createRenderPipeline(n)}createRenderPassDescriptor(){if(this.renderPassDescriptor)return this.renderPassDescriptor;const e=[{view:this.inputTextureViews[5],loadOp:"load",storeOp:"store"}];return this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({label:"Non-Instanced Non-Culled Point Lights Render Pass",colorAttachments:e,depthStencilAttachment:{depthReadOnly:!0,stencilReadOnly:!0,view:this.inputTextureViews[2]}}),this.renderPassDescriptor}render(e,t,r){this.inputTextureViews.length||(this.inputTextureViews.push(r[0].createView()),this.inputTextureViews.push(r[1].createView()),this.inputTextureViews.push(r[2].createView({aspect:"all"})),this.inputTextureViews.push(r[2].createView({aspect:"depth-only"})),this.inputTextureViews.push(r[3].createView()),this.inputTextureViews.push(r[4].createView()),this.updateGbufferBindGroupEntryAt(0,this.inputTextureViews[0]).updateGbufferBindGroupEntryAt(1,this.inputTextureViews[1]).updateGbufferBindGroupEntryAt(2,this.inputTextureViews[3]).updateGbufferBindGroupEntryAt(3,this.inputTextureViews[4]).updateGbufferBindGroupEntryAt(4,{buffer:this.camera.gpuBuffer}).recreateGBufferTexturesBindGroup());const n=e.beginRenderPass(this.createRenderPassDescriptor()),i=nt.pointLightSphereGeometry.indexBuffer,o=nt.pointLightSphereGeometry.vertexBuffers[0],u=nt.pointLightSphereGeometry.indexCount;n.setIndexBuffer(i,Ae.INDEX_FORMAT),n.setVertexBuffer(0,o),n.setBindGroup(0,this.gbufferTexturesBindGroup);let l=!1,m=!1;for(const b of t.lightingManager.cameraFaceCulledPointLights)D.dist(b.position,this.camera.position)>b.radius+.1?(l||n.setPipeline(this.frontFaceCullRenderPSO),l=!0,m=!1):(m||n.setPipeline(this.backFaceCullRenderPSO),l=!1,m=!0),n.setBindGroup(1,b.bindGroup),n.drawIndexed(u);return n.end(),this.postRender(e),[r[4]]}};Yt.FRONT_FACE_RENDER_PSO_LABEL="Render Non-Instanced Non-Culled Point Lights Front Face PSO Descriptor",Yt.BACK_FACE_RENDER_PSO_LABEL="Render Non-Instanced Non-Culled Point Lights Back Face PSO Descriptor";let Zi=Yt;class eo extends gr{constructor(e,t){super(N.PointLightsLighting,e,t);const r={compare:"less",failOp:"keep",depthFailOp:"keep",passOp:"keep"},n={label:"Point Light Render PSO",layout:B.device.createPipelineLayout({label:"Render Lights PSO Layout",bindGroupLayouts:[this.gbufferCommonBindGroupLayout]}),vertex:{module:J.createShaderModule(Qi(N.PointLightsLighting),"Point Light Render Pass Vertex Shader"),entryPoint:$s,buffers:_e.defaultLayout,constants:{}},fragment:{module:J.createShaderModule(Yi(N.PointLightsLighting),"Point Light Render Pass Fragment Shader"),entryPoint:Ws,targets:eo.RENDER_TARGETS},depthStencil:{format:B.depthStencilFormat,depthWriteEnabled:!1,depthCompare:"less-equal",stencilReadMask:255,stencilWriteMask:0,stencilBack:r,stencilFront:r},primitive:{cullMode:"back"}};this.renderPSO=J.createRenderPipeline(n)}createRenderPassDescriptor(){if(this.renderPassDescriptor)return this.renderPassDescriptor;const e=[{view:this.inputTextureViews[5],loadOp:"load",storeOp:"store"}];return this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({label:"Point Lights Render Pass",colorAttachments:e,depthStencilAttachment:{depthReadOnly:!0,stencilReadOnly:!1,view:this.inputTextureViews[2],stencilLoadOp:"load",stencilStoreOp:"store"}}),this.renderPassDescriptor}render(e,t,r){this.inputTextureViews.length||(this.inputTextureViews.push(r[0].createView()),this.inputTextureViews.push(r[1].createView()),this.inputTextureViews.push(r[2].createView({aspect:"all"})),this.inputTextureViews.push(r[2].createView({aspect:"depth-only"})),this.inputTextureViews.push(r[3].createView()),this.inputTextureViews.push(r[4].createView()),this.updateGbufferBindGroupEntryAt(0,this.inputTextureViews[0]).updateGbufferBindGroupEntryAt(1,this.inputTextureViews[1]).updateGbufferBindGroupEntryAt(2,this.inputTextureViews[3]).updateGbufferBindGroupEntryAt(3,this.inputTextureViews[4]).updateGbufferBindGroupEntryAt(4,{buffer:this.camera.gpuBuffer}).updateGbufferBindGroupEntryAt(5,{buffer:t.lightingManager.gpuBuffer}).recreateGBufferTexturesBindGroup());const n=e.beginRenderPass(this.createRenderPassDescriptor());return B.setActiveRenderPass(this.type,n),B.ENABLE_DEBUG_GROUPS&&n.pushDebugGroup("Begin Point LightingSystem"),B.bindRenderPSO(this.renderPSO),n.setBindGroup(0,this.gbufferTexturesBindGroup),n.setVertexBuffer(0,nt.pointLightSphereGeometry.vertexBuffers[0]),n.setIndexBuffer(nt.pointLightSphereGeometry.indexBuffer,Ae.INDEX_FORMAT),n.drawIndexed(nt.pointLightSphereGeometry.indexCount,t.lightingManager.pointLightsCount,0,0,1),B.ENABLE_DEBUG_GROUPS&&n.popDebugGroup(),n.end(),this.postRender(e),[r[4]]}}const Fc="main",Et=class Et extends Te{constructor(e,t){super(N.Reflection,e,t),this._maxIterations=150,this._debugMissedIntersections=!1,this._isHiZ=!0;const r=[{binding:0,visibility:GPUShaderStage.COMPUTE,texture:{}},{binding:1,visibility:GPUShaderStage.COMPUTE,texture:{}},{binding:2,visibility:GPUShaderStage.COMPUTE,texture:{}},{binding:3,visibility:GPUShaderStage.COMPUTE,texture:{sampleType:"unfilterable-float"}},{binding:4,visibility:GPUShaderStage.COMPUTE,storageTexture:{access:"write-only",format:"rgba16float",viewDimension:"2d"}},{binding:5,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}},{binding:6,visibility:GPUShaderStage.COMPUTE,buffer:{type:"uniform"}}];var n;this.bindGroupLayout=B.device.createBindGroupLayout({label:"Reflection Pass ComputePSO Bind Group Layout",entries:r}),this.computePSO=J.createComputePipeline({label:"Reflection Pass Compute PSO",layout:B.device.createPipelineLayout({label:"Reflection PASS ComputePSO Layout",bindGroupLayouts:[this.bindGroupLayout]}),compute:{entryPoint:Fc,module:J.createShaderModule((n="rgba16float",` - ${W.Camera} - - struct SSRSettings { - isHiZ: i32, - maxIterations: i32, - debugMissedIntersections: i32 - }; - - @group(0) @binding(0) var sceneTexture: texture_2d; - @group(0) @binding(1) var normalMetallicRoughnessTexture: texture_2d; - @group(0) @binding(2) var albedoReflectanceTexture: texture_2d; - @group(0) @binding(3) var depthTexture: texture_2d; - @group(0) @binding(4) var outTexture: texture_storage_2d<${n}, write>; - @group(0) @binding(5) var camera: Camera; - @group(0) @binding(6) var settings: SSRSettings; - - override WORKGROUP_SIZE_X: u32; - override WORKGROUP_SIZE_Y: u32; - - ${kr} - - const MAX_THICKNESS = 0.001; - - fn ComputePosAndReflection( - tid: vec2u, - viewNormal: vec3f, - projectionMatrix: mat4x4f, - inverseProjectionMatrix: mat4x4f, - viewportWidth: u32, - viewportHeight: u32, - depthTexture: texture_2d, - outSamplePosInTexSpace: ptr, - outReflDirInTexSpace: ptr, - outMaxDistance: ptr - ) { - let sampleDepth = textureLoad(depthTexture, tid, 0).r; - var samplePosClipSpace = vec4f( - ((f32(tid.x) + 0.5) / f32(viewportWidth)) * 2 - 1.0, - ((f32(tid.y) + 0.5) / f32(viewportHeight)) * 2 - 1.0, - sampleDepth, - 1 - ); - samplePosClipSpace.y *= -1; - var samplePosViewSpace = inverseProjectionMatrix * samplePosClipSpace; - samplePosViewSpace /= samplePosViewSpace.w; - let vCamToSampleViewSpace = normalize(samplePosViewSpace.xyz); - let vReflectionViewSpace = vec4f(reflect(vCamToSampleViewSpace.xyz, viewNormal.xyz), 0.0); - - var vReflectionEndPosViewSpace = samplePosViewSpace + vReflectionViewSpace * 1000; - // vReflectionEndPosViewSpace /= select(1.0, vReflectionEndPosViewSpace.z, vReflectionEndPosViewSpace.z > 0.0); - var vReflectionEndPosClipSpace = projectionMatrix * vec4f(vReflectionEndPosViewSpace.xyz, 1.0); - vReflectionEndPosClipSpace /= vReflectionEndPosClipSpace.w; - - let vReflectionDir = normalize((vReflectionEndPosClipSpace - samplePosClipSpace).xyz); - - // transform to texture space - (*outSamplePosInTexSpace) = vec3f( - samplePosClipSpace.xy * vec2f(0.5, -0.5) + vec2f(0.5, 0.5), - samplePosClipSpace.z - ); - - (*outReflDirInTexSpace) = vec3f( - vReflectionDir.xy * vec2f(0.5, -0.5), - vReflectionDir.z - ); - - (*outMaxDistance) = select(-outSamplePosInTexSpace.x / outReflDirInTexSpace.x, (1 - outSamplePosInTexSpace.x) / outReflDirInTexSpace.x, outReflDirInTexSpace.x >= 0); - (*outMaxDistance) = min(*outMaxDistance, select((1 - outSamplePosInTexSpace.y) / outReflDirInTexSpace.y, -outSamplePosInTexSpace.y / outReflDirInTexSpace.y, outReflDirInTexSpace.y < 0)); - (*outMaxDistance) = min(*outMaxDistance, select((1 - outSamplePosInTexSpace.z) / outReflDirInTexSpace.z, -outSamplePosInTexSpace.z / outReflDirInTexSpace.z, outReflDirInTexSpace.z < 0)); - } - - @must_use - fn FindIntersectionLinear( - samplePosInTexSpace: vec3f, - reflDirInTexSpace: vec3f, - maxTraceDistance: f32, - viewportWidth: u32, - viewportHeight: u32, - depthTexture: texture_2d, - intersection: ptr - ) -> f32 { - let vReflectionEndPosTexSpace = samplePosInTexSpace + reflDirInTexSpace * maxTraceDistance; - var dp = vReflectionEndPosTexSpace.xyz - samplePosInTexSpace.xyz; - let viewSize = vec2f(f32(viewportWidth), f32(viewportHeight)); - let sampleScreenPos = vec2i(samplePosInTexSpace.xy * viewSize); - let endPosScreenPos = vec2i(vReflectionEndPosTexSpace.xy * viewSize); - let dp2 = endPosScreenPos - sampleScreenPos; - let maxDist = max(abs(dp2.x), abs(dp2.y)); - dp /= f32(maxDist); - - var rayPosTexSpace = vec4f(samplePosInTexSpace.xyz + dp, 0); - let rayDirTexSpace = vec4f(dp.xyz, 0); - let rayPosStartTexSpace = rayPosTexSpace; - - var hitIndex = -1; - for (var i = 0; i < maxDist && i < settings.maxIterations; i += 4) { - let rayPosTexSpace0 = rayPosTexSpace + rayDirTexSpace * 0; - let rayPosTexSpace1 = rayPosTexSpace + rayDirTexSpace * 1; - let rayPosTexSpace2 = rayPosTexSpace + rayDirTexSpace * 2; - let rayPosTexSpace3 = rayPosTexSpace + rayDirTexSpace * 3; - - let depth0 = textureLoad(depthTexture, vec2u(rayPosTexSpace0.xy * viewSize), 0).r; - let depth1 = textureLoad(depthTexture, vec2u(rayPosTexSpace1.xy * viewSize), 0).r; - let depth2 = textureLoad(depthTexture, vec2u(rayPosTexSpace2.xy * viewSize), 0).r; - let depth3 = textureLoad(depthTexture, vec2u(rayPosTexSpace3.xy * viewSize), 0).r; - - var thickness = 0.0; - - thickness = rayPosTexSpace0.z - depth0; - hitIndex = select(hitIndex, i + 0, thickness >= 0 && thickness < MAX_THICKNESS); - - thickness = rayPosTexSpace1.z - depth1; - hitIndex = select(hitIndex, i + 1, thickness >= 0 && thickness < MAX_THICKNESS); - - thickness = rayPosTexSpace2.z - depth2; - hitIndex = select(hitIndex, i + 2, thickness >= 0 && thickness < MAX_THICKNESS); - - thickness = rayPosTexSpace3.z - depth3; - hitIndex = select(hitIndex, i + 3, thickness >= 0 && thickness < MAX_THICKNESS); - - if (hitIndex != -1) { - break; - } - - rayPosTexSpace = rayPosTexSpace3 + rayDirTexSpace; - } - - let intersected = hitIndex >= 0; - (*intersection) = rayPosStartTexSpace.xyz + rayDirTexSpace.xyz * f32(hitIndex); - - return select(0.0, 1.0, intersected); - } - - @must_use - fn getCellCount(mipLevel: i32, depthTexture: texture_2d) -> vec2f { - return vec2f(textureDimensions(depthTexture, mipLevel)); - } - - @must_use - fn getCell(pos: vec2f, cell_count: vec2f) -> vec2f { - return vec2f(floor(pos * cell_count)); - } - - @must_use - fn intersectDepthPlane(o: vec3f, d: vec3f, z: f32) -> vec3f { - return o + d * z; - } - - @must_use - fn intersectCellBoundary( - o: vec3f, - d: vec3f, - cell: vec2f, - cellCount: vec2f, - crossStep: vec2f, - crossOffset: vec2f - ) -> vec3f { - var intersection = vec3f(0.0); - - let index = cell + crossStep; - var boundary = index / cellCount; - boundary += crossOffset; - - var delta = boundary - o.xy; - delta /= d.xy; - let t = min(delta.x, delta.y); - - intersection = intersectDepthPlane(o, d, t); - - return intersection; - } - - @must_use - fn getMinimumDepthPlane( - p: vec2f, - mipLevel: i32, - depthTexture: texture_2d - ) -> f32 { - return textureLoad(depthTexture, vec2u(p), mipLevel).r; - } - - @must_use - fn crossedCellBoundary(oldCellIndex: vec2f, newCellIndex: vec2f) -> bool { - return (oldCellIndex.x != newCellIndex.x) || (oldCellIndex.y != newCellIndex.y); - } - - @must_use - fn FindIntersectionHiZ( - samplePosInTexSpace: vec3f, - reflDirInTexSpace: vec3f, - maxTraceDistance: f32, - viewportWidth: u32, - viewportHeight: u32, - depthTexture: texture_2d, - intersection: ptr - ) -> f32 { - let viewSize = vec2f(f32(viewportWidth), f32(viewportHeight)); - let maxLevel = textureNumLevels(depthTexture) - 1; - - var crossStep = vec2f( - select(-1.0, 1.0, reflDirInTexSpace.x >= 0), - select(-1.0, 1.0, reflDirInTexSpace.y >= 0) - ); - let crossOffset = crossStep / viewSize / 128.0; - crossStep = saturate(crossStep); - - var ray = samplePosInTexSpace.xyz; - let minZ = ray.z; - let maxZ = ray.z + reflDirInTexSpace.z * maxTraceDistance; - let deltaZ = (maxZ - minZ); - - let o = ray; - let d = reflDirInTexSpace * maxTraceDistance; - - let startLevel = 2; - let stopLevel = 0; - - let startCellCount = getCellCount(startLevel, depthTexture); - - let rayCell = getCell(ray.xy, startCellCount); - ray = intersectCellBoundary( - o, - d, - rayCell, - startCellCount, - crossStep, - crossOffset * 64 - ); - - var level = startLevel; - var iter = 0; - let isBackwardRay = reflDirInTexSpace.z < 0; - let rayDir = select(1.0, -1.0, isBackwardRay); - - while(level >= stopLevel && ray.z * rayDir <= maxZ * rayDir && iter < settings.maxIterations) { - let cellCount = getCellCount(level, depthTexture); - let oldCellIdx = getCell(ray.xy, cellCount); - let cellMinZ = getMinimumDepthPlane((oldCellIdx + 0.5), level, depthTexture); - let tmpRay = select( - ray, - intersectDepthPlane(o, d, (cellMinZ - minZ) / deltaZ), - (cellMinZ > ray.z) && !isBackwardRay - ); - let newCellIdx = getCell(tmpRay.xy, cellCount); - - let thickness = select(0, (ray.z - cellMinZ), level == 0); - let crossed = (isBackwardRay && (cellMinZ > ray.z)) || - (thickness > (MAX_THICKNESS)) || - crossedCellBoundary(oldCellIdx, newCellIdx); - ray = select( - tmpRay, - intersectCellBoundary(o, d, oldCellIdx, cellCount, crossStep, crossOffset), - crossed - ); - level = select( - level - 1, - min(i32(maxLevel), level + 1), - crossed - ); - - iter++; - } - - let intersected = (level < stopLevel); - (*intersection) = ray; - - let intensity = select(0.0, 1.0, intersected); - - return intensity; - } - - @must_use - fn ComputeReflectionColor( - intensity: f32, - intersection: vec3f, - viewportWidth: u32, - viewportHeight: u32, - sceneTexture: texture_2d - ) -> vec4f { - let viewSize = vec2f(f32(viewportWidth), f32(viewportHeight)); - let texCoords = vec2u(intersection.xy * viewSize); - let ssrColor = textureLoad(sceneTexture, texCoords, 0); - return ssrColor; - } - - @compute @workgroup_size(WORKGROUP_SIZE_X, WORKGROUP_SIZE_Y) - fn ${Fc}(@builtin(global_invocation_id) globalInvocationId : vec3u,) { - let pos = globalInvocationId.xy; - - let encodedN = textureLoad(normalMetallicRoughnessTexture, pos, 0).rg; - let N = decodeNormal(encodedN); - let sceneColor = textureLoad(sceneTexture, pos, 0); - let reflectanceMask = textureLoad(albedoReflectanceTexture, pos, 0).a; - - var reflectionColor = vec4f(0); - var intensity = 0.0; - - let isReflectance = reflectanceMask != 0; - if (isReflectance) { - var samplePosInTexSpace = vec3f(0); - var reflDirInTexSpace = vec3f(0); - var maxTraceDistance = 0.0; - - ComputePosAndReflection( - pos.xy, - N, - camera.projectionMatrix, - camera.inverseProjectionMatrix, - camera.viewportWidth, - camera.viewportHeight, - depthTexture, - &samplePosInTexSpace, - &reflDirInTexSpace, - &maxTraceDistance - ); - - var intersection = vec3f(0); - - if (settings.isHiZ == 1) { - intensity = FindIntersectionHiZ( - samplePosInTexSpace, - reflDirInTexSpace, - maxTraceDistance, - camera.viewportWidth, - camera.viewportHeight, - depthTexture, - &intersection - ); - } else { - intensity = FindIntersectionLinear( - samplePosInTexSpace, - reflDirInTexSpace, - maxTraceDistance, - camera.viewportWidth, - camera.viewportHeight, - depthTexture, - &intersection - ); - } - - reflectionColor = ComputeReflectionColor( - intensity, - intersection, - camera.viewportWidth, - camera.viewportHeight, - sceneTexture - ); - } - - let combinedColor = sceneColor + reflectionColor; - let finalColor = select( - combinedColor, - mix( - select(combinedColor, vec4f(0, 1, 0, 1), isReflectance), - combinedColor, - intensity - ), - settings.debugMissedIntersections == 1 - ); - - textureStore(outTexture, pos, finalColor); - - } -`)),constants:{WORKGROUP_SIZE_X:Et.COMPUTE_WORKGROUP_SIZE_X,WORKGROUP_SIZE_Y:Et.COMPUTE_WORKGROUP_SIZE_Y}}}),this.settingsBuffer=B.device.createBuffer({label:"SSR Settings Buffer",size:4*Uint32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),Y.addBufferBytes(this.settingsBuffer),new Int32Array(this.settingsBuffer.getMappedRange()).set(new Int32Array([this._isHiZ?1:0,this._maxIterations,this._debugMissedIntersections?1:0])),this.settingsBuffer.unmap(),this.outTextures.push(B.device.createTexture({label:"Reflection Texture",size:{width:e,height:t,depthOrArrayLayers:1},format:"rgba16float",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.COPY_SRC})),Y.addTextureBytes(this.outTextures[0])}set maxIterations(e){this._maxIterations=e,this.updateSettingsBuffer()}set debugMissedIntersections(e){this._debugMissedIntersections=e,this.updateSettingsBuffer()}set isHiZ(e){this._isHiZ=e,this.updateSettingsBuffer()}updateSettingsBuffer(){B.device.queue.writeBuffer(this.settingsBuffer,0,new Int32Array([this._isHiZ?1:0,this._maxIterations,this._debugMissedIntersections?1:0]))}async destroy(){super.destroy(),await B.device.queue.onSubmittedWorkDone(),Y.removeBufferBytes(this.settingsBuffer),this.settingsBuffer.destroy()}setCamera(e){return this.camera=e,this}createComputePassDescriptor(){return this.computePassDescriptor||(this.computePassDescriptor={label:"Reflection Compute Pass Encoder"}),this.computePassDescriptor}render(e,t,r){if(!this.inputTextureViews.length){this.inputTextureViews.push(r[0].createView()),this.inputTextureViews.push(r[1].createView()),this.inputTextureViews.push(r[2].createView()),this.inputTextureViews.push(r[3].createView());const u=[{binding:0,resource:this.inputTextureViews[0]},{binding:1,resource:this.inputTextureViews[1]},{binding:2,resource:this.inputTextureViews[2]},{binding:3,resource:this.inputTextureViews[3]},{binding:4,resource:this.outTextures[0].createView()},{binding:5,resource:{buffer:this.camera.gpuBuffer}},{binding:6,resource:{buffer:this.settingsBuffer}}];this.bindGroup=B.device.createBindGroup({label:"Compute Reflections Bind Group",entries:u,layout:this.bindGroupLayout})}const n=e.beginComputePass(this.createComputePassDescriptor());B.ENABLE_DEBUG_GROUPS&&n.pushDebugGroup("Begin Reflection Compute Pass"),n.setPipeline(this.computePSO),n.setBindGroup(0,this.bindGroup);const i=Math.ceil(this.outTextures[0].width/Et.COMPUTE_WORKGROUP_SIZE_X),o=Math.ceil(this.outTextures[0].height/Et.COMPUTE_WORKGROUP_SIZE_Y);return n.dispatchWorkgroups(i,o,1),B.ENABLE_DEBUG_GROUPS&&n.popDebugGroup(),n.end(),this.postRender(e),this.outTextures}};Et.COMPUTE_WORKGROUP_SIZE_X=8,Et.COMPUTE_WORKGROUP_SIZE_Y=8;let to=Et;const Dc="fragBlurSSAO",Hp=` - ${W.Camera} - ${W.VertexOutput} - - @group(0) @binding(0) var ssaoTexture: texture_2d; - - @fragment - fn ${Dc}(in: VertexOutput) -> @location(0) vec4f { - let coord = in.position; - let pixelCoords = vec2i(floor(coord.xy)); - var result = 0.0; - for (var y = -2; y < 2; y++) { - for (var x = -2; x < 2; x++) { - let offset = pixelCoords + vec2i(x, y); - result += textureLoad(ssaoTexture, offset, 0).r; - } - } - return vec4f(result / 16.0, 0, 0, 1); - } -`;class Jp extends Te{constructor(e,t){super(N.SSAOBlur,e,t);const r=[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:"unfilterable-float"}}];this.bindGroupLayout=B.device.createBindGroupLayout({label:"SSAO Blur Input Bind Group",entries:r}),this.renderPSO=J.createRenderPipeline({label:"SSAO Blur RenderPSO",layout:B.device.createPipelineLayout({label:"SSAO Blur RenderPSO Layout",bindGroupLayouts:[this.bindGroupLayout]}),vertex:{module:J.createShaderModule(zt),entryPoint:_t},fragment:{module:J.createShaderModule(Hp),entryPoint:Dc,targets:[{format:"r16float"}]}}),this.outTextures.push(B.device.createTexture({dimension:"2d",format:"r16float",mipLevelCount:1,sampleCount:1,size:{width:e,height:t,depthOrArrayLayers:1},usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT,label:"SSAO Blurred Texture"})),Y.addTextureBytes(this.outTextures[0]),this.outTextureView=this.outTextures[0].createView()}createRenderPassDescriptor(){if(this.renderPassDescriptor)return this.renderPassDescriptor;const e=[{loadOp:"load",storeOp:"store",view:this.outTextureView}];return this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({label:"SSAO Blur Render Pass Descriptor",colorAttachments:e}),this.renderPassDescriptor}render(e,t,r){if(!this.inputTextureViews.length){this.inputTextureViews.push(r[0].createView());const i=[{binding:0,resource:this.inputTextureViews[0]}];this.bindGroup=B.device.createBindGroup({label:"SSAO Blur Bind Group",entries:i,layout:this.bindGroupLayout})}const n=e.beginRenderPass(this.createRenderPassDescriptor());return B.ENABLE_DEBUG_GROUPS&&n.pushDebugGroup("Begin SSAO Blur"),n.setBindGroup(0,this.bindGroup),n.setPipeline(this.renderPSO),n.draw(3),B.ENABLE_DEBUG_GROUPS&&n.popDebugGroup(),n.end(),this.postRender(e),this.outTextures}}const Uc="fragSSAO",zp=` - ${W.Camera} - ${W.VertexOutput} - ${W.MathHelpers} - - ${kr} - - struct Settings { - kernelSize: u32, - radius: f32, - strength: f32 - }; - - @group(0) @binding(0) var normalMetallicRoughnessTex: texture_2d; - @group(0) @binding(1) var depthTexture: texture_depth_2d; - @group(0) @binding(2) var noiseTexture: texture_2d; - @group(0) @binding(3) var kernelBuffer: array; - @group(0) @binding(4) var camera: Camera; - @group(0) @binding(5) var settings: Settings; - - @fragment - fn ${Uc}( - in: VertexOutput - ) -> @location(0) vec4f { - let coord = in.position; - let pixelCoords = vec2i(floor(coord.xy)); - let encodedN = textureLoad(normalMetallicRoughnessTex, pixelCoords, 0).rg; - let viewNormal = decodeNormal(encodedN); - let centerDepth = textureLoad(depthTexture, pixelCoords, 0); - let viewSpacePos = calcViewSpacePos(camera, coord.xy, centerDepth); - - let noiseScale = vec2i(textureDimensions(noiseTexture).xy); - let sampleCoords = pixelCoords % noiseScale; - var randomVec = textureLoad(noiseTexture, sampleCoords, 0).rgb; - randomVec = (camera.viewMatrix * vec4f(randomVec, 0)).xyz; - - let viewTangent = normalize(randomVec - viewNormal * dot(randomVec, viewNormal)); - let viewBitangent = cross(viewNormal, viewTangent); - let TBN = mat3x3f(viewTangent, viewBitangent, viewNormal); - - let kernelSize = settings.kernelSize; - let radius = settings.radius; - - var occlusion = 0.0; - - let screenSize = vec2i(textureDimensions(depthTexture).xy); - - for (var i = 0u; i < kernelSize; i++) { - var viewSamplePos = TBN * kernelBuffer[i].xyz; - viewSamplePos = viewSpacePos + viewSamplePos * radius; - - let viewSampleDir = normalize(viewSamplePos - viewSpacePos); - let NdotS = max(dot(viewNormal, viewSampleDir), 0.0); - - let clipPos = camera.projectionMatrix * vec4f(viewSamplePos, 1.0); - let ndcPos = clipPos.xy / clipPos.w; - - let screenCoord = vec2i(vec2f(ndcPos.x * 0.5 + 0.5, -ndcPos.y * 0.5 + 0.5) * vec2f(screenSize)); - - var sampleDepth = textureLoad(depthTexture, screenCoord, 0); - sampleDepth = calcViewSpacePos(camera, vec2f(screenCoord), sampleDepth).z; - - let rangeCheck = smoothstep(0.0, 1.0, radius / abs(viewSpacePos.z - sampleDepth)); - - occlusion += select(0.0, 1.0, sampleDepth > viewSamplePos.z) * rangeCheck * NdotS; - } - - occlusion = 1 - (occlusion / f32(kernelSize)); - let finalOcclusion = pow(occlusion, settings.strength); - - return vec4f(finalOcclusion); - } -`,fo=class fo extends Te{constructor(e,t){super(N.SSAO,e,t),this.gbufferTexturesBindGroupEntries=[],this.startKernelSize=8,this._kernelSize=128,this._radius=.5,this._strength=2;const r=this.kernelSize,n=new Float32Array(4*r);for(let u=0;u; - @group(0) @binding(1) var velocityTexture: texture_2d; - @group(0) @binding(2) var historyTexture: texture_2d; - @group(0) @binding(3) var historyMixFactor: f32; - - @fragment - fn ${kc}(@builtin(position) coord: vec4f) -> @location(0) vec4f { - let pixelCoords = vec2i(floor(coord.xy)); - let currColor = textureLoad(colorTexture, pixelCoords, 0).xyz; - let velocity = textureLoad(velocityTexture, pixelCoords, 0).xy; - let prevousPixelPos = vec2i(floor(coord.xy - velocity)); - - var history = textureLoad(historyTexture, prevousPixelPos, 0).xyz; - - let nearColor0 = textureLoad(colorTexture, pixelCoords + vec2i(1, 0), 0).xyz; - let nearColor1 = textureLoad(colorTexture, pixelCoords + vec2i(0, 1), 0).xyz; - let nearColor2 = textureLoad(colorTexture, pixelCoords + vec2i(-1, 0), 0).xyz; - let nearColor3 = textureLoad(colorTexture, pixelCoords + vec2i(0, -1), 0).xyz; - - let boxMin = min(currColor, min(nearColor0, min(nearColor1, min(nearColor2, nearColor3)))); - let boxMax = max(currColor, max(nearColor0, max(nearColor1, max(nearColor2, nearColor3))));; - - history = clamp(history, boxMin, boxMax); - - var color = vec4f(mix(currColor, history, historyMixFactor), 1.0); - - return color; - } -`,jr=class jr extends Te{constructor(e,t){super(N.TAAResolve,e,t),this.historyReset=!1;const r=J.createShaderModule(zt),n=J.createShaderModule(Kp),i=[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:1,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:2,visibility:GPUShaderStage.FRAGMENT,texture:{}},{binding:3,visibility:GPUShaderStage.FRAGMENT,buffer:{}}];this.texturesBindGroupLayout=B.device.createBindGroupLayout({label:"TAA Resolve Input Textures Bind Group",entries:i});const o={layout:B.device.createPipelineLayout({bindGroupLayouts:[this.texturesBindGroupLayout]}),vertex:{module:r,entryPoint:_t},fragment:{module:n,entryPoint:kc,targets:[{format:"rgba16float"}]},primitive:{topology:"triangle-list",cullMode:"back"}};this.renderPSO=J.createRenderPipeline(o),this.outTextures.push(B.device.createTexture({dimension:"2d",format:"rgba16float",mipLevelCount:1,sampleCount:1,size:{width:e,height:t,depthOrArrayLayers:1},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING|GPUTextureUsage.COPY_SRC,label:"TAA Resolve Texture"})),this.outTextureView=this.outTextures[0].createView(),Y.addTextureBytes(this.outTextures[0]),this.sourceCopyTextureInfo={texture:this.outTextures[0],mipLevel:0,origin:{x:0,y:0,z:0}},this.outTextures.push(B.device.createTexture({dimension:"2d",format:"rgba16float",mipLevelCount:1,sampleCount:1,size:{width:e,height:t,depthOrArrayLayers:1},usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST,label:"TAA Resolve Texture"})),this.historyTextureView=this.outTextures[1].createView(),Y.addTextureBytes(this.outTextures[1]),this.destCopyTextureInfo={texture:this.outTextures[1],mipLevel:0,origin:{x:0,y:0,z:0}},this.copyTextureExtend={width:e,height:t,depthOrArrayLayers:1},this.historyMixFactorBuffer=B.device.createBuffer({label:"TAA History Mix Factor Buffer",size:1*Float32Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST,mappedAtCreation:!0}),new Float32Array(this.historyMixFactorBuffer.getMappedRange()).set([jr.HISTORY_MIX_FACTOR]),Y.addBufferBytes(this.historyMixFactorBuffer),this.historyMixFactorBuffer.unmap()}async destroy(){super.destroy(),await B.device.queue.onSubmittedWorkDone(),Y.removeBufferBytes(this.historyMixFactorBuffer),this.historyMixFactorBuffer.destroy()}resetHistory(){this.historyReset=!0,B.device.queue.writeBuffer(this.historyMixFactorBuffer,0,new Float32Array([0]))}createRenderPassDescriptor(){if(this.renderPassDescriptor)return this.renderPassDescriptor;const e=[{view:this.outTextureView,loadOp:"load",storeOp:"store"}];return this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({label:"TAA Resolve Pass",colorAttachments:e}),this.renderPassDescriptor}render(e,t,r){if(!this.inputTextureViews.length){this.inputTextureViews.push(r[0].createView()),this.inputTextureViews.push(r[1].createView());const o=[{binding:0,resource:this.inputTextureViews[0]},{binding:1,resource:this.inputTextureViews[1]},{binding:2,resource:this.historyTextureView},{binding:3,resource:{buffer:this.historyMixFactorBuffer}}];this.textureBindGroup=B.device.createBindGroup({layout:this.texturesBindGroupLayout,entries:o})}const n=this.createRenderPassDescriptor(),i=e.beginRenderPass(n);return B.setActiveRenderPass(this.type,i),B.bindRenderPSO(this.renderPSO),i.setBindGroup(0,this.textureBindGroup),i.draw(3),i.end(),e.copyTextureToTexture(this.sourceCopyTextureInfo,this.destCopyTextureInfo,this.copyTextureExtend),this.postRender(e),this.historyReset&&(B.device.queue.onSubmittedWorkDone().then(()=>{B.device.queue.writeBuffer(this.historyMixFactorBuffer,0,new Float32Array([jr.HISTORY_MIX_FACTOR]))}),this.historyReset=!1),this.outTextures}};jr.HISTORY_MIX_FACTOR=.9;let so=jr;class Xp extends Te{constructor(e,t){super(N.Transparent,e,t)}setCamera(e){return this.camera=e,this}createRenderPassDescriptor(){if(this.renderPassDescriptor)return this.renderPassDescriptor;const e=[{view:this.inputTextureViews[0],loadOp:"load",storeOp:"store"}];return this.renderPassDescriptor=this.augmentRenderPassDescriptorWithTimestampQuery({label:"Transparent Render Pass",colorAttachments:e,depthStencilAttachment:{view:this.inputTextureViews[1],depthLoadOp:"load",depthStoreOp:"store",stencilReadOnly:!0}}),this.renderPassDescriptor}render(e,t,r){this.inputTextureViews.length||(this.inputTextureViews.push(r[0].createView()),this.inputTextureViews.push(r[1].createView()));const n=e.beginRenderPass(this.createRenderPassDescriptor());return B.setActiveRenderPass(this.type,n),B.ENABLE_DEBUG_GROUPS&&n.pushDebugGroup("Render Transparent Nodes"),this.cameraBindGroup=B.device.createBindGroup({label:"Camera Bind Group for: Transparent Pass",layout:J.defaultCameraPlusLightsBindGroupLayout,entries:[{binding:0,resource:{buffer:this.camera.gpuBuffer}},{binding:1,resource:{buffer:t.lightingManager.gpuBuffer}}]}),n.setBindGroup(ue.CameraPlusOptionalLights,this.cameraBindGroup),t.lightingManager.render(n),t.renderDebugMeshes(n),B.ENABLE_DEBUG_GROUPS&&n.popDebugGroup(),n.end(),this.postRender(e),r}}const Vr="deferredPBRFrag",qs=({hasPBRTextures:s=!1,isInstanced:e=!1}={})=>At` - ${W.Camera} - ${W.VertexOutput} - ${W.GBufferOutput} - ${W.ModelUniform} - ${W.InstanceInput} - - @group(${ue.CameraPlusOptionalLights}) @binding(0) var camera: Camera; - @group(${ue.Model}) @binding(0) var model: ModelUniform; - - @group(${ue.PBRTextures}) @binding(${as.Default}) var texSampler: sampler; - @group(${ue.PBRTextures}) @binding(${me.Albedo}) var albedoTexture: texture_2d; - @group(${ue.PBRTextures}) @binding(${me.Normal}) var normalTexture: texture_2d; - @group(${ue.PBRTextures}) @binding(${me.MetallicRoughness}) var metallicRoughnessTexture: texture_2d; - - #if ${e} - @group(${ue.InstanceInputs}) @binding(0) var instanceInputs: array; - #endif - - ${kr} - - @fragment - fn ${Vr}(in: VertexOutput) -> GBufferOutput { - let uv = in.uv; - - var viewSpaceN = normalize(in.viewNormal); - let viewSpaceT = normalize(in.viewTangent); - let viewSpaceB = normalize(in.viewBitangent); - let viewSpaceTBN = mat3x3f(viewSpaceT, viewSpaceB, viewSpaceN); - - // var textureNormal = textureSampleLevel(normalTexture, texSampler, uv, 5.0).rgb * 2 - 1; - let textureNormal = textureSample(normalTexture, texSampler, uv).rgb * 2 - 1; - - if (${s}) { - viewSpaceN = normalize(viewSpaceTBN * textureNormal); - } - - var color = model.baseColor; - if (${s}) { - let texColor = textureSample(albedoTexture, texSampler, uv); - if (texColor.a < 0.2) { - discard; - } - color = texColor.rgb; - } - - var out: GBufferOutput; - - #if ${e} - var metallic = instanceInputs[in.instanceId].metallic; - var roughness = instanceInputs[in.instanceId].roughness; - #else - var metallic = model.metallic; - var roughness = model.roughness; - #endif - - - if (${s}) { - let metallicRoughness = textureSample(metallicRoughnessTexture, texSampler, uv).rgb; - metallic = metallicRoughness.b; - roughness = metallicRoughness.g; - } - - out.normalMetallicRoughness = vec4f( - encodeNormal(viewSpaceN), - metallic, - roughness - ); - - out.color = vec4f(color, f32(model.isReflective)); - - var oldPos = in.prevFrameClipPos; - var newPos = in.currFrameClipPos; - - oldPos /= oldPos.w; - oldPos.x = (oldPos.x+1)/2.0; - oldPos.y = (oldPos.y+1)/2.0; - oldPos.y = 1 - oldPos.y; - - newPos /= newPos.w; - newPos.x = (newPos.x+1)/2.0; - newPos.y = (newPos.y+1)/2.0; - newPos.y = 1 - newPos.y; - - out.velocity = vec4f((newPos - oldPos).xy, 0, 1); - - return out; - } -`,Nc="forwardPBRFrag",Yp=({hasPBRTextures:s=!1,isInstanced:e=!1}={})=>At` - ${W.Camera} - ${W.VertexOutput} - ${W.GBufferOutput} - ${W.ModelUniform} - ${W.Material} - ${W.InstanceInput} - ${W.CommonHelpers} - ${W.Light} - - @group(${ue.CameraPlusOptionalLights}) @binding(0) var camera: Camera; - @group(${ue.CameraPlusOptionalLights}) @binding(1) var lightsBuffer: array; - - @group(${ue.Model}) @binding(0) var model: ModelUniform; - - @group(${ue.PBRTextures}) @binding(${as.Default}) var texSampler: sampler; - @group(${ue.PBRTextures}) @binding(${me.Albedo}) var albedoTexture: texture_2d; - @group(${ue.PBRTextures}) @binding(${me.Normal}) var normalTexture: texture_2d; - @group(${ue.PBRTextures}) @binding(${me.MetallicRoughness}) var metallicRoughnessTexture: texture_2d; - - #if ${e} - @group(${ue.InstanceInputs}) @binding(0) var instanceInputs: array; - #endif - - ${Lc({isDeferred:!1,hasIBL:!1})} - - @fragment - fn ${Nc}(in: VertexOutput) -> @location(0) vec4f { - let uv = in.uv; - - var N = normalize(in.viewNormal); - let T = normalize(in.viewTangent); - let B = normalize(in.viewBitangent); - let TBN = mat3x3f(T, B, N); - let textureNormal = textureSample(normalTexture, texSampler, uv).rgb * 2 - 1; - if (${s}) { - N = normalize(TBN * textureNormal); - } - - #if ${e} - var metallic = instanceInputs[in.instanceId].metallic; - var roughness = instanceInputs[in.instanceId].roughness; - #else - var metallic = model.metallic; - var roughness = model.roughness; - #endif - - if (${s}) { - let metallicRoughness = textureSample(metallicRoughnessTexture, texSampler, uv).rgb; - metallic = metallicRoughness.b; - roughness = metallicRoughness.g; - } - - let modelTexColor = textureSample(albedoTexture, texSampler, uv).rgb; - var color = vec4f(model.baseColor, 1); - if (${s}) { - color = textureSample(albedoTexture, texSampler, uv); - } - - // if (color.a < 0.01) { - // discard; - // } - - var material = Material(); - material.albedo = color.rgb; - material.roughness = roughness; - // return vec4f(vec3f(1 - metallic), 1); - material.metallic = metallic; - material.ambientOcclusion = 1.0; - - let V = normalize(camera.position - in.worldPosition); - - return PBRLighting( - material, - 0, - in.worldPosition, - N, - V, - 1, - color.a - ); - } -`,ft="vertexMain",Bt=({isInstanced:s,isShadow:e}={isInstanced:!1,isShadow:!1})=>At` - ${W.VertexInput} - ${W.VertexOutput} - ${W.ModelUniform} - ${W.Camera} - ${W.InstanceInput} - - @group(${ue.CameraPlusOptionalLights}) @binding(0) var camera: Camera; - @group(${ue.Model}) @binding(0) var model: ModelUniform; - - @group(${ue.PBRTextures}) @binding(${me.Albedo}) var albedoTexture: texture_2d; - @group(${ue.PBRTextures}) @binding(${me.Normal}) var normalTexture: texture_2d; - - #if ${s} - @group(${ue.InstanceInputs}) @binding(0) var instanceInputs: array; - #endif - - @vertex - fn ${ft}( - @builtin(instance_index) instanceId: u32, - in: VertexInput - ) -> VertexOutput { - var position = in.position; - - var worldMatrix: mat4x4f; - - #if ${!e} - var prevWorldMatrix: mat4x4f; - #endif - - #if ${s} - worldMatrix = instanceInputs[instanceId].worldMatrix * model.worldMatrix; - #if ${!e} - prevWorldMatrix = instanceInputs[instanceId].worldMatrix * model.prevFrameWorldMatrix; - #endif - #else - worldMatrix = model.worldMatrix; - #if ${!e} - prevWorldMatrix = model.prevFrameWorldMatrix; - #endif - #endif - - var out: VertexOutput; - let worldPosition = worldMatrix * in.position; - #if ${e} - out.position = camera.projectionViewMatrix * worldPosition; - #else - out.position = camera.projectionViewMatrix * worldPosition; - out.worldPosition = worldPosition.xyz; - - // var jitterOffset = camera.jitterOffset; - // jitterOffset.x = ((jitterOffset.x - 0.5) / f32(camera.viewportWidth)) * 2; - // jitterOffset.y = ((jitterOffset.y - 0.5) / f32(camera.viewportHeight)) * 2; - - out.position += vec4f(camera.jitterOffset * out.position.w, 0, 0); - - out.currFrameClipPos = out.position; - out.prevFrameClipPos = camera.prevFrameProjectionViewMatrix * prevWorldMatrix * in.position; - - let viewSpaceNormMatrix = mat3x3f( - camera.viewMatrix[0].xyz, - camera.viewMatrix[1].xyz, - camera.viewMatrix[2].xyz - ) * model.normalMatrix; - - let viewTangent = normalize(viewSpaceNormMatrix * in.tangent.xyz); - let viewNormal = normalize(viewSpaceNormMatrix * in.normal); - let viewBitangent = normalize(cross(viewNormal, viewTangent)) * in.tangent.w; - - out.viewTangent = viewTangent; - out.viewBitangent = viewBitangent; - out.viewNormal = viewNormal; - out.instanceId = instanceId; - out.uv = in.uv; - #endif - - return out; - } - `;let Qs,Zs,en,no,io,oo,ao,uo;const Vc=Object.freeze({get defaultGLTFTransparentPBRMaterial(){return uo||(uo=new ht({debugLabel:"Forward Pass Default PBR Material",vertexShaderSrc:Bt(),vertexShaderEntryFn:ft,vertexBuffers:_e.defaultGLTFLayout,fragmentShaderSrc:Yp({hasPBRTextures:!0}),fragmentShaderEntryFn:Nc,targets:[{format:"rgba16float",blend:{color:{srcFactor:"src-alpha",dstFactor:"one-minus-src-alpha",operation:"add"},alpha:{srcFactor:"one",dstFactor:"one-minus-src-alpha",operation:"add"}}}],bindGroupLayouts:[J.defaultCameraPlusLightsBindGroupLayout,J.defaultModelBindGroupLayout,J.defaultModelMaterialBindGroupLayout],depthStencilState:{format:Xt.depthStencilFormat,depthWriteEnabled:!0,depthCompare:"less"},primitive:{cullMode:"none"}}),uo)},get defaultDeferredPBRMaterial(){if(Qs)return Qs;const s={compare:"always",failOp:"keep",depthFailOp:"keep",passOp:"replace"};return Qs=new ht({debugLabel:"Deferred Pass Default PBR Material",vertexShaderSrc:Bt(),vertexShaderEntryFn:ft,vertexBuffers:_e.defaultLayout,fragmentShaderSrc:qs(),fragmentShaderEntryFn:Vr,constants:{},targets:Jt,depthStencilState:{format:Xt.depthStencilFormat,depthWriteEnabled:!0,depthCompare:"less",stencilReadMask:0,stencilWriteMask:255,stencilBack:s,stencilFront:s}}),Qs},get defaultGLTFDeferredPBRMaterial(){if(Zs)return Zs;const s={compare:"always",failOp:"keep",depthFailOp:"keep",passOp:"replace"};return Zs=new ht({debugLabel:"Deferred Pass Default PBR Material",vertexShaderSrc:Bt(),vertexShaderEntryFn:ft,vertexBuffers:_e.defaultGLTFLayout,fragmentShaderSrc:qs(),fragmentShaderEntryFn:Vr,constants:{},targets:Jt,depthStencilState:{format:Xt.depthStencilFormat,depthWriteEnabled:!0,depthCompare:"less",stencilReadMask:0,stencilWriteMask:255,stencilBack:s,stencilFront:s}}),Zs},get defaultGLTFTexturedDeferredMaterial(){if(en)return en;const s={compare:"always",failOp:"keep",depthFailOp:"keep",passOp:"replace"};return en=new ht({debugLabel:"Default Textured Deferred PBR",vertexShaderSrc:Bt(),vertexShaderEntryFn:ft,vertexBuffers:_e.defaultGLTFLayout,fragmentShaderSrc:qs({hasPBRTextures:!0}),fragmentShaderEntryFn:Vr,constants:{},targets:Jt,depthStencilState:{format:Xt.depthStencilFormat,depthWriteEnabled:!0,depthCompare:"less",stencilReadMask:0,stencilWriteMask:255,stencilBack:s,stencilFront:s}}),en},get defaultDeferredInstancedMaterial(){return no||(no=new ht({debugLabel:"Material",vertexShaderSrc:Bt({isInstanced:!0}),vertexShaderEntryFn:ft,fragmentShaderSrc:qs(),fragmentShaderEntryFn:Vr,bindGroupLayouts:[J.defaultCameraBindGroupLayout,J.defaultModelBindGroupLayout,J.instancesBindGroupLayout],targets:Jt}),no)},get defaultShadowMaterial(){return oo||(oo=new ht({debugLabel:"Default Shadow Material",vertexShaderSrc:Bt(),vertexShaderEntryFn:ft,vertexBuffers:_e.defaultLayout}),oo)},get defaultGLTFShadowMaterial(){return io||(io=new ht({debugLabel:"Default Shadow Material",vertexShaderSrc:Bt({isShadow:!0}),vertexShaderEntryFn:ft,vertexBuffers:_e.defaultGLTFLayout,primitive:{cullMode:"front"},depthStencilState:{format:"depth32float",depthWriteEnabled:!0,depthCompare:"less"}}),io)},get defaultInstancedShadowMaterial(){return ao||(ao=new ht({debugLabel:"Default Shadow Material",vertexShaderSrc:Bt({isInstanced:!0}),vertexShaderEntryFn:ft,bindGroupLayouts:[J.defaultCameraBindGroupLayout,J.defaultModelBindGroupLayout,J.defaultModelMaterialBindGroupLayout,J.instancesBindGroupLayout],depthStencilState:{format:"depth24plus",depthWriteEnabled:!0,depthCompare:"less"}}),ao)}}),cn=class cn extends B{constructor(){super(),this.scene=new op,this.cpuAverage=new cs,this.gpuAverage=new cs,this.fpsDisplayAverage=new cs,this.resizeCounter=0,this.enableAnimation=!0,this.mainCamera=new Nn(70,1,.1,100),this.mainCamera.shouldJitter=!0,this.mainCamera.setPositionAsVec3(_c),this.mainCamera.setLookAt(0,2,0),this.mainCamera.updateViewMatrix(),this.mainCameraCtrl=new Mn(this.mainCamera,document.body,B.$canvas),this.mainCameraCtrl.startTick(),this.debugCamera=new Nn(70,1,.1,100),this.debugCamera.setPosition(6,12,1),this.debugCamera.setLookAt(0,7,0),this.debugCamera.updateViewMatrix();const e=new bd(yp,!0).getPoints(240);this.lightingManager=new Vi(e),this.scene.lightingManager=this.lightingManager,this.texturesDebugContainer=new Ui,this.timingDebugContainer=new ki,this.scene.skybox=new Lp;const t=new sp(pl);this.scene.addChild(t),t.setPositionY(2).updateWorldMatrix(),Promise.all([Be.load6SeparateHDRFacesAsCubeMapTexture(gp,512,!0,"Skybox Faces"),t.load()]).then(([r])=>{this.envDiffuseTexture=Ii.encode(r),this.envSpecularTexture=Fi.encode(r,256),this.envBdrfLutTexture=Oi.encode(),Ht.generateMipsForCubeTexture(this.envDiffuseTexture),this.scene.skybox.setTexture(this.envDiffuseTexture),this.renderPassComposer.getPass(N.DirectionalAmbientLighting).setDiffuseIBLTexture(this.envDiffuseTexture).setSpecularIBLTexture(this.envSpecularTexture).setBDRFLutTexture(this.envBdrfLutTexture),Y.removeTextureBytes(r),r.destroy(),t.setMaterial(Vc.defaultGLTFTexturedDeferredMaterial).setMaterial(Vc.defaultGLTFShadowMaterial,N.Shadow),setTimeout(()=>{document.getElementById("loader").classList.toggle("faded"),new es({durationMS:1500,delayMS:100,easeName:"sine_InOut",onUpdate:n=>{const i=D.lerp(xc,bp,n),o=Do(0,2,n);this.sunPositionX=i[0],this.sunPositionY=i[1],this.sunPositionZ=i[2],this.sunIntensity=o},onComplete:()=>{new es({durationMS:500,delayMS:200,easeName:"quad_Out",onUpdate:n=>{this.lightingManager.fireParticlesRevealFactor=n},onComplete:()=>{document.getElementById("logo").classList.toggle("faded"),this.mainCameraCtrl.revealTouchControls(),this.onIntroAnimComplete&&this.onIntroAnimComplete()}}).start()}}).start(),new es({durationMS:1800,easeName:"quad_Out",onUpdate:n=>{this.mainCamera.setPositionAsVec3(D.lerp(_c,xp,n)).updateViewMatrix()},onComplete:()=>{}}).start(),this.renderPassComposer.getPass(N.Blit).revealWithAnimation(800)},500)})}set sunPositionX(e){this.lightingManager.sunPositionX=e}set sunPositionY(e){this.lightingManager.sunPositionY=e}set sunPositionZ(e){this.lightingManager.sunPositionZ=e}set sunIntensity(e){this.lightingManager.sunIntensity=e}set ssaoEnabled(e){this.renderPassComposer.getPass(N.DirectionalAmbientLighting).ssaoMixFactor=e?1:0}set ssaoKernelSize(e){this.renderPassComposer.getPass(N.SSAO).kernelSize=e}set ssaoRadius(e){this.renderPassComposer.getPass(N.SSAO).radius=e}set ssaoStrength(e){this.renderPassComposer.getPass(N.SSAO).strength=e}set enableTAA(e){this.mainCamera.shouldJitter=e;const t=this.renderPassComposer.getPass(N.TAAResolve),r=this.renderPassComposer.getPass(N.BloomDownsample),n=this.renderPassComposer.getPass(N.Blit);t.enabled=e,e&&t.resetHistory(),r.resetInputs().addInputTexture(e?Fr:Dr),n.resetInputs().addInputTextures([Ur,e?Fr:Dr])}set debugGBuffer(e){e?(this.texturesDebugContainer.scrollIntoGbufferSection(),this.texturesDebugContainer.reveal()):this.texturesDebugContainer.hide()}set debugShadowMap(e){e?(this.texturesDebugContainer.scrollToShadowSection(),this.texturesDebugContainer.reveal()):this.texturesDebugContainer.hide()}set shadowMapSize(e){const t=this.renderPassComposer.getPass(N.Shadow);this.renderPassComposer.getPass(N.DirectionalAmbientLighting).resetInputs().addInputTextures([rt,xt,Ce,pr,Ir]),t.shadowMapSize=e}set debugShadowCascadeIndex(e){this.renderPassComposer.getPass(N.DirectionalAmbientLighting).debugShadowCascadeLayer=e}set debugLightsMask(e){this.renderPassComposer.getPass(N.PointLightsLighting).debugLightsMask=e}set render2ndFloorPoints(e){this.lightingManager.render2ndFloorParticles=e}set ssrIsHiZ(e){this.renderPassComposer.getPass(N.Reflection).isHiZ=e,this.renderPassComposer.getPass(N.HiZ).enabled=e}set ssrMaxIterations(e){this.renderPassComposer.getPass(N.Reflection).maxIterations=e}set debugMissedSSR(e){this.renderPassComposer.getPass(N.Reflection).debugMissedIntersections=e}set ssrEnabled(e){this.renderPassComposer.getPass(N.Reflection).enabled=e,this.renderPassComposer.getPass(N.TAAResolve).clearInputTextures().addInputTextures([e?Dr:Xe,zs])}set bloomEnabled(e){this.renderPassComposer.getPass(N.BloomDownsample).enabled=e,this.renderPassComposer.getPass(N.BloomUpsample).enabled=e,this.renderPassComposer.getPass(N.Blit).bloomEnabled=e}set bloomFilterRadius(e){this.renderPassComposer.getPass(N.BloomUpsample).bloomFilterRadius=e}set debugBoundingBoxes(e){this.renderPassComposer.getPass(N.DebugBounds).enabled=e}set debugMovementCurve(e){this.curveMoveLine.visible=e}toggleStatsVisibility(){this.timingDebugContainer.toggleVisibility()}recreateRenderComposer(e,t){var h;(h=this.renderPassComposer)==null||h.destroy(),this.renderPassComposer=new yd,this.renderPassComposer.setScene(this.scene);const r=new Ys(this.lightingManager.mainDirLight,e,t).addOutputTexture(Ir).setCamera(this.mainCamera),n=new Up(e,t).setCamera(this.mainCamera).addOutputTextures([rt,xt,zs,Ce]),i=new ro(e,t).setCamera(this.mainCamera).addInputTextures([rt,Ce]).addOutputTexture(bc),o=new Jp(e,t).addInputTexture(bc).addOutputTexture(pr),u=new Wi(r.shadowCascadesBuffer,e,t).setCamera(this.mainCamera).addInputTextures([rt,xt,Ce,pr,Ir]).addOutputTexture(Xe);this.envDiffuseTexture&&u.setDiffuseIBLTexture(this.envDiffuseTexture),this.envSpecularTexture&&u.setSpecularIBLTexture(this.envSpecularTexture),this.envBdrfLutTexture&&u.setBDRFLutTexture(this.envBdrfLutTexture);const l=new Zi(e,t).setCamera(this.mainCamera).addInputTextures([rt,xt,Ce,pr,Xe]).addOutputTexture(Xe),m=new Vp(e,t).setCamera(this.mainCamera).addInputTextures([Ce]).addOutputTexture(Ce).setLightsBuffer(this.lightingManager.gpuBuffer).updateLightsMaskBindGroup(),b=new eo(e,t).setCamera(this.mainCamera).addInputTextures([rt,xt,Ce,pr,Xe]).addOutputTexture(Xe),d=new Xp(e,t).setCamera(this.mainCamera).addInputTextures([Xe,Ce]).addOutputTextures([Xe,Ce]),x=new jp(e,t).setCamera(this.mainCamera).addInputTextures([Xe,Ce]).addOutputTextures([Xe,Ce]),g=new $i(e,t).addInputTexture(Ce).addOutputTexture(js),_=new qi(e,t).addInputTexture(js).addOutputTexture(js),w=new to(e,t).setCamera(this.mainCamera).addInputTextures([Xe,rt,xt,js]).addOutputTexture(Dr),f=new so(e,t).addInputTextures([Dr,zs]).addOutputTexture(Fr),p=new Xi(e,t).addInputTexture(Fr).addOutputTexture(Ur),a=new Dp(e,t).addInputTexture(Ur).addOutputTexture(Ur),c=new Ki(e,t,this.resizeCounter>0).addInputTextures([Ur,Fr]);this.renderPassComposer.addPass(r).addPass(n).addPass(i).addPass(o).addPass(u).addPass(l).addPass(m).addPass(b).addPass(d).addPass(x).addPass(g).addPass(_).addPass(w).addPass(f).addPass(p).addPass(a).addPass(c)}resize(e,t){this.debugCamera.onResize(e,t),this.mainCamera.onResize(e,t),this.recreateRenderComposer(e,t),this.resizeCounter++}async renderFrame(e){const t=.001*(e-B.elapsedTimeMs),r=t-B.prevTimeMs;B.prevTimeMs=t,B.elapsedTimeMs+=this.enableAnimation?r:0,B.deltaTimeMs=this.enableAnimation?Math.min(r,.5):0;const n=performance.now();this.debugCamera.onFrameStart(),this.mainCamera.onFrameStart();const i=B.device.createCommandEncoder({label:"Frame Command Encoder"});this.lightingManager.update(i),this.renderPassComposer.render(i),this.texturesDebugContainer.setTextureGBufferSection($.Albedo,this.renderPassComposer.getTexture(xt)).setTextureGBufferSection($.Normal,this.renderPassComposer.getTexture(rt)).setTextureGBufferSection($.Metallic,this.renderPassComposer.getTexture(rt)).setTextureGBufferSection($.Roughness,this.renderPassComposer.getTexture(rt)).setTextureGBufferSection($.AO,this.renderPassComposer.getTexture(pr)).setTextureGBufferSection($.Reflectance,this.renderPassComposer.getTexture(xt)).setTextureGBufferSection($.Depth,this.renderPassComposer.getTexture(Ce)).setTextureGBufferSection($.Velocity,this.renderPassComposer.getTexture(zs)).setTextureShadowSection($.ShadowDepthCascade0,this.renderPassComposer.getTexture(Ir)).setTextureShadowSection($.ShadowDepthCascade1,this.renderPassComposer.getTexture(Ir)).render(i),B.device.queue.submit([i.finish()]),this.renderPassComposer.onFrameEnd(),this.mainCamera.onFrameEnd(),this.debugCamera.onFrameEnd();const o=performance.now()-n;if(B.supportsGPUTimestampQuery){const[b,d]=await Promise.all([this.renderPassComposer.getPass(N.Shadow).getTimingResult(),this.renderPassComposer.getPass(N.Blit).getTimingResult()]),x=b.timings,g=(d.timings[1]-x[0])/1e6;this.gpuAverage.addSample(g)}this.cpuAverage.addSample(o),this.fpsDisplayAverage.addSample(1/r);const u=this.cpuAverage.get(),l=this.fpsDisplayAverage.get(),m=this.gpuAverage.get();l>70&&(this.mainCameraCtrl.speed=20),B.supportsGPUTimestampQuery&&this.timingDebugContainer.setDisplayValue(se.GPUTotal,m>0?`${m.toFixed(1)}ms`:"N/A"),this.timingDebugContainer.setDisplayValue(se.CPUTotal,u!==0?`${u.toFixed(1)}ms`:"N/A").setDisplayValue(se.FPS,l!==0?`${l.toFixed(1)}ms`:"N/A").setDisplayValue(se.VRAM,Y.getFormattedSize()).setDisplayValue(se.VisibleMeshes,`${this.scene.visibleNodesCount} / ${this.scene.nodesCount}`).setDisplayValue(se.LightsCount,this.lightingManager.lightsCount.toString()),B.frameIndex++}};cn.initialize=async e=>{if(!navigator.gpu)return;const t=await navigator.gpu.requestAdapter();return B.$canvas=e,B.canvasContext=e.getContext("webgpu"),B.pixelFormat=navigator.gpu.getPreferredCanvasFormat(),B.device=await t.requestDevice({requiredFeatures:[]}),B.supportsGPUTimestampQuery=!1,B.canvasContext.configure({device:B.device,format:B.pixelFormat,usage:GPUTextureUsage.RENDER_ATTACHMENT}),new cn};let Xt=cn;const Hr=document.getElementById("c"),ce=await Xt.initialize(Hr);if(ce===void 0){document.getElementById("no-webgpu-wrapper").style.setProperty("display","block"),document.getElementById("loader").classList.toggle("faded");const s=document.createElement("img");s.src="no-webgpu.png",document.getElementById("no-webgpu-preview").appendChild(s)}const ae={"Play Animation":!0,"Performance Stats":!1,"Enable TAA":!0,"Debug G-Buffer":!1,"Debug Shadow Map":!1,"Debug Shadow Cascades":!1,"Shadow Map Size":2048,"Debug Point Lights Mask":!1,"Render 2nd Floor Points":!0,"Enable SSR":!0,"SSR Method":"hi-z","SSR Max Iterations":30,"Debug No Info Rays":!1,"Sun Intensity":2,"Sun Position X":.1,"Sun Position Y":100,"Sun Position Z":.1,"Debug Skybox":!0,"Enable Bloom":!0,"Bloom Filter Radius":.0035,"Enable SSAO":!0,"SSAO Kernel Size":8,"SSAO Radius":.2,"SSAO Strength":3};function Hc(){const s=innerWidth,e=innerHeight,t=Math.min(devicePixelRatio,1.5);Hr.width=s*t,Hr.height=e*t,Hr.style.setProperty("width",`${s}px`),Hr.style.setProperty("height",`${e}px`),ce.resize(s*t,e*t)}function Jc(){document.getElementById("logo").classList.toggle("faded"),document.getElementById("timings-debug-container").classList.toggle("faded")}ce.onIntroAnimComplete=function(){const s=new ul({width:270});s.close(),s.add(ae,"Play Animation").onChange(l=>{ce.enableAnimation=l}),s.add(ae,"Performance Stats").onChange(()=>{ce.toggleStatsVisibility()}),s.add(ae,"Debug G-Buffer").onChange(l=>{ce.debugGBuffer=l,Jc(),l&&ae["Debug Shadow Map"]&&(ae["Debug Shadow Map"]=!1)}).listen();const e=s.addFolder("Lighting");e.open(),e.add(ae,"Sun Intensity",0,100).onChange(l=>{ce.sunIntensity=l}),e.add(ae,"Sun Position X",-60,60,.5).onChange(l=>{ce.sunPositionZ=l}),e.add(ae,"Sun Position Z",-150,150,.5).onChange(l=>{ce.sunPositionX=l});const t=s.addFolder("Shadow");t.open(),t.add(ae,"Debug Shadow Map").onChange(l=>{ce.debugShadowMap=l,Jc(),l&&ae["Debug G-Buffer"]&&(ae["Debug G-Buffer"]=!1)}).listen(),t.add(ae,"Shadow Map Size",[512,1024,2048,4096]).onChange(l=>{ce.shadowMapSize=parseInt(l)}),t.add(ae,"Debug Shadow Cascades").onChange(l=>{ce.debugShadowCascadeIndex=l});let r=ae["Enable Bloom"];e.add(ae,"Debug Point Lights Mask").onChange(l=>{l?(r=ae["Enable Bloom"],ae["Enable Bloom"]=!1,ce.bloomEnabled=!1):r&&(ae["Enable Bloom"]=!0,ce.bloomEnabled=!0),ce.debugLightsMask=l}),e.add(ae,"Render 2nd Floor Points").onChange(l=>{ce.render2ndFloorPoints=l});const n=s.addFolder("Screen space Ambient Occlusion");n.open(),n.add(ae,"Enable SSAO").onChange(l=>{ce.ssaoEnabled=l}),n.add(ae,"SSAO Kernel Size",8,128,1).onChange(l=>{ce.ssaoKernelSize=l}),n.add(ae,"SSAO Radius",0,1).onChange(l=>{ce.ssaoRadius=l}),n.add(ae,"SSAO Strength",0,5).onChange(l=>{ce.ssaoStrength=l});const i=s.addFolder("Screen space Reflections");i.open(),i.add(ae,"Enable SSR").onChange(l=>{ce.ssrEnabled=l}),i.add(ae,"SSR Method",["hi-z","linear"]).onChange(l=>{ce.ssrIsHiZ=l==="hi-z"}),i.add(ae,"SSR Max Iterations",0,1500,1).onChange(l=>{ce.ssrMaxIterations=l}),i.add(ae,"Debug No Info Rays").onChange(l=>{ce.debugMissedSSR=l});const o=s.addFolder("Bloom");o.open(),o.add(ae,"Enable Bloom").onChange(l=>{ce.bloomEnabled=l}).listen(),o.add(ae,"Bloom Filter Radius",.001,.005,5e-4).onChange(l=>{ce.bloomFilterRadius=l});const u=s.addFolder("Anti-Aliasing");u.open(),u.add(ae,"Enable TAA").onChange(l=>{ce.enableTAA=l})},requestAnimationFrame(function s(){const e=performance.now();ce.renderFrame(e),requestAnimationFrame(s)}),window.addEventListener("resize",Hc),Hc()})(); diff --git a/docs/assets/index-CYLuyR0P.js.gz b/docs/assets/index-CYLuyR0P.js.gz deleted file mode 100644 index a869fda..0000000 Binary files a/docs/assets/index-CYLuyR0P.js.gz and /dev/null differ diff --git a/docs/index.html b/docs/index.html index 91a6b7f..6beb0fa 100644 --- a/docs/index.html +++ b/docs/index.html @@ -6,7 +6,7 @@ WebGPU SSR - + diff --git a/docs/index.html.gz b/docs/index.html.gz index 200d9da..c818b89 100644 Binary files a/docs/index.html.gz and b/docs/index.html.gz differ