Simple GPU Path Tracing, Part 7.0 : Transparency
- 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
From the previous renders, we can see that we're lacking something on the front glass of our car : Transparency ! we should be able to see through this glass.
In this post, we will be implementing that.
Here's the commit for today's post.
Opacity
We want to have materials with opacity, meaning that we can see through them like the glass of the car for example.
To do that, let's add a field in the material struct, and in the materialPoint struct as well :
struct material
{
glm::vec3 Emission = {};
float Roughness = 0;
glm::vec3 Colour = {};
float Metallic = 0;
glm::vec2 Padding;
float MaterialType = 0;
float Opacity = 1;
int EmissionTexture = InvalidID;
int ColourTexture = InvalidID;
int RoughnessTexture = InvalidID;
int NormalTexture = InvalidID;
};
struct materialPoint
{
glm::vec3 Emission;
glm::vec3 Colour;
int MaterialType;
float Roughness, Metallic, Opacity;
};
then in the EvalMaterial function in PathTraceCode, we can fill in the materialPoint opacity value :
Point.Opacity = Material.Opacity * ColourTexture.w;
Note that we modulate the material opacity with the opacity read from the texture.
Next, we will be using that in the main loop :
The way it's going to work is quite simple : if an object is transparent, we want our ray to pass through it. But we don't want all the rays to pass through, otherwise the object would become invisible ! So we want some rays to pass through, and some rays to still interact with the object.
to do that, we generate a random number between 0 and 1 and compare it with the opacity. If the number is higher than the opacity value, we let the ray pass through :
What happens effectively is that we just shift the ray origin by a small amount, just enough to pass through the surface, and then restart the routine as if the ray was shot from behind the transparent surface.
If the random number is less than the opacity, we calculate lighting as we would do otherwise.
We also keep track of an "opacity bounces" number, which calculates how many times we hit a transparent material and had to shif the ray origin by a small amount.
That's because when we hit a transparent material and have to shift the ray, it doesn't count as a bounce, and we effectively have to restart shooting the ray from beyond the surface. Now imagine if we have a very complex object with many layers, and it's transparent. We would have do this ray origin shifting many many times, and this would become inefficient.
So if we do more than 128 opacity bounces, we just want to break out of the bounces loop.
Here's the full code :
Here's the full code :
// Opacity
if(Material.Opacity < 1 && RandomUnilateral(Isect.RandomState) >= Material.Opacity)
{
if(OpacityBounces++ > 128) break;
Ray.Origin = Position + Ray.Direction * 1e-2f;
Bounce--;
continue;
}
Again, that's very simple, and here's the result :
We can see through the glass, with a slightly green tinted colour. Nice !
Commentaires
Enregistrer un commentaire