render_path_base.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  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. function render_path_base_init() {
  9. pipes_init();
  10. const_data_create_screen_aligned_data();
  11. render_path_base_super_sample = config_raw.rp_supersample;
  12. }
  13. function render_path_base_apply_config() {
  14. if (render_path_base_super_sample != config_raw.rp_supersample) {
  15. render_path_base_super_sample = config_raw.rp_supersample;
  16. let keys: string[] = map_keys(render_path_render_targets);
  17. for (let i: i32 = 0; i < keys.length; ++i) {
  18. let rt: render_target_t = map_get(render_path_render_targets, keys[i]);
  19. if (rt.width == 0) {
  20. rt.scale = render_path_base_super_sample;
  21. }
  22. }
  23. render_path_resize();
  24. }
  25. }
  26. function render_path_base_get_super_sampling(): f32 {
  27. return render_path_base_super_sample;
  28. }
  29. function render_path_base_draw_compass() {
  30. compass_render();
  31. }
  32. function render_path_base_begin() {
  33. // Begin split
  34. if (context_raw.split_view && !context_raw.paint2d_view) {
  35. if (context_raw.view_index_last == -1 && context_raw.view_index == -1) {
  36. // Begin split, draw right viewport first
  37. context_raw.view_index = 1;
  38. }
  39. else {
  40. // Set current viewport
  41. context_raw.view_index = mouse_view_x() > base_w() / 2 ? 1 : 0;
  42. }
  43. let cam: camera_object_t = scene_camera;
  44. if (context_raw.view_index_last > -1) {
  45. // Save current viewport camera
  46. camera_views[context_raw.view_index_last].v = mat4_clone(cam.base.transform.local);
  47. }
  48. let decal: bool = context_is_decal();
  49. if (context_raw.view_index_last != context_raw.view_index || decal || !config_raw.brush_3d) {
  50. // Redraw on current viewport change
  51. context_raw.ddirty = 1;
  52. }
  53. transform_set_matrix(cam.base.transform, camera_views[context_raw.view_index].v);
  54. camera_object_build_mat(cam);
  55. camera_object_build_proj(cam);
  56. }
  57. // Match projection matrix jitter
  58. let skip_taa: bool =
  59. context_raw.split_view ||
  60. context_raw.viewport_mode == viewport_mode_t.PATH_TRACE ||
  61. ((context_raw.tool == tool_type_t.CLONE ||
  62. context_raw.tool == tool_type_t.BLUR ||
  63. context_raw.tool == tool_type_t.SMUDGE) && context_raw.pdirty > 0);
  64. scene_camera.frame = skip_taa ? 0 : render_path_base_taa_frame;
  65. camera_object_proj_jitter(scene_camera);
  66. camera_object_build_mat(scene_camera);
  67. }
  68. function render_path_base_end() {
  69. // End split
  70. context_raw.view_index_last = context_raw.view_index;
  71. context_raw.view_index = -1;
  72. if (context_raw.foreground_event && !mouse_down()) {
  73. context_raw.foreground_event = false;
  74. context_raw.pdirty = 0;
  75. }
  76. render_path_base_taa_frame++;
  77. }
  78. function render_path_base_ssaa4(): bool {
  79. return config_raw.rp_supersample == 4;
  80. }
  81. function render_path_base_is_cached(): bool {
  82. if (iron_window_width() == 0 || iron_window_height() == 0) {
  83. return true;
  84. }
  85. let mx: f32 = render_path_base_last_x;
  86. let my: f32 = render_path_base_last_y;
  87. render_path_base_last_x = mouse_view_x();
  88. render_path_base_last_y = mouse_view_y();
  89. if (context_raw.ddirty <= 0 && context_raw.rdirty <= 0 && context_raw.pdirty <= 0) {
  90. if (mx != render_path_base_last_x || my != render_path_base_last_y || mouse_locked) {
  91. context_raw.ddirty = 0;
  92. }
  93. if (context_raw.ddirty > -6) {
  94. // Accumulate taa frames
  95. context_raw.ddirty--;
  96. return false;
  97. }
  98. if (context_raw.ddirty > -12) {
  99. render_path_set_target("");
  100. render_path_bind_target("last", "tex");
  101. if (render_path_base_ssaa4()) {
  102. render_path_draw_shader("shader_datas/supersample_resolve/supersample_resolveRGBA64");
  103. }
  104. else {
  105. render_path_draw_shader("shader_datas/copy_pass/copy_pass");
  106. }
  107. render_path_paint_commands_cursor();
  108. context_raw.ddirty--;
  109. }
  110. render_path_base_end();
  111. return true;
  112. }
  113. return false;
  114. }
  115. function render_path_base_commands(draw_commands: ()=>void) {
  116. if (render_path_base_is_cached()) {
  117. return;
  118. }
  119. render_path_base_begin();
  120. render_path_paint_begin();
  121. render_path_base_draw_split(draw_commands);
  122. render_path_base_draw_gbuffer();
  123. render_path_paint_draw();
  124. if (context_raw.viewport_mode == viewport_mode_t.PATH_TRACE) {
  125. let use_live_layer: bool = context_raw.tool == tool_type_t.MATERIAL;
  126. render_path_raytrace_draw(use_live_layer);
  127. context_raw.foreground_event = false;
  128. render_path_base_end();
  129. return;
  130. }
  131. draw_commands();
  132. render_path_paint_commands_cursor();
  133. render_path_paint_end();
  134. render_path_base_end();
  135. }
  136. function render_path_base_draw_bloom(source: string, target: string) {
  137. if (config_raw.rp_bloom == false) {
  138. return;
  139. }
  140. if (render_path_base_bloom_mipmaps == null) {
  141. render_path_base_bloom_mipmaps = [];
  142. let prev_scale: f32 = 1.0;
  143. for (let i: i32 = 0; i < 10; ++i) {
  144. let t: render_target_t = render_target_create();
  145. t.name = "bloom_mip_" + i;
  146. t.width = 0;
  147. t.height = 0;
  148. prev_scale *= 0.5;
  149. t.scale = prev_scale;
  150. t.format = "RGBA64";
  151. array_push(render_path_base_bloom_mipmaps, render_path_create_render_target(t));
  152. }
  153. render_path_load_shader("shader_datas/bloom_pass/bloom_downsample_pass");
  154. render_path_load_shader("shader_datas/bloom_pass/bloom_upsample_pass");
  155. }
  156. let bloom_radius: f32 = 6.5;
  157. let min_dim: f32 = math_min(render_path_current_w, render_path_current_h);
  158. let log_min_dim: f32 = math_max(1.0, math_log2(min_dim) + (bloom_radius - 8.0));
  159. let num_mips: i32 = math_floor(log_min_dim);
  160. render_path_base_bloom_sample_scale = 0.5 + log_min_dim - num_mips;
  161. for (let i: i32 = 0; i < num_mips; ++i) {
  162. render_path_base_bloom_current_mip = i;
  163. render_path_set_target(render_path_base_bloom_mipmaps[i].name, null, null, clear_flag_t.COLOR, 0x00000000);
  164. render_path_bind_target(i == 0 ? source : render_path_base_bloom_mipmaps[i - 1].name, "tex");
  165. render_path_draw_shader("shader_datas/bloom_pass/bloom_downsample_pass");
  166. }
  167. for (let i: i32 = 0; i < num_mips; ++i) {
  168. let mip_level: i32 = num_mips - 1 - i;
  169. render_path_base_bloom_current_mip = mip_level;
  170. render_path_set_target(mip_level == 0 ? target : render_path_base_bloom_mipmaps[mip_level - 1].name);
  171. render_path_bind_target(render_path_base_bloom_mipmaps[mip_level].name, "tex");
  172. render_path_draw_shader("shader_datas/bloom_pass/bloom_upsample_pass");
  173. }
  174. }
  175. function render_path_base_draw_split(draw_commands: ()=>void) {
  176. if (context_raw.split_view && !context_raw.paint2d_view) {
  177. context_raw.ddirty = 2;
  178. let cam: camera_object_t = scene_camera;
  179. context_raw.view_index = context_raw.view_index == 0 ? 1 : 0;
  180. transform_set_matrix(cam.base.transform, camera_views[context_raw.view_index].v);
  181. camera_object_build_mat(cam);
  182. camera_object_build_proj(cam);
  183. render_path_base_draw_gbuffer();
  184. let use_live_layer: bool = context_raw.tool == tool_type_t.MATERIAL;
  185. context_raw.viewport_mode == viewport_mode_t.PATH_TRACE ?
  186. render_path_raytrace_draw(use_live_layer) :
  187. draw_commands();
  188. context_raw.view_index = context_raw.view_index == 0 ? 1 : 0;
  189. transform_set_matrix(cam.base.transform, camera_views[context_raw.view_index].v);
  190. camera_object_build_mat(cam);
  191. camera_object_build_proj(cam);
  192. }
  193. }
  194. function render_path_base_init_ssao() {
  195. ///if (arm_macos || arm_ios || arm_android)
  196. let scale: f32 = 0.5;
  197. ///else
  198. let scale: f32 = 1.0;
  199. ///end
  200. {
  201. let t: render_target_t = render_target_create();
  202. t.name = "singlea";
  203. t.width = 0;
  204. t.height = 0;
  205. t.format = "R8";
  206. t.scale = scale * render_path_base_get_super_sampling();
  207. render_path_create_render_target(t);
  208. }
  209. {
  210. let t: render_target_t = render_target_create();
  211. t.name = "singleb";
  212. t.width = 0;
  213. t.height = 0;
  214. t.format = "R8";
  215. t.scale = scale * render_path_base_get_super_sampling();
  216. render_path_create_render_target(t);
  217. }
  218. render_path_load_shader("shader_datas/ssao_pass/ssao_pass");
  219. render_path_load_shader("shader_datas/ssao_blur_pass/ssao_blur_pass_x");
  220. render_path_load_shader("shader_datas/ssao_blur_pass/ssao_blur_pass_y");
  221. }
  222. function render_path_base_draw_ssao() {
  223. let ssao: bool = config_raw.rp_ssao != false && context_raw.camera_type == camera_type_t.PERSPECTIVE;
  224. if (ssao && context_raw.ddirty > 0 && _render_path_frame > 0) {
  225. if (map_get(render_path_render_targets, "singlea") == null) {
  226. render_path_base_init_ssao();
  227. }
  228. render_path_set_target("singlea");
  229. render_path_bind_target("main", "gbufferD");
  230. render_path_bind_target("gbuffer0", "gbuffer0");
  231. render_path_draw_shader("shader_datas/ssao_pass/ssao_pass");
  232. render_path_set_target("singleb");
  233. render_path_bind_target("singlea", "tex");
  234. render_path_bind_target("gbuffer0", "gbuffer0");
  235. render_path_draw_shader("shader_datas/ssao_blur_pass/ssao_blur_pass_x");
  236. render_path_set_target("singlea");
  237. render_path_bind_target("singleb", "tex");
  238. render_path_bind_target("gbuffer0", "gbuffer0");
  239. render_path_draw_shader("shader_datas/ssao_blur_pass/ssao_blur_pass_y");
  240. }
  241. }
  242. function render_path_base_draw_deferred_light() {
  243. render_path_set_target("buf");
  244. render_path_bind_target("main", "gbufferD");
  245. render_path_bind_target("gbuffer0", "gbuffer0");
  246. render_path_bind_target("gbuffer1", "gbuffer1");
  247. let ssao: bool = config_raw.rp_ssao != false && context_raw.camera_type == camera_type_t.PERSPECTIVE;
  248. if (ssao && _render_path_frame > 0) {
  249. render_path_bind_target("singlea", "ssaotex");
  250. }
  251. else {
  252. render_path_bind_target("empty_white", "ssaotex");
  253. }
  254. render_path_draw_shader("shader_datas/deferred_light/deferred_light");
  255. render_path_set_target("buf", null, "main");
  256. render_path_draw_skydome("shader_datas/world_pass/world_pass");
  257. }
  258. // function render_path_base_draw_histogram() {
  259. // {
  260. // let t: render_target_t = RenderTarget.create();
  261. // t.name = "histogram";
  262. // t.width = 1;
  263. // t.height = 1;
  264. // t.format = "RGBA64";
  265. // render_path_create_render_target(t);
  266. // render_path_load_shader("shader_datas/histogram_pass/histogram_pass");
  267. // }
  268. // render_path_set_target("histogram");
  269. // render_path_bind_target("last", "tex");
  270. // render_path_draw_shader("shader_datas/histogram_pass/histogram_pass");
  271. // }
  272. function render_path_base_draw_taa(bufa: string, bufb: string) {
  273. render_path_set_target(bufb);
  274. render_path_bind_target(bufa, "tex");
  275. let skip_taa: bool = context_raw.split_view;
  276. if (skip_taa) {
  277. render_path_draw_shader("shader_datas/copy_pass/copyRGBA64_pass");
  278. }
  279. else {
  280. render_path_bind_target("last", "tex2");
  281. render_path_draw_shader("shader_datas/taa_pass/taa_pass");
  282. }
  283. render_path_set_target("");
  284. render_path_bind_target(bufb, "tex");
  285. if (render_path_base_ssaa4()) {
  286. render_path_draw_shader("shader_datas/supersample_resolve/supersample_resolveRGBA64");
  287. }
  288. else {
  289. render_path_draw_shader("shader_datas/copy_pass/copy_pass");
  290. }
  291. // Swap buf and last targets
  292. let last_target: render_target_t = map_get(render_path_render_targets, "last");
  293. last_target.name = bufb;
  294. let buf_target: render_target_t = map_get(render_path_render_targets, bufb);
  295. buf_target.name = "last";
  296. map_set(render_path_render_targets, bufb, last_target);
  297. map_set(render_path_render_targets, "last", buf_target);
  298. }
  299. function render_path_base_draw_gbuffer() {
  300. render_path_set_target("gbuffer0", null, "main", clear_flag_t.DEPTH, 0, 1.0); // Only clear gbuffer0
  301. let additional: string[] = ["gbuffer1", "gbuffer2"];
  302. render_path_set_target("gbuffer0", additional, "main");
  303. render_path_paint_bind_layers();
  304. render_path_draw_meshes("mesh");
  305. render_path_paint_unbind_layers();
  306. if (make_mesh_layer_pass_count > 1) {
  307. render_path_base_make_gbuffer_copy_textures();
  308. for (let i: i32 = 1; i < make_mesh_layer_pass_count; ++i) {
  309. let ping: string = i % 2 == 1 ? "_copy" : "";
  310. let pong: string = i % 2 == 1 ? "" : "_copy";
  311. if (i == make_mesh_layer_pass_count - 1) {
  312. render_path_set_target("gbuffer2" + ping, null, null, clear_flag_t.COLOR, 0xff000000);
  313. }
  314. let g1ping: string = "gbuffer1" + ping;
  315. let g2ping: string = "gbuffer2" + ping;
  316. let additional: string[] = [g1ping, g2ping];
  317. render_path_set_target("gbuffer0" + ping, additional, "main");
  318. render_path_bind_target("gbuffer0" + pong, "gbuffer0");
  319. render_path_bind_target("gbuffer1" + pong, "gbuffer1");
  320. render_path_bind_target("gbuffer2" + pong, "gbuffer2");
  321. render_path_paint_bind_layers();
  322. render_path_draw_meshes("mesh" + i);
  323. render_path_paint_unbind_layers();
  324. }
  325. if (make_mesh_layer_pass_count % 2 == 0) {
  326. render_path_base_copy_to_gbuffer();
  327. }
  328. }
  329. let hide: bool = operator_shortcut(map_get(config_keymap, "stencil_hide"), shortcut_type_t.DOWN) || keyboard_down("control");
  330. let is_decal: bool = base_is_decal_layer();
  331. if (is_decal && !hide) {
  332. line_draw_color = 0xff000000;
  333. line_draw_strength = 0.005;
  334. let additional: string[] = ["gbuffer1"];
  335. render_path_set_target("gbuffer0", additional, "main");
  336. line_draw_render(context_raw.layer.decal_mat);
  337. }
  338. }
  339. function render_path_base_make_gbuffer_copy_textures() {
  340. let copy: render_target_t = map_get(render_path_render_targets, "gbuffer0_copy");
  341. let g0: render_target_t = map_get(render_path_render_targets, "gbuffer0");
  342. if (copy == null || copy._image.width != g0._image.width || copy._image.height != g0._image.height) {
  343. {
  344. let t: render_target_t = render_target_create();
  345. t.name = "gbuffer0_copy";
  346. t.width = 0;
  347. t.height = 0;
  348. t.format = "RGBA64";
  349. t.scale = render_path_base_get_super_sampling();
  350. render_path_create_render_target(t);
  351. }
  352. {
  353. let t: render_target_t = render_target_create();
  354. t.name = "gbuffer1_copy";
  355. t.width = 0;
  356. t.height = 0;
  357. t.format = "RGBA64";
  358. t.scale = render_path_base_get_super_sampling();
  359. render_path_create_render_target(t);
  360. }
  361. {
  362. let t: render_target_t = render_target_create();
  363. t.name = "gbuffer2_copy";
  364. t.width = 0;
  365. t.height = 0;
  366. t.format = "RGBA64";
  367. t.scale = render_path_base_get_super_sampling();
  368. render_path_create_render_target(t);
  369. }
  370. }
  371. }
  372. function render_path_base_copy_to_gbuffer() {
  373. let additional: string[] = ["gbuffer1", "gbuffer2"];
  374. render_path_set_target("gbuffer0", additional);
  375. render_path_bind_target("gbuffer0_copy", "tex0");
  376. render_path_bind_target("gbuffer1_copy", "tex1");
  377. render_path_bind_target("gbuffer2_copy", "tex2");
  378. render_path_draw_shader("shader_datas/copy_mrt3_pass/copy_mrt3RGBA64_pass");
  379. }