render_path_base.ts 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. let render_path_base_taa_frame: i32 = 0;
  2. let render_path_base_super_sample: f32 = 1.0;
  3. let render_path_base_last_x: f32 = -1.0;
  4. let render_path_base_last_y: f32 = -1.0;
  5. let render_path_base_bloom_mipmaps: render_target_t[];
  6. let render_path_base_bloom_current_mip: i32 = 0;
  7. let render_path_base_bloom_sample_scale: f32;
  8. ///if arm_voxels
  9. let render_path_base_voxels_res: i32 = 256;
  10. let render_path_base_voxels_created: bool = false;
  11. ///end
  12. function render_path_base_init() {
  13. pipes_init();
  14. const_data_create_screen_aligned_data();
  15. render_path_base_super_sample = config_raw.rp_supersample;
  16. }
  17. ///if arm_voxels
  18. function render_path_base_init_voxels(target_name: string = "voxels") {
  19. if (config_raw.rp_gi != true || render_path_base_voxels_created) {
  20. return;
  21. }
  22. render_path_base_voxels_created = true;
  23. {
  24. let t: render_target_t = render_target_create();
  25. t.name = target_name;
  26. t.format = "R8";
  27. t.width = render_path_base_voxels_res;
  28. t.height = render_path_base_voxels_res;
  29. t.depth = render_path_base_voxels_res;
  30. t.is_image = true;
  31. t.mipmaps = true;
  32. render_path_create_render_target(t);
  33. }
  34. }
  35. ///end
  36. function render_path_base_apply_config() {
  37. if (render_path_base_super_sample != config_raw.rp_supersample) {
  38. render_path_base_super_sample = config_raw.rp_supersample;
  39. let keys: string[] = map_keys(render_path_render_targets);
  40. for (let i: i32 = 0; i < keys.length; ++i) {
  41. let rt: render_target_t = map_get(render_path_render_targets, keys[i]);
  42. if (rt.width == 0) {
  43. rt.scale = render_path_base_super_sample;
  44. }
  45. }
  46. render_path_resize();
  47. }
  48. ///if arm_voxels
  49. if (!render_path_base_voxels_created) {
  50. render_path_base_init_voxels();
  51. }
  52. ///end
  53. }
  54. function render_path_base_get_super_sampling(): f32 {
  55. return render_path_base_super_sample;
  56. }
  57. function render_path_base_draw_compass() {
  58. compass_render();
  59. }
  60. function render_path_base_begin() {
  61. // Begin split
  62. if (context_raw.split_view && !context_raw.paint2d_view) {
  63. if (context_raw.view_index_last == -1 && context_raw.view_index == -1) {
  64. // Begin split, draw right viewport first
  65. context_raw.view_index = 1;
  66. }
  67. else {
  68. // Set current viewport
  69. context_raw.view_index = mouse_view_x() > base_w() / 2 ? 1 : 0;
  70. }
  71. let cam: camera_object_t = scene_camera;
  72. if (context_raw.view_index_last > -1) {
  73. // Save current viewport camera
  74. camera_views[context_raw.view_index_last].v = mat4_clone(cam.base.transform.local);
  75. }
  76. let decal: bool = context_is_decal();
  77. if (context_raw.view_index_last != context_raw.view_index || decal || !config_raw.brush_3d) {
  78. // Redraw on current viewport change
  79. context_raw.ddirty = 1;
  80. }
  81. transform_set_matrix(cam.base.transform, camera_views[context_raw.view_index].v);
  82. camera_object_build_mat(cam);
  83. camera_object_build_proj(cam);
  84. }
  85. // Match projection matrix jitter
  86. let skip_taa: bool =
  87. context_raw.split_view ||
  88. context_raw.viewport_mode == viewport_mode_t.PATH_TRACE ||
  89. ((context_raw.tool == workspace_tool_t.CLONE ||
  90. context_raw.tool == workspace_tool_t.BLUR ||
  91. context_raw.tool == workspace_tool_t.SMUDGE) && context_raw.pdirty > 0);
  92. scene_camera.frame = skip_taa ? 0 : render_path_base_taa_frame;
  93. camera_object_proj_jitter(scene_camera);
  94. camera_object_build_mat(scene_camera);
  95. }
  96. function render_path_base_end() {
  97. // End split
  98. context_raw.view_index_last = context_raw.view_index;
  99. context_raw.view_index = -1;
  100. if (context_raw.foreground_event && !mouse_down()) {
  101. context_raw.foreground_event = false;
  102. context_raw.pdirty = 0;
  103. }
  104. render_path_base_taa_frame++;
  105. }
  106. function render_path_base_ssaa4(): bool {
  107. return config_raw.rp_supersample == 4;
  108. }
  109. function render_path_base_is_cached(): bool {
  110. if (sys_width() == 0 || sys_height() == 0) {
  111. return true;
  112. }
  113. let mx: f32 = render_path_base_last_x;
  114. let my: f32 = render_path_base_last_y;
  115. render_path_base_last_x = mouse_view_x();
  116. render_path_base_last_y = mouse_view_y();
  117. if (context_raw.ddirty <= 0 && context_raw.rdirty <= 0 && context_raw.pdirty <= 0) {
  118. if (mx != render_path_base_last_x || my != render_path_base_last_y || mouse_locked) {
  119. context_raw.ddirty = 0;
  120. }
  121. ///if (arm_metal || arm_android)
  122. if (context_raw.ddirty > -6) {
  123. ///else
  124. if (context_raw.ddirty > -2) {
  125. ///end
  126. render_path_set_target("");
  127. render_path_bind_target("taa", "tex");
  128. render_path_base_ssaa4() ?
  129. render_path_draw_shader("shader_datas/supersample_resolve/supersample_resolve") :
  130. render_path_draw_shader("shader_datas/copy_pass/copy_pass");
  131. render_path_paint_commands_cursor();
  132. if (context_raw.ddirty <= 0) {
  133. context_raw.ddirty--;
  134. }
  135. }
  136. render_path_base_end();
  137. return true;
  138. }
  139. return false;
  140. }
  141. function render_path_base_commands(draw_commands: ()=>void) {
  142. if (render_path_base_is_cached()) {
  143. return;
  144. }
  145. render_path_base_begin();
  146. render_path_paint_begin();
  147. render_path_base_draw_split(draw_commands);
  148. render_path_base_draw_gbuffer();
  149. render_path_paint_draw();
  150. ///if (arm_direct3d12 || arm_vulkan || arm_metal)
  151. if (context_raw.viewport_mode == viewport_mode_t.PATH_TRACE) {
  152. let use_live_layer: bool = context_raw.tool == workspace_tool_t.MATERIAL;
  153. render_path_raytrace_draw(use_live_layer);
  154. context_raw.foreground_event = false; // render_path_paint_end();
  155. render_path_base_end();
  156. return;
  157. }
  158. ///end
  159. draw_commands();
  160. render_path_paint_end();
  161. render_path_base_end();
  162. }
  163. function render_path_base_draw_bloom(tex: string) {
  164. if (config_raw.rp_bloom == false) {
  165. return;
  166. }
  167. if (render_path_base_bloom_mipmaps == null) {
  168. render_path_base_bloom_mipmaps = [];
  169. let prev_scale: f32 = 1.0;
  170. for (let i: i32 = 0; i < 10; ++i) {
  171. let t: render_target_t = render_target_create();
  172. t.name = "bloom_mip_" + i;
  173. t.width = 0;
  174. t.height = 0;
  175. prev_scale *= 0.5;
  176. t.scale = prev_scale;
  177. t.format = "RGBA64";
  178. array_push(render_path_base_bloom_mipmaps, render_path_create_render_target(t));
  179. }
  180. render_path_load_shader("shader_datas/bloom_pass/bloom_downsample_pass");
  181. render_path_load_shader("shader_datas/bloom_pass/bloom_upsample_pass");
  182. }
  183. let bloom_radius: f32 = 6.5;
  184. let min_dim: f32 = math_min(render_path_current_w, render_path_current_h);
  185. let log_min_dim: f32 = math_max(1.0, math_log2(min_dim) + (bloom_radius - 8.0));
  186. let num_mips: i32 = math_floor(log_min_dim);
  187. render_path_base_bloom_sample_scale = 0.5 + log_min_dim - num_mips;
  188. for (let i: i32 = 0; i < num_mips; ++i) {
  189. render_path_base_bloom_current_mip = i;
  190. render_path_set_target(render_path_base_bloom_mipmaps[i].name);
  191. render_path_clear_target(0x00000000);
  192. render_path_bind_target(i == 0 ? tex : render_path_base_bloom_mipmaps[i - 1].name, "tex");
  193. render_path_draw_shader("shader_datas/bloom_pass/bloom_downsample_pass");
  194. }
  195. for (let i: i32 = 0; i < num_mips; ++i) {
  196. let mip_level: i32 = num_mips - 1 - i;
  197. render_path_base_bloom_current_mip = mip_level;
  198. render_path_set_target(mip_level == 0 ? tex : render_path_base_bloom_mipmaps[mip_level - 1].name);
  199. render_path_bind_target(render_path_base_bloom_mipmaps[mip_level].name, "tex");
  200. render_path_draw_shader("shader_datas/bloom_pass/bloom_upsample_pass");
  201. }
  202. }
  203. function render_path_base_draw_split(draw_commands: ()=>void) {
  204. if (context_raw.split_view && !context_raw.paint2d_view) {
  205. context_raw.ddirty = 2;
  206. let cam: camera_object_t = scene_camera;
  207. context_raw.view_index = context_raw.view_index == 0 ? 1 : 0;
  208. transform_set_matrix(cam.base.transform, camera_views[context_raw.view_index].v);
  209. camera_object_build_mat(cam);
  210. camera_object_build_proj(cam);
  211. render_path_base_draw_gbuffer();
  212. ///if (arm_direct3d12 || arm_vulkan || arm_metal)
  213. let use_live_layer: bool = context_raw.tool == workspace_tool_t.MATERIAL;
  214. context_raw.viewport_mode == viewport_mode_t.PATH_TRACE ? render_path_raytrace_draw(use_live_layer) : draw_commands();
  215. ///else
  216. draw_commands();
  217. ///end
  218. context_raw.view_index = context_raw.view_index == 0 ? 1 : 0;
  219. transform_set_matrix(cam.base.transform, camera_views[context_raw.view_index].v);
  220. camera_object_build_mat(cam);
  221. camera_object_build_proj(cam);
  222. }
  223. }
  224. ///if arm_voxels
  225. function render_path_base_draw_voxels() {
  226. if (config_raw.rp_gi != false) {
  227. let voxelize: bool = context_raw.ddirty > 0 && render_path_base_taa_frame > 0;
  228. if (voxelize) {
  229. render_path_clear_image("voxels", 0x00000000);
  230. render_path_set_target("");
  231. render_path_set_viewport(render_path_base_voxels_res, render_path_base_voxels_res);
  232. render_path_bind_target("voxels", "voxels");
  233. if (make_material_height_used) {
  234. let tid: i32 = 0; // layers[0].id;
  235. render_path_bind_target("texpaint_pack" + tid, "texpaint_pack");
  236. }
  237. render_path_draw_meshes("voxel");
  238. render_path_gen_mipmaps("voxels");
  239. }
  240. }
  241. }
  242. ///end
  243. function render_path_base_init_ssao() {
  244. {
  245. let t: render_target_t = render_target_create();
  246. t.name = "singlea";
  247. t.width = 0;
  248. t.height = 0;
  249. t.format = "R8";
  250. t.scale = render_path_base_get_super_sampling();
  251. render_path_create_render_target(t);
  252. }
  253. {
  254. let t: render_target_t = render_target_create();
  255. t.name = "singleb";
  256. t.width = 0;
  257. t.height = 0;
  258. t.format = "R8";
  259. t.scale = render_path_base_get_super_sampling();
  260. render_path_create_render_target(t);
  261. }
  262. render_path_load_shader("shader_datas/ssao_pass/ssao_pass");
  263. render_path_load_shader("shader_datas/ssao_blur_pass/ssao_blur_pass_x");
  264. render_path_load_shader("shader_datas/ssao_blur_pass/ssao_blur_pass_y");
  265. }
  266. function render_path_base_draw_ssao() {
  267. let ssao: bool = config_raw.rp_ssao != false && context_raw.camera_type == camera_type_t.PERSPECTIVE;
  268. if (ssao && context_raw.ddirty > 0 && render_path_base_taa_frame > 0) {
  269. if (map_get(render_path_render_targets, "singlea") == null) {
  270. render_path_base_init_ssao();
  271. }
  272. render_path_set_target("singlea");
  273. render_path_bind_target("_main", "gbufferD");
  274. render_path_bind_target("gbuffer0", "gbuffer0");
  275. render_path_draw_shader("shader_datas/ssao_pass/ssao_pass");
  276. render_path_set_target("singleb");
  277. render_path_bind_target("singlea", "tex");
  278. render_path_bind_target("gbuffer0", "gbuffer0");
  279. render_path_draw_shader("shader_datas/ssao_blur_pass/ssao_blur_pass_x");
  280. render_path_set_target("singlea");
  281. render_path_bind_target("singleb", "tex");
  282. render_path_bind_target("gbuffer0", "gbuffer0");
  283. render_path_draw_shader("shader_datas/ssao_blur_pass/ssao_blur_pass_y");
  284. }
  285. }
  286. function render_path_base_draw_deferred_light() {
  287. render_path_set_target("tex");
  288. render_path_bind_target("_main", "gbufferD");
  289. render_path_bind_target("gbuffer0", "gbuffer0");
  290. render_path_bind_target("gbuffer1", "gbuffer1");
  291. let ssao: bool = config_raw.rp_ssao != false && context_raw.camera_type == camera_type_t.PERSPECTIVE;
  292. if (ssao && render_path_base_taa_frame > 0) {
  293. render_path_bind_target("singlea", "ssaotex");
  294. }
  295. else {
  296. render_path_bind_target("empty_white", "ssaotex");
  297. }
  298. let voxelao_pass: bool = false;
  299. ///if arm_voxels
  300. if (config_raw.rp_gi != false) {
  301. voxelao_pass = true;
  302. render_path_bind_target("voxels", "voxels");
  303. }
  304. ///end
  305. voxelao_pass ?
  306. render_path_draw_shader("shader_datas/deferred_light/deferred_light_voxel") :
  307. render_path_draw_shader("shader_datas/deferred_light/deferred_light");
  308. ///if (arm_direct3d11 || arm_direct3d12 || arm_metal || arm_vulkan)
  309. render_path_set_depth_from("tex", "gbuffer0"); // Bind depth for world pass
  310. ///end
  311. render_path_set_target("tex");
  312. render_path_draw_skydome("shader_datas/world_pass/world_pass");
  313. ///if (arm_direct3d11 || arm_direct3d12 || arm_metal || arm_vulkan)
  314. render_path_set_depth_from("tex", "gbuffer1"); // Unbind depth
  315. ///end
  316. }
  317. // function render_path_base_draw_motion_blur() {
  318. // if (config_raw.rp_motionblur != false) {
  319. // render_path_set_target("buf");
  320. // render_path_bind_target("tex", "tex");
  321. // render_path_bind_target("gbuffer0", "gbuffer0");
  322. // ///if (rp_motionblur == "Camera")
  323. // {
  324. // render_path_bind_target("_main", "gbufferD");
  325. // render_path_draw_shader("shader_datas/motion_blur_pass/motion_blur_pass");
  326. // }
  327. // ///else
  328. // {
  329. // render_path_bind_target("gbuffer2", "sveloc");
  330. // render_path_draw_shader("shader_datas/motion_blur_veloc_pass/motion_blur_veloc_pass");
  331. // }
  332. // ///end
  333. // render_path_set_target("tex");
  334. // render_path_bind_target("buf", "tex");
  335. // render_path_draw_shader("shader_datas/copy_pass/copy_pass");
  336. // }
  337. // }
  338. // function render_path_base_draw_histogram() {
  339. // {
  340. // let t: render_target_t = RenderTarget.create();
  341. // t.name = "histogram";
  342. // t.width = 1;
  343. // t.height = 1;
  344. // t.format = "RGBA64";
  345. // render_path_create_render_target(t);
  346. // render_path_load_shader("shader_datas/histogram_pass/histogram_pass");
  347. // }
  348. // render_path_set_target("histogram");
  349. // render_path_bind_target("taa", "tex");
  350. // render_path_draw_shader("shader_datas/histogram_pass/histogram_pass");
  351. // }
  352. function render_path_base_draw_taa() {
  353. let current: string = render_path_base_taa_frame % 2 == 0 ? "buf2" : "taa2";
  354. let last: string = render_path_base_taa_frame % 2 == 0 ? "taa2" : "buf2";
  355. render_path_set_target(current);
  356. render_path_clear_target(0x00000000);
  357. render_path_bind_target("buf", "color_tex");
  358. render_path_draw_shader("shader_datas/smaa_edge_detect/smaa_edge_detect");
  359. render_path_set_target("taa");
  360. render_path_clear_target(0x00000000);
  361. render_path_bind_target(current, "edges_tex");
  362. render_path_draw_shader("shader_datas/smaa_blend_weight/smaa_blend_weight");
  363. render_path_set_target(current);
  364. render_path_bind_target("buf", "color_tex");
  365. render_path_bind_target("taa", "blend_tex");
  366. render_path_bind_target("gbuffer2", "sveloc");
  367. render_path_draw_shader("shader_datas/smaa_neighborhood_blend/smaa_neighborhood_blend");
  368. let skip_taa: bool = context_raw.split_view;
  369. if (skip_taa) {
  370. render_path_set_target("taa");
  371. render_path_bind_target(current, "tex");
  372. render_path_draw_shader("shader_datas/copy_pass/copy_pass");
  373. }
  374. else {
  375. render_path_set_target("taa");
  376. render_path_bind_target(current, "tex");
  377. render_path_bind_target(last, "tex2");
  378. render_path_bind_target("gbuffer2", "sveloc");
  379. render_path_draw_shader("shader_datas/taa_pass/taa_pass");
  380. }
  381. if (render_path_base_ssaa4()) {
  382. render_path_set_target("");
  383. render_path_bind_target(render_path_base_taa_frame % 2 == 0 ? "taa2" : "taa", "tex");
  384. render_path_draw_shader("shader_datas/supersample_resolve/supersample_resolve");
  385. }
  386. else {
  387. render_path_set_target("");
  388. render_path_bind_target(render_path_base_taa_frame == 0 ? current : "taa", "tex");
  389. render_path_draw_shader("shader_datas/copy_pass/copy_pass");
  390. }
  391. }
  392. function render_path_base_draw_gbuffer() {
  393. render_path_set_target("gbuffer0"); // Only clear gbuffer0
  394. ///if arm_metal
  395. render_path_clear_target(0x00000000, 1.0, clear_flag_t.COLOR | clear_flag_t.DEPTH);
  396. ///else
  397. render_path_clear_target(0, 1.0, clear_flag_t.DEPTH);
  398. ///end
  399. if (make_mesh_layer_pass_count == 1) {
  400. render_path_set_target("gbuffer2");
  401. render_path_clear_target(0xff000000);
  402. }
  403. let additional: string[] = ["gbuffer1", "gbuffer2"];
  404. render_path_set_target("gbuffer0", additional);
  405. render_path_paint_bind_layers();
  406. render_path_draw_meshes("mesh");
  407. render_path_paint_unbind_layers();
  408. if (make_mesh_layer_pass_count > 1) {
  409. render_path_base_make_gbuffer_copy_textures();
  410. for (let i: i32 = 1; i < make_mesh_layer_pass_count; ++i) {
  411. let ping: string = i % 2 == 1 ? "_copy" : "";
  412. let pong: string = i % 2 == 1 ? "" : "_copy";
  413. if (i == make_mesh_layer_pass_count - 1) {
  414. render_path_set_target("gbuffer2" + ping);
  415. render_path_clear_target(0xff000000);
  416. }
  417. let g1ping: string = "gbuffer1" + ping;
  418. let g2ping: string = "gbuffer2" + ping;
  419. let additional: string[] = [g1ping, g2ping];
  420. render_path_set_target("gbuffer0" + ping, additional);
  421. render_path_bind_target("gbuffer0" + pong, "gbuffer0");
  422. render_path_bind_target("gbuffer1" + pong, "gbuffer1");
  423. render_path_bind_target("gbuffer2" + pong, "gbuffer2");
  424. render_path_paint_bind_layers();
  425. render_path_draw_meshes("mesh" + i);
  426. render_path_paint_unbind_layers();
  427. }
  428. if (make_mesh_layer_pass_count % 2 == 0) {
  429. render_path_base_copy_to_gbuffer();
  430. }
  431. }
  432. let hide: bool = operator_shortcut(map_get(config_keymap, "stencil_hide"), shortcut_type_t.DOWN) || keyboard_down("control");
  433. let is_decal: bool = base_is_decal_layer();
  434. if (is_decal && !hide) {
  435. line_draw_color = 0xff000000;
  436. line_draw_strength = 0.005;
  437. line_draw_render(context_raw.layer.decal_mat);
  438. }
  439. }
  440. function render_path_base_make_gbuffer_copy_textures() {
  441. let copy: render_target_t = map_get(render_path_render_targets, "gbuffer0_copy");
  442. let g0: render_target_t = map_get(render_path_render_targets, "gbuffer0");
  443. if (copy == null || copy._image.width != g0._image.width || copy._image.height != g0._image.height) {
  444. {
  445. let t: render_target_t = render_target_create();
  446. t.name = "gbuffer0_copy";
  447. t.width = 0;
  448. t.height = 0;
  449. t.format = "RGBA64";
  450. t.scale = render_path_base_get_super_sampling();
  451. t.depth_buffer = "main";
  452. render_path_create_render_target(t);
  453. }
  454. {
  455. let t: render_target_t = render_target_create();
  456. t.name = "gbuffer1_copy";
  457. t.width = 0;
  458. t.height = 0;
  459. t.format = "RGBA64";
  460. t.scale = render_path_base_get_super_sampling();
  461. render_path_create_render_target(t);
  462. }
  463. {
  464. let t: render_target_t = render_target_create();
  465. t.name = "gbuffer2_copy";
  466. t.width = 0;
  467. t.height = 0;
  468. t.format = "RGBA64";
  469. t.scale = render_path_base_get_super_sampling();
  470. render_path_create_render_target(t);
  471. }
  472. ///if arm_metal
  473. // TODO: Fix depth attach for gbuffer0_copy on metal
  474. // Use resize to re-create buffers from scratch for now
  475. render_path_resize();
  476. ///end
  477. }
  478. }
  479. function render_path_base_copy_to_gbuffer() {
  480. let additional: string[] = ["gbuffer1", "gbuffer2"];
  481. render_path_set_target("gbuffer0", additional);
  482. render_path_bind_target("gbuffer0_copy", "tex0");
  483. render_path_bind_target("gbuffer1_copy", "tex1");
  484. render_path_bind_target("gbuffer2_copy", "tex2");
  485. render_path_draw_shader("shader_datas/copy_mrt3_pass/copy_mrt3RGBA64_pass");
  486. }