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.
48 lines
1.6 KiB
C
48 lines
1.6 KiB
C
#include "Lighting/LightEvaluation.h"
|
|
#include "Algorithm/BSDF.h"
|
|
#include "Algorithm/RayIntersection.h"
|
|
|
|
path_output evaluate_bsdf_directional(directional_light_t light, const light_shading_context_t* context, vec3s throughput, uint32_t sample_index)
|
|
{
|
|
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);
|
|
|
|
uint16_t d1 = sobol_get_dimension(context->bounce_depth, PRNG_LIGHT_U);
|
|
uint16_t d2 = sobol_get_dimension(context->bounce_depth, PRNG_LIGHT_V);
|
|
|
|
vec3s wi = random_uniform_cdf_direction_angular(light.direction, sample_index, angular_radius, d1, d2);
|
|
|
|
float n_dot_l = glms_vec3_dot(context->normal, wi);
|
|
if (n_dot_l <= 0.0f)
|
|
{
|
|
return output;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
vec3s light_radiance = glms_vec3_scale(light.color, light.intensity);
|
|
vec3s light_contribute = glms_vec3_scale( throughput, fmaxf(0.0f, n_dot_l)); // we always assume pdf = 1.0f for directional light
|
|
|
|
output.direct_lighting = glms_vec3_mul(light_radiance, light_contribute);
|
|
output.wi = wi;
|
|
output.state = NORMAL;
|
|
return output;
|
|
}
|