Files
SimpleRayTracing/source/Lighting/LightEvaluation.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 = PS_TERMINATE;
output.pdf = 1.0f;
if (light.intensity <= 0.0f)
{
return output;
}
float angular_radius = glm_rad(light.angular_diameter * 0.5f);
uint32_t scramble = hash_position(context->position);
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, scramble);
float n_dot_l = glms_vec3_dot(context->normal, wi);
if (n_dot_l <= 0.0f)
{
return output;
}
ray_t shadow_ray = ray_create(offset_ray_origin(context->position, context->normal, context->wo), wi, 0.0f, 0.0f);
float closest = FLT_MAX;
hit_result_t shadow_hit = {0};
ray_intersect_bvh_any(&shadow_ray, context->bvh_tree->nodes, context->bvh_tree->primitive_indices, context->bvh_tree->triangles, 0, &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 = PS_SUCCESS;
return output;
}