UNPKG

@polygonjs/polygonjs

Version:

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

240 lines (239 loc) 8.19 kB
"use strict"; import { GlType } from "./../../../../../poly/registers/nodes/types/Gl"; import { BackSide, UniformsUtils, ShaderMaterial, ShaderLib } from "three"; import { BaseShaderAssemblerRayMarchingAbstract } from "./_BaseRayMarchingAbstract"; import { ShaderName } from "../../../../utils/shaders/ShaderName"; import { GlConnectionPointType, GlConnectionPoint } from "../../../../utils/io/connections/Gl"; import { ShaderConfig } from "../../configs/ShaderConfig"; import { VariableConfig } from "../../configs/VariableConfig"; import VERTEX from "../../../gl/raymarching/vert.glsl"; import FRAGMENT from "../../../gl/raymarching/fragApplyMaterial.glsl"; import { RAYMARCHING_UNIFORMS } from "../../../gl/raymarching/uniforms"; const INSERT_DEFINE_AFTER_MAP = /* @__PURE__ */ new Map([ // [ShaderName.VERTEX, '#include <common>'], [ShaderName.FRAGMENT, "// start applyMaterial builder define code"] ]); const INSERT_BODY_AFTER_MAP = /* @__PURE__ */ new Map([ // [ShaderName.VERTEX, '// start builder body code'], [ShaderName.FRAGMENT, "// start applyMaterial builder body code"] ]); const LINES_TO_REMOVE_MAP = /* @__PURE__ */ new Map([[ShaderName.FRAGMENT, []]]); const SDF_CONTEXT_INPUT_NAME = GlConnectionPointType.SDF_CONTEXT; const REFLECTION_NOT_ALLOWED = { START: "// --- REFLECTION NOT ALLOWED - START", END: "// --- REFLECTION NOT ALLOWED - END" }; const REFLECTION = { START: "// --- REFLECTION - START", END: "// --- REFLECTION - END" }; const REFRACTION_NOT_ALLOWED = { START: "// --- REFRACTION NOT ALLOWED - START", END: "// --- REFRACTION NOT ALLOWED - END" }; const REFRACTION = { START: "// --- REFRACTION - START", END: "// --- REFRACTION - END" }; export class ShaderAssemblerRayMarchingApplyMaterial extends BaseShaderAssemblerRayMarchingAbstract { templateShader() { return { vertexShader: VERTEX, fragmentShader: FRAGMENT, uniforms: UniformsUtils.clone(RAYMARCHING_UNIFORMS) }; } createMaterial() { const templateShader = this.templateShader(); const material = new ShaderMaterial({ vertexShader: templateShader.vertexShader, fragmentShader: templateShader.fragmentShader, side: BackSide, transparent: true, depthTest: true, alphaTest: 0.5, lights: true, uniforms: { ...UniformsUtils.clone(ShaderLib.standard.uniforms), ...UniformsUtils.clone(templateShader.uniforms) } }); return material; } // static add_output_inputs(output_child: OutputGlNode) { // // adding the color here would require to understand how to have the color affect the light in raymarch_light // // output_child.params.add_param(ParamType.COLOR, 'color', [1, 1, 1], {hidden: true}); // // output_child.params.add_param(ParamType.VECTOR3, 'position', [0, 0, 0], {hidden: true}); // // output_child.params.add_param(ParamType.FLOAT, 'density', 1, {hidden: true}); // } add_output_inputs(output_child) { output_child.io.inputs.setNamedInputConnectionPoints([ new GlConnectionPoint( SDF_CONTEXT_INPUT_NAME, GlConnectionPointType.SDF_CONTEXT, "SDFContext(0.0, 0, 0, 0, 0.)" ) ]); } static create_globals_node_output_connections() { return [ new GlConnectionPoint("position", GlConnectionPointType.VEC3), new GlConnectionPoint("time", GlConnectionPointType.FLOAT), new GlConnectionPoint("cameraPosition", GlConnectionPointType.VEC3) ]; } create_globals_node_output_connections() { return ShaderAssemblerRayMarchingApplyMaterial.create_globals_node_output_connections(); } insertDefineAfter(shaderName) { return INSERT_DEFINE_AFTER_MAP.get(shaderName); } insertBodyAfter(shaderName) { return INSERT_BODY_AFTER_MAP.get(shaderName); } linesToRemove(shaderName) { return LINES_TO_REMOVE_MAP.get(shaderName); } create_shader_configs() { return [ new ShaderConfig(ShaderName.VERTEX, [], []), new ShaderConfig( ShaderName.FRAGMENT, [ /*'color', */ "color", /* lighting */ "diffuse", "emissive", /* envMap */ "envMapTint", "envMapIntensity", "envMapRoughness", "envMapFresnel", "envMapFresnelPower", /* reflection */ "reflectionTint", "reflectionDepth", "reflectivity", "reflectionBiasMult", /* refraction */ "refractionTint", "refractionDepth", "ior", "iorOffset", "transmission", "absorption", "refractionBiasMult" ], [] ) ]; } static create_variable_configs() { return [ // new VariableConfig('position', { // // default_from_attribute: true, // // prefix: 'vec3 transformed = ', // }), // new VariableConfig('cameraPosition', { // // default_from_attribute: true, // // prefix: 'vec3 transformed = ', // }), // new VariableConfig('color', { // prefix: 'BUILDER_color.xyz = ', // }), new VariableConfig(SDF_CONTEXT_INPUT_NAME, { prefix: "sdfContext = " }) ]; } create_variable_configs() { return ShaderAssemblerRayMarchingApplyMaterial.create_variable_configs(); } // // // // // updateShaders() { this._shaders_by_name.clear(); this._lines.clear(); for (const shaderName of this.shaderNames()) { const template = this._template_shader_for_shader_name(shaderName); if (template) { this._lines.set(shaderName, template.split("\n")); } } const rootNodes = this.currentGlParentNode().nodesByType(GlType.SDF_MATERIAL); if (rootNodes.length > 0) { this.buildCodeFromNodes(rootNodes); this._buildLines(); } for (const shaderName of this.shaderNames()) { const lines = this._lines.get(shaderName); if (lines) { this._shaders_by_name.set(shaderName, lines.join("\n")); } } this._removeNestedReflection(); this._removeNestedRefraction(); } _removeNestedReflection() { const fragmentShader = this._shaders_by_name.get(ShaderName.FRAGMENT); if (!fragmentShader) { return; } const lines = fragmentShader.split("\n"); const newLines = []; let inNotAllowed = false; let inAllowed = false; for (const line of lines) { if (line.includes(REFLECTION_NOT_ALLOWED.START)) { inNotAllowed = true; } if (line.includes(REFLECTION_NOT_ALLOWED.END)) { inNotAllowed = false; } if (line.includes(REFLECTION.START)) { inAllowed = true; } if (line.includes(REFLECTION.END)) { inAllowed = false; } if (!(inNotAllowed && inAllowed) && !line.includes(REFLECTION_NOT_ALLOWED.START) && !line.includes(REFLECTION_NOT_ALLOWED.END) && !line.includes(REFLECTION.START) && !line.includes(REFLECTION.END)) { newLines.push(line); } } const newFragmentShader = newLines.join("\n"); this._shaders_by_name.set(ShaderName.FRAGMENT, newFragmentShader); } _removeNestedRefraction() { const fragmentShader = this._shaders_by_name.get(ShaderName.FRAGMENT); if (!fragmentShader) { return; } const lines = fragmentShader.split("\n"); const newLines = []; let inNotAllowed = false; let inAllowed = false; for (const line of lines) { if (line.includes(REFRACTION_NOT_ALLOWED.START)) { inNotAllowed = true; } if (line.includes(REFRACTION_NOT_ALLOWED.END)) { inNotAllowed = false; } if (line.includes(REFRACTION.START)) { inAllowed = true; } if (line.includes(REFRACTION.END)) { inAllowed = false; } if (!(inNotAllowed && inAllowed) && !line.includes(REFRACTION_NOT_ALLOWED.START) && !line.includes(REFRACTION_NOT_ALLOWED.END) && !line.includes(REFRACTION.START) && !line.includes(REFRACTION.END)) { newLines.push(line); } } const newFragmentShader = newLines.join("\n"); this._shaders_by_name.set(ShaderName.FRAGMENT, newFragmentShader); } }