UNPKG

@polygonjs/polygonjs

Version:

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

152 lines (151 loc) 5.89 kB
"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; } }