render_path_paint.ts 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876
  1. let render_path_paint_live_layer: slot_layer_t = null;
  2. let render_path_paint_live_layer_drawn: i32 = 0;
  3. let render_path_paint_live_layer_locked: bool = false;
  4. let render_path_paint_dilated: bool = true;
  5. let render_path_paint_push_undo_last: bool;
  6. let render_path_paint_painto: mesh_object_t = null;
  7. let render_path_paint_planeo: mesh_object_t = null;
  8. let render_path_paint_visibles: bool[] = null;
  9. let render_path_paint_merged_object_visible: bool = false;
  10. let render_path_paint_saved_fov: f32 = 0.0;
  11. let render_path_paint_baking: bool = false;
  12. let _render_path_paint_texpaint: render_target_t;
  13. let _render_path_paint_texpaint_nor: render_target_t;
  14. let _render_path_paint_texpaint_pack: render_target_t;
  15. let _render_path_paint_texpaint_undo: render_target_t;
  16. let _render_path_paint_texpaint_nor_undo: render_target_t;
  17. let _render_path_paint_texpaint_pack_undo: render_target_t;
  18. let render_path_paint_last_x: f32 = -1.0;
  19. let render_path_paint_last_y: f32 = -1.0;
  20. function render_path_paint_init() {
  21. {
  22. let t: render_target_t = render_target_create();
  23. t.name = "texpaint_blend0";
  24. t.width = config_get_texture_res_x();
  25. t.height = config_get_texture_res_y();
  26. t.format = "R8";
  27. render_path_create_render_target(t);
  28. }
  29. {
  30. let t: render_target_t = render_target_create();
  31. t.name = "texpaint_blend1";
  32. t.width = config_get_texture_res_x();
  33. t.height = config_get_texture_res_y();
  34. t.format = "R8";
  35. render_path_create_render_target(t);
  36. }
  37. {
  38. let t: render_target_t = render_target_create();
  39. t.name = "texpaint_colorid";
  40. t.width = 1;
  41. t.height = 1;
  42. t.format = "RGBA32";
  43. render_path_create_render_target(t);
  44. }
  45. {
  46. let t: render_target_t = render_target_create();
  47. t.name = "texpaint_picker";
  48. t.width = 1;
  49. t.height = 1;
  50. t.format = "RGBA32";
  51. render_path_create_render_target(t);
  52. }
  53. {
  54. let t: render_target_t = render_target_create();
  55. t.name = "texpaint_nor_picker";
  56. t.width = 1;
  57. t.height = 1;
  58. t.format = "RGBA32";
  59. render_path_create_render_target(t);
  60. }
  61. {
  62. let t: render_target_t = render_target_create();
  63. t.name = "texpaint_pack_picker";
  64. t.width = 1;
  65. t.height = 1;
  66. t.format = "RGBA32";
  67. render_path_create_render_target(t);
  68. }
  69. {
  70. let t: render_target_t = render_target_create();
  71. t.name = "texpaint_uv_picker";
  72. t.width = 1;
  73. t.height = 1;
  74. t.format = "RGBA32";
  75. render_path_create_render_target(t);
  76. }
  77. {
  78. let t: render_target_t = render_target_create();
  79. t.name = "texpaint_posnortex_picker0";
  80. t.width = 1;
  81. t.height = 1;
  82. t.format = "RGBA128";
  83. render_path_create_render_target(t);
  84. }
  85. {
  86. let t: render_target_t = render_target_create();
  87. t.name = "texpaint_posnortex_picker1";
  88. t.width = 1;
  89. t.height = 1;
  90. t.format = "RGBA128";
  91. render_path_create_render_target(t);
  92. }
  93. render_path_load_shader("Scene/copy_mrt3_pass/copy_mrt3_pass");
  94. render_path_load_shader("Scene/copy_mrt3_pass/copy_mrt3RGBA64_pass");
  95. render_path_load_shader("Scene/copy_mrt3_pass/copy_mrt3RGBA128_pass");
  96. render_path_load_shader("Scene/dilate_pass/dilate_pass");
  97. render_path_load_shader("Scene/dilate_pass/dilateRGBA64_pass");
  98. render_path_load_shader("Scene/dilate_pass/dilateRGBA128_pass");
  99. }
  100. function render_path_paint_draw_fullscreen_triangle(context: string) {
  101. // Note that vertices are mangled in vertex shader to form a fullscreen triangle,
  102. // so plane transform does not matter
  103. let plane: mesh_object_t = scene_get_child(".Plane").ext;
  104. let _visible: bool = plane.base.visible;
  105. plane.base.visible = true;
  106. mesh_object_render(plane, context, _render_path_bind_params);
  107. plane.base.visible = _visible;
  108. render_path_end();
  109. }
  110. function render_path_paint_commands_paint(dilation: bool = true) {
  111. let tid: i32 = context_raw.layer.id;
  112. if (context_raw.layer.texpaint_sculpt != null) {
  113. render_path_sculpt_commands();
  114. return;
  115. }
  116. if (context_raw.pdirty > 0) {
  117. if (context_raw.tool == tool_type_t.COLORID) {
  118. render_path_set_target("texpaint_colorid", null, null, gpu_clear_t.COLOR, 0xff000000);
  119. render_path_bind_target("gbuffer2", "gbuffer2");
  120. render_path_paint_draw_fullscreen_triangle("paint");
  121. ui_header_handle.redraws = 2;
  122. }
  123. else if (context_raw.tool == tool_type_t.PICKER || context_raw.tool == tool_type_t.MATERIAL) {
  124. if (context_raw.pick_pos_nor_tex) {
  125. if (context_raw.paint2d) {
  126. let additional: string[] = [ "gbuffer1", "gbuffer2" ];
  127. render_path_set_target("gbuffer0", additional, "main");
  128. render_path_draw_meshes("mesh");
  129. }
  130. let additional: string[] = [ "texpaint_posnortex_picker1" ];
  131. render_path_set_target("texpaint_posnortex_picker0", additional);
  132. render_path_bind_target("gbuffer2", "gbuffer2");
  133. render_path_bind_target("main", "gbufferD");
  134. render_path_draw_meshes("paint");
  135. let picker0: render_target_t = map_get(render_path_render_targets, "texpaint_posnortex_picker0");
  136. let picker1: render_target_t = map_get(render_path_render_targets, "texpaint_posnortex_picker1");
  137. let texpaint_posnortex_picker0: gpu_texture_t = picker0._image;
  138. let texpaint_posnortex_picker1: gpu_texture_t = picker1._image;
  139. let a: buffer_t = gpu_get_texture_pixels(texpaint_posnortex_picker0);
  140. let b: buffer_t = gpu_get_texture_pixels(texpaint_posnortex_picker1);
  141. context_raw.posx_picked = buffer_get_f32(a, 0);
  142. context_raw.posy_picked = buffer_get_f32(a, 4);
  143. context_raw.posz_picked = buffer_get_f32(a, 8);
  144. context_raw.uvx_picked = buffer_get_f32(a, 12);
  145. context_raw.norx_picked = buffer_get_f32(b, 0);
  146. context_raw.nory_picked = buffer_get_f32(b, 4);
  147. context_raw.norz_picked = buffer_get_f32(b, 8);
  148. context_raw.uvy_picked = buffer_get_f32(b, 12);
  149. }
  150. else {
  151. let additional: string[] = [ "texpaint_nor_picker", "texpaint_pack_picker", "texpaint_uv_picker" ];
  152. render_path_set_target("texpaint_picker", additional);
  153. render_path_bind_target("gbuffer2", "gbuffer2");
  154. tid = context_raw.layer.id;
  155. let use_live_layer: bool = context_raw.tool == tool_type_t.MATERIAL;
  156. if (use_live_layer) {
  157. render_path_paint_use_live_layer(true);
  158. }
  159. render_path_bind_target("texpaint" + tid, "texpaint");
  160. render_path_bind_target("texpaint_nor" + tid, "texpaint_nor");
  161. render_path_bind_target("texpaint_pack" + tid, "texpaint_pack");
  162. render_path_paint_draw_fullscreen_triangle("paint");
  163. if (use_live_layer) {
  164. render_path_paint_use_live_layer(false);
  165. }
  166. ui_header_handle.redraws = 2;
  167. ui_base_hwnds[2].redraws = 2;
  168. let texpaint_picker: render_target_t = map_get(render_path_render_targets, "texpaint_picker");
  169. let texpaint_nor_picker: render_target_t = map_get(render_path_render_targets, "texpaint_nor_picker");
  170. let texpaint_pack_picker: render_target_t = map_get(render_path_render_targets, "texpaint_pack_picker");
  171. let texpaint_uv_picker: render_target_t = map_get(render_path_render_targets, "texpaint_uv_picker");
  172. let a: buffer_t = gpu_get_texture_pixels(texpaint_picker._image);
  173. let b: buffer_t = gpu_get_texture_pixels(texpaint_nor_picker._image);
  174. let c: buffer_t = gpu_get_texture_pixels(texpaint_pack_picker._image);
  175. let d: buffer_t = gpu_get_texture_pixels(texpaint_uv_picker._image);
  176. if (context_raw.color_picker_callback != null) {
  177. context_raw.color_picker_callback(context_raw.picked_color);
  178. }
  179. // Picked surface values
  180. /// if IRON_BGRA
  181. let i0: i32 = 2;
  182. let i1: i32 = 1;
  183. let i2: i32 = 0;
  184. /// else
  185. let i0: i32 = 0;
  186. let i1: i32 = 1;
  187. let i2: i32 = 2;
  188. /// end
  189. let i3: i32 = 3;
  190. context_raw.picked_color.base = color_set_rb(context_raw.picked_color.base, buffer_get_u8(a, i0));
  191. context_raw.picked_color.base = color_set_gb(context_raw.picked_color.base, buffer_get_u8(a, i1));
  192. context_raw.picked_color.base = color_set_bb(context_raw.picked_color.base, buffer_get_u8(a, i2));
  193. context_raw.picked_color.normal = color_set_rb(context_raw.picked_color.normal, buffer_get_u8(b, i0));
  194. context_raw.picked_color.normal = color_set_gb(context_raw.picked_color.normal, buffer_get_u8(b, i1));
  195. context_raw.picked_color.normal = color_set_bb(context_raw.picked_color.normal, buffer_get_u8(b, i2));
  196. context_raw.picked_color.occlusion = buffer_get_u8(c, i0) / 255;
  197. context_raw.picked_color.roughness = buffer_get_u8(c, i1) / 255;
  198. context_raw.picked_color.metallic = buffer_get_u8(c, i2) / 255;
  199. context_raw.picked_color.height = buffer_get_u8(c, i3) / 255;
  200. context_raw.picked_color.opacity = buffer_get_u8(a, i3) / 255;
  201. context_raw.uvx_picked = buffer_get_u8(d, i0) / 255;
  202. context_raw.uvy_picked = buffer_get_u8(d, i1) / 255;
  203. // Pick material
  204. if (context_raw.picker_select_material && context_raw.color_picker_callback == null) {
  205. // matid % 3 == 0 - normal, 1 - emission, 2 - subsurface
  206. let id: i32 = buffer_get_u8(b, 3);
  207. let matid: i32 = math_floor((id - (id % 3)) / 3);
  208. for (let i: i32 = 0; i < project_materials.length; ++i) {
  209. let m: slot_material_t = project_materials[i];
  210. if (m.id == matid) {
  211. context_set_material(m);
  212. context_raw.materialid_picked = matid;
  213. break;
  214. }
  215. }
  216. }
  217. }
  218. }
  219. else {
  220. let texpaint: string = "texpaint" + tid;
  221. if (context_raw.tool == tool_type_t.BAKE && context_raw.brush_time == sys_delta()) {
  222. // Clear to black on bake start
  223. render_path_set_target(texpaint, null, null, gpu_clear_t.COLOR, 0xff000000);
  224. }
  225. render_path_set_target("texpaint_blend1");
  226. render_path_bind_target("texpaint_blend0", "tex");
  227. render_path_draw_shader("Scene/copy_pass/copyR8_pass");
  228. let is_mask: bool = slot_layer_is_mask(context_raw.layer);
  229. if (is_mask) {
  230. let ptid: i32 = context_raw.layer.parent.id;
  231. if (slot_layer_is_group(context_raw.layer.parent)) { // Group mask
  232. for (let i: i32 = 0; i < slot_layer_get_children(context_raw.layer.parent).length; ++i) {
  233. let c: slot_layer_t = slot_layer_get_children(context_raw.layer.parent)[i];
  234. ptid = c.id;
  235. break;
  236. }
  237. }
  238. let additional: string[] = [ "texpaint_nor" + ptid, "texpaint_pack" + ptid, "texpaint_blend0" ];
  239. render_path_set_target(texpaint, additional);
  240. }
  241. else {
  242. let additional: string[] = [ "texpaint_nor" + tid, "texpaint_pack" + tid, "texpaint_blend0" ];
  243. render_path_set_target(texpaint, additional);
  244. }
  245. render_path_bind_target("main", "gbufferD");
  246. if (context_raw.xray || config_raw.brush_angle_reject) {
  247. render_path_bind_target("gbuffer0", "gbuffer0");
  248. }
  249. render_path_bind_target("texpaint_blend1", "paintmask");
  250. if (context_raw.colorid_picked) {
  251. render_path_bind_target("texpaint_colorid", "texpaint_colorid");
  252. }
  253. // Read texcoords from gbuffer
  254. let read_tc: bool = (context_raw.tool == tool_type_t.FILL && context_raw.fill_type_handle.i == fill_type_t.FACE) ||
  255. context_raw.tool == tool_type_t.CLONE || context_raw.tool == tool_type_t.BLUR || context_raw.tool == tool_type_t.SMUDGE;
  256. if (read_tc) {
  257. render_path_bind_target("gbuffer2", "gbuffer2");
  258. }
  259. render_path_draw_meshes("paint");
  260. if (context_raw.tool == tool_type_t.BAKE && context_raw.bake_type == bake_type_t.CURVATURE && context_raw.bake_curv_smooth > 0) {
  261. if (map_get(render_path_render_targets, "texpaint_blur") == null) {
  262. let t: render_target_t = render_target_create();
  263. t.name = "texpaint_blur";
  264. t.width = math_floor(config_get_texture_res_x() * 0.95);
  265. t.height = math_floor(config_get_texture_res_y() * 0.95);
  266. t.format = "RGBA32";
  267. render_path_create_render_target(t);
  268. }
  269. let blurs: i32 = math_round(context_raw.bake_curv_smooth);
  270. for (let i: i32 = 0; i < blurs; ++i) {
  271. render_path_set_target("texpaint_blur");
  272. render_path_bind_target(texpaint, "tex");
  273. render_path_draw_shader("Scene/copy_pass/copy_pass");
  274. render_path_set_target(texpaint);
  275. render_path_bind_target("texpaint_blur", "tex");
  276. render_path_draw_shader("Scene/copy_pass/copy_pass");
  277. }
  278. }
  279. if (dilation) {
  280. render_path_paint_dilate(true, false);
  281. }
  282. }
  283. }
  284. }
  285. function render_path_paint_use_live_layer(use: bool) {
  286. let tid: i32 = context_raw.layer.id;
  287. let hid: i32 = history_undo_i - 1 < 0 ? config_raw.undo_steps - 1 : history_undo_i - 1;
  288. if (use) {
  289. _render_path_paint_texpaint = map_get(render_path_render_targets, "texpaint" + tid);
  290. _render_path_paint_texpaint_undo = map_get(render_path_render_targets, "texpaint_undo" + hid);
  291. _render_path_paint_texpaint_nor_undo = map_get(render_path_render_targets, "texpaint_nor_undo" + hid);
  292. _render_path_paint_texpaint_pack_undo = map_get(render_path_render_targets, "texpaint_pack_undo" + hid);
  293. _render_path_paint_texpaint_nor = map_get(render_path_render_targets, "texpaint_nor" + tid);
  294. _render_path_paint_texpaint_pack = map_get(render_path_render_targets, "texpaint_pack" + tid);
  295. map_set(render_path_render_targets, "texpaint_undo" + hid, map_get(render_path_render_targets, "texpaint" + tid));
  296. map_set(render_path_render_targets, "texpaint" + tid, map_get(render_path_render_targets, "texpaint_live"));
  297. if (slot_layer_is_layer(context_raw.layer)) {
  298. map_set(render_path_render_targets, "texpaint_nor_undo" + hid, map_get(render_path_render_targets, "texpaint_nor" + tid));
  299. map_set(render_path_render_targets, "texpaint_pack_undo" + hid, map_get(render_path_render_targets, "texpaint_pack" + tid));
  300. map_set(render_path_render_targets, "texpaint_nor" + tid, map_get(render_path_render_targets, "texpaint_nor_live"));
  301. map_set(render_path_render_targets, "texpaint_pack" + tid, map_get(render_path_render_targets, "texpaint_pack_live"));
  302. }
  303. }
  304. else {
  305. map_set(render_path_render_targets, "texpaint" + tid, _render_path_paint_texpaint);
  306. map_set(render_path_render_targets, "texpaint_undo" + hid, _render_path_paint_texpaint_undo);
  307. if (slot_layer_is_layer(context_raw.layer)) {
  308. map_set(render_path_render_targets, "texpaint_nor_undo" + hid, _render_path_paint_texpaint_nor_undo);
  309. map_set(render_path_render_targets, "texpaint_pack_undo" + hid, _render_path_paint_texpaint_pack_undo);
  310. map_set(render_path_render_targets, "texpaint_nor" + tid, _render_path_paint_texpaint_nor);
  311. map_set(render_path_render_targets, "texpaint_pack" + tid, _render_path_paint_texpaint_pack);
  312. }
  313. }
  314. render_path_paint_live_layer_locked = use;
  315. }
  316. function render_path_paint_commands_live_brush() {
  317. let tool: tool_type_t = context_raw.tool;
  318. if (tool != tool_type_t.BRUSH && tool != tool_type_t.ERASER && tool != tool_type_t.CLONE && tool != tool_type_t.DECAL && tool != tool_type_t.TEXT &&
  319. tool != tool_type_t.BLUR && tool != tool_type_t.SMUDGE) {
  320. return;
  321. }
  322. if (render_path_paint_live_layer_locked) {
  323. return;
  324. }
  325. if (render_path_paint_live_layer == null) {
  326. render_path_paint_live_layer = slot_layer_create("_live");
  327. }
  328. let tid: i32 = context_raw.layer.id;
  329. if (slot_layer_is_mask(context_raw.layer)) {
  330. render_path_set_target("texpaint_live");
  331. render_path_bind_target("texpaint" + tid, "tex");
  332. render_path_draw_shader("Scene/copy_pass/copy_pass");
  333. }
  334. else {
  335. let additional: string[] = [ "texpaint_nor_live", "texpaint_pack_live" ];
  336. render_path_set_target("texpaint_live", additional);
  337. render_path_bind_target("texpaint" + tid, "tex0");
  338. render_path_bind_target("texpaint_nor" + tid, "tex1");
  339. render_path_bind_target("texpaint_pack" + tid, "tex2");
  340. render_path_draw_shader("Scene/copy_mrt3_pass/copy_mrt3_pass");
  341. }
  342. render_path_paint_use_live_layer(true);
  343. render_path_paint_live_layer_drawn = 2;
  344. ui_view2d_hwnd.redraws = 2;
  345. let _x: f32 = context_raw.paint_vec.x;
  346. let _y: f32 = context_raw.paint_vec.y;
  347. let _last_x: f32 = context_raw.last_paint_vec_x;
  348. let _last_y: f32 = context_raw.last_paint_vec_y;
  349. let _pdirty: i32 = context_raw.pdirty;
  350. context_raw.last_paint_vec_x = context_raw.paint_vec.x;
  351. context_raw.last_paint_vec_y = context_raw.paint_vec.y;
  352. if (operator_shortcut(map_get(config_keymap, "brush_ruler"))) {
  353. context_raw.last_paint_vec_x = context_raw.last_paint_x;
  354. context_raw.last_paint_vec_y = context_raw.last_paint_y;
  355. }
  356. context_raw.pdirty = 2;
  357. render_path_paint_commands_symmetry();
  358. render_path_paint_commands_paint();
  359. render_path_paint_use_live_layer(false);
  360. context_raw.paint_vec.x = _x;
  361. context_raw.paint_vec.y = _y;
  362. context_raw.last_paint_vec_x = _last_x;
  363. context_raw.last_paint_vec_y = _last_y;
  364. context_raw.pdirty = _pdirty;
  365. context_raw.brush_blend_dirty = true;
  366. }
  367. function render_path_paint_commands_cursor() {
  368. let decal_mask: bool = context_is_decal_mask();
  369. let tool: tool_type_t = context_raw.tool;
  370. if (tool != tool_type_t.BRUSH && tool != tool_type_t.ERASER && tool != tool_type_t.CLONE && tool != tool_type_t.BLUR && tool != tool_type_t.SMUDGE &&
  371. tool != tool_type_t.PARTICLE && !decal_mask) {
  372. return;
  373. }
  374. let fill_layer: bool = context_raw.layer.fill_layer != null;
  375. let group_layer: bool = slot_layer_is_group(context_raw.layer);
  376. if (!base_ui_enabled || base_is_dragging || fill_layer || group_layer) {
  377. return;
  378. }
  379. let mx: f32 = context_raw.paint_vec.x;
  380. let my: f32 = 1.0 - context_raw.paint_vec.y;
  381. let radius: f32 = decal_mask ? context_raw.brush_decal_mask_radius : context_raw.brush_radius;
  382. render_path_paint_draw_cursor(mx, my, context_raw.brush_nodes_radius * radius / 3.4);
  383. }
  384. function render_path_paint_draw_cursor(mx: f32, my: f32, radius: f32, tint_r: f32 = 1.0, tint_g: f32 = 1.0, tint_b: f32 = 1.0) {
  385. let plane: mesh_object_t = scene_get_child(".Plane").ext;
  386. let geom: mesh_data_t = plane.data;
  387. render_path_set_target("");
  388. gpu_set_pipeline(pipes_cursor);
  389. let rt: render_target_t = map_get(render_path_render_targets, "main");
  390. let main: gpu_texture_t = rt._image;
  391. gpu_set_texture(pipes_cursor_gbufferd, main);
  392. gpu_set_float2(pipes_cursor_mouse, mx, my);
  393. gpu_set_float2(pipes_cursor_tex_step, 1 / main.width, 1 / main.height);
  394. gpu_set_float(pipes_cursor_radius, radius);
  395. let right: vec4_t = vec4_norm(camera_object_right_world(scene_camera));
  396. gpu_set_float3(pipes_cursor_camera_right, right.x, right.y, right.z);
  397. gpu_set_float3(pipes_cursor_tint, tint_r, tint_g, tint_b);
  398. gpu_set_matrix4(pipes_cursor_vp, scene_camera.vp);
  399. let inv_vp: mat4_t = mat4_inv(scene_camera.vp);
  400. gpu_set_matrix4(pipes_cursor_inv_vp, inv_vp);
  401. gpu_set_vertex_buffer(geom._.vertex_buffer);
  402. gpu_set_index_buffer(geom._.index_buffer);
  403. gpu_draw();
  404. render_path_end();
  405. }
  406. function render_path_paint_commands_symmetry() {
  407. if (context_raw.sym_x || context_raw.sym_y || context_raw.sym_z) {
  408. context_raw.ddirty = 2;
  409. let t: transform_t = context_raw.paint_object.base.transform;
  410. let sx: f32 = t.scale.x;
  411. let sy: f32 = t.scale.y;
  412. let sz: f32 = t.scale.z;
  413. if (context_raw.sym_x) {
  414. t.scale = vec4_create(-sx, sy, sz);
  415. transform_build_matrix(t);
  416. render_path_paint_commands_paint(false);
  417. }
  418. if (context_raw.sym_y) {
  419. t.scale = vec4_create(sx, -sy, sz);
  420. transform_build_matrix(t);
  421. render_path_paint_commands_paint(false);
  422. }
  423. if (context_raw.sym_z) {
  424. t.scale = vec4_create(sx, sy, -sz);
  425. transform_build_matrix(t);
  426. render_path_paint_commands_paint(false);
  427. }
  428. if (context_raw.sym_x && context_raw.sym_y) {
  429. t.scale = vec4_create(-sx, -sy, sz);
  430. transform_build_matrix(t);
  431. render_path_paint_commands_paint(false);
  432. }
  433. if (context_raw.sym_x && context_raw.sym_z) {
  434. t.scale = vec4_create(-sx, sy, -sz);
  435. transform_build_matrix(t);
  436. render_path_paint_commands_paint(false);
  437. }
  438. if (context_raw.sym_y && context_raw.sym_z) {
  439. t.scale = vec4_create(sx, -sy, -sz);
  440. transform_build_matrix(t);
  441. render_path_paint_commands_paint(false);
  442. }
  443. if (context_raw.sym_x && context_raw.sym_y && context_raw.sym_z) {
  444. t.scale = vec4_create(-sx, -sy, -sz);
  445. transform_build_matrix(t);
  446. render_path_paint_commands_paint(false);
  447. }
  448. t.scale = vec4_create(sx, sy, sz);
  449. transform_build_matrix(t);
  450. }
  451. }
  452. function render_path_paint_paint_enabled(): bool {
  453. let fill_layer: bool = context_raw.layer.fill_layer != null && context_raw.tool != tool_type_t.PICKER && context_raw.tool != tool_type_t.MATERIAL &&
  454. context_raw.tool != tool_type_t.COLORID;
  455. let group_layer: bool = slot_layer_is_group(context_raw.layer);
  456. let gizmo: bool = context_raw.tool == tool_type_t.GIZMO;
  457. return !fill_layer && !group_layer && !context_raw.foreground_event && !gizmo;
  458. }
  459. function render_path_paint_live_brush_dirty() {
  460. let mx: f32 = render_path_paint_last_x;
  461. let my: f32 = render_path_paint_last_y;
  462. render_path_paint_last_x = mouse_view_x();
  463. render_path_paint_last_y = mouse_view_y();
  464. if (config_raw.brush_live && context_raw.pdirty <= 0) {
  465. let moved: bool = (mx != render_path_paint_last_x || my != render_path_paint_last_y) && (context_in_3d_view() || context_in_2d_view());
  466. if (moved || context_raw.brush_locked) {
  467. context_raw.rdirty = 2;
  468. }
  469. }
  470. }
  471. function render_path_paint_begin() {
  472. if (context_raw.layer.texpaint_sculpt != null) {
  473. render_path_sculpt_begin();
  474. return;
  475. }
  476. if (!render_path_paint_dilated) {
  477. render_path_paint_dilate(false, true);
  478. render_path_paint_dilated = true;
  479. }
  480. if (!render_path_paint_paint_enabled()) {
  481. return;
  482. }
  483. render_path_paint_push_undo_last = history_push_undo;
  484. if (history_push_undo && history_undo_layers != null) {
  485. history_paint();
  486. }
  487. if (context_raw.paint2d) {
  488. render_path_paint_set_plane_mesh();
  489. }
  490. if (render_path_paint_live_layer_drawn > 0) {
  491. render_path_paint_live_layer_drawn--;
  492. }
  493. if (config_raw.brush_live && context_raw.pdirty <= 0 && context_raw.ddirty <= 0 && context_raw.brush_time == 0) {
  494. // Depth is unchanged, draw before gbuffer gets updated
  495. render_path_paint_commands_live_brush();
  496. }
  497. }
  498. function render_path_paint_end() {
  499. context_raw.ddirty--;
  500. context_raw.rdirty--;
  501. if (!render_path_paint_paint_enabled()) {
  502. return;
  503. }
  504. context_raw.pdirty--;
  505. }
  506. let _render_path_paint_bake_type: bake_type_t;
  507. function _render_path_paint_final() {
  508. context_raw.bake_type = _render_path_paint_bake_type;
  509. make_material_parse_paint_material();
  510. context_raw.pdirty = 1;
  511. render_path_paint_commands_paint();
  512. context_raw.pdirty = 0;
  513. render_path_paint_baking = false;
  514. render_path_paint_update_bake_layer(texture_bits_t.BITS8);
  515. }
  516. function _render_path_paint_deriv() {
  517. context_raw.bake_type = bake_type_t.HEIGHT;
  518. make_material_parse_paint_material();
  519. context_raw.pdirty = 1;
  520. render_path_paint_commands_paint();
  521. context_raw.pdirty = 0;
  522. if (render_path_paint_push_undo_last) {
  523. history_paint();
  524. }
  525. sys_notify_on_next_frame(_render_path_paint_final);
  526. }
  527. function render_path_paint_is_rt_bake(): bool {
  528. return (context_raw.bake_type == bake_type_t.AO || context_raw.bake_type == bake_type_t.LIGHTMAP || context_raw.bake_type == bake_type_t.BENT_NORMAL ||
  529. context_raw.bake_type == bake_type_t.THICKNESS);
  530. }
  531. function render_path_paint_update_bake_layer(bits: texture_bits_t) {
  532. if (base_bits_handle.i != bits) {
  533. base_bits_handle.i = bits;
  534. layers_set_bits();
  535. }
  536. }
  537. function render_path_paint_draw() {
  538. if (!render_path_paint_paint_enabled()) {
  539. return;
  540. }
  541. if (config_raw.brush_live && context_raw.pdirty <= 0 && context_raw.ddirty > 0 && context_raw.brush_time == 0) {
  542. // gbuffer has been updated now but brush will lag 1 frame
  543. render_path_paint_commands_live_brush();
  544. }
  545. if (history_undo_layers != null) {
  546. render_path_paint_commands_symmetry();
  547. if (context_raw.pdirty > 0) {
  548. render_path_paint_dilated = false;
  549. }
  550. if (context_raw.tool == tool_type_t.BAKE) {
  551. if (context_raw.bake_type == bake_type_t.NORMAL || context_raw.bake_type == bake_type_t.HEIGHT || context_raw.bake_type == bake_type_t.DERIVATIVE) {
  552. if (!render_path_paint_baking && context_raw.pdirty > 0) {
  553. // Use RGBA128 texture format for high poly to low poly baking to prevent artifacts
  554. render_path_paint_update_bake_layer(texture_bits_t.BITS32);
  555. render_path_paint_baking = true;
  556. _render_path_paint_bake_type = context_raw.bake_type;
  557. context_raw.bake_type =
  558. context_raw.bake_type == bake_type_t.NORMAL ? bake_type_t.NORMAL_OBJECT : bake_type_t.POSITION; // Bake high poly data
  559. make_material_parse_paint_material();
  560. let _paint_object: mesh_object_t = context_raw.paint_object;
  561. let high_poly: mesh_object_t = project_paint_objects[context_raw.bake_high_poly];
  562. let _visible: bool = high_poly.base.visible;
  563. high_poly.base.visible = true;
  564. context_select_paint_object(high_poly);
  565. render_path_paint_commands_paint();
  566. high_poly.base.visible = _visible;
  567. if (render_path_paint_push_undo_last) {
  568. history_paint();
  569. }
  570. context_select_paint_object(_paint_object);
  571. if (context_raw.bake_type == bake_type_t.DERIVATIVE) {
  572. sys_notify_on_next_frame(_render_path_paint_deriv);
  573. }
  574. else {
  575. sys_notify_on_next_frame(_render_path_paint_final);
  576. }
  577. }
  578. }
  579. else if (context_raw.bake_type == bake_type_t.OBJECTID) {
  580. let _layer_filter: i32 = context_raw.layer_filter;
  581. let _paint_object: mesh_object_t = context_raw.paint_object;
  582. let is_merged: bool = context_raw.merged_object != null;
  583. let _visible: bool = is_merged && context_raw.merged_object.base.visible;
  584. context_raw.layer_filter = 1;
  585. if (is_merged) {
  586. context_raw.merged_object.base.visible = false;
  587. }
  588. for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
  589. let p: mesh_object_t = project_paint_objects[i];
  590. context_select_paint_object(p);
  591. render_path_paint_commands_paint();
  592. }
  593. context_raw.layer_filter = _layer_filter;
  594. context_select_paint_object(_paint_object);
  595. if (is_merged)
  596. context_raw.merged_object.base.visible = _visible;
  597. }
  598. else if (render_path_paint_is_rt_bake()) {
  599. let dirty: bool = render_path_raytrace_bake_commands(make_material_parse_paint_material);
  600. if (dirty)
  601. ui_header_handle.redraws = 2;
  602. render_path_paint_dilate(true, false);
  603. }
  604. else {
  605. render_path_paint_commands_paint();
  606. }
  607. }
  608. else { // Paint
  609. render_path_paint_commands_paint();
  610. }
  611. }
  612. if (context_raw.brush_blend_dirty) {
  613. context_raw.brush_blend_dirty = false;
  614. render_path_set_target("texpaint_blend0", null, null, gpu_clear_t.COLOR, 0x00000000);
  615. render_path_set_target("texpaint_blend1", null, null, gpu_clear_t.COLOR, 0x00000000);
  616. render_path_end();
  617. }
  618. if (context_raw.paint2d) {
  619. render_path_paint_restore_plane_mesh();
  620. }
  621. }
  622. function render_path_paint_set_plane_mesh() {
  623. context_raw.paint2d_view = true;
  624. render_path_paint_painto = context_raw.paint_object;
  625. render_path_paint_visibles = [];
  626. for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
  627. let p: mesh_object_t = project_paint_objects[i];
  628. array_push(render_path_paint_visibles, p.base.visible);
  629. p.base.visible = false;
  630. }
  631. if (context_raw.merged_object != null) {
  632. render_path_paint_merged_object_visible = context_raw.merged_object.base.visible;
  633. context_raw.merged_object.base.visible = false;
  634. }
  635. let cam: camera_object_t = scene_camera;
  636. context_raw.saved_camera = mat4_clone(cam.base.transform.local);
  637. render_path_paint_saved_fov = cam.data.fov;
  638. viewport_update_camera_type(camera_type_t.PERSPECTIVE);
  639. let m: mat4_t = mat4_identity();
  640. m = mat4_translate(m, 0, 0, 0.5);
  641. transform_set_matrix(cam.base.transform, m);
  642. cam.data.fov = 0.69;
  643. camera_object_build_proj(cam);
  644. camera_object_build_mat(cam);
  645. let tw: f32 = 0.95 * ui_view2d_pan_scale;
  646. let tx: f32 = ui_view2d_pan_x / ui_view2d_ww;
  647. let ty: f32 = ui_view2d_pan_y / sys_h();
  648. m = mat4_identity();
  649. m = mat4_scale(m, vec4_create(tw, tw, 1));
  650. m = mat4_set_loc(m, vec4_create(tx, ty, 0));
  651. let m2: mat4_t = mat4_identity();
  652. m2 = mat4_inv(scene_camera.vp);
  653. m = mat4_mult_mat(m, m2);
  654. let tiled: bool = ui_view2d_tiled_show;
  655. if (tiled && scene_get_child(".PlaneTiled") == null) {
  656. // 3x3 planes
  657. let posa: i16[] = [
  658. 32767, 0, -32767, 0, 10922, 0, -10922, 0, 10922, 0, -32767, 0, 10922, 0, -10922, 0, -10922, 0, 10922, 0, -10922, 0, -10922, 0,
  659. -10922, 0, 10922, 0, -32767, 0, 32767, 0, -32767, 0, 10922, 0, 10922, 0, 10922, 0, -10922, 0, 32767, 0, -10922, 0, 10922, 0,
  660. 32767, 0, 10922, 0, 10922, 0, 32767, 0, 10922, 0, 10922, 0, -10922, 0, -10922, 0, -32767, 0, 10922, 0, -32767, 0, -10922, 0,
  661. 32767, 0, -10922, 0, 10922, 0, 10922, 0, 10922, 0, -10922, 0, -10922, 0, -32767, 0, -32767, 0, -10922, 0, -32767, 0, -32767, 0,
  662. 10922, 0, -32767, 0, -10922, 0, -10922, 0, -10922, 0, -32767, 0, 32767, 0, -32767, 0, 32767, 0, -10922, 0, 10922, 0, -10922, 0,
  663. 10922, 0, -10922, 0, 10922, 0, 10922, 0, -10922, 0, 10922, 0, -10922, 0, 10922, 0, -10922, 0, 32767, 0, -32767, 0, 32767, 0,
  664. 10922, 0, 10922, 0, 10922, 0, 32767, 0, -10922, 0, 32767, 0, 32767, 0, 10922, 0, 32767, 0, 32767, 0, 10922, 0, 32767, 0,
  665. -10922, 0, -10922, 0, -10922, 0, 10922, 0, -32767, 0, 10922, 0, 32767, 0, -10922, 0, 32767, 0, 10922, 0, 10922, 0, 10922, 0,
  666. -10922, 0, -32767, 0, -10922, 0, -10922, 0, -32767, 0, -10922, 0, 10922, 0, -32767, 0, 10922, 0, -10922, 0, -10922, 0, -10922, 0
  667. ];
  668. let nora: i16[] = [
  669. 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767,
  670. 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767,
  671. 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767,
  672. 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767,
  673. 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767, 0, -32767
  674. ];
  675. let texa: i16[] = [
  676. 32767, 32767, 0, 0, 0, 32767, 32767, 32767, 0, 0, 0, 32767, 32767, 32767, 0, 0, 0, 32767, 32767, 32767, 0, 0, 0, 32767,
  677. 32767, 32767, 0, 0, 0, 32767, 32767, 32767, 0, 0, 0, 32767, 32767, 32767, 0, 0, 0, 32767, 32767, 32767, 0, 0, 0, 32767,
  678. 32767, 32767, 0, 0, 0, 32767, 32767, 32767, 32767, 0, 0, 0, 32767, 32767, 32767, 0, 0, 0, 32767, 32767, 32767, 0, 0, 0,
  679. 32767, 32767, 32767, 0, 0, 0, 32767, 32767, 32767, 0, 0, 0, 32767, 32767, 32767, 0, 0, 0, 32767, 32767, 32767, 0, 0, 0,
  680. 32767, 32767, 32767, 0, 0, 0, 32767, 32767, 32767, 0, 0, 0
  681. ];
  682. let inda: u32[] = [
  683. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
  684. 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53
  685. ];
  686. let raw: mesh_data_t = {
  687. name : ".PlaneTiled",
  688. vertex_arrays : [
  689. {attrib : "pos", values : i16_array_create_from_array(posa), data : "short4norm"},
  690. {attrib : "nor", values : i16_array_create_from_array(nora), data : "short2norm"},
  691. {attrib : "tex", values : i16_array_create_from_array(texa), data : "short2norm"}
  692. ],
  693. index_array : u32_array_create_from_array(inda),
  694. scale_pos : 1.5,
  695. scale_tex : 1.0
  696. };
  697. let md: mesh_data_t = mesh_data_create(raw);
  698. let mo: mesh_object_t = scene_get_child(".Plane").ext;
  699. let material: material_data_t = mo.material;
  700. let o: mesh_object_t = scene_add_mesh_object(md, material);
  701. o.base.name = ".PlaneTiled";
  702. }
  703. render_path_paint_planeo = scene_get_child(tiled ? ".PlaneTiled" : ".Plane").ext;
  704. render_path_paint_planeo.base.visible = true;
  705. context_raw.paint_object = render_path_paint_planeo;
  706. let v: vec4_t = vec4_create();
  707. v = vec4_create(m.m00, m.m01, m.m02);
  708. let sx: f32 = vec4_len(v);
  709. render_path_paint_planeo.base.transform.rot = quat_from_euler(-math_pi() / 2, 0, 0);
  710. render_path_paint_planeo.base.transform.scale = vec4_create(sx, 1.0, sx);
  711. render_path_paint_planeo.base.transform.scale.z *= config_get_texture_res_y() / config_get_texture_res_x();
  712. render_path_paint_planeo.base.transform.loc = vec4_create(m.m30, -m.m31, 0.0);
  713. transform_build_matrix(render_path_paint_planeo.base.transform);
  714. }
  715. function render_path_paint_restore_plane_mesh() {
  716. context_raw.paint2d_view = false;
  717. render_path_paint_planeo.base.visible = false;
  718. render_path_paint_planeo.base.transform.loc = vec4_create(0.0, 0.0, 0.0);
  719. for (let i: i32 = 0; i < project_paint_objects.length; ++i) {
  720. project_paint_objects[i].base.visible = render_path_paint_visibles[i];
  721. }
  722. if (context_raw.merged_object != null) {
  723. context_raw.merged_object.base.visible = render_path_paint_merged_object_visible;
  724. }
  725. context_raw.paint_object = render_path_paint_painto;
  726. transform_set_matrix(scene_camera.base.transform, context_raw.saved_camera);
  727. scene_camera.data.fov = render_path_paint_saved_fov;
  728. viewport_update_camera_type(context_raw.camera_type);
  729. camera_object_build_proj(scene_camera);
  730. camera_object_build_mat(scene_camera);
  731. render_path_base_draw_gbuffer();
  732. }
  733. function render_path_paint_bind_layers() {
  734. let is_live: bool = config_raw.brush_live && render_path_paint_live_layer_drawn > 0;
  735. let is_material_tool: bool = context_raw.tool == tool_type_t.MATERIAL;
  736. if (is_live || is_material_tool) {
  737. render_path_paint_use_live_layer(true);
  738. }
  739. for (let i: i32 = 0; i < project_layers.length; ++i) {
  740. let l: slot_layer_t = project_layers[i];
  741. render_path_bind_target("texpaint" + l.id, "texpaint" + l.id);
  742. if (slot_layer_is_layer(l)) {
  743. render_path_bind_target("texpaint_nor" + l.id, "texpaint_nor" + l.id);
  744. render_path_bind_target("texpaint_pack" + l.id, "texpaint_pack" + l.id);
  745. }
  746. if (l.texpaint_sculpt != null) {
  747. render_path_bind_target("texpaint_sculpt" + l.id, "texpaint_sculpt" + l.id);
  748. }
  749. }
  750. }
  751. function render_path_paint_unbind_layers() {
  752. let is_live: bool = config_raw.brush_live && render_path_paint_live_layer_drawn > 0;
  753. let is_material_tool: bool = context_raw.tool == tool_type_t.MATERIAL;
  754. if (is_live || is_material_tool) {
  755. render_path_paint_use_live_layer(false);
  756. }
  757. }
  758. function render_path_paint_dilate(base: bool, nor_pack: bool) {
  759. if (config_raw.dilate_radius > 0 && !context_raw.paint2d) {
  760. util_uv_cache_dilate_map();
  761. layers_make_temp_img();
  762. let tid: i32 = context_raw.layer.id;
  763. let format: string = base_bits_handle.i == texture_bits_t.BITS8 ? "RGBA32" : base_bits_handle.i == texture_bits_t.BITS16 ? "RGBA64" : "RGBA128";
  764. let copy_pass: string = format == "RGBA64" ? "copyRGBA64_pass" : format == "RGBA128" ? "copyRGBA128_pass" : "copy_pass";
  765. let dilate_pass: string = format == "RGBA64" ? "dilateRGBA64_pass" : format == "RGBA128" ? "dilateRGBA128_pass" : "dilate_pass";
  766. if (base) {
  767. let texpaint: string = "texpaint";
  768. render_path_set_target("temptex0");
  769. render_path_bind_target(texpaint + tid, "tex");
  770. render_path_draw_shader("Scene/copy_pass/" + copy_pass);
  771. render_path_set_target(texpaint + tid);
  772. render_path_bind_target("temptex0", "tex");
  773. render_path_draw_shader("Scene/dilate_pass/" + dilate_pass);
  774. }
  775. if (nor_pack && !slot_layer_is_mask(context_raw.layer)) {
  776. render_path_set_target("temptex0");
  777. render_path_bind_target("texpaint_nor" + tid, "tex");
  778. render_path_draw_shader("Scene/copy_pass/" + copy_pass);
  779. render_path_set_target("texpaint_nor" + tid);
  780. render_path_bind_target("temptex0", "tex");
  781. render_path_draw_shader("Scene/dilate_pass/" + dilate_pass);
  782. render_path_set_target("temptex0");
  783. render_path_bind_target("texpaint_pack" + tid, "tex");
  784. render_path_draw_shader("Scene/copy_pass/" + copy_pass);
  785. render_path_set_target("texpaint_pack" + tid);
  786. render_path_bind_target("temptex0", "tex");
  787. render_path_draw_shader("Scene/dilate_pass/" + dilate_pass);
  788. }
  789. }
  790. }