University of Pennsylvania, CIS 561: Advanced Computer Graphics, Homework 8
Yilin Liu
31955379
Overview ------------ You will take what you learned in part I of this physically-based shader assignment and combine it with the pre-computation of irradiance applied to the plastic-metallic BRDF. Recall that the overall formula for this BSDF is +Here are some example screenshots of what your implementation should look like with varying amounts of roughness and metallicness:
- Lo is the light that exits point p along ray ωo.
- Le is the light inherently emitted by the surface at point p along ray ωo.
- ∫S is the integral over the sphere of ray directions from which light can reach point p. ωo and ωi are within this domain.
- f is the Bidirectional Scattering Distribution Function of the material at point p, which evaluates the proportion of energy received from ωi at point p that is reflected along ωo.
- Li is the light energy that reaches point p from the ray ωi. This is the recursive term of the LTE.
- V is a simple visibility test that determines if the surface point p' from which ωi originates is visible to p. It returns 1 if there is no obstruction, and 0 is there is something between p and p'. This is really only included in the LTE when one generates ωi by randomly choosing a point of origin in the scene rather than generating a ray and finding its intersection with the scene.
- The absolute-value dot product term accounts for Lambert's Law of Cosines.
In order to save space in your repository, we have uploaded a .zip
file to Canvas
containing the environment map .hdr
files and .json
scene files you can load into
your program. Download this .zip
and extract its contents into the same folder your .pro
is in. We have also added a .gitignore
that will ignore these folders when you push your
code to Github. Make sure, then, that you explicitly git add
any custom scene files you
write as part of your extra credit.
Make sure that you fill out this README.md
file with your name and PennKey,
along with your example screenshots. For this assignment, you should take screenshots of your OpenGL window with the following configurations:
- 0% metallic, 0% rough, RBG = 1 1 1
- 100% metallic, 0% rough, RGB = 1 1 1
- 100% metallic, 25% rough, RGB = 1 1 1
- cerberus.json, with a camera angle that shows the model in profile
All code written for this point-light based PBR shader will be implemented in three different .glsl
files:
pbr.frag.glsl
(same name as last assignment, different code)diffuseConvolution.frag.glsl
glossyConvolution.frag.glsl
While we are implementing the paper Real Shading in Unreal 4, you can find an excellent in-depth tutorial on its implementation on LearnOpenGL.org. For this assignment, you will want to refer to the following two articles:
While you are encouraged to refer to the articles on LearnOpenGL.org linked above, we want to make sure that you are doing more than simply copying the code listed there. As such, you must assign specific names to variables that serve particular purposes, as the code linked above uses different names:
- Name:
wo
| Purpose: The ray traveling from the point being shaded to the camera - Name:
wi
| Purpose: The ray traveling from the point being shaded to the source of irradiance - Name:
wh
| Purpose: The microfacet surface normal one would use to reflectwo
in the direction ofwi
. - Name:
R
| Purpose: The innate material color used in the Fresnel reflectance function
Please make sure to use this terminology in all three .glsl
files where appropriate.
Implement the main
function of diffuseConvolution.frag.glsl
so that it takes samples of
u_EnvironmentMap
across the set of directions within the hemisphere aligned with the input surface
normal. Please carefully read the comments in this shader file in order to determine what the surface
normal is in the context of this shader.
When you have implemented the diffuse irradiance map, you can view it as your scene's background by
modifying the code in MyGL::renderEnvironmentMap()
. Below are two examples of what you should see
(excluding the appearance of the sphere, as you have not yet implemented the PBR shader).
Default environment map:
Fireplace environment map:
Now that you have your diffuse Li
term, you can implement one portion of pbr.frag.glsl
.
Using the surface normal direction in the shader, sample the diffuse irradiance cubemap
(u_DiffuseIrradianceMap
) and combine it with your material's albedo. If you set this as your
output color, and set your material properties to the ones shown below, you should be able to
match these screenshots (also, don't forget to apply the Reinhard operator and gamma correction):
Default environment map:
Fireplace environment map:
Fireplace environment map (viewed from another angle):
Implement the main
function of glossyConvolution.frag.glsl
so that it takes samples of
u_EnvironmentMap
via importance sampling based on the GGX normal distribution function. Please carefully read the comments in this shader file in order to determine how you should orient the
glossy BRDF lobe you'll be importance sampling.
When you have implemented the glossy irradiance map, you can view it as your scene's background by
modifying the code in MyGL::renderEnvironmentMap()
, and uncommenting the invocation of textureLod
in envMap.frag.glsl
. Below are two examples of what you should see
(excluding the appearance of the sphere, as you have not yet implemented the other portion of the PBR shader).
Default environment map:
Panorama environment map:
Now that you have your glossy Li
term, you can implement the other portion of pbr.frag.glsl
.
You must compute the following attributes of your Cook-Torrance BRDF:
- Fresnel term using the Schlick approximation
- The combined D and G terms by sampling
u_BRDFLookupTexture
based on theabsdot
term androughness
.
Then, use wi
to sample u_GlossyIrradianceMap
using textureLod
, along with roughness
to determine
the mip level.
You must also compute kD
based on your kS
term, and multiply it with your diffuse component.
If you combine your diffuse and glossy colors into your output, and set your material properties to the ones shown below, you should be able to match the screenshots shown in the very beginning of these instructions.
Modify pbr.frag.glsl
and pbr.vert.glsl
to do the following:
- Alter
N
to align with the direction given byu_NormalMap
whenu_UseNormalMap
is true - Alter
displacedPos
so that it is displaced along the surface normal byu_DisplacementMagnitude
times a scalar obtained fromu_DisplacementMap
whenu_UseDisplacementMap
is true.
Create your own custom JSON scenes and load them into your project. Create texture maps for as many material attributes as you can for more interesting surface appearance. The more interesting and numerous your scenes are, the more points you'll receive. You'll also have created excellent material for your demo reel in the process!
Along with your project code, make sure that you fill out this README.md
file
with your name and PennKey, along with your test renders.
Rather than uploading a zip file to Canvas, you will simply submit a link to the committed version of your code you wish us to grade. If you click on the Commits tab of your repository on Github, you will be brought to a list of commits you've made. Simply click on the one you wish for us to grade, then copy and paste the URL of the page into the Canvas submission form.