Files
armorpaint/armorsculpt/Sources/MakeMaterial.ts
T

325 lines
9.6 KiB
TypeScript
Raw Normal View History

2023-04-24 15:20:03 +02:00
class MakeMaterial {
2024-02-05 20:57:20 +01:00
static defaultScon: shader_context_t = null;
static defaultMcon: material_context_t = null;
2023-04-24 15:20:03 +02:00
2024-01-17 18:53:31 +01:00
static heightUsed = false;
static emisUsed = false;
static subsUsed = false;
2023-04-24 15:20:03 +02:00
2024-01-17 18:53:31 +01:00
static getMOut = (): bool => {
2024-01-21 15:18:44 +01:00
for (let n of UINodes.getCanvasMaterial().nodes) if (n.type == "OUTPUT_MATERIAL_PBR") return true;
2023-04-24 15:20:03 +02:00
return false;
}
2024-01-17 18:53:31 +01:00
static parseMeshMaterial = () => {
let m = Project.materials[0].data;
2023-04-24 15:20:03 +02:00
2024-01-30 23:55:35 +01:00
for (let c of m._shader._contexts) {
if (c.name == "mesh") {
array_remove(m._shader.contexts, c);
array_remove(m._shader._contexts, c);
2024-01-26 22:09:49 +01:00
MakeMaterial.deleteContext(c);
2023-04-24 15:20:03 +02:00
break;
}
}
if (MakeMesh.layerPassCount > 1) {
2024-01-17 18:53:31 +01:00
let i = 0;
2024-01-30 23:55:35 +01:00
while (i < m._shader._contexts.length) {
let c = m._shader._contexts[i];
2024-01-17 18:53:31 +01:00
for (let j = 1; j < MakeMesh.layerPassCount; ++j) {
2024-01-30 23:55:35 +01:00
if (c.name == "mesh" + j) {
array_remove(m._shader.contexts, c);
array_remove(m._shader._contexts, c);
2024-01-26 22:09:49 +01:00
MakeMaterial.deleteContext(c);
2023-04-24 15:20:03 +02:00
i--;
break;
}
}
i++;
}
i = 0;
while (i < m.contexts.length) {
2024-01-17 18:53:31 +01:00
let c = m.contexts[i];
for (let j = 1; j < MakeMesh.layerPassCount; ++j) {
2024-01-30 23:55:35 +01:00
if (c.name == "mesh" + j) {
2024-01-26 22:09:49 +01:00
array_remove(m.contexts, c);
2024-01-30 23:55:35 +01:00
array_remove(m._contexts, c);
2023-04-24 15:20:03 +02:00
i--;
break;
}
}
i++;
}
}
2024-01-26 16:50:04 +01:00
let con = MakeMesh.run({ name: "Material", canvas: null });
2024-02-19 17:07:09 +01:00
let scon: shader_context_t = shader_context_create(con.data);
2024-02-05 20:57:20 +01:00
scon._override_context = {};
2023-04-24 15:20:03 +02:00
if (con.frag.sharedSamplers.length > 0) {
2024-01-17 18:53:31 +01:00
let sampler = con.frag.sharedSamplers[0];
2024-02-05 20:57:20 +01:00
scon._override_context.shared_sampler = sampler.substr(sampler.lastIndexOf(" ") + 1);
2023-04-24 15:20:03 +02:00
}
if (!Context.raw.textureFilter) {
2024-02-05 20:57:20 +01:00
scon._override_context.filter = "point";
2023-04-24 15:20:03 +02:00
}
2024-01-30 23:55:35 +01:00
m._shader.contexts.push(scon);
m._shader._contexts.push(scon);
2023-04-24 15:20:03 +02:00
2024-01-17 18:53:31 +01:00
for (let i = 1; i < MakeMesh.layerPassCount; ++i) {
2024-01-26 16:50:04 +01:00
let con = MakeMesh.run({ name: "Material", canvas: null }, i);
2024-02-19 17:07:09 +01:00
let scon: shader_context_t = shader_context_create(con.data);
2024-02-05 20:57:20 +01:00
scon._override_context = {};
2023-04-24 15:20:03 +02:00
if (con.frag.sharedSamplers.length > 0) {
2024-01-17 18:53:31 +01:00
let sampler = con.frag.sharedSamplers[0];
2024-02-05 20:57:20 +01:00
scon._override_context.shared_sampler = sampler.substr(sampler.lastIndexOf(" ") + 1);
2023-04-24 15:20:03 +02:00
}
if (!Context.raw.textureFilter) {
2024-02-05 20:57:20 +01:00
scon._override_context.filter = "point";
2023-04-24 15:20:03 +02:00
}
2024-01-30 23:55:35 +01:00
m._shader.contexts.push(scon);
m._shader._contexts.push(scon);
2023-04-24 15:20:03 +02:00
2024-02-19 17:07:09 +01:00
let mcon: material_context_t = material_context_create({ name: "mesh" + i, bind_textures: [] });
2023-04-24 15:20:03 +02:00
m.contexts.push(mcon);
2024-01-30 23:55:35 +01:00
m._contexts.push(mcon);
2023-04-24 15:20:03 +02:00
}
Context.raw.ddirty = 2;
2024-01-17 18:53:31 +01:00
///if arm_voxels
2024-01-26 22:09:49 +01:00
MakeMaterial.makeVoxel(m);
2024-01-17 18:53:31 +01:00
///end
2023-04-24 15:20:03 +02:00
}
2024-01-17 18:53:31 +01:00
static parseParticleMaterial = () => {
let m = Context.raw.particleMaterial;
2024-02-05 20:57:20 +01:00
let sc: shader_context_t = null;
2024-01-30 23:55:35 +01:00
for (let c of m._shader._contexts) {
if (c.name == "mesh") {
2023-04-24 15:20:03 +02:00
sc = c;
break;
}
}
if (sc != null) {
2024-01-30 23:55:35 +01:00
array_remove(m._shader.contexts, sc);
array_remove(m._shader._contexts, sc);
2023-04-24 15:20:03 +02:00
}
2024-01-26 16:50:04 +01:00
let con = MakeParticle.run({ name: "MaterialParticle", canvas: null });
2024-01-26 22:09:49 +01:00
if (sc != null) MakeMaterial.deleteContext(sc);
2024-02-19 17:07:09 +01:00
sc = shader_context_create(con.data);
2024-01-30 23:55:35 +01:00
m._shader.contexts.push(sc);
m._shader._contexts.push(sc);
2023-04-24 15:20:03 +02:00
}
2024-01-17 18:53:31 +01:00
static parseMeshPreviewMaterial = () => {
2024-01-26 22:09:49 +01:00
if (!MakeMaterial.getMOut()) return;
2023-04-24 15:20:03 +02:00
2024-01-17 18:53:31 +01:00
let m = Project.materials[0].data;
2024-02-05 20:57:20 +01:00
let scon: shader_context_t = null;
2024-01-30 23:55:35 +01:00
for (let c of m._shader._contexts) {
if (c.name == "mesh") {
2023-04-24 15:20:03 +02:00
scon = c;
break;
}
}
2024-01-30 23:55:35 +01:00
array_remove(m._shader.contexts, scon);
array_remove(m._shader._contexts, scon);
2023-04-24 15:20:03 +02:00
2024-02-05 20:57:20 +01:00
let mcon: material_context_t = { name: "mesh", bind_textures: [] };
2023-04-24 15:20:03 +02:00
2024-01-26 16:50:04 +01:00
let sd: TMaterial = { name: "Material", canvas: null };
2024-01-17 18:53:31 +01:00
let con = MakeMeshPreview.run(sd, mcon);
2023-04-24 15:20:03 +02:00
2024-01-17 18:53:31 +01:00
for (let i = 0; i < m.contexts.length; ++i) {
2024-01-30 23:55:35 +01:00
if (m.contexts[i].name == "mesh") {
2024-02-19 17:07:09 +01:00
m.contexts[i] = material_context_create(mcon);
2023-04-24 15:20:03 +02:00
break;
}
}
2024-01-26 22:09:49 +01:00
if (scon != null) MakeMaterial.deleteContext(scon);
2023-04-24 15:20:03 +02:00
2024-01-17 18:53:31 +01:00
let compileError = false;
2024-02-19 17:07:09 +01:00
let _scon: shader_context_t = shader_context_create(con.data);
if (_scon == null) compileError = true;
scon = _scon;
2023-04-24 15:20:03 +02:00
if (compileError) return;
2024-01-30 23:55:35 +01:00
m._shader.contexts.push(scon);
m._shader._contexts.push(scon);
2023-04-24 15:20:03 +02:00
}
2024-01-17 18:53:31 +01:00
///if arm_voxels
2024-02-05 20:57:20 +01:00
static makeVoxel = (m: material_data_t) => {
2024-01-26 22:09:49 +01:00
let rebuild = MakeMaterial.heightUsed;
2023-04-24 15:20:03 +02:00
if (Config.raw.rp_gi != false && rebuild) {
2024-02-05 20:57:20 +01:00
let scon: shader_context_t = null;
2024-01-30 23:55:35 +01:00
for (let c of m._shader._contexts) {
if (c.name == "voxel") {
2023-04-24 15:20:03 +02:00
scon = c;
break;
}
}
if (scon != null) MakeVoxel.run(scon);
}
}
2024-01-17 18:53:31 +01:00
///end
2023-04-24 15:20:03 +02:00
2024-01-17 18:53:31 +01:00
static parsePaintMaterial = (bakePreviews = true) => {
2024-01-26 22:09:49 +01:00
if (!MakeMaterial.getMOut()) return;
2023-04-24 15:20:03 +02:00
if (bakePreviews) {
2024-02-05 20:57:20 +01:00
let current = _g2_current;
2024-02-07 21:39:06 +01:00
if (current != null) g2_end();
2024-01-26 22:09:49 +01:00
MakeMaterial.bakeNodePreviews();
2024-02-05 20:57:20 +01:00
if (current != null) g2_begin(current, false);
2023-04-24 15:20:03 +02:00
}
2024-01-17 18:53:31 +01:00
let m = Project.materials[0].data;
2024-02-05 20:57:20 +01:00
let scon: shader_context_t = null;
let mcon: material_context_t = null;
2024-01-30 23:55:35 +01:00
for (let c of m._shader._contexts) {
if (c.name == "paint") {
array_remove(m._shader.contexts, c);
array_remove(m._shader._contexts, c);
2024-01-26 22:09:49 +01:00
if (c != MakeMaterial.defaultScon) MakeMaterial.deleteContext(c);
2023-04-24 15:20:03 +02:00
break;
}
}
2024-01-17 18:53:31 +01:00
for (let c of m.contexts) {
2024-01-30 23:55:35 +01:00
if (c.name == "paint") {
2024-01-26 22:09:49 +01:00
array_remove(m.contexts, c);
2024-01-30 23:55:35 +01:00
array_remove(m._contexts, c);
2023-04-24 15:20:03 +02:00
break;
}
}
2024-01-26 16:50:04 +01:00
let sdata: TMaterial = { name: "Material", canvas: UINodes.getCanvasMaterial() };
2024-02-05 20:57:20 +01:00
let mcon2: material_context_t = { name: "paint", bind_textures: [] };
2024-01-26 22:09:49 +01:00
let con = MakeSculpt.run(sdata, mcon2);
2023-04-24 15:20:03 +02:00
2024-01-17 18:53:31 +01:00
let compileError = false;
2024-02-05 20:57:20 +01:00
let scon2: shader_context_t;
2024-02-19 17:07:09 +01:00
let _scon: shader_context_t = shader_context_create(con.data);
if (_scon == null) compileError = true;
scon2 = _scon;
2023-04-24 15:20:03 +02:00
if (compileError) return;
2024-02-05 20:57:20 +01:00
scon2._override_context = {};
scon2._override_context.addressing = "repeat";
2024-02-19 17:07:09 +01:00
let mcon3: material_context_t = material_context_create(mcon2);
2023-04-24 15:20:03 +02:00
2024-01-30 23:55:35 +01:00
m._shader.contexts.push(scon2);
m._shader._contexts.push(scon2);
2024-01-26 22:09:49 +01:00
m.contexts.push(mcon3);
2024-01-30 23:55:35 +01:00
m._contexts.push(mcon3);
2023-04-24 15:20:03 +02:00
2024-01-26 22:09:49 +01:00
if (MakeMaterial.defaultScon == null) MakeMaterial.defaultScon = scon2;
if (MakeMaterial.defaultMcon == null) MakeMaterial.defaultMcon = mcon3;
2023-04-24 15:20:03 +02:00
}
2024-01-17 18:53:31 +01:00
static bakeNodePreviews = () => {
2023-04-24 15:20:03 +02:00
Context.raw.nodePreviewsUsed = [];
2024-01-26 22:09:49 +01:00
if (Context.raw.nodePreviews == null) Context.raw.nodePreviews = new Map();
MakeMaterial.traverseNodes(UINodes.getCanvasMaterial().nodes, null, []);
2024-01-17 18:53:31 +01:00
for (let key of Context.raw.nodePreviews.keys()) {
2023-04-24 15:20:03 +02:00
if (Context.raw.nodePreviewsUsed.indexOf(key) == -1) {
2024-01-17 18:53:31 +01:00
let image = Context.raw.nodePreviews.get(key);
2024-02-05 20:57:20 +01:00
Base.notifyOnNextFrame(function() { image_unload(image); });
2024-01-26 22:09:49 +01:00
Context.raw.nodePreviews.delete(key);
2023-04-24 15:20:03 +02:00
}
}
}
2024-02-06 19:32:21 +01:00
static traverseNodes = (nodes: zui_node_t[], group: zui_node_canvas_t, parents: zui_node_t[]) => {
2024-01-17 18:53:31 +01:00
for (let node of nodes) {
2024-01-26 22:09:49 +01:00
MakeMaterial.bakeNodePreview(node, group, parents);
2023-04-24 15:20:03 +02:00
if (node.type == "GROUP") {
2024-01-17 18:53:31 +01:00
for (let g of Project.materialGroups) {
2023-04-24 15:20:03 +02:00
if (g.canvas.name == node.name) {
parents.push(node);
2024-01-26 22:09:49 +01:00
MakeMaterial.traverseNodes(g.canvas.nodes, g.canvas, parents);
2023-04-24 15:20:03 +02:00
parents.pop();
break;
}
}
}
}
}
2024-02-06 19:32:21 +01:00
static bakeNodePreview = (node: zui_node_t, group: zui_node_canvas_t, parents: zui_node_t[]) => {
2023-04-24 15:20:03 +02:00
if (node.type == "BLUR") {
2024-01-17 18:53:31 +01:00
let id = ParserMaterial.node_name(node, parents);
let image = Context.raw.nodePreviews.get(id);
2023-04-24 15:20:03 +02:00
Context.raw.nodePreviewsUsed.push(id);
2024-01-17 18:53:31 +01:00
let resX = Math.floor(Config.getTextureResX() / 4);
let resY = Math.floor(Config.getTextureResY() / 4);
2023-04-24 15:20:03 +02:00
if (image == null || image.width != resX || image.height != resY) {
2024-02-05 20:57:20 +01:00
if (image != null) image_unload(image);
image = image_create_render_target(resX, resY);
2023-04-24 15:20:03 +02:00
Context.raw.nodePreviews.set(id, image);
}
2023-12-13 15:52:41 +01:00
ParserMaterial.blur_passthrough = true;
2024-01-21 15:18:44 +01:00
UtilRender.makeNodePreview(UINodes.getCanvasMaterial(), node, image, group, parents);
2023-12-13 15:52:41 +01:00
ParserMaterial.blur_passthrough = false;
2023-04-24 15:20:03 +02:00
}
else if (node.type == "DIRECT_WARP") {
2024-01-17 18:53:31 +01:00
let id = ParserMaterial.node_name(node, parents);
let image = Context.raw.nodePreviews.get(id);
2023-04-24 15:20:03 +02:00
Context.raw.nodePreviewsUsed.push(id);
2024-01-17 18:53:31 +01:00
let resX = Math.floor(Config.getTextureResX());
let resY = Math.floor(Config.getTextureResY());
2023-04-24 15:20:03 +02:00
if (image == null || image.width != resX || image.height != resY) {
2024-02-05 20:57:20 +01:00
if (image != null) image_unload(image);
image = image_create_render_target(resX, resY);
2023-04-24 15:20:03 +02:00
Context.raw.nodePreviews.set(id, image);
}
2023-12-13 15:52:41 +01:00
ParserMaterial.warp_passthrough = true;
2024-01-21 15:18:44 +01:00
UtilRender.makeNodePreview(UINodes.getCanvasMaterial(), node, image, group, parents);
2023-12-13 15:52:41 +01:00
ParserMaterial.warp_passthrough = false;
2023-04-24 15:20:03 +02:00
}
}
2024-02-06 19:32:21 +01:00
static parseNodePreviewMaterial = (node: zui_node_t, group: zui_node_canvas_t = null, parents: zui_node_t[] = null): { scon: shader_context_t, mcon: material_context_t } => {
2023-04-24 15:20:03 +02:00
if (node.outputs.length == 0) return null;
2024-01-26 16:50:04 +01:00
let sdata: TMaterial = { name: "Material", canvas: UINodes.getCanvasMaterial() };
2024-02-05 20:57:20 +01:00
let mcon_raw: material_context_t = { name: "mesh", bind_textures: [] };
2024-01-17 18:53:31 +01:00
let con = MakeNodePreview.run(sdata, mcon_raw, node, group, parents);
let compileError = false;
2024-02-05 20:57:20 +01:00
let scon: shader_context_t;
2024-02-19 17:07:09 +01:00
let _scon: shader_context_t = shader_context_create(con.data);
if (_scon == null) compileError = true;
scon = _scon;
2023-04-24 15:20:03 +02:00
if (compileError) return null;
2024-02-19 17:07:09 +01:00
let mcon: material_context_t = material_context_create(mcon_raw);
2023-04-24 15:20:03 +02:00
return { scon: scon, mcon: mcon };
}
2024-01-17 18:53:31 +01:00
static parseBrush = () => {
2023-12-13 15:52:41 +01:00
ParserLogic.parse(Context.raw.brush.canvas);
2023-04-24 15:20:03 +02:00
}
2024-01-17 18:53:31 +01:00
static getDisplaceStrength = (): f32 => {
2024-01-31 15:12:28 +01:00
let sc = Context.mainObject().base.transform.scale.x;
2023-04-24 15:20:03 +02:00
return Config.raw.displace_strength * 0.02 * sc;
}
2024-01-17 18:53:31 +01:00
static voxelgiHalfExtents = (): string => {
let ext = Context.raw.vxaoExt;
return `const vec3 voxelgiHalfExtents = vec3(${ext}, ${ext}, ${ext});`;
2023-04-24 15:20:03 +02:00
}
2024-02-05 20:57:20 +01:00
static deleteContext = (c: shader_context_t) => {
2024-01-17 18:53:31 +01:00
Base.notifyOnNextFrame(() => { // Ensure pipeline is no longer in use
2024-02-05 20:57:20 +01:00
shader_context_delete(c);
2023-04-24 15:20:03 +02:00
});
}
}