Update project structure and improve performance

Added new files for BVH, AABB, and Debug functionalities.
Added new utility functions in Common.h.
Added gamma correction function in PostProcessing.h.
Changed the return type of path_trace to vec4s for alpha blending.
Changed BSDF function signatures to include sample index and bounce.
Changed the BSDF.h to replace inline functions with declarations.
Changed the Light and SkyLight evaluation functions to include throughput and sample index.
Changed the sphere creation function in GeometryUtilities.h for better quality.
Changed the scene structure to include a BVH tree for improved ray intersection.
Changed the scene initialization parameters for better performance.
Created new Debug functions for ray intersection counting.
Created new functions for triangle collection management in Triangle.c.
Improved pixel updating logic in Window.c.
Improved ray intersection performance with new BVH implementation.
Removed unused includes from Common.h.
Removed old library linking methods in CMakeLists.txt.
This commit is contained in:
2025-04-21 15:56:19 +09:00
parent 1162575545
commit 6800810369
36 changed files with 1590 additions and 579 deletions

View File

@@ -1,33 +1,32 @@
#include "Algorithm/PathTracing.h"
#include "Algorithm/RayIntersection.h"
#include "Algorithm/BSDF.h"
#include "Algorithm/Sobol.h"
#include "Lighting/LightEvaluation.h"
// TODO: Implement a faster methods like BVH, KD-Tree or uniform grid acceleration
// TODO: Split the diffuse and specular into different Monte Carlo, so we can decide the sample count for each one
vec3s path_trace(const scene_t* scene, ray_t ray, uint32_t sample_index, int max_depth)
vec4s path_trace(const scene_t* scene, ray_t ray, uint32_t sample_index, uint16_t max_depth)
{
const triangle_collection_t* triangles = &scene->triangles;
const bvh_tree_t* bvh_tree = &scene->bvh_tree;
const material_collection_t* materials = &scene->materials;
const light_collection_t* lights = &scene->lights;
vec3s accumulated_color = glms_vec3_zero();
vec4s accumulated_color = glms_vec4_zero();
vec3s throughput = glms_vec3_one();
ray_t active_ray = ray;
vec3s prev_normal = glms_vec3_zero();
float pdf_bsdf = 1.0f; // Even though pdf_bsdf should be avaliable after the first bounce. For seafty, we set it to 1.0f for the first iteration.
sobol_state_t sobol_state = {sample_index, 0};
float pdf_bsdf = 1.0f;
int depth = 0;
uint16_t depth = 0;
while (depth < max_depth)
{
hit_result_t closest_hit = ray_intersect_closest(triangles, active_ray);
hit_result_t closest_hit = ray_intersect_scene(active_ray, scene);
if (!closest_hit.hit)
{
vec3s sky_light = evaluate_bsdf_sky(scene, NULL, &sobol_state);
vec3s sky_light = evaluate_bsdf_sky(scene, NULL, throughput, sample_index);
if (depth > 0)
{
// Have to multiply the weight since we evaluate the sky at each bounce
@@ -35,21 +34,23 @@ vec3s path_trace(const scene_t* scene, ray_t ray, uint32_t sample_index, int
float weight = power_heuristic(pdf_bsdf, pdf_nee);
sky_light = glms_vec3_scale(sky_light, weight);
}
accumulated_color = glms_vec3_add(accumulated_color, sky_light); // TODO: Skybox
accumulated_color = glms_vec4_add(accumulated_color, glms_vec4(sky_light, 1.0f)); // TODO: Physical Skybox
break;
}
// Add the emission of the hit material to the accumulated color
material_t* hit_material = &materials->buffer[triangles->buffer[closest_hit.triangle_id].material_id];
vec3s emission = hit_material->emission;
accumulated_color = glms_vec3_add(accumulated_color, glms_vec3_mul(throughput, emission));
accumulated_color = glms_vec4_add(accumulated_color, glms_vec4(glms_vec3_mul(throughput, emission), 1.0f));
light_shading_context_t light_context = {
.normal = closest_hit.normal,
.hit_point = closest_hit.point,
.wo = active_ray.direction,
.throughput = throughput,
.triangles = triangles,
.bounce_depth = depth,
.bvh_tree = bvh_tree,
.material = hit_material
};
@@ -57,16 +58,16 @@ vec3s path_trace(const scene_t* scene, ray_t ray, uint32_t sample_index, int
// TODO: Implementing other light types.
for (uint32_t i = 0; i < lights->directional_light_count; i++)
{
vec3s l = evaluate_bsdf_directional(lights->directional_lights[i], &light_context, &sobol_state);
accumulated_color = glms_vec3_add(accumulated_color, l);
vec3s l = evaluate_bsdf_directional(lights->directional_lights[i], &light_context, throughput, sample_index);
accumulated_color = glms_vec4_add(accumulated_color, glms_vec4(l, 1.0f));
}
vec3s sky_light = evaluate_bsdf_sky(scene, &light_context, &sobol_state);
accumulated_color = glms_vec3_add(accumulated_color, sky_light);
vec3s sky_light = evaluate_bsdf_sky(scene, &light_context, throughput, sample_index);
accumulated_color = glms_vec4_add(accumulated_color, glms_vec4(sky_light, 1.0f));
// Bounce and prepare for the next iteration
vec3s wo = glms_vec3_negate(active_ray.direction); // We need to negate the direction of the incoming ray
vec3s wi = sample_material_bsdf(hit_material, closest_hit.normal, wo, &sobol_state, &pdf_bsdf);
vec3s wi = sample_material_bsdf(hit_material, closest_hit.normal, wo, sample_index, depth, &pdf_bsdf);
if (pdf_bsdf <= 0.0f)
{
break;
@@ -86,7 +87,9 @@ vec3s path_trace(const scene_t* scene, ray_t ray, uint32_t sample_index, int
if (depth > 2)
{
float q = fminf(glms_vec3_max(throughput), 0.95f);
if (random_float() > q)
float rr_sample = sobol_sample(sample_index, sobol_get_dimension(depth, PRNG_TERMINATE));
// float rr_sample = random_float();
if (rr_sample > q)
{
break; // Terminate the path
}
@@ -94,7 +97,7 @@ vec3s path_trace(const scene_t* scene, ray_t ray, uint32_t sample_index, int
throughput = glms_vec3_scale(throughput, 1.0f / q);
}
active_ray.origin = glms_vec3_add(closest_hit.point, glms_vec3_scale(closest_hit.normal, FLT_EPSILON));
active_ray.origin = glms_vec3_add(closest_hit.point, glms_vec3_scale(closest_hit.normal, 1.192092896e-04F));
active_ray.direction = wi;
prev_normal = closest_hit.normal;