@luma.gl/shadertools 9.3.0-alpha.6 → 9.3.0-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +2550 -331
- package/dist/dist.min.js +1803 -283
- package/dist/index.cjs +2496 -358
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/preprocessor/preprocessor.d.ts.map +1 -1
- package/dist/lib/preprocessor/preprocessor.js +4 -3
- package/dist/lib/preprocessor/preprocessor.js.map +1 -1
- package/dist/lib/shader-assembler.d.ts +10 -0
- package/dist/lib/shader-assembler.d.ts.map +1 -1
- package/dist/lib/shader-assembler.js +12 -2
- package/dist/lib/shader-assembler.js.map +1 -1
- package/dist/lib/shader-assembly/assemble-shaders.d.ts +23 -2
- package/dist/lib/shader-assembly/assemble-shaders.d.ts.map +1 -1
- package/dist/lib/shader-assembly/assemble-shaders.js +211 -11
- package/dist/lib/shader-assembly/assemble-shaders.js.map +1 -1
- package/dist/lib/shader-assembly/wgsl-binding-debug.d.ts +37 -0
- package/dist/lib/shader-assembly/wgsl-binding-debug.d.ts.map +1 -0
- package/dist/lib/shader-assembly/wgsl-binding-debug.js +140 -0
- package/dist/lib/shader-assembly/wgsl-binding-debug.js.map +1 -0
- package/dist/lib/shader-generator/glsl/generate-glsl.js +3 -0
- package/dist/lib/shader-generator/glsl/generate-glsl.js.map +1 -1
- package/dist/lib/shader-generator/wgsl/generate-wgsl.d.ts.map +1 -1
- package/dist/lib/shader-generator/wgsl/generate-wgsl.js +3 -0
- package/dist/lib/shader-generator/wgsl/generate-wgsl.js.map +1 -1
- package/dist/lib/shader-module/shader-module-uniform-layout.d.ts +22 -0
- package/dist/lib/shader-module/shader-module-uniform-layout.d.ts.map +1 -0
- package/dist/lib/shader-module/shader-module-uniform-layout.js +113 -0
- package/dist/lib/shader-module/shader-module-uniform-layout.js.map +1 -0
- package/dist/lib/shader-module/shader-module.d.ts +11 -5
- package/dist/lib/shader-module/shader-module.d.ts.map +1 -1
- package/dist/lib/shader-module/shader-module.js.map +1 -1
- package/dist/lib/utils/uniform-types.d.ts +11 -7
- package/dist/lib/utils/uniform-types.d.ts.map +1 -1
- package/dist/modules/engine/picking/picking.d.ts +3 -0
- package/dist/modules/engine/picking/picking.d.ts.map +1 -1
- package/dist/modules/engine/picking/picking.js +3 -0
- package/dist/modules/engine/picking/picking.js.map +1 -1
- package/dist/modules/engine/skin/skin.d.ts +7 -6
- package/dist/modules/engine/skin/skin.d.ts.map +1 -1
- package/dist/modules/engine/skin/skin.js +3 -5
- package/dist/modules/engine/skin/skin.js.map +1 -1
- package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts +1 -0
- package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts.map +1 -1
- package/dist/modules/lighting/gouraud-material/gouraud-material.js +3 -0
- package/dist/modules/lighting/gouraud-material/gouraud-material.js.map +1 -1
- package/dist/modules/lighting/ibl/ibl.d.ts +26 -0
- package/dist/modules/lighting/ibl/ibl.d.ts.map +1 -0
- package/dist/modules/lighting/ibl/ibl.js +33 -0
- package/dist/modules/lighting/ibl/ibl.js.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-material.d.ts +10 -0
- package/dist/modules/lighting/lambert-material/lambert-material.d.ts.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-material.js +33 -0
- package/dist/modules/lighting/lambert-material/lambert-material.js.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.d.ts +3 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.d.ts.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.js +60 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.js.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.d.ts +2 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.d.ts.map +1 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.js +73 -0
- package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.js.map +1 -0
- package/dist/modules/lighting/lights/lighting-glsl.d.ts +1 -1
- package/dist/modules/lighting/lights/lighting-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/lights/lighting-glsl.js +43 -55
- package/dist/modules/lighting/lights/lighting-glsl.js.map +1 -1
- package/dist/modules/lighting/lights/lighting-wgsl.d.ts +1 -1
- package/dist/modules/lighting/lights/lighting-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/lights/lighting-wgsl.js +43 -65
- package/dist/modules/lighting/lights/lighting-wgsl.js.map +1 -1
- package/dist/modules/lighting/lights/lighting.d.ts +104 -86
- package/dist/modules/lighting/lights/lighting.d.ts.map +1 -1
- package/dist/modules/lighting/lights/lighting.js +96 -83
- package/dist/modules/lighting/lights/lighting.js.map +1 -1
- package/dist/modules/lighting/no-material/dirlight.d.ts +7 -2
- package/dist/modules/lighting/no-material/dirlight.d.ts.map +1 -1
- package/dist/modules/lighting/no-material/dirlight.js +3 -1
- package/dist/modules/lighting/no-material/dirlight.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.js +524 -28
- package/dist/modules/lighting/pbr-material/pbr-material-glsl.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +2 -2
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +706 -50
- package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts +110 -61
- package/dist/modules/lighting/pbr-material/pbr-material.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-material.js +85 -9
- package/dist/modules/lighting/pbr-material/pbr-material.js.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-projection.d.ts.map +1 -1
- package/dist/modules/lighting/pbr-material/pbr-projection.js +2 -1
- package/dist/modules/lighting/pbr-material/pbr-projection.js.map +1 -1
- package/dist/modules/lighting/phong-material/phong-material.d.ts +1 -0
- package/dist/modules/lighting/phong-material/phong-material.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-material.js +4 -0
- package/dist/modules/lighting/phong-material/phong-material.js.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts +2 -2
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.js +15 -4
- package/dist/modules/lighting/phong-material/phong-shaders-glsl.js.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts.map +1 -1
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js +36 -5
- package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js.map +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.d.ts +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.d.ts.map +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.js +41 -10
- package/dist/modules/math/fp64/fp64-arithmetic-glsl.js.map +1 -1
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.d.ts +2 -0
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.d.ts.map +1 -0
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.js +212 -0
- package/dist/modules/math/fp64/fp64-arithmetic-wgsl.js.map +1 -0
- package/dist/modules/math/fp64/fp64.d.ts +1 -0
- package/dist/modules/math/fp64/fp64.d.ts.map +1 -1
- package/dist/modules/math/fp64/fp64.js +8 -2
- package/dist/modules/math/fp64/fp64.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +19 -2
- package/src/lib/preprocessor/preprocessor.ts +6 -3
- package/src/lib/shader-assembler.ts +17 -2
- package/src/lib/shader-assembly/assemble-shaders.ts +377 -12
- package/src/lib/shader-assembly/wgsl-binding-debug.ts +216 -0
- package/src/lib/shader-generator/glsl/generate-glsl.ts +7 -1
- package/src/lib/shader-generator/wgsl/generate-wgsl.ts +6 -0
- package/src/lib/shader-module/shader-module-uniform-layout.ts +195 -0
- package/src/lib/shader-module/shader-module.ts +16 -6
- package/src/lib/utils/uniform-types.ts +24 -9
- package/src/modules/engine/picking/picking.ts +3 -0
- package/src/modules/engine/skin/skin.ts +3 -5
- package/src/modules/lighting/gouraud-material/gouraud-material.ts +4 -0
- package/src/modules/lighting/ibl/ibl.ts +44 -0
- package/src/modules/lighting/lambert-material/lambert-material.ts +42 -0
- package/src/modules/lighting/lambert-material/lambert-shaders-glsl.ts +61 -0
- package/src/modules/lighting/lambert-material/lambert-shaders-wgsl.ts +73 -0
- package/src/modules/lighting/lights/lighting-glsl.ts +43 -55
- package/src/modules/lighting/lights/lighting-wgsl.ts +43 -65
- package/src/modules/lighting/lights/lighting.ts +186 -123
- package/src/modules/lighting/no-material/dirlight.ts +3 -1
- package/src/modules/lighting/pbr-material/pbr-material-glsl.ts +524 -28
- package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +706 -50
- package/src/modules/lighting/pbr-material/pbr-material.ts +111 -18
- package/src/modules/lighting/pbr-material/pbr-projection.ts +2 -1
- package/src/modules/lighting/phong-material/phong-material.ts +5 -0
- package/src/modules/lighting/phong-material/phong-shaders-glsl.ts +15 -4
- package/src/modules/lighting/phong-material/phong-shaders-wgsl.ts +36 -5
- package/src/modules/math/fp64/fp64-arithmetic-glsl.ts +41 -10
- package/src/modules/math/fp64/fp64-arithmetic-wgsl.ts +212 -0
- package/src/modules/math/fp64/fp64.ts +9 -3
package/dist/dist.min.js
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
else if (typeof define === 'function' && define.amd) define([], factory);
|
|
5
5
|
else if (typeof exports === 'object') exports['luma'] = factory();
|
|
6
6
|
else root['luma'] = factory();})(globalThis, function () {
|
|
7
|
-
"use strict";var __exports__=(()=>{var
|
|
7
|
+
"use strict";var __exports__=(()=>{var Nn=Object.create;var j=Object.defineProperty;var yn=Object.getOwnPropertyDescriptor;var On=Object.getOwnPropertyNames;var Tn=Object.getPrototypeOf,Fn=Object.prototype.hasOwnProperty;var wn=(e,t,n)=>t in e?j(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Bn=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),kn=(e,t)=>{for(var n in t)j(e,n,{get:t[n],enumerable:!0})},re=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of On(t))!Fn.call(e,o)&&o!==n&&j(e,o,{get:()=>t[o],enumerable:!(r=yn(t,o))||r.enumerable});return e},oe=(e,t,n)=>(re(e,t,"default"),n&&re(n,t,"default")),Ze=(e,t,n)=>(n=e!=null?Nn(Tn(e)):{},re(t||!e||!e.__esModule?j(n,"default",{value:e,enumerable:!0}):n,e)),Dn=e=>re(j({},"__esModule",{value:!0}),e);var Je=(e,t,n)=>(wn(e,typeof t!="symbol"?t+"":t,n),n);var Ie=Bn((mo,Qe)=>{Qe.exports=globalThis.luma});var ne={};kn(ne,{ShaderAssembler:()=>J,_getDependencyGraph:()=>X,_resolveModules:()=>ft,assembleGLSLShaderPair:()=>he,capitalize:()=>k,checkShaderModuleDeprecations:()=>K,combineInjects:()=>ct,convertToVec4:()=>Be,dirlight:()=>qe,fp32:()=>pn,fp64:()=>gn,fp64LowPart:()=>Q,fp64arithmetic:()=>je,fp64ify:()=>V,fp64ifyMatrix4:()=>ee,fromHalfFloat:()=>cn,generateShaderForModule:()=>Tt,getPassthroughFS:()=>Ct,getQualifierDetails:()=>It,getShaderInfo:()=>ce,getShaderModuleDependencies:()=>Y,getShaderModuleSource:()=>ue,getShaderModuleUniformBlockFields:()=>Ne,getShaderModuleUniformBlockName:()=>ae,getShaderModuleUniformLayoutValidationResult:()=>ye,getShaderModuleUniforms:()=>lt,gouraudMaterial:()=>Ye,ibl:()=>Le,initializeShaderModule:()=>ie,initializeShaderModules:()=>T,lambertMaterial:()=>Ke,lighting:()=>F,pbrMaterial:()=>Pn,phongMaterial:()=>Xe,picking:()=>mn,preprocess:()=>ge,random:()=>fn,skin:()=>dn,toHalfFloat:()=>sn,typeToChannelCount:()=>Nt,typeToChannelSuffix:()=>Pt,validateShaderModuleUniformLayout:()=>se});oe(ne,Ze(Ie(),1));function O(e,t){if(!e){let n=new Error(t||"shadertools: assertion failed.");throw Error.captureStackTrace?.(n,O),n}}var Ce={number:{type:"number",validate(e,t){return Number.isFinite(e)&&typeof t=="object"&&(t.max===void 0||e<=t.max)&&(t.min===void 0||e>=t.min)}},array:{type:"array",validate(e,t){return Array.isArray(e)||ArrayBuffer.isView(e)}}};function tt(e){let t={};for(let[n,r]of Object.entries(e))t[n]=Un(r);return t}function nt(e,t,n){let r={};for(let[o,i]of Object.entries(t))e&&o in e&&!i.private?(i.validate&&O(i.validate(e[o],i),`${n}: invalid ${o}`),r[o]=e[o]):r[o]=i.value;return r}function Un(e){let t=et(e);if(t!=="object")return{value:e,...Ce[t],type:t};if(typeof e=="object")return e?e.type!==void 0?{...e,...Ce[e.type],type:e.type}:e.value===void 0?{type:"object",value:e}:(t=et(e.value),{...e,...Ce[t],type:t}):{type:"object",value:null};throw new Error("props")}function et(e){return Array.isArray(e)||ArrayBuffer.isView(e)?"array":typeof e}var rt=`#ifdef MODULE_LOGDEPTH
|
|
8
8
|
logdepth_adjustPosition(gl_Position);
|
|
9
9
|
#endif
|
|
10
|
-
`,
|
|
10
|
+
`,ot=`#ifdef MODULE_MATERIAL
|
|
11
11
|
fragColor = material_filterColor(fragColor);
|
|
12
12
|
#endif
|
|
13
13
|
|
|
@@ -27,10 +27,13 @@
|
|
|
27
27
|
#ifdef MODULE_LOGDEPTH
|
|
28
28
|
logdepth_setFragDepth();
|
|
29
29
|
#endif
|
|
30
|
-
`;var
|
|
30
|
+
`;var zn={vertex:rt,fragment:ot},it=/void\s+main\s*\([^)]*\)\s*\{\n?/,at=/}\n?[^{}]*$/,Pe=[],$="__LUMA_INJECT_DECLARATIONS__";function st(e){let t={vertex:{},fragment:{}};for(let n in e){let r=e[n],o=Hn(n);typeof r=="string"&&(r={order:0,injection:r}),t[o][n]=r}return t}function Hn(e){let t=e.slice(0,2);switch(t){case"vs":return"vertex";case"fs":return"fragment";default:throw new Error(t)}}function q(e,t,n,r=!1){let o=t==="vertex";for(let i in n){let a=n[i];a.sort((c,l)=>c.order-l.order),Pe.length=a.length;for(let c=0,l=a.length;c<l;++c)Pe[c]=a[c].injection;let s=`${Pe.join(`
|
|
31
31
|
`)}
|
|
32
|
-
`;switch(
|
|
33
|
-
${n[
|
|
32
|
+
`;switch(i){case"vs:#decl":o&&(e=e.replace($,s));break;case"vs:#main-start":o&&(e=e.replace(it,c=>c+s));break;case"vs:#main-end":o&&(e=e.replace(at,c=>s+c));break;case"fs:#decl":o||(e=e.replace($,s));break;case"fs:#main-start":o||(e=e.replace(it,c=>c+s));break;case"fs:#main-end":o||(e=e.replace(at,c=>s+c));break;default:e=e.replace(i,c=>c+s)}}return e=e.replace($,""),r&&(e=e.replace(/\}\s*$/,i=>i+zn[t])),e}function ct(e){let t={};return O(Array.isArray(e)&&e.length>1),e.forEach(n=>{for(let r in n)t[r]=t[r]?`${t[r]}
|
|
33
|
+
${n[r]}`:n[r]}),t}function T(e){e.map(t=>ie(t))}function ie(e){if(e.instance)return;T(e.dependencies||[]);let{propTypes:t={},deprecations:n=[],inject:r={}}=e,o={normalizedInjections:st(r),parsedDeprecations:Gn(n)};t&&(o.propValidators=tt(t)),e.instance=o;let i={};t&&(i=Object.entries(t).reduce((a,[s,c])=>{let l=c?.value;return l&&(a[s]=l),a},{})),e.defaultUniforms={...e.defaultUniforms,...i}}function lt(e,t,n){ie(e);let r=n||{...e.defaultUniforms};return t&&e.getUniforms?e.getUniforms(t,r):nt(t,e.instance?.propValidators,e.name)}function K(e,t,n){e.deprecations?.forEach(r=>{r.regex?.test(t)&&(r.deprecated?n.deprecated(r.old,r.new)():n.removed(r.old,r.new)())})}function Gn(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}function Y(e){T(e);let t={},n={};X({modules:e,level:0,moduleMap:t,moduleDepth:n});let r=Object.keys(n).sort((o,i)=>n[i]-n[o]).map(o=>t[o]);return T(r),r}function X(e){let{modules:t,level:n,moduleMap:r,moduleDepth:o}=e;if(n>=5)throw new Error("Possible loop in shader dependency graph");for(let i of t)r[i.name]=i,(o[i.name]===void 0||o[i.name]<n)&&(o[i.name]=n);for(let i of t)i.dependencies&&X({modules:i.dependencies,level:n+1,moduleMap:r,moduleDepth:o})}function Vn(e){T(e);let t={},n={};return X({modules:e,level:0,moduleMap:t,moduleDepth:n}),e=Object.keys(n).sort((r,o)=>n[o]-n[r]).map(r=>t[r]),T(e),e}function ft(e){return Vn(e)}var Wn=/^(?:uniform\s+)?(?:(?:lowp|mediump|highp)\s+)?[A-Za-z0-9_]+(?:<[^>]+>)?\s+([A-Za-z0-9_]+)(?:\s*\[[^\]]+\])?\s*;/;function ae(e){return`${e.name}Uniforms`}function Ne(e,t){let n=t==="wgsl"?e.source:t==="vertex"?e.vs:e.fs;if(!n)return null;let r=ae(e);return jn(n,t==="wgsl"?"wgsl":"glsl",r)}function ye(e,t){let n=Object.keys(e.uniformTypes||{});if(!n.length)return null;let r=Ne(e,t);return r?{moduleName:e.name,uniformBlockName:ae(e),stage:t,expectedUniformNames:n,actualUniformNames:r,matches:Kn(n,r)}:null}function se(e,t,n={}){let r=ye(e,t);if(!r||r.matches)return r;let o=Yn(r);return n.log?.error?.(o,r)(),n.throwOnError!==!1&&O(!1,o),r}function jn(e,t,n){let r=t==="wgsl"?$n(e,n):qn(e,n);if(!r)return null;let o=[];for(let i of r.split(`
|
|
34
|
+
`)){let a=i.replace(/\/\/.*$/,"").trim();if(!a||a.startsWith("#"))continue;let s=t==="wgsl"?a.match(/^([A-Za-z0-9_]+)\s*:/):a.match(Wn);s&&o.push(s[1])}return o}function $n(e,t){let n=new RegExp(`\\bstruct\\s+${t}\\b`,"m").exec(e);if(!n)return null;let r=e.indexOf("{",n.index);if(r<0)return null;let o=0;for(let i=r;i<e.length;i++){let a=e[i];if(a==="{"){o++;continue}if(a==="}"&&(o--,o===0))return e.slice(r+1,i)}return null}function qn(e,t){return e.match(new RegExp(`uniform\\s+${t}\\s*\\{([\\s\\S]*?)\\}\\s*[A-Za-z0-9_]+\\s*;`,"m"))?.[1]||null}function Kn(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function Yn(e){return`${e.moduleName}: ${e.stage} shader uniform block ${e.uniformBlockName} does not match module.uniformTypes.
|
|
35
|
+
Expected: ${e.expectedUniformNames.join(", ")}
|
|
36
|
+
Actual: ${e.actualUniformNames.join(", ")}`}function pt(e){switch(e?.gpu.toLowerCase()){case"apple":return`#define APPLE_GPU
|
|
34
37
|
// Apple optimizes away the calculation necessary for emulated fp64
|
|
35
38
|
#define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1
|
|
36
39
|
#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1
|
|
@@ -54,55 +57,58 @@ ${n[i]}`:n[i]}),t}function T(e){e.map(t=>re(t))}function re(e){if(e.instance)ret
|
|
|
54
57
|
#define LUMA_FP32_TAN_PRECISION_WORKAROUND 1
|
|
55
58
|
// If the GPU doesn't have full 32 bits precision, will causes overflow
|
|
56
59
|
#define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1
|
|
57
|
-
`}}function
|
|
58
|
-
`],[/\btexture(2D|2DProj|Cube)Lod(EXT)?\(/g,"textureLod("],[/\btexture(2D|2DProj|Cube)(EXT)?\(/g,"texture("]],
|
|
59
|
-
`,
|
|
60
|
-
`}
|
|
61
|
-
`}return n}function
|
|
62
|
-
|
|
63
|
-
${
|
|
64
|
-
`,
|
|
65
|
-
`;function
|
|
60
|
+
`}}function ut(e,t){if(Number(e.match(/^#version[ \t]+(\d+)/m)?.[1]||100)!==300)throw new Error("luma.gl v9 only supports GLSL 3.00 shader sources");switch(t){case"vertex":return e=ht(e,Xn),e;case"fragment":return e=ht(e,Zn),e;default:throw new Error(t)}}var gt=[[/^(#version[ \t]+(100|300[ \t]+es))?[ \t]*\n/,`#version 300 es
|
|
61
|
+
`],[/\btexture(2D|2DProj|Cube)Lod(EXT)?\(/g,"textureLod("],[/\btexture(2D|2DProj|Cube)(EXT)?\(/g,"texture("]],Xn=[...gt,[Oe("attribute"),"in $1"],[Oe("varying"),"out $1"]],Zn=[...gt,[Oe("varying"),"in $1"]];function ht(e,t){for(let[n,r]of t)e=e.replace(n,r);return e}function Oe(e){return new RegExp(`\\b${e}[ \\t]+(\\w+[ \\t]+\\w+(\\[\\w+\\])?;)`,"g")}function Te(e,t){let n="";for(let r in e){let o=e[r];if(n+=`void ${o.signature} {
|
|
62
|
+
`,o.header&&(n+=` ${o.header}`),t[r]){let i=t[r];i.sort((a,s)=>a.order-s.order);for(let a of i)n+=` ${a.injection}
|
|
63
|
+
`}o.footer&&(n+=` ${o.footer}`),n+=`}
|
|
64
|
+
`}return n}function Fe(e){let t={vertex:{},fragment:{}};for(let n of e){let r,o;typeof n!="string"?(r=n,o=r.hook):(r={},o=n),o=o.trim();let[i,a]=o.split(":"),s=o.replace(/\(.+/,""),c=Object.assign(r,{signature:a});switch(i){case"vs":t.vertex[s]=c;break;case"fs":t.fragment[s]=c;break;default:throw new Error(i)}}return t}function ce(e,t){return{name:Jn(e,t),language:"glsl",version:Qn(e)}}function Jn(e,t="unnamed"){let r=/#define[^\S\r\n]*SHADER_NAME[^\S\r\n]*([A-Za-z0-9_-]+)\s*/.exec(e);return r?r[1]:t}function Qn(e){let t=100,n=e.match(/[^\s]+/g);if(n&&n.length>=2&&n[0]==="#version"){let r=parseInt(n[1],10);Number.isFinite(r)&&(t=r)}if(t!==100&&t!==300)throw new Error(`Invalid GLSL version ${t}`);return t}var mt=[/@binding\(\s*(\d+)\s*\)\s*@group\(\s*(\d+)\s*\)\s*var(?:<([^>]+)>)?\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*([^;]+);/g,/@group\(\s*(\d+)\s*\)\s*@binding\(\s*(\d+)\s*\)\s*var(?:<([^>]+)>)?\s+([A-Za-z_][A-Za-z0-9_]*)\s*:\s*([^;]+);/g];function le(e,t=[]){let n=new Map;for(let o of t)n.set(dt(o.name,o.group,o.location),o.moduleName);let r=[];for(let o of mt){o.lastIndex=0;let i;for(;i=o.exec(e);){let a=o===mt[0],s=Number(i[a?1:2]),c=Number(i[a?2:1]),l=i[3]?.trim(),p=i[4],f=i[5].trim(),h=n.get(dt(p,c,s));r.push(er({name:p,group:c,binding:s,owner:h?"module":"application",moduleName:h,accessDeclaration:l,resourceType:f}))}}return r.sort((o,i)=>o.group!==i.group?o.group-i.group:o.binding!==i.binding?o.binding-i.binding:o.name.localeCompare(i.name))}function er(e){let t={name:e.name,group:e.group,binding:e.binding,owner:e.owner,kind:"unknown",moduleName:e.moduleName,resourceType:e.resourceType};if(e.accessDeclaration){let n=e.accessDeclaration.split(",").map(r=>r.trim());if(n[0]==="uniform")return{...t,kind:"uniform",access:"uniform"};if(n[0]==="storage"){let r=n[1]||"read_write";return{...t,kind:r==="read"?"read-only-storage":"storage",access:r}}}return e.resourceType==="sampler"||e.resourceType==="sampler_comparison"?{...t,kind:"sampler",samplerKind:e.resourceType==="sampler_comparison"?"comparison":"filtering"}:e.resourceType.startsWith("texture_storage_")?{...t,kind:"storage-texture",access:nr(e.resourceType),viewDimension:_t(e.resourceType)}:e.resourceType.startsWith("texture_")?{...t,kind:"texture",viewDimension:_t(e.resourceType),sampleType:tr(e.resourceType),multisampled:e.resourceType.startsWith("texture_multisampled_")}:t}function dt(e,t,n){return`${t}:${n}:${e}`}function _t(e){if(e.includes("cube_array"))return"cube-array";if(e.includes("2d_array"))return"2d-array";if(e.includes("cube"))return"cube";if(e.includes("3d"))return"3d";if(e.includes("2d"))return"2d";if(e.includes("1d"))return"1d"}function tr(e){if(e.startsWith("texture_depth_"))return"depth";if(e.includes("<i32>"))return"sint";if(e.includes("<u32>"))return"uint";if(e.includes("<f32>"))return"float"}function nr(e){return/,\s*([A-Za-z_][A-Za-z0-9_]*)\s*>$/.exec(e)?.[1]}var Lt=`
|
|
65
|
+
|
|
66
|
+
${$}
|
|
67
|
+
`,fe=[/@binding\(\s*(auto|\d+)\s*\)\s*@group\(\s*(\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g,/@group\(\s*(\d+)\s*\)\s*@binding\(\s*(auto|\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g],bt=[/@binding\(\s*(\d+)\s*\)\s*@group\(\s*(\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g,/@group\(\s*(\d+)\s*\)\s*@binding\(\s*(\d+)\s*\)\s*(var(?:<[^>]+>)?\s+([A-Za-z_][A-Za-z0-9_]*))/g],Z=100,rr=`precision highp float;
|
|
68
|
+
`;function At(e){let t=Y(e.modules||[]),{source:n,bindingAssignments:r}=or(e.platformInfo,{...e,source:e.source,stage:"vertex",modules:t});return{source:n,getUniforms:Et(t),bindingAssignments:r,bindingTable:le(n,r)}}function he(e){let{vs:t,fs:n}=e,r=Y(e.modules||[]);return{vs:vt(e.platformInfo,{...e,source:t,stage:"vertex",modules:r}),fs:vt(e.platformInfo,{...e,source:n,stage:"fragment",modules:r}),getUniforms:Et(r)}}function or(e,t){let{source:n,stage:r,modules:o,hookFunctions:i=[],inject:a={},log:s}=t;O(typeof n=="string","shader source must be a string");let c=n,l="",p=Fe(i),f={},h={},g={};for(let M in a){let b=typeof a[M]=="string"?{injection:a[M],order:0}:a[M],S=/^(v|f)s:(#)?([\w-]+)$/.exec(M);if(S){let v=S[2],u=S[3];v?u==="decl"?h[M]=[b]:g[M]=[b]:f[M]=[b]}else g[M]=[b]}let _=o,m=ar(c),x=lr(_,t._bindingRegistry,m),d=[];for(let M of _){s&&K(M,c,s);let b=sr(ue(M,"wgsl",s),M,{usedBindingsByGroup:m,bindingRegistry:t._bindingRegistry,reservedBindingKeysByGroup:x});d.push(...b.bindingAssignments);let S=b.source;l+=S;let v=M.injections?.[r]||{};for(let u in v){let E=/^(v|f)s:#([\w-]+)$/.exec(u);if(E){let L=E[2]==="decl"?h:g;L[u]=L[u]||[],L[u].push(v[u])}else f[u]=f[u]||[],f[u].push(v[u])}}return l+=Lt,l=q(l,r,h),l+=Te(p[r],f),l+=gr(d),l+=c,l=q(l,r,g),ur(l),{source:l,bindingAssignments:d}}function vt(e,t){let{source:n,stage:r,language:o="glsl",modules:i,defines:a={},hookFunctions:s=[],inject:c={},prologue:l=!0,log:p}=t;O(typeof n=="string","shader source must be a string");let f=o==="glsl"?ce(n).version:-1,h=e.shaderLanguageVersion,g=f===100?"#version 100":"#version 300 es",m=n.split(`
|
|
66
69
|
`).slice(1).join(`
|
|
67
|
-
`),
|
|
70
|
+
`),x={};i.forEach(u=>{Object.assign(x,u.defines)}),Object.assign(x,a);let d="";switch(o){case"wgsl":break;case"glsl":d=l?`${g}
|
|
68
71
|
|
|
69
72
|
// ----- PROLOGUE -------------------------
|
|
70
|
-
${`#define SHADER_TYPE_${
|
|
73
|
+
${`#define SHADER_TYPE_${r.toUpperCase()}`}
|
|
71
74
|
|
|
72
|
-
${
|
|
73
|
-
${
|
|
75
|
+
${pt(e)}
|
|
76
|
+
${r==="fragment"?rr:""}
|
|
74
77
|
|
|
75
78
|
// ----- APPLICATION DEFINES -------------------------
|
|
76
79
|
|
|
77
|
-
${
|
|
80
|
+
${ir(x)}
|
|
78
81
|
|
|
79
|
-
`:`${
|
|
80
|
-
`;break}let
|
|
81
|
-
`)}return t}function
|
|
82
|
+
`:`${g}
|
|
83
|
+
`;break}let M=Fe(s),b={},S={},v={};for(let u in c){let E=typeof c[u]=="string"?{injection:c[u],order:0}:c[u],R=/^(v|f)s:(#)?([\w-]+)$/.exec(u);if(R){let L=R[2],I=R[3];L?I==="decl"?S[u]=[E]:v[u]=[E]:b[u]=[E]}else v[u]=[E]}for(let u of i){p&&K(u,m,p);let E=ue(u,r,p);d+=E;let R=u.instance?.normalizedInjections[r]||{};for(let L in R){let I=/^(v|f)s:#([\w-]+)$/.exec(L);if(I){let C=I[2]==="decl"?S:v;C[L]=C[L]||[],C[L].push(R[L])}else b[L]=b[L]||[],b[L].push(R[L])}}return d+="// ----- MAIN SHADER SOURCE -------------------------",d+=Lt,d=q(d,r,S),d+=Te(M[r],b),d+=m,d=q(d,r,v),o==="glsl"&&f!==h&&(d=ut(d,r)),d.trim()}function Et(e){return function(n){let r={};for(let o of e){let i=o.getUniforms?.(n,r);Object.assign(r,i)}return r}}function ir(e={}){let t="";for(let n in e){let r=e[n];(r||Number.isFinite(r))&&(t+=`#define ${n.toUpperCase()} ${e[n]}
|
|
84
|
+
`)}return t}function ue(e,t,n){let r;switch(t){case"vertex":r=e.vs||"";break;case"fragment":r=e.fs||"";break;case"wgsl":r=e.source||"";break;default:O(!1)}if(!e.name)throw new Error("Shader module must have a name");se(e,t,{log:n});let o=e.name.toUpperCase().replace(/[^0-9a-z]/gi,"_"),i=`// ----- MODULE ${e.name} ---------------
|
|
82
85
|
|
|
83
|
-
`;return t!=="wgsl"&&(
|
|
84
|
-
`),
|
|
85
|
-
`,
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
`;return t!=="wgsl"&&(i+=`#define MODULE_${o}
|
|
87
|
+
`),i+=`${r}
|
|
88
|
+
`,i}function ar(e){let t=new Map;for(let n of bt){n.lastIndex=0;let r;for(;r=n.exec(e);){let o=n===bt[0],i=Number(r[o?1:2]),a=Number(r[o?2:1]),s=r[4];hr(a,i,s),pe(t,a,i,`application binding "${s}"`)}}return t}function sr(e,t,n){let r=[],o={sawSupportedBindingDeclaration:!1,nextHintedBindingLocation:typeof t.firstBindingSlot=="number"?t.firstBindingSlot:null},i=St(e,fe[0],{isBindingFirst:!0,module:t,context:n,bindingAssignments:r,relocationState:o});if(i=St(i,fe[1],{isBindingFirst:!1,module:t,context:n,bindingAssignments:r,relocationState:o}),e.includes("@binding(auto)")&&!o.sawSupportedBindingDeclaration)throw new Error(`Unsupported @binding(auto) declaration form in module "${t.name}". Use "@group(N) @binding(auto) var ..." or "@binding(auto) @group(N) var ..." on a single line.`);return{source:i,bindingAssignments:r}}function St(e,t,n){return e.replace(t,(...r)=>cr(r,n))}function cr(e,t){let{isBindingFirst:n,module:r,context:o,bindingAssignments:i,relocationState:a}=t;a.sawSupportedBindingDeclaration=!0;let s=e[0],c=e[n?1:2],l=e[n?2:1],p=e[4],f=Number(l);if(c==="auto"){let g=Rt(f,r.name,p),_=o.bindingRegistry?.get(g),m=_!==void 0?_:a.nextHintedBindingLocation===null?Mt(f,o.usedBindingsByGroup):Mt(f,o.usedBindingsByGroup,a.nextHintedBindingLocation);return xt(r.name,f,m,p),_!==void 0&&fr(o.reservedBindingKeysByGroup,f,m,g)?(i.push({moduleName:r.name,name:p,group:f,location:m}),s.replace(/@binding\(\s*auto\s*\)/,`@binding(${m})`)):(pe(o.usedBindingsByGroup,f,m,`module "${r.name}" binding "${p}"`),o.bindingRegistry?.set(g,m),i.push({moduleName:r.name,name:p,group:f,location:m}),a.nextHintedBindingLocation!==null&&_===void 0&&(a.nextHintedBindingLocation=m+1),s.replace(/@binding\(\s*auto\s*\)/,`@binding(${m})`))}let h=Number(c);return xt(r.name,f,h,p),pe(o.usedBindingsByGroup,f,h,`module "${r.name}" binding "${p}"`),i.push({moduleName:r.name,name:p,group:f,location:h}),s}function lr(e,t,n){let r=new Map;if(!t)return r;for(let o of e)for(let i of pr(o)){let a=Rt(i.group,o.name,i.name),s=t.get(a);if(s!==void 0){let c=r.get(i.group)||new Map,l=c.get(s);if(l&&l!==a)throw new Error(`Duplicate WGSL binding reservation for modules "${l}" and "${a}": group ${i.group}, binding ${s}.`);pe(n,i.group,s,`registered module binding "${a}"`),c.set(s,a),r.set(i.group,c)}}return r}function fr(e,t,n,r){let o=e.get(t);if(!o)return!1;let i=o.get(n);if(!i)return!1;if(i!==r)throw new Error(`Registered module binding "${r}" collided with "${i}": group ${t}, binding ${n}.`);return!0}function pr(e){let t=[],n=e.source||"";for(let r of fe){r.lastIndex=0;let o;for(;o=r.exec(n);){let i=r===fe[0];t.push({name:o[4],group:Number(o[i?2:1])})}}return t}function hr(e,t,n){if(e===0&&t>=Z)throw new Error(`Application binding "${n}" in group 0 uses reserved binding ${t}. Application-owned explicit group-0 bindings must stay below ${Z}.`)}function xt(e,t,n,r){if(t===0&&n<Z)throw new Error(`Module "${e}" binding "${r}" in group 0 uses reserved application binding ${n}. Module-owned explicit group-0 bindings must be ${Z} or higher.`)}function pe(e,t,n,r){let o=e.get(t)||new Set;if(o.has(n))throw new Error(`Duplicate WGSL binding assignment for ${r}: group ${t}, binding ${n}.`);o.add(n),e.set(t,o)}function Mt(e,t,n){let r=t.get(e)||new Set,o=n??(e===0?Z:r.size>0?Math.max(...r)+1:0);for(;r.has(o);)o++;return o}function ur(e){if(/@binding\(\s*auto\s*\)/.test(e))throw new Error("Unresolved @binding(auto) remained in assembled WGSL source.")}function gr(e){if(e.length===0)return"";let t=`// ----- MODULE WGSL BINDING ASSIGNMENTS ---------------
|
|
89
|
+
`;for(let n of e)t+=`// ${n.moduleName}.${n.name} -> @group(${n.group}) @binding(${n.location})
|
|
90
|
+
`;return t+=`
|
|
91
|
+
`,t}function Rt(e,t,n){return`${e}:${t}:${n}`}var we="([a-zA-Z_][a-zA-Z0-9_]*)",mr=new RegExp(`^\\s*\\#\\s*ifdef\\s*${we}\\s*$`),dr=new RegExp(`^\\s*\\#\\s*ifndef\\s*${we}\\s*(?:\\/\\/.*)?$`),_r=/^\s*\#\s*else\s*(?:\/\/.*)?$/,br=/^\s*\#\s*endif\s*$/,vr=new RegExp(`^\\s*\\#\\s*ifdef\\s*${we}\\s*(?:\\/\\/.*)?$`),Sr=/^\s*\#\s*endif\s*(?:\/\/.*)?$/;function ge(e,t){let n=e.split(`
|
|
92
|
+
`),r=[],o=[],i=!0;for(let a of n){let s=a.match(vr)||a.match(mr),c=a.match(dr),l=a.match(_r),p=a.match(Sr)||a.match(br);if(s||c){let f=(s||c)?.[1],h=Boolean(t?.defines?.[f]),g=s?h:!h,_=i&&g;o.push({parentActive:i,branchTaken:g,active:_}),i=_}else if(l){let f=o[o.length-1];if(!f)throw new Error("Encountered #else without matching #ifdef or #ifndef");f.active=f.parentActive&&!f.branchTaken,f.branchTaken=!0,i=f.active}else p?(o.pop(),i=o.length?o[o.length-1].active:!0):i&&r.push(a)}if(o.length>0)throw new Error("Unterminated conditional block in shader source");return r.join(`
|
|
93
|
+
`)}var z=class{_hookFunctions=[];_defaultModules=[];_wgslBindingRegistry=new Map;static getDefaultShaderAssembler(){return z.defaultShaderAssembler=z.defaultShaderAssembler||new z,z.defaultShaderAssembler}addDefaultModule(t){this._defaultModules.find(n=>n.name===(typeof t=="string"?t:t.name))||this._defaultModules.push(t)}removeDefaultModule(t){let n=typeof t=="string"?t:t.name;this._defaultModules=this._defaultModules.filter(r=>r.name!==n)}addShaderHook(t,n){n&&(t=Object.assign(n,{hook:t})),this._hookFunctions.push(t)}assembleWGSLShader(t){let n=this._getModuleList(t.modules),r=this._hookFunctions,{source:o,getUniforms:i,bindingAssignments:a}=At({...t,source:t.source,_bindingRegistry:this._wgslBindingRegistry,modules:n,hookFunctions:r}),s={...n.reduce((l,p)=>(Object.assign(l,p.defines),l),{}),...t.defines},c=t.platformInfo.shaderLanguage==="wgsl"?ge(o,{defines:s}):o;return{source:c,getUniforms:i,modules:n,bindingAssignments:a,bindingTable:le(c,a)}}assembleGLSLShaderPair(t){let n=this._getModuleList(t.modules),r=this._hookFunctions;return{...he({...t,vs:t.vs,fs:t.fs,modules:n,hookFunctions:r}),modules:n}}_getModuleList(t=[]){let n=new Array(this._defaultModules.length+t.length),r={},o=0;for(let i=0,a=this._defaultModules.length;i<a;++i){let s=this._defaultModules[i],c=s.name;n[o++]=s,r[c]=!0}for(let i=0,a=t.length;i<a;++i){let s=t[i],c=s.name;r[c]||(n[o++]=s,r[c]=!0)}return n.length=o,T(n),n}},J=z;Je(J,"defaultShaderAssembler");var xr=`out vec4 transform_output;
|
|
88
94
|
void main() {
|
|
89
95
|
transform_output = vec4(0);
|
|
90
|
-
}`,
|
|
91
|
-
${
|
|
92
|
-
in ${
|
|
93
|
-
out vec4 ${
|
|
96
|
+
}`,Mr=`#version 300 es
|
|
97
|
+
${xr}`;function It(e,t){t=Array.isArray(t)?t:[t];let n=e.replace(/^\s+/,"").split(/\s+/),[r,o,i]=n;if(!t.includes(r)||!o||!i)return null;let a=i.split(";")[0];return{qualifier:r,type:o,name:a}}function Ct(e){let{input:t,inputChannels:n,output:r}=e||{};if(!t)return Mr;if(!n)throw new Error("inputChannels");let o=Lr(n),i=Be(t,n);return`#version 300 es
|
|
98
|
+
in ${o} ${t};
|
|
99
|
+
out vec4 ${r};
|
|
94
100
|
void main() {
|
|
95
|
-
${
|
|
96
|
-
}`}function
|
|
97
|
-
`)}function
|
|
98
|
-
`)}function gt(e,t){switch(t.shaderLanguage){case"glsl":return pt(e,t);case"wgsl":return ht(e,t)}}var lr=1/Math.PI*180,fr=1/180*Math.PI,Un={EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1};globalThis.mathgl=globalThis.mathgl||{config:{...Un}};var C=globalThis.mathgl.config;function Ie(e,{precision:t=C.precision}={}){return e=Bn(e),`${parseFloat(e.toPrecision(t))}`}function z(e){return Array.isArray(e)||ArrayBuffer.isView(e)&&!(e instanceof DataView)}function Pe(e,t,n){return Hn(e,i=>Math.max(t,Math.min(n,i)))}function le(e,t,n){let i=C.EPSILON;n&&(C.EPSILON=n);try{if(e===t)return!0;if(z(e)&&z(t)){if(e.length!==t.length)return!1;for(let r=0;r<e.length;++r)if(!le(e[r],t[r]))return!1;return!0}return e&&e.equals?e.equals(t):t&&t.equals?t.equals(e):typeof e=="number"&&typeof t=="number"?Math.abs(e-t)<=C.EPSILON*Math.max(1,Math.abs(e),Math.abs(t)):!1}finally{C.EPSILON=i}}function Bn(e){return Math.round(e/C.EPSILON)*C.EPSILON}function zn(e){return e.clone?e.clone():new Array(e.length)}function Hn(e,t,n){if(z(e)){let i=e;n=n||zn(i);for(let r=0;r<n.length&&r<i.length;++r){let o=typeof e=="number"?e:e[r];n[r]=t(o,r,n)}return n}return t(e)}var fe=class extends Array{clone(){return new this.constructor().copy(this)}fromArray(t,n=0){for(let i=0;i<this.ELEMENTS;++i)this[i]=t[i+n];return this.check()}toArray(t=[],n=0){for(let i=0;i<this.ELEMENTS;++i)t[n+i]=this[i];return t}toObject(t){return t}from(t){return Array.isArray(t)?this.copy(t):this.fromObject(t)}to(t){return t===this?this:z(t)?this.toArray(t):this.toObject(t)}toTarget(t){return t?this.to(t):this}toFloat32Array(){return new Float32Array(this)}toString(){return this.formatString(C)}formatString(t){let n="";for(let i=0;i<this.ELEMENTS;++i)n+=(i>0?", ":"")+Ie(this[i],t);return`${t.printTypes?this.constructor.name:""}[${n}]`}equals(t){if(!t||this.length!==t.length)return!1;for(let n=0;n<this.ELEMENTS;++n)if(!le(this[n],t[n]))return!1;return!0}exactEquals(t){if(!t||this.length!==t.length)return!1;for(let n=0;n<this.ELEMENTS;++n)if(this[n]!==t[n])return!1;return!0}negate(){for(let t=0;t<this.ELEMENTS;++t)this[t]=-this[t];return this.check()}lerp(t,n,i){if(i===void 0)return this.lerp(this,t,n);for(let r=0;r<this.ELEMENTS;++r){let o=t[r],s=typeof n=="number"?n:n[r];this[r]=o+i*(s-o)}return this.check()}min(t){for(let n=0;n<this.ELEMENTS;++n)this[n]=Math.min(t[n],this[n]);return this.check()}max(t){for(let n=0;n<this.ELEMENTS;++n)this[n]=Math.max(t[n],this[n]);return this.check()}clamp(t,n){for(let i=0;i<this.ELEMENTS;++i)this[i]=Math.min(Math.max(this[i],t[i]),n[i]);return this.check()}add(...t){for(let n of t)for(let i=0;i<this.ELEMENTS;++i)this[i]+=n[i];return this.check()}subtract(...t){for(let n of t)for(let i=0;i<this.ELEMENTS;++i)this[i]-=n[i];return this.check()}scale(t){if(typeof t=="number")for(let n=0;n<this.ELEMENTS;++n)this[n]*=t;else for(let n=0;n<this.ELEMENTS&&n<t.length;++n)this[n]*=t[n];return this.check()}multiplyByScalar(t){for(let n=0;n<this.ELEMENTS;++n)this[n]*=t;return this.check()}check(){if(C.debug&&!this.validate())throw new Error(`math.gl: ${this.constructor.name} some fields set to invalid numbers'`);return this}validate(){let t=this.length===this.ELEMENTS;for(let n=0;n<this.ELEMENTS;++n)t=t&&Number.isFinite(this[n]);return t}sub(t){return this.subtract(t)}setScalar(t){for(let n=0;n<this.ELEMENTS;++n)this[n]=t;return this.check()}addScalar(t){for(let n=0;n<this.ELEMENTS;++n)this[n]+=t;return this.check()}subScalar(t){return this.addScalar(-t)}multiplyScalar(t){for(let n=0;n<this.ELEMENTS;++n)this[n]*=t;return this.check()}divideScalar(t){return this.multiplyByScalar(1/t)}clampScalar(t,n){for(let i=0;i<this.ELEMENTS;++i)this[i]=Math.min(Math.max(this[i],t),n);return this.check()}get elements(){return this}};function Gn(e,t){if(e.length!==t)return!1;for(let n=0;n<e.length;++n)if(!Number.isFinite(e[n]))return!1;return!0}function mt(e){if(!Number.isFinite(e))throw new Error(`Invalid number ${JSON.stringify(e)}`);return e}function pe(e,t,n=""){if(C.debug&&!Gn(e,t))throw new Error(`math.gl: ${n} some fields set to invalid numbers'`);return e}var w=typeof Float32Array<"u"?Float32Array:Array;var ur=Math.PI/180;function Vn(){let e=new w(2);return w!=Float32Array&&(e[0]=0,e[1]=0),e}function dt(e,t,n){let i=t[0],r=t[1];return e[0]=n[0]*i+n[4]*r+n[12],e[1]=n[1]*i+n[5]*r+n[13],e}var dr=function(){let e=Vn();return function(t,n,i,r,o,s){let c,a;for(n||(n=2),i||(i=0),r?a=Math.min(r*n+i,t.length):a=t.length,c=i;c<a;c+=n)e[0]=t[c],e[1]=t[c+1],o(e,e,s),t[c]=e[0],t[c+1]=e[1];return t}}();function vt(e,t,n){let i=t[0],r=t[1],o=n[3]*i+n[7]*r||1;return e[0]=(n[0]*i+n[4]*r)/o,e[1]=(n[1]*i+n[5]*r)/o,e}function xt(e,t,n){let i=t[0],r=t[1],o=t[2],s=n[3]*i+n[7]*r+n[11]*o||1;return e[0]=(n[0]*i+n[4]*r+n[8]*o)/s,e[1]=(n[1]*i+n[5]*r+n[9]*o)/s,e[2]=(n[2]*i+n[6]*r+n[10]*o)/s,e}function jn(){let e=new w(3);return w!=Float32Array&&(e[0]=0,e[1]=0,e[2]=0),e}function bt(e,t,n){let i=t[0],r=t[1],o=t[2],s=n[3]*i+n[7]*r+n[11]*o+n[15];return s=s||1,e[0]=(n[0]*i+n[4]*r+n[8]*o+n[12])/s,e[1]=(n[1]*i+n[5]*r+n[9]*o+n[13])/s,e[2]=(n[2]*i+n[6]*r+n[10]*o+n[14])/s,e}var br=function(){let e=jn();return function(t,n,i,r,o,s){let c,a;for(n||(n=3),i||(i=0),r?a=Math.min(r*n+i,t.length):a=t.length,c=i;c<a;c+=n)e[0]=t[c],e[1]=t[c+1],e[2]=t[c+2],o(e,e,s),t[c]=e[0],t[c+1]=e[1],t[c+2]=e[2];return t}}();var he=class extends fe{toString(){let t="[";if(C.printRowMajor){t+="row-major:";for(let n=0;n<this.RANK;++n)for(let i=0;i<this.RANK;++i)t+=` ${this[i*this.RANK+n]}`}else{t+="column-major:";for(let n=0;n<this.ELEMENTS;++n)t+=` ${this[n]}`}return t+="]",t}getElementIndex(t,n){return n*this.RANK+t}getElement(t,n){return this[n*this.RANK+t]}setElement(t,n,i){return this[n*this.RANK+t]=mt(i),this}getColumn(t,n=new Array(this.RANK).fill(-0)){let i=t*this.RANK;for(let r=0;r<this.RANK;++r)n[r]=this[i+r];return n}setColumn(t,n){let i=t*this.RANK;for(let r=0;r<this.RANK;++r)this[i+r]=n[r];return this}};function qn(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e}function Mt(e,t){if(e===t){let n=t[1],i=t[2],r=t[3],o=t[6],s=t[7],c=t[11];e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[6]=t[9],e[7]=t[13],e[8]=i,e[9]=o,e[11]=t[14],e[12]=r,e[13]=s,e[14]=c}else e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15];return e}function At(e,t){let n=t[0],i=t[1],r=t[2],o=t[3],s=t[4],c=t[5],a=t[6],l=t[7],h=t[8],f=t[9],p=t[10],m=t[11],x=t[12],_=t[13],d=t[14],g=t[15],A=n*c-i*s,v=n*a-r*s,M=n*l-o*s,b=i*a-r*c,u=i*l-o*c,I=r*l-o*a,E=h*_-f*x,L=h*d-p*x,P=h*g-m*x,O=f*d-p*_,R=f*g-m*_,N=p*g-m*d,S=A*N-v*R+M*O+b*P-u*L+I*E;return S?(S=1/S,e[0]=(c*N-a*R+l*O)*S,e[1]=(r*R-i*N-o*O)*S,e[2]=(_*I-d*u+g*b)*S,e[3]=(p*u-f*I-m*b)*S,e[4]=(a*P-s*N-l*L)*S,e[5]=(n*N-r*P+o*L)*S,e[6]=(d*M-x*I-g*v)*S,e[7]=(h*I-p*M+m*v)*S,e[8]=(s*R-c*P+l*E)*S,e[9]=(i*P-n*R-o*E)*S,e[10]=(x*u-_*M+g*A)*S,e[11]=(f*M-h*u-m*A)*S,e[12]=(c*L-s*O-a*E)*S,e[13]=(n*O-i*L+r*E)*S,e[14]=(_*v-x*b-d*A)*S,e[15]=(h*b-f*v+p*A)*S,e):null}function Lt(e){let t=e[0],n=e[1],i=e[2],r=e[3],o=e[4],s=e[5],c=e[6],a=e[7],l=e[8],h=e[9],f=e[10],p=e[11],m=e[12],x=e[13],_=e[14],d=e[15],g=t*s-n*o,A=t*c-i*o,v=n*c-i*s,M=l*x-h*m,b=l*_-f*m,u=h*_-f*x,I=t*u-n*b+i*M,E=o*u-s*b+c*M,L=l*v-h*A+f*g,P=m*v-x*A+_*g;return a*I-r*E+d*L-p*P}function Ce(e,t,n){let i=t[0],r=t[1],o=t[2],s=t[3],c=t[4],a=t[5],l=t[6],h=t[7],f=t[8],p=t[9],m=t[10],x=t[11],_=t[12],d=t[13],g=t[14],A=t[15],v=n[0],M=n[1],b=n[2],u=n[3];return e[0]=v*i+M*c+b*f+u*_,e[1]=v*r+M*a+b*p+u*d,e[2]=v*o+M*l+b*m+u*g,e[3]=v*s+M*h+b*x+u*A,v=n[4],M=n[5],b=n[6],u=n[7],e[4]=v*i+M*c+b*f+u*_,e[5]=v*r+M*a+b*p+u*d,e[6]=v*o+M*l+b*m+u*g,e[7]=v*s+M*h+b*x+u*A,v=n[8],M=n[9],b=n[10],u=n[11],e[8]=v*i+M*c+b*f+u*_,e[9]=v*r+M*a+b*p+u*d,e[10]=v*o+M*l+b*m+u*g,e[11]=v*s+M*h+b*x+u*A,v=n[12],M=n[13],b=n[14],u=n[15],e[12]=v*i+M*c+b*f+u*_,e[13]=v*r+M*a+b*p+u*d,e[14]=v*o+M*l+b*m+u*g,e[15]=v*s+M*h+b*x+u*A,e}function St(e,t,n){let i=n[0],r=n[1],o=n[2],s,c,a,l,h,f,p,m,x,_,d,g;return t===e?(e[12]=t[0]*i+t[4]*r+t[8]*o+t[12],e[13]=t[1]*i+t[5]*r+t[9]*o+t[13],e[14]=t[2]*i+t[6]*r+t[10]*o+t[14],e[15]=t[3]*i+t[7]*r+t[11]*o+t[15]):(s=t[0],c=t[1],a=t[2],l=t[3],h=t[4],f=t[5],p=t[6],m=t[7],x=t[8],_=t[9],d=t[10],g=t[11],e[0]=s,e[1]=c,e[2]=a,e[3]=l,e[4]=h,e[5]=f,e[6]=p,e[7]=m,e[8]=x,e[9]=_,e[10]=d,e[11]=g,e[12]=s*i+h*r+x*o+t[12],e[13]=c*i+f*r+_*o+t[13],e[14]=a*i+p*r+d*o+t[14],e[15]=l*i+m*r+g*o+t[15]),e}function Et(e,t,n){let i=n[0],r=n[1],o=n[2];return e[0]=t[0]*i,e[1]=t[1]*i,e[2]=t[2]*i,e[3]=t[3]*i,e[4]=t[4]*r,e[5]=t[5]*r,e[6]=t[6]*r,e[7]=t[7]*r,e[8]=t[8]*o,e[9]=t[9]*o,e[10]=t[10]*o,e[11]=t[11]*o,e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e}function It(e,t,n,i){let r=i[0],o=i[1],s=i[2],c=Math.sqrt(r*r+o*o+s*s),a,l,h,f,p,m,x,_,d,g,A,v,M,b,u,I,E,L,P,O,R,N,S,V;return c<1e-6?null:(c=1/c,r*=c,o*=c,s*=c,l=Math.sin(n),a=Math.cos(n),h=1-a,f=t[0],p=t[1],m=t[2],x=t[3],_=t[4],d=t[5],g=t[6],A=t[7],v=t[8],M=t[9],b=t[10],u=t[11],I=r*r*h+a,E=o*r*h+s*l,L=s*r*h-o*l,P=r*o*h-s*l,O=o*o*h+a,R=s*o*h+r*l,N=r*s*h+o*l,S=o*s*h-r*l,V=s*s*h+a,e[0]=f*I+_*E+v*L,e[1]=p*I+d*E+M*L,e[2]=m*I+g*E+b*L,e[3]=x*I+A*E+u*L,e[4]=f*P+_*O+v*R,e[5]=p*P+d*O+M*R,e[6]=m*P+g*O+b*R,e[7]=x*P+A*O+u*R,e[8]=f*N+_*S+v*V,e[9]=p*N+d*S+M*V,e[10]=m*N+g*S+b*V,e[11]=x*N+A*S+u*V,t!==e&&(e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]),e)}function Pt(e,t,n){let i=Math.sin(n),r=Math.cos(n),o=t[4],s=t[5],c=t[6],a=t[7],l=t[8],h=t[9],f=t[10],p=t[11];return t!==e&&(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]),e[4]=o*r+l*i,e[5]=s*r+h*i,e[6]=c*r+f*i,e[7]=a*r+p*i,e[8]=l*r-o*i,e[9]=h*r-s*i,e[10]=f*r-c*i,e[11]=p*r-a*i,e}function Rt(e,t,n){let i=Math.sin(n),r=Math.cos(n),o=t[0],s=t[1],c=t[2],a=t[3],l=t[8],h=t[9],f=t[10],p=t[11];return t!==e&&(e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]),e[0]=o*r-l*i,e[1]=s*r-h*i,e[2]=c*r-f*i,e[3]=a*r-p*i,e[8]=o*i+l*r,e[9]=s*i+h*r,e[10]=c*i+f*r,e[11]=a*i+p*r,e}function Ct(e,t,n){let i=Math.sin(n),r=Math.cos(n),o=t[0],s=t[1],c=t[2],a=t[3],l=t[4],h=t[5],f=t[6],p=t[7];return t!==e&&(e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]),e[0]=o*r+l*i,e[1]=s*r+h*i,e[2]=c*r+f*i,e[3]=a*r+p*i,e[4]=l*r-o*i,e[5]=h*r-s*i,e[6]=f*r-c*i,e[7]=p*r-a*i,e}function Ot(e,t){let n=t[0],i=t[1],r=t[2],o=t[3],s=n+n,c=i+i,a=r+r,l=n*s,h=i*s,f=i*c,p=r*s,m=r*c,x=r*a,_=o*s,d=o*c,g=o*a;return e[0]=1-f-x,e[1]=h+g,e[2]=p-d,e[3]=0,e[4]=h-g,e[5]=1-l-x,e[6]=m+_,e[7]=0,e[8]=p+d,e[9]=m-_,e[10]=1-l-f,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e}function Nt(e,t,n,i,r,o,s){let c=1/(n-t),a=1/(r-i),l=1/(o-s);return e[0]=o*2*c,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=o*2*a,e[6]=0,e[7]=0,e[8]=(n+t)*c,e[9]=(r+i)*a,e[10]=(s+o)*l,e[11]=-1,e[12]=0,e[13]=0,e[14]=s*o*2*l,e[15]=0,e}function Wn(e,t,n,i,r){let o=1/Math.tan(t/2);if(e[0]=o/n,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=o,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[11]=-1,e[12]=0,e[13]=0,e[15]=0,r!=null&&r!==1/0){let s=1/(i-r);e[10]=(r+i)*s,e[14]=2*r*i*s}else e[10]=-1,e[14]=-2*i;return e}var yt=Wn;function $n(e,t,n,i,r,o,s){let c=1/(t-n),a=1/(i-r),l=1/(o-s);return e[0]=-2*c,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=-2*a,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=2*l,e[11]=0,e[12]=(t+n)*c,e[13]=(r+i)*a,e[14]=(s+o)*l,e[15]=1,e}var Tt=$n;function Ft(e,t,n,i){let r,o,s,c,a,l,h,f,p,m,x=t[0],_=t[1],d=t[2],g=i[0],A=i[1],v=i[2],M=n[0],b=n[1],u=n[2];return Math.abs(x-M)<1e-6&&Math.abs(_-b)<1e-6&&Math.abs(d-u)<1e-6?qn(e):(f=x-M,p=_-b,m=d-u,r=1/Math.sqrt(f*f+p*p+m*m),f*=r,p*=r,m*=r,o=A*m-v*p,s=v*f-g*m,c=g*p-A*f,r=Math.sqrt(o*o+s*s+c*c),r?(r=1/r,o*=r,s*=r,c*=r):(o=0,s=0,c=0),a=p*c-m*s,l=m*o-f*c,h=f*s-p*o,r=Math.sqrt(a*a+l*l+h*h),r?(r=1/r,a*=r,l*=r,h*=r):(a=0,l=0,h=0),e[0]=o,e[1]=a,e[2]=f,e[3]=0,e[4]=s,e[5]=l,e[6]=p,e[7]=0,e[8]=c,e[9]=h,e[10]=m,e[11]=0,e[12]=-(o*x+s*_+c*d),e[13]=-(a*x+l*_+h*d),e[14]=-(f*x+p*_+m*d),e[15]=1,e)}function Yn(){let e=new w(4);return w!=Float32Array&&(e[0]=0,e[1]=0,e[2]=0,e[3]=0),e}function wt(e,t,n){let i=t[0],r=t[1],o=t[2],s=t[3];return e[0]=n[0]*i+n[4]*r+n[8]*o+n[12]*s,e[1]=n[1]*i+n[5]*r+n[9]*o+n[13]*s,e[2]=n[2]*i+n[6]*r+n[10]*o+n[14]*s,e[3]=n[3]*i+n[7]*r+n[11]*o+n[15]*s,e}var Pr=function(){let e=Yn();return function(t,n,i,r,o,s){let c,a;for(n||(n=4),i||(i=0),r?a=Math.min(r*n+i,t.length):a=t.length,c=i;c<a;c+=n)e[0]=t[c],e[1]=t[c+1],e[2]=t[c+2],e[3]=t[c+3],o(e,e,s),t[c]=e[0],t[c+1]=e[1],t[c+2]=e[2],t[c+3]=e[3];return t}}();var ye;(function(e){e[e.COL0ROW0=0]="COL0ROW0",e[e.COL0ROW1=1]="COL0ROW1",e[e.COL0ROW2=2]="COL0ROW2",e[e.COL0ROW3=3]="COL0ROW3",e[e.COL1ROW0=4]="COL1ROW0",e[e.COL1ROW1=5]="COL1ROW1",e[e.COL1ROW2=6]="COL1ROW2",e[e.COL1ROW3=7]="COL1ROW3",e[e.COL2ROW0=8]="COL2ROW0",e[e.COL2ROW1=9]="COL2ROW1",e[e.COL2ROW2=10]="COL2ROW2",e[e.COL2ROW3=11]="COL2ROW3",e[e.COL3ROW0=12]="COL3ROW0",e[e.COL3ROW1=13]="COL3ROW1",e[e.COL3ROW2=14]="COL3ROW2",e[e.COL3ROW3=15]="COL3ROW3"})(ye||(ye={}));var Kn=45*Math.PI/180,Xn=1,Oe=.1,Ne=500,Zn=Object.freeze([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),k=class extends he{static get IDENTITY(){return Qn()}static get ZERO(){return Jn()}get ELEMENTS(){return 16}get RANK(){return 4}get INDICES(){return ye}constructor(t){super(-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0),arguments.length===1&&Array.isArray(t)?this.copy(t):this.identity()}copy(t){return this[0]=t[0],this[1]=t[1],this[2]=t[2],this[3]=t[3],this[4]=t[4],this[5]=t[5],this[6]=t[6],this[7]=t[7],this[8]=t[8],this[9]=t[9],this[10]=t[10],this[11]=t[11],this[12]=t[12],this[13]=t[13],this[14]=t[14],this[15]=t[15],this.check()}set(t,n,i,r,o,s,c,a,l,h,f,p,m,x,_,d){return this[0]=t,this[1]=n,this[2]=i,this[3]=r,this[4]=o,this[5]=s,this[6]=c,this[7]=a,this[8]=l,this[9]=h,this[10]=f,this[11]=p,this[12]=m,this[13]=x,this[14]=_,this[15]=d,this.check()}setRowMajor(t,n,i,r,o,s,c,a,l,h,f,p,m,x,_,d){return this[0]=t,this[1]=o,this[2]=l,this[3]=m,this[4]=n,this[5]=s,this[6]=h,this[7]=x,this[8]=i,this[9]=c,this[10]=f,this[11]=_,this[12]=r,this[13]=a,this[14]=p,this[15]=d,this.check()}toRowMajor(t){return t[0]=this[0],t[1]=this[4],t[2]=this[8],t[3]=this[12],t[4]=this[1],t[5]=this[5],t[6]=this[9],t[7]=this[13],t[8]=this[2],t[9]=this[6],t[10]=this[10],t[11]=this[14],t[12]=this[3],t[13]=this[7],t[14]=this[11],t[15]=this[15],t}identity(){return this.copy(Zn)}fromObject(t){return this.check()}fromQuaternion(t){return Ot(this,t),this.check()}frustum(t){let{left:n,right:i,bottom:r,top:o,near:s=Oe,far:c=Ne}=t;return c===1/0?ei(this,n,i,r,o,s):Nt(this,n,i,r,o,s,c),this.check()}lookAt(t){let{eye:n,center:i=[0,0,0],up:r=[0,1,0]}=t;return Ft(this,n,i,r),this.check()}ortho(t){let{left:n,right:i,bottom:r,top:o,near:s=Oe,far:c=Ne}=t;return Tt(this,n,i,r,o,s,c),this.check()}orthographic(t){let{fovy:n=Kn,aspect:i=Xn,focalDistance:r=1,near:o=Oe,far:s=Ne}=t;kt(n);let c=n/2,a=r*Math.tan(c),l=a*i;return this.ortho({left:-l,right:l,bottom:-a,top:a,near:o,far:s})}perspective(t){let{fovy:n=45*Math.PI/180,aspect:i=1,near:r=.1,far:o=500}=t;return kt(n),yt(this,n,i,r,o),this.check()}determinant(){return Lt(this)}getScale(t=[-0,-0,-0]){return t[0]=Math.sqrt(this[0]*this[0]+this[1]*this[1]+this[2]*this[2]),t[1]=Math.sqrt(this[4]*this[4]+this[5]*this[5]+this[6]*this[6]),t[2]=Math.sqrt(this[8]*this[8]+this[9]*this[9]+this[10]*this[10]),t}getTranslation(t=[-0,-0,-0]){return t[0]=this[12],t[1]=this[13],t[2]=this[14],t}getRotation(t,n){t=t||[-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0],n=n||[-0,-0,-0];let i=this.getScale(n),r=1/i[0],o=1/i[1],s=1/i[2];return t[0]=this[0]*r,t[1]=this[1]*o,t[2]=this[2]*s,t[3]=0,t[4]=this[4]*r,t[5]=this[5]*o,t[6]=this[6]*s,t[7]=0,t[8]=this[8]*r,t[9]=this[9]*o,t[10]=this[10]*s,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}getRotationMatrix3(t,n){t=t||[-0,-0,-0,-0,-0,-0,-0,-0,-0],n=n||[-0,-0,-0];let i=this.getScale(n),r=1/i[0],o=1/i[1],s=1/i[2];return t[0]=this[0]*r,t[1]=this[1]*o,t[2]=this[2]*s,t[3]=this[4]*r,t[4]=this[5]*o,t[5]=this[6]*s,t[6]=this[8]*r,t[7]=this[9]*o,t[8]=this[10]*s,t}transpose(){return Mt(this,this),this.check()}invert(){return At(this,this),this.check()}multiplyLeft(t){return Ce(this,t,this),this.check()}multiplyRight(t){return Ce(this,this,t),this.check()}rotateX(t){return Pt(this,this,t),this.check()}rotateY(t){return Rt(this,this,t),this.check()}rotateZ(t){return Ct(this,this,t),this.check()}rotateXYZ(t){return this.rotateX(t[0]).rotateY(t[1]).rotateZ(t[2])}rotateAxis(t,n){return It(this,this,t,n),this.check()}scale(t){return Et(this,this,Array.isArray(t)?t:[t,t,t]),this.check()}translate(t){return St(this,this,t),this.check()}transform(t,n){return t.length===4?(n=wt(n||[-0,-0,-0,-0],t,this),pe(n,4),n):this.transformAsPoint(t,n)}transformAsPoint(t,n){let{length:i}=t,r;switch(i){case 2:r=dt(n||[-0,-0],t,this);break;case 3:r=bt(n||[-0,-0,-0],t,this);break;default:throw new Error("Illegal vector")}return pe(r,t.length),r}transformAsVector(t,n){let i;switch(t.length){case 2:i=vt(n||[-0,-0],t,this);break;case 3:i=xt(n||[-0,-0,-0],t,this);break;default:throw new Error("Illegal vector")}return pe(i,t.length),i}transformPoint(t,n){return this.transformAsPoint(t,n)}transformVector(t,n){return this.transformAsPoint(t,n)}transformDirection(t,n){return this.transformAsVector(t,n)}makeRotationX(t){return this.identity().rotateX(t)}makeTranslation(t,n,i){return this.identity().translate([t,n,i])}},ge,me;function Jn(){return ge||(ge=new k([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),Object.freeze(ge)),ge}function Qn(){return me||(me=new k,Object.freeze(me)),me}function kt(e){if(e>Math.PI*2)throw Error("expected radians")}function ei(e,t,n,i,r,o){let s=2*o/(n-t),c=2*o/(r-i),a=(n+t)/(n-t),l=(r+i)/(r-i),h=-1,f=-1,p=-2*o;return e[0]=s,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=c,e[6]=0,e[7]=0,e[8]=a,e[9]=l,e[10]=h,e[11]=f,e[12]=0,e[13]=0,e[14]=p,e[15]=0,e}var U=null,Dt=new ArrayBuffer(4),Ut=new Float32Array(Dt),Bt=new Uint32Array(Dt);function zt(e){U||=Gt(),e=Pe(e,-65504,65504),Ut[0]=e;let t=Bt[0],n=t>>23&511;return U.baseTable[n]+((t&8388607)>>U.shiftTable[n])}function Ht(e){U||=Gt();let t=e>>10;return Bt[0]=U.mantissaTable[U.offsetTable[t]+(e&1023)]+U.exponentTable[t],Ut[0]}function Gt(){let e=new Uint32Array(512),t=new Uint32Array(512);for(let o=0;o<256;++o){let s=o-127;s<-27?(e[o]=0,e[o|256]=32768,t[o]=24,t[o|256]=24):s<-14?(e[o]=1024>>-s-14,e[o|256]=1024>>-s-14|32768,t[o]=-s-1,t[o|256]=-s-1):s<=15?(e[o]=s+15<<10,e[o|256]=s+15<<10|32768,t[o]=13,t[o|256]=13):s<128?(e[o]=31744,e[o|256]=64512,t[o]=24,t[o|256]=24):(e[o]=31744,e[o|256]=64512,t[o]=13,t[o|256]=13)}let n=new Uint32Array(2048),i=new Uint32Array(64),r=new Uint32Array(64);for(let o=1;o<1024;++o){let s=o<<13,c=0;for(;!(s&8388608);)s<<=1,c-=8388608;s&=-8388609,c+=947912704,n[o]=s|c}for(let o=1024;o<2048;++o)n[o]=939524096+(o-1024<<13);for(let o=1;o<31;++o)i[o]=o<<23;i[31]=1199570944,i[32]=2147483648;for(let o=33;o<63;++o)i[o]=2147483648+(o-32<<23);i[63]=3347054592;for(let o=1;o<64;++o)o!==32&&(r[o]=1024);return{baseTable:e,shiftTable:t,mantissaTable:n,exponentTable:i,offsetTable:r}}function G(e,t=[],n=0){let i=Math.fround(e),r=e-i;return t[n]=i,t[n+1]=r,t}function Z(e){return e-Math.fround(e)}function J(e){let t=new Float32Array(32);for(let n=0;n<4;++n)for(let i=0;i<4;++i){let r=n*4+i;G(e[i*4+n],t,r*2)}return t}var ti=`fn random(scale: vec3f, seed: f32) -> f32 {
|
|
101
|
+
${r} = ${i};
|
|
102
|
+
}`}function Pt(e){switch(e){case"float":return"x";case"vec2":return"xy";case"vec3":return"xyz";case"vec4":return"xyzw";default:throw new Error(e)}}function Nt(e){switch(e){case"float":return 1;case"vec2":return 2;case"vec3":return 3;case"vec4":return 4;default:throw new Error(e)}}function Lr(e){switch(e){case 1:return"float";case 2:return"vec2";case 3:return"vec3";case 4:return"vec4";default:throw new Error(`invalid channels: ${e}`)}}function Be(e,t){switch(t){case 1:return`vec4(${e}, 0.0, 0.0, 1.0)`;case 2:return`vec4(${e}, 0.0, 1.0)`;case 3:return`vec4(${e}, 1.0)`;case 4:return e;default:throw new Error(`invalid channels: ${t}`)}}function k(e){return typeof e=="string"?e.charAt(0).toUpperCase()+e.slice(1):e}function yt(e,t){return Ar(e,t)}function Ar(e,t){let n=[];switch(t.uniforms){case"scoped-interface-blocks":case"unscoped-interface-blocks":n.push(`uniform ${k(e.name)} {`);break;case"uniforms":}for(let[r,o]of Object.entries(e.uniformTypes||{})){if(typeof o!="string")throw new Error(`Composite uniform types are not supported by GLSL shader generation: ${e.name}.${r}`);let i=Er(o);switch(t.uniforms){case"scoped-interface-blocks":n.push(` ${i} ${r};`);break;case"unscoped-interface-blocks":n.push(` ${i} ${e.name}_${r};`);break;case"uniforms":n.push(`uniform ${i} ${e.name}_${r};`)}}switch(t.uniforms){case"scoped-interface-blocks":n.push(`} ${e.name};`);break;case"unscoped-interface-blocks":n.push("};");break;case"uniforms":}return n.push(""),n.join(`
|
|
103
|
+
`)}function Er(e){return{f32:"float",i32:"int",u32:"uint","vec2<f32>":"vec2","vec3<f32>":"vec3","vec4<f32>":"vec4","vec2<i32>":"ivec2","vec3<i32>":"ivec3","vec4<i32>":"ivec4","vec2<u32>":"uvec2","vec3<u32>":"uvec3","vec4<u32>":"uvec4","mat2x2<f32>":"mat2","mat2x3<f32>":"mat2x3","mat2x4<f32>":"mat2x4","mat3x2<f32>":"mat3x2","mat3x3<f32>":"mat3","mat3x4<f32>":"mat3x4","mat4x2<f32>":"mat4x2","mat4x3<f32>":"mat4x3","mat4x4<f32>":"mat4"}[e]}function Ot(e,t){return Rr(e,t)}function Rr(e,t){let n=[];n.push(`struct ${k(e.name)} {`);for(let[r,o]of Object.entries(e?.uniformTypes||{})){if(typeof o!="string")throw new Error(`Composite uniform types are not supported by WGSL shader generation: ${e.name}.${r}`);let i=o;n.push(` ${r} : ${i};`)}return n.push("};"),n.push(`var<uniform> ${e.name} : ${k(e.name)};`),n.join(`
|
|
104
|
+
`)}function Tt(e,t){switch(t.shaderLanguage){case"glsl":return yt(e,t);case"wgsl":return Ot(e,t)}}var li=1/Math.PI*180,fi=1/180*Math.PI,Ir={EPSILON:1e-12,debug:!1,precision:4,printTypes:!1,printDegrees:!1,printRowMajor:!0,_cartographicRadians:!1};globalThis.mathgl=globalThis.mathgl||{config:{...Ir}};var P=globalThis.mathgl.config;function ke(e,{precision:t=P.precision}={}){return e=Cr(e),`${parseFloat(e.toPrecision(t))}`}function H(e){return Array.isArray(e)||ArrayBuffer.isView(e)&&!(e instanceof DataView)}function De(e,t,n){return Nr(e,r=>Math.max(t,Math.min(n,r)))}function me(e,t,n){let r=P.EPSILON;n&&(P.EPSILON=n);try{if(e===t)return!0;if(H(e)&&H(t)){if(e.length!==t.length)return!1;for(let o=0;o<e.length;++o)if(!me(e[o],t[o]))return!1;return!0}return e&&e.equals?e.equals(t):t&&t.equals?t.equals(e):typeof e=="number"&&typeof t=="number"?Math.abs(e-t)<=P.EPSILON*Math.max(1,Math.abs(e),Math.abs(t)):!1}finally{P.EPSILON=r}}function Cr(e){return Math.round(e/P.EPSILON)*P.EPSILON}function Pr(e){return e.clone?e.clone():new Array(e.length)}function Nr(e,t,n){if(H(e)){let r=e;n=n||Pr(r);for(let o=0;o<n.length&&o<r.length;++o){let i=typeof e=="number"?e:e[o];n[o]=t(i,o,n)}return n}return t(e)}var de=class extends Array{clone(){return new this.constructor().copy(this)}fromArray(t,n=0){for(let r=0;r<this.ELEMENTS;++r)this[r]=t[r+n];return this.check()}toArray(t=[],n=0){for(let r=0;r<this.ELEMENTS;++r)t[n+r]=this[r];return t}toObject(t){return t}from(t){return Array.isArray(t)?this.copy(t):this.fromObject(t)}to(t){return t===this?this:H(t)?this.toArray(t):this.toObject(t)}toTarget(t){return t?this.to(t):this}toFloat32Array(){return new Float32Array(this)}toString(){return this.formatString(P)}formatString(t){let n="";for(let r=0;r<this.ELEMENTS;++r)n+=(r>0?", ":"")+ke(this[r],t);return`${t.printTypes?this.constructor.name:""}[${n}]`}equals(t){if(!t||this.length!==t.length)return!1;for(let n=0;n<this.ELEMENTS;++n)if(!me(this[n],t[n]))return!1;return!0}exactEquals(t){if(!t||this.length!==t.length)return!1;for(let n=0;n<this.ELEMENTS;++n)if(this[n]!==t[n])return!1;return!0}negate(){for(let t=0;t<this.ELEMENTS;++t)this[t]=-this[t];return this.check()}lerp(t,n,r){if(r===void 0)return this.lerp(this,t,n);for(let o=0;o<this.ELEMENTS;++o){let i=t[o],a=typeof n=="number"?n:n[o];this[o]=i+r*(a-i)}return this.check()}min(t){for(let n=0;n<this.ELEMENTS;++n)this[n]=Math.min(t[n],this[n]);return this.check()}max(t){for(let n=0;n<this.ELEMENTS;++n)this[n]=Math.max(t[n],this[n]);return this.check()}clamp(t,n){for(let r=0;r<this.ELEMENTS;++r)this[r]=Math.min(Math.max(this[r],t[r]),n[r]);return this.check()}add(...t){for(let n of t)for(let r=0;r<this.ELEMENTS;++r)this[r]+=n[r];return this.check()}subtract(...t){for(let n of t)for(let r=0;r<this.ELEMENTS;++r)this[r]-=n[r];return this.check()}scale(t){if(typeof t=="number")for(let n=0;n<this.ELEMENTS;++n)this[n]*=t;else for(let n=0;n<this.ELEMENTS&&n<t.length;++n)this[n]*=t[n];return this.check()}multiplyByScalar(t){for(let n=0;n<this.ELEMENTS;++n)this[n]*=t;return this.check()}check(){if(P.debug&&!this.validate())throw new Error(`math.gl: ${this.constructor.name} some fields set to invalid numbers'`);return this}validate(){let t=this.length===this.ELEMENTS;for(let n=0;n<this.ELEMENTS;++n)t=t&&Number.isFinite(this[n]);return t}sub(t){return this.subtract(t)}setScalar(t){for(let n=0;n<this.ELEMENTS;++n)this[n]=t;return this.check()}addScalar(t){for(let n=0;n<this.ELEMENTS;++n)this[n]+=t;return this.check()}subScalar(t){return this.addScalar(-t)}multiplyScalar(t){for(let n=0;n<this.ELEMENTS;++n)this[n]*=t;return this.check()}divideScalar(t){return this.multiplyByScalar(1/t)}clampScalar(t,n){for(let r=0;r<this.ELEMENTS;++r)this[r]=Math.min(Math.max(this[r],t),n);return this.check()}get elements(){return this}};function yr(e,t){if(e.length!==t)return!1;for(let n=0;n<e.length;++n)if(!Number.isFinite(e[n]))return!1;return!0}function Ft(e){if(!Number.isFinite(e))throw new Error(`Invalid number ${JSON.stringify(e)}`);return e}function _e(e,t,n=""){if(P.debug&&!yr(e,t))throw new Error(`math.gl: ${n} some fields set to invalid numbers'`);return e}var w=typeof Float32Array<"u"?Float32Array:Array;var di=Math.PI/180;function Or(){let e=new w(2);return w!=Float32Array&&(e[0]=0,e[1]=0),e}function kt(e,t,n){let r=t[0],o=t[1];return e[0]=n[0]*r+n[4]*o+n[12],e[1]=n[1]*r+n[5]*o+n[13],e}var _i=function(){let e=Or();return function(t,n,r,o,i,a){let s,c;for(n||(n=2),r||(r=0),o?c=Math.min(o*n+r,t.length):c=t.length,s=r;s<c;s+=n)e[0]=t[s],e[1]=t[s+1],i(e,e,a),t[s]=e[0],t[s+1]=e[1];return t}}();function Dt(e,t,n){let r=t[0],o=t[1],i=n[3]*r+n[7]*o||1;return e[0]=(n[0]*r+n[4]*o)/i,e[1]=(n[1]*r+n[5]*o)/i,e}function Ut(e,t,n){let r=t[0],o=t[1],i=t[2],a=n[3]*r+n[7]*o+n[11]*i||1;return e[0]=(n[0]*r+n[4]*o+n[8]*i)/a,e[1]=(n[1]*r+n[5]*o+n[9]*i)/a,e[2]=(n[2]*r+n[6]*o+n[10]*i)/a,e}function Tr(){let e=new w(3);return w!=Float32Array&&(e[0]=0,e[1]=0,e[2]=0),e}function zt(e,t,n){let r=t[0],o=t[1],i=t[2],a=n[3]*r+n[7]*o+n[11]*i+n[15];return a=a||1,e[0]=(n[0]*r+n[4]*o+n[8]*i+n[12])/a,e[1]=(n[1]*r+n[5]*o+n[9]*i+n[13])/a,e[2]=(n[2]*r+n[6]*o+n[10]*i+n[14])/a,e}var Si=function(){let e=Tr();return function(t,n,r,o,i,a){let s,c;for(n||(n=3),r||(r=0),o?c=Math.min(o*n+r,t.length):c=t.length,s=r;s<c;s+=n)e[0]=t[s],e[1]=t[s+1],e[2]=t[s+2],i(e,e,a),t[s]=e[0],t[s+1]=e[1],t[s+2]=e[2];return t}}();var be=class extends de{toString(){let t="[";if(P.printRowMajor){t+="row-major:";for(let n=0;n<this.RANK;++n)for(let r=0;r<this.RANK;++r)t+=` ${this[r*this.RANK+n]}`}else{t+="column-major:";for(let n=0;n<this.ELEMENTS;++n)t+=` ${this[n]}`}return t+="]",t}getElementIndex(t,n){return n*this.RANK+t}getElement(t,n){return this[n*this.RANK+t]}setElement(t,n,r){return this[n*this.RANK+t]=Ft(r),this}getColumn(t,n=new Array(this.RANK).fill(-0)){let r=t*this.RANK;for(let o=0;o<this.RANK;++o)n[o]=this[r+o];return n}setColumn(t,n){let r=t*this.RANK;for(let o=0;o<this.RANK;++o)this[r+o]=n[o];return this}};function Fr(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e}function Ht(e,t){if(e===t){let n=t[1],r=t[2],o=t[3],i=t[6],a=t[7],s=t[11];e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=n,e[6]=t[9],e[7]=t[13],e[8]=r,e[9]=i,e[11]=t[14],e[12]=o,e[13]=a,e[14]=s}else e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15];return e}function Gt(e,t){let n=t[0],r=t[1],o=t[2],i=t[3],a=t[4],s=t[5],c=t[6],l=t[7],p=t[8],f=t[9],h=t[10],g=t[11],_=t[12],m=t[13],x=t[14],d=t[15],M=n*s-r*a,b=n*c-o*a,S=n*l-i*a,v=r*c-o*s,u=r*l-i*s,E=o*l-i*c,R=p*m-f*_,L=p*x-h*_,I=p*d-g*_,N=f*x-h*m,C=f*d-g*m,y=h*d-g*x,A=M*y-b*C+S*N+v*I-u*L+E*R;return A?(A=1/A,e[0]=(s*y-c*C+l*N)*A,e[1]=(o*C-r*y-i*N)*A,e[2]=(m*E-x*u+d*v)*A,e[3]=(h*u-f*E-g*v)*A,e[4]=(c*I-a*y-l*L)*A,e[5]=(n*y-o*I+i*L)*A,e[6]=(x*S-_*E-d*b)*A,e[7]=(p*E-h*S+g*b)*A,e[8]=(a*C-s*I+l*R)*A,e[9]=(r*I-n*C-i*R)*A,e[10]=(_*u-m*S+d*M)*A,e[11]=(f*S-p*u-g*M)*A,e[12]=(s*L-a*N-c*R)*A,e[13]=(n*N-r*L+o*R)*A,e[14]=(m*b-_*v-x*M)*A,e[15]=(p*v-f*b+h*M)*A,e):null}function Vt(e){let t=e[0],n=e[1],r=e[2],o=e[3],i=e[4],a=e[5],s=e[6],c=e[7],l=e[8],p=e[9],f=e[10],h=e[11],g=e[12],_=e[13],m=e[14],x=e[15],d=t*a-n*i,M=t*s-r*i,b=n*s-r*a,S=l*_-p*g,v=l*m-f*g,u=p*m-f*_,E=t*u-n*v+r*S,R=i*u-a*v+s*S,L=l*b-p*M+f*d,I=g*b-_*M+m*d;return c*E-o*R+x*L-h*I}function ze(e,t,n){let r=t[0],o=t[1],i=t[2],a=t[3],s=t[4],c=t[5],l=t[6],p=t[7],f=t[8],h=t[9],g=t[10],_=t[11],m=t[12],x=t[13],d=t[14],M=t[15],b=n[0],S=n[1],v=n[2],u=n[3];return e[0]=b*r+S*s+v*f+u*m,e[1]=b*o+S*c+v*h+u*x,e[2]=b*i+S*l+v*g+u*d,e[3]=b*a+S*p+v*_+u*M,b=n[4],S=n[5],v=n[6],u=n[7],e[4]=b*r+S*s+v*f+u*m,e[5]=b*o+S*c+v*h+u*x,e[6]=b*i+S*l+v*g+u*d,e[7]=b*a+S*p+v*_+u*M,b=n[8],S=n[9],v=n[10],u=n[11],e[8]=b*r+S*s+v*f+u*m,e[9]=b*o+S*c+v*h+u*x,e[10]=b*i+S*l+v*g+u*d,e[11]=b*a+S*p+v*_+u*M,b=n[12],S=n[13],v=n[14],u=n[15],e[12]=b*r+S*s+v*f+u*m,e[13]=b*o+S*c+v*h+u*x,e[14]=b*i+S*l+v*g+u*d,e[15]=b*a+S*p+v*_+u*M,e}function Wt(e,t,n){let r=n[0],o=n[1],i=n[2],a,s,c,l,p,f,h,g,_,m,x,d;return t===e?(e[12]=t[0]*r+t[4]*o+t[8]*i+t[12],e[13]=t[1]*r+t[5]*o+t[9]*i+t[13],e[14]=t[2]*r+t[6]*o+t[10]*i+t[14],e[15]=t[3]*r+t[7]*o+t[11]*i+t[15]):(a=t[0],s=t[1],c=t[2],l=t[3],p=t[4],f=t[5],h=t[6],g=t[7],_=t[8],m=t[9],x=t[10],d=t[11],e[0]=a,e[1]=s,e[2]=c,e[3]=l,e[4]=p,e[5]=f,e[6]=h,e[7]=g,e[8]=_,e[9]=m,e[10]=x,e[11]=d,e[12]=a*r+p*o+_*i+t[12],e[13]=s*r+f*o+m*i+t[13],e[14]=c*r+h*o+x*i+t[14],e[15]=l*r+g*o+d*i+t[15]),e}function jt(e,t,n){let r=n[0],o=n[1],i=n[2];return e[0]=t[0]*r,e[1]=t[1]*r,e[2]=t[2]*r,e[3]=t[3]*r,e[4]=t[4]*o,e[5]=t[5]*o,e[6]=t[6]*o,e[7]=t[7]*o,e[8]=t[8]*i,e[9]=t[9]*i,e[10]=t[10]*i,e[11]=t[11]*i,e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e}function $t(e,t,n,r){let o=r[0],i=r[1],a=r[2],s=Math.sqrt(o*o+i*i+a*a),c,l,p,f,h,g,_,m,x,d,M,b,S,v,u,E,R,L,I,N,C,y,A,W;return s<1e-6?null:(s=1/s,o*=s,i*=s,a*=s,l=Math.sin(n),c=Math.cos(n),p=1-c,f=t[0],h=t[1],g=t[2],_=t[3],m=t[4],x=t[5],d=t[6],M=t[7],b=t[8],S=t[9],v=t[10],u=t[11],E=o*o*p+c,R=i*o*p+a*l,L=a*o*p-i*l,I=o*i*p-a*l,N=i*i*p+c,C=a*i*p+o*l,y=o*a*p+i*l,A=i*a*p-o*l,W=a*a*p+c,e[0]=f*E+m*R+b*L,e[1]=h*E+x*R+S*L,e[2]=g*E+d*R+v*L,e[3]=_*E+M*R+u*L,e[4]=f*I+m*N+b*C,e[5]=h*I+x*N+S*C,e[6]=g*I+d*N+v*C,e[7]=_*I+M*N+u*C,e[8]=f*y+m*A+b*W,e[9]=h*y+x*A+S*W,e[10]=g*y+d*A+v*W,e[11]=_*y+M*A+u*W,t!==e&&(e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]),e)}function qt(e,t,n){let r=Math.sin(n),o=Math.cos(n),i=t[4],a=t[5],s=t[6],c=t[7],l=t[8],p=t[9],f=t[10],h=t[11];return t!==e&&(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]),e[4]=i*o+l*r,e[5]=a*o+p*r,e[6]=s*o+f*r,e[7]=c*o+h*r,e[8]=l*o-i*r,e[9]=p*o-a*r,e[10]=f*o-s*r,e[11]=h*o-c*r,e}function Kt(e,t,n){let r=Math.sin(n),o=Math.cos(n),i=t[0],a=t[1],s=t[2],c=t[3],l=t[8],p=t[9],f=t[10],h=t[11];return t!==e&&(e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]),e[0]=i*o-l*r,e[1]=a*o-p*r,e[2]=s*o-f*r,e[3]=c*o-h*r,e[8]=i*r+l*o,e[9]=a*r+p*o,e[10]=s*r+f*o,e[11]=c*r+h*o,e}function Yt(e,t,n){let r=Math.sin(n),o=Math.cos(n),i=t[0],a=t[1],s=t[2],c=t[3],l=t[4],p=t[5],f=t[6],h=t[7];return t!==e&&(e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]),e[0]=i*o+l*r,e[1]=a*o+p*r,e[2]=s*o+f*r,e[3]=c*o+h*r,e[4]=l*o-i*r,e[5]=p*o-a*r,e[6]=f*o-s*r,e[7]=h*o-c*r,e}function Xt(e,t){let n=t[0],r=t[1],o=t[2],i=t[3],a=n+n,s=r+r,c=o+o,l=n*a,p=r*a,f=r*s,h=o*a,g=o*s,_=o*c,m=i*a,x=i*s,d=i*c;return e[0]=1-f-_,e[1]=p+d,e[2]=h-x,e[3]=0,e[4]=p-d,e[5]=1-l-_,e[6]=g+m,e[7]=0,e[8]=h+x,e[9]=g-m,e[10]=1-l-f,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e}function Zt(e,t,n,r,o,i,a){let s=1/(n-t),c=1/(o-r),l=1/(i-a);return e[0]=i*2*s,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=i*2*c,e[6]=0,e[7]=0,e[8]=(n+t)*s,e[9]=(o+r)*c,e[10]=(a+i)*l,e[11]=-1,e[12]=0,e[13]=0,e[14]=a*i*2*l,e[15]=0,e}function wr(e,t,n,r,o){let i=1/Math.tan(t/2);if(e[0]=i/n,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=i,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[11]=-1,e[12]=0,e[13]=0,e[15]=0,o!=null&&o!==1/0){let a=1/(r-o);e[10]=(o+r)*a,e[14]=2*o*r*a}else e[10]=-1,e[14]=-2*r;return e}var Jt=wr;function Br(e,t,n,r,o,i,a){let s=1/(t-n),c=1/(r-o),l=1/(i-a);return e[0]=-2*s,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=-2*c,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=2*l,e[11]=0,e[12]=(t+n)*s,e[13]=(o+r)*c,e[14]=(a+i)*l,e[15]=1,e}var Qt=Br;function en(e,t,n,r){let o,i,a,s,c,l,p,f,h,g,_=t[0],m=t[1],x=t[2],d=r[0],M=r[1],b=r[2],S=n[0],v=n[1],u=n[2];return Math.abs(_-S)<1e-6&&Math.abs(m-v)<1e-6&&Math.abs(x-u)<1e-6?Fr(e):(f=_-S,h=m-v,g=x-u,o=1/Math.sqrt(f*f+h*h+g*g),f*=o,h*=o,g*=o,i=M*g-b*h,a=b*f-d*g,s=d*h-M*f,o=Math.sqrt(i*i+a*a+s*s),o?(o=1/o,i*=o,a*=o,s*=o):(i=0,a=0,s=0),c=h*s-g*a,l=g*i-f*s,p=f*a-h*i,o=Math.sqrt(c*c+l*l+p*p),o?(o=1/o,c*=o,l*=o,p*=o):(c=0,l=0,p=0),e[0]=i,e[1]=c,e[2]=f,e[3]=0,e[4]=a,e[5]=l,e[6]=h,e[7]=0,e[8]=s,e[9]=p,e[10]=g,e[11]=0,e[12]=-(i*_+a*m+s*x),e[13]=-(c*_+l*m+p*x),e[14]=-(f*_+h*m+g*x),e[15]=1,e)}function kr(){let e=new w(4);return w!=Float32Array&&(e[0]=0,e[1]=0,e[2]=0,e[3]=0),e}function tn(e,t,n){let r=t[0],o=t[1],i=t[2],a=t[3];return e[0]=n[0]*r+n[4]*o+n[8]*i+n[12]*a,e[1]=n[1]*r+n[5]*o+n[9]*i+n[13]*a,e[2]=n[2]*r+n[6]*o+n[10]*i+n[14]*a,e[3]=n[3]*r+n[7]*o+n[11]*i+n[15]*a,e}var Ii=function(){let e=kr();return function(t,n,r,o,i,a){let s,c;for(n||(n=4),r||(r=0),o?c=Math.min(o*n+r,t.length):c=t.length,s=r;s<c;s+=n)e[0]=t[s],e[1]=t[s+1],e[2]=t[s+2],e[3]=t[s+3],i(e,e,a),t[s]=e[0],t[s+1]=e[1],t[s+2]=e[2],t[s+3]=e[3];return t}}();var Ve;(function(e){e[e.COL0ROW0=0]="COL0ROW0",e[e.COL0ROW1=1]="COL0ROW1",e[e.COL0ROW2=2]="COL0ROW2",e[e.COL0ROW3=3]="COL0ROW3",e[e.COL1ROW0=4]="COL1ROW0",e[e.COL1ROW1=5]="COL1ROW1",e[e.COL1ROW2=6]="COL1ROW2",e[e.COL1ROW3=7]="COL1ROW3",e[e.COL2ROW0=8]="COL2ROW0",e[e.COL2ROW1=9]="COL2ROW1",e[e.COL2ROW2=10]="COL2ROW2",e[e.COL2ROW3=11]="COL2ROW3",e[e.COL3ROW0=12]="COL3ROW0",e[e.COL3ROW1=13]="COL3ROW1",e[e.COL3ROW2=14]="COL3ROW2",e[e.COL3ROW3=15]="COL3ROW3"})(Ve||(Ve={}));var Dr=45*Math.PI/180,Ur=1,He=.1,Ge=500,zr=Object.freeze([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),B=class extends be{static get IDENTITY(){return Gr()}static get ZERO(){return Hr()}get ELEMENTS(){return 16}get RANK(){return 4}get INDICES(){return Ve}constructor(t){super(-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0),arguments.length===1&&Array.isArray(t)?this.copy(t):this.identity()}copy(t){return this[0]=t[0],this[1]=t[1],this[2]=t[2],this[3]=t[3],this[4]=t[4],this[5]=t[5],this[6]=t[6],this[7]=t[7],this[8]=t[8],this[9]=t[9],this[10]=t[10],this[11]=t[11],this[12]=t[12],this[13]=t[13],this[14]=t[14],this[15]=t[15],this.check()}set(t,n,r,o,i,a,s,c,l,p,f,h,g,_,m,x){return this[0]=t,this[1]=n,this[2]=r,this[3]=o,this[4]=i,this[5]=a,this[6]=s,this[7]=c,this[8]=l,this[9]=p,this[10]=f,this[11]=h,this[12]=g,this[13]=_,this[14]=m,this[15]=x,this.check()}setRowMajor(t,n,r,o,i,a,s,c,l,p,f,h,g,_,m,x){return this[0]=t,this[1]=i,this[2]=l,this[3]=g,this[4]=n,this[5]=a,this[6]=p,this[7]=_,this[8]=r,this[9]=s,this[10]=f,this[11]=m,this[12]=o,this[13]=c,this[14]=h,this[15]=x,this.check()}toRowMajor(t){return t[0]=this[0],t[1]=this[4],t[2]=this[8],t[3]=this[12],t[4]=this[1],t[5]=this[5],t[6]=this[9],t[7]=this[13],t[8]=this[2],t[9]=this[6],t[10]=this[10],t[11]=this[14],t[12]=this[3],t[13]=this[7],t[14]=this[11],t[15]=this[15],t}identity(){return this.copy(zr)}fromObject(t){return this.check()}fromQuaternion(t){return Xt(this,t),this.check()}frustum(t){let{left:n,right:r,bottom:o,top:i,near:a=He,far:s=Ge}=t;return s===1/0?Vr(this,n,r,o,i,a):Zt(this,n,r,o,i,a,s),this.check()}lookAt(t){let{eye:n,center:r=[0,0,0],up:o=[0,1,0]}=t;return en(this,n,r,o),this.check()}ortho(t){let{left:n,right:r,bottom:o,top:i,near:a=He,far:s=Ge}=t;return Qt(this,n,r,o,i,a,s),this.check()}orthographic(t){let{fovy:n=Dr,aspect:r=Ur,focalDistance:o=1,near:i=He,far:a=Ge}=t;nn(n);let s=n/2,c=o*Math.tan(s),l=c*r;return this.ortho({left:-l,right:l,bottom:-c,top:c,near:i,far:a})}perspective(t){let{fovy:n=45*Math.PI/180,aspect:r=1,near:o=.1,far:i=500}=t;return nn(n),Jt(this,n,r,o,i),this.check()}determinant(){return Vt(this)}getScale(t=[-0,-0,-0]){return t[0]=Math.sqrt(this[0]*this[0]+this[1]*this[1]+this[2]*this[2]),t[1]=Math.sqrt(this[4]*this[4]+this[5]*this[5]+this[6]*this[6]),t[2]=Math.sqrt(this[8]*this[8]+this[9]*this[9]+this[10]*this[10]),t}getTranslation(t=[-0,-0,-0]){return t[0]=this[12],t[1]=this[13],t[2]=this[14],t}getRotation(t,n){t=t||[-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0,-0],n=n||[-0,-0,-0];let r=this.getScale(n),o=1/r[0],i=1/r[1],a=1/r[2];return t[0]=this[0]*o,t[1]=this[1]*i,t[2]=this[2]*a,t[3]=0,t[4]=this[4]*o,t[5]=this[5]*i,t[6]=this[6]*a,t[7]=0,t[8]=this[8]*o,t[9]=this[9]*i,t[10]=this[10]*a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}getRotationMatrix3(t,n){t=t||[-0,-0,-0,-0,-0,-0,-0,-0,-0],n=n||[-0,-0,-0];let r=this.getScale(n),o=1/r[0],i=1/r[1],a=1/r[2];return t[0]=this[0]*o,t[1]=this[1]*i,t[2]=this[2]*a,t[3]=this[4]*o,t[4]=this[5]*i,t[5]=this[6]*a,t[6]=this[8]*o,t[7]=this[9]*i,t[8]=this[10]*a,t}transpose(){return Ht(this,this),this.check()}invert(){return Gt(this,this),this.check()}multiplyLeft(t){return ze(this,t,this),this.check()}multiplyRight(t){return ze(this,this,t),this.check()}rotateX(t){return qt(this,this,t),this.check()}rotateY(t){return Kt(this,this,t),this.check()}rotateZ(t){return Yt(this,this,t),this.check()}rotateXYZ(t){return this.rotateX(t[0]).rotateY(t[1]).rotateZ(t[2])}rotateAxis(t,n){return $t(this,this,t,n),this.check()}scale(t){return jt(this,this,Array.isArray(t)?t:[t,t,t]),this.check()}translate(t){return Wt(this,this,t),this.check()}transform(t,n){return t.length===4?(n=tn(n||[-0,-0,-0,-0],t,this),_e(n,4),n):this.transformAsPoint(t,n)}transformAsPoint(t,n){let{length:r}=t,o;switch(r){case 2:o=kt(n||[-0,-0],t,this);break;case 3:o=zt(n||[-0,-0,-0],t,this);break;default:throw new Error("Illegal vector")}return _e(o,t.length),o}transformAsVector(t,n){let r;switch(t.length){case 2:r=Dt(n||[-0,-0],t,this);break;case 3:r=Ut(n||[-0,-0,-0],t,this);break;default:throw new Error("Illegal vector")}return _e(r,t.length),r}transformPoint(t,n){return this.transformAsPoint(t,n)}transformVector(t,n){return this.transformAsPoint(t,n)}transformDirection(t,n){return this.transformAsVector(t,n)}makeRotationX(t){return this.identity().rotateX(t)}makeTranslation(t,n,r){return this.identity().translate([t,n,r])}},ve,Se;function Hr(){return ve||(ve=new B([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),Object.freeze(ve)),ve}function Gr(){return Se||(Se=new B,Object.freeze(Se)),Se}function nn(e){if(e>Math.PI*2)throw Error("expected radians")}function Vr(e,t,n,r,o,i){let a=2*i/(n-t),s=2*i/(o-r),c=(n+t)/(n-t),l=(o+r)/(o-r),p=-1,f=-1,h=-2*i;return e[0]=a,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=s,e[6]=0,e[7]=0,e[8]=c,e[9]=l,e[10]=p,e[11]=f,e[12]=0,e[13]=0,e[14]=h,e[15]=0,e}var D=null,rn=new ArrayBuffer(4),on=new Float32Array(rn),an=new Uint32Array(rn);function sn(e){D||=ln(),e=De(e,-65504,65504),on[0]=e;let t=an[0],n=t>>23&511;return D.baseTable[n]+((t&8388607)>>D.shiftTable[n])}function cn(e){D||=ln();let t=e>>10;return an[0]=D.mantissaTable[D.offsetTable[t]+(e&1023)]+D.exponentTable[t],on[0]}function ln(){let e=new Uint32Array(512),t=new Uint32Array(512);for(let i=0;i<256;++i){let a=i-127;a<-27?(e[i]=0,e[i|256]=32768,t[i]=24,t[i|256]=24):a<-14?(e[i]=1024>>-a-14,e[i|256]=1024>>-a-14|32768,t[i]=-a-1,t[i|256]=-a-1):a<=15?(e[i]=a+15<<10,e[i|256]=a+15<<10|32768,t[i]=13,t[i|256]=13):a<128?(e[i]=31744,e[i|256]=64512,t[i]=24,t[i|256]=24):(e[i]=31744,e[i|256]=64512,t[i]=13,t[i|256]=13)}let n=new Uint32Array(2048),r=new Uint32Array(64),o=new Uint32Array(64);for(let i=1;i<1024;++i){let a=i<<13,s=0;for(;!(a&8388608);)a<<=1,s-=8388608;a&=-8388609,s+=947912704,n[i]=a|s}for(let i=1024;i<2048;++i)n[i]=939524096+(i-1024<<13);for(let i=1;i<31;++i)r[i]=i<<23;r[31]=1199570944,r[32]=2147483648;for(let i=33;i<63;++i)r[i]=2147483648+(i-32<<23);r[63]=3347054592;for(let i=1;i<64;++i)i!==32&&(o[i]=1024);return{baseTable:e,shiftTable:t,mantissaTable:n,exponentTable:r,offsetTable:o}}function V(e,t=[],n=0){let r=Math.fround(e),o=e-r;return t[n]=r,t[n+1]=o,t}function Q(e){return e-Math.fround(e)}function ee(e){let t=new Float32Array(32);for(let n=0;n<4;++n)for(let r=0;r<4;++r){let o=n*4+r;V(e[r*4+n],t,o*2)}return t}var Wr=`fn random(scale: vec3f, seed: f32) -> f32 {
|
|
99
105
|
return fract(sin(dot(scale + vec3f(seed), vec3f(12.9898, 78.233, 151.7182))) * 43758.5453 + seed);
|
|
100
106
|
}
|
|
101
|
-
`,
|
|
107
|
+
`,jr=`float random(vec3 scale, float seed) {
|
|
102
108
|
/* use the fragment position for a different seed per-pixel */
|
|
103
109
|
return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);
|
|
104
110
|
}
|
|
105
|
-
`,
|
|
111
|
+
`,fn={name:"random",source:Wr,fs:jr};var $r=`#ifdef LUMA_FP32_TAN_PRECISION_WORKAROUND
|
|
106
112
|
|
|
107
113
|
// All these functions are for substituting tan() function from Intel GPU only
|
|
108
114
|
const float TWO_PI = 6.2831854820251465;
|
|
@@ -252,9 +258,10 @@ float tan_fp32(float a) {
|
|
|
252
258
|
return tan(a);
|
|
253
259
|
#endif
|
|
254
260
|
}
|
|
255
|
-
`,
|
|
261
|
+
`,pn={name:"fp32",vs:$r};var We=`
|
|
256
262
|
uniform fp64arithmeticUniforms {
|
|
257
263
|
uniform float ONE;
|
|
264
|
+
uniform float SPLIT;
|
|
258
265
|
} fp64;
|
|
259
266
|
|
|
260
267
|
/*
|
|
@@ -264,6 +271,12 @@ The purpose of this workaround is to prevent shader compilers from
|
|
|
264
271
|
optimizing away necessary arithmetic operations by swapping their sequences
|
|
265
272
|
or transform the equation to some 'equivalent' form.
|
|
266
273
|
|
|
274
|
+
These helpers implement Dekker/Veltkamp-style error tracking. If the compiler
|
|
275
|
+
folds constants or reassociates the arithmetic, the high/low split can stop
|
|
276
|
+
tracking the rounding error correctly. That failure mode tends to look fine in
|
|
277
|
+
simple coordinate setup, but then breaks down inside iterative arithmetic such
|
|
278
|
+
as fp64 Mandelbrot loops.
|
|
279
|
+
|
|
267
280
|
The method is to multiply an artifical variable, ONE, which will be known to
|
|
268
281
|
the compiler to be 1 only at runtime. The whole expression is then represented
|
|
269
282
|
as a polynomial with respective to ONE. In the coefficients of all terms, only one a
|
|
@@ -272,17 +285,23 @@ and one b should appear
|
|
|
272
285
|
err = (a + b) * ONE^6 - a * ONE^5 - (a + b) * ONE^4 + a * ONE^3 - b - (a + b) * ONE^2 + a * ONE
|
|
273
286
|
*/
|
|
274
287
|
|
|
275
|
-
|
|
276
|
-
vec2 split(float a) {
|
|
277
|
-
const float SPLIT = 4097.0;
|
|
278
|
-
float t = a * SPLIT;
|
|
288
|
+
float prevent_fp64_optimization(float value) {
|
|
279
289
|
#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)
|
|
280
|
-
|
|
281
|
-
float a_lo = a * fp64.ONE - a_hi;
|
|
290
|
+
return value + fp64.ONE * 0.0;
|
|
282
291
|
#else
|
|
283
|
-
|
|
284
|
-
float a_lo = a - a_hi;
|
|
292
|
+
return value;
|
|
285
293
|
#endif
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Divide float number to high and low floats to extend fraction bits
|
|
297
|
+
vec2 split(float a) {
|
|
298
|
+
// Keep SPLIT as a runtime uniform so the compiler cannot fold the Dekker
|
|
299
|
+
// split into a constant expression and reassociate the recovery steps.
|
|
300
|
+
float split = prevent_fp64_optimization(fp64.SPLIT);
|
|
301
|
+
float t = prevent_fp64_optimization(a * split);
|
|
302
|
+
float temp = t - a;
|
|
303
|
+
float a_hi = t - temp;
|
|
304
|
+
float a_lo = a - a_hi;
|
|
286
305
|
return vec2(a_hi, a_lo);
|
|
287
306
|
}
|
|
288
307
|
|
|
@@ -346,8 +365,26 @@ vec2 twoProd(float a, float b) {
|
|
|
346
365
|
float prod = a * b;
|
|
347
366
|
vec2 a_fp64 = split(a);
|
|
348
367
|
vec2 b_fp64 = split(b);
|
|
349
|
-
|
|
350
|
-
|
|
368
|
+
// twoProd is especially sensitive because mul_fp64 and div_fp64 both depend
|
|
369
|
+
// on the split terms and cross terms staying in the original evaluation
|
|
370
|
+
// order. If the compiler folds or reassociates them, the low part tends to
|
|
371
|
+
// collapse to zero or NaN on some drivers.
|
|
372
|
+
float highProduct = prevent_fp64_optimization(a_fp64.x * b_fp64.x);
|
|
373
|
+
float crossProduct1 = prevent_fp64_optimization(a_fp64.x * b_fp64.y);
|
|
374
|
+
float crossProduct2 = prevent_fp64_optimization(a_fp64.y * b_fp64.x);
|
|
375
|
+
float lowProduct = prevent_fp64_optimization(a_fp64.y * b_fp64.y);
|
|
376
|
+
#if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)
|
|
377
|
+
float err1 = (highProduct - prod) * fp64.ONE;
|
|
378
|
+
float err2 = crossProduct1 * fp64.ONE * fp64.ONE;
|
|
379
|
+
float err3 = crossProduct2 * fp64.ONE * fp64.ONE * fp64.ONE;
|
|
380
|
+
float err4 = lowProduct * fp64.ONE * fp64.ONE * fp64.ONE * fp64.ONE;
|
|
381
|
+
#else
|
|
382
|
+
float err1 = highProduct - prod;
|
|
383
|
+
float err2 = crossProduct1;
|
|
384
|
+
float err3 = crossProduct2;
|
|
385
|
+
float err4 = lowProduct;
|
|
386
|
+
#endif
|
|
387
|
+
float err = ((err1 + err2) + err3) + err4;
|
|
351
388
|
return vec2(prod, err);
|
|
352
389
|
}
|
|
353
390
|
|
|
@@ -420,7 +457,213 @@ vec2 sqrt_fp64(vec2 a) {
|
|
|
420
457
|
return sum_fp64(vec2(yn, 0.0), prod);
|
|
421
458
|
#endif
|
|
422
459
|
}
|
|
423
|
-
`;var
|
|
460
|
+
`;var hn=`struct Fp64ArithmeticUniforms {
|
|
461
|
+
ONE: f32,
|
|
462
|
+
SPLIT: f32,
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
@group(0) @binding(auto) var<uniform> fp64arithmetic : Fp64ArithmeticUniforms;
|
|
466
|
+
|
|
467
|
+
fn fp64_nan(seed: f32) -> f32 {
|
|
468
|
+
let nanBits = 0x7fc00000u | select(0u, 1u, seed < 0.0);
|
|
469
|
+
return bitcast<f32>(nanBits);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
fn fp64_runtime_zero() -> f32 {
|
|
473
|
+
return fp64arithmetic.ONE * 0.0;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
fn prevent_fp64_optimization(value: f32) -> f32 {
|
|
477
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
478
|
+
return value + fp64_runtime_zero();
|
|
479
|
+
#else
|
|
480
|
+
return value;
|
|
481
|
+
#endif
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
fn split(a: f32) -> vec2f {
|
|
485
|
+
let splitValue = prevent_fp64_optimization(fp64arithmetic.SPLIT + fp64_runtime_zero());
|
|
486
|
+
let t = prevent_fp64_optimization(a * splitValue);
|
|
487
|
+
let temp = prevent_fp64_optimization(t - a);
|
|
488
|
+
let aHi = prevent_fp64_optimization(t - temp);
|
|
489
|
+
let aLo = prevent_fp64_optimization(a - aHi);
|
|
490
|
+
return vec2f(aHi, aLo);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
fn split2(a: vec2f) -> vec2f {
|
|
494
|
+
var b = split(a.x);
|
|
495
|
+
b.y = b.y + a.y;
|
|
496
|
+
return b;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
fn quickTwoSum(a: f32, b: f32) -> vec2f {
|
|
500
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
501
|
+
let sum = prevent_fp64_optimization((a + b) * fp64arithmetic.ONE);
|
|
502
|
+
let err = prevent_fp64_optimization(b - (sum - a) * fp64arithmetic.ONE);
|
|
503
|
+
#else
|
|
504
|
+
let sum = prevent_fp64_optimization(a + b);
|
|
505
|
+
let err = prevent_fp64_optimization(b - (sum - a));
|
|
506
|
+
#endif
|
|
507
|
+
return vec2f(sum, err);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
fn twoSum(a: f32, b: f32) -> vec2f {
|
|
511
|
+
let s = prevent_fp64_optimization(a + b);
|
|
512
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
513
|
+
let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE);
|
|
514
|
+
let err =
|
|
515
|
+
prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) *
|
|
516
|
+
fp64arithmetic.ONE *
|
|
517
|
+
fp64arithmetic.ONE *
|
|
518
|
+
fp64arithmetic.ONE) +
|
|
519
|
+
prevent_fp64_optimization(b - v);
|
|
520
|
+
#else
|
|
521
|
+
let v = prevent_fp64_optimization(s - a);
|
|
522
|
+
let err = prevent_fp64_optimization(a - (s - v)) + prevent_fp64_optimization(b - v);
|
|
523
|
+
#endif
|
|
524
|
+
return vec2f(s, err);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
fn twoSub(a: f32, b: f32) -> vec2f {
|
|
528
|
+
let s = prevent_fp64_optimization(a - b);
|
|
529
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
530
|
+
let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE);
|
|
531
|
+
let err =
|
|
532
|
+
prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) *
|
|
533
|
+
fp64arithmetic.ONE *
|
|
534
|
+
fp64arithmetic.ONE *
|
|
535
|
+
fp64arithmetic.ONE) -
|
|
536
|
+
prevent_fp64_optimization(b + v);
|
|
537
|
+
#else
|
|
538
|
+
let v = prevent_fp64_optimization(s - a);
|
|
539
|
+
let err = prevent_fp64_optimization(a - (s - v)) - prevent_fp64_optimization(b + v);
|
|
540
|
+
#endif
|
|
541
|
+
return vec2f(s, err);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
fn twoSqr(a: f32) -> vec2f {
|
|
545
|
+
let prod = prevent_fp64_optimization(a * a);
|
|
546
|
+
let aFp64 = split(a);
|
|
547
|
+
let highProduct = prevent_fp64_optimization(aFp64.x * aFp64.x);
|
|
548
|
+
let crossProduct = prevent_fp64_optimization(2.0 * aFp64.x * aFp64.y);
|
|
549
|
+
let lowProduct = prevent_fp64_optimization(aFp64.y * aFp64.y);
|
|
550
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
551
|
+
let err =
|
|
552
|
+
(prevent_fp64_optimization(highProduct - prod) * fp64arithmetic.ONE +
|
|
553
|
+
crossProduct * fp64arithmetic.ONE * fp64arithmetic.ONE) +
|
|
554
|
+
lowProduct * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE;
|
|
555
|
+
#else
|
|
556
|
+
let err = ((prevent_fp64_optimization(highProduct - prod) + crossProduct) + lowProduct);
|
|
557
|
+
#endif
|
|
558
|
+
return vec2f(prod, err);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
fn twoProd(a: f32, b: f32) -> vec2f {
|
|
562
|
+
let prod = prevent_fp64_optimization(a * b);
|
|
563
|
+
let aFp64 = split(a);
|
|
564
|
+
let bFp64 = split(b);
|
|
565
|
+
let highProduct = prevent_fp64_optimization(aFp64.x * bFp64.x);
|
|
566
|
+
let crossProduct1 = prevent_fp64_optimization(aFp64.x * bFp64.y);
|
|
567
|
+
let crossProduct2 = prevent_fp64_optimization(aFp64.y * bFp64.x);
|
|
568
|
+
let lowProduct = prevent_fp64_optimization(aFp64.y * bFp64.y);
|
|
569
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
570
|
+
let err1 = (highProduct - prod) * fp64arithmetic.ONE;
|
|
571
|
+
let err2 = crossProduct1 * fp64arithmetic.ONE * fp64arithmetic.ONE;
|
|
572
|
+
let err3 = crossProduct2 * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE;
|
|
573
|
+
let err4 =
|
|
574
|
+
lowProduct *
|
|
575
|
+
fp64arithmetic.ONE *
|
|
576
|
+
fp64arithmetic.ONE *
|
|
577
|
+
fp64arithmetic.ONE *
|
|
578
|
+
fp64arithmetic.ONE;
|
|
579
|
+
#else
|
|
580
|
+
let err1 = highProduct - prod;
|
|
581
|
+
let err2 = crossProduct1;
|
|
582
|
+
let err3 = crossProduct2;
|
|
583
|
+
let err4 = lowProduct;
|
|
584
|
+
#endif
|
|
585
|
+
let err12InputA = prevent_fp64_optimization(err1);
|
|
586
|
+
let err12InputB = prevent_fp64_optimization(err2);
|
|
587
|
+
let err12 = prevent_fp64_optimization(err12InputA + err12InputB);
|
|
588
|
+
let err123InputA = prevent_fp64_optimization(err12);
|
|
589
|
+
let err123InputB = prevent_fp64_optimization(err3);
|
|
590
|
+
let err123 = prevent_fp64_optimization(err123InputA + err123InputB);
|
|
591
|
+
let err1234InputA = prevent_fp64_optimization(err123);
|
|
592
|
+
let err1234InputB = prevent_fp64_optimization(err4);
|
|
593
|
+
let err = prevent_fp64_optimization(err1234InputA + err1234InputB);
|
|
594
|
+
return vec2f(prod, err);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
fn sum_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
598
|
+
var s = twoSum(a.x, b.x);
|
|
599
|
+
let t = twoSum(a.y, b.y);
|
|
600
|
+
s.y = prevent_fp64_optimization(s.y + t.x);
|
|
601
|
+
s = quickTwoSum(s.x, s.y);
|
|
602
|
+
s.y = prevent_fp64_optimization(s.y + t.y);
|
|
603
|
+
s = quickTwoSum(s.x, s.y);
|
|
604
|
+
return s;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
fn sub_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
608
|
+
var s = twoSub(a.x, b.x);
|
|
609
|
+
let t = twoSub(a.y, b.y);
|
|
610
|
+
s.y = prevent_fp64_optimization(s.y + t.x);
|
|
611
|
+
s = quickTwoSum(s.x, s.y);
|
|
612
|
+
s.y = prevent_fp64_optimization(s.y + t.y);
|
|
613
|
+
s = quickTwoSum(s.x, s.y);
|
|
614
|
+
return s;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
fn mul_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
618
|
+
var prod = twoProd(a.x, b.x);
|
|
619
|
+
let crossProduct1 = prevent_fp64_optimization(a.x * b.y);
|
|
620
|
+
prod.y = prevent_fp64_optimization(prod.y + crossProduct1);
|
|
621
|
+
#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND
|
|
622
|
+
prod = split2(prod);
|
|
623
|
+
#endif
|
|
624
|
+
prod = quickTwoSum(prod.x, prod.y);
|
|
625
|
+
let crossProduct2 = prevent_fp64_optimization(a.y * b.x);
|
|
626
|
+
prod.y = prevent_fp64_optimization(prod.y + crossProduct2);
|
|
627
|
+
#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND
|
|
628
|
+
prod = split2(prod);
|
|
629
|
+
#endif
|
|
630
|
+
prod = quickTwoSum(prod.x, prod.y);
|
|
631
|
+
return prod;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
fn div_fp64(a: vec2f, b: vec2f) -> vec2f {
|
|
635
|
+
let xn = prevent_fp64_optimization(1.0 / b.x);
|
|
636
|
+
let yn = mul_fp64(a, vec2f(xn, fp64_runtime_zero()));
|
|
637
|
+
let diff = prevent_fp64_optimization(sub_fp64(a, mul_fp64(b, yn)).x);
|
|
638
|
+
let prod = twoProd(xn, diff);
|
|
639
|
+
return sum_fp64(yn, prod);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
fn sqrt_fp64(a: vec2f) -> vec2f {
|
|
643
|
+
if (a.x == 0.0 && a.y == 0.0) {
|
|
644
|
+
return vec2f(0.0, 0.0);
|
|
645
|
+
}
|
|
646
|
+
if (a.x < 0.0) {
|
|
647
|
+
let nanValue = fp64_nan(a.x);
|
|
648
|
+
return vec2f(nanValue, nanValue);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
let x = prevent_fp64_optimization(1.0 / sqrt(a.x));
|
|
652
|
+
let yn = prevent_fp64_optimization(a.x * x);
|
|
653
|
+
#ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
|
|
654
|
+
let ynSqr = twoSqr(yn) * fp64arithmetic.ONE;
|
|
655
|
+
#else
|
|
656
|
+
let ynSqr = twoSqr(yn);
|
|
657
|
+
#endif
|
|
658
|
+
let diff = prevent_fp64_optimization(sub_fp64(a, ynSqr).x);
|
|
659
|
+
let prod = twoProd(prevent_fp64_optimization(x * 0.5), diff);
|
|
660
|
+
#ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND
|
|
661
|
+
return sum_fp64(split(yn), prod);
|
|
662
|
+
#else
|
|
663
|
+
return sum_fp64(vec2f(yn, 0.0), prod);
|
|
664
|
+
#endif
|
|
665
|
+
}
|
|
666
|
+
`;var un=`const vec2 E_FP64 = vec2(2.7182817459106445e+00, 8.254840366817007e-08);
|
|
424
667
|
const vec2 LOG2_FP64 = vec2(0.6931471824645996e+00, -1.9046542121259336e-09);
|
|
425
668
|
const vec2 PI_FP64 = vec2(3.1415927410125732, -8.742278012618954e-8);
|
|
426
669
|
const vec2 TWO_PI_FP64 = vec2(6.2831854820251465, -1.7484556025237907e-7);
|
|
@@ -1089,7 +1332,7 @@ void mat4_vec4_mul_fp64(vec2 b[16], vec2 a[4], out vec2 out_val[4]) {
|
|
|
1089
1332
|
vec4_dot_fp64(a, tmp, out_val[i]);
|
|
1090
1333
|
}
|
|
1091
1334
|
}
|
|
1092
|
-
`;var
|
|
1335
|
+
`;var qr={ONE:1,SPLIT:4097},je={name:"fp64arithmetic",source:hn,fs:We,vs:We,defaultUniforms:qr,uniformTypes:{ONE:"f32",SPLIT:"f32"},fp64ify:V,fp64LowPart:Q,fp64ifyMatrix4:ee},gn={name:"fp64",vs:un,dependencies:[je],fp64ify:V,fp64LowPart:Q,fp64ifyMatrix4:ee};var Kr=[0,1,1,1],Yr=`uniform pickingUniforms {
|
|
1093
1336
|
float isActive;
|
|
1094
1337
|
float isAttribute;
|
|
1095
1338
|
float isHighlightActive;
|
|
@@ -1160,7 +1403,7 @@ void picking_setPickingAttribute(vec3 value) {
|
|
|
1160
1403
|
picking_vRGBcolor_Avalid.rgb = value;
|
|
1161
1404
|
}
|
|
1162
1405
|
}
|
|
1163
|
-
`,
|
|
1406
|
+
`,Xr=`uniform pickingUniforms {
|
|
1164
1407
|
float isActive;
|
|
1165
1408
|
float isAttribute;
|
|
1166
1409
|
float isHighlightActive;
|
|
@@ -1216,12 +1459,12 @@ vec4 picking_filterColor(vec4 color) {
|
|
|
1216
1459
|
vec4 highlightColor = picking_filterHighlightColor(color);
|
|
1217
1460
|
return picking_filterPickingColor(highlightColor);
|
|
1218
1461
|
}
|
|
1219
|
-
`,
|
|
1462
|
+
`,mn={props:{},uniforms:{},name:"picking",uniformTypes:{isActive:"f32",isAttribute:"f32",isHighlightActive:"f32",useFloatColors:"f32",highlightedObjectColor:"vec3<f32>",highlightColor:"vec4<f32>"},defaultUniforms:{isActive:!1,isAttribute:!1,isHighlightActive:!1,useFloatColors:!0,highlightedObjectColor:[0,0,0],highlightColor:Kr},vs:Yr,fs:Xr,getUniforms:Zr};function Zr(e={},t){let n={};if(e.highlightedObjectColor!==void 0)if(e.highlightedObjectColor===null)n.isHighlightActive=!1;else{n.isHighlightActive=!0;let r=e.highlightedObjectColor.slice(0,3);n.highlightedObjectColor=r}if(e.highlightColor){let r=Array.from(e.highlightColor,o=>o/255);Number.isFinite(r[3])||(r[3]=1),n.highlightColor=r}return e.isActive!==void 0&&(n.isActive=Boolean(e.isActive),n.isAttribute=Boolean(e.isAttribute)),e.useFloatColors!==void 0&&(n.useFloatColors=Boolean(e.useFloatColors)),n}var te=20,Jr=`
|
|
1220
1463
|
struct skinUniforms {
|
|
1221
|
-
jointMatrix: array<mat4x4<f32>, ${
|
|
1464
|
+
jointMatrix: array<mat4x4<f32>, ${te}>,
|
|
1222
1465
|
};
|
|
1223
1466
|
|
|
1224
|
-
@
|
|
1467
|
+
@group(0) @binding(auto) var<uniform> skin: skinUniforms;
|
|
1225
1468
|
|
|
1226
1469
|
fn getSkinMatrix(weights: vec4f, joints: vec4u) -> mat4x4<f32> {
|
|
1227
1470
|
return (weights.x * skin.jointMatrix[joints.x])
|
|
@@ -1229,7 +1472,7 @@ fn getSkinMatrix(weights: vec4f, joints: vec4u) -> mat4x4<f32> {
|
|
|
1229
1472
|
+ (weights.z * skin.jointMatrix[joints.z])
|
|
1230
1473
|
+ (weights.w * skin.jointMatrix[joints.w]);
|
|
1231
1474
|
}
|
|
1232
|
-
`,
|
|
1475
|
+
`,Qr=`
|
|
1233
1476
|
uniform skinUniforms {
|
|
1234
1477
|
mat4 jointMatrix[SKIN_MAX_JOINTS];
|
|
1235
1478
|
} skin;
|
|
@@ -1241,7 +1484,7 @@ mat4 getSkinMatrix(vec4 weights, uvec4 joints) {
|
|
|
1241
1484
|
+ (weights.w * skin.jointMatrix[joints.w]);
|
|
1242
1485
|
}
|
|
1243
1486
|
|
|
1244
|
-
`,
|
|
1487
|
+
`,eo="",dn={props:{},uniforms:{},name:"skin",bindingLayout:[{name:"skin",group:0}],dependencies:[],source:Jr,vs:Qr,fs:eo,defines:{SKIN_MAX_JOINTS:te},getUniforms:(e={},t)=>{let{scenegraphsFromGLTF:n}=e;if(!n?.gltf?.skins?.[0])return{jointMatrix:[]};let{inverseBindMatrices:r,joints:o,skeleton:i}=n.gltf.skins[0],a=[],s=r.value.length/16;for(let f=0;f<s;f++){let h=r.value.subarray(f*16,f*16+16);a.push(new B(Array.from(h)))}let c=n.gltfNodeIndexToNodeMap.get(i),l={};c.preorderTraversal((f,{worldMatrix:h})=>{l[f.id]=h});let p=new Float32Array(te*16);for(let f=0;f<te;++f){let h=o[f];if(h===void 0)break;let g=l[n.gltfNodeIndexToNodeMap.get(h).id],_=a[f],m=new B().copy(g).multiplyRight(_),x=f*16;for(let d=0;d<16;d++)p[x+d]=m[d]}return{jointMatrix:p}},uniformTypes:{jointMatrix:["mat4x4<f32>",te]}};var bn=Ze(Ie(),1);var $e=`precision highp int;
|
|
1245
1488
|
|
|
1246
1489
|
// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))
|
|
1247
1490
|
struct AmbientLight {
|
|
@@ -1254,77 +1497,51 @@ struct PointLight {
|
|
|
1254
1497
|
vec3 attenuation; // 2nd order x:Constant-y:Linear-z:Exponential
|
|
1255
1498
|
};
|
|
1256
1499
|
|
|
1500
|
+
struct SpotLight {
|
|
1501
|
+
vec3 color;
|
|
1502
|
+
vec3 position;
|
|
1503
|
+
vec3 direction;
|
|
1504
|
+
vec3 attenuation;
|
|
1505
|
+
vec2 coneCos;
|
|
1506
|
+
};
|
|
1507
|
+
|
|
1257
1508
|
struct DirectionalLight {
|
|
1258
1509
|
vec3 color;
|
|
1259
1510
|
vec3 direction;
|
|
1260
1511
|
};
|
|
1261
1512
|
|
|
1513
|
+
struct UniformLight {
|
|
1514
|
+
vec3 color;
|
|
1515
|
+
vec3 position;
|
|
1516
|
+
vec3 direction;
|
|
1517
|
+
vec3 attenuation;
|
|
1518
|
+
vec2 coneCos;
|
|
1519
|
+
};
|
|
1520
|
+
|
|
1262
1521
|
uniform lightingUniforms {
|
|
1263
1522
|
int enabled;
|
|
1264
|
-
int lightType;
|
|
1265
|
-
|
|
1266
1523
|
int directionalLightCount;
|
|
1267
1524
|
int pointLightCount;
|
|
1268
|
-
|
|
1525
|
+
int spotLightCount;
|
|
1269
1526
|
vec3 ambientColor;
|
|
1270
|
-
|
|
1271
|
-
vec3 lightColor0;
|
|
1272
|
-
vec3 lightPosition0;
|
|
1273
|
-
vec3 lightDirection0;
|
|
1274
|
-
vec3 lightAttenuation0;
|
|
1275
|
-
|
|
1276
|
-
vec3 lightColor1;
|
|
1277
|
-
vec3 lightPosition1;
|
|
1278
|
-
vec3 lightDirection1;
|
|
1279
|
-
vec3 lightAttenuation1;
|
|
1280
|
-
|
|
1281
|
-
vec3 lightColor2;
|
|
1282
|
-
vec3 lightPosition2;
|
|
1283
|
-
vec3 lightDirection2;
|
|
1284
|
-
vec3 lightAttenuation2;
|
|
1285
|
-
|
|
1286
|
-
vec3 lightColor3;
|
|
1287
|
-
vec3 lightPosition3;
|
|
1288
|
-
vec3 lightDirection3;
|
|
1289
|
-
vec3 lightAttenuation3;
|
|
1290
|
-
|
|
1291
|
-
vec3 lightColor4;
|
|
1292
|
-
vec3 lightPosition4;
|
|
1293
|
-
vec3 lightDirection4;
|
|
1294
|
-
vec3 lightAttenuation4;
|
|
1527
|
+
UniformLight lights[5];
|
|
1295
1528
|
} lighting;
|
|
1296
1529
|
|
|
1297
1530
|
PointLight lighting_getPointLight(int index) {
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
case 3:
|
|
1306
|
-
return PointLight(lighting.lightColor3, lighting.lightPosition3, lighting.lightAttenuation3);
|
|
1307
|
-
case 4:
|
|
1308
|
-
default:
|
|
1309
|
-
return PointLight(lighting.lightColor4, lighting.lightPosition4, lighting.lightAttenuation4);
|
|
1310
|
-
}
|
|
1531
|
+
UniformLight light = lighting.lights[index];
|
|
1532
|
+
return PointLight(light.color, light.position, light.attenuation);
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
SpotLight lighting_getSpotLight(int index) {
|
|
1536
|
+
UniformLight light = lighting.lights[lighting.pointLightCount + index];
|
|
1537
|
+
return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos);
|
|
1311
1538
|
}
|
|
1312
1539
|
|
|
1313
1540
|
DirectionalLight lighting_getDirectionalLight(int index) {
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);
|
|
1319
|
-
case 2:
|
|
1320
|
-
return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);
|
|
1321
|
-
case 3:
|
|
1322
|
-
return DirectionalLight(lighting.lightColor3, lighting.lightDirection3);
|
|
1323
|
-
case 4:
|
|
1324
|
-
default:
|
|
1325
|
-
return DirectionalLight(lighting.lightColor4, lighting.lightDirection4);
|
|
1326
|
-
}
|
|
1327
|
-
}
|
|
1541
|
+
UniformLight light =
|
|
1542
|
+
lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index];
|
|
1543
|
+
return DirectionalLight(light.color, light.direction);
|
|
1544
|
+
}
|
|
1328
1545
|
|
|
1329
1546
|
float getPointLightAttenuation(PointLight pointLight, float distance) {
|
|
1330
1547
|
return pointLight.attenuation.x
|
|
@@ -1332,8 +1549,22 @@ float getPointLightAttenuation(PointLight pointLight, float distance) {
|
|
|
1332
1549
|
+ pointLight.attenuation.z * distance * distance;
|
|
1333
1550
|
}
|
|
1334
1551
|
|
|
1552
|
+
float getSpotLightAttenuation(SpotLight spotLight, vec3 positionWorldspace) {
|
|
1553
|
+
vec3 light_direction = normalize(positionWorldspace - spotLight.position);
|
|
1554
|
+
float coneFactor = smoothstep(
|
|
1555
|
+
spotLight.coneCos.y,
|
|
1556
|
+
spotLight.coneCos.x,
|
|
1557
|
+
dot(normalize(spotLight.direction), light_direction)
|
|
1558
|
+
);
|
|
1559
|
+
float distanceAttenuation = getPointLightAttenuation(
|
|
1560
|
+
PointLight(spotLight.color, spotLight.position, spotLight.attenuation),
|
|
1561
|
+
distance(spotLight.position, positionWorldspace)
|
|
1562
|
+
);
|
|
1563
|
+
return distanceAttenuation / max(coneFactor, 0.0001);
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1335
1566
|
// #endif
|
|
1336
|
-
`;var
|
|
1567
|
+
`;var _n=`// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))
|
|
1337
1568
|
const MAX_LIGHTS: i32 = 5;
|
|
1338
1569
|
|
|
1339
1570
|
struct AmbientLight {
|
|
@@ -1346,95 +1577,86 @@ struct PointLight {
|
|
|
1346
1577
|
attenuation: vec3<f32>, // 2nd order x:Constant-y:Linear-z:Exponential
|
|
1347
1578
|
};
|
|
1348
1579
|
|
|
1580
|
+
struct SpotLight {
|
|
1581
|
+
color: vec3<f32>,
|
|
1582
|
+
position: vec3<f32>,
|
|
1583
|
+
direction: vec3<f32>,
|
|
1584
|
+
attenuation: vec3<f32>,
|
|
1585
|
+
coneCos: vec2<f32>,
|
|
1586
|
+
};
|
|
1587
|
+
|
|
1349
1588
|
struct DirectionalLight {
|
|
1350
1589
|
color: vec3<f32>,
|
|
1351
1590
|
direction: vec3<f32>,
|
|
1352
1591
|
};
|
|
1353
1592
|
|
|
1593
|
+
struct UniformLight {
|
|
1594
|
+
color: vec3<f32>,
|
|
1595
|
+
position: vec3<f32>,
|
|
1596
|
+
direction: vec3<f32>,
|
|
1597
|
+
attenuation: vec3<f32>,
|
|
1598
|
+
coneCos: vec2<f32>,
|
|
1599
|
+
};
|
|
1600
|
+
|
|
1354
1601
|
struct lightingUniforms {
|
|
1355
1602
|
enabled: i32,
|
|
1356
|
-
lightType: i32,
|
|
1357
|
-
|
|
1358
1603
|
directionalLightCount: i32,
|
|
1359
1604
|
pointLightCount: i32,
|
|
1360
|
-
|
|
1605
|
+
spotLightCount: i32,
|
|
1361
1606
|
ambientColor: vec3<f32>,
|
|
1362
|
-
|
|
1363
|
-
lightColor0: vec3<f32>,
|
|
1364
|
-
lightPosition0: vec3<f32>,
|
|
1365
|
-
lightDirection0: vec3<f32>,
|
|
1366
|
-
lightAttenuation0: vec3<f32>,
|
|
1367
|
-
|
|
1368
|
-
lightColor1: vec3<f32>,
|
|
1369
|
-
lightPosition1: vec3<f32>,
|
|
1370
|
-
lightDirection1: vec3<f32>,
|
|
1371
|
-
lightAttenuation1: vec3<f32>,
|
|
1372
|
-
|
|
1373
|
-
lightColor2: vec3<f32>,
|
|
1374
|
-
lightPosition2: vec3<f32>,
|
|
1375
|
-
lightDirection2: vec3<f32>,
|
|
1376
|
-
lightAttenuation2: vec3<f32>,
|
|
1377
|
-
|
|
1378
|
-
lightColor3: vec3<f32>,
|
|
1379
|
-
lightPosition3: vec3<f32>,
|
|
1380
|
-
lightDirection3: vec3<f32>,
|
|
1381
|
-
lightAttenuation3: vec3<f32>,
|
|
1382
|
-
|
|
1383
|
-
lightColor4: vec3<f32>,
|
|
1384
|
-
lightPosition4: vec3<f32>,
|
|
1385
|
-
lightDirection4: vec3<f32>,
|
|
1386
|
-
lightAttenuation4: vec3<f32>,
|
|
1607
|
+
lights: array<UniformLight, 5>,
|
|
1387
1608
|
};
|
|
1388
1609
|
|
|
1389
|
-
|
|
1390
|
-
@binding(1) @group(0) var<uniform> lighting : lightingUniforms;
|
|
1610
|
+
@group(2) @binding(auto) var<uniform> lighting : lightingUniforms;
|
|
1391
1611
|
|
|
1392
1612
|
fn lighting_getPointLight(index: i32) -> PointLight {
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
case 2: {
|
|
1401
|
-
return PointLight(lighting.lightColor2, lighting.lightPosition2, lighting.lightAttenuation2);
|
|
1402
|
-
}
|
|
1403
|
-
case 3: {
|
|
1404
|
-
return PointLight(lighting.lightColor3, lighting.lightPosition3, lighting.lightAttenuation3);
|
|
1405
|
-
}
|
|
1406
|
-
case 4, default: {
|
|
1407
|
-
return PointLight(lighting.lightColor4, lighting.lightPosition4, lighting.lightAttenuation4);
|
|
1408
|
-
}
|
|
1409
|
-
}
|
|
1613
|
+
let light = lighting.lights[index];
|
|
1614
|
+
return PointLight(light.color, light.position, light.attenuation);
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
fn lighting_getSpotLight(index: i32) -> SpotLight {
|
|
1618
|
+
let light = lighting.lights[lighting.pointLightCount + index];
|
|
1619
|
+
return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos);
|
|
1410
1620
|
}
|
|
1411
1621
|
|
|
1412
1622
|
fn lighting_getDirectionalLight(index: i32) -> DirectionalLight {
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
}
|
|
1417
|
-
case 1: {
|
|
1418
|
-
return DirectionalLight(lighting.lightColor1, lighting.lightDirection1);
|
|
1419
|
-
}
|
|
1420
|
-
case 2: {
|
|
1421
|
-
return DirectionalLight(lighting.lightColor2, lighting.lightDirection2);
|
|
1422
|
-
}
|
|
1423
|
-
case 3: {
|
|
1424
|
-
return DirectionalLight(lighting.lightColor3, lighting.lightDirection3);
|
|
1425
|
-
}
|
|
1426
|
-
case 4, default: {
|
|
1427
|
-
return DirectionalLight(lighting.lightColor4, lighting.lightDirection4);
|
|
1428
|
-
}
|
|
1429
|
-
}
|
|
1430
|
-
}
|
|
1623
|
+
let light = lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index];
|
|
1624
|
+
return DirectionalLight(light.color, light.direction);
|
|
1625
|
+
}
|
|
1431
1626
|
|
|
1432
1627
|
fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
|
|
1433
1628
|
return pointLight.attenuation.x
|
|
1434
1629
|
+ pointLight.attenuation.y * distance
|
|
1435
1630
|
+ pointLight.attenuation.z * distance * distance;
|
|
1436
1631
|
}
|
|
1437
|
-
|
|
1632
|
+
|
|
1633
|
+
fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>) -> f32 {
|
|
1634
|
+
let lightDirection = normalize(positionWorldspace - spotLight.position);
|
|
1635
|
+
let coneFactor = smoothstep(
|
|
1636
|
+
spotLight.coneCos.y,
|
|
1637
|
+
spotLight.coneCos.x,
|
|
1638
|
+
dot(normalize(spotLight.direction), lightDirection)
|
|
1639
|
+
);
|
|
1640
|
+
let distanceAttenuation = getPointLightAttenuation(
|
|
1641
|
+
PointLight(spotLight.color, spotLight.position, spotLight.attenuation),
|
|
1642
|
+
distance(spotLight.position, positionWorldspace)
|
|
1643
|
+
);
|
|
1644
|
+
return distanceAttenuation / max(coneFactor, 0.0001);
|
|
1645
|
+
}
|
|
1646
|
+
`;var U=5,to=255,no={color:"vec3<f32>",position:"vec3<f32>",direction:"vec3<f32>",attenuation:"vec3<f32>",coneCos:"vec2<f32>"},F={props:{},uniforms:{},name:"lighting",defines:{},uniformTypes:{enabled:"i32",directionalLightCount:"i32",pointLightCount:"i32",spotLightCount:"i32",ambientColor:"vec3<f32>",lights:[no,U]},defaultUniforms:Me(),bindingLayout:[{name:"lighting",group:2}],firstBindingSlot:0,source:_n,vs:$e,fs:$e,getUniforms:ro};function ro(e,t={}){if(e=e&&{...e},!e)return Me();e.lights&&(e={...e,...io(e.lights),lights:void 0});let{ambientLight:n,pointLights:r,spotLights:o,directionalLights:i}=e||{};if(!(n||r&&r.length>0||o&&o.length>0||i&&i.length>0))return{...Me(),enabled:0};let s={...Me(),...oo({ambientLight:n,pointLights:r,spotLights:o,directionalLights:i})};return e.enabled!==void 0&&(s.enabled=e.enabled?1:0),s}function oo({ambientLight:e,pointLights:t=[],spotLights:n=[],directionalLights:r=[]}){let o=vn(),i=0,a=0,s=0,c=0;for(let l of t){if(i>=U)break;o[i]={...o[i],color:xe(l),position:l.position,attenuation:l.attenuation||[1,0,0]},i++,a++}for(let l of n){if(i>=U)break;o[i]={...o[i],color:xe(l),position:l.position,direction:l.direction,attenuation:l.attenuation||[1,0,0],coneCos:so(l)},i++,s++}for(let l of r){if(i>=U)break;o[i]={...o[i],color:xe(l),direction:l.direction},i++,c++}return t.length+n.length+r.length>U&&bn.log.warn(`MAX_LIGHTS exceeded, truncating to ${U}`)(),{ambientColor:xe(e),directionalLightCount:c,pointLightCount:a,spotLightCount:s,lights:o}}function io(e){let t={pointLights:[],spotLights:[],directionalLights:[]};for(let n of e||[])switch(n.type){case"ambient":t.ambientLight=n;break;case"directional":t.directionalLights?.push(n);break;case"point":t.pointLights?.push(n);break;case"spot":t.spotLights?.push(n);break;default:}return t}function xe(e={}){let{color:t=[0,0,0],intensity:n=1}=e;return t.map(r=>r*n/to)}function Me(){return{enabled:1,directionalLightCount:0,pointLightCount:0,spotLightCount:0,ambientColor:[.1,.1,.1],lights:vn()}}function vn(){return Array.from({length:U},()=>ao())}function ao(){return{color:[1,1,1],position:[1,1,2],direction:[1,1,1],attenuation:[1,0,0],coneCos:[1,0]}}function so(e){let t=e.innerConeAngle??0,n=e.outerConeAngle??Math.PI/4;return[Math.cos(t),Math.cos(n)]}var co=`#ifdef USE_IBL
|
|
1647
|
+
@group(2) @binding(auto) var pbr_diffuseEnvSampler: texture_cube<f32>;
|
|
1648
|
+
@group(2) @binding(auto) var pbr_diffuseEnvSamplerSampler: sampler;
|
|
1649
|
+
@group(2) @binding(auto) var pbr_specularEnvSampler: texture_cube<f32>;
|
|
1650
|
+
@group(2) @binding(auto) var pbr_specularEnvSamplerSampler: sampler;
|
|
1651
|
+
@group(2) @binding(auto) var pbr_brdfLUT: texture_2d<f32>;
|
|
1652
|
+
@group(2) @binding(auto) var pbr_brdfLUTSampler: sampler;
|
|
1653
|
+
#endif
|
|
1654
|
+
`,Sn=`#ifdef USE_IBL
|
|
1655
|
+
uniform samplerCube pbr_diffuseEnvSampler;
|
|
1656
|
+
uniform samplerCube pbr_specularEnvSampler;
|
|
1657
|
+
uniform sampler2D pbr_brdfLUT;
|
|
1658
|
+
#endif
|
|
1659
|
+
`,Le={name:"ibl",firstBindingSlot:32,bindingLayout:[{name:"pbr_diffuseEnvSampler",group:2},{name:"pbr_specularEnvSampler",group:2},{name:"pbr_brdfLUT",group:2}],source:co,vs:Sn,fs:Sn};var lo=`
|
|
1438
1660
|
struct dirlightUniforms {
|
|
1439
1661
|
lightDirection: vec3<f32>,
|
|
1440
1662
|
};
|
|
@@ -1445,7 +1667,7 @@ struct DirlightInputs {
|
|
|
1445
1667
|
normal: DirlightNormal,
|
|
1446
1668
|
};
|
|
1447
1669
|
|
|
1448
|
-
@
|
|
1670
|
+
@group(2) @binding(auto) var<uniform> dirlight : dirlightUniforms;
|
|
1449
1671
|
|
|
1450
1672
|
// For vertex
|
|
1451
1673
|
fn dirlight_setNormal(normal: vec3<f32>) -> DirlightNormal {
|
|
@@ -1460,12 +1682,12 @@ fn dirlight_filterColor(color: vec4<f32>, inputs: DirlightInputs) -> vec4<f32> {
|
|
|
1460
1682
|
let d: f32 = abs(dot(inputs.normal, normalize(lightDirection)));
|
|
1461
1683
|
return vec4<f32>(color.rgb * d, color.a);
|
|
1462
1684
|
}
|
|
1463
|
-
`,
|
|
1685
|
+
`,fo=`out vec3 dirlight_vNormal;
|
|
1464
1686
|
|
|
1465
1687
|
void dirlight_setNormal(vec3 normal) {
|
|
1466
1688
|
dirlight_vNormal = normalize(normal);
|
|
1467
1689
|
}
|
|
1468
|
-
`,
|
|
1690
|
+
`,po=`uniform dirlightUniforms {
|
|
1469
1691
|
vec3 lightDirection;
|
|
1470
1692
|
} dirlight;
|
|
1471
1693
|
|
|
@@ -1476,15 +1698,134 @@ vec4 dirlight_filterColor(vec4 color) {
|
|
|
1476
1698
|
float d = abs(dot(dirlight_vNormal, normalize(dirlight.lightDirection)));
|
|
1477
1699
|
return vec4(color.rgb * d, color.a);
|
|
1478
1700
|
}
|
|
1479
|
-
`,
|
|
1701
|
+
`,qe={props:{},uniforms:{},name:"dirlight",bindingLayout:[{name:"dirlight",group:2}],firstBindingSlot:16,dependencies:[],source:lo,vs:fo,fs:po,uniformTypes:{lightDirection:"vec3<f32>"},defaultUniforms:{lightDirection:[1,1,2]},getUniforms:ho};function ho(e=qe.defaultUniforms){let t={};return e.lightDirection&&(t.lightDirection=e.lightDirection),t}var xn=`struct lambertMaterialUniforms {
|
|
1702
|
+
unlit: u32,
|
|
1703
|
+
ambient: f32,
|
|
1704
|
+
diffuse: f32,
|
|
1705
|
+
};
|
|
1706
|
+
|
|
1707
|
+
@group(3) @binding(auto) var<uniform> lambertMaterial : lambertMaterialUniforms;
|
|
1708
|
+
|
|
1709
|
+
fn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, normal_worldspace: vec3<f32>, color: vec3<f32>) -> vec3<f32> {
|
|
1710
|
+
let lambertian: f32 = max(dot(light_direction, normal_worldspace), 0.0);
|
|
1711
|
+
return lambertian * lambertMaterial.diffuse * surfaceColor * color;
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1714
|
+
fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32> {
|
|
1715
|
+
var lightColor: vec3<f32> = surfaceColor;
|
|
1716
|
+
|
|
1717
|
+
if (lambertMaterial.unlit != 0u) {
|
|
1718
|
+
return surfaceColor;
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
if (lighting.enabled == 0) {
|
|
1722
|
+
return lightColor;
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
lightColor = lambertMaterial.ambient * surfaceColor * lighting.ambientColor;
|
|
1726
|
+
|
|
1727
|
+
for (var i: i32 = 0; i < lighting.pointLightCount; i++) {
|
|
1728
|
+
let pointLight: PointLight = lighting_getPointLight(i);
|
|
1729
|
+
let light_position_worldspace: vec3<f32> = pointLight.position;
|
|
1730
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
1731
|
+
let light_attenuation = getPointLightAttenuation(
|
|
1732
|
+
pointLight,
|
|
1733
|
+
distance(light_position_worldspace, position_worldspace)
|
|
1734
|
+
);
|
|
1735
|
+
lightColor += lighting_getLightColor(
|
|
1736
|
+
surfaceColor,
|
|
1737
|
+
light_direction,
|
|
1738
|
+
normal_worldspace,
|
|
1739
|
+
pointLight.color / light_attenuation
|
|
1740
|
+
);
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
for (var i: i32 = 0; i < lighting.spotLightCount; i++) {
|
|
1744
|
+
let spotLight: SpotLight = lighting_getSpotLight(i);
|
|
1745
|
+
let light_position_worldspace: vec3<f32> = spotLight.position;
|
|
1746
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
1747
|
+
let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
1748
|
+
lightColor += lighting_getLightColor(
|
|
1749
|
+
surfaceColor,
|
|
1750
|
+
light_direction,
|
|
1751
|
+
normal_worldspace,
|
|
1752
|
+
spotLight.color / light_attenuation
|
|
1753
|
+
);
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {
|
|
1757
|
+
let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
|
|
1758
|
+
lightColor += lighting_getLightColor(
|
|
1759
|
+
surfaceColor,
|
|
1760
|
+
-directionalLight.direction,
|
|
1761
|
+
normal_worldspace,
|
|
1762
|
+
directionalLight.color
|
|
1763
|
+
);
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
return lightColor;
|
|
1767
|
+
}
|
|
1768
|
+
`;var Mn=`uniform lambertMaterialUniforms {
|
|
1769
|
+
uniform bool unlit;
|
|
1770
|
+
uniform float ambient;
|
|
1771
|
+
uniform float diffuse;
|
|
1772
|
+
} material;
|
|
1773
|
+
`,Ln=`uniform lambertMaterialUniforms {
|
|
1774
|
+
uniform bool unlit;
|
|
1775
|
+
uniform float ambient;
|
|
1776
|
+
uniform float diffuse;
|
|
1777
|
+
} material;
|
|
1778
|
+
|
|
1779
|
+
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 normal_worldspace, vec3 color) {
|
|
1780
|
+
float lambertian = max(dot(light_direction, normal_worldspace), 0.0);
|
|
1781
|
+
return lambertian * material.diffuse * surfaceColor * color;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) {
|
|
1785
|
+
vec3 lightColor = surfaceColor;
|
|
1786
|
+
|
|
1787
|
+
if (material.unlit) {
|
|
1788
|
+
return surfaceColor;
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
if (lighting.enabled == 0) {
|
|
1792
|
+
return lightColor;
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
lightColor = material.ambient * surfaceColor * lighting.ambientColor;
|
|
1796
|
+
|
|
1797
|
+
for (int i = 0; i < lighting.pointLightCount; i++) {
|
|
1798
|
+
PointLight pointLight = lighting_getPointLight(i);
|
|
1799
|
+
vec3 light_position_worldspace = pointLight.position;
|
|
1800
|
+
vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
|
|
1801
|
+
float light_attenuation = getPointLightAttenuation(pointLight, distance(light_position_worldspace, position_worldspace));
|
|
1802
|
+
lightColor += lighting_getLightColor(surfaceColor, light_direction, normal_worldspace, pointLight.color / light_attenuation);
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
for (int i = 0; i < lighting.spotLightCount; i++) {
|
|
1806
|
+
SpotLight spotLight = lighting_getSpotLight(i);
|
|
1807
|
+
vec3 light_position_worldspace = spotLight.position;
|
|
1808
|
+
vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
|
|
1809
|
+
float light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
1810
|
+
lightColor += lighting_getLightColor(surfaceColor, light_direction, normal_worldspace, spotLight.color / light_attenuation);
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
for (int i = 0; i < lighting.directionalLightCount; i++) {
|
|
1814
|
+
DirectionalLight directionalLight = lighting_getDirectionalLight(i);
|
|
1815
|
+
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, normal_worldspace, directionalLight.color);
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
return lightColor;
|
|
1819
|
+
}
|
|
1820
|
+
`;var Ke={name:"lambertMaterial",firstBindingSlot:0,bindingLayout:[{name:"lambertMaterial",group:3}],dependencies:[F],source:xn,vs:Mn,fs:Ln,defines:{LIGHTING_FRAGMENT:!0},uniformTypes:{unlit:"i32",ambient:"f32",diffuse:"f32"},defaultUniforms:{unlit:!1,ambient:.35,diffuse:.6},getUniforms(e){return{...Ke.defaultUniforms,...e}}};var Ae=`uniform phongMaterialUniforms {
|
|
1821
|
+
uniform bool unlit;
|
|
1480
1822
|
uniform float ambient;
|
|
1481
1823
|
uniform float diffuse;
|
|
1482
1824
|
uniform float shininess;
|
|
1483
1825
|
uniform vec3 specularColor;
|
|
1484
1826
|
} material;
|
|
1485
|
-
`,
|
|
1486
|
-
|
|
1487
|
-
uniform phongMaterialUniforms {
|
|
1827
|
+
`,Ee=`uniform phongMaterialUniforms {
|
|
1828
|
+
uniform bool unlit;
|
|
1488
1829
|
uniform float ambient;
|
|
1489
1830
|
uniform float diffuse;
|
|
1490
1831
|
uniform float shininess;
|
|
@@ -1506,6 +1847,10 @@ vec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 view_d
|
|
|
1506
1847
|
vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) {
|
|
1507
1848
|
vec3 lightColor = surfaceColor;
|
|
1508
1849
|
|
|
1850
|
+
if (material.unlit) {
|
|
1851
|
+
return surfaceColor;
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1509
1854
|
if (lighting.enabled == 0) {
|
|
1510
1855
|
return lightColor;
|
|
1511
1856
|
}
|
|
@@ -1521,22 +1866,30 @@ vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 positio
|
|
|
1521
1866
|
lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color / light_attenuation);
|
|
1522
1867
|
}
|
|
1523
1868
|
|
|
1524
|
-
int
|
|
1525
|
-
|
|
1869
|
+
for (int i = 0; i < lighting.spotLightCount; i++) {
|
|
1870
|
+
SpotLight spotLight = lighting_getSpotLight(i);
|
|
1871
|
+
vec3 light_position_worldspace = spotLight.position;
|
|
1872
|
+
vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
|
|
1873
|
+
float light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
1874
|
+
lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, spotLight.color / light_attenuation);
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
for (int i = 0; i < lighting.directionalLightCount; i++) {
|
|
1526
1878
|
DirectionalLight directionalLight = lighting_getDirectionalLight(i);
|
|
1527
1879
|
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
|
|
1528
1880
|
}
|
|
1529
1881
|
|
|
1530
1882
|
return lightColor;
|
|
1531
1883
|
}
|
|
1532
|
-
`;var
|
|
1884
|
+
`;var Re=`struct phongMaterialUniforms {
|
|
1885
|
+
unlit: u32,
|
|
1533
1886
|
ambient: f32,
|
|
1534
1887
|
diffuse: f32,
|
|
1535
1888
|
shininess: f32,
|
|
1536
1889
|
specularColor: vec3<f32>,
|
|
1537
1890
|
};
|
|
1538
1891
|
|
|
1539
|
-
@
|
|
1892
|
+
@group(3) @binding(auto) var<uniform> phongMaterial : phongMaterialUniforms;
|
|
1540
1893
|
|
|
1541
1894
|
fn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, view_direction: vec3<f32>, normal_worldspace: vec3<f32>, color: vec3<f32>) -> vec3<f32> {
|
|
1542
1895
|
let halfway_direction: vec3<f32> = normalize(light_direction + view_direction);
|
|
@@ -1553,6 +1906,10 @@ fn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, v
|
|
|
1553
1906
|
fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32> {
|
|
1554
1907
|
var lightColor: vec3<f32> = surfaceColor;
|
|
1555
1908
|
|
|
1909
|
+
if (phongMaterial.unlit != 0u) {
|
|
1910
|
+
return surfaceColor;
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1556
1913
|
if (lighting.enabled == 0) {
|
|
1557
1914
|
return lightColor;
|
|
1558
1915
|
}
|
|
@@ -1577,8 +1934,21 @@ fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, p
|
|
|
1577
1934
|
);
|
|
1578
1935
|
}
|
|
1579
1936
|
|
|
1580
|
-
|
|
1581
|
-
|
|
1937
|
+
for (var i: i32 = 0; i < lighting.spotLightCount; i++) {
|
|
1938
|
+
let spotLight: SpotLight = lighting_getSpotLight(i);
|
|
1939
|
+
let light_position_worldspace: vec3<f32> = spotLight.position;
|
|
1940
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
1941
|
+
let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
1942
|
+
lightColor += lighting_getLightColor(
|
|
1943
|
+
surfaceColor,
|
|
1944
|
+
light_direction,
|
|
1945
|
+
view_direction,
|
|
1946
|
+
normal_worldspace,
|
|
1947
|
+
spotLight.color / light_attenuation
|
|
1948
|
+
);
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {
|
|
1582
1952
|
let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
|
|
1583
1953
|
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
|
|
1584
1954
|
}
|
|
@@ -1610,15 +1980,28 @@ fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace
|
|
|
1610
1980
|
);
|
|
1611
1981
|
}
|
|
1612
1982
|
|
|
1613
|
-
|
|
1614
|
-
|
|
1983
|
+
for (var i: i32 = 0; i < lighting.spotLightCount; i++) {
|
|
1984
|
+
let spotLight: SpotLight = lighting_getSpotLight(i);
|
|
1985
|
+
let light_position_worldspace: vec3<f32> = spotLight.position;
|
|
1986
|
+
let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
|
|
1987
|
+
let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
|
|
1988
|
+
lightColor += lighting_getLightColor(
|
|
1989
|
+
surfaceColor,
|
|
1990
|
+
light_direction,
|
|
1991
|
+
view_direction,
|
|
1992
|
+
normal_worldspace,
|
|
1993
|
+
spotLight.color / light_attenuation
|
|
1994
|
+
);
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {
|
|
1615
1998
|
let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
|
|
1616
1999
|
lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
|
|
1617
2000
|
}
|
|
1618
2001
|
}
|
|
1619
2002
|
return lightColor;
|
|
1620
2003
|
}
|
|
1621
|
-
`;var
|
|
2004
|
+
`;var Ye={props:{},name:"gouraudMaterial",bindingLayout:[{name:"gouraudMaterial",group:3}],vs:Ee.replace("phongMaterial","gouraudMaterial"),fs:Ae.replace("phongMaterial","gouraudMaterial"),source:Re.replaceAll("phongMaterial","gouraudMaterial"),defines:{LIGHTING_VERTEX:!0},dependencies:[F],uniformTypes:{unlit:"i32",ambient:"f32",diffuse:"f32",shininess:"f32",specularColor:"vec3<f32>"},defaultUniforms:{unlit:!1,ambient:.35,diffuse:.6,shininess:32,specularColor:[.15,.15,.15]},getUniforms(e){let t={...e};return t.specularColor&&(t.specularColor=t.specularColor.map(n=>n/255)),{...Ye.defaultUniforms,...t}}};var Xe={name:"phongMaterial",firstBindingSlot:0,bindingLayout:[{name:"phongMaterial",group:3}],dependencies:[F],source:Re,vs:Ae,fs:Ee,defines:{LIGHTING_FRAGMENT:!0},uniformTypes:{unlit:"i32",ambient:"f32",diffuse:"f32",shininess:"f32",specularColor:"vec3<f32>"},defaultUniforms:{unlit:!1,ambient:.35,diffuse:.6,shininess:32,specularColor:[.15,.15,.15]},getUniforms(e){let t={...e};return t.specularColor&&(t.specularColor=t.specularColor.map(n=>n/255)),{...Xe.defaultUniforms,...t}}};var An=`out vec3 pbr_vPosition;
|
|
1622
2005
|
out vec2 pbr_vUV;
|
|
1623
2006
|
|
|
1624
2007
|
#ifdef HAS_NORMALS
|
|
@@ -1651,7 +2034,7 @@ void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, ve
|
|
|
1651
2034
|
pbr_vUV = vec2(0.,0.);
|
|
1652
2035
|
#endif
|
|
1653
2036
|
}
|
|
1654
|
-
`,
|
|
2037
|
+
`,En=`precision highp float;
|
|
1655
2038
|
|
|
1656
2039
|
uniform pbrMaterialUniforms {
|
|
1657
2040
|
// Material is unlit
|
|
@@ -1693,10 +2076,12 @@ uniform pbrMaterialUniforms {
|
|
|
1693
2076
|
float clearcoatFactor;
|
|
1694
2077
|
float clearcoatRoughnessFactor;
|
|
1695
2078
|
bool clearcoatMapEnabled;
|
|
2079
|
+
bool clearcoatRoughnessMapEnabled;
|
|
1696
2080
|
|
|
1697
2081
|
vec3 sheenColorFactor;
|
|
1698
2082
|
float sheenRoughnessFactor;
|
|
1699
2083
|
bool sheenColorMapEnabled;
|
|
2084
|
+
bool sheenRoughnessMapEnabled;
|
|
1700
2085
|
|
|
1701
2086
|
float iridescenceFactor;
|
|
1702
2087
|
float iridescenceIor;
|
|
@@ -1746,26 +2131,33 @@ uniform sampler2D pbr_specularIntensitySampler;
|
|
|
1746
2131
|
#ifdef HAS_TRANSMISSIONMAP
|
|
1747
2132
|
uniform sampler2D pbr_transmissionSampler;
|
|
1748
2133
|
#endif
|
|
2134
|
+
#ifdef HAS_THICKNESSMAP
|
|
2135
|
+
uniform sampler2D pbr_thicknessSampler;
|
|
2136
|
+
#endif
|
|
1749
2137
|
#ifdef HAS_CLEARCOATMAP
|
|
1750
2138
|
uniform sampler2D pbr_clearcoatSampler;
|
|
2139
|
+
#endif
|
|
2140
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
1751
2141
|
uniform sampler2D pbr_clearcoatRoughnessSampler;
|
|
1752
2142
|
#endif
|
|
2143
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
2144
|
+
uniform sampler2D pbr_clearcoatNormalSampler;
|
|
2145
|
+
#endif
|
|
1753
2146
|
#ifdef HAS_SHEENCOLORMAP
|
|
1754
2147
|
uniform sampler2D pbr_sheenColorSampler;
|
|
2148
|
+
#endif
|
|
2149
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
1755
2150
|
uniform sampler2D pbr_sheenRoughnessSampler;
|
|
1756
2151
|
#endif
|
|
1757
2152
|
#ifdef HAS_IRIDESCENCEMAP
|
|
1758
2153
|
uniform sampler2D pbr_iridescenceSampler;
|
|
1759
2154
|
#endif
|
|
2155
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
2156
|
+
uniform sampler2D pbr_iridescenceThicknessSampler;
|
|
2157
|
+
#endif
|
|
1760
2158
|
#ifdef HAS_ANISOTROPYMAP
|
|
1761
2159
|
uniform sampler2D pbr_anisotropySampler;
|
|
1762
2160
|
#endif
|
|
1763
|
-
#ifdef USE_IBL
|
|
1764
|
-
uniform samplerCube pbr_diffuseEnvSampler;
|
|
1765
|
-
uniform samplerCube pbr_specularEnvSampler;
|
|
1766
|
-
uniform sampler2D pbr_brdfLUT;
|
|
1767
|
-
#endif
|
|
1768
|
-
|
|
1769
2161
|
// Inputs from vertex shader
|
|
1770
2162
|
|
|
1771
2163
|
in vec3 pbr_vPosition;
|
|
@@ -1802,6 +2194,8 @@ struct PBRInfo {
|
|
|
1802
2194
|
const float M_PI = 3.141592653589793;
|
|
1803
2195
|
const float c_MinRoughness = 0.04;
|
|
1804
2196
|
|
|
2197
|
+
vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor);
|
|
2198
|
+
|
|
1805
2199
|
vec4 SRGBtoLINEAR(vec4 srgbIn)
|
|
1806
2200
|
{
|
|
1807
2201
|
#ifdef MANUAL_SRGB
|
|
@@ -1817,11 +2211,9 @@ vec4 SRGBtoLINEAR(vec4 srgbIn)
|
|
|
1817
2211
|
#endif //MANUAL_SRGB
|
|
1818
2212
|
}
|
|
1819
2213
|
|
|
1820
|
-
//
|
|
1821
|
-
|
|
1822
|
-
vec3 getNormal()
|
|
2214
|
+
// Build the tangent basis from interpolated attributes or screen-space derivatives.
|
|
2215
|
+
mat3 getTBN()
|
|
1823
2216
|
{
|
|
1824
|
-
// Retrieve the tangent space matrix
|
|
1825
2217
|
#ifndef HAS_TANGENTS
|
|
1826
2218
|
vec3 pos_dx = dFdx(pbr_vPosition);
|
|
1827
2219
|
vec3 pos_dy = dFdy(pbr_vPosition);
|
|
@@ -1842,17 +2234,38 @@ vec3 getNormal()
|
|
|
1842
2234
|
mat3 tbn = pbr_vTBN;
|
|
1843
2235
|
#endif
|
|
1844
2236
|
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
2237
|
+
return tbn;
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2240
|
+
// Find the normal for this fragment, pulling either from a predefined normal map
|
|
2241
|
+
// or from the interpolated mesh normal and tangent attributes.
|
|
2242
|
+
vec3 getMappedNormal(sampler2D normalSampler, mat3 tbn, float normalScale)
|
|
2243
|
+
{
|
|
2244
|
+
vec3 n = texture(normalSampler, pbr_vUV).rgb;
|
|
2245
|
+
return normalize(tbn * ((2.0 * n - 1.0) * vec3(normalScale, normalScale, 1.0)));
|
|
2246
|
+
}
|
|
2247
|
+
|
|
2248
|
+
vec3 getNormal(mat3 tbn)
|
|
2249
|
+
{
|
|
2250
|
+
#ifdef HAS_NORMALMAP
|
|
2251
|
+
vec3 n = getMappedNormal(pbr_normalSampler, tbn, pbrMaterial.normalScale);
|
|
2252
|
+
#else
|
|
2253
|
+
// The tbn matrix is linearly interpolated, so we need to re-normalize
|
|
2254
|
+
vec3 n = normalize(tbn[2].xyz);
|
|
2255
|
+
#endif
|
|
1852
2256
|
|
|
1853
2257
|
return n;
|
|
1854
2258
|
}
|
|
1855
2259
|
|
|
2260
|
+
vec3 getClearcoatNormal(mat3 tbn, vec3 baseNormal)
|
|
2261
|
+
{
|
|
2262
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
2263
|
+
return getMappedNormal(pbr_clearcoatNormalSampler, tbn, 1.0);
|
|
2264
|
+
#else
|
|
2265
|
+
return baseNormal;
|
|
2266
|
+
#endif
|
|
2267
|
+
}
|
|
2268
|
+
|
|
1856
2269
|
// Calculation of the lighting contribution from an optional Image Based Light source.
|
|
1857
2270
|
// Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
|
|
1858
2271
|
// See our README.md on Environment Maps [3] for additional discussion.
|
|
@@ -1928,6 +2341,169 @@ float microfacetDistribution(PBRInfo pbrInfo)
|
|
|
1928
2341
|
return roughnessSq / (M_PI * f * f);
|
|
1929
2342
|
}
|
|
1930
2343
|
|
|
2344
|
+
float maxComponent(vec3 value)
|
|
2345
|
+
{
|
|
2346
|
+
return max(max(value.r, value.g), value.b);
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2349
|
+
float getDielectricF0(float ior)
|
|
2350
|
+
{
|
|
2351
|
+
float clampedIor = max(ior, 1.0);
|
|
2352
|
+
float ratio = (clampedIor - 1.0) / (clampedIor + 1.0);
|
|
2353
|
+
return ratio * ratio;
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
vec2 normalizeDirection(vec2 direction)
|
|
2357
|
+
{
|
|
2358
|
+
float directionLength = length(direction);
|
|
2359
|
+
return directionLength > 0.0001 ? direction / directionLength : vec2(1.0, 0.0);
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
vec2 rotateDirection(vec2 direction, float rotation)
|
|
2363
|
+
{
|
|
2364
|
+
float s = sin(rotation);
|
|
2365
|
+
float c = cos(rotation);
|
|
2366
|
+
return vec2(direction.x * c - direction.y * s, direction.x * s + direction.y * c);
|
|
2367
|
+
}
|
|
2368
|
+
|
|
2369
|
+
vec3 getIridescenceTint(float iridescence, float thickness, float NdotV)
|
|
2370
|
+
{
|
|
2371
|
+
if (iridescence <= 0.0) {
|
|
2372
|
+
return vec3(1.0);
|
|
2373
|
+
}
|
|
2374
|
+
|
|
2375
|
+
float phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;
|
|
2376
|
+
vec3 thinFilmTint =
|
|
2377
|
+
0.5 + 0.5 * cos(vec3(phase, phase + 2.0943951, phase + 4.1887902));
|
|
2378
|
+
return mix(vec3(1.0), thinFilmTint, iridescence);
|
|
2379
|
+
}
|
|
2380
|
+
|
|
2381
|
+
vec3 getVolumeAttenuation(float thickness)
|
|
2382
|
+
{
|
|
2383
|
+
if (thickness <= 0.0) {
|
|
2384
|
+
return vec3(1.0);
|
|
2385
|
+
}
|
|
2386
|
+
|
|
2387
|
+
vec3 attenuationCoefficient =
|
|
2388
|
+
-log(max(pbrMaterial.attenuationColor, vec3(0.0001))) /
|
|
2389
|
+
max(pbrMaterial.attenuationDistance, 0.0001);
|
|
2390
|
+
return exp(-attenuationCoefficient * thickness);
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2393
|
+
PBRInfo createClearcoatPBRInfo(PBRInfo basePBRInfo, vec3 clearcoatNormal, float clearcoatRoughness)
|
|
2394
|
+
{
|
|
2395
|
+
float perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
2396
|
+
float alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
2397
|
+
float NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);
|
|
2398
|
+
|
|
2399
|
+
return PBRInfo(
|
|
2400
|
+
basePBRInfo.NdotL,
|
|
2401
|
+
NdotV,
|
|
2402
|
+
basePBRInfo.NdotH,
|
|
2403
|
+
basePBRInfo.LdotH,
|
|
2404
|
+
basePBRInfo.VdotH,
|
|
2405
|
+
perceptualRoughness,
|
|
2406
|
+
0.0,
|
|
2407
|
+
vec3(0.04),
|
|
2408
|
+
vec3(1.0),
|
|
2409
|
+
alphaRoughness,
|
|
2410
|
+
vec3(0.0),
|
|
2411
|
+
vec3(0.04),
|
|
2412
|
+
clearcoatNormal,
|
|
2413
|
+
basePBRInfo.v
|
|
2414
|
+
);
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2417
|
+
vec3 calculateClearcoatContribution(
|
|
2418
|
+
PBRInfo pbrInfo,
|
|
2419
|
+
vec3 lightColor,
|
|
2420
|
+
vec3 clearcoatNormal,
|
|
2421
|
+
float clearcoatFactor,
|
|
2422
|
+
float clearcoatRoughness
|
|
2423
|
+
) {
|
|
2424
|
+
if (clearcoatFactor <= 0.0) {
|
|
2425
|
+
return vec3(0.0);
|
|
2426
|
+
}
|
|
2427
|
+
|
|
2428
|
+
PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
2429
|
+
return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;
|
|
2430
|
+
}
|
|
2431
|
+
|
|
2432
|
+
#ifdef USE_IBL
|
|
2433
|
+
vec3 calculateClearcoatIBLContribution(
|
|
2434
|
+
PBRInfo pbrInfo,
|
|
2435
|
+
vec3 clearcoatNormal,
|
|
2436
|
+
vec3 reflection,
|
|
2437
|
+
float clearcoatFactor,
|
|
2438
|
+
float clearcoatRoughness
|
|
2439
|
+
) {
|
|
2440
|
+
if (clearcoatFactor <= 0.0) {
|
|
2441
|
+
return vec3(0.0);
|
|
2442
|
+
}
|
|
2443
|
+
|
|
2444
|
+
PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
2445
|
+
return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;
|
|
2446
|
+
}
|
|
2447
|
+
#endif
|
|
2448
|
+
|
|
2449
|
+
vec3 calculateSheenContribution(
|
|
2450
|
+
PBRInfo pbrInfo,
|
|
2451
|
+
vec3 lightColor,
|
|
2452
|
+
vec3 sheenColor,
|
|
2453
|
+
float sheenRoughness
|
|
2454
|
+
) {
|
|
2455
|
+
if (maxComponent(sheenColor) <= 0.0) {
|
|
2456
|
+
return vec3(0.0);
|
|
2457
|
+
}
|
|
2458
|
+
|
|
2459
|
+
float sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
|
|
2460
|
+
float sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);
|
|
2461
|
+
return pbrInfo.NdotL *
|
|
2462
|
+
lightColor *
|
|
2463
|
+
sheenColor *
|
|
2464
|
+
(0.25 + 0.75 * sheenFresnel) *
|
|
2465
|
+
sheenVisibility *
|
|
2466
|
+
(1.0 - pbrInfo.metalness);
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
float calculateAnisotropyBoost(
|
|
2470
|
+
PBRInfo pbrInfo,
|
|
2471
|
+
vec3 anisotropyTangent,
|
|
2472
|
+
float anisotropyStrength
|
|
2473
|
+
) {
|
|
2474
|
+
if (anisotropyStrength <= 0.0) {
|
|
2475
|
+
return 1.0;
|
|
2476
|
+
}
|
|
2477
|
+
|
|
2478
|
+
vec3 anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));
|
|
2479
|
+
float bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));
|
|
2480
|
+
return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2483
|
+
vec3 calculateMaterialLightColor(
|
|
2484
|
+
PBRInfo pbrInfo,
|
|
2485
|
+
vec3 lightColor,
|
|
2486
|
+
vec3 clearcoatNormal,
|
|
2487
|
+
float clearcoatFactor,
|
|
2488
|
+
float clearcoatRoughness,
|
|
2489
|
+
vec3 sheenColor,
|
|
2490
|
+
float sheenRoughness,
|
|
2491
|
+
vec3 anisotropyTangent,
|
|
2492
|
+
float anisotropyStrength
|
|
2493
|
+
) {
|
|
2494
|
+
float anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
2495
|
+
vec3 color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;
|
|
2496
|
+
color += calculateClearcoatContribution(
|
|
2497
|
+
pbrInfo,
|
|
2498
|
+
lightColor,
|
|
2499
|
+
clearcoatNormal,
|
|
2500
|
+
clearcoatFactor,
|
|
2501
|
+
clearcoatRoughness
|
|
2502
|
+
);
|
|
2503
|
+
color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);
|
|
2504
|
+
return color;
|
|
2505
|
+
}
|
|
2506
|
+
|
|
1931
2507
|
void PBRInfo_setAmbientLight(inout PBRInfo pbrInfo) {
|
|
1932
2508
|
pbrInfo.NdotL = 1.0;
|
|
1933
2509
|
pbrInfo.NdotH = 0.0;
|
|
@@ -1952,6 +2528,11 @@ void PBRInfo_setPointLight(inout PBRInfo pbrInfo, PointLight pointLight) {
|
|
|
1952
2528
|
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
1953
2529
|
}
|
|
1954
2530
|
|
|
2531
|
+
void PBRInfo_setSpotLight(inout PBRInfo pbrInfo, SpotLight spotLight) {
|
|
2532
|
+
vec3 light_direction = normalize(spotLight.position - pbr_vPosition);
|
|
2533
|
+
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
2534
|
+
}
|
|
2535
|
+
|
|
1955
2536
|
vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor) {
|
|
1956
2537
|
// Calculate the shading terms for the microfacet specular shading model
|
|
1957
2538
|
vec3 F = specularReflection(pbrInfo);
|
|
@@ -1982,6 +2563,8 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
1982
2563
|
|
|
1983
2564
|
vec3 color = vec3(0, 0, 0);
|
|
1984
2565
|
|
|
2566
|
+
float transmission = 0.0;
|
|
2567
|
+
|
|
1985
2568
|
if(pbrMaterial.unlit){
|
|
1986
2569
|
color.rgb = baseColor.rgb;
|
|
1987
2570
|
}
|
|
@@ -2000,14 +2583,252 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
2000
2583
|
#endif
|
|
2001
2584
|
perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
|
|
2002
2585
|
metallic = clamp(metallic, 0.0, 1.0);
|
|
2586
|
+
mat3 tbn = getTBN();
|
|
2587
|
+
vec3 n = getNormal(tbn); // normal at surface point
|
|
2588
|
+
vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
|
|
2589
|
+
float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
2590
|
+
#ifdef USE_MATERIAL_EXTENSIONS
|
|
2591
|
+
bool useExtendedPBR =
|
|
2592
|
+
pbrMaterial.specularColorMapEnabled ||
|
|
2593
|
+
pbrMaterial.specularIntensityMapEnabled ||
|
|
2594
|
+
abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||
|
|
2595
|
+
maxComponent(abs(pbrMaterial.specularColorFactor - vec3(1.0))) > 0.0001 ||
|
|
2596
|
+
abs(pbrMaterial.ior - 1.5) > 0.0001 ||
|
|
2597
|
+
pbrMaterial.transmissionMapEnabled ||
|
|
2598
|
+
pbrMaterial.transmissionFactor > 0.0001 ||
|
|
2599
|
+
pbrMaterial.clearcoatMapEnabled ||
|
|
2600
|
+
pbrMaterial.clearcoatRoughnessMapEnabled ||
|
|
2601
|
+
pbrMaterial.clearcoatFactor > 0.0001 ||
|
|
2602
|
+
pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||
|
|
2603
|
+
pbrMaterial.sheenColorMapEnabled ||
|
|
2604
|
+
pbrMaterial.sheenRoughnessMapEnabled ||
|
|
2605
|
+
maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||
|
|
2606
|
+
pbrMaterial.sheenRoughnessFactor > 0.0001 ||
|
|
2607
|
+
pbrMaterial.iridescenceMapEnabled ||
|
|
2608
|
+
pbrMaterial.iridescenceFactor > 0.0001 ||
|
|
2609
|
+
abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||
|
|
2610
|
+
abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||
|
|
2611
|
+
abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||
|
|
2612
|
+
pbrMaterial.anisotropyMapEnabled ||
|
|
2613
|
+
pbrMaterial.anisotropyStrength > 0.0001 ||
|
|
2614
|
+
abs(pbrMaterial.anisotropyRotation) > 0.0001 ||
|
|
2615
|
+
length(pbrMaterial.anisotropyDirection - vec2(1.0, 0.0)) > 0.0001;
|
|
2616
|
+
#else
|
|
2617
|
+
bool useExtendedPBR = false;
|
|
2618
|
+
#endif
|
|
2619
|
+
|
|
2620
|
+
if (!useExtendedPBR) {
|
|
2621
|
+
// Keep the baseline metallic-roughness implementation byte-for-byte equivalent in behavior.
|
|
2622
|
+
float alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
2623
|
+
|
|
2624
|
+
vec3 f0 = vec3(0.04);
|
|
2625
|
+
vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
|
|
2626
|
+
diffuseColor *= 1.0 - metallic;
|
|
2627
|
+
vec3 specularColor = mix(f0, baseColor.rgb, metallic);
|
|
2628
|
+
|
|
2629
|
+
float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
2630
|
+
float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
2631
|
+
vec3 specularEnvironmentR0 = specularColor.rgb;
|
|
2632
|
+
vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
|
|
2633
|
+
vec3 reflection = -normalize(reflect(v, n));
|
|
2634
|
+
|
|
2635
|
+
PBRInfo pbrInfo = PBRInfo(
|
|
2636
|
+
0.0, // NdotL
|
|
2637
|
+
NdotV,
|
|
2638
|
+
0.0, // NdotH
|
|
2639
|
+
0.0, // LdotH
|
|
2640
|
+
0.0, // VdotH
|
|
2641
|
+
perceptualRoughness,
|
|
2642
|
+
metallic,
|
|
2643
|
+
specularEnvironmentR0,
|
|
2644
|
+
specularEnvironmentR90,
|
|
2645
|
+
alphaRoughness,
|
|
2646
|
+
diffuseColor,
|
|
2647
|
+
specularColor,
|
|
2648
|
+
n,
|
|
2649
|
+
v
|
|
2650
|
+
);
|
|
2651
|
+
|
|
2652
|
+
#ifdef USE_LIGHTS
|
|
2653
|
+
PBRInfo_setAmbientLight(pbrInfo);
|
|
2654
|
+
color += calculateFinalColor(pbrInfo, lighting.ambientColor);
|
|
2655
|
+
|
|
2656
|
+
for(int i = 0; i < lighting.directionalLightCount; i++) {
|
|
2657
|
+
if (i < lighting.directionalLightCount) {
|
|
2658
|
+
PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
2659
|
+
color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
|
|
2663
|
+
for(int i = 0; i < lighting.pointLightCount; i++) {
|
|
2664
|
+
if (i < lighting.pointLightCount) {
|
|
2665
|
+
PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
|
|
2666
|
+
float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
|
|
2667
|
+
color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
|
|
2668
|
+
}
|
|
2669
|
+
}
|
|
2670
|
+
|
|
2671
|
+
for(int i = 0; i < lighting.spotLightCount; i++) {
|
|
2672
|
+
if (i < lighting.spotLightCount) {
|
|
2673
|
+
PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));
|
|
2674
|
+
float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);
|
|
2675
|
+
color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
#endif
|
|
2679
|
+
|
|
2680
|
+
#ifdef USE_IBL
|
|
2681
|
+
if (pbrMaterial.IBLenabled) {
|
|
2682
|
+
color += getIBLContribution(pbrInfo, n, reflection);
|
|
2683
|
+
}
|
|
2684
|
+
#endif
|
|
2685
|
+
|
|
2686
|
+
#ifdef HAS_OCCLUSIONMAP
|
|
2687
|
+
if (pbrMaterial.occlusionMapEnabled) {
|
|
2688
|
+
float ao = texture(pbr_occlusionSampler, pbr_vUV).r;
|
|
2689
|
+
color = mix(color, color * ao, pbrMaterial.occlusionStrength);
|
|
2690
|
+
}
|
|
2691
|
+
#endif
|
|
2692
|
+
|
|
2693
|
+
vec3 emissive = pbrMaterial.emissiveFactor;
|
|
2694
|
+
#ifdef HAS_EMISSIVEMAP
|
|
2695
|
+
if (pbrMaterial.emissiveMapEnabled) {
|
|
2696
|
+
emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb;
|
|
2697
|
+
}
|
|
2698
|
+
#endif
|
|
2699
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
2700
|
+
|
|
2701
|
+
#ifdef PBR_DEBUG
|
|
2702
|
+
color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
|
|
2703
|
+
color = mix(color, vec3(metallic), pbrMaterial.scaleDiffBaseMR.z);
|
|
2704
|
+
color = mix(color, vec3(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
|
|
2705
|
+
#endif
|
|
2706
|
+
|
|
2707
|
+
return vec4(pow(color, vec3(1.0 / 2.2)), baseColor.a);
|
|
2708
|
+
}
|
|
2709
|
+
|
|
2710
|
+
float specularIntensity = pbrMaterial.specularIntensityFactor;
|
|
2711
|
+
#ifdef HAS_SPECULARINTENSITYMAP
|
|
2712
|
+
if (pbrMaterial.specularIntensityMapEnabled) {
|
|
2713
|
+
specularIntensity *= texture(pbr_specularIntensitySampler, pbr_vUV).a;
|
|
2714
|
+
}
|
|
2715
|
+
#endif
|
|
2716
|
+
|
|
2717
|
+
vec3 specularFactor = pbrMaterial.specularColorFactor;
|
|
2718
|
+
#ifdef HAS_SPECULARCOLORMAP
|
|
2719
|
+
if (pbrMaterial.specularColorMapEnabled) {
|
|
2720
|
+
specularFactor *= SRGBtoLINEAR(texture(pbr_specularColorSampler, pbr_vUV)).rgb;
|
|
2721
|
+
}
|
|
2722
|
+
#endif
|
|
2723
|
+
|
|
2724
|
+
transmission = pbrMaterial.transmissionFactor;
|
|
2725
|
+
#ifdef HAS_TRANSMISSIONMAP
|
|
2726
|
+
if (pbrMaterial.transmissionMapEnabled) {
|
|
2727
|
+
transmission *= texture(pbr_transmissionSampler, pbr_vUV).r;
|
|
2728
|
+
}
|
|
2729
|
+
#endif
|
|
2730
|
+
transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);
|
|
2731
|
+
float thickness = max(pbrMaterial.thicknessFactor, 0.0);
|
|
2732
|
+
#ifdef HAS_THICKNESSMAP
|
|
2733
|
+
thickness *= texture(pbr_thicknessSampler, pbr_vUV).g;
|
|
2734
|
+
#endif
|
|
2735
|
+
|
|
2736
|
+
float clearcoatFactor = pbrMaterial.clearcoatFactor;
|
|
2737
|
+
float clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;
|
|
2738
|
+
#ifdef HAS_CLEARCOATMAP
|
|
2739
|
+
if (pbrMaterial.clearcoatMapEnabled) {
|
|
2740
|
+
clearcoatFactor *= texture(pbr_clearcoatSampler, pbr_vUV).r;
|
|
2741
|
+
}
|
|
2742
|
+
#endif
|
|
2743
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
2744
|
+
if (pbrMaterial.clearcoatRoughnessMapEnabled) {
|
|
2745
|
+
clearcoatRoughness *= texture(pbr_clearcoatRoughnessSampler, pbr_vUV).g;
|
|
2746
|
+
}
|
|
2747
|
+
#endif
|
|
2748
|
+
clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);
|
|
2749
|
+
clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
2750
|
+
vec3 clearcoatNormal = getClearcoatNormal(tbn, n);
|
|
2751
|
+
|
|
2752
|
+
vec3 sheenColor = pbrMaterial.sheenColorFactor;
|
|
2753
|
+
float sheenRoughness = pbrMaterial.sheenRoughnessFactor;
|
|
2754
|
+
#ifdef HAS_SHEENCOLORMAP
|
|
2755
|
+
if (pbrMaterial.sheenColorMapEnabled) {
|
|
2756
|
+
sheenColor *= SRGBtoLINEAR(texture(pbr_sheenColorSampler, pbr_vUV)).rgb;
|
|
2757
|
+
}
|
|
2758
|
+
#endif
|
|
2759
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
2760
|
+
if (pbrMaterial.sheenRoughnessMapEnabled) {
|
|
2761
|
+
sheenRoughness *= texture(pbr_sheenRoughnessSampler, pbr_vUV).a;
|
|
2762
|
+
}
|
|
2763
|
+
#endif
|
|
2764
|
+
sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);
|
|
2765
|
+
|
|
2766
|
+
float iridescence = pbrMaterial.iridescenceFactor;
|
|
2767
|
+
#ifdef HAS_IRIDESCENCEMAP
|
|
2768
|
+
if (pbrMaterial.iridescenceMapEnabled) {
|
|
2769
|
+
iridescence *= texture(pbr_iridescenceSampler, pbr_vUV).r;
|
|
2770
|
+
}
|
|
2771
|
+
#endif
|
|
2772
|
+
iridescence = clamp(iridescence, 0.0, 1.0);
|
|
2773
|
+
float iridescenceThickness = mix(
|
|
2774
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
2775
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
2776
|
+
0.5
|
|
2777
|
+
);
|
|
2778
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
2779
|
+
iridescenceThickness = mix(
|
|
2780
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
2781
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
2782
|
+
texture(pbr_iridescenceThicknessSampler, pbr_vUV).g
|
|
2783
|
+
);
|
|
2784
|
+
#endif
|
|
2785
|
+
|
|
2786
|
+
float anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);
|
|
2787
|
+
vec2 anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);
|
|
2788
|
+
#ifdef HAS_ANISOTROPYMAP
|
|
2789
|
+
if (pbrMaterial.anisotropyMapEnabled) {
|
|
2790
|
+
vec3 anisotropySample = texture(pbr_anisotropySampler, pbr_vUV).rgb;
|
|
2791
|
+
anisotropyStrength *= anisotropySample.b;
|
|
2792
|
+
vec2 mappedDirection = anisotropySample.rg * 2.0 - 1.0;
|
|
2793
|
+
if (length(mappedDirection) > 0.0001) {
|
|
2794
|
+
anisotropyDirection = normalize(mappedDirection);
|
|
2795
|
+
}
|
|
2796
|
+
}
|
|
2797
|
+
#endif
|
|
2798
|
+
anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);
|
|
2799
|
+
vec3 anisotropyTangent = normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);
|
|
2800
|
+
if (length(anisotropyTangent) < 0.0001) {
|
|
2801
|
+
anisotropyTangent = normalize(tbn[0]);
|
|
2802
|
+
}
|
|
2803
|
+
float anisotropyViewAlignment = abs(dot(v, anisotropyTangent));
|
|
2804
|
+
perceptualRoughness = mix(
|
|
2805
|
+
perceptualRoughness,
|
|
2806
|
+
clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),
|
|
2807
|
+
anisotropyStrength
|
|
2808
|
+
);
|
|
2809
|
+
|
|
2003
2810
|
// Roughness is authored as perceptual roughness; as is convention,
|
|
2004
2811
|
// convert to material roughness by squaring the perceptual roughness [2].
|
|
2005
2812
|
float alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
2006
2813
|
|
|
2007
|
-
|
|
2008
|
-
vec3
|
|
2009
|
-
|
|
2010
|
-
|
|
2814
|
+
float dielectricF0 = getDielectricF0(pbrMaterial.ior);
|
|
2815
|
+
vec3 dielectricSpecularF0 = min(
|
|
2816
|
+
vec3(dielectricF0) * specularFactor * specularIntensity,
|
|
2817
|
+
vec3(1.0)
|
|
2818
|
+
);
|
|
2819
|
+
vec3 iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);
|
|
2820
|
+
dielectricSpecularF0 = mix(
|
|
2821
|
+
dielectricSpecularF0,
|
|
2822
|
+
dielectricSpecularF0 * iridescenceTint,
|
|
2823
|
+
iridescence
|
|
2824
|
+
);
|
|
2825
|
+
vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - dielectricSpecularF0);
|
|
2826
|
+
diffuseColor *= (1.0 - metallic) * (1.0 - transmission);
|
|
2827
|
+
vec3 specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);
|
|
2828
|
+
|
|
2829
|
+
float baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;
|
|
2830
|
+
diffuseColor *= baseLayerEnergy;
|
|
2831
|
+
specularColor *= baseLayerEnergy;
|
|
2011
2832
|
|
|
2012
2833
|
// Compute reflectance.
|
|
2013
2834
|
float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
@@ -2019,11 +2840,6 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
2019
2840
|
float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
2020
2841
|
vec3 specularEnvironmentR0 = specularColor.rgb;
|
|
2021
2842
|
vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
|
|
2022
|
-
|
|
2023
|
-
vec3 n = getNormal(); // normal at surface point
|
|
2024
|
-
vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
|
|
2025
|
-
|
|
2026
|
-
float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
2027
2843
|
vec3 reflection = -normalize(reflect(v, n));
|
|
2028
2844
|
|
|
2029
2845
|
PBRInfo pbrInfo = PBRInfo(
|
|
@@ -2047,13 +2863,33 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
2047
2863
|
#ifdef USE_LIGHTS
|
|
2048
2864
|
// Apply ambient light
|
|
2049
2865
|
PBRInfo_setAmbientLight(pbrInfo);
|
|
2050
|
-
color +=
|
|
2866
|
+
color += calculateMaterialLightColor(
|
|
2867
|
+
pbrInfo,
|
|
2868
|
+
lighting.ambientColor,
|
|
2869
|
+
clearcoatNormal,
|
|
2870
|
+
clearcoatFactor,
|
|
2871
|
+
clearcoatRoughness,
|
|
2872
|
+
sheenColor,
|
|
2873
|
+
sheenRoughness,
|
|
2874
|
+
anisotropyTangent,
|
|
2875
|
+
anisotropyStrength
|
|
2876
|
+
);
|
|
2051
2877
|
|
|
2052
2878
|
// Apply directional light
|
|
2053
2879
|
for(int i = 0; i < lighting.directionalLightCount; i++) {
|
|
2054
2880
|
if (i < lighting.directionalLightCount) {
|
|
2055
2881
|
PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
2056
|
-
color +=
|
|
2882
|
+
color += calculateMaterialLightColor(
|
|
2883
|
+
pbrInfo,
|
|
2884
|
+
lighting_getDirectionalLight(i).color,
|
|
2885
|
+
clearcoatNormal,
|
|
2886
|
+
clearcoatFactor,
|
|
2887
|
+
clearcoatRoughness,
|
|
2888
|
+
sheenColor,
|
|
2889
|
+
sheenRoughness,
|
|
2890
|
+
anisotropyTangent,
|
|
2891
|
+
anisotropyStrength
|
|
2892
|
+
);
|
|
2057
2893
|
}
|
|
2058
2894
|
}
|
|
2059
2895
|
|
|
@@ -2062,7 +2898,35 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
2062
2898
|
if (i < lighting.pointLightCount) {
|
|
2063
2899
|
PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
|
|
2064
2900
|
float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
|
|
2065
|
-
color +=
|
|
2901
|
+
color += calculateMaterialLightColor(
|
|
2902
|
+
pbrInfo,
|
|
2903
|
+
lighting_getPointLight(i).color / attenuation,
|
|
2904
|
+
clearcoatNormal,
|
|
2905
|
+
clearcoatFactor,
|
|
2906
|
+
clearcoatRoughness,
|
|
2907
|
+
sheenColor,
|
|
2908
|
+
sheenRoughness,
|
|
2909
|
+
anisotropyTangent,
|
|
2910
|
+
anisotropyStrength
|
|
2911
|
+
);
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
|
|
2915
|
+
for(int i = 0; i < lighting.spotLightCount; i++) {
|
|
2916
|
+
if (i < lighting.spotLightCount) {
|
|
2917
|
+
PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));
|
|
2918
|
+
float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);
|
|
2919
|
+
color += calculateMaterialLightColor(
|
|
2920
|
+
pbrInfo,
|
|
2921
|
+
lighting_getSpotLight(i).color / attenuation,
|
|
2922
|
+
clearcoatNormal,
|
|
2923
|
+
clearcoatFactor,
|
|
2924
|
+
clearcoatRoughness,
|
|
2925
|
+
sheenColor,
|
|
2926
|
+
sheenRoughness,
|
|
2927
|
+
anisotropyTangent,
|
|
2928
|
+
anisotropyStrength
|
|
2929
|
+
);
|
|
2066
2930
|
}
|
|
2067
2931
|
}
|
|
2068
2932
|
#endif
|
|
@@ -2070,7 +2934,16 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
2070
2934
|
// Calculate lighting contribution from image based lighting source (IBL)
|
|
2071
2935
|
#ifdef USE_IBL
|
|
2072
2936
|
if (pbrMaterial.IBLenabled) {
|
|
2073
|
-
color += getIBLContribution(pbrInfo, n, reflection)
|
|
2937
|
+
color += getIBLContribution(pbrInfo, n, reflection) *
|
|
2938
|
+
calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
2939
|
+
color += calculateClearcoatIBLContribution(
|
|
2940
|
+
pbrInfo,
|
|
2941
|
+
clearcoatNormal,
|
|
2942
|
+
-normalize(reflect(v, clearcoatNormal)),
|
|
2943
|
+
clearcoatFactor,
|
|
2944
|
+
clearcoatRoughness
|
|
2945
|
+
);
|
|
2946
|
+
color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;
|
|
2074
2947
|
}
|
|
2075
2948
|
#endif
|
|
2076
2949
|
|
|
@@ -2082,12 +2955,17 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
2082
2955
|
}
|
|
2083
2956
|
#endif
|
|
2084
2957
|
|
|
2958
|
+
vec3 emissive = pbrMaterial.emissiveFactor;
|
|
2085
2959
|
#ifdef HAS_EMISSIVEMAP
|
|
2086
2960
|
if (pbrMaterial.emissiveMapEnabled) {
|
|
2087
|
-
|
|
2088
|
-
color += emissive;
|
|
2961
|
+
emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb;
|
|
2089
2962
|
}
|
|
2090
2963
|
#endif
|
|
2964
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
2965
|
+
|
|
2966
|
+
if (transmission > 0.0) {
|
|
2967
|
+
color = mix(color, color * getVolumeAttenuation(thickness), transmission);
|
|
2968
|
+
}
|
|
2091
2969
|
|
|
2092
2970
|
// This section uses mix to override final color for reference app visualization
|
|
2093
2971
|
// of various parameters in the lighting equation.
|
|
@@ -2107,9 +2985,10 @@ vec4 pbr_filterColor(vec4 colorUnused)
|
|
|
2107
2985
|
|
|
2108
2986
|
}
|
|
2109
2987
|
|
|
2110
|
-
|
|
2988
|
+
float alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);
|
|
2989
|
+
return vec4(pow(color,vec3(1.0/2.2)), alpha);
|
|
2111
2990
|
}
|
|
2112
|
-
`;var
|
|
2991
|
+
`;var Rn=`struct PBRFragmentInputs {
|
|
2113
2992
|
pbr_vPosition: vec3f,
|
|
2114
2993
|
pbr_vUV: vec2f,
|
|
2115
2994
|
pbr_vTBN: mat3x3f,
|
|
@@ -2167,6 +3046,42 @@ struct pbrMaterialUniforms {
|
|
|
2167
3046
|
|
|
2168
3047
|
alphaCutoffEnabled: i32,
|
|
2169
3048
|
alphaCutoff: f32, // #ifdef ALPHA_CUTOFF
|
|
3049
|
+
|
|
3050
|
+
specularColorFactor: vec3f,
|
|
3051
|
+
specularIntensityFactor: f32,
|
|
3052
|
+
specularColorMapEnabled: i32,
|
|
3053
|
+
specularIntensityMapEnabled: i32,
|
|
3054
|
+
|
|
3055
|
+
ior: f32,
|
|
3056
|
+
|
|
3057
|
+
transmissionFactor: f32,
|
|
3058
|
+
transmissionMapEnabled: i32,
|
|
3059
|
+
|
|
3060
|
+
thicknessFactor: f32,
|
|
3061
|
+
attenuationDistance: f32,
|
|
3062
|
+
attenuationColor: vec3f,
|
|
3063
|
+
|
|
3064
|
+
clearcoatFactor: f32,
|
|
3065
|
+
clearcoatRoughnessFactor: f32,
|
|
3066
|
+
clearcoatMapEnabled: i32,
|
|
3067
|
+
clearcoatRoughnessMapEnabled: i32,
|
|
3068
|
+
|
|
3069
|
+
sheenColorFactor: vec3f,
|
|
3070
|
+
sheenRoughnessFactor: f32,
|
|
3071
|
+
sheenColorMapEnabled: i32,
|
|
3072
|
+
sheenRoughnessMapEnabled: i32,
|
|
3073
|
+
|
|
3074
|
+
iridescenceFactor: f32,
|
|
3075
|
+
iridescenceIor: f32,
|
|
3076
|
+
iridescenceThicknessRange: vec2f,
|
|
3077
|
+
iridescenceMapEnabled: i32,
|
|
3078
|
+
|
|
3079
|
+
anisotropyStrength: f32,
|
|
3080
|
+
anisotropyRotation: f32,
|
|
3081
|
+
anisotropyDirection: vec2f,
|
|
3082
|
+
anisotropyMapEnabled: i32,
|
|
3083
|
+
|
|
3084
|
+
emissiveStrength: f32,
|
|
2170
3085
|
|
|
2171
3086
|
// IBL
|
|
2172
3087
|
IBLenabled: i32,
|
|
@@ -2179,38 +3094,77 @@ struct pbrMaterialUniforms {
|
|
|
2179
3094
|
// #endif
|
|
2180
3095
|
}
|
|
2181
3096
|
|
|
2182
|
-
@
|
|
3097
|
+
@group(3) @binding(auto) var<uniform> pbrMaterial : pbrMaterialUniforms;
|
|
2183
3098
|
|
|
2184
3099
|
// Samplers
|
|
2185
3100
|
#ifdef HAS_BASECOLORMAP
|
|
2186
|
-
@
|
|
2187
|
-
@
|
|
3101
|
+
@group(3) @binding(auto) var pbr_baseColorSampler: texture_2d<f32>;
|
|
3102
|
+
@group(3) @binding(auto) var pbr_baseColorSamplerSampler: sampler;
|
|
2188
3103
|
#endif
|
|
2189
3104
|
#ifdef HAS_NORMALMAP
|
|
2190
|
-
@
|
|
2191
|
-
@
|
|
3105
|
+
@group(3) @binding(auto) var pbr_normalSampler: texture_2d<f32>;
|
|
3106
|
+
@group(3) @binding(auto) var pbr_normalSamplerSampler: sampler;
|
|
2192
3107
|
#endif
|
|
2193
3108
|
#ifdef HAS_EMISSIVEMAP
|
|
2194
|
-
@
|
|
2195
|
-
@
|
|
3109
|
+
@group(3) @binding(auto) var pbr_emissiveSampler: texture_2d<f32>;
|
|
3110
|
+
@group(3) @binding(auto) var pbr_emissiveSamplerSampler: sampler;
|
|
2196
3111
|
#endif
|
|
2197
3112
|
#ifdef HAS_METALROUGHNESSMAP
|
|
2198
|
-
@
|
|
2199
|
-
@
|
|
3113
|
+
@group(3) @binding(auto) var pbr_metallicRoughnessSampler: texture_2d<f32>;
|
|
3114
|
+
@group(3) @binding(auto) var pbr_metallicRoughnessSamplerSampler: sampler;
|
|
2200
3115
|
#endif
|
|
2201
3116
|
#ifdef HAS_OCCLUSIONMAP
|
|
2202
|
-
@
|
|
2203
|
-
@
|
|
3117
|
+
@group(3) @binding(auto) var pbr_occlusionSampler: texture_2d<f32>;
|
|
3118
|
+
@group(3) @binding(auto) var pbr_occlusionSamplerSampler: sampler;
|
|
2204
3119
|
#endif
|
|
2205
|
-
#ifdef
|
|
2206
|
-
@
|
|
2207
|
-
@
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
@
|
|
2211
|
-
@
|
|
3120
|
+
#ifdef HAS_SPECULARCOLORMAP
|
|
3121
|
+
@group(3) @binding(auto) var pbr_specularColorSampler: texture_2d<f32>;
|
|
3122
|
+
@group(3) @binding(auto) var pbr_specularColorSamplerSampler: sampler;
|
|
3123
|
+
#endif
|
|
3124
|
+
#ifdef HAS_SPECULARINTENSITYMAP
|
|
3125
|
+
@group(3) @binding(auto) var pbr_specularIntensitySampler: texture_2d<f32>;
|
|
3126
|
+
@group(3) @binding(auto) var pbr_specularIntensitySamplerSampler: sampler;
|
|
3127
|
+
#endif
|
|
3128
|
+
#ifdef HAS_TRANSMISSIONMAP
|
|
3129
|
+
@group(3) @binding(auto) var pbr_transmissionSampler: texture_2d<f32>;
|
|
3130
|
+
@group(3) @binding(auto) var pbr_transmissionSamplerSampler: sampler;
|
|
3131
|
+
#endif
|
|
3132
|
+
#ifdef HAS_THICKNESSMAP
|
|
3133
|
+
@group(3) @binding(auto) var pbr_thicknessSampler: texture_2d<f32>;
|
|
3134
|
+
@group(3) @binding(auto) var pbr_thicknessSamplerSampler: sampler;
|
|
3135
|
+
#endif
|
|
3136
|
+
#ifdef HAS_CLEARCOATMAP
|
|
3137
|
+
@group(3) @binding(auto) var pbr_clearcoatSampler: texture_2d<f32>;
|
|
3138
|
+
@group(3) @binding(auto) var pbr_clearcoatSamplerSampler: sampler;
|
|
3139
|
+
#endif
|
|
3140
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
3141
|
+
@group(3) @binding(auto) var pbr_clearcoatRoughnessSampler: texture_2d<f32>;
|
|
3142
|
+
@group(3) @binding(auto) var pbr_clearcoatRoughnessSamplerSampler: sampler;
|
|
3143
|
+
#endif
|
|
3144
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
3145
|
+
@group(3) @binding(auto) var pbr_clearcoatNormalSampler: texture_2d<f32>;
|
|
3146
|
+
@group(3) @binding(auto) var pbr_clearcoatNormalSamplerSampler: sampler;
|
|
3147
|
+
#endif
|
|
3148
|
+
#ifdef HAS_SHEENCOLORMAP
|
|
3149
|
+
@group(3) @binding(auto) var pbr_sheenColorSampler: texture_2d<f32>;
|
|
3150
|
+
@group(3) @binding(auto) var pbr_sheenColorSamplerSampler: sampler;
|
|
3151
|
+
#endif
|
|
3152
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
3153
|
+
@group(3) @binding(auto) var pbr_sheenRoughnessSampler: texture_2d<f32>;
|
|
3154
|
+
@group(3) @binding(auto) var pbr_sheenRoughnessSamplerSampler: sampler;
|
|
3155
|
+
#endif
|
|
3156
|
+
#ifdef HAS_IRIDESCENCEMAP
|
|
3157
|
+
@group(3) @binding(auto) var pbr_iridescenceSampler: texture_2d<f32>;
|
|
3158
|
+
@group(3) @binding(auto) var pbr_iridescenceSamplerSampler: sampler;
|
|
3159
|
+
#endif
|
|
3160
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
3161
|
+
@group(3) @binding(auto) var pbr_iridescenceThicknessSampler: texture_2d<f32>;
|
|
3162
|
+
@group(3) @binding(auto) var pbr_iridescenceThicknessSamplerSampler: sampler;
|
|
3163
|
+
#endif
|
|
3164
|
+
#ifdef HAS_ANISOTROPYMAP
|
|
3165
|
+
@group(3) @binding(auto) var pbr_anisotropySampler: texture_2d<f32>;
|
|
3166
|
+
@group(3) @binding(auto) var pbr_anisotropySamplerSampler: sampler;
|
|
2212
3167
|
#endif
|
|
2213
|
-
|
|
2214
3168
|
// Encapsulate the various inputs used by the various functions in the shading equation
|
|
2215
3169
|
// We store values in this struct to simplify the integration of alternative implementations
|
|
2216
3170
|
// of the shading terms, outlined in the Readme.MD Appendix.
|
|
@@ -2251,11 +3205,9 @@ fn SRGBtoLINEAR(srgbIn: vec4f ) -> vec4f
|
|
|
2251
3205
|
return vec4f(linOut, srgbIn.w);
|
|
2252
3206
|
}
|
|
2253
3207
|
|
|
2254
|
-
//
|
|
2255
|
-
|
|
2256
|
-
fn getNormal() -> vec3f
|
|
3208
|
+
// Build the tangent basis from interpolated attributes or screen-space derivatives.
|
|
3209
|
+
fn getTBN() -> mat3x3f
|
|
2257
3210
|
{
|
|
2258
|
-
// Retrieve the tangent space matrix
|
|
2259
3211
|
let pos_dx: vec3f = dpdx(fragmentInputs.pbr_vPosition);
|
|
2260
3212
|
let pos_dy: vec3f = dpdy(fragmentInputs.pbr_vPosition);
|
|
2261
3213
|
let tex_dx: vec3f = dpdx(vec3f(fragmentInputs.pbr_vUV, 0.0));
|
|
@@ -2273,16 +3225,52 @@ fn getNormal() -> vec3f
|
|
|
2273
3225
|
tbn = fragmentInputs.pbr_vTBN;
|
|
2274
3226
|
#endif
|
|
2275
3227
|
|
|
3228
|
+
return tbn;
|
|
3229
|
+
}
|
|
3230
|
+
|
|
3231
|
+
// Find the normal for this fragment, pulling either from a predefined normal map
|
|
3232
|
+
// or from the interpolated mesh normal and tangent attributes.
|
|
3233
|
+
fn getMappedNormal(
|
|
3234
|
+
normalSampler: texture_2d<f32>,
|
|
3235
|
+
normalSamplerBinding: sampler,
|
|
3236
|
+
tbn: mat3x3f,
|
|
3237
|
+
normalScale: f32
|
|
3238
|
+
) -> vec3f
|
|
3239
|
+
{
|
|
3240
|
+
let n = textureSample(normalSampler, normalSamplerBinding, fragmentInputs.pbr_vUV).rgb;
|
|
3241
|
+
return normalize(tbn * ((2.0 * n - 1.0) * vec3f(normalScale, normalScale, 1.0)));
|
|
3242
|
+
}
|
|
3243
|
+
|
|
3244
|
+
fn getNormal(tbn: mat3x3f) -> vec3f
|
|
3245
|
+
{
|
|
2276
3246
|
// The tbn matrix is linearly interpolated, so we need to re-normalize
|
|
2277
3247
|
var n: vec3f = normalize(tbn[2].xyz);
|
|
2278
3248
|
#ifdef HAS_NORMALMAP
|
|
2279
|
-
n =
|
|
2280
|
-
|
|
3249
|
+
n = getMappedNormal(
|
|
3250
|
+
pbr_normalSampler,
|
|
3251
|
+
pbr_normalSamplerSampler,
|
|
3252
|
+
tbn,
|
|
3253
|
+
pbrMaterial.normalScale
|
|
3254
|
+
);
|
|
2281
3255
|
#endif
|
|
2282
3256
|
|
|
2283
3257
|
return n;
|
|
2284
3258
|
}
|
|
2285
3259
|
|
|
3260
|
+
fn getClearcoatNormal(tbn: mat3x3f, baseNormal: vec3f) -> vec3f
|
|
3261
|
+
{
|
|
3262
|
+
#ifdef HAS_CLEARCOATNORMALMAP
|
|
3263
|
+
return getMappedNormal(
|
|
3264
|
+
pbr_clearcoatNormalSampler,
|
|
3265
|
+
pbr_clearcoatNormalSamplerSampler,
|
|
3266
|
+
tbn,
|
|
3267
|
+
1.0
|
|
3268
|
+
);
|
|
3269
|
+
#else
|
|
3270
|
+
return baseNormal;
|
|
3271
|
+
#endif
|
|
3272
|
+
}
|
|
3273
|
+
|
|
2286
3274
|
// Calculation of the lighting contribution from an optional Image Based Light source.
|
|
2287
3275
|
// Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
|
|
2288
3276
|
// See our README.md on Environment Maps [3] for additional discussion.
|
|
@@ -2293,17 +3281,25 @@ fn getIBLContribution(pbrInfo: PBRInfo, n: vec3f, reflection: vec3f) -> vec3f
|
|
|
2293
3281
|
let lod: f32 = pbrInfo.perceptualRoughness * mipCount;
|
|
2294
3282
|
// retrieve a scale and bias to F0. See [1], Figure 3
|
|
2295
3283
|
let brdf = SRGBtoLINEAR(
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
vec2f(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness)
|
|
3284
|
+
textureSampleLevel(
|
|
3285
|
+
pbr_brdfLUT,
|
|
3286
|
+
pbr_brdfLUTSampler,
|
|
3287
|
+
vec2f(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness),
|
|
3288
|
+
0.0
|
|
2300
3289
|
)
|
|
2301
3290
|
).rgb;
|
|
2302
3291
|
let diffuseLight =
|
|
2303
|
-
SRGBtoLINEAR(
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
var specularLight =
|
|
3292
|
+
SRGBtoLINEAR(
|
|
3293
|
+
textureSampleLevel(pbr_diffuseEnvSampler, pbr_diffuseEnvSamplerSampler, n, 0.0)
|
|
3294
|
+
).rgb;
|
|
3295
|
+
var specularLight = SRGBtoLINEAR(
|
|
3296
|
+
textureSampleLevel(
|
|
3297
|
+
pbr_specularEnvSampler,
|
|
3298
|
+
pbr_specularEnvSamplerSampler,
|
|
3299
|
+
reflection,
|
|
3300
|
+
0.0
|
|
3301
|
+
)
|
|
3302
|
+
).rgb;
|
|
2307
3303
|
#ifdef USE_TEX_LOD
|
|
2308
3304
|
specularLight = SRGBtoLINEAR(
|
|
2309
3305
|
textureSampleLevel(
|
|
@@ -2364,6 +3360,172 @@ fn microfacetDistribution(pbrInfo: PBRInfo) -> f32 {
|
|
|
2364
3360
|
return roughnessSq / (M_PI * f * f);
|
|
2365
3361
|
}
|
|
2366
3362
|
|
|
3363
|
+
fn maxComponent(value: vec3f) -> f32 {
|
|
3364
|
+
return max(max(value.r, value.g), value.b);
|
|
3365
|
+
}
|
|
3366
|
+
|
|
3367
|
+
fn getDielectricF0(ior: f32) -> f32 {
|
|
3368
|
+
let clampedIor = max(ior, 1.0);
|
|
3369
|
+
let ratio = (clampedIor - 1.0) / (clampedIor + 1.0);
|
|
3370
|
+
return ratio * ratio;
|
|
3371
|
+
}
|
|
3372
|
+
|
|
3373
|
+
fn normalizeDirection(direction: vec2f) -> vec2f {
|
|
3374
|
+
let directionLength = length(direction);
|
|
3375
|
+
if (directionLength > 0.0001) {
|
|
3376
|
+
return direction / directionLength;
|
|
3377
|
+
}
|
|
3378
|
+
|
|
3379
|
+
return vec2f(1.0, 0.0);
|
|
3380
|
+
}
|
|
3381
|
+
|
|
3382
|
+
fn rotateDirection(direction: vec2f, rotation: f32) -> vec2f {
|
|
3383
|
+
let s = sin(rotation);
|
|
3384
|
+
let c = cos(rotation);
|
|
3385
|
+
return vec2f(direction.x * c - direction.y * s, direction.x * s + direction.y * c);
|
|
3386
|
+
}
|
|
3387
|
+
|
|
3388
|
+
fn getIridescenceTint(iridescence: f32, thickness: f32, NdotV: f32) -> vec3f {
|
|
3389
|
+
if (iridescence <= 0.0) {
|
|
3390
|
+
return vec3f(1.0);
|
|
3391
|
+
}
|
|
3392
|
+
|
|
3393
|
+
let phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;
|
|
3394
|
+
let thinFilmTint =
|
|
3395
|
+
0.5 +
|
|
3396
|
+
0.5 *
|
|
3397
|
+
cos(vec3f(phase, phase + 2.0943951, phase + 4.1887902));
|
|
3398
|
+
return mix(vec3f(1.0), thinFilmTint, iridescence);
|
|
3399
|
+
}
|
|
3400
|
+
|
|
3401
|
+
fn getVolumeAttenuation(thickness: f32) -> vec3f {
|
|
3402
|
+
if (thickness <= 0.0) {
|
|
3403
|
+
return vec3f(1.0);
|
|
3404
|
+
}
|
|
3405
|
+
|
|
3406
|
+
let attenuationCoefficient =
|
|
3407
|
+
-log(max(pbrMaterial.attenuationColor, vec3f(0.0001))) /
|
|
3408
|
+
max(pbrMaterial.attenuationDistance, 0.0001);
|
|
3409
|
+
return exp(-attenuationCoefficient * thickness);
|
|
3410
|
+
}
|
|
3411
|
+
|
|
3412
|
+
fn createClearcoatPBRInfo(
|
|
3413
|
+
basePBRInfo: PBRInfo,
|
|
3414
|
+
clearcoatNormal: vec3f,
|
|
3415
|
+
clearcoatRoughness: f32
|
|
3416
|
+
) -> PBRInfo {
|
|
3417
|
+
let perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
3418
|
+
let alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
3419
|
+
let NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);
|
|
3420
|
+
|
|
3421
|
+
return PBRInfo(
|
|
3422
|
+
basePBRInfo.NdotL,
|
|
3423
|
+
NdotV,
|
|
3424
|
+
basePBRInfo.NdotH,
|
|
3425
|
+
basePBRInfo.LdotH,
|
|
3426
|
+
basePBRInfo.VdotH,
|
|
3427
|
+
perceptualRoughness,
|
|
3428
|
+
0.0,
|
|
3429
|
+
vec3f(0.04),
|
|
3430
|
+
vec3f(1.0),
|
|
3431
|
+
alphaRoughness,
|
|
3432
|
+
vec3f(0.0),
|
|
3433
|
+
vec3f(0.04),
|
|
3434
|
+
clearcoatNormal,
|
|
3435
|
+
basePBRInfo.v
|
|
3436
|
+
);
|
|
3437
|
+
}
|
|
3438
|
+
|
|
3439
|
+
fn calculateClearcoatContribution(
|
|
3440
|
+
pbrInfo: PBRInfo,
|
|
3441
|
+
lightColor: vec3f,
|
|
3442
|
+
clearcoatNormal: vec3f,
|
|
3443
|
+
clearcoatFactor: f32,
|
|
3444
|
+
clearcoatRoughness: f32
|
|
3445
|
+
) -> vec3f {
|
|
3446
|
+
if (clearcoatFactor <= 0.0) {
|
|
3447
|
+
return vec3f(0.0);
|
|
3448
|
+
}
|
|
3449
|
+
|
|
3450
|
+
let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
3451
|
+
return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;
|
|
3452
|
+
}
|
|
3453
|
+
|
|
3454
|
+
#ifdef USE_IBL
|
|
3455
|
+
fn calculateClearcoatIBLContribution(
|
|
3456
|
+
pbrInfo: PBRInfo,
|
|
3457
|
+
clearcoatNormal: vec3f,
|
|
3458
|
+
reflection: vec3f,
|
|
3459
|
+
clearcoatFactor: f32,
|
|
3460
|
+
clearcoatRoughness: f32
|
|
3461
|
+
) -> vec3f {
|
|
3462
|
+
if (clearcoatFactor <= 0.0) {
|
|
3463
|
+
return vec3f(0.0);
|
|
3464
|
+
}
|
|
3465
|
+
|
|
3466
|
+
let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
|
|
3467
|
+
return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;
|
|
3468
|
+
}
|
|
3469
|
+
#endif
|
|
3470
|
+
|
|
3471
|
+
fn calculateSheenContribution(
|
|
3472
|
+
pbrInfo: PBRInfo,
|
|
3473
|
+
lightColor: vec3f,
|
|
3474
|
+
sheenColor: vec3f,
|
|
3475
|
+
sheenRoughness: f32
|
|
3476
|
+
) -> vec3f {
|
|
3477
|
+
if (maxComponent(sheenColor) <= 0.0) {
|
|
3478
|
+
return vec3f(0.0);
|
|
3479
|
+
}
|
|
3480
|
+
|
|
3481
|
+
let sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
|
|
3482
|
+
let sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);
|
|
3483
|
+
return pbrInfo.NdotL *
|
|
3484
|
+
lightColor *
|
|
3485
|
+
sheenColor *
|
|
3486
|
+
(0.25 + 0.75 * sheenFresnel) *
|
|
3487
|
+
sheenVisibility *
|
|
3488
|
+
(1.0 - pbrInfo.metalness);
|
|
3489
|
+
}
|
|
3490
|
+
|
|
3491
|
+
fn calculateAnisotropyBoost(
|
|
3492
|
+
pbrInfo: PBRInfo,
|
|
3493
|
+
anisotropyTangent: vec3f,
|
|
3494
|
+
anisotropyStrength: f32
|
|
3495
|
+
) -> f32 {
|
|
3496
|
+
if (anisotropyStrength <= 0.0) {
|
|
3497
|
+
return 1.0;
|
|
3498
|
+
}
|
|
3499
|
+
|
|
3500
|
+
let anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));
|
|
3501
|
+
let bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));
|
|
3502
|
+
return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);
|
|
3503
|
+
}
|
|
3504
|
+
|
|
3505
|
+
fn calculateMaterialLightColor(
|
|
3506
|
+
pbrInfo: PBRInfo,
|
|
3507
|
+
lightColor: vec3f,
|
|
3508
|
+
clearcoatNormal: vec3f,
|
|
3509
|
+
clearcoatFactor: f32,
|
|
3510
|
+
clearcoatRoughness: f32,
|
|
3511
|
+
sheenColor: vec3f,
|
|
3512
|
+
sheenRoughness: f32,
|
|
3513
|
+
anisotropyTangent: vec3f,
|
|
3514
|
+
anisotropyStrength: f32
|
|
3515
|
+
) -> vec3f {
|
|
3516
|
+
let anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
3517
|
+
var color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;
|
|
3518
|
+
color += calculateClearcoatContribution(
|
|
3519
|
+
pbrInfo,
|
|
3520
|
+
lightColor,
|
|
3521
|
+
clearcoatNormal,
|
|
3522
|
+
clearcoatFactor,
|
|
3523
|
+
clearcoatRoughness
|
|
3524
|
+
);
|
|
3525
|
+
color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);
|
|
3526
|
+
return color;
|
|
3527
|
+
}
|
|
3528
|
+
|
|
2367
3529
|
fn PBRInfo_setAmbientLight(pbrInfo: ptr<function, PBRInfo>) {
|
|
2368
3530
|
(*pbrInfo).NdotL = 1.0;
|
|
2369
3531
|
(*pbrInfo).NdotH = 0.0;
|
|
@@ -2388,6 +3550,11 @@ fn PBRInfo_setPointLight(pbrInfo: ptr<function, PBRInfo>, pointLight: PointLight
|
|
|
2388
3550
|
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
2389
3551
|
}
|
|
2390
3552
|
|
|
3553
|
+
fn PBRInfo_setSpotLight(pbrInfo: ptr<function, PBRInfo>, spotLight: SpotLight) {
|
|
3554
|
+
let light_direction = normalize(spotLight.position - fragmentInputs.pbr_vPosition);
|
|
3555
|
+
PBRInfo_setDirectionalLight(pbrInfo, light_direction);
|
|
3556
|
+
}
|
|
3557
|
+
|
|
2391
3558
|
fn calculateFinalColor(pbrInfo: PBRInfo, lightColor: vec3<f32>) -> vec3<f32> {
|
|
2392
3559
|
// Calculate the shading terms for the microfacet specular shading model
|
|
2393
3560
|
let F = specularReflection(pbrInfo);
|
|
@@ -2417,6 +3584,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
2417
3584
|
#endif
|
|
2418
3585
|
|
|
2419
3586
|
var color = vec3<f32>(0.0, 0.0, 0.0);
|
|
3587
|
+
var transmission = 0.0;
|
|
2420
3588
|
|
|
2421
3589
|
if (pbrMaterial.unlit != 0u) {
|
|
2422
3590
|
color = baseColor.rgb;
|
|
@@ -2439,14 +3607,308 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
2439
3607
|
#endif
|
|
2440
3608
|
perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
|
|
2441
3609
|
metallic = clamp(metallic, 0.0, 1.0);
|
|
3610
|
+
let tbn = getTBN();
|
|
3611
|
+
let n = getNormal(tbn); // normal at surface point
|
|
3612
|
+
let v = normalize(pbrProjection.camera - fragmentInputs.pbr_vPosition); // Vector from surface point to camera
|
|
3613
|
+
let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
3614
|
+
var useExtendedPBR = false;
|
|
3615
|
+
#ifdef USE_MATERIAL_EXTENSIONS
|
|
3616
|
+
useExtendedPBR =
|
|
3617
|
+
pbrMaterial.specularColorMapEnabled != 0 ||
|
|
3618
|
+
pbrMaterial.specularIntensityMapEnabled != 0 ||
|
|
3619
|
+
abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||
|
|
3620
|
+
maxComponent(abs(pbrMaterial.specularColorFactor - vec3f(1.0))) > 0.0001 ||
|
|
3621
|
+
abs(pbrMaterial.ior - 1.5) > 0.0001 ||
|
|
3622
|
+
pbrMaterial.transmissionMapEnabled != 0 ||
|
|
3623
|
+
pbrMaterial.transmissionFactor > 0.0001 ||
|
|
3624
|
+
pbrMaterial.clearcoatMapEnabled != 0 ||
|
|
3625
|
+
pbrMaterial.clearcoatRoughnessMapEnabled != 0 ||
|
|
3626
|
+
pbrMaterial.clearcoatFactor > 0.0001 ||
|
|
3627
|
+
pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||
|
|
3628
|
+
pbrMaterial.sheenColorMapEnabled != 0 ||
|
|
3629
|
+
pbrMaterial.sheenRoughnessMapEnabled != 0 ||
|
|
3630
|
+
maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||
|
|
3631
|
+
pbrMaterial.sheenRoughnessFactor > 0.0001 ||
|
|
3632
|
+
pbrMaterial.iridescenceMapEnabled != 0 ||
|
|
3633
|
+
pbrMaterial.iridescenceFactor > 0.0001 ||
|
|
3634
|
+
abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||
|
|
3635
|
+
abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||
|
|
3636
|
+
abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||
|
|
3637
|
+
pbrMaterial.anisotropyMapEnabled != 0 ||
|
|
3638
|
+
pbrMaterial.anisotropyStrength > 0.0001 ||
|
|
3639
|
+
abs(pbrMaterial.anisotropyRotation) > 0.0001 ||
|
|
3640
|
+
length(pbrMaterial.anisotropyDirection - vec2f(1.0, 0.0)) > 0.0001;
|
|
3641
|
+
#endif
|
|
3642
|
+
|
|
3643
|
+
if (!useExtendedPBR) {
|
|
3644
|
+
let alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
3645
|
+
|
|
3646
|
+
let f0 = vec3<f32>(0.04);
|
|
3647
|
+
var diffuseColor = baseColor.rgb * (vec3<f32>(1.0) - f0);
|
|
3648
|
+
diffuseColor *= 1.0 - metallic;
|
|
3649
|
+
let specularColor = mix(f0, baseColor.rgb, metallic);
|
|
3650
|
+
|
|
3651
|
+
let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
3652
|
+
let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
3653
|
+
let specularEnvironmentR0 = specularColor;
|
|
3654
|
+
let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;
|
|
3655
|
+
let reflection = -normalize(reflect(v, n));
|
|
3656
|
+
|
|
3657
|
+
var pbrInfo = PBRInfo(
|
|
3658
|
+
0.0, // NdotL
|
|
3659
|
+
NdotV,
|
|
3660
|
+
0.0, // NdotH
|
|
3661
|
+
0.0, // LdotH
|
|
3662
|
+
0.0, // VdotH
|
|
3663
|
+
perceptualRoughness,
|
|
3664
|
+
metallic,
|
|
3665
|
+
specularEnvironmentR0,
|
|
3666
|
+
specularEnvironmentR90,
|
|
3667
|
+
alphaRoughness,
|
|
3668
|
+
diffuseColor,
|
|
3669
|
+
specularColor,
|
|
3670
|
+
n,
|
|
3671
|
+
v
|
|
3672
|
+
);
|
|
3673
|
+
|
|
3674
|
+
#ifdef USE_LIGHTS
|
|
3675
|
+
PBRInfo_setAmbientLight(&pbrInfo);
|
|
3676
|
+
color += calculateFinalColor(pbrInfo, lighting.ambientColor);
|
|
3677
|
+
|
|
3678
|
+
for (var i = 0; i < lighting.directionalLightCount; i++) {
|
|
3679
|
+
if (i < lighting.directionalLightCount) {
|
|
3680
|
+
PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
3681
|
+
color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
|
|
3682
|
+
}
|
|
3683
|
+
}
|
|
3684
|
+
|
|
3685
|
+
for (var i = 0; i < lighting.pointLightCount; i++) {
|
|
3686
|
+
if (i < lighting.pointLightCount) {
|
|
3687
|
+
PBRInfo_setPointLight(&pbrInfo, lighting_getPointLight(i));
|
|
3688
|
+
let attenuation = getPointLightAttenuation(
|
|
3689
|
+
lighting_getPointLight(i),
|
|
3690
|
+
distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)
|
|
3691
|
+
);
|
|
3692
|
+
color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
|
|
3693
|
+
}
|
|
3694
|
+
}
|
|
3695
|
+
|
|
3696
|
+
for (var i = 0; i < lighting.spotLightCount; i++) {
|
|
3697
|
+
if (i < lighting.spotLightCount) {
|
|
3698
|
+
PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));
|
|
3699
|
+
let attenuation = getSpotLightAttenuation(
|
|
3700
|
+
lighting_getSpotLight(i),
|
|
3701
|
+
fragmentInputs.pbr_vPosition
|
|
3702
|
+
);
|
|
3703
|
+
color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);
|
|
3704
|
+
}
|
|
3705
|
+
}
|
|
3706
|
+
#endif
|
|
3707
|
+
|
|
3708
|
+
#ifdef USE_IBL
|
|
3709
|
+
if (pbrMaterial.IBLenabled != 0) {
|
|
3710
|
+
color += getIBLContribution(pbrInfo, n, reflection);
|
|
3711
|
+
}
|
|
3712
|
+
#endif
|
|
3713
|
+
|
|
3714
|
+
#ifdef HAS_OCCLUSIONMAP
|
|
3715
|
+
if (pbrMaterial.occlusionMapEnabled != 0) {
|
|
3716
|
+
let ao =
|
|
3717
|
+
textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, fragmentInputs.pbr_vUV).r;
|
|
3718
|
+
color = mix(color, color * ao, pbrMaterial.occlusionStrength);
|
|
3719
|
+
}
|
|
3720
|
+
#endif
|
|
3721
|
+
|
|
3722
|
+
var emissive = pbrMaterial.emissiveFactor;
|
|
3723
|
+
#ifdef HAS_EMISSIVEMAP
|
|
3724
|
+
if (pbrMaterial.emissiveMapEnabled != 0u) {
|
|
3725
|
+
emissive *= SRGBtoLINEAR(
|
|
3726
|
+
textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, fragmentInputs.pbr_vUV)
|
|
3727
|
+
).rgb;
|
|
3728
|
+
}
|
|
3729
|
+
#endif
|
|
3730
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
3731
|
+
|
|
3732
|
+
#ifdef PBR_DEBUG
|
|
3733
|
+
color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
|
|
3734
|
+
color = mix(color, vec3<f32>(metallic), pbrMaterial.scaleDiffBaseMR.z);
|
|
3735
|
+
color = mix(color, vec3<f32>(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
|
|
3736
|
+
#endif
|
|
3737
|
+
|
|
3738
|
+
return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), baseColor.a);
|
|
3739
|
+
}
|
|
3740
|
+
|
|
3741
|
+
var specularIntensity = pbrMaterial.specularIntensityFactor;
|
|
3742
|
+
#ifdef HAS_SPECULARINTENSITYMAP
|
|
3743
|
+
if (pbrMaterial.specularIntensityMapEnabled != 0) {
|
|
3744
|
+
specularIntensity *= textureSample(
|
|
3745
|
+
pbr_specularIntensitySampler,
|
|
3746
|
+
pbr_specularIntensitySamplerSampler,
|
|
3747
|
+
fragmentInputs.pbr_vUV
|
|
3748
|
+
).a;
|
|
3749
|
+
}
|
|
3750
|
+
#endif
|
|
3751
|
+
|
|
3752
|
+
var specularFactor = pbrMaterial.specularColorFactor;
|
|
3753
|
+
#ifdef HAS_SPECULARCOLORMAP
|
|
3754
|
+
if (pbrMaterial.specularColorMapEnabled != 0) {
|
|
3755
|
+
specularFactor *= SRGBtoLINEAR(
|
|
3756
|
+
textureSample(
|
|
3757
|
+
pbr_specularColorSampler,
|
|
3758
|
+
pbr_specularColorSamplerSampler,
|
|
3759
|
+
fragmentInputs.pbr_vUV
|
|
3760
|
+
)
|
|
3761
|
+
).rgb;
|
|
3762
|
+
}
|
|
3763
|
+
#endif
|
|
3764
|
+
|
|
3765
|
+
transmission = pbrMaterial.transmissionFactor;
|
|
3766
|
+
#ifdef HAS_TRANSMISSIONMAP
|
|
3767
|
+
if (pbrMaterial.transmissionMapEnabled != 0) {
|
|
3768
|
+
transmission *= textureSample(
|
|
3769
|
+
pbr_transmissionSampler,
|
|
3770
|
+
pbr_transmissionSamplerSampler,
|
|
3771
|
+
fragmentInputs.pbr_vUV
|
|
3772
|
+
).r;
|
|
3773
|
+
}
|
|
3774
|
+
#endif
|
|
3775
|
+
transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);
|
|
3776
|
+
var thickness = max(pbrMaterial.thicknessFactor, 0.0);
|
|
3777
|
+
#ifdef HAS_THICKNESSMAP
|
|
3778
|
+
thickness *= textureSample(
|
|
3779
|
+
pbr_thicknessSampler,
|
|
3780
|
+
pbr_thicknessSamplerSampler,
|
|
3781
|
+
fragmentInputs.pbr_vUV
|
|
3782
|
+
).g;
|
|
3783
|
+
#endif
|
|
3784
|
+
|
|
3785
|
+
var clearcoatFactor = pbrMaterial.clearcoatFactor;
|
|
3786
|
+
var clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;
|
|
3787
|
+
#ifdef HAS_CLEARCOATMAP
|
|
3788
|
+
if (pbrMaterial.clearcoatMapEnabled != 0) {
|
|
3789
|
+
clearcoatFactor *= textureSample(
|
|
3790
|
+
pbr_clearcoatSampler,
|
|
3791
|
+
pbr_clearcoatSamplerSampler,
|
|
3792
|
+
fragmentInputs.pbr_vUV
|
|
3793
|
+
).r;
|
|
3794
|
+
}
|
|
3795
|
+
#endif
|
|
3796
|
+
#ifdef HAS_CLEARCOATROUGHNESSMAP
|
|
3797
|
+
if (pbrMaterial.clearcoatRoughnessMapEnabled != 0) {
|
|
3798
|
+
clearcoatRoughness *= textureSample(
|
|
3799
|
+
pbr_clearcoatRoughnessSampler,
|
|
3800
|
+
pbr_clearcoatRoughnessSamplerSampler,
|
|
3801
|
+
fragmentInputs.pbr_vUV
|
|
3802
|
+
).g;
|
|
3803
|
+
}
|
|
3804
|
+
#endif
|
|
3805
|
+
clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);
|
|
3806
|
+
clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
|
|
3807
|
+
let clearcoatNormal = getClearcoatNormal(tbn, n);
|
|
3808
|
+
|
|
3809
|
+
var sheenColor = pbrMaterial.sheenColorFactor;
|
|
3810
|
+
var sheenRoughness = pbrMaterial.sheenRoughnessFactor;
|
|
3811
|
+
#ifdef HAS_SHEENCOLORMAP
|
|
3812
|
+
if (pbrMaterial.sheenColorMapEnabled != 0) {
|
|
3813
|
+
sheenColor *= SRGBtoLINEAR(
|
|
3814
|
+
textureSample(
|
|
3815
|
+
pbr_sheenColorSampler,
|
|
3816
|
+
pbr_sheenColorSamplerSampler,
|
|
3817
|
+
fragmentInputs.pbr_vUV
|
|
3818
|
+
)
|
|
3819
|
+
).rgb;
|
|
3820
|
+
}
|
|
3821
|
+
#endif
|
|
3822
|
+
#ifdef HAS_SHEENROUGHNESSMAP
|
|
3823
|
+
if (pbrMaterial.sheenRoughnessMapEnabled != 0) {
|
|
3824
|
+
sheenRoughness *= textureSample(
|
|
3825
|
+
pbr_sheenRoughnessSampler,
|
|
3826
|
+
pbr_sheenRoughnessSamplerSampler,
|
|
3827
|
+
fragmentInputs.pbr_vUV
|
|
3828
|
+
).a;
|
|
3829
|
+
}
|
|
3830
|
+
#endif
|
|
3831
|
+
sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);
|
|
3832
|
+
|
|
3833
|
+
var iridescence = pbrMaterial.iridescenceFactor;
|
|
3834
|
+
#ifdef HAS_IRIDESCENCEMAP
|
|
3835
|
+
if (pbrMaterial.iridescenceMapEnabled != 0) {
|
|
3836
|
+
iridescence *= textureSample(
|
|
3837
|
+
pbr_iridescenceSampler,
|
|
3838
|
+
pbr_iridescenceSamplerSampler,
|
|
3839
|
+
fragmentInputs.pbr_vUV
|
|
3840
|
+
).r;
|
|
3841
|
+
}
|
|
3842
|
+
#endif
|
|
3843
|
+
iridescence = clamp(iridescence, 0.0, 1.0);
|
|
3844
|
+
var iridescenceThickness = mix(
|
|
3845
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
3846
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
3847
|
+
0.5
|
|
3848
|
+
);
|
|
3849
|
+
#ifdef HAS_IRIDESCENCETHICKNESSMAP
|
|
3850
|
+
iridescenceThickness = mix(
|
|
3851
|
+
pbrMaterial.iridescenceThicknessRange.x,
|
|
3852
|
+
pbrMaterial.iridescenceThicknessRange.y,
|
|
3853
|
+
textureSample(
|
|
3854
|
+
pbr_iridescenceThicknessSampler,
|
|
3855
|
+
pbr_iridescenceThicknessSamplerSampler,
|
|
3856
|
+
fragmentInputs.pbr_vUV
|
|
3857
|
+
).g
|
|
3858
|
+
);
|
|
3859
|
+
#endif
|
|
3860
|
+
|
|
3861
|
+
var anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);
|
|
3862
|
+
var anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);
|
|
3863
|
+
#ifdef HAS_ANISOTROPYMAP
|
|
3864
|
+
if (pbrMaterial.anisotropyMapEnabled != 0) {
|
|
3865
|
+
let anisotropySample = textureSample(
|
|
3866
|
+
pbr_anisotropySampler,
|
|
3867
|
+
pbr_anisotropySamplerSampler,
|
|
3868
|
+
fragmentInputs.pbr_vUV
|
|
3869
|
+
).rgb;
|
|
3870
|
+
anisotropyStrength *= anisotropySample.b;
|
|
3871
|
+
let mappedDirection = anisotropySample.rg * 2.0 - 1.0;
|
|
3872
|
+
if (length(mappedDirection) > 0.0001) {
|
|
3873
|
+
anisotropyDirection = normalize(mappedDirection);
|
|
3874
|
+
}
|
|
3875
|
+
}
|
|
3876
|
+
#endif
|
|
3877
|
+
anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);
|
|
3878
|
+
var anisotropyTangent =
|
|
3879
|
+
normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);
|
|
3880
|
+
if (length(anisotropyTangent) < 0.0001) {
|
|
3881
|
+
anisotropyTangent = normalize(tbn[0]);
|
|
3882
|
+
}
|
|
3883
|
+
let anisotropyViewAlignment = abs(dot(v, anisotropyTangent));
|
|
3884
|
+
perceptualRoughness = mix(
|
|
3885
|
+
perceptualRoughness,
|
|
3886
|
+
clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),
|
|
3887
|
+
anisotropyStrength
|
|
3888
|
+
);
|
|
3889
|
+
|
|
2442
3890
|
// Roughness is authored as perceptual roughness; as is convention,
|
|
2443
3891
|
// convert to material roughness by squaring the perceptual roughness [2].
|
|
2444
3892
|
let alphaRoughness = perceptualRoughness * perceptualRoughness;
|
|
2445
3893
|
|
|
2446
|
-
let
|
|
2447
|
-
var
|
|
2448
|
-
|
|
2449
|
-
|
|
3894
|
+
let dielectricF0 = getDielectricF0(pbrMaterial.ior);
|
|
3895
|
+
var dielectricSpecularF0 = min(
|
|
3896
|
+
vec3f(dielectricF0) * specularFactor * specularIntensity,
|
|
3897
|
+
vec3f(1.0)
|
|
3898
|
+
);
|
|
3899
|
+
let iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);
|
|
3900
|
+
dielectricSpecularF0 = mix(
|
|
3901
|
+
dielectricSpecularF0,
|
|
3902
|
+
dielectricSpecularF0 * iridescenceTint,
|
|
3903
|
+
iridescence
|
|
3904
|
+
);
|
|
3905
|
+
var diffuseColor = baseColor.rgb * (vec3f(1.0) - dielectricSpecularF0);
|
|
3906
|
+
diffuseColor *= (1.0 - metallic) * (1.0 - transmission);
|
|
3907
|
+
var specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);
|
|
3908
|
+
|
|
3909
|
+
let baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;
|
|
3910
|
+
diffuseColor *= baseLayerEnergy;
|
|
3911
|
+
specularColor *= baseLayerEnergy;
|
|
2450
3912
|
|
|
2451
3913
|
// Compute reflectance.
|
|
2452
3914
|
let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
|
|
@@ -2458,11 +3920,6 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
2458
3920
|
let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
|
|
2459
3921
|
let specularEnvironmentR0 = specularColor;
|
|
2460
3922
|
let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;
|
|
2461
|
-
|
|
2462
|
-
let n = getNormal(); // normal at surface point
|
|
2463
|
-
let v = normalize(pbrProjection.camera - fragmentInputs.pbr_vPosition); // Vector from surface point to camera
|
|
2464
|
-
|
|
2465
|
-
let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
|
|
2466
3923
|
let reflection = -normalize(reflect(v, n));
|
|
2467
3924
|
|
|
2468
3925
|
var pbrInfo = PBRInfo(
|
|
@@ -2485,13 +3942,33 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
2485
3942
|
#ifdef USE_LIGHTS
|
|
2486
3943
|
// Apply ambient light
|
|
2487
3944
|
PBRInfo_setAmbientLight(&pbrInfo);
|
|
2488
|
-
color +=
|
|
3945
|
+
color += calculateMaterialLightColor(
|
|
3946
|
+
pbrInfo,
|
|
3947
|
+
lighting.ambientColor,
|
|
3948
|
+
clearcoatNormal,
|
|
3949
|
+
clearcoatFactor,
|
|
3950
|
+
clearcoatRoughness,
|
|
3951
|
+
sheenColor,
|
|
3952
|
+
sheenRoughness,
|
|
3953
|
+
anisotropyTangent,
|
|
3954
|
+
anisotropyStrength
|
|
3955
|
+
);
|
|
2489
3956
|
|
|
2490
3957
|
// Apply directional light
|
|
2491
3958
|
for (var i = 0; i < lighting.directionalLightCount; i++) {
|
|
2492
3959
|
if (i < lighting.directionalLightCount) {
|
|
2493
3960
|
PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
|
|
2494
|
-
color +=
|
|
3961
|
+
color += calculateMaterialLightColor(
|
|
3962
|
+
pbrInfo,
|
|
3963
|
+
lighting_getDirectionalLight(i).color,
|
|
3964
|
+
clearcoatNormal,
|
|
3965
|
+
clearcoatFactor,
|
|
3966
|
+
clearcoatRoughness,
|
|
3967
|
+
sheenColor,
|
|
3968
|
+
sheenRoughness,
|
|
3969
|
+
anisotropyTangent,
|
|
3970
|
+
anisotropyStrength
|
|
3971
|
+
);
|
|
2495
3972
|
}
|
|
2496
3973
|
}
|
|
2497
3974
|
|
|
@@ -2503,7 +3980,35 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
2503
3980
|
lighting_getPointLight(i),
|
|
2504
3981
|
distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)
|
|
2505
3982
|
);
|
|
2506
|
-
color +=
|
|
3983
|
+
color += calculateMaterialLightColor(
|
|
3984
|
+
pbrInfo,
|
|
3985
|
+
lighting_getPointLight(i).color / attenuation,
|
|
3986
|
+
clearcoatNormal,
|
|
3987
|
+
clearcoatFactor,
|
|
3988
|
+
clearcoatRoughness,
|
|
3989
|
+
sheenColor,
|
|
3990
|
+
sheenRoughness,
|
|
3991
|
+
anisotropyTangent,
|
|
3992
|
+
anisotropyStrength
|
|
3993
|
+
);
|
|
3994
|
+
}
|
|
3995
|
+
}
|
|
3996
|
+
|
|
3997
|
+
for (var i = 0; i < lighting.spotLightCount; i++) {
|
|
3998
|
+
if (i < lighting.spotLightCount) {
|
|
3999
|
+
PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));
|
|
4000
|
+
let attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), fragmentInputs.pbr_vPosition);
|
|
4001
|
+
color += calculateMaterialLightColor(
|
|
4002
|
+
pbrInfo,
|
|
4003
|
+
lighting_getSpotLight(i).color / attenuation,
|
|
4004
|
+
clearcoatNormal,
|
|
4005
|
+
clearcoatFactor,
|
|
4006
|
+
clearcoatRoughness,
|
|
4007
|
+
sheenColor,
|
|
4008
|
+
sheenRoughness,
|
|
4009
|
+
anisotropyTangent,
|
|
4010
|
+
anisotropyStrength
|
|
4011
|
+
);
|
|
2507
4012
|
}
|
|
2508
4013
|
}
|
|
2509
4014
|
#endif
|
|
@@ -2511,7 +4016,16 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
2511
4016
|
// Calculate lighting contribution from image based lighting source (IBL)
|
|
2512
4017
|
#ifdef USE_IBL
|
|
2513
4018
|
if (pbrMaterial.IBLenabled != 0) {
|
|
2514
|
-
color += getIBLContribution(pbrInfo, n, reflection)
|
|
4019
|
+
color += getIBLContribution(pbrInfo, n, reflection) *
|
|
4020
|
+
calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
|
|
4021
|
+
color += calculateClearcoatIBLContribution(
|
|
4022
|
+
pbrInfo,
|
|
4023
|
+
clearcoatNormal,
|
|
4024
|
+
-normalize(reflect(v, clearcoatNormal)),
|
|
4025
|
+
clearcoatFactor,
|
|
4026
|
+
clearcoatRoughness
|
|
4027
|
+
);
|
|
4028
|
+
color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;
|
|
2515
4029
|
}
|
|
2516
4030
|
#endif
|
|
2517
4031
|
|
|
@@ -2524,14 +4038,19 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
2524
4038
|
}
|
|
2525
4039
|
#endif
|
|
2526
4040
|
|
|
4041
|
+
var emissive = pbrMaterial.emissiveFactor;
|
|
2527
4042
|
#ifdef HAS_EMISSIVEMAP
|
|
2528
4043
|
if (pbrMaterial.emissiveMapEnabled != 0u) {
|
|
2529
|
-
|
|
4044
|
+
emissive *= SRGBtoLINEAR(
|
|
2530
4045
|
textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, fragmentInputs.pbr_vUV)
|
|
2531
|
-
).rgb
|
|
2532
|
-
color += emissive;
|
|
4046
|
+
).rgb;
|
|
2533
4047
|
}
|
|
2534
4048
|
#endif
|
|
4049
|
+
color += emissive * pbrMaterial.emissiveStrength;
|
|
4050
|
+
|
|
4051
|
+
if (transmission > 0.0) {
|
|
4052
|
+
color = mix(color, color * getVolumeAttenuation(thickness), transmission);
|
|
4053
|
+
}
|
|
2535
4054
|
|
|
2536
4055
|
// This section uses mix to override final color for reference app visualization
|
|
2537
4056
|
// of various parameters in the lighting equation.
|
|
@@ -2550,22 +4069,23 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
|
|
|
2550
4069
|
#endif
|
|
2551
4070
|
}
|
|
2552
4071
|
|
|
2553
|
-
|
|
4072
|
+
let alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);
|
|
4073
|
+
return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), alpha);
|
|
2554
4074
|
}
|
|
2555
|
-
`;var
|
|
4075
|
+
`;var In=`uniform pbrProjectionUniforms {
|
|
2556
4076
|
mat4 modelViewProjectionMatrix;
|
|
2557
4077
|
mat4 modelMatrix;
|
|
2558
4078
|
mat4 normalMatrix;
|
|
2559
4079
|
vec3 camera;
|
|
2560
4080
|
} pbrProjection;
|
|
2561
|
-
`,
|
|
4081
|
+
`,uo=`struct pbrProjectionUniforms {
|
|
2562
4082
|
modelViewProjectionMatrix: mat4x4<f32>,
|
|
2563
4083
|
modelMatrix: mat4x4<f32>,
|
|
2564
4084
|
normalMatrix: mat4x4<f32>,
|
|
2565
4085
|
camera: vec3<f32>
|
|
2566
4086
|
};
|
|
2567
4087
|
|
|
2568
|
-
@
|
|
2569
|
-
`,
|
|
4088
|
+
@group(0) @binding(auto) var<uniform> pbrProjection: pbrProjectionUniforms;
|
|
4089
|
+
`,Cn={name:"pbrProjection",bindingLayout:[{name:"pbrProjection",group:0}],source:uo,vs:In,fs:In,getUniforms:e=>e,uniformTypes:{modelViewProjectionMatrix:"mat4x4<f32>",modelMatrix:"mat4x4<f32>",normalMatrix:"mat4x4<f32>",camera:"vec3<f32>"}};var Pn={props:{},uniforms:{},defaultUniforms:{unlit:!1,baseColorMapEnabled:!1,baseColorFactor:[1,1,1,1],normalMapEnabled:!1,normalScale:1,emissiveMapEnabled:!1,emissiveFactor:[0,0,0],metallicRoughnessValues:[1,1],metallicRoughnessMapEnabled:!1,occlusionMapEnabled:!1,occlusionStrength:1,alphaCutoffEnabled:!1,alphaCutoff:.5,IBLenabled:!1,scaleIBLAmbient:[1,1],scaleDiffBaseMR:[0,0,0,0],scaleFGDSpec:[0,0,0,0],specularColorFactor:[1,1,1],specularIntensityFactor:1,specularColorMapEnabled:!1,specularIntensityMapEnabled:!1,ior:1.5,transmissionFactor:0,transmissionMapEnabled:!1,thicknessFactor:0,attenuationDistance:1e9,attenuationColor:[1,1,1],clearcoatFactor:0,clearcoatRoughnessFactor:0,clearcoatMapEnabled:!1,clearcoatRoughnessMapEnabled:!1,sheenColorFactor:[0,0,0],sheenRoughnessFactor:0,sheenColorMapEnabled:!1,sheenRoughnessMapEnabled:!1,iridescenceFactor:0,iridescenceIor:1.3,iridescenceThicknessRange:[100,400],iridescenceMapEnabled:!1,anisotropyStrength:0,anisotropyRotation:0,anisotropyDirection:[1,0],anisotropyMapEnabled:!1,emissiveStrength:1},name:"pbrMaterial",firstBindingSlot:0,bindingLayout:[{name:"pbrMaterial",group:3},{name:"pbr_baseColorSampler",group:3},{name:"pbr_normalSampler",group:3},{name:"pbr_emissiveSampler",group:3},{name:"pbr_metallicRoughnessSampler",group:3},{name:"pbr_occlusionSampler",group:3},{name:"pbr_specularColorSampler",group:3},{name:"pbr_specularIntensitySampler",group:3},{name:"pbr_transmissionSampler",group:3},{name:"pbr_thicknessSampler",group:3},{name:"pbr_clearcoatSampler",group:3},{name:"pbr_clearcoatRoughnessSampler",group:3},{name:"pbr_clearcoatNormalSampler",group:3},{name:"pbr_sheenColorSampler",group:3},{name:"pbr_sheenRoughnessSampler",group:3},{name:"pbr_iridescenceSampler",group:3},{name:"pbr_iridescenceThicknessSampler",group:3},{name:"pbr_anisotropySampler",group:3}],dependencies:[F,Le,Cn],source:Rn,vs:An,fs:En,defines:{LIGHTING_FRAGMENT:!0,HAS_NORMALMAP:!1,HAS_EMISSIVEMAP:!1,HAS_OCCLUSIONMAP:!1,HAS_BASECOLORMAP:!1,HAS_METALROUGHNESSMAP:!1,HAS_SPECULARCOLORMAP:!1,HAS_SPECULARINTENSITYMAP:!1,HAS_TRANSMISSIONMAP:!1,HAS_THICKNESSMAP:!1,HAS_CLEARCOATMAP:!1,HAS_CLEARCOATROUGHNESSMAP:!1,HAS_CLEARCOATNORMALMAP:!1,HAS_SHEENCOLORMAP:!1,HAS_SHEENROUGHNESSMAP:!1,HAS_IRIDESCENCEMAP:!1,HAS_IRIDESCENCETHICKNESSMAP:!1,HAS_ANISOTROPYMAP:!1,USE_MATERIAL_EXTENSIONS:!1,ALPHA_CUTOFF:!1,USE_IBL:!1,PBR_DEBUG:!1},getUniforms:e=>e,uniformTypes:{unlit:"i32",baseColorMapEnabled:"i32",baseColorFactor:"vec4<f32>",normalMapEnabled:"i32",normalScale:"f32",emissiveMapEnabled:"i32",emissiveFactor:"vec3<f32>",metallicRoughnessValues:"vec2<f32>",metallicRoughnessMapEnabled:"i32",occlusionMapEnabled:"i32",occlusionStrength:"f32",alphaCutoffEnabled:"i32",alphaCutoff:"f32",specularColorFactor:"vec3<f32>",specularIntensityFactor:"f32",specularColorMapEnabled:"i32",specularIntensityMapEnabled:"i32",ior:"f32",transmissionFactor:"f32",transmissionMapEnabled:"i32",thicknessFactor:"f32",attenuationDistance:"f32",attenuationColor:"vec3<f32>",clearcoatFactor:"f32",clearcoatRoughnessFactor:"f32",clearcoatMapEnabled:"i32",clearcoatRoughnessMapEnabled:"i32",sheenColorFactor:"vec3<f32>",sheenRoughnessFactor:"f32",sheenColorMapEnabled:"i32",sheenRoughnessMapEnabled:"i32",iridescenceFactor:"f32",iridescenceIor:"f32",iridescenceThicknessRange:"vec2<f32>",iridescenceMapEnabled:"i32",anisotropyStrength:"f32",anisotropyRotation:"f32",anisotropyDirection:"vec2<f32>",anisotropyMapEnabled:"i32",emissiveStrength:"f32",IBLenabled:"i32",scaleIBLAmbient:"vec2<f32>",scaleDiffBaseMR:"vec4<f32>",scaleFGDSpec:"vec4<f32>"}};return Dn(ne);})();
|
|
2570
4090
|
return __exports__;
|
|
2571
4091
|
});
|