materials.md 8.53 KB
Newer Older
Hui Wang's avatar
Hui Wang committed
1
2
[[Home]](/docs/index.md)  [[User Guide]](/docs/guide/guide.md) [[Mesh Edit]](/docs/meshedit/overview.md) [[Path Tracer]](/docs/pathtracer/overview.md) [[Animation]](/docs/animation/overview.md)

yhesper's avatar
yhesper committed
3
4
---

TheNumbat's avatar
TheNumbat committed
5
# (Task 5) Materials
yhesper's avatar
yhesper committed
6

TheNumbat's avatar
TheNumbat committed
7
## Walkthrough
allai5's avatar
allai5 committed
8

TheNumbat's avatar
TheNumbat committed
9
10
11
<video width="750" height="500" controls>
    <source src="videos/Task6_Materials.mp4" type="video/mp4">
</video>
allai5's avatar
allai5 committed
12

TheNumbat's avatar
TheNumbat committed
13
Now that you have implemented the ability to sample more complex light paths, it's time to add support for more types of materials. In this task you will add support for two types of specular materials: mirrors and glass. These materials are implemented in `student/bsdf.cpp`.
allai5's avatar
allai5 committed
14

TheNumbat's avatar
TheNumbat committed
15
16
- In the diagrams below, both `out_dir` and `in_dir` are pointing _away_ from the intersection point. This is so that we can more consistently consider their angles with respect to the surface normal.
- Remember that we are tracing rays _backwards_, from the camera into the scene. This is why the computed scattering direction (`in_dir`) corresponds with the _incoming_ light.
yhesper's avatar
yhesper committed
17

TheNumbat's avatar
TheNumbat committed
18
<center><img src="figures\rays_dir.png" style="height:420px"></center>
allai5's avatar
allai5 committed
19

TheNumbat's avatar
TheNumbat committed
20
First, take another at the BSDF interface in `rays/bsdf.h`. There are a number of key methods you should understand in `BSDF`:
allai5's avatar
allai5 committed
21

TheNumbat's avatar
TheNumbat committed
22
23
24
25
- `Scatter scatter(Vec3 out_dir)`: given `out_dir`, generates a random sample for `in_dir`. It returns a `Scatter`, which contains both the sampled `direction` and the `attenuation` for the in/out pair.
- `Spectrum evaluate(Vec3 out_dir, Vec3 in_dir)`: evaluates the BSDF for a given pair of directions. This is only defined for continuous BSDFs.
- `float pdf(Vec3 out_dir, Vec3 in_dir)`: computes the PDF for sampling `in_dir` from the BSDF distribution, given `out_dir`. This is only defined for continuous BSDFs.
- `Spectrum emissive()`: returns emitted light. This is only defined for the diffuse light source BSDF.
yhesper's avatar
yhesper committed
26

TheNumbat's avatar
TheNumbat committed
27
To complete the mirror and glass materials, you will only need to implement their `scatter` functions, as they are both discrete BSDFs (i.e. they have a finite number of possible `in_dir`s for any `out_dir`). Additionally, you will want to complete two helper functions:
yhesper's avatar
yhesper committed
28

TheNumbat's avatar
TheNumbat committed
29
- `Vec3 reflect(Vec3 dir)`: returns a direction that is the **perfect specular reflection** of `dir` about `{0, 1, 0}`. More detail about specular reflection can be found [here](http://15462.courses.cs.cmu.edu/fall2015/lecture/reflection/slide_028).
yhesper's avatar
yhesper committed
30

TheNumbat's avatar
TheNumbat committed
31
- `Vec3 refract(Vec3 out_dir, float index_of_refraction, bool& was_internal)`: returns the ray that results from refracting `out_dir` through the surface according to [Snell's Law](http://15462.courses.cs.cmu.edu/fall2015/lecture/reflection/slide_032). Your implementation should assume that when `in_dir` **enters** the surface (that is, if `cos(theta_out) > 0`) then the ray was previously travelling in a vacuum (i.e. index of refraction = 1.0). If `cos(theta_out) < 0`, then `in_dir` is **leaving** the surface and entering a vacuum.
yhesper's avatar
yhesper committed
32

TheNumbat's avatar
TheNumbat committed
33
Finally, when working with Snell's law, there is a special case to account for: total internal reflection. This occurs when a ray hits a refractive boundary at an angle greater than the _critical angle_. The critical angle is the incident \theta_i that causes the refracted \theta_t to be >= 90 degrees, hence can produce no real solution to Snell's Law. In this case, you should set `was_internal` to `true`.
yhesper's avatar
yhesper committed
34

TheNumbat's avatar
TheNumbat committed
35
<center><img src="figures\tir_eqns.png" width="200"></center>
allai5's avatar
allai5 committed
36

TheNumbat's avatar
TheNumbat committed
37
<center><img src="figures\bsdf_diagrams.png" style="height:200px"></center>
yhesper's avatar
yhesper committed
38

TheNumbat's avatar
TheNumbat committed
39
---
allai5's avatar
allai5 committed
40
41
42

## Step 1: `BSDF_Mirror`

TheNumbat's avatar
TheNumbat committed
43
44
45
Implement `reflect` and `BSDF_Mirror::scatter()`.

Because discrete BSDFs do not require Monte Carlo integration (we can simply analytically evaluate each possible direction), we do not implement `BSDF::pdf`. Perhaps more interestingly, we also do not require `BSDF::evaluate`. This is because evaluating the BSDF is only necessary when sampling directions from distributions other than the BSDF itself. When the BSDF is discrete, like a perfect mirror, we can assume other distributions never sample the single (infinitesimal) direction at which the BSDF is non-zero.
allai5's avatar
allai5 committed
46

TheNumbat's avatar
TheNumbat committed
47
Therefore, we must update our path tracing procedure in `Pathtracer::sample_(in)direct_lighting`: when the BSDF is discrete (`BSDF::is_discrete`), we are not doing a Monte Carlo estimate, hence should not use `BSDF::pdf`. Instead, simply multiply the scattering attenuation and the incoming light. Note that failing to make this check will cause the invalid BSDF calls to abort.
allai5's avatar
allai5 committed
48
49

## Step 2: `BSDF_Glass`
yhesper's avatar
yhesper committed
50

TheNumbat's avatar
TheNumbat committed
51
Implement `refract` and `BSDF_Glass::scatter()`.
Hesper Yin's avatar
Hesper Yin committed
52

TheNumbat's avatar
TheNumbat committed
53
Glass is a material that can both reflect and transmit light. As discussed in class, the fraction of light that is reflected vs. transmitted is governed by the dielectric (non-conductive) Fresnel equations. To simulate this, we may sample `in_dir` from either reflection or refraction with probability proportional to the Fresnel reflectance. For example, if the Fresnel reflectance is 0.9, then you should generate a reflected ray 90% of the time. Note that instead of computing the full Fresnel equations, you have the option to use [Schlick's approximation](https://en.wikipedia.org/wiki/Schlick's_approximation) instead.
Hesper Yin's avatar
Hesper Yin committed
54

TheNumbat's avatar
TheNumbat committed
55
In the description below, <img src="figures/dielectric_eq1.png" width="18"> and <img src="figures/dielectric_eq2.png" width="15"> refer to the index of refraction of the medium containing the incoming ray and the angle of that ray with respect to the boundary surface normal. <img src="figures/dielectric_eq3.png" width="18"> and <img src="figures/dielectric_eq4.png" width="15"> refer to the index of refraction of the new medium and the angle to the boundary normal of the transmitted ray.
Hesper Yin's avatar
Hesper Yin committed
56

TheNumbat's avatar
TheNumbat committed
57
The Fresnel equations state that reflection from a surface is a function of the surface's index of refraction and the polarity of the incoming light. Since our renderer doesn't account for polarity, we'll apply a common approximation of averaging the reflectance of light polarized in perpendicular and parallel directions:
Hesper Yin's avatar
Hesper Yin committed
58

TheNumbat's avatar
TheNumbat committed
59
<img src="figures/dielectric_eq5.png" width="200">
Hesper Yin's avatar
Hesper Yin committed
60

TheNumbat's avatar
TheNumbat committed
61
The parallel and perpendicular terms are given by:
Hesper Yin's avatar
Hesper Yin committed
62

TheNumbat's avatar
TheNumbat committed
63
<img src="figures/dielectric_eq6.png" width="200">
Hesper Yin's avatar
Hesper Yin committed
64

TheNumbat's avatar
TheNumbat committed
65
<img src="figures/dielectric_eq7.png" width="200">
Hesper Yin's avatar
Hesper Yin committed
66

TheNumbat's avatar
TheNumbat committed
67
Therefore, for a dielectric material, the fraction of reflected light will be given by <img src="figures/dielectric_eq8.png" width="18">, and the amount of transmitted light will be given by <img src="figures/dielectric_eq9.png" width="50">.
Hesper Yin's avatar
Hesper Yin committed
68

TheNumbat's avatar
TheNumbat committed
69
Alternatively, you may compute <img src="figures/dielectric_eq8.png" width="18"> using [Schlick's approximation](https://en.wikipedia.org/wiki/Schlick%27s_approximation).
Hesper Yin's avatar
Hesper Yin committed
70

TheNumbat's avatar
TheNumbat committed
71
### Distribution Function for Transmitted Light
Hesper Yin's avatar
Hesper Yin committed
72

TheNumbat's avatar
TheNumbat committed
73
Although we described the BRDF for perfect specular reflection in class, we did not discuss the distribution function for transmitted light. Unlike reflection, refraction "spreads" or "condenses" a differential beam of light. Hence, a refraction event should change the radiance along a ray.
Hesper Yin's avatar
Hesper Yin committed
74

TheNumbat's avatar
TheNumbat committed
75
After using Snell's Law to find the direction of refracted rays, compute the BSDF attenuation using the distribution function found in Pharr, Jakob, and and Humphries's book [Physically Based Rendering](http://www.pbr-book.org/3ed-2018/Reflection_Models/Specular_Reflection_and_Transmission.html). It also includes a derivation based Snell's Law and the relation <img src="figures/dielectric_eq10.png" width="150">. Of course, you are more than welcome to attempt a derivation on your own!
Hesper Yin's avatar
Hesper Yin committed
76

TheNumbat's avatar
TheNumbat committed
77
---
Hesper Yin's avatar
Hesper Yin committed
78

TheNumbat's avatar
TheNumbat committed
79
## Tips
Hesper Yin's avatar
Hesper Yin committed
80

TheNumbat's avatar
TheNumbat committed
81
82
83
- Check your sphere intersection code, as you may have bugs there that were not exposed by rendering Lambertian spheres in Task 4.
- Check the behavior of your refract function when `index_of_refraction = 1.f`. This should not change the transmitted direction, hence make the glass sphere transparent.
- Test reflection and refraction separately, i.e. ignore the Fresnel coefficient and only refract or reflect. Once you've verified that those are correct, then go ahead and reintroduce the Fresnel coefficient and split rays between reflection  and refraction.
Hesper Yin's avatar
Hesper Yin committed
84

TheNumbat's avatar
TheNumbat committed
85
<center><img src="images/cbox_debug.png"></center>
yhesper's avatar
yhesper committed
86

TheNumbat's avatar
TheNumbat committed
87
---
yhesper's avatar
yhesper committed
88

TheNumbat's avatar
TheNumbat committed
89
## Reference Results
yhesper's avatar
yhesper committed
90

TheNumbat's avatar
TheNumbat committed
91
When you are done, you will be able to render images with specular materials, like the Cornell Box with a metal and glass sphere (`cbox.dae`, 1024 samples, max depth 8):
allai5's avatar
allai5 committed
92

TheNumbat's avatar
TheNumbat committed
93
94
95
<center><img src="images/cbox.png"></center>

---
allai5's avatar
allai5 committed
96

TheNumbat's avatar
TheNumbat committed
97
98
99
## Extra Credit
- Add a more advanced parameterized BSDF, such as Blinn-Phong, GGX, or Disney. More information about evaluating and sampling each of these distributions can be found in [Physically Based Rendering](http://www.pbr-book.org/3ed-2018/) chapters 8 & 9.
- Add textures (either procedural or mapped) defining spatially varying BSDF attributes within an object. Refer to [Physically Based Rendering](http://www.pbr-book.org/3ed-2018/) chapter 10.
allai5's avatar
allai5 committed
100