UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

301 lines (300 loc) 10.7 kB
"use strict"; import { BaseGlShaderAssembler } from "../_Base"; import TemplateDefault from "../../templates/cloth/Default.glsl"; import { AttributeGlNode } from "../../../Attribute"; import { TextureAllocationsController } from "../../utils/TextureAllocationsController"; import { ThreeToGl } from "../../../../../../core/ThreeToGl"; import { OutputGlNode } from "../../../Output"; import { GlConnectionPointType, GlConnectionPoint } from "../../../../utils/io/connections/Gl"; import { SubnetOutputGlNode } from "../../../SubnetOutput"; import { GlNodeTraverser } from "../../../../utils/shaders/GlNodeTraverser"; export class ShaderAssemblerCloth extends BaseGlShaderAssembler { templateShader() { return void 0; } _template_shader_for_shader_name(shader_name) { return TemplateDefault; } // async get_shaders(){ // await this.update_shaders() // return this._shaders_by_name // } compile() { this.setup_shader_names_and_variables(); this._updateShaders(); } rootNodesByShaderName(shader_name, rootNodes) { var _a, _b; const list = []; for (const node of rootNodes) { switch (node.type()) { case SubnetOutputGlNode.type(): case OutputGlNode.type(): { list.push(node); break; } case AttributeGlNode.type(): { const attrib_name = node.attributeName(); const variable = (_a = this._textureAllocationsController) == null ? void 0 : _a.variable(attrib_name); if (variable && variable.allocation()) { const allocation_shader_name = (_b = variable.allocation()) == null ? void 0 : _b.shaderName(); if (allocation_shader_name == shader_name) { list.push(node); } } break; } } } return list; } // override leaf_nodes_by_shader_name(shader_name: ShaderName): BaseGlNodeType[] { // const list = []; // for (let node of this._leaf_nodes) { // switch (node.type()) { // case GlobalsGlNode.type(): { // list.push(node); // break; // } // case AttributeGlNode.type(): { // const attrib_name: string = (node as AttributeGlNode).attributeName(); // const variable = this._textureAllocationsController?.variable(attrib_name); // if (variable && variable.allocation()) { // const allocation_shader_name = variable.allocation()?.shaderName(); // if (allocation_shader_name == shader_name) { // list.push(node); // } // } // break; // } // } // } // return list; // } setup_shader_names_and_variables() { var _a; const node_traverser_shallow = new GlNodeTraverser( this.currentGlParentNode(), this.shaderNames(), (root_node, shader_name) => { return this.inputNamesForShaderName(root_node, shader_name); } ); const node_traverser_deep = new GlNodeTraverser( this.currentGlParentNode(), this.shaderNames(), (root_node, shader_name) => { return this.inputNamesForShaderName(root_node, shader_name); }, { traverseChildren: true } ); this._leaf_nodes = node_traverser_shallow.leavesFromNodes(this._root_nodes); const leafNodesForTextureAllocations = node_traverser_deep.leavesFromNodes(this._root_nodes); this._textureAllocationsController = new TextureAllocationsController(); this._textureAllocationsController.allocateConnectionsFromRootNodes( this._root_nodes, leafNodesForTextureAllocations ); if (this.globalsHandler()) { (_a = this.globalsHandler()) == null ? void 0 : _a.set_texture_allocations_controller( this._textureAllocationsController ); } this._reset_shader_configs(); } _updateShaders() { this._shaders_by_name.clear(); this._lines.clear(); for (const shader_name of this.shaderNames()) { const template = this._template_shader_for_shader_name(shader_name); this._lines.set(shader_name, template.split("\n")); } if (this._root_nodes.length > 0) { this._resetCodeBuilder(); this.buildCodeFromNodes(this._root_nodes); this._buildLines(); } for (const shader_name of this.shaderNames()) { const lines = this._lines.get(shader_name); if (lines) { this._shaders_by_name.set(shader_name, lines.join("\n")); } } } // // // CHILDREN NODES PARAMS // // add_output_inputs(output_child) { output_child.io.inputs.setNamedInputConnectionPoints([ new GlConnectionPoint("position", GlConnectionPointType.VEC3) // new GlConnectionPoint('velocity', GlConnectionPointType.VEC3), ]); } add_globals_outputs(globals_node) { globals_node.io.outputs.setNamedOutputConnectionPoints([ new GlConnectionPoint("position", GlConnectionPointType.VEC3), // new GlConnectionPoint('velocity', GlConnectionPointType.VEC3), new GlConnectionPoint("time", GlConnectionPointType.FLOAT), new GlConnectionPoint("timeDelta", GlConnectionPointType.FLOAT) ]); } allow_attribute_exports() { return false; } textureAllocationsController() { return this._textureAllocationsController = this._textureAllocationsController || new TextureAllocationsController(); } // // // CONFIGS // // create_shader_configs() { var _a; return ((_a = this._textureAllocationsController) == null ? void 0 : _a.createShaderConfigs()) || []; } create_variable_configs() { return [ // new VariableConfig('position', { // default: 'vec3( position )', // prefix: 'vec3 transformed = ' // }), ]; } shaderNames() { return this.textureAllocationsController().shaderNames() || []; } inputNamesForShaderName(root_node, shader_name) { return this.textureAllocationsController().inputNamesForShaderName(root_node, shader_name) || []; } // // // TEMPLATE HOOKS // // insertDefineAfter(shader_name) { return "// INSERT DEFINE"; } insertBodyAfter(shader_name) { return "// INSERT BODY"; } linesToRemove(shader_name) { return ["// INSERT DEFINE", "// INSERT BODY"]; } // // // TEMPLATE CODE REPLACEMENT // // add_export_body_line(exportNode, inputName, input, variableName, linesController) { var _a; if (input) { const var_input = exportNode.variableForInput(inputName); const new_var = ThreeToGl.vector3(var_input); if (new_var) { const texture_variable = this.textureAllocationsController().variable(variableName); const shader_name = linesController.currentShaderName(); if (texture_variable && ((_a = texture_variable.allocation()) == null ? void 0 : _a.shaderName()) == shader_name) { const component = texture_variable.component(); const line = `${inputName}.${component} = ${new_var}`; linesController.addBodyLines(exportNode, [line], shader_name); } } } } set_node_lines_output(outputNode, linesController) { const shaderName = linesController.currentShaderName(); const inputNames = this.textureAllocationsController().inputNamesForShaderName(outputNode, shaderName); if (inputNames) { for (let inputName of inputNames) { const input = outputNode.io.inputs.named_input(inputName); if (input) { const variable_name = inputName; this.add_export_body_line(outputNode, inputName, input, variable_name, linesController); } else { } } } } setNodeLinesAttribute(attributeNode, linesController) { var _a, _b; if (attributeNode.isImporting()) { const gl_type = attributeNode.glType(); const attribute_name = attributeNode.attributeName(); const new_value = (_a = this.globalsHandler()) == null ? void 0 : _a.readAttribute( attributeNode, gl_type, attribute_name, linesController ); const var_name = attributeNode.glVarName(attributeNode.outputName()); const body_line = `${gl_type} ${var_name} = ${new_value}`; linesController.addBodyLines(attributeNode, [body_line]); const texture_variable = this.textureAllocationsController().variable(attribute_name); const shader_name = linesController.currentShaderName(); if (texture_variable && ((_b = texture_variable.allocation()) == null ? void 0 : _b.shaderName()) == shader_name) { const variable = this.textureAllocationsController().variable(attribute_name); if (variable) { const component = variable.component(); const body_line2 = `gl_FragColor.${component} = ${var_name}`; linesController.addBodyLines(attributeNode, [body_line2]); } } } if (attributeNode.isExporting()) { const input = attributeNode.connected_input_node(); if (input) { const variable_name = attributeNode.attributeName(); this.add_export_body_line( attributeNode, attributeNode.inputName(), input, variable_name, linesController ); } } } set_node_lines_globals(globals_node, linesController) { for (let outputName of globals_node.io.outputs.used_output_names()) { switch (outputName) { case "time": { this._handleGlobalsUniform(globals_node, outputName, linesController); break; } case "timeDelta": { this._handleGlobalsUniform(globals_node, outputName, linesController); break; } case "position": { this._handleGlobalsPosition(globals_node, outputName, linesController); break; } default: { this._handleGlobalsPosition(globals_node, outputName, linesController); break; } } } } _handleGlobalsUniform(globalsNode, outputName, linesController) { const varName = globalsNode.glVarName(outputName); const bodyLine = `float ${varName} = ${outputName}`; linesController.addBodyLines(globalsNode, [bodyLine]); this.setUniformsTimeDependent(); } _handleGlobalsPosition(globalsNode, outputName, linesController) { const output_connection_point = globalsNode.io.outputs.namedOutputConnectionPointsByName(outputName); if (output_connection_point) { const glType = output_connection_point.type(); const attribRead = "position"; if (attribRead) { const varName = globalsNode.glVarName(outputName); const bodyLine = `${glType} ${varName} = ${attribRead}`; linesController.addBodyLines(globalsNode, [bodyLine]); } } } }