@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
152 lines (151 loc) • 5.89 kB
JavaScript
"use strict";
import { BasePersistedConfig } from "../../../../utils/BasePersistedConfig";
import {
assignOnBeforeCompileDataAndFunction,
OnBeforeCompileDataConverter
} from "./OnBeforeCompile";
function _removeShaders(data) {
const onBeforeCompileDataJSONWithoutShaders = {
paramConfigs: data.paramConfigs,
timeDependent: data.timeDependent,
resolutionDependent: data.resolutionDependent,
raymarchingLightsWorldCoordsDependent: data.raymarchingLightsWorldCoordsDependent
};
return onBeforeCompileDataJSONWithoutShaders;
}
function _addShaders(data, options) {
const onBeforeCompileDataJSON = {
paramConfigs: data.paramConfigs,
timeDependent: data.timeDependent,
resolutionDependent: data.resolutionDependent,
raymarchingLightsWorldCoordsDependent: data.raymarchingLightsWorldCoordsDependent,
fragmentShader: options.fragment,
vertexShader: options.vertex
};
return onBeforeCompileDataJSON;
}
function _shaderKey(shaderType, customMaterialName) {
return customMaterialName ? `${customMaterialName}.${shaderType}` : shaderType;
}
export class MaterialPersistedConfig extends BasePersistedConfig {
constructor(node) {
super(node);
this.node = node;
}
async toData() {
const assemblerController = this.node.assemblerController();
if (!assemblerController) {
return;
}
const assembler = assemblerController.assembler;
const onBeforeCompileData = assembler.onBeforeCompileData();
if (!onBeforeCompileData) {
return;
}
const onBeforeCompileDataJSON = OnBeforeCompileDataConverter.toJSON(onBeforeCompileData);
const onBeforeCompileDataJSONWithoutShaders = _removeShaders(onBeforeCompileDataJSON);
const shaders = {
[_shaderKey("vertex")]: onBeforeCompileDataJSON.vertexShader,
[_shaderKey("fragment")]: onBeforeCompileDataJSON.fragmentShader
};
const customMaterialsData = {};
const material = await this.node.material();
if (!material) {
return;
}
const customMaterials = material.customMaterials;
if (customMaterials) {
assembler.traverseCustomAssemblers((customAssembler, customMaterialName) => {
const customOnBeforeCompileData = customAssembler.onBeforeCompileData();
if (customOnBeforeCompileData) {
const customMaterial = customMaterials[customMaterialName];
if (customMaterial) {
const customMaterialData = this._materialToJson(customMaterial, {
node: this.node,
suffix: customMaterialName
});
if (customMaterialData) {
const data2 = OnBeforeCompileDataConverter.toJSON(customOnBeforeCompileData);
const dataWithoutShaders = _removeShaders(data2);
customMaterialsData[customMaterialName] = {
material: customMaterialData,
onBeforeCompileDataJSONWithoutShaders: dataWithoutShaders
};
shaders[_shaderKey("vertex", customMaterialName)] = data2.vertexShader;
shaders[_shaderKey("fragment", customMaterialName)] = data2.fragmentShader;
}
}
}
});
}
const materialData = this._materialToJson(material, {
node: this.node,
suffix: "main"
});
if (!materialData) {
console.warn("failed to save material from node", this.node.path());
}
const data = {
material: materialData || {},
onBeforeCompileDataJSONWithoutShaders,
// uniforms_time_dependent: assemblerController.assembler.uniformsTimeDependent(),
// uniforms_resolution_dependent: assemblerController.assembler.uniformsResolutionDependent(),
// param_uniform_pairs: param_uniform_pairs,
customMaterials: customMaterialsData,
shaders
};
return data;
}
load(data) {
const assemblerController = this.node.assemblerController();
if (assemblerController) {
return;
}
this._material = this._loadMaterial(data.material);
if (!this._material) {
return;
}
const shaders = data.shaders;
if (!shaders) {
console.warn(`${this.node.path()}: persisted config has no shaders`);
return;
}
const onBeforeCompileDataJSON = _addShaders(
data.onBeforeCompileDataJSONWithoutShaders,
{
vertex: shaders[_shaderKey("vertex")],
fragment: shaders[_shaderKey("fragment")]
}
);
const onBeforeCompileData = OnBeforeCompileDataConverter.fromJSON(onBeforeCompileDataJSON);
const material = this._material;
assignOnBeforeCompileDataAndFunction(this.node.scene(), material, onBeforeCompileData);
for (let paramConfig of onBeforeCompileData.paramConfigs) {
paramConfig.applyToNode(this.node);
}
this._material.customMaterials = this._material.customMaterials || {};
if (data.customMaterials) {
const customMatNames = Object.keys(data.customMaterials);
for (const customMatName of customMatNames) {
const customMatData = data.customMaterials[customMatName];
const customMat = this._loadMaterial(customMatData.material);
if (customMat) {
const onBeforeCompileDataJSON2 = _addShaders(
customMatData.onBeforeCompileDataJSONWithoutShaders,
{
vertex: shaders[_shaderKey("vertex", customMatName)],
fragment: shaders[_shaderKey("fragment", customMatName)]
}
);
const customOnBeforeCompileData = OnBeforeCompileDataConverter.fromJSON(onBeforeCompileDataJSON2);
customOnBeforeCompileData.paramConfigs = onBeforeCompileData.paramConfigs;
assignOnBeforeCompileDataAndFunction(this.node.scene(), customMat, customOnBeforeCompileData);
this._material.customMaterials[customMatName] = customMat;
}
}
}
}
material() {
return this._material;
}
}