Raytraced baking stubs
This commit is contained in:
Binary file not shown.
@@ -1 +1,2 @@
|
||||
.\dxc.exe -Zpr -Fo ..\raytrace.cso -T lib_6_3 .\raytrace.hlsl
|
||||
.\dxc.exe -Zpr -Fo ..\raytrace.cso -T lib_6_3 .\raytrace.hlsl
|
||||
.\dxc.exe -Zpr -Fo ..\raytrace_bake.cso -T lib_6_3 .\raytrace_bake.hlsl
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
|
||||
struct Vertex {
|
||||
float3 position;
|
||||
float3 normal;
|
||||
float2 tex;
|
||||
};
|
||||
|
||||
struct RayGenConstantBuffer {
|
||||
float4 v0; // frame
|
||||
float4 v1;
|
||||
float4 v2;
|
||||
float4 v3;
|
||||
float4 v4;
|
||||
};
|
||||
|
||||
struct RayPayload {
|
||||
float4 color;
|
||||
float3 ray_origin;
|
||||
float3 ray_dir;
|
||||
};
|
||||
|
||||
RWTexture2D<float4> render_target : register(u0);
|
||||
RaytracingAccelerationStructure scene : register(t0);
|
||||
ByteAddressBuffer indices : register(t1);
|
||||
StructuredBuffer<Vertex> vertices : register(t2);
|
||||
ConstantBuffer<RayGenConstantBuffer> constant_buffer : register(b0);
|
||||
|
||||
Texture2D<float4> mytexture0 : register(t3);
|
||||
Texture2D<float4> mytexture1 : register(t4);
|
||||
Texture2D<float4> mytexture2 : register(t5);
|
||||
Texture2D<float4> mytexture_env : register(t6);
|
||||
|
||||
static uint seed;
|
||||
|
||||
uint wang_hash(uint seed) {
|
||||
seed = (seed ^ 61) ^ (seed >> 16);
|
||||
seed *= 9;
|
||||
seed = seed ^ (seed >> 4);
|
||||
seed *= 0x27d4eb2d;
|
||||
seed = seed ^ (seed >> 15);
|
||||
return seed;
|
||||
}
|
||||
|
||||
void compute_seed(uint index, uint iteration, uint depth) {
|
||||
seed = uint(wang_hash((1 << 31) | (depth << 22) | iteration) ^ wang_hash(index));
|
||||
}
|
||||
|
||||
float rand() {
|
||||
static const float png_01_convert = (1.0f / 4294967296.0f);
|
||||
seed ^= uint(seed << 13);
|
||||
seed ^= uint(seed >> 17);
|
||||
seed ^= uint(seed << 5);
|
||||
return float(seed * png_01_convert);
|
||||
}
|
||||
|
||||
float3 cos_weighted_random_hemisphere_direction(float3 n) {
|
||||
float2 r = float2(rand(), rand());
|
||||
float3 uu = normalize(cross(n, float3(0.0, 1.0, 1.0)));
|
||||
float3 vv = cross(uu, n);
|
||||
float ra = sqrt(r.y);
|
||||
float rx = ra * cos(6.2831 * r.x);
|
||||
float ry = ra * sin(6.2831 * r.x);
|
||||
float rz = sqrt(1.0 - r.y);
|
||||
float3 rr = float3(rx * uu + ry * vv + rz * n);
|
||||
return normalize(rr);
|
||||
}
|
||||
|
||||
[shader("raygeneration")]
|
||||
void raygeneration() {
|
||||
|
||||
uint id = DispatchRaysIndex().x + DispatchRaysDimensions().x * DispatchRaysIndex().y;
|
||||
compute_seed(id, constant_buffer.v0.x, 0);
|
||||
|
||||
float2 xy = DispatchRaysIndex().xy + 0.5f;
|
||||
xy.x += rand(); // AA
|
||||
xy.y += rand();
|
||||
|
||||
float3 pos = mytexture0.Load(uint3(xy, 0)).rgb;
|
||||
float3 nor = mytexture1.Load(uint3(xy, 0)).rgb;
|
||||
|
||||
float color = 0.0;
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
RayPayload payload;
|
||||
payload.ray_origin = pos;
|
||||
payload.ray_dir = cos_weighted_random_hemisphere_direction(nor);
|
||||
|
||||
RayDesc ray;
|
||||
ray.TMin = 0.01;
|
||||
ray.TMax = 10.0;
|
||||
ray.Origin = payload.ray_origin;
|
||||
ray.Direction = payload.ray_dir;
|
||||
|
||||
TraceRay(scene, RAY_FLAG_FORCE_OPAQUE, ~0, 0, 1, 0, ray, payload);
|
||||
color += payload.color.r;
|
||||
|
||||
compute_seed(id, constant_buffer.v0.x, i);
|
||||
}
|
||||
|
||||
color /= 4;
|
||||
color = 1 - color;
|
||||
render_target[DispatchRaysIndex().xy] = float4(color.xxx, 0.0f);
|
||||
}
|
||||
|
||||
float3 hit_world_position() {
|
||||
return WorldRayOrigin() + RayTCurrent() * WorldRayDirection();
|
||||
}
|
||||
|
||||
float3 hit_attribute(float3 vertexAttribute[3], BuiltInTriangleIntersectionAttributes attr) {
|
||||
return vertexAttribute[0] +
|
||||
attr.barycentrics.x * (vertexAttribute[1] - vertexAttribute[0]) +
|
||||
attr.barycentrics.y * (vertexAttribute[2] - vertexAttribute[0]);
|
||||
}
|
||||
|
||||
float2 hit_attribute2d(float2 vertexAttribute[3], BuiltInTriangleIntersectionAttributes attr) {
|
||||
return vertexAttribute[0] +
|
||||
attr.barycentrics.x * (vertexAttribute[1] - vertexAttribute[0]) +
|
||||
attr.barycentrics.y * (vertexAttribute[2] - vertexAttribute[0]);
|
||||
}
|
||||
|
||||
[shader("closesthit")]
|
||||
void closesthit(inout RayPayload payload, in BuiltInTriangleIntersectionAttributes attr) {
|
||||
payload.color = float4(1,1,1,0);
|
||||
}
|
||||
|
||||
[shader("miss")]
|
||||
void miss(inout RayPayload payload) {
|
||||
payload.color = float4(0,0,0,-1);
|
||||
}
|
||||
@@ -52,6 +52,26 @@ class MaterialBuilder {
|
||||
var frag = con_paint.make_frag();
|
||||
frag.ins = vert.outs;
|
||||
|
||||
#if kha_direct3d12
|
||||
if (UITrait.inst.bakeType == -1) {
|
||||
// Init raytraced bake
|
||||
vert.add_out('vec3 position');
|
||||
vert.add_out('vec3 normal');
|
||||
vert.write('position = pos.xyz;');
|
||||
vert.write('normal = vec3(nor.xy, pos.w);');
|
||||
vert.write('vec2 tpos = vec2(tex.x * 2.0 - 1.0, (1.0 - tex.y) * 2.0 - 1.0);');
|
||||
vert.write('gl_Position = vec4(tpos, 0.0, 1.0);');
|
||||
frag.add_out('vec4 fragColor[2]');
|
||||
frag.write('fragColor[0] = vec4(position, 1.0);');
|
||||
frag.write('fragColor[1] = vec4(normal, 1.0);');
|
||||
|
||||
con_paint.data.shader_from_source = true;
|
||||
con_paint.data.vertex_shader = vert.get();
|
||||
con_paint.data.fragment_shader = frag.get();
|
||||
return con_paint;
|
||||
}
|
||||
#end
|
||||
|
||||
if (Context.tool == ToolColorId || Context.tool == ToolPicker) {
|
||||
// Mangle vertices to form full screen triangle
|
||||
vert.write('gl_Position = vec4(-1.0 + float((gl_VertexID & 1) << 2), -1.0 + float((gl_VertexID & 2) << 1), 0.0, 1.0);');
|
||||
|
||||
@@ -103,7 +103,7 @@ class RenderPathDeferred {
|
||||
t.name = "taa";
|
||||
t.width = 0;
|
||||
t.height = 0;
|
||||
#if kha_direct3d12
|
||||
#if kha_direct3d12 // Match raytrace_target format
|
||||
t.format = "RGBA128";
|
||||
#else
|
||||
t.format = "RGBA32";
|
||||
@@ -632,16 +632,62 @@ class RenderPathDeferred {
|
||||
if (Context.ddirty > 1 || Context.pdirty > 0) {
|
||||
RenderPathRaytrace.frame = 1.0;
|
||||
}
|
||||
RenderPathRaytrace.commands();
|
||||
path.setTarget("taa");
|
||||
drawCompass(path.currentG);
|
||||
path.setTarget("");
|
||||
path.bindTarget("taa", "tex");
|
||||
path.drawShader("shader_datas/compositor_pass/compositor_pass");
|
||||
if (UITrait.inst.brush3d) {
|
||||
RenderPathPaint.commandsCursor();
|
||||
var bake = true;
|
||||
if (bake) {
|
||||
if (path.renderTargets.get("baketex0") == null) {
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (!RenderPathRaytrace.ready) {
|
||||
var _bakeType = UITrait.inst.bakeType;
|
||||
UITrait.inst.bakeType = -1;
|
||||
MaterialParser.parsePaintMaterial();
|
||||
|
||||
path.setTarget("baketex0", ["baketex1"]);
|
||||
path.drawMeshes("paint");
|
||||
|
||||
UITrait.inst.bakeType = _bakeType;
|
||||
// MaterialParser.parsePaintMaterial();
|
||||
}
|
||||
RenderPathRaytrace.commandsBake();
|
||||
path.setTarget("texpaint" + Context.layer.id);
|
||||
path.bindTarget("baketex2", "tex");
|
||||
path.drawShader("shader_datas/copy_pass/copy_pass");
|
||||
}
|
||||
else {
|
||||
RenderPathRaytrace.commands();
|
||||
path.setTarget("taa");
|
||||
drawCompass(path.currentG);
|
||||
path.setTarget("");
|
||||
path.bindTarget("taa", "tex");
|
||||
path.drawShader("shader_datas/compositor_pass/compositor_pass");
|
||||
if (UITrait.inst.brush3d) {
|
||||
RenderPathPaint.commandsCursor();
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
#end
|
||||
|
||||
#end // arm_painter
|
||||
|
||||
@@ -128,6 +128,60 @@ class RenderPathRaytrace {
|
||||
Context.pdirty--;
|
||||
Context.rdirty--;
|
||||
}
|
||||
|
||||
public static function initBake() {
|
||||
iron.data.Data.getBlob("raytrace_bake.cso", function(shader:kha.Blob) {
|
||||
if (Context.mergedObject == null) arm.util.MeshUtil.mergeMesh();
|
||||
var mo = Context.mergedObject;
|
||||
var sc = mo.transform.scale;
|
||||
var md = mo.data;
|
||||
var geom = md.geom;
|
||||
var count = Std.int(geom.positions.length / 4);
|
||||
var vb = new kha.arrays.Float32Array((count + 4) * 8);
|
||||
for (i in 0...count) {
|
||||
vb[i * 8 ] = (geom.positions[i * 4 ] / 32767);
|
||||
vb[i * 8 + 1] = (geom.positions[i * 4 + 1] / 32767);
|
||||
vb[i * 8 + 2] = (geom.positions[i * 4 + 2] / 32767);
|
||||
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];
|
||||
var ib = new kha.arrays.Uint32Array(indices.length + 6);
|
||||
for (i in 0...indices.length) ib[i] = indices[i];
|
||||
|
||||
var path = RenderPathDeferred.path;
|
||||
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;
|
||||
var layer = Context.layer;
|
||||
|
||||
untyped Krom.raytraceInit(
|
||||
shader.bytes.getData(), vb.buffer, ib.buffer, layer.texpaint.width, layer.texpaint.height,
|
||||
baketex0.renderTarget_, baketex1.renderTarget_, baketex2.renderTarget_,
|
||||
savedEnvmap.texture_);
|
||||
});
|
||||
}
|
||||
|
||||
public static function commandsBake() {
|
||||
if (!ready) { ready = true; initBake(); return; }
|
||||
f32[0] = frame;
|
||||
frame += 1.0;
|
||||
|
||||
var path = RenderPathDeferred.path;
|
||||
var baketex2 = path.renderTargets.get("baketex2").image;
|
||||
|
||||
untyped Krom.raytraceDispatchRays(baketex2.renderTarget_, f32.buffer);
|
||||
|
||||
Context.ddirty = 1;
|
||||
// Context.ddirty--;
|
||||
Context.pdirty--;
|
||||
Context.rdirty--;
|
||||
}
|
||||
}
|
||||
|
||||
#end
|
||||
|
||||
Reference in New Issue
Block a user