layers.ts 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. let layers_temp_image: image_t = null;
  2. let layers_expa: image_t = null;
  3. let layers_expb: image_t = null;
  4. let layers_expc: image_t = null;
  5. let layers_default_base: f32 = 0.5;
  6. let layers_default_rough: f32 = 0.4;
  7. let layers_max_layers: i32 =
  8. ///if (arm_android || arm_ios)
  9. 18;
  10. ///else
  11. 255;
  12. ///end
  13. let _layers_uv_type: uv_type_t;
  14. let _layers_decal_mat: mat4_t;
  15. let _layers_position: i32;
  16. let _layers_base_color: i32;
  17. let _layers_occlusion: f32;
  18. let _layers_roughness: f32;
  19. let _layers_metallic: f32;
  20. function layers_init() {
  21. ///if (is_paint || is_sculpt)
  22. slot_layer_clear(project_layers[0], color_from_floats(layers_default_base, layers_default_base, layers_default_base, 1.0));
  23. ///end
  24. ///if is_lab
  25. let texpaint: render_target_t = map_get(render_path_render_targets, "texpaint");
  26. let texpaint_nor: render_target_t = map_get(render_path_render_targets, "texpaint_nor");
  27. let texpaint_pack: render_target_t = map_get(render_path_render_targets, "texpaint_pack");
  28. g2_begin(texpaint._image);
  29. g2_draw_scaled_image(resource_get("placeholder.k"), 0, 0, config_get_texture_res_x(), config_get_texture_res_y()); // Base
  30. g2_end();
  31. g4_begin(texpaint_nor._image);
  32. g4_clear(color_from_floats(0.5, 0.5, 1.0, 0.0)); // Nor
  33. g4_end();
  34. g4_begin(texpaint_pack._image);
  35. g4_clear(color_from_floats(1.0, 0.4, 0.0, 0.0)); // Occ, rough, met
  36. g4_end();
  37. let texpaint_nor_empty: render_target_t = map_get(render_path_render_targets, "texpaint_nor_empty");
  38. let texpaint_pack_empty: render_target_t = map_get(render_path_render_targets, "texpaint_pack_empty");
  39. g4_begin(texpaint_nor_empty._image);
  40. g4_clear(color_from_floats(0.5, 0.5, 1.0, 0.0)); // Nor
  41. g4_end();
  42. g4_begin(texpaint_pack_empty._image);
  43. g4_clear(color_from_floats(1.0, 0.4, 0.0, 0.0)); // Occ, rough, met
  44. g4_end();
  45. ///end
  46. }
  47. function layers_resize() {
  48. let conf: config_t = config_raw;
  49. if (base_res_handle.position >= math_floor(texture_res_t.RES16384)) { // Save memory for >=16k
  50. conf.undo_steps = 1;
  51. if (context_raw.undo_handle != null) {
  52. context_raw.undo_handle.value = conf.undo_steps;
  53. }
  54. while (history_undo_layers.length > conf.undo_steps) {
  55. let l: slot_layer_t = array_pop(history_undo_layers);
  56. app_notify_on_next_frame(function (l: slot_layer_t) {
  57. slot_layer_unload(l);
  58. }, l);
  59. }
  60. }
  61. for (let i: i32 = 0; i < project_layers.length; ++i) {
  62. let l: slot_layer_t = project_layers[i];
  63. slot_layer_resize_and_set_bits(l);
  64. }
  65. for (let i: i32 = 0; i < history_undo_layers.length; ++i) {
  66. let l: slot_layer_t = history_undo_layers[i];
  67. slot_layer_resize_and_set_bits(l);
  68. }
  69. let rts: map_t<string, render_target_t> = render_path_render_targets;
  70. let blend0: render_target_t = map_get(rts, "texpaint_blend0");
  71. let _texpaint_blend0: image_t = blend0._image;
  72. app_notify_on_next_frame(function (_texpaint_blend0: image_t) {
  73. image_unload(_texpaint_blend0);
  74. }, _texpaint_blend0);
  75. blend0.width = config_get_texture_res_x();
  76. blend0.height = config_get_texture_res_y();
  77. blend0._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8);
  78. let blend1: render_target_t = map_get(rts, "texpaint_blend1");
  79. let _texpaint_blend1: image_t = blend1._image;
  80. app_notify_on_next_frame(function (_texpaint_blend1: image_t) {
  81. image_unload(_texpaint_blend1);
  82. }, _texpaint_blend1);
  83. blend1.width = config_get_texture_res_x();
  84. blend1.height = config_get_texture_res_y();
  85. blend1._image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8);
  86. context_raw.brush_blend_dirty = true;
  87. let blur: render_target_t = map_get(rts, "texpaint_blur");
  88. if (blur != null) {
  89. let _texpaint_blur: image_t = blur._image;
  90. app_notify_on_next_frame(function (_texpaint_blur: image_t) {
  91. image_unload(_texpaint_blur);
  92. }, _texpaint_blur);
  93. let size_x: f32 = math_floor(config_get_texture_res_x() * 0.95);
  94. let size_y: f32 = math_floor(config_get_texture_res_y() * 0.95);
  95. blur.width = size_x;
  96. blur.height = size_y;
  97. blur._image = image_create_render_target(size_x, size_y);
  98. }
  99. if (render_path_paint_live_layer != null) {
  100. slot_layer_resize_and_set_bits(render_path_paint_live_layer);
  101. }
  102. ///if (arm_direct3d12 || arm_vulkan || arm_metal)
  103. render_path_raytrace_ready = false; // Rebuild baketex
  104. ///end
  105. context_raw.ddirty = 2;
  106. }
  107. function layers_set_bits() {
  108. for (let i: i32 = 0; i < project_layers.length; ++i) {
  109. let l: slot_layer_t = project_layers[i];
  110. slot_layer_resize_and_set_bits(l);
  111. }
  112. for (let i: i32 = 0; i < history_undo_layers.length; ++i) {
  113. let l: slot_layer_t = history_undo_layers[i];
  114. slot_layer_resize_and_set_bits(l);
  115. }
  116. }
  117. function layers_make_temp_img() {
  118. ///if (is_paint || is_sculpt)
  119. let l: slot_layer_t = project_layers[0];
  120. ///end
  121. ///if is_lab
  122. let l: brush_output_node_t = context_raw.brush_output_node_inst;
  123. ///end
  124. if (layers_temp_image != null && (layers_temp_image.width != l.texpaint.width || layers_temp_image.height != l.texpaint.height || layers_temp_image.format != l.texpaint.format)) {
  125. let _temptex0: render_target_t = map_get(render_path_render_targets, "temptex0");
  126. app_notify_on_next_frame(function (_temptex0: render_target_t) {
  127. render_target_unload(_temptex0);
  128. }, _temptex0);
  129. map_delete(render_path_render_targets, "temptex0");
  130. layers_temp_image = null;
  131. }
  132. if (layers_temp_image == null) {
  133. let format: string = base_bits_handle.position == texture_bits_t.BITS8 ? "RGBA32" :
  134. base_bits_handle.position == texture_bits_t.BITS16 ? "RGBA64" :
  135. "RGBA128";
  136. ///if is_lab
  137. format = "RGBA32";
  138. ///end
  139. let t: render_target_t = render_target_create();
  140. t.name = "temptex0";
  141. t.width = l.texpaint.width;
  142. t.height = l.texpaint.height;
  143. t.format = format;
  144. let rt: render_target_t = render_path_create_render_target(t);
  145. layers_temp_image = rt._image;
  146. }
  147. }
  148. function layers_make_temp_mask_img() {
  149. if (pipes_temp_mask_image != null && (pipes_temp_mask_image.width != config_get_texture_res_x() || pipes_temp_mask_image.height != config_get_texture_res_y())) {
  150. let _temp_mask_image: image_t = pipes_temp_mask_image;
  151. app_notify_on_next_frame(function (_temp_mask_image: image_t) {
  152. image_unload(_temp_mask_image);
  153. }, _temp_mask_image);
  154. pipes_temp_mask_image = null;
  155. }
  156. if (pipes_temp_mask_image == null) {
  157. pipes_temp_mask_image = image_create_render_target(config_get_texture_res_x(), config_get_texture_res_y(), tex_format_t.R8);
  158. }
  159. }
  160. function layers_make_export_img() {
  161. ///if (is_paint || is_sculpt)
  162. let l: slot_layer_t = project_layers[0];
  163. ///end
  164. ///if is_lab
  165. let l: brush_output_node_t = context_raw.brush_output_node_inst;
  166. ///end
  167. if (layers_expa != null && (layers_expa.width != l.texpaint.width || layers_expa.height != l.texpaint.height || layers_expa.format != l.texpaint.format)) {
  168. let _expa: image_t = layers_expa;
  169. let _expb: image_t = layers_expb;
  170. let _expc: image_t = layers_expc;
  171. app_notify_on_next_frame(function (_expa: image_t) {
  172. image_unload(_expa);
  173. }, _expa);
  174. app_notify_on_next_frame(function (_expb: image_t) {
  175. image_unload(_expb);
  176. }, _expb);
  177. app_notify_on_next_frame(function (_expc: image_t) {
  178. image_unload(_expc);
  179. }, _expc);
  180. layers_expa = null;
  181. layers_expb = null;
  182. layers_expc = null;
  183. map_delete(render_path_render_targets, "expa");
  184. map_delete(render_path_render_targets, "expb");
  185. map_delete(render_path_render_targets, "expc");
  186. }
  187. if (layers_expa == null) {
  188. let format: string = base_bits_handle.position == texture_bits_t.BITS8 ? "RGBA32" :
  189. base_bits_handle.position == texture_bits_t.BITS16 ? "RGBA64" :
  190. "RGBA128";
  191. ///if is_lab
  192. format = "RGBA32";
  193. ///end
  194. {
  195. let t: render_target_t = render_target_create();
  196. t.name = "expa";
  197. t.width = l.texpaint.width;
  198. t.height = l.texpaint.height;
  199. t.format = format;
  200. let rt: render_target_t = render_path_create_render_target(t);
  201. layers_expa = rt._image;
  202. }
  203. {
  204. let t: render_target_t = render_target_create();
  205. t.name = "expb";
  206. t.width = l.texpaint.width;
  207. t.height = l.texpaint.height;
  208. t.format = format;
  209. let rt: render_target_t = render_path_create_render_target(t);
  210. layers_expb = rt._image;
  211. }
  212. {
  213. let t: render_target_t = render_target_create();
  214. t.name = "expc";
  215. t.width = l.texpaint.width;
  216. t.height = l.texpaint.height;
  217. t.format = format;
  218. let rt: render_target_t = render_path_create_render_target(t);
  219. layers_expc = rt._image;
  220. }
  221. }
  222. }
  223. function layers_apply_mask(l: slot_layer_t, m: slot_layer_t) {
  224. if (!slot_layer_is_layer(l) || !slot_layer_is_mask(m)) {
  225. return;
  226. }
  227. layers_make_temp_img();
  228. // Copy layer to temp
  229. g2_begin(layers_temp_image);
  230. g2_set_pipeline(pipes_copy);
  231. g2_draw_image(l.texpaint, 0, 0);
  232. g2_set_pipeline(null);
  233. g2_end();
  234. // Apply mask
  235. g4_begin(l.texpaint);
  236. g4_set_pipeline(pipes_apply_mask);
  237. g4_set_tex(pipes_tex0_mask, layers_temp_image);
  238. g4_set_tex(pipes_texa_mask, m.texpaint);
  239. g4_set_vertex_buffer(const_data_screen_aligned_vb);
  240. g4_set_index_buffer(const_data_screen_aligned_ib);
  241. g4_draw();
  242. g4_end();
  243. }
  244. function layers_commands_merge_pack(pipe: pipeline_t, i0: image_t, i1: image_t, i1pack: image_t, i1mask_opacity: f32, i1texmask: image_t, i1blending: i32 = -1) {
  245. g4_begin(i0);
  246. g4_set_pipeline(pipe);
  247. g4_set_tex(pipes_tex0, i1);
  248. g4_set_tex(pipes_tex1, i1pack);
  249. g4_set_tex(pipes_texmask, i1texmask);
  250. g4_set_tex(pipes_texa, layers_temp_image);
  251. g4_set_float(pipes_opac, i1mask_opacity);
  252. g4_set_int(pipes_blending, i1blending);
  253. g4_set_vertex_buffer(const_data_screen_aligned_vb);
  254. g4_set_index_buffer(const_data_screen_aligned_ib);
  255. g4_draw();
  256. g4_end();
  257. }
  258. function layers_is_fill_material(): bool {
  259. if (context_raw.tool == workspace_tool_t.MATERIAL) {
  260. return true;
  261. }
  262. let m: slot_material_t = context_raw.material;
  263. for (let i: i32 = 0; i < project_layers.length; ++i) {
  264. let l: slot_layer_t = project_layers[i];
  265. if (l.fill_layer == m) {
  266. return true;
  267. }
  268. }
  269. return false;
  270. }
  271. function layers_update_fill_layers() {
  272. let _layer: slot_layer_t = context_raw.layer;
  273. let _tool: workspace_tool_t = context_raw.tool;
  274. let _fill_type: i32 = context_raw.fill_type_handle.position;
  275. let current: image_t = null;
  276. if (context_raw.tool == workspace_tool_t.MATERIAL) {
  277. if (render_path_paint_live_layer == null) {
  278. render_path_paint_live_layer = slot_layer_create("_live");
  279. }
  280. current = _g2_current;
  281. if (current != null) g2_end();
  282. context_raw.tool = workspace_tool_t.FILL;
  283. context_raw.fill_type_handle.position = fill_type_t.OBJECT;
  284. make_material_parse_paint_material(false);
  285. context_raw.pdirty = 1;
  286. render_path_paint_use_live_layer(true);
  287. render_path_paint_commands_paint(false);
  288. render_path_paint_dilate(true, true);
  289. render_path_paint_use_live_layer(false);
  290. context_raw.tool = _tool;
  291. context_raw.fill_type_handle.position = _fill_type;
  292. context_raw.pdirty = 0;
  293. context_raw.rdirty = 2;
  294. if (current != null) g2_begin(current);
  295. return;
  296. }
  297. let has_fill_layer: bool = false;
  298. let has_fill_mask: bool = false;
  299. for (let i: i32 = 0; i < project_layers.length; ++i) {
  300. let l: slot_layer_t = project_layers[i];
  301. if (slot_layer_is_layer(l) && l.fill_layer == context_raw.material) {
  302. has_fill_layer = true;
  303. }
  304. }
  305. for (let i: i32 = 0; i < project_layers.length; ++i) {
  306. let l: slot_layer_t = project_layers[i];
  307. if (slot_layer_is_mask(l) && l.fill_layer == context_raw.material) {
  308. has_fill_mask = true;
  309. }
  310. }
  311. if (has_fill_layer || has_fill_mask) {
  312. current = _g2_current;
  313. if (current != null) {
  314. g2_end();
  315. }
  316. context_raw.pdirty = 1;
  317. context_raw.tool = workspace_tool_t.FILL;
  318. context_raw.fill_type_handle.position = fill_type_t.OBJECT;
  319. if (has_fill_layer) {
  320. let first: bool = true;
  321. for (let i: i32 = 0; i < project_layers.length; ++i) {
  322. let l: slot_layer_t = project_layers[i];
  323. if (slot_layer_is_layer(l) && l.fill_layer == context_raw.material) {
  324. context_raw.layer = l;
  325. if (first) {
  326. first = false;
  327. make_material_parse_paint_material(false);
  328. }
  329. layers_set_object_mask();
  330. slot_layer_clear(l);
  331. render_path_paint_commands_paint(false);
  332. render_path_paint_dilate(true, true);
  333. }
  334. }
  335. }
  336. if (has_fill_mask) {
  337. let first: bool = true;
  338. for (let i: i32 = 0; i < project_layers.length; ++i) {
  339. let l: slot_layer_t = project_layers[i];
  340. if (slot_layer_is_mask(l) && l.fill_layer == context_raw.material) {
  341. context_raw.layer = l;
  342. if (first) {
  343. first = false;
  344. make_material_parse_paint_material(false);
  345. }
  346. layers_set_object_mask();
  347. slot_layer_clear(l);
  348. render_path_paint_commands_paint(false);
  349. render_path_paint_dilate(true, true);
  350. }
  351. }
  352. }
  353. context_raw.pdirty = 0;
  354. context_raw.ddirty = 2;
  355. context_raw.rdirty = 2;
  356. context_raw.layers_preview_dirty = true; // Repaint all layer previews as multiple layers might have changed.
  357. if (current != null) g2_begin(current);
  358. context_raw.layer = _layer;
  359. layers_set_object_mask();
  360. context_raw.tool = _tool;
  361. context_raw.fill_type_handle.position = _fill_type;
  362. make_material_parse_paint_material(false);
  363. }
  364. }
  365. function layers_update_fill_layer(parse_paint: bool = true) {
  366. let current: image_t = _g2_current;
  367. let g2_in_use: bool = _g2_in_use;
  368. if (g2_in_use) g2_end();
  369. let _tool: workspace_tool_t = context_raw.tool;
  370. let _fill_type: i32 = context_raw.fill_type_handle.position;
  371. context_raw.tool = workspace_tool_t.FILL;
  372. context_raw.fill_type_handle.position = fill_type_t.OBJECT;
  373. context_raw.pdirty = 1;
  374. slot_layer_clear(context_raw.layer);
  375. if (parse_paint) {
  376. make_material_parse_paint_material(false);
  377. }
  378. render_path_paint_commands_paint(false);
  379. render_path_paint_dilate(true, true);
  380. context_raw.rdirty = 2;
  381. context_raw.tool = _tool;
  382. context_raw.fill_type_handle.position = _fill_type;
  383. if (g2_in_use) g2_begin(current);
  384. }
  385. function layers_set_object_mask() {
  386. ///if is_sculpt
  387. return;
  388. ///end
  389. let ar: string[] = [tr("None")];
  390. for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
  391. let p: mesh_object_t = project_paint_objects[i];
  392. array_push(ar, p.base.name);
  393. }
  394. let mask: i32 = context_object_mask_used() ? slot_layer_get_object_mask(context_raw.layer) : 0;
  395. if (context_layer_filter_used()) {
  396. mask = context_raw.layer_filter;
  397. }
  398. if (mask > 0) {
  399. if (context_raw.merged_object != null) {
  400. context_raw.merged_object.base.visible = false;
  401. }
  402. let o: mesh_object_t = project_paint_objects[0];
  403. for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
  404. let p: mesh_object_t = project_paint_objects[i];
  405. let mask_name: string = ar[mask];
  406. if (p.base.name == mask_name) {
  407. o = p;
  408. break;
  409. }
  410. }
  411. context_select_paint_object(o);
  412. }
  413. else {
  414. let is_atlas: bool = slot_layer_get_object_mask(context_raw.layer) > 0 && slot_layer_get_object_mask(context_raw.layer) <= project_paint_objects.length;
  415. if (context_raw.merged_object == null || is_atlas || context_raw.merged_object_is_atlas) {
  416. let visibles: mesh_object_t[] = is_atlas ? project_get_atlas_objects(slot_layer_get_object_mask(context_raw.layer)) : null;
  417. util_mesh_merge(visibles);
  418. }
  419. context_select_paint_object(context_main_object());
  420. context_raw.paint_object.skip_context = "paint";
  421. context_raw.merged_object.base.visible = true;
  422. }
  423. util_uv_dilatemap_cached = false;
  424. }
  425. function layers_new_layer(clear: bool = true, position: i32 = -1): slot_layer_t {
  426. if (project_layers.length > layers_max_layers) {
  427. return null;
  428. }
  429. let l: slot_layer_t = slot_layer_create();
  430. l.object_mask = context_raw.layer_filter;
  431. if (position == -1) {
  432. if (slot_layer_is_mask(context_raw.layer)) context_set_layer(context_raw.layer.parent);
  433. array_insert(project_layers, array_index_of(project_layers, context_raw.layer) + 1, l);
  434. }
  435. else {
  436. array_insert(project_layers, position, l);
  437. }
  438. context_set_layer(l);
  439. let li: i32 = array_index_of(project_layers, context_raw.layer);
  440. if (li > 0) {
  441. let below: slot_layer_t = project_layers[li - 1];
  442. if (slot_layer_is_layer(below)) {
  443. context_raw.layer.parent = below.parent;
  444. }
  445. }
  446. if (clear) {
  447. app_notify_on_init(function (l: slot_layer_t) {
  448. slot_layer_clear(l);
  449. }, l);
  450. }
  451. context_raw.layer_preview_dirty = true;
  452. return l;
  453. }
  454. function layers_new_mask(clear: bool = true, parent: slot_layer_t, position: i32 = -1): slot_layer_t {
  455. if (project_layers.length > layers_max_layers) {
  456. return null;
  457. }
  458. let l: slot_layer_t = slot_layer_create("", layer_slot_type_t.MASK, parent);
  459. if (position == -1) {
  460. position = array_index_of(project_layers, parent);
  461. }
  462. array_insert(project_layers, position, l);
  463. context_set_layer(l);
  464. if (clear) {
  465. app_notify_on_init(function (l: slot_layer_t) {
  466. slot_layer_clear(l);
  467. }, l);
  468. }
  469. context_raw.layer_preview_dirty = true;
  470. return l;
  471. }
  472. function layers_new_group(): slot_layer_t {
  473. if (project_layers.length > layers_max_layers) {
  474. return null;
  475. }
  476. let l: slot_layer_t = slot_layer_create("", layer_slot_type_t.GROUP);
  477. array_push(project_layers, l);
  478. context_set_layer(l);
  479. return l;
  480. }
  481. function layers_create_fill_layer(uv_type: uv_type_t = uv_type_t.UVMAP, decal_mat: mat4_t = mat4nan, position: i32 = -1) {
  482. ///if is_forge
  483. return;
  484. ///end
  485. _layers_uv_type = uv_type;
  486. _layers_decal_mat = decal_mat;
  487. _layers_position = position;
  488. app_notify_on_init(function () {
  489. let l: slot_layer_t = layers_new_layer(false, _layers_position);
  490. history_new_layer();
  491. l.uv_type = _layers_uv_type;
  492. if (!mat4_isnan(_layers_decal_mat)) {
  493. l.decal_mat = _layers_decal_mat;
  494. }
  495. l.object_mask = context_raw.layer_filter;
  496. history_to_fill_layer();
  497. slot_layer_to_fill_layer(l);
  498. });
  499. }
  500. function layers_create_image_mask(asset: asset_t) {
  501. let l: slot_layer_t = context_raw.layer;
  502. if (slot_layer_is_mask(l) || slot_layer_is_group(l)) {
  503. return;
  504. }
  505. history_new_layer();
  506. let m: slot_layer_t = layers_new_mask(false, l);
  507. slot_layer_clear(m, 0x00000000, project_get_image(asset));
  508. context_raw.layer_preview_dirty = true;
  509. }
  510. function layers_create_color_layer(base_color: i32, occlusion: f32 = 1.0, roughness: f32 = layers_default_rough, metallic: f32 = 0.0, position: i32 = -1) {
  511. _layers_base_color = base_color;
  512. _layers_occlusion = occlusion;
  513. _layers_roughness = roughness;
  514. _layers_metallic = metallic;
  515. _layers_position = position;
  516. app_notify_on_init(function () {
  517. let l: slot_layer_t = layers_new_layer(false, _layers_position);
  518. history_new_layer();
  519. l.uv_type = uv_type_t.UVMAP;
  520. l.object_mask = context_raw.layer_filter;
  521. slot_layer_clear(l, _layers_base_color, null, _layers_occlusion, _layers_roughness, _layers_metallic);
  522. });
  523. }
  524. function layers_duplicate_layer(l: slot_layer_t) {
  525. if (!slot_layer_is_group(l)) {
  526. let new_layer: slot_layer_t = slot_layer_duplicate(l);
  527. context_set_layer(new_layer);
  528. let masks: slot_layer_t[] = slot_layer_get_masks(l, false);
  529. if (masks != null) {
  530. for (let i: i32 = 0; i < masks.length; ++i) {
  531. let m: slot_layer_t = masks[i];
  532. m = slot_layer_duplicate(m);
  533. m.parent = new_layer;
  534. array_remove(project_layers, m);
  535. array_insert(project_layers, array_index_of(project_layers, new_layer), m);
  536. }
  537. }
  538. context_set_layer(new_layer);
  539. }
  540. else {
  541. let new_group: slot_layer_t = layers_new_group();
  542. array_remove(project_layers, new_group);
  543. array_insert(project_layers, array_index_of(project_layers, l) + 1, new_group);
  544. // group.show_panel = true;
  545. for (let i: i32 = 0; i < slot_layer_get_children(l).length; ++i) {
  546. let c: slot_layer_t = slot_layer_get_children(l)[i];
  547. let masks: slot_layer_t[] = slot_layer_get_masks(c, false);
  548. let new_layer: slot_layer_t = slot_layer_duplicate(c);
  549. new_layer.parent = new_group;
  550. array_remove(project_layers, new_layer);
  551. array_insert(project_layers, array_index_of(project_layers, new_group), new_layer);
  552. if (masks != null) {
  553. for (let i: i32 = 0; i < masks.length; ++i) {
  554. let m: slot_layer_t = masks[i];
  555. let new_mask: slot_layer_t = slot_layer_duplicate(m);
  556. new_mask.parent = new_layer;
  557. array_remove(project_layers, new_mask);
  558. array_insert(project_layers, array_index_of(project_layers, new_layer), new_mask);
  559. }
  560. }
  561. }
  562. let group_masks: slot_layer_t[] = slot_layer_get_masks(l);
  563. if (group_masks != null) {
  564. for (let i: i32 = 0; i < group_masks.length; ++i) {
  565. let m: slot_layer_t = group_masks[i];
  566. let new_mask: slot_layer_t = slot_layer_duplicate(m);
  567. new_mask.parent = new_group;
  568. array_remove(project_layers, new_mask);
  569. array_insert(project_layers, array_index_of(project_layers, new_group), new_mask);
  570. }
  571. }
  572. context_set_layer(new_group);
  573. }
  574. }
  575. function layers_apply_masks(l: slot_layer_t) {
  576. let masks: slot_layer_t[] = slot_layer_get_masks(l);
  577. if (masks != null) {
  578. for (let i: i32 = 0; i < masks.length - 1; ++i) {
  579. layers_merge_layer(masks[i + 1], masks[i]);
  580. slot_layer_delete(masks[i]);
  581. }
  582. slot_layer_apply_mask(masks[masks.length - 1]);
  583. context_raw.layer_preview_dirty = true;
  584. }
  585. }
  586. function layers_merge_down() {
  587. let l1: slot_layer_t = context_raw.layer;
  588. if (slot_layer_is_group(l1)) {
  589. l1 = layers_merge_group(l1);
  590. }
  591. else if (slot_layer_has_masks(l1)) { // It is a layer
  592. layers_apply_masks(l1);
  593. context_set_layer(l1);
  594. }
  595. let l0: slot_layer_t = project_layers[array_index_of(project_layers, l1) - 1];
  596. if (slot_layer_is_group(l0)) {
  597. l0 = layers_merge_group(l0);
  598. }
  599. else if (slot_layer_has_masks(l0)) { // It is a layer
  600. layers_apply_masks(l0);
  601. context_set_layer(l0);
  602. }
  603. layers_merge_layer(l0, l1);
  604. slot_layer_delete(l1);
  605. context_set_layer(l0);
  606. context_raw.layer_preview_dirty = true;
  607. }
  608. function layers_merge_group(l: slot_layer_t): slot_layer_t {
  609. if (!slot_layer_is_group(l)) {
  610. return null;
  611. }
  612. let children: slot_layer_t[] = slot_layer_get_children(l);
  613. if (children.length == 1 && slot_layer_has_masks(children[0], false)) {
  614. layers_apply_masks(children[0]);
  615. }
  616. for (let i: i32 = 0; i < children.length - 1; ++i) {
  617. context_set_layer(children[children.length - 1 - i]);
  618. history_merge_layers();
  619. layers_merge_down();
  620. }
  621. // Now apply the group masks
  622. let masks: slot_layer_t[] = slot_layer_get_masks(l);
  623. if (masks != null) {
  624. for (let i: i32 = 0; i < masks.length - 1; ++i) {
  625. layers_merge_layer(masks[i + 1], masks[i]);
  626. slot_layer_delete(masks[i]);
  627. }
  628. layers_apply_mask(children[0], masks[masks.length - 1]);
  629. }
  630. children[0].parent = null;
  631. children[0].name = l.name;
  632. if (children[0].fill_layer != null) {
  633. slot_layer_to_paint_layer(children[0]);
  634. }
  635. slot_layer_delete(l);
  636. return children[0];
  637. }
  638. function layers_merge_layer(l0 : slot_layer_t, l1: slot_layer_t, use_mask: bool = false) {
  639. if (!l1.visible || slot_layer_is_group(l1)) {
  640. return;
  641. }
  642. layers_make_temp_img();
  643. g2_begin(layers_temp_image); // Copy to temp
  644. g2_set_pipeline(pipes_copy);
  645. g2_draw_image(l0.texpaint, 0, 0);
  646. g2_set_pipeline(null);
  647. g2_end();
  648. let empty_rt: render_target_t = map_get(render_path_render_targets, "empty_white");
  649. let empty: image_t = empty_rt._image;
  650. let mask: image_t = empty;
  651. let l1masks: slot_layer_t[] = use_mask ? slot_layer_get_masks(l1) : null;
  652. if (l1masks != null) {
  653. // for (let i: i32 = 1; i < l1masks.length - 1; ++i) {
  654. // merge_layer(l1masks[i + 1], l1masks[i]);
  655. // }
  656. mask = l1masks[0].texpaint;
  657. }
  658. if (slot_layer_is_mask(l1)) {
  659. g4_begin(l0.texpaint);
  660. g4_set_pipeline(pipes_merge_mask);
  661. g4_set_tex(pipes_tex0_merge_mask, l1.texpaint);
  662. g4_set_tex(pipes_texa_merge_mask, layers_temp_image);
  663. g4_set_float(pipes_opac_merge_mask, slot_layer_get_opacity(l1));
  664. g4_set_int(pipes_blending_merge_mask, l1.blending);
  665. g4_set_vertex_buffer(const_data_screen_aligned_vb);
  666. g4_set_index_buffer(const_data_screen_aligned_ib);
  667. g4_draw();
  668. g4_end();
  669. }
  670. if (slot_layer_is_layer(l1)) {
  671. if (l1.paint_base) {
  672. g4_begin(l0.texpaint);
  673. g4_set_pipeline(pipes_merge);
  674. g4_set_tex(pipes_tex0, l1.texpaint);
  675. g4_set_tex(pipes_tex1, empty);
  676. g4_set_tex(pipes_texmask, mask);
  677. g4_set_tex(pipes_texa, layers_temp_image);
  678. g4_set_float(pipes_opac, slot_layer_get_opacity(l1));
  679. g4_set_int(pipes_blending, l1.blending);
  680. g4_set_vertex_buffer(const_data_screen_aligned_vb);
  681. g4_set_index_buffer(const_data_screen_aligned_ib);
  682. g4_draw();
  683. g4_end();
  684. }
  685. if (l0.texpaint_nor != null) {
  686. g2_begin(layers_temp_image);
  687. g2_set_pipeline(pipes_copy);
  688. g2_draw_image(l0.texpaint_nor, 0, 0);
  689. g2_set_pipeline(null);
  690. g2_end();
  691. if (l1.paint_nor) {
  692. g4_begin(l0.texpaint_nor);
  693. g4_set_pipeline(pipes_merge);
  694. g4_set_tex(pipes_tex0, l1.texpaint);
  695. g4_set_tex(pipes_tex1, l1.texpaint_nor);
  696. g4_set_tex(pipes_texmask, mask);
  697. g4_set_tex(pipes_texa, layers_temp_image);
  698. g4_set_float(pipes_opac, slot_layer_get_opacity(l1));
  699. g4_set_int(pipes_blending, l1.paint_nor_blend ? -2 : -1);
  700. g4_set_vertex_buffer(const_data_screen_aligned_vb);
  701. g4_set_index_buffer(const_data_screen_aligned_ib);
  702. g4_draw();
  703. g4_end();
  704. }
  705. }
  706. if (l0.texpaint_pack != null) {
  707. g2_begin(layers_temp_image);
  708. g2_set_pipeline(pipes_copy);
  709. g2_draw_image(l0.texpaint_pack, 0, 0);
  710. g2_set_pipeline(null);
  711. g2_end();
  712. if (l1.paint_occ || l1.paint_rough || l1.paint_met || l1.paint_height) {
  713. if (l1.paint_occ && l1.paint_rough && l1.paint_met && l1.paint_height) {
  714. layers_commands_merge_pack(pipes_merge, l0.texpaint_pack, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask, l1.paint_height_blend ? -3 : -1);
  715. }
  716. else {
  717. if (l1.paint_occ) {
  718. layers_commands_merge_pack(pipes_merge_r, l0.texpaint_pack, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask);
  719. }
  720. if (l1.paint_rough) {
  721. layers_commands_merge_pack(pipes_merge_g, l0.texpaint_pack, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask);
  722. }
  723. if (l1.paint_met) {
  724. layers_commands_merge_pack(pipes_merge_b, l0.texpaint_pack, l1.texpaint, l1.texpaint_pack, slot_layer_get_opacity(l1), mask);
  725. }
  726. }
  727. }
  728. }
  729. }
  730. }
  731. function layers_flatten(height_to_normal: bool = false, layers: slot_layer_t[] = null): slot_layer_t {
  732. return layers_ext_flatten(height_to_normal, layers);
  733. }
  734. function layers_on_resized() {
  735. layers_ext_on_resized();
  736. }