@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
6 lines (5 loc) • 5.62 kB
JavaScript
/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.32/esri/copyright.txt for details.
*/
import{cloneShaderNode as e}from"./ShaderGraphNode.js";class t{constructor(e,t,d){this.variableName=e,this.variableInputType=t,this.node=d,this.type="shader-input",this.isUsed=!1}clone(){return new t(this.variableName,this.variableInputType,e(this.node))}}class d{constructor(e,t,d){this.outVariableName=e,this.outVariableType=t,this.node=d,this.type="shader-output"}clone(){const t=new d(this.outVariableName,this.outVariableType,e(this.node));return t.variableName=this.variableName,t}}class o{static createVertex(e,a,n,i,r,s){const u=[];for(const d in e){const o=e[d],a=n.get(d);a?u.push(new t(a,"builtin",o)):u.push(new t("a_"+d,"in",o))}for(const d of i){const e=d.uniformHydrated;u.push(new t(d.uniformName,"uniform",e))}const p=[];for(const t in a){const e=a[t];"glPosition"===t?p.push(new d("gl_Position","builtin",e)):"glPointSize"===t?p.push(new d("gl_PointSize","builtin",e)):p.push(new d("v_"+t,"out",e))}return new o(u,p,r,s)}static createFragment(e,a,n,i,r,s){const u=[],p=Array.from(r.rootOutputNodes());for(const d in e){const o=e[d],a=n.get(d);if(a){u.push(new t(a,"builtin",o));continue}const i=p.find((e=>e.node===o));i&&u.push(new t(i.outVariableName,"in",o))}for(const d of i){const e=d.uniformHydrated;u.push(new t(d.uniformName,"uniform",e))}const h=[];for(const t in a){const e=a[t],o=n.get(t);"discard"===t?h.push(new d(null,"discard",e)):o?h.push(new d(o,"builtin",e)):h.push(new d(t,"out",e))}return new o(u,h,s)}constructor(e,t,d,o){this.type="shader-graph-context",this.indent=0,this.body="",this.varCount=0,this._inputShaderTypesByNodeUid=new Map,this._nodeEmitMap=new Map;for(const a of e)this._inputShaderTypesByNodeUid.set(a.node.uid,a);this._outputShaderTypes=t,this._transformFeedbackBindings=d,this._transformFeedbackNames=new Set(d.map((e=>"v_"+e.propertyKey))),this._usedInFragmentShader=o}shouldPruneOutputNode(e){return!!this._usedInFragmentShader&&("builtin"!==e.outVariableType&&(!this._transformFeedbackNames.has(e.outVariableName)&&!this._usedInFragmentShader.has(e.node.uid)))}setEmit(e,t){this._nodeEmitMap.set(e.uid,t)}getEmit(e){return this._nodeEmitMap.get(e.uid)}inputs(){return this._inputShaderTypesByNodeUid.values()}getInput(e){return this._inputShaderTypesByNodeUid.get(e.uid)}*rootOutputNodes(){for(const e of this._outputShaderTypes)yield e}*nodes(){const e=[];for(const t of this._outputShaderTypes.values())e.push(t.node);for(;e.length;){const t=e.pop();"number"!=typeof t&&"boolean"!=typeof t&&e.push(...t.children.filter(Boolean)),yield t}}*nodesOfTypeOrFunction(){for(const e of this.nodes())"number"!=typeof e&&"boolean"!=typeof e&&(yield e)}createSubgraphContext(){const e=this.clone();return e.body="",e.indent=this.indent+2,e._nodeEmitMap=new Map(this._nodeEmitMap),e}clone(){const e=new o([],this._outputShaderTypes,this._transformFeedbackBindings,this._usedInFragmentShader);return e._inputShaderTypesByNodeUid=this._inputShaderTypesByNodeUid,e.indent=this.indent,e.body=this.body,e.varCount=this.varCount,e._nodeEmitMap=this._nodeEmitMap,e}insertVertexShader(e){e.vertex.code.add(""),this._insertInputs(e,"vertex"),e.vertex.code.add(""),e.vertex.code.add("// OUTPUTS: "),e.vertex.code.add("// --------------------------------------------------------- ");for(const t of this.rootOutputNodes()){const d="builtin"===t.outVariableType;this.shouldPruneOutputNode(t)||(d?e.vertex.code.add(`// ${t.outVariableType.padEnd(7)} ${t.node.type.padEnd(9)} ${t.outVariableName};`):e.vertex.code.add(`${t.outVariableType.padEnd(10)} ${t.node.type.padEnd(9)} ${t.outVariableName};`))}e.vertex.code.add(""),e.vertex.code.add("void main() {"),e.vertex.code.add(" "+this.body.split("\n").join("\n "));for(const t of this.rootOutputNodes())this.shouldPruneOutputNode(t)||e.vertex.code.add(` ${t.outVariableName} = ${t.variableName};`);e.vertex.code.add("}")}insertFragmentShader(e){this._insertInputs(e,"fragment"),e.fragment.code.add(""),e.fragment.code.add("// OUTPUTS: "),e.fragment.code.add("// --------------------------------------------------------- ");let t=0;for(const d of this.rootOutputNodes()){"builtin"===d.outVariableType?e.fragment.code.add(`// ${d.outVariableType.padEnd(7)} ${d.node.type.padEnd(9)} ${d.outVariableName};`):e.outputs.add(d.outVariableName,d.node.type,t++)}e.fragment.code.add(""),e.fragment.code.add("void main() {"),e.fragment.code.add(" "+this.body.split("\n").join("\n "));for(const d of this.rootOutputNodes())"discard"===d.outVariableType?(e.fragment.code.add(" // TODO: Should ensure codegen for discard appears first in fragment shader"),e.fragment.code.add(` if (${d.variableName}) {`),e.fragment.code.add(" discard;"),e.fragment.code.add(" }"),e.fragment.code.add(" ")):e.fragment.code.add(` ${d.outVariableName} = ${d.variableName};`);e.fragment.code.add("}")}_insertInputs(e,t){e[t].code.add("// INPUTS: "),e[t].code.add("// --------------------------------------------------------- ");for(const d of this.inputs())d.isUsed&&"builtin"!==d.variableInputType&&("array"===d.node.type?e[t].code.add(`${d.variableInputType.padEnd(10)} ${d.node.elementType.type.padEnd(9)} ${d.variableName}[${d.node.size}];`):"array-2d"===d.node.type?e[t].code.add(`${d.variableInputType.padEnd(10)} ${d.node.elementType.type.padEnd(9)} ${d.variableName}[${d.node.size}]; // Emulated 2D Array. Not supported by ES3.0`):e[t].code.add(`${d.variableInputType.padEnd(10)} ${d.node.type.padEnd(9)} ${d.variableName};`))}}export{o as ShaderGraphContext,t as ShaderInput,d as ShaderOutput};