From f8f8d3ba7d4eba79212e47d8fe9a961b35d40f11 Mon Sep 17 00:00:00 2001 From: Krzysztof Jakubowski Date: Sat, 19 Oct 2024 22:00:54 +0200 Subject: [PATCH] PathTracer: enabled simple AO in shader (#10) --- data/shaders/trace.glsl | 55 ++++++++++++++++++++++++----------------- src/lucid_app.cpp | 2 ++ src/path_tracer.cpp | 3 ++- src/path_tracer.h | 1 + 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/data/shaders/trace.glsl b/data/shaders/trace.glsl index b0e70ce..ead8d4b 100644 --- a/data/shaders/trace.glsl +++ b/data/shaders/trace.glsl @@ -22,6 +22,7 @@ layout(binding = 1) uniform config_ { PathTracerConfig u_config; }; layout(binding = 2, rgba8) uniform image2D g_raster_image; +layout(binding = 4) buffer buf04_ { uint g_indices[]; }; layout(binding = 5) buffer buf05_ { float g_vertices[]; }; layout(binding = 6) uniform accelerationStructureEXT g_accelStruct; @@ -44,6 +45,14 @@ vec3 getVertex(uint idx) { return vec3(g_vertices[idx * 3 + 0], g_vertices[idx * 3 + 1], g_vertices[idx * 3 + 2]); } +void getTriangleVertices(uint tri_id, out vec3 tri0, out vec3 tri1, out vec3 tri2) { + uint idx0 = g_indices[tri_id * 3 + 0], idx1 = g_indices[tri_id * 3 + 1], + idx2 = g_indices[tri_id * 3 + 2]; + tri0 = getVertex(idx0); + tri1 = getVertex(idx1); + tri2 = getVertex(idx2); +} + void getTriangleVectors(in vec3 tri0, in vec3 tri1, in vec3 tri2, out vec3 tangent, out vec3 normal, out vec3 binormal) { tangent = normalize(tri1 - tri0); @@ -72,6 +81,7 @@ TraceResult rayTraceAS(vec3 origin, vec3 dir) { if(rayQueryGetIntersectionTypeEXT(rq, true) != 0) { result.dist = rayQueryGetIntersectionTEXT(rq, true); result.tri_id = rayQueryGetIntersectionPrimitiveIndexEXT(rq, true); + // rayQueryGetIntersectionBarycentricsEXT } else { result.dist = MAX_ISECT_DIST; result.tri_id = INVALID_TRI_ID; @@ -94,7 +104,28 @@ void getScreenRay(ivec2 pixel_pos, out vec3 origin, out vec3 dir) { dir += vec3(0.0000001); // avoiding division by 0 } -//#define COMPUTE_AO +float computeAO(uint tri_id, vec3 hit_point) { + vec3 tri[3]; + getTriangleVertices(tri_id, tri[0], tri[1], tri[2]); + vec3 tri_vecs[3]; + getTriangleVectors(tri[0], tri[1], tri[2], tri_vecs[0], tri_vecs[1], tri_vecs[2]); + + const int dim_size = 4; + int hits = 0, total = (dim_size + 1) * (dim_size + 1); + + for(int x = 0; x <= dim_size; x++) + for(int y = 0; y <= dim_size; y++) { + vec2 pos = vec2(x, y) * (1.0 / dim_size); + vec3 hemi = uniformSampleHemisphere(pos); + vec3 dir = tri_vecs[0] * hemi[0] + tri_vecs[1] * hemi[2] + tri_vecs[2] * hemi[1]; + vec3 origin = hit_point + dir * 0.001; + TraceResult ao_hit = rayTraceAS(origin, dir); + if(ao_hit.dist > 0.05 && ao_hit.dist < 5.0 && ao_hit.tri_id != tri_id) + hits++; + } + + return max(0.0, (total - hits) / float(total) - 0.1) * (1.0 / 0.9); +} void traceBin() { ivec2 pixel_pos = ivec2(LIX & 31, LIX >> 5) + s_bin_pos; @@ -103,30 +134,10 @@ void traceBin() { TraceResult result = rayTraceAS(ray_origin, ray_dir); float ao_value = 1.0; - -#ifdef COMPUTE_AO if(result.dist < MAX_ISECT_DIST) { - vec3 tri_vecs[3]; - getTriangleVectors(result.tri_id, tri_vecs[0], tri_vecs[1], tri_vecs[2]); vec3 hit_point = ray_origin + ray_dir * result.dist; - - const int dim_size = 10; - int hits = 0, total = (dim_size + 1) * (dim_size + 1); - - for(int x = 0; x <= dim_size; x++) - for(int y = 0; y <= dim_size; y++) { - vec2 pos = vec2(x, y) * (1.0 / dim_size); - vec3 hemi = uniformSampleHemisphere(pos); - vec3 dir = tri_vecs[0] * hemi[0] + tri_vecs[1] * hemi[2] + tri_vecs[2] * hemi[1]; - vec3 origin = hit_point + dir * 0.00001; - TraceResult ao_hit = rayTraceAS(origin, dir); - if(ao_hit.dist > 0.0001 && ao_hit.dist < 0.5 && ao_hit.tri_id != result.tri_id) - hits++; - } - - ao_value = (total - hits) / float(total); + ao_value = computeAO(result.tri_id, hit_point); } -#endif vec3 vcolor = vec3(0.0); if(result.dist < MAX_ISECT_DIST) { diff --git a/src/lucid_app.cpp b/src/lucid_app.cpp index 7d126a3..2e04dde 100644 --- a/src/lucid_app.cpp +++ b/src/lucid_app.cpp @@ -236,6 +236,8 @@ Ex LucidApp::updateRenderer() { insertBack(used_shaders, m_pbr_renderer->shaderDefIds()); if(m_lucid_renderer) insertBack(used_shaders, m_lucid_renderer->shaderDefIds()); + if(m_path_tracer) + insertBack(used_shaders, m_path_tracer->shaderDefIds()); makeSortedUnique(used_shaders); if(setIntersection(used_shaders, update_list)) do_update = true; diff --git a/src/path_tracer.cpp b/src/path_tracer.cpp index 19da2c0..934f2c6 100644 --- a/src/path_tracer.cpp +++ b/src/path_tracer.cpp @@ -124,6 +124,7 @@ Ex<> PathTracer::updateScene(VulkanDevice &device, Scene &scene) { EX_PASS(VulkanAccelStruct::buildBottom(device, scene.verts.positions, scene.tris_ib)); VAccelStructInstance instance{blas, Matrix4::identity()}; m_accel_struct = EX_PASS(VulkanAccelStruct::buildTop(device, {instance})); + m_indices = scene.tris_ib; m_vertices = scene.verts.positions; // TODO: wait until AS is built? @@ -151,7 +152,7 @@ void PathTracer::render(const Context &ctx) { auto raster_image = swap_chain->acquiredImage(); ds.setStorageImage(2, raster_image, VImageLayout::general); - ds.set(5, m_vertices); + ds.set(4, m_indices, m_vertices); ds.set(6, m_accel_struct); auto sampler = ctx.device.getSampler(ctx.config.sampler_setup); diff --git a/src/path_tracer.h b/src/path_tracer.h index d73a80c..6afbd78 100644 --- a/src/path_tracer.h +++ b/src/path_tracer.h @@ -55,6 +55,7 @@ class PathTracer { VBufferSpan m_frame_config[num_frames]; VBufferSpan m_debug_buffer; + VBufferSpan m_indices; VBufferSpan m_vertices; PVAccelStruct m_accel_struct;