Files
armorpaint/Libraries/renderlib/Sources/arm/render/RenderPathRaytrace.hx
T

290 lines
8.9 KiB
Haxe
Raw Normal View History

2019-07-29 12:17:56 +02:00
package arm.render;
import iron.RenderPath;
import iron.Scene;
2020-03-18 20:26:28 +01:00
import arm.ui.UISidebar;
2020-03-19 22:06:38 +01:00
import arm.ui.UIHeader;
2020-08-17 14:13:57 +02:00
import arm.node.MakeMaterial;
2020-04-08 19:59:14 +02:00
import arm.Enums;
2019-07-29 12:17:56 +02:00
2020-08-05 19:26:14 +02:00
#if (kha_direct3d12 || kha_vulkan)
2019-07-31 22:05:24 +02:00
2019-07-29 12:17:56 +02:00
class RenderPathRaytrace {
2019-10-04 10:19:37 +02:00
public static var frame = 0;
public static var raysPix = 0;
public static var raysSec = 0;
2019-07-31 22:05:24 +02:00
public static var ready = false;
2020-12-06 17:38:59 +01:00
public static var dirty = 0;
2019-12-09 00:28:10 +01:00
static var path: RenderPath;
2019-10-08 22:10:23 +02:00
static var first = true;
static var f32 = new kha.arrays.Float32Array(24);
2019-07-29 12:17:56 +02:00
static var helpMat = iron.math.Mat4.identity();
2020-01-27 19:33:56 +01:00
static var vb_scale = 1.0;
static var vb: kha.graphics4.VertexBuffer;
static var ib: kha.graphics4.IndexBuffer;
2019-10-04 10:19:37 +02:00
static var raysTimer = 0.0;
static var raysCounter = 0;
2019-12-09 00:28:10 +01:00
static var lastLayer: kha.Image = null;
static var lastEnvmap: kha.Image = null;
2019-10-09 21:16:28 +02:00
static var isBake = false;
2019-12-05 14:27:31 +01:00
static var lastBake = 0;
2019-07-29 12:17:56 +02:00
2020-08-06 14:03:30 +02:00
#if kha_direct3d12
static inline var ext = ".cso";
#else
static inline var ext = ".spirv";
#end
2019-12-09 00:28:10 +01:00
public static function init(_path: RenderPath) {
2019-12-05 18:00:38 +01:00
path = _path;
}
2019-07-29 12:17:56 +02:00
public static function commands() {
2019-10-09 21:16:28 +02:00
if (!ready || isBake) {
2019-10-08 22:10:23 +02:00
ready = true;
2019-10-09 21:16:28 +02:00
isBake = false;
2020-10-13 14:18:53 +02:00
var mode = Context.pathTraceMode == TraceCore ? "core" : "full";
raytraceInit("raytrace_brute_" + mode + ext);
2019-10-08 22:10:23 +02:00
lastEnvmap = null;
}
2020-09-05 15:18:23 +02:00
if (!Context.envmapLoaded) Context.loadEnvmap();
2019-11-04 00:11:51 +01:00
var probe = Scene.active.world.probe;
2020-09-05 15:18:23 +02:00
var savedEnvmap = Context.showEnvmapBlur ? probe.radianceMipmaps[0] : Context.savedEnvmap;
2020-04-09 19:48:00 +02:00
var isLive = Config.raw.brush_live && RenderPathPaint.liveLayerDrawn > 0;
2020-04-08 19:59:14 +02:00
var materialSpace = UIHeader.inst.worktab.position == SpaceMaterial;
2020-04-09 19:48:00 +02:00
var layer = (isLive || materialSpace) ? RenderPathPaint.liveLayer : Context.layer;
2020-12-06 17:38:59 +01:00
if (lastEnvmap != savedEnvmap) {
2019-12-11 21:30:29 +01:00
lastEnvmap = savedEnvmap;
2019-12-12 19:18:23 +01:00
var bnoise_sobol = Scene.active.embedded.get("bnoise_sobol.k");
var bnoise_scramble = Scene.active.embedded.get("bnoise_scramble.k");
var bnoise_rank = Scene.active.embedded.get("bnoise_rank.k");
Layers.flatten(true);
2020-12-06 17:38:59 +01:00
Krom.raytraceSetTextures(Layers.expa.renderTarget_, Layers.expb.renderTarget_, Layers.expc.renderTarget_, savedEnvmap.texture_, bnoise_sobol.texture_, bnoise_scramble.texture_, bnoise_rank.texture_);
}
if (Context.pdirty > 0 || dirty > 0) {
Layers.flatten(true);
2019-10-08 22:10:23 +02:00
}
2019-07-29 12:17:56 +02:00
var cam = Scene.active.camera;
var ct = cam.transform;
helpMat.setFrom(cam.V);
helpMat.multmat(cam.P);
helpMat.getInverse(helpMat);
f32[0] = ct.worldx();
f32[1] = ct.worldy();
f32[2] = ct.worldz();
2019-08-02 15:36:51 +02:00
f32[3] = frame;
2019-11-15 17:45:04 +01:00
frame = (frame % 4) + 1; // _PAINT
// frame = frame + 1; // _RENDER
2019-07-29 12:17:56 +02:00
f32[4] = helpMat._00;
f32[5] = helpMat._01;
f32[6] = helpMat._02;
f32[7] = helpMat._03;
f32[8] = helpMat._10;
f32[9] = helpMat._11;
f32[10] = helpMat._12;
f32[11] = helpMat._13;
f32[12] = helpMat._20;
f32[13] = helpMat._21;
f32[14] = helpMat._22;
f32[15] = helpMat._23;
f32[16] = helpMat._30;
f32[17] = helpMat._31;
f32[18] = helpMat._32;
f32[19] = helpMat._33;
2021-02-02 16:36:22 +01:00
f32[20] = Scene.active.world.probe.raw.strength * 1.5;
2020-04-22 16:08:12 +02:00
if (!Context.showEnvmap) f32[20] = -f32[20];
2020-05-20 13:18:22 +02:00
f32[21] = Context.envmapAngle;
2020-08-05 19:26:14 +02:00
f32[22] = Project.layers.length;
2019-07-29 12:17:56 +02:00
2019-11-16 17:52:43 +01:00
var framebuffer = path.renderTargets.get("buf").image;
2019-09-03 21:58:40 +02:00
Krom.raytraceDispatchRays(framebuffer.renderTarget_, f32.buffer);
2019-07-29 12:17:56 +02:00
2019-11-16 17:52:43 +01:00
if (Context.ddirty == 1 || Context.pdirty == 1) Context.rdirty = 4;
Context.ddirty--;
2019-07-31 22:05:24 +02:00
Context.pdirty--;
Context.rdirty--;
2019-11-16 17:52:43 +01:00
// Context.ddirty = 1; // _RENDER
2019-07-29 12:17:56 +02:00
}
2019-08-23 15:39:25 +02:00
public static function commandsBake() {
2020-03-26 15:22:22 +01:00
if (!ready || !isBake || lastBake != Context.bakeType) {
var rebuild = !(ready && isBake && lastBake != Context.bakeType);
lastBake = Context.bakeType;
2019-10-04 10:19:37 +02:00
ready = true;
2019-10-09 21:16:28 +02:00
isBake = true;
2019-12-05 14:27:31 +01:00
lastEnvmap = null;
lastLayer = null;
2019-10-04 10:19:37 +02:00
if (path.renderTargets.get("baketex0") != null) {
path.renderTargets.get("baketex0").image.unload();
path.renderTargets.get("baketex1").image.unload();
path.renderTargets.get("baketex2").image.unload();
}
{
var t = new RenderTargetRaw();
t.name = "baketex0";
2020-06-03 16:35:39 +02:00
t.width = Config.getTextureResX();
t.height = Config.getTextureResY();
2019-10-04 10:19:37 +02:00
t.format = "RGBA64";
path.createRenderTarget(t);
}
{
var t = new RenderTargetRaw();
t.name = "baketex1";
2020-06-03 16:35:39 +02:00
t.width = Config.getTextureResX();
t.height = Config.getTextureResY();
2019-10-04 10:19:37 +02:00
t.format = "RGBA64";
path.createRenderTarget(t);
}
{
var t = new RenderTargetRaw();
t.name = "baketex2";
2020-06-03 16:35:39 +02:00
t.width = Config.getTextureResX();
t.height = Config.getTextureResY();
2019-12-11 21:30:29 +01:00
t.format = "RGBA64"; // Match raytrace_target format
2019-10-04 10:19:37 +02:00
path.createRenderTarget(t);
}
2020-03-26 15:22:22 +01:00
var _bakeType = Context.bakeType;
Context.bakeType = BakeInit;
2020-08-17 14:13:57 +02:00
MakeMaterial.parsePaintMaterial();
2019-12-07 15:01:13 +01:00
path.setTarget("baketex0");
path.clearTarget(0x00000000); // Pixels with alpha of 0.0 are skipped during raytracing
2019-10-04 10:19:37 +02:00
for (i in 0...4) { // Jitter
path.setTarget("baketex0", ["baketex1"]);
path.drawMeshes("paint");
}
2020-03-26 15:22:22 +01:00
Context.bakeType = _bakeType;
2020-11-05 11:59:29 +01:00
function _next() {
2020-08-17 14:13:57 +02:00
MakeMaterial.parsePaintMaterial();
2019-12-11 21:30:29 +01:00
}
2020-11-05 11:59:29 +01:00
App.notifyOnNextFrame(_next);
2019-10-04 10:19:37 +02:00
2019-12-16 16:32:08 +01:00
raytraceInit(getBakeShaderName(), rebuild);
2019-10-08 22:10:23 +02:00
2019-12-05 14:27:31 +01:00
return;
}
2020-09-05 15:18:23 +02:00
if (!Context.envmapLoaded) Context.loadEnvmap();
2019-12-05 14:27:31 +01:00
var probe = Scene.active.world.probe;
2020-09-05 15:18:23 +02:00
var savedEnvmap = Context.showEnvmapBlur ? probe.radianceMipmaps[0] : Context.savedEnvmap;
2019-12-05 14:27:31 +01:00
if (lastEnvmap != savedEnvmap || lastLayer != Context.layer.texpaint) {
lastEnvmap = savedEnvmap;
lastLayer = Context.layer.texpaint;
2019-10-08 22:10:23 +02:00
var baketex0 = path.renderTargets.get("baketex0").image;
var baketex1 = path.renderTargets.get("baketex1").image;
2019-12-12 19:18:23 +01:00
var bnoise_sobol = Scene.active.embedded.get("bnoise_sobol.k");
var bnoise_scramble = Scene.active.embedded.get("bnoise_scramble.k");
var bnoise_rank = Scene.active.embedded.get("bnoise_rank.k");
2019-12-20 18:10:07 +01:00
var texpaint_undo = RenderPath.active.renderTargets.get("texpaint_undo" + History.undoI).image;
Krom.raytraceSetTextures(baketex0.renderTarget_, baketex1.renderTarget_, texpaint_undo.renderTarget_, savedEnvmap.texture_, bnoise_sobol.texture_, bnoise_scramble.texture_, bnoise_rank.texture_);
2019-10-04 10:19:37 +02:00
}
2019-08-23 15:39:25 +02:00
2020-03-26 15:22:22 +01:00
if (Context.brushTime > 0) {
2019-10-04 00:25:42 +02:00
Context.pdirty = 2;
Context.rdirty = 2;
}
2019-08-23 15:39:25 +02:00
2019-10-04 00:25:42 +02:00
if (Context.pdirty > 0) {
2019-10-04 10:19:37 +02:00
f32[0] = frame++;
2020-03-26 15:22:22 +01:00
f32[1] = Context.bakeAoStrength;
f32[2] = Context.bakeAoRadius;
f32[3] = Context.bakeAoOffset;
2019-12-05 14:27:31 +01:00
f32[4] = Scene.active.world.probe.raw.strength;
2020-03-26 15:22:22 +01:00
f32[5] = Context.bakeUpAxis;
2020-05-20 13:18:22 +02:00
f32[6] = Context.envmapAngle;
2019-08-23 15:39:25 +02:00
2019-12-12 00:59:10 +01:00
var framebuffer = path.renderTargets.get("baketex2").image;
Krom.raytraceDispatchRays(framebuffer.renderTarget_, f32.buffer);
2019-09-30 13:42:54 +02:00
path.setTarget("texpaint" + Context.layer.id);
path.bindTarget("baketex2", "tex");
path.drawShader("shader_datas/copy_pass/copy_pass");
2019-10-04 10:19:37 +02:00
raysPix = frame * 64;
raysCounter += 64;
raysTimer += iron.system.Time.realDelta;
if (raysTimer >= 1) {
raysSec = raysCounter;
raysTimer = 0;
raysCounter = 0;
}
2020-03-19 22:06:38 +01:00
UIHeader.inst.headerHandle.redraws = 2;
2019-09-30 13:42:54 +02:00
}
2019-10-04 00:25:42 +02:00
else {
frame = 0;
2019-10-04 10:19:37 +02:00
raysTimer = 0;
raysCounter = 0;
2019-10-04 00:25:42 +02:00
}
2019-08-23 15:39:25 +02:00
}
2019-09-27 15:38:24 +02:00
2019-12-12 00:59:10 +01:00
static function raytraceInit(shaderName: String, build = true) {
2019-12-05 14:27:31 +01:00
if (first) {
2019-12-11 21:30:29 +01:00
first = false;
2019-12-12 19:18:23 +01:00
Scene.active.embedData("bnoise_sobol.k", function() {});
Scene.active.embedData("bnoise_scramble.k", function() {});
Scene.active.embedData("bnoise_rank.k", function() {});
2019-12-05 14:27:31 +01:00
}
2019-12-09 00:28:10 +01:00
iron.data.Data.getBlob(shaderName, function(shader: kha.Blob) {
2019-12-05 14:27:31 +01:00
if (build) buildData();
2019-12-12 19:18:23 +01:00
var bnoise_sobol = Scene.active.embedded.get("bnoise_sobol.k");
var bnoise_scramble = Scene.active.embedded.get("bnoise_scramble.k");
var bnoise_rank = Scene.active.embedded.get("bnoise_rank.k");
2020-01-27 19:33:56 +01:00
Krom.raytraceInit(shader.bytes.getData(), untyped vb.buffer, untyped ib.buffer, vb_scale);
2019-12-05 14:27:31 +01:00
});
}
2019-09-27 15:38:24 +02:00
static function buildData() {
if (Context.mergedObject == null) arm.util.MeshUtil.mergeMesh();
2021-01-14 18:48:55 +01:00
var mo = !Context.layerFilterUsed() ? Context.mergedObject : Context.paintObject;
2019-09-27 15:38:24 +02:00
var md = mo.data;
var geom = md.geom;
2020-09-10 21:45:17 +02:00
var mo_scale = mo.transform.scale.x; // Uniform scale only
vb_scale = mo.parent.transform.scale.x * md.scalePos * mo_scale;
2020-01-27 19:33:56 +01:00
vb = geom.vertexBuffer;
ib = geom.indexBuffers[0];
2019-09-27 15:38:24 +02:00
}
2019-12-05 14:27:31 +01:00
2019-12-09 00:28:10 +01:00
static function getBakeShaderName(): String {
2019-12-05 14:27:31 +01:00
return
2020-08-06 14:03:30 +02:00
Context.bakeType == BakeAO ? "raytrace_bake_ao" + ext :
Context.bakeType == BakeLightmap ? "raytrace_bake_light" + ext :
Context.bakeType == BakeBentNormal ? "raytrace_bake_bent" + ext :
"raytrace_bake_thick" + ext;
2019-12-05 14:27:31 +01:00
}
2019-12-05 16:52:14 +01:00
public static function draw() {
2020-04-09 19:48:00 +02:00
var isLive = Config.raw.brush_live && RenderPathPaint.liveLayerDrawn > 0;
if (Context.ddirty > 1 || Context.pdirty > 0 || isLive) frame = 0;
2019-12-05 16:52:14 +01:00
commands();
2021-02-07 10:46:26 +01:00
if (Config.raw.rp_bloom != false) {
RenderPathDeferred.commandsBloom("buf");
}
2020-12-10 17:22:33 +01:00
path.setTarget("buf");
path.drawMeshes("overlay");
2019-12-05 16:52:14 +01:00
path.setTarget("buf");
Inc.drawCompass(path.currentG);
path.setTarget("taa");
path.bindTarget("buf", "tex");
path.drawShader("shader_datas/compositor_pass/compositor_pass");
path.setTarget("");
path.bindTarget("taa", "tex");
path.drawShader("shader_datas/copy_pass/copy_pass");
2020-03-26 17:14:07 +01:00
if (Config.raw.brush_3d) {
2019-12-05 16:52:14 +01:00
RenderPathPaint.commandsCursor();
}
}
2019-07-29 12:17:56 +02:00
}
2019-07-31 22:05:24 +02:00
#end