@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
215 lines (213 loc) • 6.82 kB
JavaScript
;
import {
BaseJsShaderAssembler,
INSERT_DEFINE_AFTER,
INSERT_BODY_AFTER,
INSERT_MEMBERS_AFTER
} from "../_Base";
import { ThreeToGl } from "../../../../../../core/ThreeToGl";
import { JsShaderConfig } from "../../configs/ShaderConfig";
import { VariableConfig } from "../../configs/VariableConfig";
import { JsFunctionName } from "../../../../utils/shaders/ShaderName";
import { JsConnectionPointType, JsConnectionPoint } from "../../../../utils/io/connections/Js";
import { Vector3 } from "three";
var SDFVariable = /* @__PURE__ */ ((SDFVariable2) => {
SDFVariable2["D"] = "d";
return SDFVariable2;
})(SDFVariable || {});
const TEMPLATE = `
${INSERT_DEFINE_AFTER}
${INSERT_MEMBERS_AFTER}
${INSERT_BODY_AFTER}
`;
export class JsAssemblerSDF extends BaseJsShaderAssembler {
// private _function: Function | undefined;
// private _uniforms: IUniforms | undefined;
// private _functionsByName: Map<string, Function> = new Map();
makeFunctionNodeDirtyOnChange() {
return true;
}
defaultObjectVariable() {
return "null";
}
defaultObject3DMaterialVariable() {
return "null";
}
defaultPrimitiveGraph() {
return "null";
}
templateShader() {
return {
main: TEMPLATE
};
}
spareParamsOptions(options) {
const _options = {
spare: true,
// computeOnDirty: true, // not needed if cook option is not set
// cook: false, // for SDFBuilder, the node needs to recook
// important for texture nodes
// that compute after being found by the nodepath param
dependentOnFoundNode: true
};
return _options;
}
functionData() {
const functionBody = this._shaders_by_name.get(JsFunctionName.MAIN);
if (!functionBody) {
return;
}
const variableNames = [];
const functionNames = [];
const variablesByName = {};
const functionsByName = {};
this.traverseRegisteredVariables((variable, varName) => {
variableNames.push(varName);
variablesByName[varName] = variable;
});
this.traverseRegisteredFunctions((namedFunction) => {
functionNames.push(namedFunction.type());
functionsByName[namedFunction.type()] = namedFunction.func.bind(namedFunction);
});
const paramConfigs = this.param_configs();
return {
functionBody,
variableNames,
variablesByName,
functionNames,
functionsByName,
paramConfigs: [...paramConfigs]
};
}
// uniforms() {
// return this._uniforms;
// }
// evalFunction(position: Vector3) {
// if (this._function) {
// return this._function(position);
// }
// }
updateFunction() {
super.updateFunction();
this._lines = /* @__PURE__ */ new Map();
this._shaders_by_name = /* @__PURE__ */ new Map();
const shaderNames = this.shaderNames();
if (this._root_nodes.length > 0) {
this.buildCodeFromNodes(this._root_nodes);
this._buildLines();
}
for (const shaderName of shaderNames) {
const lines = this._lines.get(shaderName);
if (lines) {
this._shaders_by_name.set(shaderName, lines.join("\n"));
}
}
}
//
//
// CHILDREN NODES PARAMS
//
//
add_output_inputs(output_child) {
output_child.io.inputs.setNamedInputConnectionPoints([
new JsConnectionPoint("d" /* D */, JsConnectionPointType.FLOAT)
// new JsConnectionPoint('alpha', JsConnectionPointType.FLOAT),
]);
}
add_globals_outputs(globals_node) {
globals_node.io.outputs.setNamedOutputConnectionPoints([
new JsConnectionPoint("position", JsConnectionPointType.VECTOR3)
// new JsConnectionPoint('gl_FragCoord', JsConnectionPointType.VEC4),
// new JsConnectionPoint('resolution', JsConnectionPointType.VEC2),
// new JsConnectionPoint('time', JsConnectionPointType.FLOAT),
// new Connection.Vec2('resolution'),
]);
}
//
//
// CONFIGS
//
//
create_shader_configs() {
return [new JsShaderConfig(JsFunctionName.MAIN, ["d" /* D */], [])];
}
create_variable_configs() {
return [
new VariableConfig("d" /* D */, {
prefix: "return "
})
// new VariableConfig('alpha', {
// prefix: 'diffuseColor.a = ',
// default: '1.0',
// }),
];
}
//
//
// TEMPLATE HOOKS
//
//
// protected override insertDefineAfter(shader_name: ShaderName) {
// return '// INSERT DEFINE';
// }
// protected override insertBodyAfter(shader_name: ShaderName) {
// return '// INSERT BODY';
// }
// protected override linesToRemove(shader_name: ShaderName) {
// return ['// INSERT DEFINE', '// INSERT BODY'];
// }
// private _handle_gl_FragCoord(body_lines: string[], shaderName: ShaderName, var_name: string) {
// if (shaderName == ShaderName.FRAGMENT) {
// body_lines.push(`vec4 ${var_name} = gl_FragCoord`);
// }
// }
// private _handle_resolution(bodyLines: string[], shaderName: ShaderName, var_name: string) {
// if (shaderName == ShaderName.FRAGMENT) {
// bodyLines.push(`vec2 ${var_name} = resolution`);
// }
// }
// private _handleUV(bodyLines: string[], shaderName: ShaderName, var_name: string) {
// if (shaderName == ShaderName.FRAGMENT) {
// bodyLines.push(
// `vec2 ${var_name} = vec2(gl_FragCoord.x / (resolution.x-1.), gl_FragCoord.y / (resolution.y-1.))`
// );
// }
// }
setNodeLinesOutput(outputNode, shadersCollectionController) {
const inputNames = this.inputNamesForShaderName(outputNode, shadersCollectionController.currentShaderName());
if (inputNames) {
for (const inputName of inputNames) {
const input = outputNode.io.inputs.named_input(inputName);
if (input) {
const gl_var = outputNode.variableForInput(shadersCollectionController, inputName);
let bodyLine;
if (inputName == "d" /* D */) {
bodyLine = `return ${ThreeToGl.any(gl_var)}`;
}
if (bodyLine) {
shadersCollectionController._addBodyLines(outputNode, [bodyLine]);
}
}
}
}
}
setNodeLinesGlobals(globalsNode, shadersCollectionController) {
const shaderName = shadersCollectionController.currentShaderName();
const shaderConfig = this.shader_config(shaderName);
if (!shaderConfig) {
return;
}
const bodyLines = [];
const usedOutputNames = globalsNode.io.outputs.used_output_names();
for (const outputName of usedOutputNames) {
const varName = globalsNode.jsVarName(outputName);
switch (outputName) {
case "position":
shadersCollectionController.addVariable(globalsNode, new Vector3(), varName);
bodyLines.push(`${varName}.copy(${outputName})`);
break;
}
}
shadersCollectionController._addBodyLines(globalsNode, bodyLines);
}
}