Simple GPU Path Tracing, Part 7.1 : Refractive material
- Simple GPU Path Tracing : Introduction
- Simple GPU Path Tracing, Part. 1 : Project Setup
- Simple GPU Path Tracing, Part. 1.1 : Adding a cuda backend to the project
- Simple GPU Path Tracing, Part. 2.0 : Scene Representation
- Simple GPU Path Tracing, Part. 2.1 : Acceleration structure
- Simple GPU Path Tracing, Part. 3.0 : Path Tracing Basics
- Simple GPU Path Tracing, Part. 3.1 : Matte Material
- Simple GPU Path Tracing, Part. 3.2 : Physically Based Material
- Simple GPU Path Tracing, Part. 3.4 : Small Improvements, Camera and wrap up
- Simple GPU Path Tracing, Part. 4.0 : Mesh Loading
- Simple GPU Path Tracing, Part. 4.1 : Textures
- Simple GPU Path Tracing, Part. 4.2 : Normal Mapping & GLTF Textures
- Simple GPU Path Tracing, Part. 5.0 : Sampling lights
- Simple GPU Path Tracing, Part 6 : GUI
- Simple GPU Path Tracing, Part 7.0 : Transparency
- Simple GPU Path Tracing, Part 7.1 : Volumetric materials
- Simple GPU Path Tracing, Part 7.2 : Refractive material
- Simple GPU Path Tracing, Part 8 : Denoising
- Simple GPU Path Tracing, Part 9 : Environment Lighting
- Simple GPU Path Tracing, Part 10 : Little Optimizations
- Simple GPU Path Tracing, Part 11 : Multiple Importance Sampling
So we now have a good set up for volumetric rendering in our path tracer. We have implemented a simple volume material with no surface. Now, we can implement another type of volumetric material that does have a surface, meaning the light can either reflect from it, or scatter inside.
Here's the commit for this post.
We will again rely heavily on the famous paper by Walter et al. that we've already used before in our physically based BRDF implementation.
Let's create a new material type, we'll call it glass material, as it's a material that we will see through, but that still has a surface.
And we'll set our small box to use this material :
We don't have to add other parameters to the material struct, as we can use all of the existing ones for describing how light reflects from a surface, and how it scatters into it.
So we can jump straight in our implementation!
in EvalMaterial, we'll have to calculate the density for glass materials too :
we also have to change the IsVolumetric function to account for this new material :
Then, we'll have to write the 3 usual functions for new materials : SampleBSDFCos, SampleBSDFCosPDF, and EvalBSDFCos.
First, let's look at SampleGlass(). When we generate the next direction for the ray, we either want the ray to be reflected off the surface, or scattered inside. As we've seen before, the portion of light that is reflected is dictated by the fresnel equations. Here, we will not use the Schlick approximation anymore, but rather the dielectric Fresnel formulas :
where n_1 and n_2 are the indices of refraction of the 2 materials (Typically, n1 is the air, and n2 is the material). the angle theta is calculated with Snell's law, using the refract function in glsl.
Here's the implementation :
Now let's see how EvalGlass works :
So we first check if we're entering the surface, by checking the angle between the normal of the surface and the outgoing direction.
We see that if we're entering, o and n have an angle < 90deg, which means their dot product is > 1. If the ray is going out, o and n have a angle > 90deg, which means their dot product is < 1.
Then, depending on whether we're entering or not, we'll use the Fresnel function with the IOR of the surface, or its inverse if we're going out.
Then, based on the result of the Fresnel term, if the ray is reflected, we use the reflect() function of glsl. otherwise, we use the refract() function.
Cool, now we have the next ray direction after hitting a glass surface. Next, let's see how we compute the bsdf of such a surface. Again, there will be two distinct cases in the EvalGlass function.
the if statement checks if the ray is exiting from the surface (No matter if it's being reflected, or if the ray is exiting the surface after scattering inside).
If the ray is entering / exiting the shape, we calculate the brdf as usual with the PBR equations.
Otherwise, the ray is being refracted inside the shape after hitting the surface, in which case we have to use the refraction term of the BSDF, which is explained in the paper, equation 21 :
That's quite a complicated equation ! But here's the implementation, not too bad :
Okay, now what's left is the PDF calculation. The same condition applies here. If the ray is being reflected, we use the regular pbr pdf as before.
Otherwise, we'll use equation 17 from the same paper :
And we're done, amazing!
Here are some renders with that material :
Links
Next post : Simple GPU Path Tracing, Part 8 : Denoising
Commentaires
Enregistrer un commentaire