Update AOV support, ray intersection logic, and README
Added: - AOV support for normals, albedo, and depth marked as completed. - New function `normal_unpack` in `BSDF.h`. - New field `esp` in `ray_t` structure in `RayIntersection.h`. Changed: - Updated `normal_ts_to_ws` to accept an additional parameter. - Refactored `weight_nee_light` for clarity. - Modified `RAY_EPSILON` for improved precision. - Updated `path_output` structure to include a `normal` field. - Normalized unpacked normal vector in `normal_unpack` function. - Updated `path_trace` to use closest hit ray intersection. - Updated `render_aov` to utilize closest hit logic. - Modified `ray_create` to initialize `esp` based on ray origin. - Improved accuracy in `offset_ray_origin` calculations. - Updated ray intersection logic in `ray_intersect_triangle` and `ray_intersect_aabb` to include epsilon checks. - Updated `evaluate_bsdf_directional` and `evaluate_bsdf_const_sky` for shadow rays. - Adjusted `sample_bsdf_simple_lit` for incoming light direction calculations. - Enhanced `render_pixel` to manage AOV flags effectively. - Changed camera rotation and light intensity in `scene_setup`. - Simplified texture loading by removing unnecessary sRGB conversion. Modified: - Several binary image files have been updated.
This commit is contained in:
@@ -19,13 +19,15 @@ static void get_surface_data(const shading_context_t* context, const void* prope
|
||||
data_out->albedo = glms_vec3_mul(data_out->albedo, glms_vec3(texture_sample(albedo_texture, context->uv.x, context->uv.y)));
|
||||
}
|
||||
|
||||
// NOTE: Currently normal map will produce lots of fireflies, need to be fixed.
|
||||
// Not sure is it because of the quality of the normal map or the algorithm itself.
|
||||
data_out->normal = context->normal;
|
||||
const texture_t* normal_texture = get_texture(context->textures, prop->normal_texture);
|
||||
if (normal_texture != NULL && normal_texture->data != NULL)
|
||||
{
|
||||
vec3s normal_sample = glms_vec3(texture_sample(normal_texture, context->uv.x, context->uv.y));
|
||||
normal_sample = normal_unpack(normal_sample);
|
||||
data_out->normal = glms_vec3_add(data_out->normal, normal_ts_to_ws(normal_sample, context->tangent));
|
||||
data_out->normal = normal_ts_to_ws(normal_sample, context->normal, context->tangent);
|
||||
}
|
||||
|
||||
data_out->roughness = prop->roughness;
|
||||
@@ -54,6 +56,7 @@ static vec3s sample_bsdf_simple_lit(const shading_context_t* context, const surf
|
||||
vec3s f = fresnel_schlick_vec3(f0, cos_theta_0);
|
||||
float lum_f = (f.x + f.y + f.z) / 3.0f;
|
||||
|
||||
//float prob_specular = 0.0f;
|
||||
float prob_specular = glm_lerp(lum_f, 1.0f, surface_data->metallic);
|
||||
float prob_diffuse = (1.0f - surface_data->metallic) * (1.0f - lum_f); // Diffuse only for non-metals, reduced by reflection
|
||||
float total_prob = prob_diffuse + prob_specular;
|
||||
@@ -110,8 +113,8 @@ static vec3s sample_bsdf_simple_lit(const shading_context_t* context, const surf
|
||||
h_ws = glms_vec3_add(h_ws, scaled_n);
|
||||
h_ws = glms_vec3_normalize(h_ws);
|
||||
|
||||
// wi is simple now, just reflect wo around normal
|
||||
wi = glms_vec3_reflect(glms_vec3_negate(L), h_ws);
|
||||
// wi is simple now, just reflect L around normal
|
||||
wi = glms_vec3_reflect(L, h_ws);
|
||||
}
|
||||
|
||||
// Final check to ensure wi is in the correct hemisphere
|
||||
@@ -139,7 +142,7 @@ static float sample_bsdf_pdf_simple_lit(const shading_context_t* context, const
|
||||
vec3s L = glms_vec3_negate(context->wo);
|
||||
|
||||
vec3s f0 = glms_vec3_lerp(DIELECTRIC_REFLECTIVE, surface_data->albedo, surface_data->metallic);
|
||||
float cos_theta_o = fmaxf(glms_vec3_dot(context->normal, L), 0.0f); // Use 'o' for outgoing (wo)
|
||||
float cos_theta_o = fmaxf(glms_vec3_dot(surface_data->normal, L), 0.0f); // Use 'o' for outgoing (wo)
|
||||
float F = glms_vec3_max(fresnel_schlick_vec3(f0, cos_theta_o));
|
||||
|
||||
float prob_specular = glm_lerp(F, 1.0f, surface_data->metallic);
|
||||
@@ -153,11 +156,10 @@ static float sample_bsdf_pdf_simple_lit(const shading_context_t* context, const
|
||||
prob_diffuse /= total_prob;
|
||||
prob_specular /= total_prob;
|
||||
|
||||
float pdf_diff = pdf_cosine_weighted_hemisphere(context->normal, wi);
|
||||
float pdf_diff = pdf_cosine_weighted_hemisphere(surface_data->normal, wi);
|
||||
float diffuse_pdf_component = prob_diffuse * pdf_diff;
|
||||
|
||||
// When computing specular PDF, L is the wi and wi is the view direction
|
||||
float pdf_spec = pdf_blinn_phong_lobe(context->normal, L, wi, surface_data->roughness);
|
||||
float pdf_spec = pdf_blinn_phong_lobe(surface_data->normal, wi, L, surface_data->roughness);
|
||||
float specular_pdf_component = prob_specular * pdf_spec;
|
||||
|
||||
return diffuse_pdf_component + specular_pdf_component;
|
||||
@@ -231,7 +233,8 @@ path_output simple_lit_render_loop(const shading_context_t* properties, const sh
|
||||
if (light_output.state == PS_NORMAL)
|
||||
{
|
||||
vec3s bsdf_dir_light = evaluate_bsdf_simple_lit(context, &surface_data, light_output.wi);
|
||||
vec3s light_contribute = glms_vec3_mul(light_output.direct_lighting, bsdf_dir_light);
|
||||
float pdf_bsdf = sample_bsdf_pdf_simple_lit(context, &surface_data, light_output.wi);
|
||||
vec3s light_contribute = weight_nee_light(bsdf_dir_light, light_output.direct_lighting, pdf_bsdf, light_output.pdf);
|
||||
output.direct_lighting = glms_vec3_add(output.direct_lighting, light_contribute);
|
||||
}
|
||||
}
|
||||
@@ -254,8 +257,9 @@ path_output simple_lit_render_loop(const shading_context_t* properties, const sh
|
||||
}
|
||||
|
||||
vec3s bsdf = evaluate_bsdf_simple_lit(context, &surface_data, output.wi);
|
||||
float cos_theta = fmaxf(0.0f, glms_vec3_dot(output.wi, context->normal));
|
||||
float cos_theta = fmaxf(0.0f, glms_vec3_dot(output.wi, surface_data.normal));
|
||||
|
||||
output.normal = surface_data.normal;
|
||||
output.bsdf = glms_vec3_scale(bsdf, cos_theta / output.pdf);
|
||||
output.state = PS_NORMAL;
|
||||
return output;
|
||||
|
||||
Reference in New Issue
Block a user