UNPKG

@polygonjs/polygonjs

Version:

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

242 lines (224 loc) 9.24 kB
import {GlobalsBaseController} from './_Base'; import {GlobalsGlNode} from '../../Globals'; import {AttributeGlNode} from '../../Attribute'; // import {Definition} from '../../Definition/_Module'; // import {DefinitionBaseConfig} from '../Config/DefinitionBaseConfig'; // import {BaseGlNodeType} from '../../_Base'; import {VaryingGLDefinition, AttributeGLDefinition} from '../../utils/GLDefinition'; import {GlConnectionPointType} from '../../../utils/io/connections/Gl'; // import {TypeAssert} from '../../../../poly/Assert'; import {pushOnArrayAtEntry} from '../../../../../core/MapUtils'; import {ShaderName} from '../../../utils/shaders/ShaderName'; import {BaseGlNodeType} from '../../_Base'; import {ShadersCollectionController} from '../utils/ShadersCollectionController'; import {PolyDictionary} from '../../../../../types/GlobalTypes'; import {GlobalsOutput} from '../assemblers/materials/common/GlobalOutput'; import {GlobalsBaseControllerType} from './Common'; const VARIABLE_CONFIG_DEFAULT_BY_NAME: PolyDictionary<string> = { position: 'vec3( position )', }; export class GlobalsGeometryHandler extends GlobalsBaseController { static PRE_DEFINED_ATTRIBUTES = [ 'position', 'color', 'normal', 'uv', 'uv2', 'morphTarget0', 'morphTarget1', 'morphTarget2', 'morphTarget3', 'skinIndex', 'skinWeight', ]; static IF_RULE = { uv: 'defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )', }; type() { return GlobalsBaseControllerType.GEOMETRY; } override handleGlobalsNode( globals_node: GlobalsGlNode, output_name: string, shaders_collection_controller: ShadersCollectionController // definitions_by_shader_name: Map<ShaderName, BaseGLDefinition[]>, // body_lines_by_shader_name: Map<ShaderName, string[]>, // body_lines: string[], // dependencies: ShaderName[], // shader_name: ShaderName ): void { const connection_point = globals_node.io.outputs.namedOutputConnectionPointsByName(output_name); if (!connection_point) { return; } const glType = connection_point.type(); this.handleGlobalVar(globals_node, output_name, glType, shaders_collection_controller); } override handleGlobalVar( globals_node: BaseGlNodeType, output_name: string, glType: GlConnectionPointType, shaders_collection_controller: ShadersCollectionController ): void { const var_name = globals_node.glVarName(output_name); const definition = new VaryingGLDefinition(globals_node, glType, var_name); // push_on_array_at_entry(definitions_by_shader_name, shader_name, definition); shaders_collection_controller.addDefinitions(globals_node, [definition]); // definitions_by_shader_name.get(shader_name)!.push(definition); const assembler = globals_node.materialNode()?.assemblerController()?.assembler; if (!assembler) { return; } const shader_config = assembler.shader_config(shaders_collection_controller.currentShaderName()); if (!shader_config) { return; } const dependencies = shader_config.dependencies(); const body_lines: string[] = []; const worldPositionLine = `${var_name} = modelMatrix * vec4( position, 1.0 )`; const worldNormalLine = `${var_name} = normalize( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal )`; // const ILine = `${var_name} = worldPosition.xyz - cameraPosition`; switch (output_name) { case GlobalsOutput.WORLD_POSITION: { body_lines.push(worldPositionLine); break; } case GlobalsOutput.WORLD_NORMAL: { body_lines.push(worldNormalLine); break; } // case 'I': { // body_lines.push(worldPositionLine); // body_lines.push(ILine); // break; // } default: { body_lines.push(`${var_name} = ${glType}(${output_name})`); } } for (const dependency of dependencies) { // push_on_array_at_entry(definitions_by_shader_name, dependency, definition); // push_on_array_at_entry(body_lines_by_shader_name, dependency, body_line); shaders_collection_controller.addDefinitions(globals_node, [definition], dependency); shaders_collection_controller.addBodyLines(globals_node, body_lines, dependency); } if (dependencies.length == 0) { // body_lines.push(body_line); shaders_collection_controller.addBodyLines(globals_node, body_lines); } } static variable_config_default(variable_name: string): string | undefined { return VARIABLE_CONFIG_DEFAULT_BY_NAME[variable_name]; } variable_config_default(variable_name: string): string | undefined { return GlobalsGeometryHandler.variable_config_default(variable_name); } // variable_config_required_definitions(variable_name:string):DefinitionBaseConfig[]{ // return null // } readAttribute( node: BaseGlNodeType, gl_type: GlConnectionPointType, attrib_name: string, shaders_collection_controller: ShadersCollectionController ) { return GlobalsGeometryHandler.readAttribute(node, gl_type, attrib_name, shaders_collection_controller); } static readAttribute( node: BaseGlNodeType, gl_type: GlConnectionPointType, attrib_name: string, shaders_collection_controller: ShadersCollectionController ): string | undefined { if (GlobalsGeometryHandler.PRE_DEFINED_ATTRIBUTES.indexOf(attrib_name) < 0) { shaders_collection_controller.addDefinitions( node, [new AttributeGLDefinition(node, gl_type, attrib_name)], ShaderName.VERTEX ); } else { // const if_rule = GlobalsGeometryHandler.IF_RULE[attrib_name] // if(if_rule){ // const definition = new Definition.Attribute(node, gl_type, attrib_name) // definition.set_if_rule(if_rule) // node.addDefinitions([definition]) // } } // if (!shader_name) { // throw 'no shader name'; // } const shader_name = shaders_collection_controller.currentShaderName(); switch (shader_name) { case ShaderName.VERTEX: { return attrib_name; } case ShaderName.FRAGMENT: { // let's assume it can only be an attribute gl node if (!(node instanceof AttributeGlNode)) { return; } const attribNode = node as AttributeGlNode; const var_name = attribNode.varyingName(); //'varying_' + node.glVarName(node.outputName()); const varying_definition = new VaryingGLDefinition(node, gl_type, var_name); const definitions_by_shader_name: Map<ShaderName, VaryingGLDefinition[]> = new Map(); // definitions_by_shader_name.set(ShaderName.VERTEX, []) definitions_by_shader_name.set(ShaderName.FRAGMENT, []); // { // [ShaderName.VERTEX]: [], // [ShaderName.FRAGMENT]: [], // }; const body_lines_by_shader_name: Map<ShaderName, string[]> = new Map(); // body_lines_by_shader_name.set(ShaderName.VERTEX, []) body_lines_by_shader_name.set(ShaderName.FRAGMENT, []); pushOnArrayAtEntry(definitions_by_shader_name, shader_name, varying_definition); const set_varying_body_line = `${var_name} = ${gl_type}(${attrib_name})`; const shader_config = node.materialNode()?.assemblerController()?.assembler.shader_config(shader_name); if (shader_config) { const dependencies = shader_config.dependencies(); for (const dependency of dependencies) { pushOnArrayAtEntry(definitions_by_shader_name, dependency, varying_definition); pushOnArrayAtEntry(body_lines_by_shader_name, dependency, set_varying_body_line); } definitions_by_shader_name.forEach((definitions, shader_name) => { shaders_collection_controller.addDefinitions(node, definitions, shader_name); }); body_lines_by_shader_name.forEach((body_lines, shader_name) => { shaders_collection_controller.addBodyLines(node, body_lines, shader_name); }); } return var_name; } } // TypeAssert.unreachable(shader_name); // const shader_name = node._shader_name // TODO: this is hack // const varying_definition = new Definition.Varying(node, gl_type, attrib_name) // const var_name = varying_definition.name() // definitions_by_shader_name[shader_name].push(varying_definition) // const shader_config = node.shader_config(shader_name) // const dependencies = shader_config.dependencies() // const body_line = `${var_name} = ${gl_type}(${attrib_name})` // for(let dependency of dependencies){ // definitions_by_shader_name[dependency].push(varying_definition) // body_lines_by_shader_name[dependency].push(body_line) // } // // if(dependencies.length == 0){ // // body_lines.push(body_line) // node.addBodyLines([body_line]) // // } // for(let shader_name of Object.keys(definitions_by_shader_name)){ // node.addDefinitions(definitions_by_shader_name[shader_name], shader_name) // } // for(let shader_name of Object.keys(body_lines_by_shader_name)){ // node.addBodyLines(body_lines_by_shader_name[shader_name], shader_name) // } // node.addBodyLines(body_lines) } handle_attribute_node( node: AttributeGlNode, gl_type: GlConnectionPointType, attrib_name: string, shaders_collection_controller: ShadersCollectionController ) { return GlobalsGeometryHandler.readAttribute(node, gl_type, attrib_name, shaders_collection_controller); } }