UNPKG

@polygonjs/polygonjs

Version:

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

305 lines (304 loc) 11.2 kB
"use strict"; import { BaseGlShaderAssembler } from "../_Base"; import TemplateDefault from "../../templates/particles/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 { UniformGLDefinition } from "../../../utils/GLDefinition"; import { SubnetOutputGlNode } from "../../../SubnetOutput"; import { GlNodeTraverser } from "../../../../utils/shaders/GlNodeTraverser"; export class ShaderAssemblerParticles 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 TypedNamedConnectionPoint('acceleration', ConnectionPointType.VEC3), new GlConnectionPoint("time", GlConnectionPointType.FLOAT) ]); } allow_attribute_exports() { return true; } 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(export_node, input_name, input, variable_name, shaders_collection_controller) { var _a; if (input) { const var_input = export_node.variableForInput(input_name); const new_var = ThreeToGl.vector3(var_input); if (new_var) { const texture_variable = this.textureAllocationsController().variable(variable_name); const shader_name = shaders_collection_controller.currentShaderName(); if (texture_variable && ((_a = texture_variable.allocation()) == null ? void 0 : _a.shaderName()) == shader_name) { const component = texture_variable.component(); const line = `gl_FragColor.${component} = ${new_var}`; shaders_collection_controller.addBodyLines(export_node, [line], shader_name); } } } } set_node_lines_output(output_node, shaders_collection_controller) { const shader_name = shaders_collection_controller.currentShaderName(); const input_names = this.textureAllocationsController().inputNamesForShaderName(output_node, shader_name); if (input_names) { for (const input_name of input_names) { const input = output_node.io.inputs.named_input(input_name); if (input) { const variable_name = input_name; this.add_export_body_line( output_node, input_name, input, variable_name, shaders_collection_controller ); } else { } } } } setNodeLinesAttribute(attribute_node, shaders_collection_controller) { var _a, _b; if (attribute_node.isImporting()) { const gl_type = attribute_node.glType(); const attribute_name = attribute_node.attributeName(); const new_value = (_a = this.globalsHandler()) == null ? void 0 : _a.readAttribute( attribute_node, gl_type, attribute_name, shaders_collection_controller ); const var_name = attribute_node.glVarName(attribute_node.outputName()); const body_line = `${gl_type} ${var_name} = ${new_value}`; shaders_collection_controller.addBodyLines(attribute_node, [body_line]); const texture_variable = this.textureAllocationsController().variable(attribute_name); const shader_name = shaders_collection_controller.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}`; shaders_collection_controller.addBodyLines(attribute_node, [body_line2]); } } } if (attribute_node.isExporting()) { const input = attribute_node.connected_input_node(); if (input) { const variable_name = attribute_node.attributeName(); this.add_export_body_line( attribute_node, attribute_node.inputName(), input, variable_name, shaders_collection_controller ); } } } set_node_lines_globals(globals_node, shaders_collection_controller) { for (const output_name of globals_node.io.outputs.used_output_names()) { switch (output_name) { case "time": this._handle_globals_time(globals_node, output_name, shaders_collection_controller); break; default: this._handle_globals_default(globals_node, output_name, shaders_collection_controller); } } } _handle_globals_time(globals_node, output_name, shaders_collection_controller) { const definition = new UniformGLDefinition(globals_node, GlConnectionPointType.FLOAT, output_name); shaders_collection_controller.addDefinitions(globals_node, [definition]); const var_name = globals_node.glVarName(output_name); const body_line = `float ${var_name} = ${output_name}`; shaders_collection_controller.addBodyLines(globals_node, [body_line]); this.setUniformsTimeDependent(); } _handle_globals_default(globals_node, output_name, shaders_collection_controller) { var _a; const output_connection_point = globals_node.io.outputs.namedOutputConnectionPointsByName(output_name); if (output_connection_point) { const gl_type = output_connection_point.type(); const attrib_read = (_a = this.globalsHandler()) == null ? void 0 : _a.readAttribute( globals_node, gl_type, output_name, shaders_collection_controller ); if (attrib_read) { const var_name = globals_node.glVarName(output_name); const body_line = `${gl_type} ${var_name} = ${attrib_read}`; shaders_collection_controller.addBodyLines(globals_node, [body_line]); } } } }