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:
101
source/Material/Material.c
Normal file
101
source/Material/Material.c
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "Material/Material.h"
|
||||
|
||||
bool material_collection_init(size_t size, material_collection_t* materials)
|
||||
{
|
||||
if (size > 254)
|
||||
{
|
||||
size = 254; // Limit the count to 254 to fit in a uint8_t
|
||||
}
|
||||
|
||||
material_collection_t temp = {0};
|
||||
temp.buffer = (material_t*)malloc(size * sizeof(material_t));
|
||||
if (temp.buffer == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
temp.size = (uint8_t)size;
|
||||
temp.count = 0;
|
||||
*materials = temp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void material_collection_resize(material_collection_t* materials, size_t size)
|
||||
{
|
||||
if (size > 254)
|
||||
{
|
||||
size = 254; // Limit the count to 254 to fit in a uint8_t
|
||||
}
|
||||
|
||||
material_t* temp = (material_t*)realloc(materials->buffer, size * sizeof(material_t));
|
||||
if (temp != NULL)
|
||||
{
|
||||
materials->buffer = temp;
|
||||
materials->size = (uint8_t)size;
|
||||
}
|
||||
}
|
||||
|
||||
void material_collection_free(material_collection_t* materials)
|
||||
{
|
||||
if (materials->buffer != NULL)
|
||||
{
|
||||
free(materials->buffer);
|
||||
materials->buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
material_entity_t material_create(sample_bsdf_f sample, sample_bsdf_pdf_f sample_pdf, evaluate_bsdf_f evaluate, void* data, material_collection_t* collection)
|
||||
{
|
||||
material_t material = {0};
|
||||
|
||||
if (collection->count >= collection->size)
|
||||
{
|
||||
material_collection_resize(collection, collection->size * 2);
|
||||
}
|
||||
|
||||
material.sample_bsdf = sample;
|
||||
material.sample_bsdf_pdf = sample_pdf;
|
||||
material.evaluate_bsdf = evaluate;
|
||||
material.data = data;
|
||||
|
||||
material_entity_t entity = {.id = collection->count};
|
||||
|
||||
collection->buffer[collection->count] = material;
|
||||
collection->count++;
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
vec3s sample_material_bsdf(const material_t* material, vec3s normal, vec3s wo, uint32_t sample_index, uint32_t bounce, float* pdf_out)
|
||||
{
|
||||
vec3s wi = glms_vec3_zero();
|
||||
if (material->sample_bsdf != NULL)
|
||||
{
|
||||
wi = material->sample_bsdf(material->data, normal, wo, sample_index, bounce, pdf_out);
|
||||
}
|
||||
|
||||
return wi;
|
||||
}
|
||||
|
||||
float sample_material_bsdf_pdf(const material_t* material, vec3s normal, vec3s wo, vec3s wi)
|
||||
{
|
||||
float pdf = 0.0f;
|
||||
if (material->sample_bsdf_pdf != NULL)
|
||||
{
|
||||
pdf = material->sample_bsdf_pdf(material->data, normal, wo, wi);
|
||||
}
|
||||
|
||||
return pdf;
|
||||
}
|
||||
|
||||
vec3s evaluate_material_bsdf(const material_t* material, const shading_context_t* context)
|
||||
{
|
||||
vec3s bsdf_color = glms_vec3_zero();
|
||||
if (material->evaluate_bsdf != NULL)
|
||||
{
|
||||
bsdf_color = material->evaluate_bsdf(context, material->data);
|
||||
}
|
||||
|
||||
return bsdf_color;
|
||||
}
|
||||
@@ -1,22 +1,24 @@
|
||||
#include "Material/SimpleLit.h"
|
||||
#include "Algorithm/BSDF.h"
|
||||
#include "Algorithm/Sobol.h"
|
||||
#include <float.h>
|
||||
|
||||
static float DIELECTRIC_REFLECTIVE_F0 = 0.04f; // Standard dielectric reflectivity coef at incident angle (= 4%)
|
||||
static vec3s DIELECTRIC_REFLECTIVE = {0.04f, 0.04f, 0.04f}; // Standard dielectric reflectivity coef at incident angle (= 4%)
|
||||
|
||||
// Simple lit, but keep it unbiased as much as possible
|
||||
vec3s sample_bsdf_simple_lit(const void* data, vec3s normal, vec3s wo, sobol_state_t* sobol_state, float* pdf_out)
|
||||
vec3s sample_bsdf_simple_lit(const void* data, vec3s normal, vec3s wo, uint32_t sample_index, uint32_t bounce, float* pdf_out)
|
||||
{
|
||||
simple_lit_data_t shading_data = *(const simple_lit_data_t*)data;
|
||||
|
||||
//TODO: having a bsdf data struct to avoid recomputing the same thing in both sample and evaluate
|
||||
vec3s f0 = glms_vec3_lerp(DIELECTRIC_REFLECTIVE, shading_data.albedo, shading_data.metallic);
|
||||
float cos_theta_0 = fmaxf(glms_vec3_dot(normal, wo), 0.0f);
|
||||
float F = glms_vec3_max(fresnel_schlick_vec3(f0, cos_theta_0)); // We use the max component of the Fresnel term for simplicity
|
||||
vec3s f = fresnel_schlick_vec3(f0, cos_theta_0);
|
||||
float lum_f = (f.x + f.y + f.z) / 3.0f;
|
||||
|
||||
float prob_specular = glm_lerp(F, 1.0f, shading_data.metallic);
|
||||
float prob_diffuse = (1.0f - shading_data.metallic) * (1.0f - F); // Diffuse only for non-metals, reduced by reflection
|
||||
float prob_specular = glm_lerp(lum_f, 1.0f, shading_data.metallic);
|
||||
float prob_diffuse = (1.0f - shading_data.metallic) * (1.0f - lum_f); // Diffuse only for non-metals, reduced by reflection
|
||||
float total_prob = prob_diffuse + prob_specular;
|
||||
if (total_prob < FLT_EPSILON)
|
||||
{
|
||||
@@ -30,10 +32,13 @@ vec3s sample_bsdf_simple_lit(const void* data, vec3s normal, vec3s wo, sobol_sta
|
||||
prob_specular /= total_prob;
|
||||
|
||||
vec3s wi;
|
||||
float lob_sample = sobol_sample(sample_index, sobol_get_dimension(bounce, PRNG_BSDF));
|
||||
uint16_t d1 = sobol_get_dimension(bounce, PRNG_BSDF_U);
|
||||
uint16_t d2 = sobol_get_dimension(bounce, PRNG_BSDF_V);
|
||||
|
||||
if (random_float() < prob_diffuse) // Diffuse Lobe
|
||||
if (lob_sample < prob_diffuse) // Diffuse Lobe
|
||||
{
|
||||
wi = random_cosine_direction(normal, sobol_state);
|
||||
wi = random_cosine_direction(normal, sample_index, d1, d2);
|
||||
}
|
||||
else // Specular Lobe
|
||||
{
|
||||
@@ -42,9 +47,13 @@ vec3s sample_bsdf_simple_lit(const void* data, vec3s normal, vec3s wo, sobol_sta
|
||||
// A common simplification involves sampling spherical coordinates(theta and phi angles) related to normal such that cose(theta) is distributed according to the Blinn-Phong distribution
|
||||
// We can use a inversion sampling where cos(theta) = powf(random_float(), 1.0f / (specular_exponent + 1.0f)) and phi = 2 * PI * random_float()
|
||||
float specular_exponent = roughness_to_blinn_phong_specular_exponent(shading_data.roughness);
|
||||
float theta = acosf(powf(sobol_next(sobol_state), 1.0f / (specular_exponent + 1.0f)));
|
||||
float phi = 2.0f * (float)M_PI * sobol_next(sobol_state);
|
||||
vec3s h_ts = (vec3s){
|
||||
|
||||
float theta = acosf(powf(sobol_sample(sample_index, d1), 1.0f / (specular_exponent + 1.0f)));
|
||||
float phi = 2.0f * (float)M_PI * sobol_sample(sample_index, d2);
|
||||
// float theta = acosf(powf(random_float(), 1.0f / (specular_exponent + 1.0f)));
|
||||
// float phi = 2.0f * (float)M_PI * random_float();
|
||||
vec3s h_ts = (vec3s)
|
||||
{
|
||||
sinf(theta) * cosf(phi),
|
||||
sinf(theta) * sinf(phi),
|
||||
cosf(theta)
|
||||
@@ -62,7 +71,7 @@ vec3s sample_bsdf_simple_lit(const void* data, vec3s normal, vec3s wo, sobol_sta
|
||||
vec3s h_ws;
|
||||
h_ws = glms_vec3_add(scaled_u, scaled_v);
|
||||
h_ws = glms_vec3_add(h_ws, scaled_n);
|
||||
h_ws = glms_vec3_normalize(h_ws); // Normalize the half-vector
|
||||
h_ws = glms_vec3_normalize(h_ws);
|
||||
|
||||
// wi is simple now, just reflect wo around normal
|
||||
wi = glms_vec3_reflect(glms_vec3_negate(wo), h_ws);
|
||||
|
||||
Reference in New Issue
Block a user