(function webpackUniversalModuleDefinition(root, factory) { if (typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if (typeof define === 'function' && define.amd) define([], factory); else if (typeof exports === 'object') exports['luma'] = factory(); else root['luma'] = factory();})(globalThis, function () { "use strict";var __exports__=(()=>{var to=Object.create;var he=Object.defineProperty;var no=Object.getOwnPropertyDescriptor;var ro=Object.getOwnPropertyNames;var oo=Object.getPrototypeOf,io=Object.prototype.hasOwnProperty;var so=(n,e,t)=>e in n?he(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var ao=(n,e)=>()=>(e||n((e={exports:{}}).exports,e),e.exports),co=(n,e)=>{for(var t in e)he(n,t,{get:e[t],enumerable:!0})},we=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of ro(e))!io.call(n,o)&&o!==t&&he(n,o,{get:()=>e[o],enumerable:!(r=no(e,o))||r.enumerable});return n},Le=(n,e,t)=>(we(n,e,"default"),t&&we(t,e,"default")),rt=(n,e,t)=>(t=n!=null?to(oo(n)):{},we(e||!n||!n.__esModule?he(t,"default",{value:n,enumerable:!0}):t,n)),lo=n=>we(he({},"__esModule",{value:!0}),n);var pn=(n,e,t)=>(so(n,typeof e!="symbol"?e+"":e,t),t);var ke=ao((Yi,dn)=>{dn.exports=globalThis.luma});var Pe={};co(Pe,{ShaderAssembler:()=>me,ShaderModuleInstance:()=>C,_ShaderModuleInstance:()=>C,_getDependencyGraph:()=>Se,_resolveModules:()=>ne,_warp:()=>fe,assembleShaderPairGLSL:()=>Te,brightnessContrast:()=>Jn,bulgePinch:()=>dr,capitalize:()=>Z,colorHalftone:()=>lr,combineInjects:()=>Ln,convertToVec4:()=>_t,denoise:()=>er,dirlight:()=>Kt,dirlight1:()=>Wr,dotScreen:()=>fr,edgeWork:()=>ur,fp32:()=>Hn,fp64:()=>Ar,fp64arithmetic:()=>nn,fxaa:()=>gr,generateShaderForModule:()=>Bn,geometry1:()=>yr,getPassthroughFS:()=>Un,getQualifierDetails:()=>On,getShaderInfo:()=>Ne,getShaderLayoutFromWGSL:()=>Vn,glsl:()=>mn,gouraudLighting:()=>$r,gouraudMaterial:()=>Zt,hexagonalPixelate:()=>_r,hueSaturation:()=>tr,ink:()=>hr,lighting:()=>Q,lights1:()=>te,magnify:()=>pr,noise:()=>nr,normalizeShaderModule:()=>Rn,pbr:()=>eo,pbrMaterial:()=>Zn,phongLighting:()=>Kr,phongMaterial:()=>Jt,picking:()=>Gn,project1:()=>nt,random:()=>q,sepia:()=>rr,swirl:()=>mr,tiltShift:()=>sr,triangleBlur:()=>ar,typeToChannelCount:()=>Dn,typeToChannelSuffix:()=>zn,vibrance:()=>or,vignette:()=>ir,zoomBlur:()=>cr});Le(Pe,rt(ke(),1));var mn=n=>`${n}`;function D(n,e){if(!n)throw new Error(e||"shadertools: assertion failed.")}var ot={number:{type:"number",validate(n,e){return Number.isFinite(n)&&typeof e=="object"&&(e.max===void 0||n<=e.max)&&(e.min===void 0||n>=e.min)}},array:{type:"array",validate(n,e){return Array.isArray(n)||ArrayBuffer.isView(n)}}};function xn(n){let e={};for(let[t,r]of Object.entries(n))e[t]=fo(r);return e}function vn(n,e,t){let r={};for(let[o,i]of Object.entries(e))n&&o in n&&!i.private?(i.validate&&D(i.validate(n[o],i),`${t}: invalid ${o}`),r[o]=n[o]):r[o]=i.value;return r}function fo(n){let e=gn(n);if(e!=="object")return{value:n,...ot[e],type:e};if(typeof n=="object")return n?n.type!==void 0?{...n,...ot[n.type],type:n.type}:n.value===void 0?{type:"object",value:n}:(e=gn(n.value),{...n,...ot[e],type:e}):{type:"object",value:null};throw new Error("props")}function gn(n){return Array.isArray(n)||ArrayBuffer.isView(n)?"array":typeof n}var An=`#ifdef MODULE_LOGDEPTH logdepth_adjustPosition(gl_Position); #endif `,yn=`#ifdef MODULE_MATERIAL gl_FragColor = material_filterColor(gl_FragColor); #endif #ifdef MODULE_LIGHTING gl_FragColor = lighting_filterColor(gl_FragColor); #endif #ifdef MODULE_FOG gl_FragColor = fog_filterColor(gl_FragColor); #endif #ifdef MODULE_PICKING gl_FragColor = picking_filterHighlightColor(gl_FragColor); gl_FragColor = picking_filterPickingColor(gl_FragColor); #endif #ifdef MODULE_LOGDEPTH logdepth_setFragDepth(); #endif `;var uo={vertex:An,fragment:yn},bn=/void\s+main\s*\([^)]*\)\s*\{\n?/,Pn=/}\n?[^{}]*$/,it=[],pe="__LUMA_INJECT_DECLARATIONS__";function wn(n){let e={vertex:{},fragment:{}};for(let t in n){let r=n[t],o=_o(t);typeof r=="string"&&(r={order:0,injection:r}),e[o][t]=r}return e}function _o(n){let e=n.slice(0,2);switch(e){case"vs":return"vertex";case"fs":return"fragment";default:throw new Error(e)}}function de(n,e,t,r=!1){let o=e==="vertex";for(let i in t){let a=t[i];a.sort((u,h)=>u.order-h.order),it.length=a.length;for(let u=0,h=a.length;uu+c));break;case"vs:#main-end":o&&(n=n.replace(Pn,u=>c+u));break;case"fs:#decl":o||(n=n.replace(pe,c));break;case"fs:#main-start":o||(n=n.replace(bn,u=>u+c));break;case"fs:#main-end":o||(n=n.replace(Pn,u=>c+u));break;default:n=n.replace(i,u=>u+c)}}return n=n.replace(pe,""),r&&(n=n.replace(/\}\s*$/,i=>i+uo[e])),n}function Ln(n){let e={};return D(Array.isArray(n)&&n.length>1),n.forEach(t=>{for(let r in t)e[r]=e[r]?`${e[r]} ${t[r]}`:t[r]}),e}var ho=1,C=class{name;vs;fs;getModuleUniforms;dependencies;deprecations;defines;injections;uniforms={};uniformTypes={};static instantiateModules(e){return e.map(t=>{if(t instanceof C)return t;D(typeof t!="string",`Shader module use by name is deprecated. Import shader module '${JSON.stringify(t)}' and use it directly.`),t.name||(console.warn("shader module has no name"),t.name=`shader-module-${ho++}`);let r=new C(t);return r.dependencies=C.instantiateModules(t.dependencies||[]),r})}constructor(e){let{name:t,vs:r,fs:o,dependencies:i=[],uniformTypes:a={},uniformPropTypes:c={},getUniforms:u,deprecations:h=[],defines:p={},inject:d={}}=e;D(typeof t=="string"),this.name=t,this.vs=r,this.fs=o,this.getModuleUniforms=u,this.dependencies=C.instantiateModules(i),this.deprecations=this._parseDeprecationDefinitions(h),this.defines=p,this.injections=wn(d),this.uniformTypes=a,c&&(this.uniforms=xn(c))}getModuleSource(e){let t;switch(e){case"vertex":t=this.vs||"";break;case"fragment":t=this.fs||"";break;default:D(!1)}let r=this.name.toUpperCase().replace(/[^0-9a-z]/gi,"_");return`// ----- MODULE ${this.name} --------------- #define MODULE_${r} ${t} `}getUniforms(e,t){return this.getModuleUniforms?this.getModuleUniforms(e,t):vn(e,this.uniforms,this.name)}getDefines(){return this.defines}checkDeprecations(e,t){this.deprecations.forEach(r=>{r.regex?.test(e)&&(r.deprecated?t.deprecated(r.old,r.new)():t.removed(r.old,r.new)())})}_parseDeprecationDefinitions(e){return e.forEach(t=>{switch(t.type){case"function":t.regex=new RegExp(`\\b${t.old}\\(`);break;default:t.regex=new RegExp(`${t.type} ${t.old};`)}}),e}_defaultGetUniforms(e={}){let t={},r=this.uniforms;for(let o in r){let i=r[o];o in e&&!i.private?(i.validate&&D(i.validate(e[o],i),`${this.name}: invalid ${o}`),t[o]=e[o]):t[o]=i.value}return t}};function st(n){if(n.source&&n.platformInfo.type==="webgpu")return{...n,vs:void 0,fs:void 0};if(!n.vs)throw new Error("no vertex shader");let e=kn(n.platformInfo,n.vs),t;return n.fs&&(t=kn(n.platformInfo,n.fs)),{...n,vs:e,fs:t}}function kn(n,e){if(typeof e=="string")return e;switch(n.type){case"webgpu":if(e?.wgsl)return e.wgsl;throw new Error("WebGPU does not support GLSL shaders");default:if(e?.glsl)return e.glsl;throw new Error("WebGL does not support WGSL shaders")}}function ne(n){let e=C.instantiateModules(n);return po(e)}function po(n){let e={},t={};return Se({modules:n,level:0,moduleMap:e,moduleDepth:t}),Object.keys(t).sort((r,o)=>t[o]-t[r]).map(r=>e[r])}function Se(n){let{modules:e,level:t,moduleMap:r,moduleDepth:o}=n;if(t>=5)throw new Error("Possible loop in shader dependency graph");for(let i of e)r[i.name]=i,(o[i.name]===void 0||o[i.name]a.order-c.order);for(let a of i)t+=` ${a.injection} `}o.footer&&(t+=` ${o.footer}`),t+=`} `}return t}function lt(n){let e={vertex:{},fragment:{}};for(let t of n){let r,o;typeof t!="string"?(r=t,o=r.hook):(r={},o=t),o=o.trim();let[i,a]=o.split(":"),c=o.replace(/\(.+/,""),u=Object.assign(r,{signature:a});switch(i){case"vs":e.vertex[c]=u;break;case"fs":e.fragment[c]=u;break;default:throw new Error(i)}}return e}function Ne(n,e){return{name:xo(n,e),language:"glsl",version:vo(n)}}function xo(n,e="unnamed"){let r=/#define[^\S\r\n]*SHADER_NAME[^\S\r\n]*([A-Za-z0-9_-]+)\s*/.exec(n);return r?r[1]:e}function vo(n){let e=100,t=n.match(/[^\s]+/g);if(t&&t.length>=2&&t[0]==="#version"){let r=parseInt(t[1],10);Number.isFinite(r)&&(e=r)}if(e!==100&&e!==300)throw new Error(`Invalid GLSL version ${e}`);return e}var In=` ${pe} `,Ao=`precision highp float; `;function Fn(n){let e=ne(n.modules||[]);return{source:ft(n.platformInfo,{...n,source:n.source,stage:"vertex",modules:e}),getUniforms:ut(e)}}function Cn(n){let e=ne(n.modules||[]);return{vs:ft(n.platformInfo,{...n,source:n.vs,stage:"vertex",modules:e}),fs:ft(n.platformInfo,{...n,source:n.fs,stage:"fragment",modules:e}),getUniforms:ut(e)}}function Te(n){let{vs:e,fs:t}=n,r=ne(n.modules||[]);return{vs:Mn(n.platformInfo,{...n,source:e,stage:"vertex",modules:r}),fs:Mn(n.platformInfo,{...n,source:t,stage:"fragment",modules:r}),getUniforms:ut(r)}}function ft(n,e){let{source:t,stage:r,modules:o,hookFunctions:i=[],inject:a={},log:c}=e;D(typeof t=="string","shader source must be a string");let u=t,h="",p=lt(i),d={},m={},x={};for(let g in a){let A=typeof a[g]=="string"?{injection:a[g],order:0}:a[g],L=/^(v|f)s:(#)?([\w-]+)$/.exec(g);if(L){let v=L[2],b=L[3];v?b==="decl"?m[g]=[A]:x[g]=[A]:d[g]=[A]}else x[g]=[A]}let w=n.type!=="webgpu"?o:[];for(let g of w){c&&g.checkDeprecations(u,c);let A=g.getModuleSource(r,"wgsl");h+=A;let L=g.injections[r];for(let v in L){let b=/^(v|f)s:#([\w-]+)$/.exec(v);if(b){let y=b[2]==="decl"?m:x;y[v]=y[v]||[],y[v].push(L[v])}else d[v]=d[v]||[],d[v].push(L[v])}}return h+=In,h=de(h,r,m),h+=ct(p[r],d),h+=u,h=de(h,r,x),h}function Mn(n,e){let{id:t,source:r,stage:o,language:i="glsl",modules:a,defines:c={},hookFunctions:u=[],inject:h={},prologue:p=!0,log:d}=e;D(typeof r=="string","shader source must be a string");let m=i==="glsl"?Ne(r).version:-1,x=n.shaderLanguageVersion,w=m===100?"#version 100":"#version 300 es",A=r.split(` `).slice(1).join(` `),L={};a.forEach(S=>{Object.assign(L,S.getDefines())}),Object.assign(L,c);let v="";switch(i){case"wgsl":break;case"glsl":v=p?`${w} // ----- PROLOGUE ------------------------- ${yo({id:t,source:r,stage:o})} ${`#define SHADER_TYPE_${o.toUpperCase()}`} ${Sn(n)} ${o==="fragment"?Ao:""} // ----- APPLICATION DEFINES ------------------------- ${bo(L)} `:`${w} `;break}let b=lt(u),P={},y={},k={};for(let S in h){let I=typeof h[S]=="string"?{injection:h[S],order:0}:h[S],M=/^(v|f)s:(#)?([\w-]+)$/.exec(S);if(M){let T=M[2],F=M[3];T?F==="decl"?y[S]=[I]:k[S]=[I]:P[S]=[I]}else k[S]=[I]}for(let S of a){d&&S.checkDeprecations(A,d);let I=S.getModuleSource(o);v+=I;let M=S.injections[o];for(let T in M){let F=/^(v|f)s:#([\w-]+)$/.exec(T);if(F){let R=F[2]==="decl"?y:k;R[T]=R[T]||[],R[T].push(M[T])}else P[T]=P[T]||[],P[T].push(M[T])}}return v+="// ----- MAIN SHADER SOURCE -------------------------",v+=In,v=de(v,o,y),v+=ct(b[o],P),v+=A,v=de(v,o,k),i==="glsl"&&m!==x&&(v=Tn(v,o)),v.trim()}function ut(n){return function(t){let r={};for(let o of n){let i=o.getUniforms(t,r);Object.assign(r,i)}return r}}function yo(n){let{id:e,source:t,stage:r}=n;return e&&t.indexOf("SHADER_NAME")===-1?` #define SHADER_NAME ${e}_${r} `:""}function bo(n={}){let e="";for(let t in n){let r=n[t];(r||Number.isFinite(r))&&(e+=`#define ${t.toUpperCase()} ${n[t]} `)}return e}var re=class{_hookFunctions=[];_defaultModules=[];static getDefaultShaderAssembler(){return re.defaultShaderAssembler=re.defaultShaderAssembler||new re,re.defaultShaderAssembler}addDefaultModule(e){this._defaultModules.find(t=>t.name===(typeof e=="string"?e:e.name))||this._defaultModules.push(e)}removeDefaultModule(e){let t=typeof e=="string"?e:e.name;this._defaultModules=this._defaultModules.filter(r=>r.name!==t)}addShaderHook(e,t){t&&(e=Object.assign(t,{hook:e})),this._hookFunctions.push(e)}assembleShader(e){let t=this._getModuleList(e.modules),r=this._hookFunctions,o=st(e);return{...Fn({platformInfo:e.platformInfo,...o,modules:t,hookFunctions:r}),modules:t}}assembleShaderPair(e){let t=st(e),r=this._getModuleList(e.modules),o=this._hookFunctions,{platformInfo:i}=e;return{...e.platformInfo.shaderLanguage==="wgsl"?Cn({platformInfo:i,...t,modules:r,hookFunctions:o}):Te({platformInfo:i,...t,modules:r,hookFunctions:o}),modules:r}}_getModuleList(e=[]){let t=new Array(this._defaultModules.length+e.length),r={},o=0;for(let i=0,a=this._defaultModules.length;i":"vec2","vec3":"vec3","vec4":"vec4","vec2":"ivec2","vec3":"ivec3","vec4":"ivec4","vec2":"uvec2","vec3":"uvec3","vec4":"uvec4","mat2x2":"mat2","mat2x3":"mat2x3","mat2x4":"mat2x4","mat3x2":"mat3x2","mat3x3":"mat3","mat3x4":"mat3x4","mat4x2":"mat4x2","mat4x3":"mat4x3","mat4x4":"mat4"}[n]}function Xn(n,e){return No(n,e)}function No(n,e){let t=[];t.push(`struct ${Z(n.name)} {`);for(let[r,o]of Object.entries(n?.uniformTypes||{})){let i=o;t.push(` ${r} : ${i};`)}return t.push("};"),t.push(`var ${n.name} : ${Z(n.name)};`),t.join(` `)}function Bn(n,e){switch(e.shaderLanguage){case"glsl":return Yn(n,e);case"wgsl":return Xn(n,e)}}var qn=rt(ke(),1);var ht=class{constructor(){this.constants=new Map,this.aliases=new Map,this.structs=new Map}},B=class{constructor(){}get isAstNode(){return!0}get astNodeType(){return""}evaluate(e){throw new Error("Cannot evaluate node")}evaluateString(e){return this.evaluate(e).toString()}search(e){}searchBlock(e,t){if(e){t(ae.instance);for(let r of e)r instanceof Array?this.searchBlock(r,t):r.search(t);t(ce.instance)}}},ae=class extends B{};ae.instance=new ae;var ce=class extends B{};ce.instance=new ce;var N=class extends B{constructor(){super()}},xe=class extends N{constructor(e,t,r,o,i,a){super(),this.calls=new Set,this.name=e,this.args=t,this.returnType=r,this.body=o,this.startLine=i,this.endLine=a}get astNodeType(){return"function"}search(e){this.searchBlock(this.body,e)}},pt=class extends N{constructor(e){super(),this.expression=e}get astNodeType(){return"staticAssert"}search(e){this.expression.search(e)}},dt=class extends N{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)}},mt=class extends N{constructor(e){super(),this.body=e}get astNodeType(){return"continuing"}search(e){this.searchBlock(this.body,e)}},gt=class extends N{constructor(e,t,r,o){super(),this.init=e,this.condition=t,this.increment=r,this.body=o}get astNodeType(){return"for"}search(e){var t,r,o;(t=this.init)===null||t===void 0||t.search(e),(r=this.condition)===null||r===void 0||r.search(e),(o=this.increment)===null||o===void 0||o.search(e),this.searchBlock(this.body,e)}},H=class extends N{constructor(e,t,r,o,i){super(),this.name=e,this.type=t,this.storage=r,this.access=o,this.value=i}get astNodeType(){return"var"}search(e){var t;e(this),(t=this.value)===null||t===void 0||t.search(e)}},Ee=class extends N{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)}},ve=class extends N{constructor(e,t,r,o,i){super(),this.name=e,this.type=t,this.storage=r,this.access=o,this.value=i}get astNodeType(){return"let"}search(e){var t;e(this),(t=this.value)===null||t===void 0||t.search(e)}},Me=class extends N{constructor(e,t,r,o,i){super(),this.name=e,this.type=t,this.storage=r,this.access=o,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)}},le;(function(n){n.increment="++",n.decrement="--"})(le||(le={}));(function(n){function e(t){let r=t;if(r=="parse")throw new Error("Invalid value for IncrementOperator");return n[r]}n.parse=e})(le||(le={}));var xt=class extends N{constructor(e,t){super(),this.operator=e,this.variable=t}get astNodeType(){return"increment"}search(e){this.variable.search(e)}},Ae;(function(n){n.assign="=",n.addAssign="+=",n.subtractAssin="-=",n.multiplyAssign="*=",n.divideAssign="/=",n.moduloAssign="%=",n.andAssign="&=",n.orAssign="|=",n.xorAssign="^=",n.shiftLeftAssign="<<=",n.shiftRightAssign=">>="})(Ae||(Ae={}));(function(n){function e(t){let r=t;if(r=="parse")throw new Error("Invalid value for AssignOperator");return r}n.parse=e})(Ae||(Ae={}));var vt=class extends N{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)}},Ie=class extends N{constructor(e,t){super(),this.name=e,this.args=t}get astNodeType(){return"call"}search(e){for(let t of this.args)t.search(e);e(this)}},At=class extends N{constructor(e,t){super(),this.body=e,this.continuing=t}get astNodeType(){return"loop"}},yt=class extends N{constructor(e,t){super(),this.condition=e,this.body=t}get astNodeType(){return"body"}},bt=class extends N{constructor(e,t,r,o){super(),this.condition=e,this.body=t,this.elseif=r,this.else=o}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)}},Pt=class extends N{constructor(e){super(),this.value=e}get astNodeType(){return"return"}search(e){var t;(t=this.value)===null||t===void 0||t.search(e)}},wt=class extends N{constructor(e){super(),this.name=e}get astNodeType(){return"enable"}},Lt=class extends N{constructor(e){super(),this.extensions=e}get astNodeType(){return"requires"}},kt=class extends N{constructor(e,t){super(),this.severity=e,this.rule=t}get astNodeType(){return"diagnostic"}},Fe=class extends N{constructor(e,t){super(),this.name=e,this.type=t}get astNodeType(){return"alias"}},St=class extends N{constructor(){super()}get astNodeType(){return"discard"}},Nt=class extends N{constructor(){super()}get astNodeType(){return"break"}},Tt=class extends N{constructor(){super()}get astNodeType(){return"continue"}},G=class extends N{constructor(e){super(),this.name=e}get astNodeType(){return"type"}get isStruct(){return!1}get isArray(){return!1}},V=class extends G{constructor(e,t,r,o){super(e),this.members=t,this.startLine=r,this.endLine=o}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)}},Be=class extends B{constructor(){super()}},Rt=class extends Be{constructor(e,t){super(),this.selector=e,this.body=t}get astNodeType(){return"case"}search(e){this.searchBlock(this.body,e)}},Ot=class extends Be{constructor(e){super(),this.body=e}get astNodeType(){return"default"}search(e){this.searchBlock(this.body,e)}},Ut=class extends B{constructor(e,t,r){super(),this.name=e,this.type=t,this.attributes=r}get astNodeType(){return"argument"}},zt=class extends B{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)}},Dt=class extends B{constructor(e,t,r){super(),this.name=e,this.type=t,this.attributes=r}get astNodeType(){return"member"}},Yt=class extends B{constructor(e,t){super(),this.name=e,this.value=t}get astNodeType(){return"attribute"}},_,f;(function(n){n[n.token=0]="token",n[n.keyword=1]="keyword",n[n.reserved=2]="reserved"})(f||(f={}));var l=class{constructor(e,t,r){this.name=e,this.type=t,this.rule=r}toString(){return this.name}},s=class{};_=s;s.none=new l("",f.reserved,"");s.eof=new l("EOF",f.token,"");s.reserved={asm:new l("asm",f.reserved,"asm"),bf16:new l("bf16",f.reserved,"bf16"),do:new l("do",f.reserved,"do"),enum:new l("enum",f.reserved,"enum"),f16:new l("f16",f.reserved,"f16"),f64:new l("f64",f.reserved,"f64"),handle:new l("handle",f.reserved,"handle"),i8:new l("i8",f.reserved,"i8"),i16:new l("i16",f.reserved,"i16"),i64:new l("i64",f.reserved,"i64"),mat:new l("mat",f.reserved,"mat"),premerge:new l("premerge",f.reserved,"premerge"),regardless:new l("regardless",f.reserved,"regardless"),typedef:new l("typedef",f.reserved,"typedef"),u8:new l("u8",f.reserved,"u8"),u16:new l("u16",f.reserved,"u16"),u64:new l("u64",f.reserved,"u64"),unless:new l("unless",f.reserved,"unless"),using:new l("using",f.reserved,"using"),vec:new l("vec",f.reserved,"vec"),void:new l("void",f.reserved,"void")};s.keywords={array:new l("array",f.keyword,"array"),atomic:new l("atomic",f.keyword,"atomic"),bool:new l("bool",f.keyword,"bool"),f32:new l("f32",f.keyword,"f32"),i32:new l("i32",f.keyword,"i32"),mat2x2:new l("mat2x2",f.keyword,"mat2x2"),mat2x3:new l("mat2x3",f.keyword,"mat2x3"),mat2x4:new l("mat2x4",f.keyword,"mat2x4"),mat3x2:new l("mat3x2",f.keyword,"mat3x2"),mat3x3:new l("mat3x3",f.keyword,"mat3x3"),mat3x4:new l("mat3x4",f.keyword,"mat3x4"),mat4x2:new l("mat4x2",f.keyword,"mat4x2"),mat4x3:new l("mat4x3",f.keyword,"mat4x3"),mat4x4:new l("mat4x4",f.keyword,"mat4x4"),ptr:new l("ptr",f.keyword,"ptr"),sampler:new l("sampler",f.keyword,"sampler"),sampler_comparison:new l("sampler_comparison",f.keyword,"sampler_comparison"),struct:new l("struct",f.keyword,"struct"),texture_1d:new l("texture_1d",f.keyword,"texture_1d"),texture_2d:new l("texture_2d",f.keyword,"texture_2d"),texture_2d_array:new l("texture_2d_array",f.keyword,"texture_2d_array"),texture_3d:new l("texture_3d",f.keyword,"texture_3d"),texture_cube:new l("texture_cube",f.keyword,"texture_cube"),texture_cube_array:new l("texture_cube_array",f.keyword,"texture_cube_array"),texture_multisampled_2d:new l("texture_multisampled_2d",f.keyword,"texture_multisampled_2d"),texture_storage_1d:new l("texture_storage_1d",f.keyword,"texture_storage_1d"),texture_storage_2d:new l("texture_storage_2d",f.keyword,"texture_storage_2d"),texture_storage_2d_array:new l("texture_storage_2d_array",f.keyword,"texture_storage_2d_array"),texture_storage_3d:new l("texture_storage_3d",f.keyword,"texture_storage_3d"),texture_depth_2d:new l("texture_depth_2d",f.keyword,"texture_depth_2d"),texture_depth_2d_array:new l("texture_depth_2d_array",f.keyword,"texture_depth_2d_array"),texture_depth_cube:new l("texture_depth_cube",f.keyword,"texture_depth_cube"),texture_depth_cube_array:new l("texture_depth_cube_array",f.keyword,"texture_depth_cube_array"),texture_depth_multisampled_2d:new l("texture_depth_multisampled_2d",f.keyword,"texture_depth_multisampled_2d"),texture_external:new l("texture_external",f.keyword,"texture_external"),u32:new l("u32",f.keyword,"u32"),vec2:new l("vec2",f.keyword,"vec2"),vec3:new l("vec3",f.keyword,"vec3"),vec4:new l("vec4",f.keyword,"vec4"),bitcast:new l("bitcast",f.keyword,"bitcast"),block:new l("block",f.keyword,"block"),break:new l("break",f.keyword,"break"),case:new l("case",f.keyword,"case"),continue:new l("continue",f.keyword,"continue"),continuing:new l("continuing",f.keyword,"continuing"),default:new l("default",f.keyword,"default"),diagnostic:new l("diagnostic",f.keyword,"diagnostic"),discard:new l("discard",f.keyword,"discard"),else:new l("else",f.keyword,"else"),enable:new l("enable",f.keyword,"enable"),fallthrough:new l("fallthrough",f.keyword,"fallthrough"),false:new l("false",f.keyword,"false"),fn:new l("fn",f.keyword,"fn"),for:new l("for",f.keyword,"for"),function:new l("function",f.keyword,"function"),if:new l("if",f.keyword,"if"),let:new l("let",f.keyword,"let"),const:new l("const",f.keyword,"const"),loop:new l("loop",f.keyword,"loop"),while:new l("while",f.keyword,"while"),private:new l("private",f.keyword,"private"),read:new l("read",f.keyword,"read"),read_write:new l("read_write",f.keyword,"read_write"),return:new l("return",f.keyword,"return"),requires:new l("requires",f.keyword,"requires"),storage:new l("storage",f.keyword,"storage"),switch:new l("switch",f.keyword,"switch"),true:new l("true",f.keyword,"true"),alias:new l("alias",f.keyword,"alias"),type:new l("type",f.keyword,"type"),uniform:new l("uniform",f.keyword,"uniform"),var:new l("var",f.keyword,"var"),override:new l("override",f.keyword,"override"),workgroup:new l("workgroup",f.keyword,"workgroup"),write:new l("write",f.keyword,"write"),r8unorm:new l("r8unorm",f.keyword,"r8unorm"),r8snorm:new l("r8snorm",f.keyword,"r8snorm"),r8uint:new l("r8uint",f.keyword,"r8uint"),r8sint:new l("r8sint",f.keyword,"r8sint"),r16uint:new l("r16uint",f.keyword,"r16uint"),r16sint:new l("r16sint",f.keyword,"r16sint"),r16float:new l("r16float",f.keyword,"r16float"),rg8unorm:new l("rg8unorm",f.keyword,"rg8unorm"),rg8snorm:new l("rg8snorm",f.keyword,"rg8snorm"),rg8uint:new l("rg8uint",f.keyword,"rg8uint"),rg8sint:new l("rg8sint",f.keyword,"rg8sint"),r32uint:new l("r32uint",f.keyword,"r32uint"),r32sint:new l("r32sint",f.keyword,"r32sint"),r32float:new l("r32float",f.keyword,"r32float"),rg16uint:new l("rg16uint",f.keyword,"rg16uint"),rg16sint:new l("rg16sint",f.keyword,"rg16sint"),rg16float:new l("rg16float",f.keyword,"rg16float"),rgba8unorm:new l("rgba8unorm",f.keyword,"rgba8unorm"),rgba8unorm_srgb:new l("rgba8unorm_srgb",f.keyword,"rgba8unorm_srgb"),rgba8snorm:new l("rgba8snorm",f.keyword,"rgba8snorm"),rgba8uint:new l("rgba8uint",f.keyword,"rgba8uint"),rgba8sint:new l("rgba8sint",f.keyword,"rgba8sint"),bgra8unorm:new l("bgra8unorm",f.keyword,"bgra8unorm"),bgra8unorm_srgb:new l("bgra8unorm_srgb",f.keyword,"bgra8unorm_srgb"),rgb10a2unorm:new l("rgb10a2unorm",f.keyword,"rgb10a2unorm"),rg11b10float:new l("rg11b10float",f.keyword,"rg11b10float"),rg32uint:new l("rg32uint",f.keyword,"rg32uint"),rg32sint:new l("rg32sint",f.keyword,"rg32sint"),rg32float:new l("rg32float",f.keyword,"rg32float"),rgba16uint:new l("rgba16uint",f.keyword,"rgba16uint"),rgba16sint:new l("rgba16sint",f.keyword,"rgba16sint"),rgba16float:new l("rgba16float",f.keyword,"rgba16float"),rgba32uint:new l("rgba32uint",f.keyword,"rgba32uint"),rgba32sint:new l("rgba32sint",f.keyword,"rgba32sint"),rgba32float:new l("rgba32float",f.keyword,"rgba32float"),static_assert:new l("static_assert",f.keyword,"static_assert")};s.tokens={decimal_float_literal:new l("decimal_float_literal",f.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 l("hex_float_literal",f.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 l("int_literal",f.token,/-?0x[0-9a-fA-F]+|0i?|-?[1-9][0-9]*i?/),uint_literal:new l("uint_literal",f.token,/0x[0-9a-fA-F]+u|0u|[1-9][0-9]*u/),ident:new l("ident",f.token,/[_a-zA-Z][0-9a-zA-Z_]*/),and:new l("and",f.token,"&"),and_and:new l("and_and",f.token,"&&"),arrow:new l("arrow ",f.token,"->"),attr:new l("attr",f.token,"@"),forward_slash:new l("forward_slash",f.token,"/"),bang:new l("bang",f.token,"!"),bracket_left:new l("bracket_left",f.token,"["),bracket_right:new l("bracket_right",f.token,"]"),brace_left:new l("brace_left",f.token,"{"),brace_right:new l("brace_right",f.token,"}"),colon:new l("colon",f.token,":"),comma:new l("comma",f.token,","),equal:new l("equal",f.token,"="),equal_equal:new l("equal_equal",f.token,"=="),not_equal:new l("not_equal",f.token,"!="),greater_than:new l("greater_than",f.token,">"),greater_than_equal:new l("greater_than_equal",f.token,">="),shift_right:new l("shift_right",f.token,">>"),less_than:new l("less_than",f.token,"<"),less_than_equal:new l("less_than_equal",f.token,"<="),shift_left:new l("shift_left",f.token,"<<"),modulo:new l("modulo",f.token,"%"),minus:new l("minus",f.token,"-"),minus_minus:new l("minus_minus",f.token,"--"),period:new l("period",f.token,"."),plus:new l("plus",f.token,"+"),plus_plus:new l("plus_plus",f.token,"++"),or:new l("or",f.token,"|"),or_or:new l("or_or",f.token,"||"),paren_left:new l("paren_left",f.token,"("),paren_right:new l("paren_right",f.token,")"),semicolon:new l("semicolon",f.token,";"),star:new l("star",f.token,"*"),tilde:new l("tilde",f.token,"~"),underscore:new l("underscore",f.token,"_"),xor:new l("xor",f.token,"^"),plus_equal:new l("plus_equal",f.token,"+="),minus_equal:new l("minus_equal",f.token,"-="),times_equal:new l("times_equal",f.token,"*="),division_equal:new l("division_equal",f.token,"/="),modulo_equal:new l("modulo_equal",f.token,"%="),and_equal:new l("and_equal",f.token,"&="),or_equal:new l("or_equal",f.token,"|="),xor_equal:new l("xor_equal",f.token,"^="),shift_right_equal:new l("shift_right_equal",f.token,">>="),shift_left_equal:new l("shift_left_equal",f.token,"<<=")};s.simpleTokens={"@":_.tokens.attr,"{":_.tokens.brace_left,"}":_.tokens.brace_right,":":_.tokens.colon,",":_.tokens.comma,"(":_.tokens.paren_left,")":_.tokens.paren_right,";":_.tokens.semicolon};s.literalTokens={"&":_.tokens.and,"&&":_.tokens.and_and,"->":_.tokens.arrow,"/":_.tokens.forward_slash,"!":_.tokens.bang,"[":_.tokens.bracket_left,"]":_.tokens.bracket_right,"=":_.tokens.equal,"==":_.tokens.equal_equal,"!=":_.tokens.not_equal,">":_.tokens.greater_than,">=":_.tokens.greater_than_equal,">>":_.tokens.shift_right,"<":_.tokens.less_than,"<=":_.tokens.less_than_equal,"<<":_.tokens.shift_left,"%":_.tokens.modulo,"-":_.tokens.minus,"--":_.tokens.minus_minus,".":_.tokens.period,"+":_.tokens.plus,"++":_.tokens.plus_plus,"|":_.tokens.or,"||":_.tokens.or_or,"*":_.tokens.star,"~":_.tokens.tilde,_:_.tokens.underscore,"^":_.tokens.xor,"+=":_.tokens.plus_equal,"-=":_.tokens.minus_equal,"*=":_.tokens.times_equal,"/=":_.tokens.division_equal,"%=":_.tokens.modulo_equal,"&=":_.tokens.and_equal,"|=":_.tokens.or_equal,"^=":_.tokens.xor_equal,">>=":_.tokens.shift_right_equal,"<<=":_.tokens.shift_left_equal};s.regexTokens={decimal_float_literal:_.tokens.decimal_float_literal,hex_float_literal:_.tokens.hex_float_literal,int_literal:_.tokens.int_literal,uint_literal:_.tokens.uint_literal,ident:_.tokens.ident};s.storage_class=[_.keywords.function,_.keywords.private,_.keywords.workgroup,_.keywords.uniform,_.keywords.storage];s.access_mode=[_.keywords.read,_.keywords.write,_.keywords.read_write];s.sampler_type=[_.keywords.sampler,_.keywords.sampler_comparison];s.sampled_texture_type=[_.keywords.texture_1d,_.keywords.texture_2d,_.keywords.texture_2d_array,_.keywords.texture_3d,_.keywords.texture_cube,_.keywords.texture_cube_array];s.multisampled_texture_type=[_.keywords.texture_multisampled_2d];s.storage_texture_type=[_.keywords.texture_storage_1d,_.keywords.texture_storage_2d,_.keywords.texture_storage_2d_array,_.keywords.texture_storage_3d];s.depth_texture_type=[_.keywords.texture_depth_2d,_.keywords.texture_depth_2d_array,_.keywords.texture_depth_cube,_.keywords.texture_depth_cube_array,_.keywords.texture_depth_multisampled_2d];s.texture_external_type=[_.keywords.texture_external];s.any_texture_type=[..._.sampled_texture_type,..._.multisampled_texture_type,..._.storage_texture_type,..._.depth_texture_type,..._.texture_external_type];s.texel_format=[_.keywords.r8unorm,_.keywords.r8snorm,_.keywords.r8uint,_.keywords.r8sint,_.keywords.r16uint,_.keywords.r16sint,_.keywords.r16float,_.keywords.rg8unorm,_.keywords.rg8snorm,_.keywords.rg8uint,_.keywords.rg8sint,_.keywords.r32uint,_.keywords.r32sint,_.keywords.r32float,_.keywords.rg16uint,_.keywords.rg16sint,_.keywords.rg16float,_.keywords.rgba8unorm,_.keywords.rgba8unorm_srgb,_.keywords.rgba8snorm,_.keywords.rgba8uint,_.keywords.rgba8sint,_.keywords.bgra8unorm,_.keywords.bgra8unorm_srgb,_.keywords.rgb10a2unorm,_.keywords.rg11b10float,_.keywords.rg32uint,_.keywords.rg32sint,_.keywords.rg32float,_.keywords.rgba16uint,_.keywords.rgba16sint,_.keywords.rgba16float,_.keywords.rgba32uint,_.keywords.rgba32sint,_.keywords.rgba32float];s.const_literal=[_.tokens.int_literal,_.tokens.uint_literal,_.tokens.decimal_float_literal,_.tokens.hex_float_literal,_.keywords.true,_.keywords.false];s.literal_or_ident=[_.tokens.ident,_.tokens.int_literal,_.tokens.uint_literal,_.tokens.decimal_float_literal,_.tokens.hex_float_literal];s.element_count_expression=[_.tokens.int_literal,_.tokens.uint_literal,_.tokens.ident];s.template_types=[_.keywords.vec2,_.keywords.vec3,_.keywords.vec4,_.keywords.mat2x2,_.keywords.mat2x3,_.keywords.mat2x4,_.keywords.mat3x2,_.keywords.mat3x3,_.keywords.mat3x4,_.keywords.mat4x2,_.keywords.mat4x3,_.keywords.mat4x4,_.keywords.atomic,_.keywords.bitcast,..._.any_texture_type];s.attribute_name=[_.tokens.ident,_.keywords.block,_.keywords.diagnostic];s.assignment_operators=[_.tokens.equal,_.tokens.plus_equal,_.tokens.minus_equal,_.tokens.times_equal,_.tokens.division_equal,_.tokens.modulo_equal,_.tokens.and_equal,_.tokens.or_equal,_.tokens.xor_equal,_.tokens.shift_right_equal,_.tokens.shift_left_equal];s.increment_operators=[_.tokens.plus_plus,_.tokens.minus_minus];var Qe=class{constructor(e,t,r){this.type=e,this.lexeme=t,this.line=r}toString(){return this.lexeme}isTemplateType(){return s.template_types.indexOf(this.type)!=-1}isArrayType(){return this.type==s.keywords.array}isArrayOrTemplateType(){return this.isArrayType()||this.isTemplateType()}},Xt=class{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 Qe(s.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}else if(this._peekAhead()=="*"){this._advance();let a=1;for(;a>0;){if(this._isAtEnd())return!0;if(e=this._advance(),e==` `)this._line++;else if(e=="*"){if(this._peekAhead()=="/"&&(this._advance(),a--,a==0))return!0}else e=="/"&&this._peekAhead()=="*"&&(this._advance(),a++)}return!0}}let t=s.simpleTokens[e];if(t)return this._addToken(t),!0;let r=s.none,o=this._isAlpha(e),i=e==="_";if(this._isAlphaNumeric(e)){let a=this._peekAhead();for(;this._isAlphaNumeric(a);)e+=this._advance(),a=this._peekAhead()}if(o){let a=s.keywords[e];if(a)return this._addToken(a),!0}if(o||i)return this._addToken(s.tokens.ident),!0;for(;;){let a=this._findType(e),c=this._peekAhead();if(e==">"&&(c==">"||c=="=")){let u=!1,h=this._tokens.length-1;for(let p=0;p<5&&h>=0;++p,--h)if(this._tokens[h].type===s.tokens.less_than){h>0&&this._tokens[h-1].isArrayOrTemplateType()&&(u=!0);break}if(u)return this._addToken(a),!0}if(a===s.none){let u=e,h=0,p=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){let t=this._source.substring(this._start,this._current);this._tokens.push(new Qe(e,t,this._line))}},Bt=class{constructor(){this._tokens=[],this._current=0,this._currentLine=0,this._context=new ht,this._deferArrayCountEval=[]}parse(e){this._initialize(e),this._deferArrayCountEval.length=0;let t=[];for(;!this._isAtEnd();){let r=this._global_decl_or_directive();if(!r)break;t.push(r)}if(this._deferArrayCountEval.length>0){for(let r of this._deferArrayCountEval){let o=r.arrayType,i=r.countNode;if(i instanceof ye){let c=i.name,u=this._context.constants.get(c);if(u)try{let h=u.evaluate(this._context);o.count=h}catch{}}}this._deferArrayCountEval.length=0}return t}_initialize(e){if(e)if(typeof e=="string"){let t=new Xt(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==s.eof}_match(e){if(e instanceof l)return this._check(e)?(this._advance(),!0):!1;for(let t=0,r=e.length;t'.");let o=this._paren_expression();return new Mt(r,o)}let e=this._type_decl(),t=this._argument_expression_list();return new It(e,t)}_argument_expression_list(){if(!this._match(s.tokens.paren_left))return null;let e=[];do{if(this._check(s.tokens.paren_right))break;let t=this._short_circuit_or_expression();e.push(t)}while(this._match(s.tokens.comma));return this._consume(s.tokens.paren_right,"Expected ')' for agument list"),e}_optional_paren_expression(){this._match(s.tokens.paren_left);let e=this._short_circuit_or_expression();return this._match(s.tokens.paren_right),new Ye([e])}_paren_expression(){this._consume(s.tokens.paren_left,"Expected '('.");let e=this._short_circuit_or_expression();return this._consume(s.tokens.paren_right,"Expected ')'."),new Ye([e])}_struct_decl(){if(!this._match(s.keywords.struct))return null;let e=this._currentLine,t=this._consume(s.tokens.ident,"Expected name for struct.").toString();this._consume(s.tokens.brace_left,"Expected '{' for struct body.");let r=[];for(;!this._check(s.tokens.brace_right);){let a=this._attribute(),c=this._consume(s.tokens.ident,"Expected variable name.").toString();this._consume(s.tokens.colon,"Expected ':' for struct member type.");let u=this._attribute(),h=this._type_decl();h!=null&&(h.attributes=u),this._check(s.tokens.brace_right)?this._match(s.tokens.comma):this._consume(s.tokens.comma,"Expected ',' for struct member."),r.push(new Dt(c,h,a))}this._consume(s.tokens.brace_right,"Expected '}' after struct body.");let o=this._currentLine,i=new V(t,r,e,o);return this._context.structs.set(t,i),i}_global_variable_decl(){let e=this._variable_decl();return e&&this._match(s.tokens.equal)&&(e.value=this._const_expression()),e}_override_variable_decl(){let e=this._override_decl();return e&&this._match(s.tokens.equal)&&(e.value=this._const_expression()),e}_global_const_decl(){if(!this._match(s.keywords.const))return null;let e=this._consume(s.tokens.ident,"Expected variable name"),t=null;if(this._match(s.tokens.colon)){let i=this._attribute();t=this._type_decl(),t!=null&&(t.attributes=i)}let r=null;if(this._match(s.tokens.equal)){let i=this._short_circuit_or_expression();if(i instanceof $)r=i;else if(i instanceof ze&&i.initializer instanceof $)r=i.initializer;else try{let a=i.evaluate(this._context);r=new De(a)}catch{r=i}}let o=new Me(e.toString(),t,"","",r);return this._context.constants.set(o.name,o),o}_global_let_decl(){if(!this._match(s.keywords.let))return null;let e=this._consume(s.tokens.ident,"Expected variable name"),t=null;if(this._match(s.tokens.colon)){let o=this._attribute();t=this._type_decl(),t!=null&&(t.attributes=o)}let r=null;return this._match(s.tokens.equal)&&(r=this._const_expression()),new ve(e.toString(),t,"","",r)}_const_expression(){if(this._match(s.const_literal))return new Oe(this._previous().toString());let e=this._type_decl();this._consume(s.tokens.paren_left,"Expected '('.");let t=[];for(;!this._check(s.tokens.paren_right)&&(t.push(this._const_expression()),!!this._check(s.tokens.comma));)this._advance();return this._consume(s.tokens.paren_right,"Expected ')'."),new $(e,t)}_variable_decl(){if(!this._match(s.keywords.var))return null;let e="",t="";this._match(s.tokens.less_than)&&(e=this._consume(s.storage_class,"Expected storage_class.").toString(),this._match(s.tokens.comma)&&(t=this._consume(s.access_mode,"Expected access_mode.").toString()),this._consume(s.tokens.greater_than,"Expected '>'."));let r=this._consume(s.tokens.ident,"Expected variable name"),o=null;if(this._match(s.tokens.colon)){let i=this._attribute();o=this._type_decl(),o!=null&&(o.attributes=i)}return new H(r.toString(),o,e,t,null)}_override_decl(){if(!this._match(s.keywords.override))return null;let e=this._consume(s.tokens.ident,"Expected variable name"),t=null;if(this._match(s.tokens.colon)){let r=this._attribute();t=this._type_decl(),t!=null&&(t.attributes=r)}return new Ee(e.toString(),t,null)}_diagnostic(){this._consume(s.tokens.paren_left,"Expected '('");let e=this._consume(s.tokens.ident,"Expected severity control name.");this._consume(s.tokens.comma,"Expected ','");let t=this._consume(s.tokens.ident,"Expected diagnostic rule name.");return this._consume(s.tokens.paren_right,"Expected ')'"),new kt(e.toString(),t.toString())}_enable_directive(){let e=this._consume(s.tokens.ident,"identity expected.");return new wt(e.toString())}_requires_directive(){let e=[this._consume(s.tokens.ident,"identity expected.").toString()];for(;this._match(s.tokens.comma);){let t=this._consume(s.tokens.ident,"identity expected.");e.push(t.toString())}return new Lt(e)}_type_alias(){let e=this._consume(s.tokens.ident,"identity expected.");this._consume(s.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);let r=new Fe(e.toString(),t);return this._context.aliases.set(r.name,r),r}_type_decl(){if(this._check([s.tokens.ident,...s.texel_format,s.keywords.bool,s.keywords.f32,s.keywords.i32,s.keywords.u32])){let r=this._advance(),o=r.toString();return this._context.structs.has(o)?this._context.structs.get(o):this._context.aliases.has(o)?this._context.aliases.get(o).type:new G(r.toString())}let e=this._texture_sampler_types();if(e)return e;if(this._check(s.template_types)){let r=this._advance().toString(),o=null,i=null;return this._match(s.tokens.less_than)&&(o=this._type_decl(),i=null,this._match(s.tokens.comma)&&(i=this._consume(s.access_mode,"Expected access_mode for pointer").toString()),this._consume(s.tokens.greater_than,"Expected '>' for type.")),new Ce(r,o,i)}if(this._match(s.keywords.ptr)){let r=this._previous().toString();this._consume(s.tokens.less_than,"Expected '<' for pointer.");let o=this._consume(s.storage_class,"Expected storage_class for pointer");this._consume(s.tokens.comma,"Expected ',' for pointer.");let i=this._type_decl(),a=null;return this._match(s.tokens.comma)&&(a=this._consume(s.access_mode,"Expected access_mode for pointer").toString()),this._consume(s.tokens.greater_than,"Expected '>' for pointer."),new Et(r,o.toString(),i,a)}let t=this._attribute();if(this._match(s.keywords.array)){let r=null,o=-1,i=this._previous(),a=null;if(this._match(s.tokens.less_than)){r=this._type_decl(),this._context.aliases.has(r.name)&&(r=this._context.aliases.get(r.name).type);let u="";if(this._match(s.tokens.comma)){a=this._shift_expression();try{u=a.evaluate(this._context).toString(),a=null}catch{u="1"}}this._consume(s.tokens.greater_than,"Expected '>' for array."),o=u?parseInt(u):0}let c=new Re(i.toString(),t,r,o);return a&&this._deferArrayCountEval.push({arrayType:c,countNode:a}),c}return null}_texture_sampler_types(){if(this._match(s.sampler_type))return new J(this._previous().toString(),null,null);if(this._match(s.depth_texture_type))return new J(this._previous().toString(),null,null);if(this._match(s.sampled_texture_type)||this._match(s.multisampled_texture_type)){let e=this._previous();this._consume(s.tokens.less_than,"Expected '<' for sampler type.");let t=this._type_decl();return this._consume(s.tokens.greater_than,"Expected '>' for sampler type."),new J(e.toString(),t,null)}if(this._match(s.storage_texture_type)){let e=this._previous();this._consume(s.tokens.less_than,"Expected '<' for sampler type.");let t=this._consume(s.texel_format,"Invalid texel format.").toString();this._consume(s.tokens.comma,"Expected ',' after texel format.");let r=this._consume(s.access_mode,"Expected access mode for storage texture type.").toString();return this._consume(s.tokens.greater_than,"Expected '>' for sampler type."),new J(e.toString(),t,r)}return null}_attribute(){let e=[];for(;this._match(s.tokens.attr);){let t=this._consume(s.attribute_name,"Expected attribute name"),r=new Yt(t.toString(),null);if(this._match(s.tokens.paren_left)){if(r.value=this._consume(s.literal_or_ident,"Expected attribute value").toString(),this._check(s.tokens.comma)){this._advance();do{let o=this._consume(s.literal_or_ident,"Expected attribute value").toString();r.value instanceof Array||(r.value=[r.value]),r.value.push(o)}while(this._match(s.tokens.comma))}this._consume(s.tokens.paren_right,"Expected ')'")}e.push(r)}return e.length==0?null:e}},K=class{constructor(e,t){this.name=e,this.attributes=t,this.size=0}get isArray(){return!1}get isStruct(){return!1}get isTemplate(){return!1}},qe=class{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.format: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}},oe=class extends K{constructor(e,t){super(e,t),this.members=[],this.align=0,this.startLine=-1,this.endLine=-1,this.inUse=!1}get isStruct(){return!0}},ge=class extends K{constructor(e,t){super(e,t),this.count=0,this.stride=0}get isArray(){return!0}},Ve=class extends K{constructor(e,t,r,o){super(e,r),this.format=t,this.access=o}get isTemplate(){return!0}},j;(function(n){n[n.Uniform=0]="Uniform",n[n.Storage=1]="Storage",n[n.Texture=2]="Texture",n[n.Sampler=3]="Sampler",n[n.StorageTexture=4]="StorageTexture"})(j||(j={}));var ie=class{constructor(e,t,r,o,i,a,c){this.name=e,this.type=t,this.group=r,this.binding=o,this.attributes=i,this.resourceType=a,this.access=c}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.format: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}},Qt=class{constructor(e,t){this.name=e,this.type=t}},se=class{constructor(e,t){this.align=e,this.size=t}},qt=class{constructor(e,t,r,o){this.name=e,this.type=t,this.locationType=r,this.location=o,this.interpolation=null}},He=class{constructor(e,t,r,o){this.name=e,this.type=t,this.locationType=r,this.location=o}},Vt=class{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}},Ht=class{constructor(){this.vertex=[],this.fragment=[],this.compute=[]}},Gt=class{constructor(e,t,r,o){this.name=e,this.type=t,this.attributes=r,this.id=o}},Wt=class{constructor(e){this.resources=null,this.inUse=!1,this.info=null,this.node=e}},X=class{constructor(e){this.uniforms=[],this.storage=[],this.textures=[],this.samplers=[],this.aliases=[],this.overrides=[],this.structs=[],this.entry=new Ht,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){let r=new Bt().parse(e);for(let o of r)o instanceof xe&&this._functions.set(o.name,new Wt(o));for(let o of r)if(o instanceof V){let i=this._getTypeInfo(o,null);i instanceof oe&&this.structs.push(i)}for(let o of r){if(o instanceof Fe){this.aliases.push(this._getAliasInfo(o));continue}if(o instanceof Ee){let i=o,a=this._getAttributeNum(i.attributes,"id",0),c=i.type!=null?this._getTypeInfo(i.type,i.attributes):null;this.overrides.push(new Gt(i.name,c,i.attributes,a));continue}if(this._isUniformVar(o)){let i=o,a=this._getAttributeNum(i.attributes,"group",0),c=this._getAttributeNum(i.attributes,"binding",0),u=this._getTypeInfo(i.type,i.attributes),h=new ie(i.name,u,a,c,i.attributes,j.Uniform,i.access);this.uniforms.push(h);continue}if(this._isStorageVar(o)){let i=o,a=this._getAttributeNum(i.attributes,"group",0),c=this._getAttributeNum(i.attributes,"binding",0),u=this._getTypeInfo(i.type,i.attributes),h=this._isStorageTexture(u),p=new ie(i.name,u,a,c,i.attributes,h?j.StorageTexture:j.Storage,i.access);this.storage.push(p);continue}if(this._isTextureVar(o)){let i=o,a=this._getAttributeNum(i.attributes,"group",0),c=this._getAttributeNum(i.attributes,"binding",0),u=this._getTypeInfo(i.type,i.attributes),h=this._isStorageTexture(u),p=new ie(i.name,u,a,c,i.attributes,h?j.StorageTexture:j.Texture,i.access);h?this.storage.push(p):this.textures.push(p);continue}if(this._isSamplerVar(o)){let i=o,a=this._getAttributeNum(i.attributes,"group",0),c=this._getAttributeNum(i.attributes,"binding",0),u=this._getTypeInfo(i.type,i.attributes),h=new ie(i.name,u,a,c,i.attributes,j.Sampler,i.access);this.samplers.push(h);continue}if(o instanceof xe){let i=this._getAttribute(o,"vertex"),a=this._getAttribute(o,"fragment"),c=this._getAttribute(o,"compute"),u=i||a||c,h=new Vt(o.name,u?.name);h.startLine=o.startLine,h.endLine=o.endLine,this.functions.push(h),this._functions.get(o.name).info=h,u&&(this._functions.get(o.name).inUse=!0,h.inUse=!0,h.resources=this._findResources(o,!!u),h.inputs=this._getInputs(o.args),h.outputs=this._getOutputs(o.returnType),this.entry[u.name].push(h));continue}}for(let o of this._functions.values())o.info&&(o.info.inUse=o.inUse,this._addCalls(o.node,o.info.calls));for(let o of this.uniforms)this._markStructsInUse(o.type);for(let o of this.storage)this._markStructsInUse(o.type)}_markStructsInUse(e){if(e.isStruct){e.inUse=!0;for(let 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{let t=this._getAlias(e.name);t&&this._markStructsInUse(t)}}_addCalls(e,t){var r;for(let o of e.calls){let i=(r=this._functions.get(o.name))===null||r===void 0?void 0:r.info;i&&t.add(i)}}findResource(e,t){for(let r of this.uniforms)if(r.group==e&&r.binding==t)return r;for(let r of this.storage)if(r.group==e&&r.binding==t)return r;for(let r of this.textures)if(r.group==e&&r.binding==t)return r;for(let r of this.samplers)if(r.group==e&&r.binding==t)return r;return null}_findResource(e){for(let t of this.uniforms)if(t.name==e)return t;for(let t of this.storage)if(t.name==e)return t;for(let t of this.textures)if(t.name==e)return t;for(let t of this.samplers)if(t.name==e)return t;return null}_markStructsFromAST(e){let t=this._getTypeInfo(e,null);this._markStructsInUse(t)}_findResources(e,t){let r=[],o=this,i=[];return e.search(a=>{if(a instanceof ae)i.push({});else if(a instanceof ce)i.pop();else if(a instanceof H){let c=a;t&&c.type!==null&&this._markStructsFromAST(c.type),i.length>0&&(i[i.length-1][c.name]=c)}else if(a instanceof $){let c=a;t&&c.type!==null&&this._markStructsFromAST(c.type)}else if(a instanceof ve){let c=a;t&&c.type!==null&&this._markStructsFromAST(c.type),i.length>0&&(i[i.length-1][c.name]=c)}else if(a instanceof ye){let c=a;if(i.length>0&&i[i.length-1][c.name])return;let u=o._findResource(c.name);u&&r.push(u)}else if(a instanceof Ue){let c=a,u=o._functions.get(c.name);u&&(t&&(u.inUse=!0),e.calls.add(u.node),u.resources===null&&(u.resources=o._findResources(u.node,t)),r.push(...u.resources))}else if(a instanceof Ie){let c=a,u=o._functions.get(c.name);u&&(t&&(u.inUse=!0),e.calls.add(u.node),u.resources===null&&(u.resources=o._findResources(u.node,t)),r.push(...u.resources))}}),[...new Map(r.map(a=>[a.name,a])).values()]}getBindGroups(){let e=[];function t(r,o){r>=e.length&&(e.length=r+1),e[r]===void 0&&(e[r]=[]),o>=e[r].length&&(e[r].length=o+1)}for(let r of this.uniforms){t(r.group,r.binding);let o=e[r.group];o[r.binding]=r}for(let r of this.storage){t(r.group,r.binding);let o=e[r.group];o[r.binding]=r}for(let r of this.textures){t(r.group,r.binding);let o=e[r.group];o[r.binding]=r}for(let r of this.samplers){t(r.group,r.binding);let o=e[r.group];o[r.binding]=r}return e}_getOutputs(e,t=void 0){if(t===void 0&&(t=[]),e instanceof V)this._getStructOutputs(e,t);else{let r=this._getOutputInfo(e);r!==null&&t.push(r)}return t}_getStructOutputs(e,t){for(let r of e.members)if(r.type instanceof V)this._getStructOutputs(r.type,t);else{let o=this._getAttribute(r,"location")||this._getAttribute(r,"builtin");if(o!==null){let i=this._getTypeInfo(r.type,r.type.attributes),a=this._parseInt(o.value),c=new He(r.name,i,o.name,a);t.push(c)}}}_getOutputInfo(e){let t=this._getAttribute(e,"location")||this._getAttribute(e,"builtin");if(t!==null){let r=this._getTypeInfo(e,e.attributes),o=this._parseInt(t.value);return new He("",r,t.name,o)}return null}_getInputs(e,t=void 0){t===void 0&&(t=[]);for(let r of e)if(r.type instanceof V)this._getStructInputs(r.type,t);else{let o=this._getInputInfo(r);o!==null&&t.push(o)}return t}_getStructInputs(e,t){for(let r of e.members)if(r.type instanceof V)this._getStructInputs(r.type,t);else{let o=this._getInputInfo(r);o!==null&&t.push(o)}}_getInputInfo(e){let t=this._getAttribute(e,"location")||this._getAttribute(e,"builtin");if(t!==null){let r=this._getAttribute(e,"interpolation"),o=this._getTypeInfo(e.type,e.attributes),i=this._parseInt(t.value),a=new qt(e.name,o,t.name,i);return r!==null&&(a.interpolation=this._parseString(r.value)),a}return null}_parseString(e){return e instanceof Array&&(e=e[0]),e}_parseInt(e){e instanceof Array&&(e=e[0]);let t=parseInt(e);return isNaN(t)?e:t}_getAlias(e){for(let t of this.aliases)if(t.name==e)return t.type;return null}_getAliasInfo(e){return new Qt(e.name,this._getTypeInfo(e.type,null))}_getTypeInfo(e,t){if(this._types.has(e))return this._types.get(e);if(e instanceof Re){let o=e,i=this._getTypeInfo(o.format,o.attributes),a=new ge(o.name,t);return a.format=i,a.count=o.count,this._types.set(e,a),this._updateTypeInfo(a),a}if(e instanceof V){let o=e,i=new oe(o.name,t);i.startLine=o.startLine,i.endLine=o.endLine;for(let a of o.members){let c=this._getTypeInfo(a.type,a.attributes);i.members.push(new qe(a.name,c,a.attributes))}return this._types.set(e,i),this._updateTypeInfo(i),i}if(e instanceof J){let o=e,i=o.format instanceof G,a=o.format?i?this._getTypeInfo(o.format,null):new K(o.format,null):null,c=new Ve(o.name,a,t,o.access);return this._types.set(e,c),this._updateTypeInfo(c),c}if(e instanceof Ce){let o=e,i=o.format?this._getTypeInfo(o.format,null):null,a=new Ve(o.name,i,t,o.access);return this._types.set(e,a),this._updateTypeInfo(a),a}let r=new K(e.name,t);return this._types.set(e,r),this._updateTypeInfo(r),r}_updateTypeInfo(e){var t,r;let o=this._getTypeSize(e);if(e.size=(t=o?.size)!==null&&t!==void 0?t:0,e instanceof ge){let i=this._getTypeSize(e.format);e.stride=(r=i?.size)!==null&&r!==void 0?r:0,this._updateTypeInfo(e.format)}e instanceof oe&&this._updateStructInfo(e)}_updateStructInfo(e){var t;let r=0,o=0,i=0,a=0;for(let c=0,u=e.members.length;cn.name);X._samplerTypes=s.sampler_type.map(n=>n.name);function Vn(n){let e={attributes:[],bindings:[]},t;try{t=To(n)}catch(i){return qn.log.error(i.message)(),e}for(let i of t.uniforms){let a=[];for(let c of i.type?.members||[])a.push({name:c.name,type:Qn(c.type)});e.bindings.push({type:"uniform",name:i.name,location:i.binding,group:i.group,members:a})}let r=t.entry.vertex[0],o=r?.inputs.length||0;for(let i=0;i`:n.name}function To(n){try{return new X(n)}catch(e){if(e instanceof Error)throw e;let t="WGSL parse error";throw typeof e=="object"&&e?.message&&(t+=`: ${e.message} `),typeof e=="object"&&e?.token&&(t+=e.token.line||""),new Error(t,{cause:e})}}var Eo=`float random(vec3 scale, float seed) { return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed); } `,q={name:"random",fs:Eo};var Mo=`#ifdef LUMA_FP32_TAN_PRECISION_WORKAROUND const float TWO_PI = 6.2831854820251465; const float PI_2 = 1.5707963705062866; const float PI_16 = 0.1963495463132858; const float SIN_TABLE_0 = 0.19509032368659973; const float SIN_TABLE_1 = 0.3826834261417389; const float SIN_TABLE_2 = 0.5555702447891235; const float SIN_TABLE_3 = 0.7071067690849304; const float COS_TABLE_0 = 0.9807852506637573; const float COS_TABLE_1 = 0.9238795042037964; const float COS_TABLE_2 = 0.8314695954322815; const float COS_TABLE_3 = 0.7071067690849304; const float INVERSE_FACTORIAL_3 = 1.666666716337204e-01; const float INVERSE_FACTORIAL_5 = 8.333333767950535e-03; const float INVERSE_FACTORIAL_7 = 1.9841270113829523e-04; const float INVERSE_FACTORIAL_9 = 2.75573188446287533e-06; float sin_taylor_fp32(float a) { float r, s, t, x; if (a == 0.0) { return 0.0; } x = -a * a; s = a; r = a; r = r * x; t = r * INVERSE_FACTORIAL_3; s = s + t; r = r * x; t = r * INVERSE_FACTORIAL_5; s = s + t; r = r * x; t = r * INVERSE_FACTORIAL_7; s = s + t; r = r * x; t = r * INVERSE_FACTORIAL_9; s = s + t; return s; } void sincos_taylor_fp32(float a, out float sin_t, out float cos_t) { if (a == 0.0) { sin_t = 0.0; cos_t = 1.0; } sin_t = sin_taylor_fp32(a); cos_t = sqrt(1.0 - sin_t * sin_t); } float tan_taylor_fp32(float a) { float sin_a; float cos_a; if (a == 0.0) { return 0.0; } float z = floor(a / TWO_PI); float r = a - TWO_PI * z; float t; float q = floor(r / PI_2 + 0.5); int j = int(q); if (j < -2 || j > 2) { return 1.0 / 0.0; } t = r - PI_2 * q; q = floor(t / PI_16 + 0.5); int k = int(q); int abs_k = int(abs(float(k))); if (abs_k > 4) { return 1.0 / 0.0; } else { t = t - PI_16 * q; } float u = 0.0; float v = 0.0; float sin_t, cos_t; float s, c; sincos_taylor_fp32(t, sin_t, cos_t); if (k == 0) { s = sin_t; c = cos_t; } else { if (abs(float(abs_k) - 1.0) < 0.5) { u = COS_TABLE_0; v = SIN_TABLE_0; } else if (abs(float(abs_k) - 2.0) < 0.5) { u = COS_TABLE_1; v = SIN_TABLE_1; } else if (abs(float(abs_k) - 3.0) < 0.5) { u = COS_TABLE_2; v = SIN_TABLE_2; } else if (abs(float(abs_k) - 4.0) < 0.5) { u = COS_TABLE_3; v = SIN_TABLE_3; } if (k > 0) { s = u * sin_t + v * cos_t; c = u * cos_t - v * sin_t; } else { s = u * sin_t - v * cos_t; c = u * cos_t + v * sin_t; } } if (j == 0) { sin_a = s; cos_a = c; } else if (j == 1) { sin_a = c; cos_a = -s; } else if (j == -1) { sin_a = -c; cos_a = s; } else { sin_a = -s; cos_a = -c; } return sin_a / cos_a; } #endif float tan_fp32(float a) { #ifdef LUMA_FP32_TAN_PRECISION_WORKAROUND return tan_taylor_fp32(a); #else return tan(a); #endif } `,Hn={name:"fp32",vs:Mo};var Io=[0,1,1,1],Fo=`uniform pickingUniforms { float isActive; float isAttribute; float isHighlightActive; float useFloatColors; vec3 highlightedObjectColor; vec4 highlightColor; } picking; out vec4 picking_vRGBcolor_Avalid; vec3 picking_normalizeColor(vec3 color) { return picking.useFloatColors > 0.5 ? color : color / 255.0; } vec4 picking_normalizeColor(vec4 color) { return picking.useFloatColors > 0.5 ? color : color / 255.0; } bool picking_isColorZero(vec3 color) { return dot(color, vec3(1.0)) < 0.00001; } bool picking_isColorValid(vec3 color) { return dot(color, vec3(1.0)) > 0.00001; } bool isVertexHighlighted(vec3 vertexColor) { vec3 highlightedObjectColor = picking_normalizeColor(picking.highlightedObjectColor); return bool(picking.isHighlightActive) && picking_isColorZero(abs(vertexColor - highlightedObjectColor)); } void picking_setPickingColor(vec3 pickingColor) { pickingColor = picking_normalizeColor(pickingColor); if (bool(picking.isActive)) { picking_vRGBcolor_Avalid.a = float(picking_isColorValid(pickingColor)); if (!bool(picking.isAttribute)) { picking_vRGBcolor_Avalid.rgb = pickingColor; } } else { picking_vRGBcolor_Avalid.a = float(isVertexHighlighted(pickingColor)); } } void picking_setPickingAttribute(float value) { if (bool(picking.isAttribute)) { picking_vRGBcolor_Avalid.r = value; } } void picking_setPickingAttribute(vec2 value) { if (bool(picking.isAttribute)) { picking_vRGBcolor_Avalid.rg = value; } } void picking_setPickingAttribute(vec3 value) { if (bool(picking.isAttribute)) { picking_vRGBcolor_Avalid.rgb = value; } } `,Co=`uniform pickingUniforms { float isActive; float isAttribute; float isHighlightActive; float useFloatColors; vec3 highlightedObjectColor; vec4 highlightColor; } picking; in vec4 picking_vRGBcolor_Avalid; vec4 picking_filterHighlightColor(vec4 color) { if (picking.isActive > 0.5) { return color; } bool selected = bool(picking_vRGBcolor_Avalid.a); if (selected) { float highLightAlpha = picking.highlightColor.a; float blendedAlpha = highLightAlpha + color.a * (1.0 - highLightAlpha); float highLightRatio = highLightAlpha / blendedAlpha; vec3 blendedRGB = mix(color.rgb, picking.highlightColor.rgb, highLightRatio); return vec4(blendedRGB, blendedAlpha); } else { return color; } } vec4 picking_filterPickingColor(vec4 color) { if (bool(picking.isActive)) { if (picking_vRGBcolor_Avalid.a == 0.0) { discard; } return picking_vRGBcolor_Avalid; } return color; } vec4 picking_filterColor(vec4 color) { vec4 highlightColor = picking_filterHighlightColor(color); return picking_filterPickingColor(highlightColor); } `,Gn={name:"picking",vs:Fo,fs:Co,uniformTypes:{isActive:"f32",isAttribute:"f32",isHighlightActive:"f32",useFloatColors:"f32",highlightedObjectColor:"vec3",highlightColor:"vec4"},defaultUniforms:{isActive:!1,isAttribute:!1,isHighlightActive:!1,useFloatColors:!0,highlightedObjectColor:[0,0,0],highlightColor:Io},getUniforms:Ro};function Ro(n={},e){let t={};if(n.highlightedObjectColor!==void 0)if(n.highlightedObjectColor===null)t.isHighlightActive=!1;else{t.isHighlightActive=!0;let r=n.highlightedObjectColor.slice(0,3);t.highlightedObjectColor=r}if(n.highlightColor){let r=Array.from(n.highlightColor,o=>o/255);Number.isFinite(r[3])||(r[3]=1),t.highlightColor=r}return n.isActive!==void 0&&(t.isActive=Boolean(n.isActive),t.isAttribute=Boolean(n.isAttribute)),n.useFloatColors!==void 0&&(t.useFloatColors=Boolean(n.useFloatColors)),t}var jt=`precision highp int; struct AmbientLight { vec3 color; }; struct PointLight { vec3 color; vec3 position; vec3 attenuation; }; struct DirectionalLight { vec3 color; vec3 direction; }; uniform lightingUniforms { int enabled; int lightType; int directionalLightCount; int pointLightCount; vec3 ambientColor; vec3 lightColor0; vec3 lightPosition0; vec3 lightDirection0; vec3 lightAttenuation0; vec3 lightColor1; vec3 lightPosition1; vec3 lightDirection1; vec3 lightAttenuation1; vec3 lightColor2; vec3 lightPosition2; vec3 lightDirection2; vec3 lightAttenuation2; } lighting; PointLight lighting_getPointLight(int index) { switch (index) { case 0: return PointLight(lighting.lightColor0, lighting.lightPosition0, lighting.lightAttenuation0); case 1: return PointLight(lighting.lightColor1, lighting.lightPosition1, lighting.lightAttenuation1); case 2: default: return PointLight(lighting.lightColor2, lighting.lightPosition2, lighting.lightAttenuation2); } } DirectionalLight lighting_getDirectionalLight(int index) { switch (index) { case 0: return DirectionalLight(lighting.lightColor0, lighting.lightDirection0); case 1: return DirectionalLight(lighting.lightColor1, lighting.lightDirection1); case 2: default: return DirectionalLight(lighting.lightColor2, lighting.lightDirection2); } } float getPointLightAttenuation(PointLight pointLight, float distance) { return pointLight.attenuation.x + pointLight.attenuation.y * distance + pointLight.attenuation.z * distance * distance; } `;var Wn=rt(ke(),1),jn=3,Oo=255,be;(function(n){n[n.POINT=0]="POINT",n[n.DIRECTIONAL=1]="DIRECTIONAL"})(be||(be={}));var Q={name:"lighting",vs:jt,fs:jt,getUniforms(n,e){return Uo(n)},defines:{MAX_LIGHTS:jn},uniformTypes:{enabled:"i32",lightType:"i32",directionalLightCount:"i32",pointLightCount:"i32",ambientLightColor:"vec3",lightColor0:"vec3",lightPosition0:"vec3",lightDirection0:"vec3",lightAttenuation0:"vec3",lightColor1:"vec3",lightPosition1:"vec3",lightDirection1:"vec3",lightAttenuation1:"vec3",lightColor2:"vec3",lightPosition2:"vec3",lightDirection2:"vec3",lightAttenuation2:"vec3"},defaultUniforms:{enabled:1,lightType:be.POINT,directionalLightCount:0,pointLightCount:0,ambientLightColor:[.1,.1,.1],lightColor0:[1,1,1],lightPosition0:[1,1,2],lightDirection0:[1,1,1],lightAttenuation0:[1,0,0],lightColor1:[1,1,1],lightPosition1:[1,1,2],lightDirection1:[1,1,1],lightAttenuation1:[1,0,0],lightColor2:[1,1,1],lightPosition2:[1,1,2],lightDirection2:[1,1,1],lightAttenuation2:[1,0,0]}};function Uo(n,e={}){if(n=n&&{...n},!n)return{...Q.defaultUniforms};n.lights&&(n={...n,...Do(n.lights),lights:void 0});let{ambientLight:t,pointLights:r,directionalLights:o}=n||{};if(!(t||r&&r.length>0||o&&o.length>0))return{...Q.defaultUniforms,enabled:0};let a={...Q.defaultUniforms,...e,...zo({ambientLight:t,pointLights:r,directionalLights:o})};return n.enabled!==void 0&&(a.enabled=n.enabled?1:0),a}function zo({ambientLight:n,pointLights:e=[],directionalLights:t=[]}){let r={};r.ambientLightColor=$t(n);let o=0;for(let i of e){r.lightType=be.POINT;let a=o;r[`lightColor${a}`]=$t(i),r[`lightPosition${a}`]=i.position,r[`lightAttenuation${a}`]=i.attenuation||[1,0,0],o++}for(let i of t){r.lightType=be.DIRECTIONAL;let a=o;r[`lightColor${a}`]=$t(i),r[`lightDirection${a}`]=i.direction,o++}return o>jn&&Wn.log.warn("MAX_LIGHTS exceeded")(),r.directionalLightCount=t.length,r.pointLightCount=e.length,r}function Do(n){let e={pointLights:[],directionalLights:[]};for(let t of n||[])switch(t.type){case"ambient":e.ambientLight=t;break;case"directional":e.directionalLights?.push(t);break;case"point":e.pointLights?.push(t);break;default:}return e}function $t(n={}){let{color:e=[0,0,0],intensity:t=1}=n;return e.map(r=>r*t/Oo)}var Yo=`out vec3 dirlight_vNormal; void dirlight_setNormal(vec3 normal) { dirlight_vNormal = normalize(normal); } `,Xo=`uniform dirlightUniforms { vec3 lightDirection; } dirlight; in vec3 dirlight_vNormal; vec4 dirlight_filterColor(vec4 color) { float d = abs(dot(dirlight_vNormal, normalize(dirlight.lightDirection))); return vec4(color.rgb * d, color.a); } `,Kt={name:"dirlight",dependencies:[],vs:Yo,fs:Xo,uniformTypes:{lightDirection:"vec3"},defaultUniforms:{lightDirection:[1,1,2]},getUniforms:Bo};function Bo(n=Kt.defaultUniforms){let e={};return n.lightDirection&&(e.dirlight_uLightDirection=n.lightDirection),e}var Ge=`uniform phongMaterialUniforms { uniform float ambient; uniform float diffuse; uniform float shininess; uniform vec3 specularColor; } material; `,We=`uniform phongMaterialUniforms { uniform float ambient; uniform float diffuse; uniform float shininess; uniform vec3 specularColor; } material; vec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 view_direction, vec3 normal_worldspace, vec3 color) { vec3 halfway_direction = normalize(light_direction + view_direction); float lambertian = dot(light_direction, normal_worldspace); float specular = 0.0; if (lambertian > 0.0) { float specular_angle = max(dot(normal_worldspace, halfway_direction), 0.0); specular = pow(specular_angle, material.shininess); } lambertian = max(lambertian, 0.0); return (lambertian * material.diffuse * surfaceColor + specular * material.specularColor) * color; } vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) { vec3 lightColor = surfaceColor; if (lighting.enabled == 0) { return lightColor; } vec3 view_direction = normalize(cameraPosition - position_worldspace); lightColor = material.ambient * surfaceColor * lighting.ambientColor; for (int i = 0; i < lighting.pointLightCount; i++) { PointLight pointLight = lighting_getPointLight(i); vec3 light_position_worldspace = pointLight.position; vec3 light_direction = normalize(light_position_worldspace - position_worldspace); float light_attenuation = getPointLightAttenuation(pointLight, distance(light_position_worldspace, position_worldspace)); lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color / light_attenuation); } int totalLights = min(MAX_LIGHTS, lighting.pointLightCount + lighting.directionalLightCount); for (int i = lighting.pointLightCount; i < totalLights; i++) { DirectionalLight directionalLight = lighting_getDirectionalLight(i); lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color); } return lightColor; } `;var Zt={name:"gouraudMaterial",vs:We.replace("phongMaterial","gouraudMaterial"),fs:Ge.replace("phongMaterial","gouraudMaterial"),defines:{LIGHTING_VERTEX:1},dependencies:[Q],uniformTypes:{ambient:"f32",diffuse:"f32",shininess:"f32",specularColor:"vec3"},defaultUniforms:{ambient:.35,diffuse:.6,shininess:32,specularColor:[.15,.15,.15]},getUniforms(n){let e={...n};return e.specularColor&&(e.specularColor=e.specularColor.map(t=>t/255)),{...Zt.defaultUniforms,...e}}};var Jt={name:"phongMaterial",vs:Ge,fs:We,defines:{LIGHTING_FRAGMENT:1},dependencies:[Q],uniformTypes:{ambient:"f32",diffuse:"f32",shininess:"f32",specularColor:"vec3"},defaultUniforms:{ambient:.35,diffuse:.6,shininess:32,specularColor:[.15,.15,.15]},getUniforms(n){let e={...n};return e.specularColor&&(e.specularColor=e.specularColor.map(t=>t/255)),{...Jt.defaultUniforms,...e}}};var $n=`uniform projection { mat4 u_MVPMatrix; mat4 u_ModelMatrix; mat4 u_NormalMatrix; vec3 u_Camera; } varying vec3 pbr_vPosition; varying vec2 pbr_vUV; #ifdef HAS_NORMALS # ifdef HAS_TANGENTS varying mat3 pbr_vTBN; # else varying vec3 pbr_vNormal; # endif #endif void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, vec2 uv) { vec4 pos = u_ModelMatrix * position; pbr_vPosition = vec3(pos.xyz) / pos.w; #ifdef HAS_NORMALS #ifdef HAS_TANGENTS vec3 normalW = normalize(vec3(u_NormalMatrix * vec4(normal.xyz, 0.0))); vec3 tangentW = normalize(vec3(u_ModelMatrix * vec4(tangent.xyz, 0.0))); vec3 bitangentW = cross(normalW, tangentW) * tangent.w; pbr_vTBN = mat3(tangentW, bitangentW, normalW); #else pbr_vNormal = normalize(vec3(u_ModelMatrix * vec4(normal.xyz, 0.0))); #endif #endif #ifdef HAS_UV pbr_vUV = uv; #else pbr_vUV = vec2(0.,0.); #endif } `;var Kn=`precision highp float; uniform Projection { uniform vec3 u_Camera; }; uniform pbrMaterial { bool unlit; bool baseColorMapEnabled; vec4 baseColorFactor; bool normalMapEnabled; float normalScale; bool emissiveMapEnabled; vec3 emissiveFactor; vec2 metallicRoughnessValues; bool metallicRoughnessMapEnabled; bool occlusionMapEnabled; float occlusionStrength; bool alphaCutoffEnabled; float alphaCutoff; bool IBLenabled; vec2 scaleIBLAmbient; vec4 scaleDiffBaseMR; vec4 scaleFGDSpec; } u_pbrMaterial; #ifdef HAS_BASECOLORMAP uniform sampler2D u_BaseColorSampler; #endif #ifdef HAS_NORMALMAP uniform sampler2D u_NormalSampler; #endif #ifdef HAS_EMISSIVEMAP uniform sampler2D u_EmissiveSampler; #endif #ifdef HAS_METALROUGHNESSMAP uniform sampler2D u_MetallicRoughnessSampler; #endif #ifdef HAS_OCCLUSIONMAP uniform sampler2D u_OcclusionSampler; #endif #ifdef USE_IBL uniform samplerCube u_DiffuseEnvSampler; uniform samplerCube u_SpecularEnvSampler; uniform sampler2D u_brdfLUT; #endif varying vec3 pbr_vPosition; varying vec2 pbr_vUV; #ifdef HAS_NORMALS #ifdef HAS_TANGENTS varying mat3 pbr_vTBN; #else varying vec3 pbr_vNormal; #endif #endif struct PBRInfo { float NdotL; float NdotV; float NdotH; float LdotH; float VdotH; float perceptualRoughness; float metalness; vec3 reflectance0; vec3 reflectance90; float alphaRoughness; vec3 diffuseColor; vec3 specularColor; vec3 n; vec3 v; }; const float M_PI = 3.141592653589793; const float c_MinRoughness = 0.04; vec4 SRGBtoLINEAR(vec4 srgbIn) { #ifdef MANUAL_SRGB #ifdef SRGB_FAST_APPROXIMATION vec3 linOut = pow(srgbIn.xyz,vec3(2.2)); #else vec3 bLess = step(vec3(0.04045),srgbIn.xyz); vec3 linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess ); #endif return vec4(linOut,srgbIn.w);; #else return srgbIn; #endif } vec3 getNormal() { #ifndef HAS_TANGENTS vec3 pos_dx = dFdx(pbr_vPosition); vec3 pos_dy = dFdy(pbr_vPosition); vec3 tex_dx = dFdx(vec3(pbr_vUV, 0.0)); vec3 tex_dy = dFdy(vec3(pbr_vUV, 0.0)); vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t); #ifdef HAS_NORMALS vec3 ng = normalize(pbr_vNormal); #else vec3 ng = cross(pos_dx, pos_dy); #endif t = normalize(t - ng * dot(ng, t)); vec3 b = normalize(cross(ng, t)); mat3 tbn = mat3(t, b, ng); #else mat3 tbn = pbr_vTBN; #endif #ifdef HAS_NORMALMAP vec3 n = texture2D(u_NormalSampler, pbr_vUV).rgb; n = normalize(tbn * ((2.0 * n - 1.0) * vec3(u_pbrMaterial.normalScale, u_pbrMaterial.normalScale, 1.0))); #else vec3 n = normalize(tbn[2].xyz); #endif return n; } #ifdef USE_IBL vec3 getIBLContribution(PBRInfo pbrInfo, vec3 n, vec3 reflection) { float mipCount = 9.0; float lod = (pbrInfo.perceptualRoughness * mipCount); vec3 brdf = SRGBtoLINEAR(texture2D(u_brdfLUT, vec2(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness))).rgb; vec3 diffuseLight = SRGBtoLINEAR(textureCube(u_DiffuseEnvSampler, n)).rgb; #ifdef USE_TEX_LOD vec3 specularLight = SRGBtoLINEAR(textureCubeLod(u_SpecularEnvSampler, reflection, lod)).rgb; #else vec3 specularLight = SRGBtoLINEAR(textureCube(u_SpecularEnvSampler, reflection)).rgb; #endif vec3 diffuse = diffuseLight * pbrInfo.diffuseColor; vec3 specular = specularLight * (pbrInfo.specularColor * brdf.x + brdf.y); diffuse *= u_pbrMaterial.scaleIBLAmbient.x; specular *= u_pbrMaterial.scaleIBLAmbient.y; return diffuse + specular; } #endif vec3 diffuse(PBRInfo pbrInfo) { return pbrInfo.diffuseColor / M_PI; } vec3 specularReflection(PBRInfo pbrInfo) { return pbrInfo.reflectance0 + (pbrInfo.reflectance90 - pbrInfo.reflectance0) * pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0); } float geometricOcclusion(PBRInfo pbrInfo) { float NdotL = pbrInfo.NdotL; float NdotV = pbrInfo.NdotV; float r = pbrInfo.alphaRoughness; float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL))); float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV))); return attenuationL * attenuationV; } float microfacetDistribution(PBRInfo pbrInfo) { float roughnessSq = pbrInfo.alphaRoughness * pbrInfo.alphaRoughness; float f = (pbrInfo.NdotH * roughnessSq - pbrInfo.NdotH) * pbrInfo.NdotH + 1.0; return roughnessSq / (M_PI * f * f); } void PBRInfo_setAmbientLight(inout PBRInfo pbrInfo) { pbrInfo.NdotL = 1.0; pbrInfo.NdotH = 0.0; pbrInfo.LdotH = 0.0; pbrInfo.VdotH = 1.0; } void PBRInfo_setDirectionalLight(inout PBRInfo pbrInfo, vec3 lightDirection) { vec3 n = pbrInfo.n; vec3 v = pbrInfo.v; vec3 l = normalize(lightDirection); vec3 h = normalize(l+v); pbrInfo.NdotL = clamp(dot(n, l), 0.001, 1.0); pbrInfo.NdotH = clamp(dot(n, h), 0.0, 1.0); pbrInfo.LdotH = clamp(dot(l, h), 0.0, 1.0); pbrInfo.VdotH = clamp(dot(v, h), 0.0, 1.0); } void PBRInfo_setPointLight(inout PBRInfo pbrInfo, PointLight pointLight) { vec3 light_direction = normalize(pointLight.position - pbr_vPosition); PBRInfo_setDirectionalLight(pbrInfo, light_direction); } vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor) { vec3 F = specularReflection(pbrInfo); float G = geometricOcclusion(pbrInfo); float D = microfacetDistribution(pbrInfo); vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInfo); vec3 specContrib = F * G * D / (4.0 * pbrInfo.NdotL * pbrInfo.NdotV); return pbrInfo.NdotL * lightColor * (diffuseContrib + specContrib); } vec4 pbr_filterColor(vec4 colorUnused) { #ifdef HAS_BASECOLORMAP vec4 baseColor = SRGBtoLINEAR(texture2D(u_BaseColorSampler, pbr_vUV)) * u_pbrMaterial.baseColorFactor; #else vec4 baseColor = u_pbrMaterial.baseColorFactor; #endif #ifdef ALPHA_CUTOFF if (baseColor.a < u_pbrMaterial.alphaCutoff) { discard; } #endif vec3 color = vec3(0, 0, 0); if(u_pbrMaterial.unlit){ color.rgb = baseColor.rgb; } else{ float perceptualRoughness = u_pbrMaterial.metallicRoughnessValues.y; float metallic = u_pbrMaterial.metallicRoughnessValues.x; #ifdef HAS_METALROUGHNESSMAP vec4 mrSample = texture2D(u_MetallicRoughnessSampler, pbr_vUV); perceptualRoughness = mrSample.g * perceptualRoughness; metallic = mrSample.b * metallic; #endif perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0); metallic = clamp(metallic, 0.0, 1.0); float alphaRoughness = perceptualRoughness * perceptualRoughness; vec3 f0 = vec3(0.04); vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0); diffuseColor *= 1.0 - metallic; vec3 specularColor = mix(f0, baseColor.rgb, metallic); float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b); float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0); vec3 specularEnvironmentR0 = specularColor.rgb; vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90; vec3 n = getNormal(); vec3 v = normalize(u_Camera - pbr_vPosition); float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0); vec3 reflection = -normalize(reflect(v, n)); PBRInfo pbrInfo = PBRInfo( 0.0, NdotV, 0.0, 0.0, 0.0, perceptualRoughness, metallic, specularEnvironmentR0, specularEnvironmentR90, alphaRoughness, diffuseColor, specularColor, n, v ); #ifdef USE_LIGHTS PBRInfo_setAmbientLight(pbrInfo); color += calculateFinalColor(pbrInfo, lighting_uAmbientLight.color); for(int i = 0; i < lighting_uDirectionalLightCount; i++) { if (i < lighting_uDirectionalLightCount) { PBRInfo_setDirectionalLight(pbrInfo, lighting_uDirectionalLight[i].direction); color += calculateFinalColor(pbrInfo, lighting_uDirectionalLight[i].color); } } for(int i = 0; i < lighting_uPointLightCount; i++) { if (i < lighting_uPointLightCount) { PBRInfo_setPointLight(pbrInfo, lighting_uPointLight[i]); float attenuation = getPointLightAttenuation(lighting_uPointLight[i], distance(lighting_uPointLight[i].position, pbr_vPosition)); color += calculateFinalColor(pbrInfo, lighting_uPointLight[i].color / attenuation); } } #endif #ifdef USE_IBL if (u_pbrMateral.IBLEnabled) { color += getIBLContribution(pbrInfo, n, reflection); } #endif #ifdef HAS_OCCLUSIONMAP if (u_pbrMaterial.occlusionMapEnabled) { float ao = texture2D(u_OcclusionSampler, pbr_vUV).r; color = mix(color, color * ao, u_pbrMaterial.occlusionStrength); } #endif #ifdef HAS_EMISSIVEMAP if (u_pbrMaterial.emmissiveMapEnabled) { vec3 emissive = SRGBtoLINEAR(texture2D(u_EmissiveSampler, pbr_vUV)).rgb * u_pbrMaterial.emissiveFactor; color += emissive; } #endif #ifdef PBR_DEBUG color = mix(color, baseColor.rgb, u_pbrMaterial.scaleDiffBaseMR.y); color = mix(color, vec3(metallic), u_pbrMaterial.scaleDiffBaseMR.z); color = mix(color, vec3(perceptualRoughness), u_pbrMaterial.scaleDiffBaseMR.w); #endif } return vec4(pow(color,vec3(1.0/2.2)), baseColor.a); } `;var Zn={name:"pbr",vs:$n,fs:Kn,defines:{LIGHTING_FRAGMENT:1,HAS_NORMALMAP:0,HAS_EMISSIVEMAP:0,HAS_OCCLUSIONMAP:0,HAS_BASECOLORMAP:0,HAS_METALROUGHNESSMAP:0,ALPHA_CUTOFF:0,USE_IBL:0,PBR_DEBUG:0},uniformTypes:{unlit:"i32",baseColorMapEnabled:"i32",baseColorFactor:"vec4",normalMapEnabled:"i32",normalScale:"f32",emissiveMapEnabled:"i32",emissiveFactor:"vec3",metallicRoughnessValues:"vec2",metallicRoughnessMapEnabled:"i32",occlusionMapEnabled:"i32",occlusionStrength:"f32",alphaCutoffEnabled:"i32",alphaCutoff:"f32",IBLenabled:"i32",scaleIBLAmbient:"vec2",scaleDiffBaseMR:"vec4",scaleFGDSpec:"vec4"},dependencies:[Q]};var Qo=`uniform brightnessContrastUniforms { float brightness; float contrast; } brightnessContrast; vec4 brightnessContrast_filterColor(vec4 color) { color.rgb += brightnessContrast.brightness; if (brightnessContrast.contrast > 0.0) { color.rgb = (color.rgb - 0.5) / (1.0 - brightnessContrast.contrast) + 0.5; } else { color.rgb = (color.rgb - 0.5) * (1.0 + brightnessContrast.contrast) + 0.5; } return color; } vec4 brightnessContrast_filterColor(vec4 color, vec2 texSize, vec2 texCoords) { return brightnessContrast_filterColor(color); } `,Jn={name:"brightnessContrast",uniformTypes:{brightness:"f32",contrast:"f32"},uniformPropTypes:{brightness:{format:"f32",value:0,min:-1,max:1},contrast:{format:"f32",value:0,min:-1,max:1}},fs:Qo,passes:[{filter:!0}]};var qo=`uniform denoiseUniforms { float strength; } noise; vec4 denoise_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) { float adjustedExponent = 3. + 200. * pow(1. - noise.strength, 4.); vec4 center = texture(source, texCoord); vec4 color = vec4(0.0); float total = 0.0; for (float x = -4.0; x <= 4.0; x += 1.0) { for (float y = -4.0; y <= 4.0; y += 1.0) { vec4 offsetColor = texture(source, texCoord + vec2(x, y) / texSize); float weight = 1.0 - abs(dot(offsetColor.rgb - center.rgb, vec3(0.25))); weight = pow(weight, adjustedExponent); color += offsetColor * weight; total += weight; } } return color / total; } `,er={name:"denoise",uniformTypes:{strength:"f32"},uniformPropTypes:{strength:{format:"f32",value:.5,min:0,max:1}},fs:qo,passes:[{sampler:!0},{sampler:!0}]};var Vo=`uniform hueSaturationUniforms { float hue; float saturation; } hueSaturation; vec4 hueSaturation_filterColor(vec4 color) { float angle = hueSaturation.hue * 3.14159265; float s = sin(angle), c = cos(angle); vec3 weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0; float len = length(color.rgb); color.rgb = vec3( dot(color.rgb, weights.xyz), dot(color.rgb, weights.zxy), dot(color.rgb, weights.yzx) ); float average = (color.r + color.g + color.b) / 3.0; if (hueSaturation.saturation > 0.0) { color.rgb += (average - color.rgb) * (1.0 - 1.0 / (1.001 - hueSaturation.saturation)); } else { color.rgb += (average - color.rgb) * (-hueSaturation.saturation); } return color; } vec4 hueSaturation_filterColor(vec4 color, vec2 texSize, vec2 texCoord) { return hueSaturation_filterColor(color); } `,tr={name:"hueSaturation",uniformTypes:{hue:"f32",saturation:"f32"},uniformPropTypes:{hue:{value:0,min:-1,max:1},saturation:{value:0,min:-1,max:1}},fs:Vo,passes:[{filter:!0}]};var Ho=`uniform noiseUniforms { float amount; } noise; float rand(vec2 co) { return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); } vec4 noise_filterColor(vec4 color, vec2 texCoord) { float diff = (rand(texCoord) - 0.5) * noise.amount; color.r += diff; color.g += diff; color.b += diff; return color; } vec4 noise_filterColor(vec4 color, vec2 texSize, vec2 texCoord) { return noise_filterColor(color, texCoord); } `,nr={name:"noise",uniformTypes:{amount:"f32"},uniformPropTypes:{amount:{value:.5,min:0,max:1}},fs:Ho,passes:[{filter:!0}]};var Go=`uniform sepiaUniforms { float amount; } sepia; vec4 sepia_filterColor(vec4 color) { float r = color.r; float g = color.g; float b = color.b; color.r = min(1.0, (r * (1.0 - (0.607 * sepia.amount))) + (g * (0.769 * sepia.amount)) + (b * (0.189 * sepia.amount))); color.g = min(1.0, (r * 0.349 * sepia.amount) + (g * (1.0 - (0.314 * sepia.amount))) + (b * 0.168 * sepia.amount)); color.b = min(1.0, (r * 0.272 * sepia.amount) + (g * 0.534 * sepia.amount) + (b * (1.0 - (0.869 * sepia.amount)))); return color; } vec4 sepia_filterColor(vec4 color, vec2 texSize, vec2 texCoord) { return sepia_filterColor(color); } `,rr={name:"sepia",uniformTypes:{amount:"f32"},uniformPropTypes:{amount:{value:.5,min:0,max:1}},fs:Go,passes:[{filter:!0}]};var Wo=`uniform vibranceUniforms { float amount; } vibrance; vec4 vibrance_filterColor(vec4 color) { float average = (color.r + color.g + color.b) / 3.0; float mx = max(color.r, max(color.g, color.b)); float amt = (mx - average) * (-vibrance.amount * 3.0); color.rgb = mix(color.rgb, vec3(mx), amt); return color; } vec4 vibrance_filterColor(vec4 color, vec2 texSize, vec2 texCoord) { return vibrance_filterColor(color); } `,or={name:"vibrance",uniformPropTypes:{amount:{value:0,min:-1,max:1}},fs:Wo,passes:[{filter:!0}]};var jo=`uniform vignetteUniforms { float radius; float amount; } vignette; vec4 vignette_filterColor(vec4 color, vec2 texCoord) { float dist = distance(texCoord, vec2(0.5, 0.5)); float ratio = smoothstep(0.8, vignette.radius * 0.799, dist * (vignette.amount + vignette.radius)); return color.rgba * ratio + (1.0 - ratio)*vec4(0.0, 0.0, 0.0, 1.0); } vec4 vignette_filterColor(vec4 color, vec2 texSize, vec2 texCoord) { return vignette_filterColor(color, texCoord); } `,ir={name:"vignette",fs:jo,uniformTypes:{radius:"f32",amount:"f32"},uniformPropTypes:{radius:{value:.5,min:0,max:1},amount:{value:.5,min:0,max:1}},passes:[{filter:!0}]};var $o=`uniform tiltShiftUniforms { float blurRadius; float gradientRadius; vec2 start; vec2 end; bool invert; } tiltShift; vec2 tiltShift_getDelta(vec2 texSize) { vec2 vector = normalize((tiltShift.end - tiltShift.start) * texSize); return tiltShift.invert ? vec2(-vector.y, vector.x) : vector; } vec4 tiltShift_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) { vec4 color = vec4(0.0); float total = 0.0; float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0); vec2 normal = normalize(vec2((tiltShift.start.y - tiltShift.end.y) * texSize.y, (tiltShift.end.x - tiltShift.start.x) * texSize.x)); float radius = smoothstep(0.0, 1.0, abs(dot(texCoord * texSize - tiltShift.start * texSize, normal)) / tiltShift.gradientRadius) * tiltShift.blurRadius; for (float t = -30.0; t <= 30.0; t++) { float percent = (t + offset - 0.5) / 30.0; float weight = 1.0 - abs(percent); vec4 offsetColor = texture(source, texCoord + tiltShift_getDelta(texSize) / texSize * percent * radius); offsetColor.rgb *= offsetColor.a; color += offsetColor * weight; total += weight; } color = color / total; color.rgb /= color.a + 0.00001; return color; } `,sr={name:"tiltShift",uniformTypes:{blurRadius:"f32",gradientRadius:"f32",start:"vec2",end:"vec2",invert:"i32"},uniformPropTypes:{blurRadius:{value:15,min:0,max:50},gradientRadius:{value:200,min:0,max:400},start:{value:[0,0]},end:{value:[1,1]},invert:{value:!1,private:!0}},passes:[{sampler:!0,uniforms:{invert:!1}},{sampler:!0,uniforms:{invert:!0}}],dependencies:[q],fs:$o};var Ko=`uniform triangleBlurUniforms { float radius; vec2 delta; } triangleBlur; vec4 triangleBlur_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) { vec2 adjustedDelta = triangleBlur.delta * triangleBlur.radius / texSize; vec4 color = vec4(0.0); float total = 0.0; float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0); for (float t = -30.0; t <= 30.0; t++) { float percent = (t + offset - 0.5) / 30.0; float weight = 1.0 - abs(percent); vec4 offsetColor = texture(source, texCoord + adjustedDelta * percent); offsetColor.rgb *= offsetColor.a; color += offsetColor * weight; total += weight; } color = color / total; color.rgb /= color.a + 0.00001; return color; } `,ar={name:"triangleBlur",uniformTypes:{radius:"f32",delta:"vec2"},uniformPropTypes:{radius:{value:20,min:0,softMax:100},delta:{value:[1,0],private:!0}},fs:Ko,dependencies:[q],passes:[{sampler:!0,uniforms:{delta:[1,0]}},{sampler:!0,uniforms:{delta:[0,1]}}]};var Zo=` uniform zoomBlurUniforms { vec2 center; float strength; } zoomBlur; vec4 zoomBlur_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) { vec4 color = vec4(0.0); float total = 0.0; vec2 toCenter = zoomBlur.center * texSize - texCoord * texSize; /* randomize the lookup values to hide the fixed number of samples */ float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0); for (float t = 0.0; t <= 40.0; t++) { float percent = (t + offset) / 40.0; float weight = 4.0 * (percent - percent * percent); vec4 offsetColor = texture(source, texCoord + toCenter * percent * zoomBlur.strength / texSize); /* switch to pre-multiplied alpha to correctly blur transparent images */ offsetColor.rgb *= offsetColor.a; color += offsetColor * weight; total += weight; } color = color / total; /* switch back from pre-multiplied alpha */ color.rgb /= color.a + 0.00001; return color; } `,cr={name:"zoomBlur",uniformTypes:{center:"vec2",strength:"f32"},uniformPropTypes:{center:{value:[.5,.5]},strength:{value:.3,min:0,softMax:1}},fs:Zo,dependencies:[q],passes:[{sampler:!0}]};var Jo=`uniform colorHalftoneUniforms { vec2 center; float angle; float size; } colorHalftone; float pattern(float angle, float scale, vec2 texSize, vec2 texCoord) { float s = sin(angle), c = cos(angle); vec2 tex = texCoord * texSize - colorHalftone.center * texSize; vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale; return (sin(point.x) * sin(point.y)) * 4.0; } vec4 colorHalftone_filterColor(vec4 color, vec2 texSize, vec2 texCoord) { float scale = 3.1514 / colorHalftone.size; vec3 cmy = 1.0 - color.rgb; float k = min(cmy.x, min(cmy.y, cmy.z)); cmy = (cmy - k) / (1.0 - k); cmy = clamp( cmy * 10.0 - 3.0 + vec3( pattern(colorHalftone.angle + 0.26179, scale, texSize, texCoord), pattern(colorHalftone.angle + 1.30899, scale, texSize, texCoord), pattern(colorHalftone.angle, scale, texSize, texCoord) ), 0.0, 1.0 ); k = clamp(k * 10.0 - 5.0 + pattern(colorHalftone.angle + 0.78539, scale, texSize, texCoord), 0.0, 1.0); return vec4(1.0 - cmy - k, color.a); } `,lr={name:"colorHalftone",uniformTypes:{center:"vec2",angle:"f32",size:"f32"},uniformPropTypes:{center:{value:[.5,.5]},angle:{value:1.1,softMin:0,softMax:Math.PI/2},size:{value:4,min:1,softMin:3,softMax:20}},fs:Jo,passes:[{filter:!0}]};var ei=`uniform dotScreenUniforms { vec2 center; float angle; float size; } dotScreen; float pattern(vec2 texSize, vec2 texCoord) { float scale = 3.1415 / dotScreen.size; float s = sin(dotScreen.angle), c = cos(dotScreen.angle); vec2 tex = texCoord * texSize - dotScreen.center * texSize; vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale; return (sin(point.x) * sin(point.y)) * 4.0; } vec4 dotScreen_filterColor(vec4 color, vec2 texSize, vec2 texCoord) { float average = (color.r + color.g + color.b) / 3.0; return vec4(vec3(average * 10.0 - 5.0 + pattern(texSize, texCoord)), color.a); } `,fr={name:"dotScreen",uniformTypes:{center:"vec2",angle:"f32",size:"f32"},uniformPropTypes:{center:{value:[.5,.5]},angle:{value:1.1,softMin:0,softMax:Math.PI/2},size:{value:3,min:1,softMin:3,softMax:20}},fs:ei,passes:[{filter:!0}]};var ti=`uniform edgeWorkUniforms { float radius; vec2 delta; } edgeWork; vec4 edgeWork_sampleColor1(sampler2D source, vec2 texSize, vec2 texCoord) { vec2 relativeDelta = edgeWork.radius * edgeWork.delta / texSize; vec2 color = vec2(0.0); vec2 total = vec2(0.0); float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0); for (float t = -30.0; t <= 30.0; t++) { float percent = (t + offset - 0.5) / 30.0; float weight = 1.0 - abs(percent); vec3 sampleColor = texture(source, texCoord + relativeDelta * percent).rgb; float average = (sampleColor.r + sampleColor.g + sampleColor.b) / 3.0; color.x += average * weight; total.x += weight; if (abs(t) < 15.0) { weight = weight * 2.0 - 1.0; color.y += average * weight; total.y += weight; } } return vec4(color / total, 0.0, 1.0); } vec4 edgeWork_sampleColor2(sampler2D source, vec2 texSize, vec2 texCoord) { vec2 relativeDelta = edgeWork.radius * edgeWork.delta / texSize; vec2 color = vec2(0.0); vec2 total = vec2(0.0); float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0); for (float t = -30.0; t <= 30.0; t++) { float percent = (t + offset - 0.5) / 30.0; float weight = 1.0 - abs(percent); vec2 sampleColor = texture(source, texCoord + relativeDelta * percent).xy; color.x += sampleColor.x * weight; total.x += weight; if (abs(t) < 15.0) { weight = weight * 2.0 - 1.0; color.y += sampleColor.y * weight; total.y += weight; } } float c = clamp(10000.0 * (color.y / total.y - color.x / total.x) + 0.5, 0.0, 1.0); return vec4(c, c, c, 1.0); } `,ur={name:"edgeWork",uniformPropTypes:{radius:{value:2,min:1,softMax:50},delta:{value:[1,0],private:!0}},fs:ti,dependencies:[q],passes:[{sampler:"edgeWork_sampleColor1",uniformPropTypes:{delta:[1,0]}},{sampler:"edgeWork_sampleColor2",uniformPropTypes:{delta:[0,1]}}]};var ni=`uniform hexagonalPixelateUniforms { vec2 center; float scale; } hexagonalPixelate; vec4 hexagonalPixelate_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) { vec2 tex = (texCoord * texSize - hexagonalPixelate.center * texSize) / hexagonalPixelate.scale; tex.y /= 0.866025404; tex.x -= tex.y * 0.5; vec2 a; if (tex.x + tex.y - floor(tex.x) - floor(tex.y) < 1.0) { a = vec2(floor(tex.x), floor(tex.y)); } else a = vec2(ceil(tex.x), ceil(tex.y)); vec2 b = vec2(ceil(tex.x), floor(tex.y)); vec2 c = vec2(floor(tex.x), ceil(tex.y)); vec3 TEX = vec3(tex.x, tex.y, 1.0 - tex.x - tex.y); vec3 A = vec3(a.x, a.y, 1.0 - a.x - a.y); vec3 B = vec3(b.x, b.y, 1.0 - b.x - b.y); vec3 C = vec3(c.x, c.y, 1.0 - c.x - c.y); float alen = length(TEX - A); float blen = length(TEX - B); float clen = length(TEX - C); vec2 choice; if (alen < blen) { if (alen < clen) choice = a; else choice = c; } else { if (blen < clen) choice = b; else choice = c; } choice.x += choice.y * 0.5; choice.y *= 0.866025404; choice *= hexagonalPixelate.scale / texSize; return texture(source, choice + hexagonalPixelate.center); } `,_r={name:"hexagonalPixelate",uniformTypes:{center:"vec2",scale:"f32"},uniformPropTypes:{center:{value:[.5,.5],hint:"screenspace"},scale:{value:10,min:1,softMin:5,softMax:50}},fs:ni,passes:[{sampler:!0}]};var ri=`uniform inkUniforms { float strength; } ink; vec4 ink_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) { vec2 dx = vec2(1.0 / texSize.x, 0.0); vec2 dy = vec2(0.0, 1.0 / texSize.y); vec4 color = texture(source, texCoord); float bigTotal = 0.0; float smallTotal = 0.0; vec3 bigAverage = vec3(0.0); vec3 smallAverage = vec3(0.0); for (float x = -2.0; x <= 2.0; x += 1.0) { for (float y = -2.0; y <= 2.0; y += 1.0) { vec3 offsetColor = texture(source, texCoord + dx * x + dy * y).rgb; bigAverage += offsetColor; bigTotal += 1.0; if (abs(x) + abs(y) < 2.0) { smallAverage += offsetColor; smallTotal += 1.0; } } } vec3 edge = max(vec3(0.0), bigAverage / bigTotal - smallAverage / smallTotal); float power = ink.strength * ink.strength * ink.strength * ink.strength * ink.strength; return vec4(color.rgb - dot(edge, edge) * power * 100000.0, color.a); } `,hr={name:"ink",uniformTypes:{strength:"f32"},uniformPropTypes:{strength:{value:.25,min:0,softMax:1}},fs:ri,passes:[{sampler:!0}]};var oi=`uniform magnifyUniforms { vec2 screenXY; float radiusPixels; float zoom; float borderWidthPixels; vec4 borderColor; } magnify; vec4 magnify_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) { vec2 pos = vec2(magnify.screenXY.x, 1.0 - magnify.screenXY.y); float dist = distance(texCoord * texSize, pos * texSize); if (dist < magnify.radiusPixels) { return texture(source, (texCoord - pos) / magnify.zoom + pos); } if (dist <= magnify.radiusPixels + magnify.borderWidthPixels) { return magnify.borderColor; } return texture(source, texCoord); } `,pr={name:"magnify",uniformTypes:{screenXY:"vec2",radiusPixels:"f32",zoom:"f32",borderWidthPixels:"f32",borderColor:"vec4"},uniformPropTypes:{screenXY:{value:[0,0]},radiusPixels:200,zoom:2,borderWidthPixels:0,borderColor:{value:[255,255,255,255]}},fs:oi,passes:[{sampler:!0}]};var ii=`vec4 warp_sampleColor(sampler2D source, vec2 texSize, vec2 coord) { vec4 color = texture(source, coord / texSize); vec2 clampedCoord = clamp(coord, vec2(0.0), texSize); if (coord != clampedCoord) { color.a *= max(0.0, 1.0 - length(coord - clampedCoord)); } return color; } `,fe={name:"warp",passes:[],fs:ii};var si=`uniform bulgePinchUniforms { float radius; float strength; vec2 center; } bulgePinch; vec2 bulgePinch_warp(vec2 coord, vec2 texCenter) { coord -= texCenter; float distance = length(coord); if (distance < bulgePinch.radius) { float percent = distance / bulgePinch.radius; if (bulgePinch.strength > 0.0) { coord *= mix(1.0, smoothstep(0.0, bulgePinch.radius / distance, percent), bulgePinch.strength * 0.75); } else { coord *= mix(1.0, pow(percent, 1.0 + bulgePinch.strength * 0.75) * bulgePinch.radius / distance, 1.0 - percent); } } coord += texCenter; return coord; } vec4 bulgePinch_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) { vec2 coord = texCoord * texSize; coord = bulgePinch_warp(coord, bulgePinch.center * texSize); return warp_sampleColor(source, texSize, coord); } `,dr={name:"bulgePinch",fs:si,uniformTypes:{center:"vec2",radius:"f32",strength:"f32"},uniformPropTypes:{center:{value:[.5,.5]},radius:{value:200,min:1,softMax:600},strength:{value:.5,min:-1,max:1}},dependencies:[fe],passes:[{sampler:!0}]};var ai=`uniform swirlUniforms { float radius; float angle; vec2 center; } swirl; vec2 swirl_warp(vec2 coord, vec2 texCenter) { coord -= texCenter; float distance = length(coord); if (distance < swirl.radius) { float percent = (swirl.radius - distance) / swirl.radius; float theta = percent * percent * swirl.angle; float s = sin(theta); float c = cos(theta); coord = vec2( coord.x * c - coord.y * s, coord.x * s + coord.y * c ); } coord += texCenter; return coord; } vec4 swirl_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) { vec2 coord = texCoord * texSize; coord = swirl_warp(coord, swirl.center * texSize); return warp_sampleColor(source, texSize, coord); } `,mr={name:"swirl",fs:ai,uniformTypes:{center:"vec2",radius:"f32",angle:"f32"},uniformPropTypes:{center:{value:[.5,.5]},radius:{value:200,min:1,softMax:600},angle:{value:3,softMin:-25,softMax:25}},dependencies:[fe],passes:[{sampler:!0}]};var ci=` #define FXAA_QUALITY_PRESET 29 #if (FXAA_QUALITY_PRESET == 10) #define FXAA_QUALITY_PS 3 #define FXAA_QUALITY_P0 1.5 #define FXAA_QUALITY_P1 3.0 #define FXAA_QUALITY_P2 12.0 #endif #if (FXAA_QUALITY_PRESET == 11) #define FXAA_QUALITY_PS 4 #define FXAA_QUALITY_P0 1.0 #define FXAA_QUALITY_P1 1.5 #define FXAA_QUALITY_P2 3.0 #define FXAA_QUALITY_P3 12.0 #endif #if (FXAA_QUALITY_PRESET == 12) #define FXAA_QUALITY_PS 5 #define FXAA_QUALITY_P0 1.0 #define FXAA_QUALITY_P1 1.5 #define FXAA_QUALITY_P2 2.0 #define FXAA_QUALITY_P3 4.0 #define FXAA_QUALITY_P4 12.0 #endif #if (FXAA_QUALITY_PRESET == 13) #define FXAA_QUALITY_PS 6 #define FXAA_QUALITY_P0 1.0 #define FXAA_QUALITY_P1 1.5 #define FXAA_QUALITY_P2 2.0 #define FXAA_QUALITY_P3 2.0 #define FXAA_QUALITY_P4 4.0 #define FXAA_QUALITY_P5 12.0 #endif #if (FXAA_QUALITY_PRESET == 14) #define FXAA_QUALITY_PS 7 #define FXAA_QUALITY_P0 1.0 #define FXAA_QUALITY_P1 1.5 #define FXAA_QUALITY_P2 2.0 #define FXAA_QUALITY_P3 2.0 #define FXAA_QUALITY_P4 2.0 #define FXAA_QUALITY_P5 4.0 #define FXAA_QUALITY_P6 12.0 #endif #if (FXAA_QUALITY_PRESET == 15) #define FXAA_QUALITY_PS 8 #define FXAA_QUALITY_P0 1.0 #define FXAA_QUALITY_P1 1.5 #define FXAA_QUALITY_P2 2.0 #define FXAA_QUALITY_P3 2.0 #define FXAA_QUALITY_P4 2.0 #define FXAA_QUALITY_P5 2.0 #define FXAA_QUALITY_P6 4.0 #define FXAA_QUALITY_P7 12.0 #endif #if (FXAA_QUALITY_PRESET == 20) #define FXAA_QUALITY_PS 3 #define FXAA_QUALITY_P0 1.5 #define FXAA_QUALITY_P1 2.0 #define FXAA_QUALITY_P2 8.0 #endif #if (FXAA_QUALITY_PRESET == 21) #define FXAA_QUALITY_PS 4 #define FXAA_QUALITY_P0 1.0 #define FXAA_QUALITY_P1 1.5 #define FXAA_QUALITY_P2 2.0 #define FXAA_QUALITY_P3 8.0 #endif #if (FXAA_QUALITY_PRESET == 22) #define FXAA_QUALITY_PS 5 #define FXAA_QUALITY_P0 1.0 #define FXAA_QUALITY_P1 1.5 #define FXAA_QUALITY_P2 2.0 #define FXAA_QUALITY_P3 2.0 #define FXAA_QUALITY_P4 8.0 #endif #if (FXAA_QUALITY_PRESET == 23) #define FXAA_QUALITY_PS 6 #define FXAA_QUALITY_P0 1.0 #define FXAA_QUALITY_P1 1.5 #define FXAA_QUALITY_P2 2.0 #define FXAA_QUALITY_P3 2.0 #define FXAA_QUALITY_P4 2.0 #define FXAA_QUALITY_P5 8.0 #endif #if (FXAA_QUALITY_PRESET == 24) #define FXAA_QUALITY_PS 7 #define FXAA_QUALITY_P0 1.0 #define FXAA_QUALITY_P1 1.5 #define FXAA_QUALITY_P2 2.0 #define FXAA_QUALITY_P3 2.0 #define FXAA_QUALITY_P4 2.0 #define FXAA_QUALITY_P5 3.0 #define FXAA_QUALITY_P6 8.0 #endif #if (FXAA_QUALITY_PRESET == 25) #define FXAA_QUALITY_PS 8 #define FXAA_QUALITY_P0 1.0 #define FXAA_QUALITY_P1 1.5 #define FXAA_QUALITY_P2 2.0 #define FXAA_QUALITY_P3 2.0 #define FXAA_QUALITY_P4 2.0 #define FXAA_QUALITY_P5 2.0 #define FXAA_QUALITY_P6 4.0 #define FXAA_QUALITY_P7 8.0 #endif #if (FXAA_QUALITY_PRESET == 26) #define FXAA_QUALITY_PS 9 #define FXAA_QUALITY_P0 1.0 #define FXAA_QUALITY_P1 1.5 #define FXAA_QUALITY_P2 2.0 #define FXAA_QUALITY_P3 2.0 #define FXAA_QUALITY_P4 2.0 #define FXAA_QUALITY_P5 2.0 #define FXAA_QUALITY_P6 2.0 #define FXAA_QUALITY_P7 4.0 #define FXAA_QUALITY_P8 8.0 #endif #if (FXAA_QUALITY_PRESET == 27) #define FXAA_QUALITY_PS 10 #define FXAA_QUALITY_P0 1.0 #define FXAA_QUALITY_P1 1.5 #define FXAA_QUALITY_P2 2.0 #define FXAA_QUALITY_P3 2.0 #define FXAA_QUALITY_P4 2.0 #define FXAA_QUALITY_P5 2.0 #define FXAA_QUALITY_P6 2.0 #define FXAA_QUALITY_P7 2.0 #define FXAA_QUALITY_P8 4.0 #define FXAA_QUALITY_P9 8.0 #endif #if (FXAA_QUALITY_PRESET == 28) #define FXAA_QUALITY_PS 11 #define FXAA_QUALITY_P0 1.0 #define FXAA_QUALITY_P1 1.5 #define FXAA_QUALITY_P2 2.0 #define FXAA_QUALITY_P3 2.0 #define FXAA_QUALITY_P4 2.0 #define FXAA_QUALITY_P5 2.0 #define FXAA_QUALITY_P6 2.0 #define FXAA_QUALITY_P7 2.0 #define FXAA_QUALITY_P8 2.0 #define FXAA_QUALITY_P9 4.0 #define FXAA_QUALITY_P10 8.0 #endif #if (FXAA_QUALITY_PRESET == 29) #define FXAA_QUALITY_PS 12 #define FXAA_QUALITY_P0 1.0 #define FXAA_QUALITY_P1 1.5 #define FXAA_QUALITY_P2 2.0 #define FXAA_QUALITY_P3 2.0 #define FXAA_QUALITY_P4 2.0 #define FXAA_QUALITY_P5 2.0 #define FXAA_QUALITY_P6 2.0 #define FXAA_QUALITY_P7 2.0 #define FXAA_QUALITY_P8 2.0 #define FXAA_QUALITY_P9 2.0 #define FXAA_QUALITY_P10 4.0 #define FXAA_QUALITY_P11 8.0 #endif #if (FXAA_QUALITY_PRESET == 39) #define FXAA_QUALITY_PS 12 #define FXAA_QUALITY_P0 1.0 #define FXAA_QUALITY_P1 1.0 #define FXAA_QUALITY_P2 1.0 #define FXAA_QUALITY_P3 1.0 #define FXAA_QUALITY_P4 1.0 #define FXAA_QUALITY_P5 1.5 #define FXAA_QUALITY_P6 2.0 #define FXAA_QUALITY_P7 2.0 #define FXAA_QUALITY_P8 2.0 #define FXAA_QUALITY_P9 2.0 #define FXAA_QUALITY_P10 4.0 #define FXAA_QUALITY_P11 8.0 #endif #define FxaaBool bool #define FxaaFloat float #define FxaaFloat2 vec2 #define FxaaFloat3 vec3 #define FxaaFloat4 vec4 #define FxaaHalf float #define FxaaHalf2 vec2 #define FxaaHalf3 vec3 #define FxaaHalf4 vec4 #define FxaaInt2 vec2 #define FxaaTex sampler2D #define FxaaSat(x) clamp(x, 0.0, 1.0) #define FxaaTexTop(t, p) texture(t, p) #define FxaaTexOff(t, p, o, r) texture(t, p + (o * r)) FxaaFloat FxaaLuma_(FxaaFloat4 rgba) { return dot(rgba.rgb, vec3(0.2126, 0.7152, 0.0722)); } FxaaFloat4 FxaaPixelShader_( // // Use noperspective interpolation here (turn off perspective interpolation). // {xy} = center of pixel FxaaFloat2 pos, // // Input color texture. // {rgb_} = color in linear or perceptual color space // if (FXAA_GREEN_AS_LUMA == 0) // {___a} = luma in perceptual color space (not linear) FxaaTex tex, // // Only used on FXAA Quality. // This must be from a constant/uniform. // {x_} = 1.0/screenWidthInPixels // {_y} = 1.0/screenHeightInPixels FxaaFloat2 fxaaQualityRcpFrame, // // Only used on FXAA Quality. // This used to be the FXAA_QUALITY_SUBPIX define. // It is here now to allow easier tuning. // Choose the amount of sub-pixel aliasing removal. // This can effect sharpness. // 1.00 - upper limit (softer) // 0.75 - default amount of filtering // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) // 0.25 - almost off // 0.00 - completely off FxaaFloat fxaaQualitySubpix, // // Only used on FXAA Quality. // This used to be the FXAA_QUALITY_EDGE_THRESHOLD define. // It is here now to allow easier tuning. // The minimum amount of local contrast required to apply algorithm. // 0.333 - too little (faster) // 0.250 - low quality // 0.166 - default // 0.125 - high quality // 0.063 - overkill (slower) FxaaFloat fxaaQualityEdgeThreshold, // // Only used on FXAA Quality. // This used to be the FXAA_QUALITY_EDGE_THRESHOLD_MIN define. // It is here now to allow easier tuning. // Trims the algorithm from processing darks. // 0.0833 - upper limit (default, the start of visible unfiltered edges) // 0.0625 - high quality (faster) // 0.0312 - visible limit (slower) // Special notes when using FXAA_GREEN_AS_LUMA, // Likely want to set this to zero. // As colors that are mostly not-green // will appear very dark in the green channel! // Tune by looking at mostly non-green content, // then start at zero and increase until aliasing is a problem. FxaaFloat fxaaQualityEdgeThresholdMin ) { /*--------------------------------------------------------------------------*/ FxaaFloat2 posM; posM.x = pos.x; posM.y = pos.y; FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); #define lumaM rgbyM.y FxaaFloat lumaS = FxaaLuma_(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy)); FxaaFloat lumaE = FxaaLuma_(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy)); FxaaFloat lumaN = FxaaLuma_(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy)); FxaaFloat lumaW = FxaaLuma_(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy)); /*--------------------------------------------------------------------------*/ FxaaFloat maxSM = max(lumaS, lumaM); FxaaFloat minSM = min(lumaS, lumaM); FxaaFloat maxESM = max(lumaE, maxSM); FxaaFloat minESM = min(lumaE, minSM); FxaaFloat maxWN = max(lumaN, lumaW); FxaaFloat minWN = min(lumaN, lumaW); FxaaFloat rangeMax = max(maxWN, maxESM); FxaaFloat rangeMin = min(minWN, minESM); FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold; FxaaFloat range = rangeMax - rangeMin; FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled); FxaaBool earlyExit = range < rangeMaxClamped; /*--------------------------------------------------------------------------*/ if(earlyExit) return rgbyM; /*--------------------------------------------------------------------------*/ FxaaFloat lumaNW = FxaaLuma_(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy)); FxaaFloat lumaSE = FxaaLuma_(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy)); FxaaFloat lumaNE = FxaaLuma_(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy)); FxaaFloat lumaSW = FxaaLuma_(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); /*--------------------------------------------------------------------------*/ FxaaFloat lumaNS = lumaN + lumaS; FxaaFloat lumaWE = lumaW + lumaE; FxaaFloat subpixRcpRange = 1.0/range; FxaaFloat subpixNSWE = lumaNS + lumaWE; FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS; FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE; /*--------------------------------------------------------------------------*/ FxaaFloat lumaNESE = lumaNE + lumaSE; FxaaFloat lumaNWNE = lumaNW + lumaNE; FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE; FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE; /*--------------------------------------------------------------------------*/ FxaaFloat lumaNWSW = lumaNW + lumaSW; FxaaFloat lumaSWSE = lumaSW + lumaSE; FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2); FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2); FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW; FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE; FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4; FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4; /*--------------------------------------------------------------------------*/ FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE; FxaaFloat lengthSign = fxaaQualityRcpFrame.x; FxaaBool horzSpan = edgeHorz >= edgeVert; FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE; /*--------------------------------------------------------------------------*/ if(!horzSpan) lumaN = lumaW; if(!horzSpan) lumaS = lumaE; if(horzSpan) lengthSign = fxaaQualityRcpFrame.y; FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM; /*--------------------------------------------------------------------------*/ FxaaFloat gradientN = lumaN - lumaM; FxaaFloat gradientS = lumaS - lumaM; FxaaFloat lumaNN = lumaN + lumaM; FxaaFloat lumaSS = lumaS + lumaM; FxaaBool pairN = abs(gradientN) >= abs(gradientS); FxaaFloat gradient = max(abs(gradientN), abs(gradientS)); if(pairN) lengthSign = -lengthSign; FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange); /*--------------------------------------------------------------------------*/ FxaaFloat2 posB; posB.x = posM.x; posB.y = posM.y; FxaaFloat2 offNP; offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x; offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y; if(!horzSpan) posB.x += lengthSign * 0.5; if( horzSpan) posB.y += lengthSign * 0.5; /*--------------------------------------------------------------------------*/ FxaaFloat2 posN; posN.x = posB.x - offNP.x * FXAA_QUALITY_P0; posN.y = posB.y - offNP.y * FXAA_QUALITY_P0; FxaaFloat2 posP; posP.x = posB.x + offNP.x * FXAA_QUALITY_P0; posP.y = posB.y + offNP.y * FXAA_QUALITY_P0; FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0; FxaaFloat lumaEndN = FxaaLuma_(FxaaTexTop(tex, posN)); FxaaFloat subpixE = subpixC * subpixC; FxaaFloat lumaEndP = FxaaLuma_(FxaaTexTop(tex, posP)); /*--------------------------------------------------------------------------*/ if(!pairN) lumaNN = lumaSS; FxaaFloat gradientScaled = gradient * 1.0/4.0; FxaaFloat lumaMM = lumaM - lumaNN * 0.5; FxaaFloat subpixF = subpixD * subpixE; FxaaBool lumaMLTZero = lumaMM < 0.0; /*--------------------------------------------------------------------------*/ lumaEndN -= lumaNN * 0.5; lumaEndP -= lumaNN * 0.5; FxaaBool doneN = abs(lumaEndN) >= gradientScaled; FxaaBool doneP = abs(lumaEndP) >= gradientScaled; if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P1; if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P1; FxaaBool doneNP = (!doneN) || (!doneP); if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P1; if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P1; /*--------------------------------------------------------------------------*/ if(doneNP) { if(!doneN) lumaEndN = FxaaLuma_(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma_(FxaaTexTop(tex, posP.xy)); if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P2; if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P2; doneNP = (!doneN) || (!doneP); if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P2; if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P2; /*--------------------------------------------------------------------------*/ #if (FXAA_QUALITY_PS > 3) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma_(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma_(FxaaTexTop(tex, posP.xy)); if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P3; if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P3; doneNP = (!doneN) || (!doneP); if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P3; if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P3; /*--------------------------------------------------------------------------*/ #if (FXAA_QUALITY_PS > 4) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma_(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma_(FxaaTexTop(tex, posP.xy)); if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P4; if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P4; doneNP = (!doneN) || (!doneP); if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P4; if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P4; /*--------------------------------------------------------------------------*/ #if (FXAA_QUALITY_PS > 5) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma_(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma_(FxaaTexTop(tex, posP.xy)); if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P5; if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P5; doneNP = (!doneN) || (!doneP); if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P5; if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P5; /*--------------------------------------------------------------------------*/ #if (FXAA_QUALITY_PS > 6) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma_(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma_(FxaaTexTop(tex, posP.xy)); if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P6; if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P6; doneNP = (!doneN) || (!doneP); if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P6; if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P6; /*--------------------------------------------------------------------------*/ #if (FXAA_QUALITY_PS > 7) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma_(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma_(FxaaTexTop(tex, posP.xy)); if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P7; if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P7; doneNP = (!doneN) || (!doneP); if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P7; if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P7; /*--------------------------------------------------------------------------*/ #if (FXAA_QUALITY_PS > 8) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma_(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma_(FxaaTexTop(tex, posP.xy)); if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P8; if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P8; doneNP = (!doneN) || (!doneP); if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P8; if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P8; /*--------------------------------------------------------------------------*/ #if (FXAA_QUALITY_PS > 9) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma_(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma_(FxaaTexTop(tex, posP.xy)); if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P9; if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P9; doneNP = (!doneN) || (!doneP); if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P9; if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P9; /*--------------------------------------------------------------------------*/ #if (FXAA_QUALITY_PS > 10) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma_(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma_(FxaaTexTop(tex, posP.xy)); if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P10; if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P10; doneNP = (!doneN) || (!doneP); if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P10; if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P10; /*--------------------------------------------------------------------------*/ #if (FXAA_QUALITY_PS > 11) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma_(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma_(FxaaTexTop(tex, posP.xy)); if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P11; if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P11; doneNP = (!doneN) || (!doneP); if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P11; if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P11; /*--------------------------------------------------------------------------*/ #if (FXAA_QUALITY_PS > 12) if(doneNP) { if(!doneN) lumaEndN = FxaaLuma_(FxaaTexTop(tex, posN.xy)); if(!doneP) lumaEndP = FxaaLuma_(FxaaTexTop(tex, posP.xy)); if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; doneN = abs(lumaEndN) >= gradientScaled; doneP = abs(lumaEndP) >= gradientScaled; if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P12; if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P12; doneNP = (!doneN) || (!doneP); if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P12; if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P12; /*--------------------------------------------------------------------------*/ } #endif /*--------------------------------------------------------------------------*/ } #endif /*--------------------------------------------------------------------------*/ } #endif /*--------------------------------------------------------------------------*/ } #endif /*--------------------------------------------------------------------------*/ } #endif /*--------------------------------------------------------------------------*/ } #endif /*--------------------------------------------------------------------------*/ } #endif /*--------------------------------------------------------------------------*/ } #endif /*--------------------------------------------------------------------------*/ } #endif /*--------------------------------------------------------------------------*/ } #endif /*--------------------------------------------------------------------------*/ } /*--------------------------------------------------------------------------*/ FxaaFloat dstN = posM.x - posN.x; FxaaFloat dstP = posP.x - posM.x; if(!horzSpan) dstN = posM.y - posN.y; if(!horzSpan) dstP = posP.y - posM.y; /*--------------------------------------------------------------------------*/ FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero; FxaaFloat spanLength = (dstP + dstN); FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero; FxaaFloat spanLengthRcp = 1.0/spanLength; /*--------------------------------------------------------------------------*/ FxaaBool directionN = dstN < dstP; FxaaFloat dst = min(dstN, dstP); FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP; FxaaFloat subpixG = subpixF * subpixF; FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5; FxaaFloat subpixH = subpixG * fxaaQualitySubpix; /*--------------------------------------------------------------------------*/ FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0; FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH); if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign; if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign; return FxaaTexTop(tex, posM); } vec4 fxaa_sampleColor(sampler2D source, vec2 texSize, vec2 texCoord) { const float fxaa_QualitySubpix = 0.5; const float fxaa_QualityEdgeThreshold = 0.125; const float fxaa_QualityEdgeThresholdMin = 0.0833; return FxaaPixelShader_( texCoord, source, vec2(1.0) / texSize, fxaa_QualitySubpix, fxaa_QualityEdgeThreshold, fxaa_QualityEdgeThresholdMin ); } `,gr={name:"fxaa",uniformPropTypes:{},fs:ci,passes:[{sampler:!0}]};function je(n,e=[],t=0){let r=Math.fround(n),o=n-r;return e[t]=r,e[t+1]=o,e}function en(n){return n-Math.fround(n)}function tn(n){let e=new Float32Array(32);for(let t=0;t<4;++t)for(let r=0;r<4;++r){let o=t*4+r;je(n[r*4+t],e,o*2)}return e}var xr=`uniform float ONE; vec2 split(float a) { const float SPLIT = 4097.0; float t = a * SPLIT; #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) float a_hi = t * ONE - (t - a); float a_lo = a * ONE - a_hi; #else float a_hi = t - (t - a); float a_lo = a - a_hi; #endif return vec2(a_hi, a_lo); } vec2 split2(vec2 a) { vec2 b = split(a.x); b.y += a.y; return b; } vec2 quickTwoSum(float a, float b) { #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) float sum = (a + b) * ONE; float err = b - (sum - a) * ONE; #else float sum = a + b; float err = b - (sum - a); #endif return vec2(sum, err); } vec2 twoSum(float a, float b) { float s = (a + b); #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) float v = (s * ONE - a) * ONE; float err = (a - (s - v) * ONE) * ONE * ONE * ONE + (b - v); #else float v = s - a; float err = (a - (s - v)) + (b - v); #endif return vec2(s, err); } vec2 twoSub(float a, float b) { float s = (a - b); #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) float v = (s * ONE - a) * ONE; float err = (a - (s - v) * ONE) * ONE * ONE * ONE - (b + v); #else float v = s - a; float err = (a - (s - v)) - (b + v); #endif return vec2(s, err); } vec2 twoSqr(float a) { float prod = a * a; vec2 a_fp64 = split(a); #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) float err = ((a_fp64.x * a_fp64.x - prod) * ONE + 2.0 * a_fp64.x * a_fp64.y * ONE * ONE) + a_fp64.y * a_fp64.y * ONE * ONE * ONE; #else float err = ((a_fp64.x * a_fp64.x - prod) + 2.0 * a_fp64.x * a_fp64.y) + a_fp64.y * a_fp64.y; #endif return vec2(prod, err); } vec2 twoProd(float a, float b) { float prod = a * b; vec2 a_fp64 = split(a); vec2 b_fp64 = split(b); float err = ((a_fp64.x * b_fp64.x - prod) + a_fp64.x * b_fp64.y + a_fp64.y * b_fp64.x) + a_fp64.y * b_fp64.y; return vec2(prod, err); } vec2 sum_fp64(vec2 a, vec2 b) { vec2 s, t; s = twoSum(a.x, b.x); t = twoSum(a.y, b.y); s.y += t.x; s = quickTwoSum(s.x, s.y); s.y += t.y; s = quickTwoSum(s.x, s.y); return s; } vec2 sub_fp64(vec2 a, vec2 b) { vec2 s, t; s = twoSub(a.x, b.x); t = twoSub(a.y, b.y); s.y += t.x; s = quickTwoSum(s.x, s.y); s.y += t.y; s = quickTwoSum(s.x, s.y); return s; } vec2 mul_fp64(vec2 a, vec2 b) { vec2 prod = twoProd(a.x, b.x); prod.y += a.x * b.y; #if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) prod = split2(prod); #endif prod = quickTwoSum(prod.x, prod.y); prod.y += a.y * b.x; #if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) prod = split2(prod); #endif prod = quickTwoSum(prod.x, prod.y); return prod; } vec2 div_fp64(vec2 a, vec2 b) { float xn = 1.0 / b.x; #if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) vec2 yn = mul_fp64(a, vec2(xn, 0)); #else vec2 yn = a * xn; #endif float diff = (sub_fp64(a, mul_fp64(b, yn))).x; vec2 prod = twoProd(xn, diff); return sum_fp64(yn, prod); } vec2 sqrt_fp64(vec2 a) { if (a.x == 0.0 && a.y == 0.0) return vec2(0.0, 0.0); if (a.x < 0.0) return vec2(0.0 / 0.0, 0.0 / 0.0); float x = 1.0 / sqrt(a.x); float yn = a.x * x; #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) vec2 yn_sqr = twoSqr(yn) * ONE; #else vec2 yn_sqr = twoSqr(yn); #endif float diff = sub_fp64(a, yn_sqr).x; vec2 prod = twoProd(x * 0.5, diff); #if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) return sum_fp64(split(yn), prod); #else return sum_fp64(vec2(yn, 0.0), prod); #endif } `;var vr=`const vec2 E_FP64 = vec2(2.7182817459106445e+00, 8.254840366817007e-08); const vec2 LOG2_FP64 = vec2(0.6931471824645996e+00, -1.9046542121259336e-09); const vec2 PI_FP64 = vec2(3.1415927410125732, -8.742278012618954e-8); const vec2 TWO_PI_FP64 = vec2(6.2831854820251465, -1.7484556025237907e-7); const vec2 PI_2_FP64 = vec2(1.5707963705062866, -4.371139006309477e-8); const vec2 PI_4_FP64 = vec2(0.7853981852531433, -2.1855695031547384e-8); const vec2 PI_16_FP64 = vec2(0.19634954631328583, -5.463923757886846e-9); const vec2 PI_16_2_FP64 = vec2(0.39269909262657166, -1.0927847515773692e-8); const vec2 PI_16_3_FP64 = vec2(0.5890486240386963, -1.4906100798128818e-9); const vec2 PI_180_FP64 = vec2(0.01745329238474369, 1.3519960498364902e-10); const vec2 SIN_TABLE_0_FP64 = vec2(0.19509032368659973, -1.6704714833615242e-9); const vec2 SIN_TABLE_1_FP64 = vec2(0.3826834261417389, 6.22335089017767e-9); const vec2 SIN_TABLE_2_FP64 = vec2(0.5555702447891235, -1.1769521357507529e-8); const vec2 SIN_TABLE_3_FP64 = vec2(0.7071067690849304, 1.2101617041793133e-8); const vec2 COS_TABLE_0_FP64 = vec2(0.9807852506637573, 2.9739473106360492e-8); const vec2 COS_TABLE_1_FP64 = vec2(0.9238795042037964, 2.8307490351764386e-8); const vec2 COS_TABLE_2_FP64 = vec2(0.8314695954322815, 1.6870263741530778e-8); const vec2 COS_TABLE_3_FP64 = vec2(0.7071067690849304, 1.2101617152815436e-8); const vec2 INVERSE_FACTORIAL_3_FP64 = vec2(1.666666716337204e-01, -4.967053879312289e-09); const vec2 INVERSE_FACTORIAL_4_FP64 = vec2(4.16666679084301e-02, -1.2417634698280722e-09); const vec2 INVERSE_FACTORIAL_5_FP64 = vec2(8.333333767950535e-03, -4.34617203337595e-10); const vec2 INVERSE_FACTORIAL_6_FP64 = vec2(1.3888889225199819e-03, -3.3631094437103215e-11); const vec2 INVERSE_FACTORIAL_7_FP64 = vec2(1.9841270113829523e-04, -2.725596874933456e-12); const vec2 INVERSE_FACTORIAL_8_FP64 = vec2(2.4801587642286904e-05, -3.406996025904184e-13); const vec2 INVERSE_FACTORIAL_9_FP64 = vec2(2.75573188446287533e-06, 3.7935713937038186e-14); const vec2 INVERSE_FACTORIAL_10_FP64 = vec2(2.755731998149713e-07, -7.575112367869873e-15); float nint(float d) { if (d == floor(d)) return d; return floor(d + 0.5); } vec2 nint_fp64(vec2 a) { float hi = nint(a.x); float lo; vec2 tmp; if (hi == a.x) { lo = nint(a.y); tmp = quickTwoSum(hi, lo); } else { lo = 0.0; if (abs(hi - a.x) == 0.5 && a.y < 0.0) { hi -= 1.0; } tmp = vec2(hi, lo); } return tmp; } vec2 exp_fp64(vec2 a) { const int k_power = 4; const float k = 16.0; const float inv_k = 1.0 / k; if (a.x <= -88.0) return vec2(0.0, 0.0); if (a.x >= 88.0) return vec2(1.0 / 0.0, 1.0 / 0.0); if (a.x == 0.0 && a.y == 0.0) return vec2(1.0, 0.0); if (a.x == 1.0 && a.y == 0.0) return E_FP64; float m = floor(a.x / LOG2_FP64.x + 0.5); vec2 r = sub_fp64(a, mul_fp64(LOG2_FP64, vec2(m, 0.0))) * inv_k; vec2 s, t, p; p = mul_fp64(r, r); s = sum_fp64(r, p * 0.5); p = mul_fp64(p, r); t = mul_fp64(p, INVERSE_FACTORIAL_3_FP64); s = sum_fp64(s, t); p = mul_fp64(p, r); t = mul_fp64(p, INVERSE_FACTORIAL_4_FP64); s = sum_fp64(s, t); p = mul_fp64(p, r); t = mul_fp64(p, INVERSE_FACTORIAL_5_FP64); s = sum_fp64(s, t); for (int i = 0; i < k_power; i++) { s = sum_fp64(s * 2.0, mul_fp64(s, s)); } #if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND) s = sum_fp64(s, vec2(ONE, 0.0)); #else s = sum_fp64(s, vec2(1.0, 0.0)); #endif return s * pow(2.0, m); } vec2 log_fp64(vec2 a) { if (a.x == 1.0 && a.y == 0.0) return vec2(0.0, 0.0); if (a.x <= 0.0) return vec2(0.0 / 0.0, 0.0 / 0.0); vec2 x = vec2(log(a.x), 0.0); vec2 s; #if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND) s = vec2(ONE, 0.0); #else s = vec2(1.0, 0.0); #endif x = sub_fp64(sum_fp64(x, mul_fp64(a, exp_fp64(-x))), s); return x; } vec2 sin_taylor_fp64(vec2 a) { vec2 r, s, t, x; if (a.x == 0.0 && a.y == 0.0) { return vec2(0.0, 0.0); } x = -mul_fp64(a, a); s = a; r = a; r = mul_fp64(r, x); t = mul_fp64(r, INVERSE_FACTORIAL_3_FP64); s = sum_fp64(s, t); r = mul_fp64(r, x); t = mul_fp64(r, INVERSE_FACTORIAL_5_FP64); s = sum_fp64(s, t); return s; } vec2 cos_taylor_fp64(vec2 a) { vec2 r, s, t, x; if (a.x == 0.0 && a.y == 0.0) { return vec2(1.0, 0.0); } x = -mul_fp64(a, a); r = x; s = sum_fp64(vec2(1.0, 0.0), r * 0.5); r = mul_fp64(r, x); t = mul_fp64(r, INVERSE_FACTORIAL_4_FP64); s = sum_fp64(s, t); r = mul_fp64(r, x); t = mul_fp64(r, INVERSE_FACTORIAL_6_FP64); s = sum_fp64(s, t); return s; } void sincos_taylor_fp64(vec2 a, out vec2 sin_t, out vec2 cos_t) { if (a.x == 0.0 && a.y == 0.0) { sin_t = vec2(0.0, 0.0); cos_t = vec2(1.0, 0.0); } sin_t = sin_taylor_fp64(a); cos_t = sqrt_fp64(sub_fp64(vec2(1.0, 0.0), mul_fp64(sin_t, sin_t))); } vec2 sin_fp64(vec2 a) { if (a.x == 0.0 && a.y == 0.0) { return vec2(0.0, 0.0); } vec2 z = nint_fp64(div_fp64(a, TWO_PI_FP64)); vec2 r = sub_fp64(a, mul_fp64(TWO_PI_FP64, z)); vec2 t; float q = floor(r.x / PI_2_FP64.x + 0.5); int j = int(q); if (j < -2 || j > 2) { return vec2(0.0 / 0.0, 0.0 / 0.0); } t = sub_fp64(r, mul_fp64(PI_2_FP64, vec2(q, 0.0))); q = floor(t.x / PI_16_FP64.x + 0.5); int k = int(q); if (k == 0) { if (j == 0) { return sin_taylor_fp64(t); } else if (j == 1) { return cos_taylor_fp64(t); } else if (j == -1) { return -cos_taylor_fp64(t); } else { return -sin_taylor_fp64(t); } } int abs_k = int(abs(float(k))); if (abs_k > 4) { return vec2(0.0 / 0.0, 0.0 / 0.0); } else { t = sub_fp64(t, mul_fp64(PI_16_FP64, vec2(q, 0.0))); } vec2 u = vec2(0.0, 0.0); vec2 v = vec2(0.0, 0.0); #if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND) if (abs(float(abs_k) - 1.0) < 0.5) { u = COS_TABLE_0_FP64; v = SIN_TABLE_0_FP64; } else if (abs(float(abs_k) - 2.0) < 0.5) { u = COS_TABLE_1_FP64; v = SIN_TABLE_1_FP64; } else if (abs(float(abs_k) - 3.0) < 0.5) { u = COS_TABLE_2_FP64; v = SIN_TABLE_2_FP64; } else if (abs(float(abs_k) - 4.0) < 0.5) { u = COS_TABLE_3_FP64; v = SIN_TABLE_3_FP64; } #else if (abs_k == 1) { u = COS_TABLE_0_FP64; v = SIN_TABLE_0_FP64; } else if (abs_k == 2) { u = COS_TABLE_1_FP64; v = SIN_TABLE_1_FP64; } else if (abs_k == 3) { u = COS_TABLE_2_FP64; v = SIN_TABLE_2_FP64; } else if (abs_k == 4) { u = COS_TABLE_3_FP64; v = SIN_TABLE_3_FP64; } #endif vec2 sin_t, cos_t; sincos_taylor_fp64(t, sin_t, cos_t); vec2 result = vec2(0.0, 0.0); if (j == 0) { if (k > 0) { result = sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); } else { result = sub_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); } } else if (j == 1) { if (k > 0) { result = sub_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t)); } else { result = sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t)); } } else if (j == -1) { if (k > 0) { result = sub_fp64(mul_fp64(v, sin_t), mul_fp64(u, cos_t)); } else { result = -sum_fp64(mul_fp64(v, sin_t), mul_fp64(u, cos_t)); } } else { if (k > 0) { result = -sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); } else { result = sub_fp64(mul_fp64(v, cos_t), mul_fp64(u, sin_t)); } } return result; } vec2 cos_fp64(vec2 a) { if (a.x == 0.0 && a.y == 0.0) { return vec2(1.0, 0.0); } vec2 z = nint_fp64(div_fp64(a, TWO_PI_FP64)); vec2 r = sub_fp64(a, mul_fp64(TWO_PI_FP64, z)); vec2 t; float q = floor(r.x / PI_2_FP64.x + 0.5); int j = int(q); if (j < -2 || j > 2) { return vec2(0.0 / 0.0, 0.0 / 0.0); } t = sub_fp64(r, mul_fp64(PI_2_FP64, vec2(q, 0.0))); q = floor(t.x / PI_16_FP64.x + 0.5); int k = int(q); if (k == 0) { if (j == 0) { return cos_taylor_fp64(t); } else if (j == 1) { return -sin_taylor_fp64(t); } else if (j == -1) { return sin_taylor_fp64(t); } else { return -cos_taylor_fp64(t); } } int abs_k = int(abs(float(k))); if (abs_k > 4) { return vec2(0.0 / 0.0, 0.0 / 0.0); } else { t = sub_fp64(t, mul_fp64(PI_16_FP64, vec2(q, 0.0))); } vec2 u = vec2(0.0, 0.0); vec2 v = vec2(0.0, 0.0); #if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND) if (abs(float(abs_k) - 1.0) < 0.5) { u = COS_TABLE_0_FP64; v = SIN_TABLE_0_FP64; } else if (abs(float(abs_k) - 2.0) < 0.5) { u = COS_TABLE_1_FP64; v = SIN_TABLE_1_FP64; } else if (abs(float(abs_k) - 3.0) < 0.5) { u = COS_TABLE_2_FP64; v = SIN_TABLE_2_FP64; } else if (abs(float(abs_k) - 4.0) < 0.5) { u = COS_TABLE_3_FP64; v = SIN_TABLE_3_FP64; } #else if (abs_k == 1) { u = COS_TABLE_0_FP64; v = SIN_TABLE_0_FP64; } else if (abs_k == 2) { u = COS_TABLE_1_FP64; v = SIN_TABLE_1_FP64; } else if (abs_k == 3) { u = COS_TABLE_2_FP64; v = SIN_TABLE_2_FP64; } else if (abs_k == 4) { u = COS_TABLE_3_FP64; v = SIN_TABLE_3_FP64; } #endif vec2 sin_t, cos_t; sincos_taylor_fp64(t, sin_t, cos_t); vec2 result = vec2(0.0, 0.0); if (j == 0) { if (k > 0) { result = sub_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t)); } else { result = sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t)); } } else if (j == 1) { if (k > 0) { result = -sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); } else { result = sub_fp64(mul_fp64(v, cos_t), mul_fp64(u, sin_t)); } } else if (j == -1) { if (k > 0) { result = sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); } else { result = sub_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); } } else { if (k > 0) { result = sub_fp64(mul_fp64(v, sin_t), mul_fp64(u, cos_t)); } else { result = -sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t)); } } return result; } vec2 tan_fp64(vec2 a) { vec2 sin_a; vec2 cos_a; if (a.x == 0.0 && a.y == 0.0) { return vec2(0.0, 0.0); } vec2 z = nint_fp64(div_fp64(a, TWO_PI_FP64)); vec2 r = sub_fp64(a, mul_fp64(TWO_PI_FP64, z)); vec2 t; float q = floor(r.x / PI_2_FP64.x + 0.5); int j = int(q); if (j < -2 || j > 2) { return vec2(0.0 / 0.0, 0.0 / 0.0); } t = sub_fp64(r, mul_fp64(PI_2_FP64, vec2(q, 0.0))); q = floor(t.x / PI_16_FP64.x + 0.5); int k = int(q); int abs_k = int(abs(float(k))); if (abs_k > 4) { return vec2(0.0 / 0.0, 0.0 / 0.0); } else { t = sub_fp64(t, mul_fp64(PI_16_FP64, vec2(q, 0.0))); } vec2 u = vec2(0.0, 0.0); vec2 v = vec2(0.0, 0.0); vec2 sin_t, cos_t; vec2 s, c; sincos_taylor_fp64(t, sin_t, cos_t); if (k == 0) { s = sin_t; c = cos_t; } else { #if defined(NVIDIA_FP64_WORKAROUND) || defined(INTEL_FP64_WORKAROUND) if (abs(float(abs_k) - 1.0) < 0.5) { u = COS_TABLE_0_FP64; v = SIN_TABLE_0_FP64; } else if (abs(float(abs_k) - 2.0) < 0.5) { u = COS_TABLE_1_FP64; v = SIN_TABLE_1_FP64; } else if (abs(float(abs_k) - 3.0) < 0.5) { u = COS_TABLE_2_FP64; v = SIN_TABLE_2_FP64; } else if (abs(float(abs_k) - 4.0) < 0.5) { u = COS_TABLE_3_FP64; v = SIN_TABLE_3_FP64; } #else if (abs_k == 1) { u = COS_TABLE_0_FP64; v = SIN_TABLE_0_FP64; } else if (abs_k == 2) { u = COS_TABLE_1_FP64; v = SIN_TABLE_1_FP64; } else if (abs_k == 3) { u = COS_TABLE_2_FP64; v = SIN_TABLE_2_FP64; } else if (abs_k == 4) { u = COS_TABLE_3_FP64; v = SIN_TABLE_3_FP64; } #endif if (k > 0) { s = sum_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); c = sub_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t)); } else { s = sub_fp64(mul_fp64(u, sin_t), mul_fp64(v, cos_t)); c = sum_fp64(mul_fp64(u, cos_t), mul_fp64(v, sin_t)); } } if (j == 0) { sin_a = s; cos_a = c; } else if (j == 1) { sin_a = c; cos_a = -s; } else if (j == -1) { sin_a = -c; cos_a = s; } else { sin_a = -s; cos_a = -c; } return div_fp64(sin_a, cos_a); } vec2 radians_fp64(vec2 degree) { return mul_fp64(degree, PI_180_FP64); } vec2 mix_fp64(vec2 a, vec2 b, float x) { vec2 range = sub_fp64(b, a); return sum_fp64(a, mul_fp64(range, vec2(x, 0.0))); } void vec2_sum_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) { out_val[0] = sum_fp64(a[0], b[0]); out_val[1] = sum_fp64(a[1], b[1]); } void vec2_sub_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) { out_val[0] = sub_fp64(a[0], b[0]); out_val[1] = sub_fp64(a[1], b[1]); } void vec2_mul_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) { out_val[0] = mul_fp64(a[0], b[0]); out_val[1] = mul_fp64(a[1], b[1]); } void vec2_div_fp64(vec2 a[2], vec2 b[2], out vec2 out_val[2]) { out_val[0] = div_fp64(a[0], b[0]); out_val[1] = div_fp64(a[1], b[1]); } void vec2_mix_fp64(vec2 x[2], vec2 y[2], float a, out vec2 out_val[2]) { vec2 range[2]; vec2_sub_fp64(y, x, range); vec2 portion[2]; portion[0] = range[0] * a; portion[1] = range[1] * a; vec2_sum_fp64(x, portion, out_val); } vec2 vec2_length_fp64(vec2 x[2]) { return sqrt_fp64(sum_fp64(mul_fp64(x[0], x[0]), mul_fp64(x[1], x[1]))); } void vec2_normalize_fp64(vec2 x[2], out vec2 out_val[2]) { vec2 length = vec2_length_fp64(x); vec2 length_vec2[2]; length_vec2[0] = length; length_vec2[1] = length; vec2_div_fp64(x, length_vec2, out_val); } vec2 vec2_distance_fp64(vec2 x[2], vec2 y[2]) { vec2 diff[2]; vec2_sub_fp64(x, y, diff); return vec2_length_fp64(diff); } vec2 vec2_dot_fp64(vec2 a[2], vec2 b[2]) { vec2 v[2]; v[0] = mul_fp64(a[0], b[0]); v[1] = mul_fp64(a[1], b[1]); return sum_fp64(v[0], v[1]); } void vec3_sub_fp64(vec2 a[3], vec2 b[3], out vec2 out_val[3]) { for (int i = 0; i < 3; i++) { out_val[i] = sum_fp64(a[i], b[i]); } } void vec3_sum_fp64(vec2 a[3], vec2 b[3], out vec2 out_val[3]) { for (int i = 0; i < 3; i++) { out_val[i] = sum_fp64(a[i], b[i]); } } vec2 vec3_length_fp64(vec2 x[3]) { return sqrt_fp64(sum_fp64(sum_fp64(mul_fp64(x[0], x[0]), mul_fp64(x[1], x[1])), mul_fp64(x[2], x[2]))); } vec2 vec3_distance_fp64(vec2 x[3], vec2 y[3]) { vec2 diff[3]; vec3_sub_fp64(x, y, diff); return vec3_length_fp64(diff); } void vec4_fp64(vec4 a, out vec2 out_val[4]) { out_val[0].x = a[0]; out_val[0].y = 0.0; out_val[1].x = a[1]; out_val[1].y = 0.0; out_val[2].x = a[2]; out_val[2].y = 0.0; out_val[3].x = a[3]; out_val[3].y = 0.0; } void vec4_scalar_mul_fp64(vec2 a[4], vec2 b, out vec2 out_val[4]) { out_val[0] = mul_fp64(a[0], b); out_val[1] = mul_fp64(a[1], b); out_val[2] = mul_fp64(a[2], b); out_val[3] = mul_fp64(a[3], b); } void vec4_sum_fp64(vec2 a[4], vec2 b[4], out vec2 out_val[4]) { for (int i = 0; i < 4; i++) { out_val[i] = sum_fp64(a[i], b[i]); } } void vec4_dot_fp64(vec2 a[4], vec2 b[4], out vec2 out_val) { vec2 v[4]; v[0] = mul_fp64(a[0], b[0]); v[1] = mul_fp64(a[1], b[1]); v[2] = mul_fp64(a[2], b[2]); v[3] = mul_fp64(a[3], b[3]); out_val = sum_fp64(sum_fp64(v[0], v[1]), sum_fp64(v[2], v[3])); } void mat4_vec4_mul_fp64(vec2 b[16], vec2 a[4], out vec2 out_val[4]) { vec2 tmp[4]; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { tmp[j] = b[j + i * 4]; } vec4_dot_fp64(a, tmp, out_val[i]); } } `;var li={ONE:1};function fi(){return li}var nn={name:"fp64-arithmetic",vs:xr,getUniforms:fi,fp64ify:je,fp64LowPart:en,fp64ifyMatrix4:tn},Ar={name:"fp64",vs:vr,dependencies:[nn],fp64ify:je,fp64LowPart:en,fp64ifyMatrix4:tn};var ui=`varying vec4 geometry_vPosition; varying vec3 geometry_vNormal; void geometry_setNormal(vec3 normal) { geometry_vNormal = normal; } void geometry_setPosition(vec4 position) { geometry_vPosition = position; } void geometry_setPosition(vec3 position) { geometry_vPosition = vec4(position, 1.); } `,_i=`varying vec4 geometry_vPosition; varying vec3 geometry_vNormal; vec4 geometry_getPosition() { return geometry_vPosition; } vec3 geometry_getNormal() { return geometry_vNormal; } `,yr={name:"geometry",vs:ui,fs:_i};var Fa=1/Math.PI*180,Ca=1/180*Math.PI,hi={EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1};globalThis.mathgl=globalThis.mathgl||{config:{...hi}};var O=globalThis.mathgl.config;function br(n,{precision:e=O.precision}={}){return n=pi(n),`${parseFloat(n.toPrecision(e))}`}function $e(n){return Array.isArray(n)||ArrayBuffer.isView(n)&&!(n instanceof DataView)}function rn(n,e,t){let r=O.EPSILON;t&&(O.EPSILON=t);try{if(n===e)return!0;if($e(n)&&$e(e)){if(n.length!==e.length)return!1;for(let o=0;o0?", ":"")+br(this[r],e);return`${e.printTypes?this.constructor.name:""}[${t}]`}equals(e){if(!e||this.length!==e.length)return!1;for(let t=0;tMath.PI*2)throw Error("expected radians")}function Si(n,e,t,r,o,i){let a=2*i/(t-e),c=2*i/(o-r),u=(t+e)/(t-e),h=(o+r)/(o-r),p=-1,d=-1,m=-2*i;return n[0]=a,n[1]=0,n[2]=0,n[3]=0,n[4]=0,n[5]=c,n[6]=0,n[7]=0,n[8]=u,n[9]=h,n[10]=p,n[11]=d,n[12]=0,n[13]=0,n[14]=m,n[15]=0,n}var fn=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],Ni={modelMatrix:fn,viewMatrix:fn,projectionMatrix:fn,cameraPositionWorld:[0,0,0]};function Ti(n=Ni,e={}){let t={};return n.modelMatrix!==void 0&&(t.modelMatrix=n.modelMatrix),n.viewMatrix!==void 0&&(t.viewMatrix=n.viewMatrix),n.projectionMatrix!==void 0&&(t.projectionMatrix=n.projectionMatrix),n.cameraPositionWorld!==void 0&&(t.cameraPositionWorld=n.cameraPositionWorld),(n.projectionMatrix!==void 0||n.viewMatrix!==void 0)&&(t.viewProjectionMatrix=new ee(n.projectionMatrix).multiplyRight(n.viewMatrix)),t}var Hr=`varying vec4 project_vPositionWorld; varying vec3 project_vNormalWorld; vec4 project_getPosition_World() { return project_vPositionWorld; } vec3 project_getNormal_World() { return project_vNormalWorld; } `,Ei=`${Hr} // Unprefixed uniforms uniform mat4 modelMatrix; uniform mat4 viewMatrix; uniform mat4 projectionMatrix; uniform mat4 viewProjectionMatrix; uniform vec3 cameraPositionWorld; struct World { vec3 position; vec3 normal; }; World world; void project_setPosition(vec4 position) { project_vPositionWorld = position; } void project_setNormal(vec3 normal) { project_vNormalWorld = normal; } void project_setPositionAndNormal_World(vec3 position, vec3 normal) { world.position = position; world.normal = normal; } void project_setPositionAndNormal_Model(vec3 position, vec3 normal) { world.position = (modelMatrix * vec4(position, 1.)).xyz; world.normal = mat3(modelMatrix) * normal; } vec4 project_model_to_clipspace(vec4 position) { return viewProjectionMatrix * modelMatrix * position; } vec4 project_model_to_clipspace(vec3 position) { return viewProjectionMatrix * modelMatrix * vec4(position, 1.); } vec4 project_world_to_clipspace(vec3 position) { return viewProjectionMatrix * vec4(position, 1.); } vec4 project_view_to_clipspace(vec3 position) { return projectionMatrix * vec4(position, 1.); } vec4 project_to_clipspace(vec3 position) { return viewProjectionMatrix * vec4(position, 1.); } `,Mi=` ${Hr}`,nt={name:"project",getUniforms:Ti,vs:Ei,fs:Mi};var un=`#if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX)) struct AmbientLight { vec3 color; }; struct PointLight { vec3 color; vec3 position; vec3 attenuation; }; struct DirectionalLight { vec3 color; vec3 direction; }; uniform AmbientLight lighting_uAmbientLight; uniform PointLight lighting_uPointLight[MAX_LIGHTS]; uniform DirectionalLight lighting_uDirectionalLight[MAX_LIGHTS]; uniform int lighting_uPointLightCount; uniform int lighting_uDirectionalLightCount; uniform bool lighting_uEnabled; float getPointLightAttenuation(PointLight pointLight, float distance) { return pointLight.attenuation.x + pointLight.attenuation.y * distance + pointLight.attenuation.z * distance * distance; } #endif `;var Ii={lightSources:{}};function _n(n={}){let{color:e=[0,0,0],intensity:t=1}=n;return e.map(r=>r*t/255)}function Fi({ambientLight:n,pointLights:e=[],directionalLights:t=[]}){let r={};return n?r["lighting_uAmbientLight.color"]=_n(n):r["lighting_uAmbientLight.color"]=[0,0,0],e.forEach((o,i)=>{r[`lighting_uPointLight[${i}].color`]=_n(o),r[`lighting_uPointLight[${i}].position`]=o.position,r[`lighting_uPointLight[${i}].attenuation`]=o.attenuation||[1,0,0]}),r.lighting_uPointLightCount=e.length,t.forEach((o,i)=>{r[`lighting_uDirectionalLight[${i}].color`]=_n(o),r[`lighting_uDirectionalLight[${i}].direction`]=o.direction}),r.lighting_uDirectionalLightCount=t.length,r}function Gr(n=Ii){if("lightSources"in n){let{ambientLight:e,pointLights:t,directionalLights:r}=n.lightSources||{};return e||t&&t.length>0||r&&r.length>0?Object.assign({},Fi({ambientLight:e,pointLights:t,directionalLights:r}),{lighting_uEnabled:!0}):{lighting_uEnabled:!1}}if("lights"in n){let e={pointLights:[],directionalLights:[]};for(let t of n.lights||[])switch(t.type){case"ambient":e.ambientLight=t;break;case"directional":e.directionalLights?.push(t);break;case"point":e.pointLights?.push(t);break;default:}return Gr({lightSources:e})}return{}}var te={name:"lights",vs:un,fs:un,getUniforms:Gr,defines:{MAX_LIGHTS:3}};var Ci={lightDirection:new Float32Array([1,1,2])};function Ri(n=Ci){let e={};return n.lightDirection&&(e.dirlight_uLightDirection=n.lightDirection),e}var Oi=`uniform vec3 dirlight_uLightDirection; vec4 dirlight_filterColor(vec4 color) { vec3 normal = project_getNormal_World(); float d = abs(dot(normalize(normal), normalize(dirlight_uLightDirection))); return vec4(color.rgb * d, color.a); } `,Wr={name:"dirlight",fs:Oi,getUniforms:Ri,dependencies:[nt]};var hn=`uniform float lighting_uAmbient; uniform float lighting_uDiffuse; uniform float lighting_uShininess; uniform vec3 lighting_uSpecularColor; vec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 view_direction, vec3 normal_worldspace, vec3 color) { vec3 halfway_direction = normalize(light_direction + view_direction); float lambertian = dot(light_direction, normal_worldspace); float specular = 0.0; if (lambertian > 0.0) { float specular_angle = max(dot(normal_worldspace, halfway_direction), 0.0); specular = pow(specular_angle, lighting_uShininess); } lambertian = max(lambertian, 0.0); return (lambertian * lighting_uDiffuse * surfaceColor + specular * lighting_uSpecularColor) * color; } vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) { vec3 lightColor = surfaceColor; if (lighting_uEnabled) { vec3 view_direction = normalize(cameraPosition - position_worldspace); lightColor = lighting_uAmbient * surfaceColor * lighting_uAmbientLight.color; for (int i = 0; i < MAX_LIGHTS; i++) { if (i >= lighting_uPointLightCount) { break; } PointLight pointLight = lighting_uPointLight[i]; vec3 light_position_worldspace = pointLight.position; vec3 light_direction = normalize(light_position_worldspace - position_worldspace); lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color); } for (int i = 0; i < MAX_LIGHTS; i++) { if (i >= lighting_uDirectionalLightCount) { break; } DirectionalLight directionalLight = lighting_uDirectionalLight[i]; lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color); } } return lightColor; } vec3 lighting_getSpecularLightColor(vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) { vec3 lightColor = vec3(0, 0, 0); vec3 surfaceColor = vec3(0, 0, 0); if (lighting_uEnabled) { vec3 view_direction = normalize(cameraPosition - position_worldspace); for (int i = 0; i < MAX_LIGHTS; i++) { if (i >= lighting_uPointLightCount) { break; } PointLight pointLight = lighting_uPointLight[i]; vec3 light_position_worldspace = pointLight.position; vec3 light_direction = normalize(light_position_worldspace - position_worldspace); lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color); } for (int i = 0; i < MAX_LIGHTS; i++) { if (i >= lighting_uDirectionalLightCount) { break; } DirectionalLight directionalLight = lighting_uDirectionalLight[i]; lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color); } } return lightColor; } `;var Ui={};function zi(n){let{ambient:e=.35,diffuse:t=.6,shininess:r=32,specularColor:o=[30,30,30]}=n;return{lighting_uAmbient:e,lighting_uDiffuse:t,lighting_uShininess:r,lighting_uSpecularColor:o.map(i=>i/255)}}function jr(n=Ui){if(!("material"in n))return{};let{material:e}=n;return e?zi(e):{lighting_uEnabled:!1}}var $r={name:"gouraud-lighting",dependencies:[te],vs:hn,defines:{LIGHTING_VERTEX:1},getUniforms:jr},Kr={name:"phong-lighting",dependencies:[te],fs:hn,defines:{LIGHTING_FRAGMENT:1},getUniforms:jr};var Zr=`uniform mat4 u_MVPMatrix; uniform mat4 u_ModelMatrix; uniform mat4 u_NormalMatrix; out vec3 pbr_vPosition; out vec2 pbr_vUV; #ifdef HAS_NORMALS # ifdef HAS_TANGENTS out mat3 pbr_vTBN; # else out vec3 pbr_vNormal; # endif #endif void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, vec2 uv) { vec4 pos = u_ModelMatrix * position; pbr_vPosition = vec3(pos.xyz) / pos.w; #ifdef HAS_NORMALS #ifdef HAS_TANGENTS vec3 normalW = normalize(vec3(u_NormalMatrix * vec4(normal.xyz, 0.0))); vec3 tangentW = normalize(vec3(u_ModelMatrix * vec4(tangent.xyz, 0.0))); vec3 bitangentW = cross(normalW, tangentW) * tangent.w; pbr_vTBN = mat3(tangentW, bitangentW, normalW); #else pbr_vNormal = normalize(vec3(u_ModelMatrix * vec4(normal.xyz, 0.0))); #endif #endif #ifdef HAS_UV pbr_vUV = uv; #else pbr_vUV = vec2(0.,0.); #endif } `;var Jr=`precision highp float; uniform bool pbr_uUnlit; #ifdef USE_IBL uniform samplerCube u_DiffuseEnvSampler; uniform samplerCube u_SpecularEnvSampler; uniform sampler2D u_brdfLUT; uniform vec2 u_ScaleIBLAmbient; #endif #ifdef HAS_BASECOLORMAP uniform sampler2D u_BaseColorSampler; #endif #ifdef HAS_NORMALMAP uniform sampler2D u_NormalSampler; uniform float u_NormalScale; #endif #ifdef HAS_EMISSIVEMAP uniform sampler2D u_EmissiveSampler; uniform vec3 u_EmissiveFactor; #endif #ifdef HAS_METALROUGHNESSMAP uniform sampler2D u_MetallicRoughnessSampler; #endif #ifdef HAS_OCCLUSIONMAP uniform sampler2D u_OcclusionSampler; uniform float u_OcclusionStrength; #endif #ifdef ALPHA_CUTOFF uniform float u_AlphaCutoff; #endif uniform vec2 u_MetallicRoughnessValues; uniform vec4 u_BaseColorFactor; uniform vec3 u_Camera; #ifdef PBR_DEBUG uniform vec4 u_ScaleDiffBaseMR; uniform vec4 u_ScaleFGDSpec; #endif in vec3 pbr_vPosition; in vec2 pbr_vUV; #ifdef HAS_NORMALS #ifdef HAS_TANGENTS in mat3 pbr_vTBN; #else in vec3 pbr_vNormal; #endif #endif struct PBRInfo { float NdotL; float NdotV; float NdotH; float LdotH; float VdotH; float perceptualRoughness; float metalness; vec3 reflectance0; vec3 reflectance90; float alphaRoughness; vec3 diffuseColor; vec3 specularColor; vec3 n; vec3 v; }; const float M_PI = 3.141592653589793; const float c_MinRoughness = 0.04; vec4 SRGBtoLINEAR(vec4 srgbIn) { #ifdef MANUAL_SRGB #ifdef SRGB_FAST_APPROXIMATION vec3 linOut = pow(srgbIn.xyz,vec3(2.2)); #else vec3 bLess = step(vec3(0.04045),srgbIn.xyz); vec3 linOut = mix( srgbIn.xyz/vec3(12.92), pow((srgbIn.xyz+vec3(0.055))/vec3(1.055),vec3(2.4)), bLess ); #endif return vec4(linOut,srgbIn.w);; #else return srgbIn; #endif } vec3 getNormal() { #ifndef HAS_TANGENTS vec3 pos_dx = dFdx(pbr_vPosition); vec3 pos_dy = dFdy(pbr_vPosition); vec3 tex_dx = dFdx(vec3(pbr_vUV, 0.0)); vec3 tex_dy = dFdy(vec3(pbr_vUV, 0.0)); vec3 t = (tex_dy.t * pos_dx - tex_dx.t * pos_dy) / (tex_dx.s * tex_dy.t - tex_dy.s * tex_dx.t); #ifdef HAS_NORMALS vec3 ng = normalize(pbr_vNormal); #else vec3 ng = cross(pos_dx, pos_dy); #endif t = normalize(t - ng * dot(ng, t)); vec3 b = normalize(cross(ng, t)); mat3 tbn = mat3(t, b, ng); #else mat3 tbn = pbr_vTBN; #endif #ifdef HAS_NORMALMAP vec3 n = texture(u_NormalSampler, pbr_vUV).rgb; n = normalize(tbn * ((2.0 * n - 1.0) * vec3(u_NormalScale, u_NormalScale, 1.0))); #else vec3 n = normalize(tbn[2].xyz); #endif return n; } #ifdef USE_IBL vec3 getIBLContribution(PBRInfo pbrInputs, vec3 n, vec3 reflection) { float mipCount = 9.0; float lod = (pbrInputs.perceptualRoughness * mipCount); vec3 brdf = SRGBtoLINEAR(texture(u_brdfLUT, vec2(pbrInputs.NdotV, 1.0 - pbrInputs.perceptualRoughness))).rgb; vec3 diffuseLight = SRGBtoLINEAR(textureCube(u_DiffuseEnvSampler, n)).rgb; #ifdef USE_TEX_LOD vec3 specularLight = SRGBtoLINEAR(textureCubeLod(u_SpecularEnvSampler, reflection, lod)).rgb; #else vec3 specularLight = SRGBtoLINEAR(textureCube(u_SpecularEnvSampler, reflection)).rgb; #endif vec3 diffuse = diffuseLight * pbrInputs.diffuseColor; vec3 specular = specularLight * (pbrInputs.specularColor * brdf.x + brdf.y); diffuse *= u_ScaleIBLAmbient.x; specular *= u_ScaleIBLAmbient.y; return diffuse + specular; } #endif vec3 diffuse(PBRInfo pbrInputs) { return pbrInputs.diffuseColor / M_PI; } vec3 specularReflection(PBRInfo pbrInputs) { return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0); } float geometricOcclusion(PBRInfo pbrInputs) { float NdotL = pbrInputs.NdotL; float NdotV = pbrInputs.NdotV; float r = pbrInputs.alphaRoughness; float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL))); float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV))); return attenuationL * attenuationV; } float microfacetDistribution(PBRInfo pbrInputs) { float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness; float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0; return roughnessSq / (M_PI * f * f); } void PBRInfo_setAmbientLight(inout PBRInfo pbrInputs) { pbrInputs.NdotL = 1.0; pbrInputs.NdotH = 0.0; pbrInputs.LdotH = 0.0; pbrInputs.VdotH = 1.0; } void PBRInfo_setDirectionalLight(inout PBRInfo pbrInputs, vec3 lightDirection) { vec3 n = pbrInputs.n; vec3 v = pbrInputs.v; vec3 l = normalize(lightDirection); vec3 h = normalize(l+v); pbrInputs.NdotL = clamp(dot(n, l), 0.001, 1.0); pbrInputs.NdotH = clamp(dot(n, h), 0.0, 1.0); pbrInputs.LdotH = clamp(dot(l, h), 0.0, 1.0); pbrInputs.VdotH = clamp(dot(v, h), 0.0, 1.0); } void PBRInfo_setPointLight(inout PBRInfo pbrInputs, PointLight pointLight) { vec3 light_direction = normalize(pointLight.position - pbr_vPosition); PBRInfo_setDirectionalLight(pbrInputs, light_direction); } vec3 calculateFinalColor(PBRInfo pbrInputs, vec3 lightColor) { vec3 F = specularReflection(pbrInputs); float G = geometricOcclusion(pbrInputs); float D = microfacetDistribution(pbrInputs); vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs); vec3 specContrib = F * G * D / (4.0 * pbrInputs.NdotL * pbrInputs.NdotV); return pbrInputs.NdotL * lightColor * (diffuseContrib + specContrib); } vec4 pbr_filterColor(vec4 colorUnused) { #ifdef HAS_BASECOLORMAP vec4 baseColor = SRGBtoLINEAR(texture(u_BaseColorSampler, pbr_vUV)) * u_BaseColorFactor; #else vec4 baseColor = u_BaseColorFactor; #endif #ifdef ALPHA_CUTOFF if (baseColor.a < u_AlphaCutoff) { discard; } #endif vec3 color = vec3(0, 0, 0); if(pbr_uUnlit){ color.rgb = baseColor.rgb; } else{ float perceptualRoughness = u_MetallicRoughnessValues.y; float metallic = u_MetallicRoughnessValues.x; #ifdef HAS_METALROUGHNESSMAP vec4 mrSample = texture(u_MetallicRoughnessSampler, pbr_vUV); perceptualRoughness = mrSample.g * perceptualRoughness; metallic = mrSample.b * metallic; #endif perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0); metallic = clamp(metallic, 0.0, 1.0); float alphaRoughness = perceptualRoughness * perceptualRoughness; vec3 f0 = vec3(0.04); vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0); diffuseColor *= 1.0 - metallic; vec3 specularColor = mix(f0, baseColor.rgb, metallic); float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b); float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0); vec3 specularEnvironmentR0 = specularColor.rgb; vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90; vec3 n = getNormal(); vec3 v = normalize(u_Camera - pbr_vPosition); float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0); vec3 reflection = -normalize(reflect(v, n)); PBRInfo pbrInputs = PBRInfo( 0.0, NdotV, 0.0, 0.0, 0.0, perceptualRoughness, metallic, specularEnvironmentR0, specularEnvironmentR90, alphaRoughness, diffuseColor, specularColor, n, v ); #ifdef USE_LIGHTS PBRInfo_setAmbientLight(pbrInputs); color += calculateFinalColor(pbrInputs, lighting_uAmbientLight.color); for(int i = 0; i < lighting_uDirectionalLightCount; i++) { if (i < lighting_uDirectionalLightCount) { PBRInfo_setDirectionalLight(pbrInputs, lighting_uDirectionalLight[i].direction); color += calculateFinalColor(pbrInputs, lighting_uDirectionalLight[i].color); } } for(int i = 0; i < lighting_uPointLightCount; i++) { if (i < lighting_uPointLightCount) { PBRInfo_setPointLight(pbrInputs, lighting_uPointLight[i]); float attenuation = getPointLightAttenuation(lighting_uPointLight[i], distance(lighting_uPointLight[i].position, pbr_vPosition)); color += calculateFinalColor(pbrInputs, lighting_uPointLight[i].color / attenuation); } } #endif #ifdef USE_IBL color += getIBLContribution(pbrInputs, n, reflection); #endif #ifdef HAS_OCCLUSIONMAP float ao = texture(u_OcclusionSampler, pbr_vUV).r; color = mix(color, color * ao, u_OcclusionStrength); #endif #ifdef HAS_EMISSIVEMAP vec3 emissive = SRGBtoLINEAR(texture(u_EmissiveSampler, pbr_vUV)).rgb * u_EmissiveFactor; color += emissive; #endif #ifdef PBR_DEBUG color = mix(color, baseColor.rgb, u_ScaleDiffBaseMR.y); color = mix(color, vec3(metallic), u_ScaleDiffBaseMR.z); color = mix(color, vec3(perceptualRoughness), u_ScaleDiffBaseMR.w); #endif } return vec4(pow(color,vec3(1.0/2.2)), baseColor.a); } `;var eo={name:"pbr",vs:Zr,fs:Jr,defines:{LIGHTING_FRAGMENT:1},dependencies:[te]};return lo(Pe);})(); /** * ORIGINAL LICENCE * @license * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of NVIDIA CORPORATION nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ return __exports__; });