RenderPathRaytrace.hx 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. package arm.render;
  2. import iron.RenderPath;
  3. import iron.Scene;
  4. import arm.ui.UITrait;
  5. import arm.node.MaterialParser;
  6. #if kha_direct3d12
  7. class RenderPathRaytrace {
  8. public static var frame = 0;
  9. public static var raysPix = 0;
  10. public static var raysSec = 0;
  11. public static var ready = false;
  12. static var path: RenderPath;
  13. static var first = true;
  14. static var f32 = new kha.arrays.Float32Array(24);
  15. static var helpMat = iron.math.Mat4.identity();
  16. static var vb: kha.arrays.Float32Array;
  17. static var ib: kha.arrays.Uint32Array;
  18. static var raysTimer = 0.0;
  19. static var raysCounter = 0;
  20. static var lastLayer: kha.Image = null;
  21. static var lastEnvmap: kha.Image = null;
  22. static var isBake = false;
  23. static var lastBake = 0;
  24. public static function init(_path: RenderPath) {
  25. path = _path;
  26. }
  27. public static function commands() {
  28. if (!ready || isBake) {
  29. ready = true;
  30. isBake = false;
  31. raytraceInit("raytrace_brute.cso");
  32. lastEnvmap = null;
  33. lastLayer = null;
  34. }
  35. var probe = Scene.active.world.probe;
  36. var savedEnvmap = UITrait.inst.showEnvmapBlur ? probe.radianceMipmaps[0] : probe.radiance;
  37. var layer = Context.layer;
  38. if (lastEnvmap != savedEnvmap || lastLayer != layer.texpaint) {
  39. lastEnvmap = savedEnvmap;
  40. lastLayer = layer.texpaint;
  41. var bnoise_sobol = Scene.active.embedded.get("bnoise_sobol.k");
  42. var bnoise_scramble = Scene.active.embedded.get("bnoise_scramble.k");
  43. var bnoise_rank = Scene.active.embedded.get("bnoise_rank.k");
  44. Krom.raytraceSetTextures(layer.texpaint.renderTarget_, layer.texpaint_nor.renderTarget_, layer.texpaint_pack.renderTarget_, savedEnvmap.texture_, bnoise_sobol.texture_, bnoise_scramble.texture_, bnoise_rank.texture_);
  45. }
  46. var cam = Scene.active.camera;
  47. var ct = cam.transform;
  48. helpMat.setFrom(cam.V);
  49. helpMat.multmat(cam.P);
  50. helpMat.getInverse(helpMat);
  51. f32[0] = ct.worldx();
  52. f32[1] = ct.worldy();
  53. f32[2] = ct.worldz();
  54. f32[3] = frame;
  55. frame = (frame % 4) + 1; // _PAINT
  56. // frame = frame + 1; // _RENDER
  57. f32[4] = helpMat._00;
  58. f32[5] = helpMat._01;
  59. f32[6] = helpMat._02;
  60. f32[7] = helpMat._03;
  61. f32[8] = helpMat._10;
  62. f32[9] = helpMat._11;
  63. f32[10] = helpMat._12;
  64. f32[11] = helpMat._13;
  65. f32[12] = helpMat._20;
  66. f32[13] = helpMat._21;
  67. f32[14] = helpMat._22;
  68. f32[15] = helpMat._23;
  69. f32[16] = helpMat._30;
  70. f32[17] = helpMat._31;
  71. f32[18] = helpMat._32;
  72. f32[19] = helpMat._33;
  73. f32[20] = Scene.active.world.probe.raw.strength;
  74. f32[21] = UITrait.inst.showEnvmap ? 1.0 : 0.0;
  75. var framebuffer = path.renderTargets.get("buf").image;
  76. Krom.raytraceDispatchRays(framebuffer.renderTarget_, f32.buffer);
  77. if (Context.ddirty == 1 || Context.pdirty == 1) Context.rdirty = 4;
  78. Context.ddirty--;
  79. Context.pdirty--;
  80. Context.rdirty--;
  81. // Context.ddirty = 1; // _RENDER
  82. }
  83. public static function commandsBake() {
  84. if (!ready || !isBake || lastBake != UITrait.inst.bakeType) {
  85. var rebuild = !(ready && isBake && lastBake != UITrait.inst.bakeType);
  86. lastBake = UITrait.inst.bakeType;
  87. ready = true;
  88. isBake = true;
  89. lastEnvmap = null;
  90. lastLayer = null;
  91. if (path.renderTargets.get("baketex0") != null) {
  92. path.renderTargets.get("baketex0").image.unload();
  93. path.renderTargets.get("baketex1").image.unload();
  94. path.renderTargets.get("baketex2").image.unload();
  95. }
  96. {
  97. var t = new RenderTargetRaw();
  98. t.name = "baketex0";
  99. t.width = Config.getTextureRes();
  100. t.height = Config.getTextureRes();
  101. t.format = "RGBA64";
  102. path.createRenderTarget(t);
  103. }
  104. {
  105. var t = new RenderTargetRaw();
  106. t.name = "baketex1";
  107. t.width = Config.getTextureRes();
  108. t.height = Config.getTextureRes();
  109. t.format = "RGBA64";
  110. path.createRenderTarget(t);
  111. }
  112. {
  113. var t = new RenderTargetRaw();
  114. t.name = "baketex2";
  115. t.width = Config.getTextureRes();
  116. t.height = Config.getTextureRes();
  117. t.format = "RGBA64"; // Match raytrace_target format
  118. path.createRenderTarget(t);
  119. }
  120. var _bakeType = UITrait.inst.bakeType;
  121. UITrait.inst.bakeType = BakeInit;
  122. MaterialParser.parsePaintMaterial();
  123. path.setTarget("baketex0");
  124. path.clearTarget(0x00000000); // Pixels with alpha of 0.0 are skipped during raytracing
  125. for (i in 0...4) { // Jitter
  126. path.setTarget("baketex0", ["baketex1"]);
  127. path.drawMeshes("paint");
  128. }
  129. UITrait.inst.bakeType = _bakeType;
  130. function _render(_) {
  131. MaterialParser.parsePaintMaterial();
  132. iron.App.removeRender(_render);
  133. }
  134. iron.App.notifyOnRender(_render);
  135. raytraceInit(getBakeShaderName(), rebuild);
  136. return;
  137. }
  138. var probe = Scene.active.world.probe;
  139. var savedEnvmap = UITrait.inst.showEnvmapBlur ? probe.radianceMipmaps[0] : probe.radiance;
  140. if (lastEnvmap != savedEnvmap || lastLayer != Context.layer.texpaint) {
  141. lastEnvmap = savedEnvmap;
  142. lastLayer = Context.layer.texpaint;
  143. var baketex0 = path.renderTargets.get("baketex0").image;
  144. var baketex1 = path.renderTargets.get("baketex1").image;
  145. var bnoise_sobol = Scene.active.embedded.get("bnoise_sobol.k");
  146. var bnoise_scramble = Scene.active.embedded.get("bnoise_scramble.k");
  147. var bnoise_rank = Scene.active.embedded.get("bnoise_rank.k");
  148. var texpaint_undo = RenderPath.active.renderTargets.get("texpaint_undo" + History.undoI).image;
  149. Krom.raytraceSetTextures(baketex0.renderTarget_, baketex1.renderTarget_, texpaint_undo.renderTarget_, savedEnvmap.texture_, bnoise_sobol.texture_, bnoise_scramble.texture_, bnoise_rank.texture_);
  150. }
  151. if (UITrait.inst.brushTime > 0) {
  152. Context.pdirty = 2;
  153. Context.rdirty = 2;
  154. }
  155. if (Context.pdirty > 0) {
  156. f32[0] = frame++;
  157. f32[1] = UITrait.inst.bakeAoStrength;
  158. f32[2] = UITrait.inst.bakeAoRadius;
  159. f32[3] = UITrait.inst.bakeAoOffset;
  160. f32[4] = Scene.active.world.probe.raw.strength;
  161. f32[5] = UITrait.inst.bakeUpAxis;
  162. var framebuffer = path.renderTargets.get("baketex2").image;
  163. Krom.raytraceDispatchRays(framebuffer.renderTarget_, f32.buffer);
  164. path.setTarget("texpaint" + Context.layer.id);
  165. path.bindTarget("baketex2", "tex");
  166. path.drawShader("shader_datas/copy_pass/copy_pass");
  167. raysPix = frame * 64;
  168. raysCounter += 64;
  169. raysTimer += iron.system.Time.realDelta;
  170. if (raysTimer >= 1) {
  171. raysSec = raysCounter;
  172. raysTimer = 0;
  173. raysCounter = 0;
  174. }
  175. UITrait.inst.headerHandle.redraws = 2;
  176. }
  177. else {
  178. frame = 0;
  179. raysTimer = 0;
  180. raysCounter = 0;
  181. }
  182. }
  183. static function raytraceInit(shaderName: String, build = true) {
  184. if (first) {
  185. first = false;
  186. Scene.active.embedData("bnoise_sobol.k", function() {});
  187. Scene.active.embedData("bnoise_scramble.k", function() {});
  188. Scene.active.embedData("bnoise_rank.k", function() {});
  189. }
  190. iron.data.Data.getBlob(shaderName, function(shader: kha.Blob) {
  191. if (build) buildData();
  192. var bnoise_sobol = Scene.active.embedded.get("bnoise_sobol.k");
  193. var bnoise_scramble = Scene.active.embedded.get("bnoise_scramble.k");
  194. var bnoise_rank = Scene.active.embedded.get("bnoise_rank.k");
  195. Krom.raytraceInit(shader.bytes.getData(), untyped vb.buffer, untyped ib.buffer);
  196. });
  197. }
  198. static function buildData() {
  199. if (Context.mergedObject == null) arm.util.MeshUtil.mergeMesh();
  200. var mo = Context.mergedObject;
  201. var sc = mo.parent.transform.scale.x * mo.data.scalePos;
  202. var md = mo.data;
  203. var geom = md.geom;
  204. var count = Std.int(geom.positions.length / 4);
  205. vb = new kha.arrays.Float32Array(count * 8);
  206. for (i in 0...count) {
  207. vb[i * 8 ] = (geom.positions[i * 4 ] * sc / 32767);
  208. vb[i * 8 + 1] = (geom.positions[i * 4 + 1] * sc / 32767);
  209. vb[i * 8 + 2] = (geom.positions[i * 4 + 2] * sc / 32767);
  210. vb[i * 8 + 3] = geom.normals [i * 2 ] / 32767;
  211. vb[i * 8 + 4] = geom.normals [i * 2 + 1] / 32767;
  212. vb[i * 8 + 5] = geom.positions[i * 4 + 3] / 32767;
  213. vb[i * 8 + 6] = (geom.uvs[i * 2 ] / 32767);
  214. vb[i * 8 + 7] = (geom.uvs[i * 2 + 1] / 32767);
  215. }
  216. var indices = geom.indices[0];
  217. ib = new kha.arrays.Uint32Array(indices.length);
  218. for (i in 0...indices.length) ib[i] = indices[i];
  219. }
  220. static function getBakeShaderName(): String {
  221. return
  222. UITrait.inst.bakeType == BakeAO ? "raytrace_bake_ao.cso" :
  223. UITrait.inst.bakeType == BakeLightmap ? "raytrace_bake_light.cso" :
  224. UITrait.inst.bakeType == BakeBentNormal ? "raytrace_bake_bent.cso" :
  225. "raytrace_bake_thick.cso";
  226. }
  227. public static function draw() {
  228. #if arm_painter
  229. if (Context.ddirty > 1) frame = 0;
  230. #else
  231. frame = 0;
  232. #end
  233. commands();
  234. path.setTarget("buf");
  235. Inc.drawCompass(path.currentG);
  236. path.setTarget("taa");
  237. path.bindTarget("buf", "tex");
  238. path.drawShader("shader_datas/compositor_pass/compositor_pass");
  239. path.setTarget("");
  240. path.bindTarget("taa", "tex");
  241. path.drawShader("shader_datas/copy_pass/copy_pass");
  242. #if arm_painter
  243. if (UITrait.inst.brush3d) {
  244. RenderPathPaint.commandsCursor();
  245. }
  246. #end
  247. }
  248. }
  249. #end