Add HDR files and improve light handling
Added three binary files: `golden_gate_hills_1k.hdr`, `rogland_sunset_1k.hdr`, and `studio_small_03_1k.hdr`. Added a new inline function `weight_nee_light` in `BSDF.h` to compute the weighted contribution of light based on the next event estimation (NEE). Added a new function pointer type `sky_free_f` in `Light.h` for freeing sky light data. Added a new structure `hdr_sky_data_t` in `SkyLight.h` to hold HDR sky data, including texture and intensity. Changed the `RAY_EPSILON` definition in `Common.h` to a new value. Changed the `light_collection_free` function in `Light.h` to include freeing sky light data if it exists. Changed the `sky_create_hdr_sky` function in `SkyLight.h` to initialize HDR sky data and compute marginal and conditional distributions. Changed the `texture_load` function in `Texture.h` to accept a `stride` parameter for different texture formats. Changed the `evaluate_bsdf_directional` function in `LightEvaluation.c` to handle light intensity checks. Changed the `evaluate_bsdf_const_sky` function in `SkyLight.c` to use a pointer for sky data and added checks for intensity. Removed TODO comments related to handling triangle and material removal in `Triangle.h` and `Light.h`. Removed the old `weight_sky_light` function in `SkyLight.h` and replaced it with the new `weight_nee_light` function. Updated the `scene_setup` function in `main.c` to change camera position and light direction, and to load HDR textures. Increased the sample count in the rendering configuration in `main.c` for better quality rendering.
This commit is contained in:
@@ -6,6 +6,12 @@ path_output evaluate_bsdf_directional(directional_light_t light, const light_sha
|
||||
{
|
||||
path_output output = {0.0f};
|
||||
output.state = TERMINATE;
|
||||
output.pdf = 1.0f;
|
||||
|
||||
if (light.intensity <= 0.0f)
|
||||
{
|
||||
return output;
|
||||
}
|
||||
|
||||
float angular_radius = glm_rad(light.angular_diameter / 2.0f);
|
||||
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
#include "Lighting/SkyLight.h"
|
||||
#include "Algorithm/RayIntersection.h"
|
||||
#include "Common.h"
|
||||
|
||||
path_output evaluate_bsdf_const_sky(const void* data, const light_shading_context_t* context, vec3s throughput, uint32_t sample_index)
|
||||
{
|
||||
constant_sky_data_t sky_data = *(const constant_sky_data_t*)data;
|
||||
vec3s sky_color = glms_vec3_scale(sky_data.color, sky_data.intensity);
|
||||
const constant_sky_data_t* sky_data = (const constant_sky_data_t*)data;
|
||||
|
||||
path_output output = {0.0f};
|
||||
output.state = TERMINATE;
|
||||
|
||||
if (context == NULL)
|
||||
if (sky_data->intensity <= 0.0f)
|
||||
{
|
||||
output.direct_lighting = glms_vec3_mul(sky_color, throughput);
|
||||
return output;
|
||||
}
|
||||
|
||||
vec3s sky_light = glms_vec3_scale(sky_data->color, sky_data->intensity);
|
||||
|
||||
|
||||
if (context->bvh_tree == NULL)
|
||||
{
|
||||
output.direct_lighting = glms_vec3_mul(sky_light, throughput);
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -19,7 +26,6 @@ path_output evaluate_bsdf_const_sky(const void* data, const light_shading_contex
|
||||
uint16_t d2 = sobol_get_dimension(context->bounce_depth, PRNG_LIGHT_V);
|
||||
|
||||
vec3s wi = random_uniform_cdf_direction(context->normal, sample_index, d1, d2);
|
||||
float pdf = 1.0f / (4.0f * (float)M_PI);
|
||||
|
||||
ray_t shadow_ray = ray_create(BIAS_RAY_ORIGION(context->hit_point, context->normal), wi);
|
||||
|
||||
@@ -32,7 +38,8 @@ path_output evaluate_bsdf_const_sky(const void* data, const light_shading_contex
|
||||
}
|
||||
|
||||
float cos_theta = fmaxf(glms_vec3_dot(wi, context->normal), 0.0f);
|
||||
output.direct_lighting = glms_vec3_scale(throughput, cos_theta / pdf);
|
||||
float pdf = 1.0f / (4.0f * (float)M_PI);
|
||||
output.direct_lighting = glms_vec3_scale(glms_vec3_mul(sky_light, throughput), cos_theta / pdf);
|
||||
|
||||
output.wi = wi;
|
||||
output.pdf = pdf;
|
||||
@@ -40,3 +47,94 @@ path_output evaluate_bsdf_const_sky(const void* data, const light_shading_contex
|
||||
return output;
|
||||
}
|
||||
|
||||
path_output evaluate_bsdf_hdr_sky(const void* data, const light_shading_context_t* context, vec3s throughput, uint32_t sample_index)
|
||||
{
|
||||
const hdr_sky_data_t* sky_data = (const hdr_sky_data_t*)data;
|
||||
|
||||
path_output output = {0.0f};
|
||||
output.state = TERMINATE;
|
||||
|
||||
if (sky_data->intensity <= 0.0f)
|
||||
{
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
if (context->bvh_tree == NULL)
|
||||
// if (true)
|
||||
{
|
||||
vec2s uv = direction_to_equirectangular(context->wo);
|
||||
vec4s sky_light = texture_sample(get_texture(context->textures, sky_data->texture), uv.x, uv.y);
|
||||
output.direct_lighting = glms_vec3_scale(glms_vec3_mul(glms_vec3(sky_light), throughput), sky_data->intensity);
|
||||
output.pdf = 0.0f;
|
||||
return output;
|
||||
}
|
||||
|
||||
float u0 = random_float();
|
||||
uint32_t i = 0;
|
||||
while (i < sky_data->height && u0 > sky_data->marginal[i])
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
float u1 = random_float();
|
||||
uint32_t j = 0;
|
||||
while (j < sky_data->width && u1 > sky_data->conditional[i * sky_data->width + j])
|
||||
{
|
||||
j++;
|
||||
}
|
||||
|
||||
float theta = (i - 0.5f) / sky_data->height * (float)M_PI;
|
||||
float phi = (j - 0.5f) / sky_data->width * (2.0f * (float)M_PI);
|
||||
|
||||
float sin_theta = sinf(theta);
|
||||
float cos_theta = cosf(theta);
|
||||
float sin_phi = sinf(phi);
|
||||
float cos_phi = cosf(phi);
|
||||
|
||||
float domega = (2.0f * (float)M_PI / sky_data->width) * ((float)M_PI / sky_data->height) * sin_theta;
|
||||
float w_ij = (sky_data->marginal[i] - (i > 0 ? sky_data->marginal[i - 1] : 0.0f)) *
|
||||
(sky_data->conditional[i * sky_data->width + j] - (j > 0 ? sky_data->conditional[i * sky_data->width + j - 1] : 0.0f));
|
||||
float pdf = w_ij / domega;
|
||||
|
||||
vec3s wi = (vec3s)
|
||||
{
|
||||
cos_theta * cos_phi,
|
||||
sin_theta,
|
||||
cos_theta * sin_phi,
|
||||
};
|
||||
|
||||
ray_t shadow_ray = ray_create(BIAS_RAY_ORIGION(context->hit_point, context->normal), wi);
|
||||
|
||||
float closest = FLT_MAX;
|
||||
hit_result_t shadow_hit = {1};
|
||||
ray_intersect_bvh(&shadow_ray, context->bvh_tree->nodes, context->bvh_tree->primitive_indices, context->bvh_tree->triangles, 0, &closest, &shadow_hit);
|
||||
if (shadow_hit.hit)
|
||||
{
|
||||
return output;
|
||||
}
|
||||
|
||||
vec2s uv = direction_to_equirectangular(wi);
|
||||
|
||||
const texture_t* hdri = get_texture(context->textures, sky_data->texture);
|
||||
vec4s pixel = texture_sample(hdri, uv.x, uv.y);
|
||||
vec3s sky_light = glms_vec3_scale(glms_vec3(pixel), sky_data->intensity);
|
||||
|
||||
float angle = fmaxf(glms_vec3_dot(wi, context->normal), 0.0f);
|
||||
output.direct_lighting = glms_vec3_scale(glms_vec3_mul(sky_light, throughput), angle / pdf);
|
||||
output.direct_lighting = glms_vec3_clamp(output.direct_lighting, 0.0f, 1000.0f);
|
||||
|
||||
output.wi = wi;
|
||||
output.pdf = pdf;
|
||||
output.state = NORMAL;
|
||||
return output;
|
||||
}
|
||||
|
||||
void hdr_sky_free(hdr_sky_data_t* data)
|
||||
{
|
||||
free(data->marginal);
|
||||
free(data->conditional);
|
||||
|
||||
data->marginal = NULL;
|
||||
data->conditional = NULL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user