#include "Lighting/SkyLight.h" #include "Algorithm/BSDF.h" #include "Algorithm/RayIntersection.h" #include "Material/Material.h" vec3s evaluate_bsdf_const_sky(const void* data, const light_shading_context_t* context, sobol_state_t* sobol_state) { const constant_sky_data_t sky_data = *(const constant_sky_data_t*)data; if (context == NULL) { return sky_data.color; // No context, return the sky color directly. } vec3s wi = random_cosine_direction(context->normal, sobol_state); float pdf = pdf_cosine_weighted_hemisphere(context->normal, wi); ray_t shadow_ray = { .origin = glms_vec3_add(context->hit_point, glms_vec3_scale(context->normal, 0.001f)), .direction = wi, }; hit_result_t shadow_hit = ray_intersect_any(context->triangles, shadow_ray); if (shadow_hit.hit) { return glms_vec3_zero(); // Skip if the ray hits something } shading_context_t shading_context = { .normal = context->normal, .wi = wi, .wo = glms_vec3_negate(context->wo) }; vec3s bsdf = evaluate_material_bsdf(context->material, &shading_context); bsdf = glms_vec3_mul(bsdf, sky_data.color); float cos_theta = fmaxf(glms_vec3_dot(wi, context->normal), 0.0f); float pdf_bsdf = sample_material_bsdf_pdf(context->material, shading_context.normal, shading_context.wo, shading_context.wi); float weight = power_heuristic(pdf, pdf_bsdf); vec3s env_contrib = glms_vec3_scale(glms_vec3_mul(context->throughput, bsdf), cos_theta / pdf); return glms_vec3_scale(env_contrib, weight); }