Added mip selection using ray differentials
This commit is contained in:
@@ -128,21 +128,37 @@ static float oren_nayar_eval(vec3s l, vec3s v, vec3s n, float roughness, float n
|
||||
|
||||
static void get_surface_data(const shading_context_t* context, const standard_lit_properties_t* properties, standard_lit_surface_data_t* data_out)
|
||||
{
|
||||
float camera_distance = glms_vec3_distance(context->camera_position, context->position);
|
||||
vec3s view = (context->camera_direction);
|
||||
// Use the ray cone width (footprint) instead of simple distance for mip selection
|
||||
float footprint = context->cone_width;
|
||||
float distance = glms_vec3_distance(context->camera_position, context->position);
|
||||
vec3s view = context->camera_direction;
|
||||
|
||||
// Fetch geometry data for LOD calculation
|
||||
const triangle_t* triangle = &context->triangles->buffer[context->triangle_id];
|
||||
texture_sample_context_t sample_context =
|
||||
{
|
||||
.view_direction = view,
|
||||
.normal = context->normal,
|
||||
.edge1 = glms_vec3_sub(triangle->vertices[1].position, triangle->vertices[0].position),
|
||||
.edge2 = glms_vec3_sub(triangle->vertices[2].position, triangle->vertices[0].position),
|
||||
.uv1 = glms_vec2_sub(triangle->vertices[1].uv, triangle->vertices[0].uv),
|
||||
.uv2 = glms_vec2_sub(triangle->vertices[2].uv, triangle->vertices[0].uv),
|
||||
.ray_width = footprint,
|
||||
.distance = distance
|
||||
};
|
||||
|
||||
data_out->albedo = properties->albedo;
|
||||
const texture_t* albedo_texture = get_texture(context->textures, properties->albedo_texture);
|
||||
if (albedo_texture != NULL && albedo_texture->data != NULL)
|
||||
{
|
||||
data_out->albedo = glms_vec3_mul(data_out->albedo, glms_vec3(texture_sample(albedo_texture, context->uv, view, context->normal, camera_distance)));
|
||||
data_out->albedo = glms_vec3_mul(data_out->albedo, glms_vec3(texture_sample(albedo_texture, &sample_context, context->uv)));
|
||||
}
|
||||
|
||||
data_out->normal = context->normal;
|
||||
const texture_t* normal_texture = get_texture(context->textures, properties->normal_texture);
|
||||
if (normal_texture != NULL && normal_texture->data != NULL)
|
||||
{
|
||||
vec3s normal_sample = glms_vec3(texture_sample(normal_texture, context->uv, view, context->normal, camera_distance));
|
||||
vec3s normal_sample = glms_vec3(texture_sample(normal_texture, &sample_context, context->uv));
|
||||
normal_sample = normal_unpack(normal_sample);
|
||||
data_out->normal = normal_ts_to_ws(normal_sample, context->normal, context->tangent);
|
||||
}
|
||||
@@ -153,14 +169,14 @@ static void get_surface_data(const shading_context_t* context, const standard_li
|
||||
const texture_t* roughness_texture = get_texture(context->textures, properties->roughness_texture);
|
||||
if (roughness_texture != NULL && roughness_texture->data != NULL)
|
||||
{
|
||||
data_out->roughness = data_out->roughness * texture_sample(roughness_texture, context->uv, view, context->normal, camera_distance).x;
|
||||
data_out->roughness = data_out->roughness * texture_sample(roughness_texture, &sample_context, context->uv).x;
|
||||
}
|
||||
|
||||
data_out->metallic = properties->metallic;
|
||||
const texture_t* metallic_texture = get_texture(context->textures, properties->metallic_texture);
|
||||
if (metallic_texture != NULL && metallic_texture->data != NULL)
|
||||
{
|
||||
data_out->metallic = data_out->metallic * texture_sample(metallic_texture, context->uv, view, context->normal, camera_distance).x;
|
||||
data_out->metallic = data_out->metallic * texture_sample(metallic_texture, &sample_context, context->uv).x;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,6 +407,10 @@ path_output standard_lit_render_loop(const standard_lit_properties_t* properties
|
||||
|
||||
// Throughput multiplier must be: (f * NoL) / pdf_total
|
||||
output.bsdf = glms_vec3_scale(spec_f, n_dot_l / pdf_gen);
|
||||
|
||||
// Propagate spread angle for ray cones
|
||||
// Heuristic: spread increases with roughness
|
||||
output.spread_angle = context->spread_angle + surface_data.roughness * 0.2f;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -420,6 +440,9 @@ path_output standard_lit_render_loop(const standard_lit_properties_t* properties
|
||||
vec3s kD = glms_vec3_scale(glms_vec3_sub(glms_vec3_one(), F_est), 1.0f - surface_data.metallic);
|
||||
float on = oren_nayar_eval(output.wi, V, surface_data.normal, surface_data.diffuse_roughness, n_dot_l, n_dot_v);
|
||||
|
||||
|
||||
// Diffuse bounce significantly increases spread (effectively resets or becomes very wide)
|
||||
output.spread_angle = context->spread_angle + 0.5f;
|
||||
vec3s diff_f = glms_vec3_scale(glms_vec3_mul(surface_data.albedo, kD), on);
|
||||
|
||||
// Throughput multiplier: (f * NoL) / pdf_total
|
||||
|
||||
Reference in New Issue
Block a user