layers.ts 25 KB

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