Files
armorpaint/base/sources/ts/node_shader.ts
T

243 lines
5.5 KiB
TypeScript
Raw Normal View History

2024-03-13 23:50:11 +01:00
2024-03-21 21:06:41 +01:00
type node_shader_t = {
context?: node_shader_context_t;
ins?: string[];
outs?: string[];
2025-04-02 22:52:04 +02:00
frag_out?: string;
2025-04-04 23:38:01 +02:00
constants?: string[];
textures?: string[];
2024-03-21 21:06:41 +01:00
functions?: map_t<string, string>;
2025-04-02 22:52:04 +02:00
vert?: string;
vert_end?: string;
vert_normal?: string;
vert_attribs?: string;
vert_write_normal?: i32;
frag?: string;
frag_end?: string;
frag_normal?: string;
frag_attribs?: string;
frag_write_normal?: i32;
2024-03-13 23:50:11 +01:00
// References
2025-04-02 22:52:04 +02:00
vert_n?: bool;
frag_bposition?: bool;
frag_wposition?: bool;
frag_mposition?: bool;
frag_vposition?: bool;
frag_wvpposition?: bool;
frag_ndcpos?: bool;
frag_wtangent?: bool;
frag_vvec?: bool;
frag_vvec_cam?: bool;
frag_n?: bool;
frag_nattr?: bool;
frag_dotnv?: bool;
2024-03-21 21:06:41 +01:00
};
2024-03-13 23:50:11 +01:00
2025-04-02 22:52:04 +02:00
function node_shader_create(context: node_shader_context_t): node_shader_t {
2024-03-21 21:06:41 +01:00
let raw: node_shader_t = {};
2024-03-13 23:50:11 +01:00
raw.context = context;
2024-03-21 21:06:41 +01:00
raw.ins = [];
raw.outs = [];
2025-04-02 22:52:04 +02:00
raw.frag_out = "float4";
2025-04-04 23:38:01 +02:00
raw.constants = [];
raw.textures = [];
2024-03-21 21:06:41 +01:00
raw.functions = map_create();
2025-04-02 22:52:04 +02:00
raw.vert = "";
raw.vert_end = "";
raw.vert_normal = "";
raw.vert_attribs = "";
raw.vert_write_normal = 0;
raw.frag = "";
raw.frag_end = "";
raw.frag_normal = "";
raw.frag_attribs = "";
raw.frag_write_normal = 0;
2024-03-13 23:50:11 +01:00
return raw;
}
2024-03-20 16:13:54 +01:00
function node_shader_add_in(raw: node_shader_t, s: string) {
array_push(raw.ins, s);
2024-03-13 23:50:11 +01:00
}
2024-03-20 16:13:54 +01:00
function node_shader_add_out(raw: node_shader_t, s: string) {
array_push(raw.outs, s);
2024-03-13 23:50:11 +01:00
}
2025-04-04 23:38:01 +02:00
function node_shader_add_constant(raw: node_shader_t, s: string, link: string = null) {
2025-04-05 22:50:07 +02:00
// inp: float4
2025-04-04 23:38:01 +02:00
if (array_index_of(raw.constants, s) == -1) {
2025-04-05 22:50:07 +02:00
let ar: string[] = string_split(s, ": ");
let uname: string = ar[0];
let utype: string = ar[1];
////
if (utype == "float2") utype = "vec2";
if (utype == "float3") utype = "vec3";
if (utype == "float4") utype = "vec4";
if (utype == "float3x3") utype = "mat3";
if (utype == "float4x4") utype = "mat4";
////
2025-04-04 23:38:01 +02:00
array_push(raw.constants, s);
2025-04-05 22:50:07 +02:00
node_shader_context_add_constant(raw.context, utype, uname, link);
2025-04-04 23:38:01 +02:00
}
}
2025-04-19 16:55:29 +02:00
function node_shader_add_texture(raw: node_shader_t, s: string, link: string = null) {
2025-04-05 22:50:07 +02:00
// mytex: tex2d
2025-04-04 23:38:01 +02:00
if (array_index_of(raw.textures, s) == -1) {
2025-04-05 22:50:07 +02:00
let ar: string[] = string_split(s, ": ");
let uname: string = ar[0];
let utype: string = ar[1];
2025-04-04 23:38:01 +02:00
array_push(raw.textures, s);
2025-04-19 16:55:29 +02:00
node_shader_context_add_texture_unit(raw.context, utype, uname, link);
2024-03-13 23:50:11 +01:00
}
}
2024-03-20 16:13:54 +01:00
function node_shader_add_function(raw: node_shader_t, s: string) {
2024-03-22 14:17:49 +01:00
let fname: string = string_split(s, "(")[0];
if (map_get(raw.functions, fname) != null) {
2024-03-20 16:13:54 +01:00
return;
}
map_set(raw.functions, fname, s);
2024-03-13 23:50:11 +01:00
}
2025-04-02 22:52:04 +02:00
function node_shader_write_vert(raw: node_shader_t, s: string) {
if (raw.vert_write_normal > 0) {
raw.vert_normal += s + "\n";
2024-03-13 23:50:11 +01:00
}
else {
2025-04-02 22:52:04 +02:00
raw.vert += s + "\n";
2024-03-13 23:50:11 +01:00
}
}
2025-04-02 22:52:04 +02:00
function node_shader_write_end_vert(raw: node_shader_t, s: string) {
raw.vert_end += s + "\n";
2024-03-13 23:50:11 +01:00
}
2025-04-02 22:52:04 +02:00
function node_shader_write_attrib_vert(raw: node_shader_t, s: string) {
raw.vert_attribs += s + "\n";
}
function node_shader_write_frag(raw: node_shader_t, s: string) {
if (raw.frag_write_normal > 0) {
raw.frag_normal += s + "\n";
}
else {
raw.frag += s + "\n";
}
}
function node_shader_write_attrib_frag(raw: node_shader_t, s: string) {
raw.frag_attribs += s + "\n";
2024-03-13 23:50:11 +01:00
}
2024-03-20 16:13:54 +01:00
function node_shader_data_size(raw: node_shader_t, data: string): string {
2024-03-22 14:17:49 +01:00
if (data == "float1") {
return "1";
2024-03-20 16:13:54 +01:00
}
2024-09-29 21:18:27 +02:00
else if (data == "float2" || data == "short2norm") {
2024-03-22 14:17:49 +01:00
return "2";
2024-03-20 16:13:54 +01:00
}
2024-03-22 14:17:49 +01:00
else if (data == "float3") {
return "3";
2024-03-20 16:13:54 +01:00
}
2025-04-03 21:29:51 +02:00
else { // float4 || short4norm
2024-03-22 14:17:49 +01:00
return "4";
2024-03-20 16:13:54 +01:00
}
2024-03-13 23:50:11 +01:00
}
2024-03-20 16:13:54 +01:00
function node_shader_vstruct_to_vsin(raw: node_shader_t) {
2024-03-13 23:50:11 +01:00
let vs: vertex_element_t[] = raw.context.data.vertex_elements;
2024-03-21 21:06:41 +01:00
for (let i: i32 = 0; i < vs.length; ++i) {
let e: vertex_element_t = vs[i];
2025-04-03 21:29:51 +02:00
node_shader_add_in(raw, "" + e.name + ": " + "float" + node_shader_data_size(raw, e.data));
2024-03-13 23:50:11 +01:00
}
}
2024-03-20 16:13:54 +01:00
function node_shader_get(raw: node_shader_t): string {
2024-03-13 23:50:11 +01:00
2025-04-03 21:29:51 +02:00
node_shader_vstruct_to_vsin(raw);
let s: string = "";
2025-04-02 22:52:04 +02:00
2025-04-03 21:29:51 +02:00
s += "struct vert_in {\n";
for (let i: i32 = 0; i < raw.ins.length; ++i) {
let a: string = raw.ins[i];
s += "\t" + a + ";\n";
}
s += "}\n\n";
2025-04-02 22:52:04 +02:00
2025-04-03 21:29:51 +02:00
s += "struct vert_out {\n";
s += "\tpos: float4;\n";
for (let i: i32 = 0; i < raw.outs.length; ++i) {
let a: string = raw.outs[i];
s += "\t" + a + ";\n";
}
s += "}\n\n";
2025-04-02 22:52:04 +02:00
2025-04-25 20:36:00 +02:00
s += "#[set(everything)]\n";
s += "const constants: {\n";
2025-04-10 15:40:40 +02:00
if (raw.constants.length > 0) {
for (let i: i32 = 0; i < raw.constants.length; ++i) {
let a: string = raw.constants[i];
s += "\t" + a + ";\n";
}
2025-04-03 21:29:51 +02:00
}
2025-04-25 20:36:00 +02:00
else {
s += "\tempty: float4;\n";
}
s += "};\n\n";
2025-04-02 22:52:04 +02:00
2025-04-24 22:19:44 +02:00
if (raw.textures.length > 0) {
2025-04-18 09:28:41 +02:00
s += "#[set(everything)]\n";
2025-04-24 22:19:44 +02:00
s += "const sampler_linear: sampler;\n\n";
2025-04-18 09:28:41 +02:00
}
2025-04-24 22:19:44 +02:00
for (let i: i32 = 0; i < raw.textures.length; ++i) {
let a: string = raw.textures[i];
2025-04-05 22:22:43 +02:00
s += "#[set(everything)]\n";
2025-04-24 22:19:44 +02:00
s += "const " + a + ": tex2d;\n";
2025-04-05 22:22:43 +02:00
}
2025-04-02 22:52:04 +02:00
2025-04-03 21:29:51 +02:00
let keys: string[] = map_keys(raw.functions);
for (let i: i32 = 0; i < keys.length; ++i) {
let f: string = map_get(raw.functions, keys[i]);
s += f + "\n";
}
s += "\n";
s += "fun kong_vert(input: vert_in): vert_out {\n";
s += "\tvar output: vert_out;\n\n";
s += raw.vert_attribs;
s += raw.vert_normal;
s += raw.vert;
s += raw.vert_end;
2025-05-01 12:32:28 +02:00
s += "output.pos.z = (output.pos.z + output.pos.w) * 0.5;\n"; ////
2025-04-03 21:29:51 +02:00
s += "\n\treturn output;\n";
s += "}\n\n";
s += "fun kong_frag(input: vert_out): " + raw.frag_out + " {\n";
s += "\tvar output: " + raw.frag_out + ";\n\n";
s += raw.frag_attribs;
s += raw.frag_normal;
s += raw.frag;
s += raw.frag_end;
s += "\n\treturn output;\n";
s += "}\n\n";
s += "#[pipe]\n";
s += "struct pipe {\n";
s += "\tvertex = kong_vert;\n";
s += "\tfragment = kong_frag;\n";
s += "}\n";
return s;
2024-03-13 23:50:11 +01:00
}