upscale_node.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. type upscale_node_t = {
  2. base?: logic_node_t;
  3. };
  4. let upscale_node_temp: image_t = null;
  5. let upscale_node_image: image_t = null;
  6. let upscale_node_esrgan_blob: buffer_t;
  7. function upscale_node_create(arg: any): upscale_node_t {
  8. let n: float_node_t = {};
  9. n.base = logic_node_create();
  10. n.base.get_as_image = upscale_node_get_as_image;
  11. n.base.get_cached_image = upscale_node_get_cached_image;
  12. return n;
  13. }
  14. function upscale_node_get_as_image(self: upscale_node_t, from: i32): image_t {
  15. upscale_node_image = logic_node_input_get_as_image(self.base.inputs[0]);
  16. console_progress(tr("Processing") + " - " + tr("Upscale"));
  17. krom_g4_swap_buffers();
  18. upscale_node_load_blob();
  19. if (upscale_node_image.width < config_get_texture_res_x()) {
  20. upscale_node_image = upscale_node_esrgan(upscale_node_image);
  21. while (upscale_node_image.width < config_get_texture_res_x()) {
  22. let last_image = upscale_node_image;
  23. upscale_node_image = upscale_node_esrgan(upscale_node_image);
  24. image_unload(last_image);
  25. }
  26. }
  27. return upscale_node_image;
  28. }
  29. function upscale_node_load_blob() {
  30. upscale_node_esrgan_blob = data_get_blob("models/esrgan.quant.onnx");
  31. }
  32. function upscale_node_get_cached_image(self: upscale_node_t): image_t {
  33. return upscale_node_image;
  34. }
  35. function upscale_node_do_tile(source: image_t) {
  36. let result: image_t = null;
  37. let size1w = source.width;
  38. let size1h = source.height;
  39. let size2w = math_floor(size1w * 2);
  40. let size2h = math_floor(size1h * 2);
  41. if (upscale_node_temp != null) {
  42. image_unload(upscale_node_temp);
  43. }
  44. upscale_node_temp = image_create_render_target(size1w, size1h);
  45. g2_begin(upscale_node_temp);
  46. g2_draw_scaled_image(source, 0, 0, size1w, size1h);
  47. g2_end();
  48. let bytes_img = image_get_pixels(upscale_node_temp);
  49. let u8a = u8_array_create_from_buffer(bytes_img);
  50. let f32a = f32_array_create(3 * size1w * size1h);
  51. for (let i: i32 = 0; i < (size1w * size1h); ++i) {
  52. f32a[i ] = (u8a[i * 4 ] / 255);
  53. f32a[i + size1w * size1w ] = (u8a[i * 4 + 1] / 255);
  54. f32a[i + size1w * size1w * 2] = (u8a[i * 4 + 2] / 255);
  55. }
  56. let esrgan2x_buf = krom_ml_inference(upscale_node_esrgan_blob, [f32a.buffer], [[1, 3, size1w, size1h]], [1, 3, size2w, size2h], config_raw.gpu_inference);
  57. let esrgan2x = f32_array_create_from_buffer(esrgan2x_buf);
  58. for (let i: i32 = 0; i < esrgan2x.length; ++i) {
  59. if (esrgan2x[i] < 0) {
  60. esrgan2x[i] = 0;
  61. }
  62. else if (esrgan2x[i] > 1) {
  63. esrgan2x[i] = 1;
  64. }
  65. }
  66. u8a = u8_array_create(4 * size2w * size2h);
  67. for (let i: i32 = 0; i < (size2w * size2h); ++i) {
  68. u8a[i * 4 ] = math_floor(esrgan2x[i ] * 255);
  69. u8a[i * 4 + 1] = math_floor(esrgan2x[i + size2w * size2w ] * 255);
  70. u8a[i * 4 + 2] = math_floor(esrgan2x[i + size2w * size2w * 2] * 255);
  71. u8a[i * 4 + 3] = 255;
  72. }
  73. result = image_from_bytes(u8a.buffer, size2w, size2h);
  74. return result;
  75. }
  76. function upscale_node_esrgan(source: image_t): image_t {
  77. let result: image_t = null;
  78. let size1w = source.width;
  79. let size1h = source.height;
  80. let tile_size = 512;
  81. let tile_size2x = math_floor(tile_size * 2);
  82. if (size1w >= tile_size2x || size1h >= tile_size2x) { // Split into tiles
  83. let size2w = math_floor(size1w * 2);
  84. let size2h = math_floor(size1h * 2);
  85. result = image_create_render_target(size2w, size2h);
  86. let tile_source = image_create_render_target(tile_size + 32 * 2, tile_size + 32 * 2);
  87. for (let x: i32 = 0; x < math_floor(size1w / tile_size); ++x) {
  88. for (let y: i32 = 0; y < math_floor(size1h / tile_size); ++y) {
  89. g2_begin(tile_source);
  90. g2_draw_scaled_image(source, 32 - x * tile_size, 32 - y * tile_size, -source.width, source.height);
  91. g2_draw_scaled_image(source, 32 - x * tile_size, 32 - y * tile_size, source.width, -source.height);
  92. g2_draw_scaled_image(source, 32 - x * tile_size, 32 - y * tile_size, -source.width, -source.height);
  93. g2_draw_scaled_image(source, 32 - x * tile_size + tile_size, 32 - y * tile_size + tile_size, source.width, source.height);
  94. g2_draw_scaled_image(source, 32 - x * tile_size + tile_size, 32 - y * tile_size + tile_size, -source.width, source.height);
  95. g2_draw_scaled_image(source, 32 - x * tile_size + tile_size, 32 - y * tile_size + tile_size, source.width, -source.height);
  96. g2_draw_scaled_image(source, 32 - x * tile_size, 32 - y * tile_size, source.width, source.height);
  97. g2_end();
  98. let tileResult = upscale_node_do_tile(tile_source);
  99. g2_begin(result);
  100. g2_draw_sub_image(tileResult, x * tile_size2x, y * tile_size2x, 64, 64, tile_size2x, tile_size2x);
  101. g2_end();
  102. image_unload(tileResult);
  103. }
  104. }
  105. image_unload(tile_source);
  106. }
  107. else {
  108. result = upscale_node_do_tile(source); // Single tile
  109. }
  110. return result;
  111. }
  112. let upscale_node_def: zui_node_t = {
  113. id: 0,
  114. name: _tr("Upscale"),
  115. type: "upscale_node",
  116. x: 0,
  117. y: 0,
  118. color: 0xff4982a0,
  119. inputs: [
  120. {
  121. id: 0,
  122. node_id: 0,
  123. name: _tr("Color"),
  124. type: "RGBA",
  125. color: 0xffc7c729,
  126. default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0),
  127. min: 0.0,
  128. max: 1.0,
  129. precision: 100,
  130. display: 0
  131. }
  132. ],
  133. outputs: [
  134. {
  135. id: 0,
  136. node_id: 0,
  137. name: _tr("Color"),
  138. type: "RGBA",
  139. color: 0xffc7c729,
  140. default_value: f32_array_create_xyzw(0.0, 0.0, 0.0, 1.0),
  141. min: 0.0,
  142. max: 1.0,
  143. precision: 100,
  144. display: 0
  145. }
  146. ],
  147. buttons: [],
  148. width: 0
  149. };