-
Notifications
You must be signed in to change notification settings - Fork 1
Implement MIS into the PT #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| // Use emissive only on the first ray (coming from the camera) | ||
| if ray_t_min == 0.0 { radiance = ray_hit.material.emissive; } | ||
| var mis_weight = 1.0; | ||
| if !is_perfectly_specular { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does the bounce being a perfectly specular reflection matter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BSDF PDF sampling will then return 0.0 as the pdf, which, if p_light is small, would lead to fireflies or inf/nans.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, we wanna disable MIS for dirac delta functions, so it might be a good idea to special-case the BRDF lobe MIS for perfect specular reflections too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you might want to modify the mix function so that 0 roughness = always selects specular.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't do that, we still need to select diffuse if metallic is not 1, I just added a special case if statement at the top.
| ray_origin = ray_hit.world_position; | ||
| ray_t_min = RAY_T_MIN; | ||
| p_bounce = next_bounce.pdf; | ||
| is_perfectly_specular = ray_hit.material.roughness < 0.0001 && ray_hit.material.metallic > 0.9999; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we call this something like bounce_was_perfect_reflection?
| fn importance_sample_next_bounce(wo: vec3<f32>, ray_hit: ResolvedRayHitFull, rng: ptr<function, u32>) -> NextBounce { | ||
| let diffuse_weight = 1.0 - ray_hit.material.metallic; | ||
| let specular_weight = ray_hit.material.metallic; | ||
| let diffuse_weight = mix(mix(0.4f, 0.9f, ray_hit.material.roughness), 0.f, ray_hit.material.metallic); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Theoretically the best way to do this would be sampling a lobe based on fresnel, but I felt like keeping it simple. This is good too.
Did you want to use roughness, or linear roughness here though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not a very good way to importance sample, might as well try perceptual roughness if that is better.
| vertex_buffer_offset: vertex_slice.range.start, | ||
| index_buffer_id, | ||
| index_buffer_offset: index_slice.range.start, | ||
| triangle_count: (index_slice.range.len() / 3) as u32, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't love adding this extra field, it's now bigger than 128 bits :(
And the triangle count already exists in the light source structure, it's just you need this for ray traces, since your not directly sampling the lights. Hmm. Lets talk about this over discord more.
No description provided.