node_shader.ts 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. type node_shader_t = {
  2. context?: node_shader_context_t;
  3. ins?: string[];
  4. outs?: string[];
  5. frag_out?: string;
  6. consts?: string[];
  7. textures?: string[];
  8. functions?: map_t<string, string>;
  9. vert?: string;
  10. vert_end?: string;
  11. vert_normal?: string;
  12. vert_attribs?: string;
  13. vert_write_normal?: i32;
  14. frag?: string;
  15. frag_end?: string;
  16. frag_normal?: string;
  17. frag_attribs?: string;
  18. frag_write_normal?: i32;
  19. // References
  20. vert_n?: bool;
  21. frag_bposition?: bool;
  22. frag_wposition?: bool;
  23. frag_mposition?: bool;
  24. frag_vposition?: bool;
  25. frag_wvpposition?: bool;
  26. frag_ndcpos?: bool;
  27. frag_wtangent?: bool;
  28. frag_vvec?: bool;
  29. frag_vvec_cam?: bool;
  30. frag_n?: bool;
  31. frag_nattr?: bool;
  32. frag_dotnv?: bool;
  33. };
  34. function node_shader_create(context: node_shader_context_t): node_shader_t {
  35. let raw: node_shader_t = {};
  36. raw.context = context;
  37. raw.ins = [];
  38. raw.outs = [];
  39. raw.frag_out = "float4";
  40. raw.consts = [];
  41. raw.textures = [];
  42. raw.functions = map_create();
  43. raw.vert = "";
  44. raw.vert_end = "";
  45. raw.vert_normal = "";
  46. raw.vert_attribs = "";
  47. raw.vert_write_normal = 0;
  48. raw.frag = "";
  49. raw.frag_end = "";
  50. raw.frag_normal = "";
  51. raw.frag_attribs = "";
  52. raw.frag_write_normal = 0;
  53. return raw;
  54. }
  55. function node_shader_add_in(raw: node_shader_t, s: string) {
  56. array_push(raw.ins, s);
  57. }
  58. function node_shader_add_out(raw: node_shader_t, s: string) {
  59. array_push(raw.outs, s);
  60. }
  61. function node_shader_add_constant(raw: node_shader_t, s: string, link: string = null) {
  62. // inp: float4
  63. if (array_index_of(raw.consts, s) == -1) {
  64. let ar: string[] = string_split(s, ": ");
  65. let uname: string = ar[0];
  66. let utype: string = ar[1];
  67. ////
  68. if (utype == "float2")
  69. utype = "vec2";
  70. if (utype == "float3")
  71. utype = "vec3";
  72. if (utype == "float4")
  73. utype = "vec4";
  74. if (utype == "float3x3")
  75. utype = "mat3";
  76. if (utype == "float4x4")
  77. utype = "mat4";
  78. ////
  79. array_push(raw.consts, s);
  80. node_shader_context_add_constant(raw.context, utype, uname, link);
  81. }
  82. }
  83. function node_shader_add_texture(raw: node_shader_t, name: string, link: string = null) {
  84. if (array_index_of(raw.textures, name) == -1) {
  85. array_push(raw.textures, name);
  86. node_shader_context_add_texture_unit(raw.context, name, link);
  87. }
  88. }
  89. function node_shader_add_function(raw: node_shader_t, s: string) {
  90. let fname: string = string_split(s, "(")[0];
  91. if (map_get(raw.functions, fname) != null) {
  92. return;
  93. }
  94. map_set(raw.functions, fname, s);
  95. }
  96. function node_shader_write_vert(raw: node_shader_t, s: string) {
  97. if (raw.vert_write_normal > 0) {
  98. raw.vert_normal += s + "\n";
  99. }
  100. else {
  101. raw.vert += s + "\n";
  102. }
  103. }
  104. function node_shader_write_end_vert(raw: node_shader_t, s: string) {
  105. raw.vert_end += s + "\n";
  106. }
  107. function node_shader_write_attrib_vert(raw: node_shader_t, s: string) {
  108. raw.vert_attribs += s + "\n";
  109. }
  110. function node_shader_write_frag(raw: node_shader_t, s: string) {
  111. if (raw.frag_write_normal > 0) {
  112. raw.frag_normal += s + "\n";
  113. }
  114. else {
  115. raw.frag += s + "\n";
  116. }
  117. }
  118. function node_shader_write_attrib_frag(raw: node_shader_t, s: string) {
  119. raw.frag_attribs += s + "\n";
  120. }
  121. function node_shader_data_size(raw: node_shader_t, data: string): string {
  122. if (data == "float1") {
  123. return "1";
  124. }
  125. else if (data == "float2" || data == "short2norm") {
  126. return "2";
  127. }
  128. else if (data == "float3") {
  129. return "3";
  130. }
  131. else { // float4 || short4norm
  132. return "4";
  133. }
  134. }
  135. function node_shader_vstruct_to_vsin(raw: node_shader_t) {
  136. let vs: vertex_element_t[] = raw.context.data.vertex_elements;
  137. for (let i: i32 = 0; i < vs.length; ++i) {
  138. let e: vertex_element_t = vs[i];
  139. node_shader_add_in(raw, "" + e.name + ": " +
  140. "float" + node_shader_data_size(raw, e.data));
  141. }
  142. }
  143. function node_shader_get(raw: node_shader_t): string {
  144. node_shader_vstruct_to_vsin(raw);
  145. let s: string = "";
  146. s += "struct vert_in {\n";
  147. for (let i: i32 = 0; i < raw.ins.length; ++i) {
  148. let a: string = raw.ins[i];
  149. s += "\t" + a + ";\n";
  150. }
  151. s += "}\n\n";
  152. s += "struct vert_out {\n";
  153. s += "\tpos: float4;\n";
  154. for (let i: i32 = 0; i < raw.outs.length; ++i) {
  155. let a: string = raw.outs[i];
  156. s += "\t" + a + ";\n";
  157. }
  158. if (raw.consts.length == 0) {
  159. s += "\tempty: float4;\n";
  160. }
  161. s += "}\n\n";
  162. s += "#[set(everything)]\n";
  163. s += "const constants: {\n";
  164. for (let i: i32 = 0; i < raw.consts.length; ++i) {
  165. let a: string = raw.consts[i];
  166. s += "\t" + a + ";\n";
  167. }
  168. if (raw.consts.length == 0) {
  169. s += "\tempty: float4;\n";
  170. }
  171. s += "};\n\n";
  172. if (raw.textures.length > 0) {
  173. s += "#[set(everything)]\n";
  174. s += "const sampler_linear: sampler;\n\n";
  175. }
  176. for (let i: i32 = 0; i < raw.textures.length; ++i) {
  177. let a: string = raw.textures[i];
  178. s += "#[set(everything)]\n";
  179. s += "const " + a + ": tex2d;\n";
  180. }
  181. let keys: string[] = map_keys(raw.functions);
  182. for (let i: i32 = 0; i < keys.length; ++i) {
  183. let f: string = map_get(raw.functions, keys[i]);
  184. s += f + "\n";
  185. }
  186. s += "\n";
  187. s += "fun kong_vert(input: vert_in): vert_out {\n";
  188. s += "\tvar output: vert_out;\n\n";
  189. s += raw.vert_attribs;
  190. s += raw.vert_normal;
  191. s += raw.vert;
  192. s += raw.vert_end;
  193. if (raw.consts.length == 0) {
  194. s += "\toutput.empty = constants.empty;\n";
  195. }
  196. s += "\n\treturn output;\n";
  197. s += "}\n\n";
  198. s += "fun kong_frag(input: vert_out): " + raw.frag_out + " {\n";
  199. s += "\tvar output: " + raw.frag_out + ";\n\n";
  200. s += raw.frag_attribs;
  201. s += raw.frag_normal;
  202. s += raw.frag;
  203. s += raw.frag_end;
  204. s += "\n\treturn output;\n";
  205. s += "}\n\n";
  206. s += "#[pipe]\n";
  207. s += "struct pipe {\n";
  208. s += "\tvertex = kong_vert;\n";
  209. s += "\tfragment = kong_frag;\n";
  210. s += "}\n";
  211. return s;
  212. }
  213. type material_t = {
  214. name?: string;
  215. canvas?: ui_node_canvas_t;
  216. };
  217. type node_shader_context_t = {
  218. kong?: node_shader_t;
  219. data?: shader_context_t;
  220. allow_vcols?: bool;
  221. material?: material_t;
  222. };
  223. function node_shader_context_create(material: material_t, props: shader_context_t): node_shader_context_t {
  224. let raw: node_shader_context_t = {};
  225. raw.material = material;
  226. let vertex_elements_default: vertex_element_t[] = [ {name : "pos", data : "short4norm"}, {name : "nor", data : "short2norm"} ];
  227. raw.data = {
  228. name : props.name,
  229. depth_write : props.depth_write,
  230. compare_mode : props.compare_mode,
  231. cull_mode : props.cull_mode,
  232. blend_source : props.blend_source,
  233. blend_destination : props.blend_destination,
  234. alpha_blend_source : props.alpha_blend_source,
  235. alpha_blend_destination : props.alpha_blend_destination,
  236. fragment_shader : "",
  237. vertex_shader : "",
  238. vertex_elements : props.vertex_elements != null ? props.vertex_elements : vertex_elements_default,
  239. color_attachments : props.color_attachments,
  240. depth_attachment : props.depth_attachment
  241. };
  242. let rw: shader_context_t = raw.data;
  243. rw._ = {};
  244. if (props.color_writes_red != null) {
  245. raw.data.color_writes_red = props.color_writes_red;
  246. }
  247. if (props.color_writes_green != null) {
  248. raw.data.color_writes_green = props.color_writes_green;
  249. }
  250. if (props.color_writes_blue != null) {
  251. raw.data.color_writes_blue = props.color_writes_blue;
  252. }
  253. if (props.color_writes_alpha != null) {
  254. raw.data.color_writes_alpha = props.color_writes_alpha;
  255. }
  256. raw.data.texture_units = [];
  257. raw.data.constants = [];
  258. return raw;
  259. }
  260. function node_shader_context_add_elem(raw: node_shader_context_t, name: string, data_type: string) {
  261. for (let i: i32 = 0; i < raw.data.vertex_elements.length; ++i) {
  262. let e: vertex_element_t = raw.data.vertex_elements[i];
  263. if (e.name == name) {
  264. return;
  265. }
  266. }
  267. let elem: vertex_element_t = {name : name, data : data_type};
  268. array_push(raw.data.vertex_elements, elem);
  269. }
  270. function node_shader_context_is_elem(raw: node_shader_context_t, name: string): bool {
  271. for (let i: i32 = 0; i < raw.data.vertex_elements.length; ++i) {
  272. let elem: vertex_element_t = raw.data.vertex_elements[i];
  273. if (elem.name == name) {
  274. return true;
  275. }
  276. }
  277. return false;
  278. }
  279. function node_shader_context_get_elem(raw: node_shader_context_t, name: string): vertex_element_t {
  280. for (let i: i32 = 0; i < raw.data.vertex_elements.length; ++i) {
  281. let elem: vertex_element_t = raw.data.vertex_elements[i];
  282. if (elem.name == name) {
  283. return elem;
  284. }
  285. }
  286. return null;
  287. }
  288. function node_shader_context_add_constant(raw: node_shader_context_t, ctype: string, name: string, link: string = null) {
  289. for (let i: i32 = 0; i < raw.data.constants.length; ++i) {
  290. let c: shader_const_t = raw.data.constants[i];
  291. if (c.name == name) {
  292. return;
  293. }
  294. }
  295. let c: shader_const_t = {name : name, type : ctype};
  296. if (link != null) {
  297. c.link = link;
  298. }
  299. let consts: shader_const_t[] = raw.data.constants;
  300. array_push(consts, c);
  301. }
  302. function node_shader_context_add_texture_unit(raw: node_shader_context_t, name: string, link: string = null) {
  303. for (let i: i32 = 0; i < raw.data.texture_units.length; ++i) {
  304. let c: tex_unit_t = raw.data.texture_units[i];
  305. if (c.name == name) {
  306. return;
  307. }
  308. }
  309. let c: tex_unit_t = {name : name, link : link};
  310. array_push(raw.data.texture_units, c);
  311. }
  312. function node_shader_context_make_kong(raw: node_shader_context_t): node_shader_t {
  313. raw.data.vertex_shader = raw.material.name + "_" + raw.data.name + ".vert";
  314. raw.data.fragment_shader = raw.material.name + "_" + raw.data.name + ".frag";
  315. raw.kong = node_shader_create(raw);
  316. return raw.kong;
  317. }