UNPKG

@animech-public/playcanvas

Version:
2 lines (1 loc) 4.55 kB
import{uniformTypeToName as t,SHADERSTAGE_VERTEX as e,SHADERSTAGE_FRAGMENT as s,BINDGROUP_MESH as r,semanticToLocation as a,TYPE_FLOAT32 as n,TYPE_FLOAT16 as i,TEXTUREDIMENSION_2D as o,TEXTUREDIMENSION_3D as c,TEXTUREDIMENSION_CUBE as u,TEXTUREDIMENSION_2D_ARRAY as p,UNIFORM_BUFFER_DEFAULT_SLOT_NAME as m,SAMPLETYPE_FLOAT as l,SAMPLETYPE_INT as h,SAMPLETYPE_UINT as f,SAMPLETYPE_UNFILTERABLE_FLOAT as d,SAMPLETYPE_DEPTH as b,TYPE_INT8 as g,TYPE_INT16 as y,TYPE_INT32 as $}from"./constants.js";import{UniformFormat as x,UniformBufferFormat as S}from"./uniform-buffer-format.js";import{BindTextureFormat as w,BindGroupFormat as D,BindUniformBufferFormat as v}from"./bind-group-format.js";const O=/[ \t]*(\battribute\b|\bvarying\b|\buniform\b)/g,E=/(\battribute\b|\bvarying\b|\bout\b|\buniform\b)[ \t]*([^;]+)(;+)/g,I="@@@",T=/([\w-]+)\[(.*?)\]/,A=new Set(["highp","mediump","lowp"]),F=new Set(["sampler2DShadow","samplerCubeShadow","sampler2DArrayShadow"]),U={sampler2D:o,sampler3D:c,samplerCube:u,samplerCubeShadow:u,sampler2DShadow:o,sampler2DArray:p,sampler2DArrayShadow:p,isampler2D:o,usampler2D:o,isampler3D:c,usampler3D:c,isamplerCube:u,usamplerCube:u,isampler2DArray:p,usampler2DArray:p};class C{constructor(t,e){this.line=t;const s=t.trim().split(/\s+/);if(A.has(s[0])&&(this.precision=s.shift()),this.type=s.shift(),t.includes(","),t.includes("[")){const t=s.join(" "),r=T.exec(t);this.name=r[1],this.arraySize=Number(r[2]),isNaN(this.arraySize)&&(e.failed=!0)}else this.name=s.shift(),this.arraySize=0;this.isSampler=-1!==this.type.indexOf("sampler"),this.isSignedInt=-1!==this.type.indexOf("isampler"),this.isUnsignedInt=-1!==this.type.indexOf("usampler")}}class B{static run(t,e,s){const r=new Map,a=B.extract(e.vshader),n=B.extract(e.fshader),i=B.processAttributes(a.attributes,e.attributes,e.processingOptions),o=B.processVaryings(a.varyings,r,!0),c=B.processVaryings(n.varyings,r,!1),u=B.processOuts(n.outs),p=a.uniforms.concat(n.uniforms),m=Array.from(new Set(p)).map((t=>new C(t,s))),l=B.processUniforms(t,m,e.processingOptions,s),h=`${i}\n${o}\n${l.code}`,f=a.src.replace(I,h),d=`${c}\n${u}\n${l.code}`;return{vshader:f,fshader:n.src.replace(I,d),meshUniformBufferFormat:l.meshUniformBufferFormat,meshBindGroupFormat:l.meshBindGroupFormat}}static extract(t){const e=[],s=[],r=[],a=[];let n,i=`${I}\n`;for(;null!==(n=O.exec(t));){const o=n[1];switch(o){case"attribute":case"varying":case"uniform":case"out":{E.lastIndex=n.index;const c=E.exec(t);"attribute"===o?e.push(c[2]):"varying"===o?s.push(c[2]):"out"===o?r.push(c[2]):"uniform"===o&&a.push(c[2]),t=B.cutOut(t,n.index,E.lastIndex,i),O.lastIndex=n.index+i.length,i="";break}}}return{src:t,attributes:e,varyings:s,outs:r,uniforms:a}}static processUniforms(a,n,i,o){const c=[],u=[];n.forEach((t=>{t.isSampler?c.push(t):u.push(t)}));const p=[];u.forEach((e=>{if(!i.hasUniform(e.name)){const s=t.indexOf(e.type),r=new x(e.name,s,e.arraySize);p.push(r)}}));const g=p.length?new S(a,p):null,y=[];g&&y.push(new v(m,e|s));const $=[];c.forEach((t=>{if(!i.hasTexture(t.name)){let r=l;t.isSignedInt?r=h:t.isUnsignedInt?r=f:("highp"===t.precision&&(r=d),F.has(t.type)&&(r=b));const a=U[t.type];$.push(new w(t.name,e|s,a,r))}}));const O=new D(a,[...y,...$]);let E="";return i.uniformFormats.forEach(((t,e)=>{t&&(E+=t.getShaderDeclaration(e,0))})),g&&(E+=g.getShaderDeclaration(r,0)),i.bindGroupFormats.forEach(((t,e)=>{t&&(E+=t.getShaderDeclarationTextures(e))})),E+=O.getShaderDeclarationTextures(r),{code:E,meshUniformBufferFormat:g,meshBindGroupFormat:O}}static processVaryings(t,e,s){let r="";const a=s?"out":"in";return t.forEach(((t,n)=>{const i=B.splitToWords(t),o=i[0],c=i[1];s?e.set(c,n):n=e.get(c),r+=`layout(location = ${n}) ${a} ${o} ${c};\n`})),r}static processOuts(t){let e="";return t.forEach(((t,s)=>{e+=`layout(location = ${s}) out ${t};\n`})),e}static getTypeCount(t){const e=t.substring(t.length-1),s=parseInt(e,10);return isNaN(s)?1:s}static processAttributes(t,e,s){let r="";return t.forEach((t=>{const o=B.splitToWords(t);let c=o[0],u=o[1];if(e.hasOwnProperty(u)){const t=e[u],o=a[t];let p;const m=s.getVertexElement(t);if(m){const t=m.dataType;if(t!==n&&t!==i&&!m.normalize&&!m.asInt){const e=B.getTypeCount(c),s=`_private_${u}`;p=`vec${e} ${u} = vec${e}(${s});\n`,u=s;const r=t===g||t===y||t===$;c=1===e?r?"int":"uint":r?`ivec${e}`:`uvec${e}`}}r+=`layout(location = ${o}) in ${c} ${u};\n`,p&&(r+=p)}})),r}static splitToWords(t){return(t=t.replace(/\s+/g," ").trim()).split(" ")}static cutOut(t,e,s,r){return t.substring(0,e)+r+t.substring(s)}}export{B as ShaderProcessor};