@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
149 lines (148 loc) • 6.11 kB
JavaScript
;
import { UniformsUtils } from "three";
import { ShaderMaterial } from "three";
import { BaseShaderAssemblerVolume } from "./_BaseVolume";
import { ShaderName } from "../../../../utils/shaders/ShaderName";
import { GlConnectionPointType, GlConnectionPoint } from "../../../../utils/io/connections/Gl";
import { FrontSide } from "three";
import { addUserDataRenderHook } from "../../../../../../core/geometry/Material";
import { VolumeController } from "../../../../mat/utils/VolumeController";
import { ShaderConfig } from "../../configs/ShaderConfig";
import { VariableConfig } from "../../configs/VariableConfig";
import { UniformGLDefinition } from "../../../utils/GLDefinition";
import { pushOnArrayAtEntry } from "../../../../../../core/MapUtils";
import VERTEX from "../../../gl/volume/vert.glsl";
import FRAGMENT from "../../../gl/volume/frag.glsl";
import { VOLUME_UNIFORMS } from "../../../gl/volume/uniforms";
const INSERT_BODY_AFTER_MAP = /* @__PURE__ */ new Map([
[ShaderName.VERTEX, "// start builder body code"],
[ShaderName.FRAGMENT, "// start builder body code"]
]);
const LINES_TO_REMOVE_MAP = /* @__PURE__ */ new Map([[ShaderName.FRAGMENT, []]]);
export class ShaderAssemblerVolume extends BaseShaderAssemblerVolume {
templateShader() {
return {
vertexShader: VERTEX,
fragmentShader: FRAGMENT,
uniforms: UniformsUtils.clone(VOLUME_UNIFORMS)
};
}
createMaterial() {
const template_shader = this.templateShader();
const material = new ShaderMaterial({
vertexShader: template_shader.vertexShader,
fragmentShader: template_shader.fragmentShader,
side: FrontSide,
transparent: true,
depthTest: true,
uniforms: UniformsUtils.clone(template_shader.uniforms)
});
addUserDataRenderHook(material, VolumeController.renderHook.bind(VolumeController));
this._addCustomMaterials(material);
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("density", GlConnectionPointType.FLOAT, 1)
]);
}
static create_globals_node_output_connections() {
return [
new GlConnectionPoint("position", GlConnectionPointType.VEC3),
new GlConnectionPoint("pos_normalized", GlConnectionPointType.VEC3),
new GlConnectionPoint("time", GlConnectionPointType.FLOAT)
];
}
create_globals_node_output_connections() {
return ShaderAssemblerVolume.create_globals_node_output_connections();
}
insertBodyAfter(shader_name) {
return INSERT_BODY_AFTER_MAP.get(shader_name);
}
linesToRemove(shader_name) {
return LINES_TO_REMOVE_MAP.get(shader_name);
}
create_shader_configs() {
return [
new ShaderConfig(ShaderName.VERTEX, [], []),
new ShaderConfig(ShaderName.FRAGMENT, [
/*'color', */
"density"
], [ShaderName.VERTEX])
];
}
static create_variable_configs() {
return [
new VariableConfig("position", {
// default_from_attribute: true,
// prefix: 'vec3 transformed = ',
}),
// new VariableConfig('color', {
// prefix: 'BUILDER_color.xyz = ',
// }),
new VariableConfig("density", {
prefix: "density *= "
})
];
}
create_variable_configs() {
return ShaderAssemblerVolume.create_variable_configs();
}
set_node_lines_globals(globals_node, shaders_collection_controller) {
const body_lines = [];
const shader_name = shaders_collection_controller.currentShaderName();
const shader_config = this.shader_config(shader_name);
if (!shader_config) {
return;
}
const dependencies = shader_config.dependencies();
const definitions_by_shader_name = /* @__PURE__ */ new Map();
const body_lines_by_shader_name = /* @__PURE__ */ new Map();
let definition;
let body_line;
for (const output_name of globals_node.io.outputs.used_output_names()) {
const var_name = globals_node.glVarName(output_name);
const globals_shader_name = shaders_collection_controller.currentShaderName();
switch (output_name) {
case "time":
definition = new UniformGLDefinition(globals_node, GlConnectionPointType.FLOAT, output_name);
if (globals_shader_name) {
pushOnArrayAtEntry(definitions_by_shader_name, globals_shader_name, definition);
}
body_line = `float ${var_name} = ${output_name}`;
for (const dependency of dependencies) {
pushOnArrayAtEntry(definitions_by_shader_name, dependency, definition);
pushOnArrayAtEntry(body_lines_by_shader_name, dependency, body_line);
}
body_lines.push(body_line);
this.setUniformsTimeDependent();
break;
case "position":
if (shader_name == ShaderName.FRAGMENT) {
body_lines.push(`vec3 ${var_name} = position_for_step`);
}
break;
case "pos_normalized":
if (shader_name == ShaderName.FRAGMENT) {
body_lines.push(
`vec3 ${var_name} = (position_for_step - u_BoundingBoxMax) / (u_BoundingBoxMax - u_BoundingBoxMin)`
);
}
break;
}
}
definitions_by_shader_name.forEach((definitions, shader_name2) => {
shaders_collection_controller.addDefinitions(globals_node, definitions, shader_name2);
});
body_lines_by_shader_name.forEach((body_lines2, shader_name2) => {
shaders_collection_controller.addBodyLines(globals_node, body_lines2, shader_name2);
});
shaders_collection_controller.addBodyLines(globals_node, body_lines);
}
}