2019-07-29 12:17:56 +02:00
|
|
|
package arm.render;
|
|
|
|
|
|
|
|
|
|
import iron.RenderPath;
|
|
|
|
|
import iron.Scene;
|
2019-10-04 00:25:42 +02:00
|
|
|
import arm.ui.UITrait;
|
2019-11-13 15:17:10 +01:00
|
|
|
import arm.node.MaterialParser;
|
2019-07-29 12:17:56 +02:00
|
|
|
|
2019-07-31 22:05:24 +02:00
|
|
|
#if kha_direct3d12
|
|
|
|
|
|
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;
|
2019-12-05 18:00:38 +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();
|
2019-09-27 15:38:24 +02:00
|
|
|
static var vb:kha.arrays.Float32Array;
|
|
|
|
|
static var ib:kha.arrays.Uint32Array;
|
|
|
|
|
static var bsobol:kha.Image;
|
|
|
|
|
static var bscramble:kha.Image;
|
|
|
|
|
static var brank:kha.Image;
|
2019-10-04 10:19:37 +02:00
|
|
|
static var raysTimer = 0.0;
|
|
|
|
|
static var raysCounter = 0;
|
2019-10-08 22:10:23 +02: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
|
|
|
|
2019-12-05 18:00:38 +01:00
|
|
|
public static function init(_path:RenderPath) {
|
|
|
|
|
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;
|
2019-12-05 18:00:38 +01:00
|
|
|
raytraceInit("raytrace_brute.cso", iron.App.w(), iron.App.h());
|
2019-10-08 22:10:23 +02:00
|
|
|
lastEnvmap = null;
|
|
|
|
|
lastLayer = null;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-04 00:11:51 +01:00
|
|
|
var probe = Scene.active.world.probe;
|
|
|
|
|
var savedEnvmap = UITrait.inst.showEnvmapBlur ? probe.radianceMipmaps[0] : probe.radiance;
|
2019-10-08 22:10:23 +02:00
|
|
|
if (lastEnvmap != savedEnvmap) {
|
|
|
|
|
lastEnvmap = savedEnvmap;
|
|
|
|
|
lastLayer = null;
|
|
|
|
|
|
|
|
|
|
var envrt = path.renderTargets.get("envrt").image;
|
|
|
|
|
envrt.g2.begin(false);
|
|
|
|
|
envrt.g2.drawScaledImage(savedEnvmap, 0, 0, envrt.width, envrt.height);
|
|
|
|
|
envrt.g2.end();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var layer = Context.layer;
|
|
|
|
|
if (lastLayer != layer.texpaint) {
|
|
|
|
|
lastLayer = layer.texpaint;
|
|
|
|
|
var envrt = path.renderTargets.get("envrt").image;
|
|
|
|
|
Krom.raytraceSetTextures(layer.texpaint.renderTarget_, layer.texpaint_nor.renderTarget_, layer.texpaint_pack.renderTarget_, envrt.renderTarget_);
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
2019-10-08 22:10:23 +02:00
|
|
|
f32[20] = Scene.active.world.probe.raw.strength;
|
|
|
|
|
f32[21] = UITrait.inst.showEnvmap ? 1.0 : 0.0;
|
2019-07-29 12:17:56 +02:00
|
|
|
|
2019-11-16 17:52:43 +01:00
|
|
|
var framebuffer = path.renderTargets.get("buf").image;
|
2019-07-29 12:17:56 +02:00
|
|
|
|
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() {
|
2019-10-09 21:16:28 +02:00
|
|
|
if (!ready || !isBake) {
|
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";
|
|
|
|
|
t.width = Config.getTextureRes();
|
|
|
|
|
t.height = Config.getTextureRes();
|
|
|
|
|
t.format = "RGBA64";
|
|
|
|
|
path.createRenderTarget(t);
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
var t = new RenderTargetRaw();
|
|
|
|
|
t.name = "baketex1";
|
|
|
|
|
t.width = Config.getTextureRes();
|
|
|
|
|
t.height = Config.getTextureRes();
|
|
|
|
|
t.format = "RGBA64";
|
|
|
|
|
path.createRenderTarget(t);
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
var t = new RenderTargetRaw();
|
|
|
|
|
t.name = "baketex2";
|
|
|
|
|
t.width = Config.getTextureRes();
|
|
|
|
|
t.height = Config.getTextureRes();
|
|
|
|
|
t.format = "RGBA128"; // Match raytrace_target format
|
|
|
|
|
path.createRenderTarget(t);
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-05 14:27:31 +01:00
|
|
|
var _bakeType = UITrait.inst.bakeType;
|
2019-10-04 10:19:37 +02:00
|
|
|
UITrait.inst.bakeType = -1;
|
|
|
|
|
MaterialParser.parsePaintMaterial();
|
|
|
|
|
for (i in 0...4) { // Jitter
|
|
|
|
|
path.setTarget("baketex0", ["baketex1"]);
|
|
|
|
|
path.drawMeshes("paint");
|
|
|
|
|
}
|
2019-12-05 14:27:31 +01:00
|
|
|
UITrait.inst.bakeType = _bakeType;
|
2019-10-04 10:19:37 +02:00
|
|
|
// MaterialParser.parsePaintMaterial();
|
|
|
|
|
|
2019-12-05 18:00:38 +01:00
|
|
|
raytraceInit(getBakeShaderName(), Config.getTextureRes(), Config.getTextureRes());
|
2019-10-08 22:10:23 +02:00
|
|
|
|
2019-12-05 14:27:31 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lastBake != UITrait.inst.bakeType) {
|
|
|
|
|
lastBake = UITrait.inst.bakeType;
|
2019-12-05 18:00:38 +01:00
|
|
|
raytraceInit(getBakeShaderName(), Config.getTextureRes(), Config.getTextureRes(), false);
|
2019-12-05 14:27:31 +01:00
|
|
|
lastEnvmap = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var probe = Scene.active.world.probe;
|
|
|
|
|
var savedEnvmap = UITrait.inst.showEnvmapBlur ? probe.radianceMipmaps[0] : probe.radiance;
|
|
|
|
|
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;
|
|
|
|
|
var baketex2 = path.renderTargets.get("baketex2").image;
|
|
|
|
|
var savedEnvmap = Scene.active.world.probe.radiance;
|
2019-10-09 21:16:28 +02:00
|
|
|
var envrt = path.renderTargets.get("envrt").image;
|
|
|
|
|
envrt.g2.begin(false);
|
|
|
|
|
envrt.g2.drawScaledImage(savedEnvmap, 0, 0, envrt.width, envrt.height);
|
|
|
|
|
envrt.g2.end();
|
|
|
|
|
|
2019-12-05 14:27:31 +01:00
|
|
|
Krom.raytraceSetTextures(baketex0.renderTarget_, baketex1.renderTarget_, Context.layer.texpaint.renderTarget_, envrt.renderTarget_);
|
2019-10-04 10:19:37 +02:00
|
|
|
}
|
2019-08-23 15:39:25 +02:00
|
|
|
|
2019-10-04 00:25:42 +02:00
|
|
|
if (UITrait.inst.brushTime > 0) {
|
|
|
|
|
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++;
|
2019-10-04 00:25:42 +02:00
|
|
|
f32[1] = UITrait.inst.bakeAoStrength;
|
|
|
|
|
f32[2] = UITrait.inst.bakeAoRadius;
|
|
|
|
|
f32[3] = UITrait.inst.bakeAoOffset;
|
2019-12-05 14:27:31 +01:00
|
|
|
f32[4] = Scene.active.world.probe.raw.strength;
|
2019-12-06 21:21:25 +01:00
|
|
|
f32[5] = UITrait.inst.bakeUpAxis;
|
2019-08-23 15:39:25 +02:00
|
|
|
|
2019-09-30 13:42:54 +02:00
|
|
|
var baketex2 = path.renderTargets.get("baketex2").image;
|
|
|
|
|
Krom.raytraceDispatchRays(baketex2.renderTarget_, f32.buffer);
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
UITrait.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-05 18:00:38 +01:00
|
|
|
static function raytraceInit(shaderName:String, targetW:Int, targetH:Int, build = true) {
|
2019-12-05 14:27:31 +01:00
|
|
|
|
|
|
|
|
if (first) {
|
|
|
|
|
Scene.active.embedData("bnoise_sobol.png", function() {});
|
|
|
|
|
Scene.active.embedData("bnoise_scramble.png", function() {});
|
|
|
|
|
Scene.active.embedData("bnoise_rank.png", function() {});
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
var t = new RenderTargetRaw();
|
|
|
|
|
t.name = "bsobol";
|
|
|
|
|
t.width = 256;
|
|
|
|
|
t.height = 256;
|
|
|
|
|
t.format = "RGBA32";
|
|
|
|
|
path.createRenderTarget(t);
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
var t = new RenderTargetRaw();
|
|
|
|
|
t.name = "bscramble";
|
|
|
|
|
t.width = 128;
|
|
|
|
|
t.height = 1024;
|
|
|
|
|
t.format = "RGBA32";
|
|
|
|
|
path.createRenderTarget(t);
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
var t = new RenderTargetRaw();
|
|
|
|
|
t.name = "brank";
|
|
|
|
|
t.width = 128;
|
|
|
|
|
t.height = 1024;
|
|
|
|
|
t.format = "RGBA32";
|
|
|
|
|
path.createRenderTarget(t);
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
var t = new RenderTargetRaw();
|
|
|
|
|
t.name = "envrt";
|
|
|
|
|
t.width = 4096;
|
|
|
|
|
t.height = 2048;
|
|
|
|
|
t.format = "RGBA128";
|
|
|
|
|
path.createRenderTarget(t);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iron.data.Data.getBlob(shaderName, function(shader:kha.Blob) {
|
|
|
|
|
if (build) buildData();
|
|
|
|
|
Krom.raytraceInit(
|
|
|
|
|
shader.bytes.getData(), untyped vb.buffer, untyped ib.buffer, targetW, targetH,
|
|
|
|
|
bsobol.renderTarget_, bscramble.renderTarget_, brank.renderTarget_);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-27 15:38:24 +02:00
|
|
|
static function buildData() {
|
|
|
|
|
if (Context.mergedObject == null) arm.util.MeshUtil.mergeMesh();
|
|
|
|
|
var mo = Context.mergedObject;
|
2019-10-24 15:29:52 +02:00
|
|
|
var sc = mo.parent.transform.scale.x * mo.data.scalePos;
|
2019-09-27 15:38:24 +02:00
|
|
|
var md = mo.data;
|
|
|
|
|
var geom = md.geom;
|
|
|
|
|
var count = Std.int(geom.positions.length / 4);
|
|
|
|
|
vb = new kha.arrays.Float32Array(count * 8);
|
|
|
|
|
for (i in 0...count) {
|
2019-10-24 15:29:52 +02:00
|
|
|
vb[i * 8 ] = (geom.positions[i * 4 ] * sc / 32767);
|
|
|
|
|
vb[i * 8 + 1] = (geom.positions[i * 4 + 1] * sc / 32767);
|
|
|
|
|
vb[i * 8 + 2] = (geom.positions[i * 4 + 2] * sc / 32767);
|
2019-09-27 15:38:24 +02:00
|
|
|
vb[i * 8 + 3] = geom.normals [i * 2 ] / 32767;
|
|
|
|
|
vb[i * 8 + 4] = geom.normals [i * 2 + 1] / 32767;
|
|
|
|
|
vb[i * 8 + 5] = geom.positions[i * 4 + 3] / 32767;
|
|
|
|
|
vb[i * 8 + 6] = (geom.uvs[i * 2 ] / 32767);
|
|
|
|
|
vb[i * 8 + 7] = (geom.uvs[i * 2 + 1] / 32767);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var indices = geom.indices[0];
|
|
|
|
|
ib = new kha.arrays.Uint32Array(indices.length);
|
|
|
|
|
for (i in 0...indices.length) ib[i] = indices[i];
|
|
|
|
|
|
2019-12-05 14:27:31 +01:00
|
|
|
buildSobol();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static function buildSobol() {
|
2019-09-27 15:38:24 +02:00
|
|
|
var bnoise_sobol = Scene.active.embedded.get("bnoise_sobol.png");
|
|
|
|
|
var bnoise_scramble = Scene.active.embedded.get("bnoise_scramble.png");
|
|
|
|
|
var bnoise_rank = Scene.active.embedded.get("bnoise_rank.png");
|
|
|
|
|
|
|
|
|
|
bsobol = path.renderTargets.get("bsobol").image;
|
|
|
|
|
bscramble = path.renderTargets.get("bscramble").image;
|
|
|
|
|
brank = path.renderTargets.get("brank").image;
|
|
|
|
|
|
2019-10-08 22:10:23 +02:00
|
|
|
bsobol.g2.begin(false);
|
2019-09-27 15:38:24 +02:00
|
|
|
bsobol.g2.drawImage(bnoise_sobol, 0, 0);
|
|
|
|
|
bsobol.g2.end();
|
2019-10-08 22:10:23 +02:00
|
|
|
bscramble.g2.begin(false);
|
2019-09-27 15:38:24 +02:00
|
|
|
bscramble.g2.drawImage(bnoise_scramble, 0, 0);
|
|
|
|
|
bscramble.g2.end();
|
2019-10-08 22:10:23 +02:00
|
|
|
brank.g2.begin(false);
|
2019-09-27 15:38:24 +02:00
|
|
|
brank.g2.drawImage(bnoise_rank, 0, 0);
|
|
|
|
|
brank.g2.end();
|
|
|
|
|
}
|
2019-12-05 14:27:31 +01:00
|
|
|
|
|
|
|
|
static function getBakeShaderName():String {
|
|
|
|
|
return
|
|
|
|
|
UITrait.inst.bakeType == 0 ? "raytrace_bake_ao.cso" :
|
|
|
|
|
UITrait.inst.bakeType == 8 ? "raytrace_bake_light.cso" :
|
2019-12-06 23:34:21 +01:00
|
|
|
UITrait.inst.bakeType == 9 ? "raytrace_bake_bent.cso" :
|
|
|
|
|
"raytrace_bake_thick.cso";
|
2019-12-05 14:27:31 +01:00
|
|
|
}
|
2019-12-05 16:52:14 +01:00
|
|
|
|
|
|
|
|
public static function draw() {
|
|
|
|
|
#if arm_painter
|
|
|
|
|
if (Context.ddirty > 1) frame = 0;
|
|
|
|
|
#else
|
|
|
|
|
frame = 0;
|
|
|
|
|
#end
|
|
|
|
|
|
|
|
|
|
commands();
|
|
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
#if arm_painter
|
|
|
|
|
if (UITrait.inst.brush3d) {
|
|
|
|
|
RenderPathPaint.commandsCursor();
|
|
|
|
|
}
|
|
|
|
|
#end
|
|
|
|
|
}
|
2019-07-29 12:17:56 +02:00
|
|
|
}
|
2019-07-31 22:05:24 +02:00
|
|
|
|
|
|
|
|
#end
|