**Advanced Computer Graphics: Project Report** Final render ============ Here is my final render, produced with 512 samples per pixel:
* Biscuits from [butter biscuits](84621LICENSE.html) * Table texture *Wood026* from https://cc0textures.com/ * Card design from the famous bicycle game card, *Old Fan back design* from 1885 * Environment map *combination_room* from https://hdrihaven.com/ * *Alice in Wonderland* rabbit engraving by Sir John Tenniel Motivation ========== When thinking of dreams, I thought first about Alice in Wonderland: she falls asleep, and then lives some adventures in her dreamed world. I also wanted to play with mirror, in particular with reflects, which can represent a dreamed reality. It happens that the second volume of *Alice in Wonderland* is titled "Through the looking glass", with an original engraving by Sir John Tenniel:
alice
Therefore, I wanted to represent a "dreamed reality" behind a mirror. Some images playing with this idea have already been produced:
Chess
Inspired by that, my goal was to design a scene containing a table, with some objects on it, that won't reflect right: some textures or objects would appear. Idealy there will be objects recalling Alice in Wonderland: a chess set, a card game, the "drink me" bottle and the "eat me" biscuits. Feature list ============
Feature Standard point count Adjusted point count Use in the scene
Textures or Procedural images 10 10 Textures can be used to almost any objects of my scene, and are needed to represent some objects (card game, for example)
Bump mapping / normal mapping 10 10 Bump maping can add realism to the wood materials of my scene.
Simple extra BSDFs 10 10 (rough) conductors can be used to render some metal objects, such as the corners of the mirror
(Beer-Lambert Law) (10) (0) (I want to implement it (for beverages in glasses), but it will not give points, since I would like to implement "homogeneous media" feature)
Mesh design 10 10 I modelled almost all my meshes in Blender.
Image Based Lighting 15 15 Image Based Lighting can add a lot of realism
Homogeneous participating media 30 25 It is firstly to use on some liquids of my scene. But I also used it for the marble chess queen
Magic Mirror effect 0 0 Used to make objects appear behind the mirror
Total 85 80
Feature Description ========= The scene used for testing is from [Benedikt Bitterli: MaterialTestBall](https://benedikt-bitterli.me/resources/). The environment map is [At the Window (Wells, UK) from Bernhard Vogl](http://dativ.at/lightprobes/). The texture used are CastleBirck and Sandstone from https://texturehaven.com/ and Wood026 from https://cc0textures.com/. ## Feature 1: Textures ### Description !!! "Create spatially varying BSDF parameters using texture maps. This could involve textures from an image file or procedurally generated​ textures." I chose to focus on textures from image files. The texture could be either a image which is repeated, or a texture designed specifically for an object. I used both in my scene: the first to add texture to the table, the second to add texture to the cards, for example. I also implemented some UV mapping useful when the UV coordinates are not given in the .obj. I implemented three UV mapping: spherical, cylindrical and planar; I added a checkerboard texture, useful for testing them. ### Design * A new nori object had to be created: ETexture; the header describing it is *texture.h*. This header also contains the class *TextureMapping2D* and the functions to do the UV mapping (see also texture.cpp). * The first texture implemented are the *ConstantTexture* and the *Checkerboard* in *bsdfs/constant.cpp* and *bsdfs/checkerboard.cpp*. The *Checkerboard* can take some parameters, such as the two colors, a scale and an offset. * Then, the class *ImageTexture* in *bsdfs/image.cpp* loads an exr image. It also takes a scale parameter. * The classes *diffuse* and *microfacet* were adapted: for diffuse, the albedo is a texture (by default constant). For microfacet, two textures can be used: one for the coefficient of diffusion $k_d$ and the other for the roughness $alpha$. ### Validation * Here are some examples of UV mapping: the objects are mapped with the three types of UV Mapping: spherical for the sphere, cylindical for the interior object, and plannar for the ground plane. ![Different UVMapping and checkerboard textures](data/UVMapping.png width="450") * Here is an example of an image texture applied on a sphere: diffuse, and using microfacet.
![Diffuse texture](data/bricks.png) ![Microfacet with textures](data/wood.png)
* Then, a texture specific to an object can be applied, for example for the card player.
UV Mapping UV Mapping
## Feature 2: Bump mapping / normal mapping ### Description !!! "Model small surface irregularities by perturbing the shading coordinate frame based on a texture. See PBRTv3 Chapter 9.3" I wanted to try both Normal Maps, which descript the orientation of the local normals with a 3 channels image, and Bump Maps, which are grey-scaled images which encodes the local displacement, and from which we can extract the normal. ### Design * I created a new nori object, *EBumpMap*, defined in *bumpMap.h*. * Then I created two instances of bumpMaps: BumpTexture in *textures/bumpTexture.cpp* and NormalTexture in *NormalTexture.cpp* * Again, these two textures takes a filename to a exr and an optionnal scale. * For normalTexture, we simply convert the rgb color to a local normal. Then we use in *accel.cpp* the bump map and the normal of the geoFrame to compute the new normal. * For bumpTexture, we compute the differential in u and v from the geoframe; then we use the image to have the displacement (taking the differencial with the adjacent pixels) at a certain point. We choose to neglect the derivatives of the normals, because the displacement is expected to be small. * The bump map has to be attached directly to a mesh: it was also possible to attached it to a bsdf (to have a bumpM map attached for each bsdf), but it was not useful in my scene. Here, the new normal is computed in *accel.cpp* ### Validation Here are some examples of BumpMaps, the first one using normalTexture and the second one BumpTexture.
UV Mapping UV Mapping
## Feature 3: Simple BSDFs ### Description We can implement new bsdfs: conductors, rough conductors, and rough dielectrics. The latter ones are described in the paper Microfacet Models for Refraction through Rough Surfaces (Walter et al. 2007) https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf Rough conductors are used in my scene for the corners of the mirror and of the photo frame. Rough dielectrics are not used in my scene (and were not part of the feature evaluation :)). ### Design I implemented three new classes: * Conductors in *bsdfs/conductors.cpp*: it ressembles the mirror class, except that the light reflected is tinted by the *fesnelConductor* coefficient. It has two parameters, m_eta and m_k, that are defined for every metal (often approximated because we are working in rgb and not with a continuous spectrum) * Rough Conductors in *bsdfs/roughConductor* As in microfacet, we sample the reflected light using Beckmann function. For computing the Fresnel Coefficient, we use the one for metal, which can deal with complex coefficient (as in the class conductor). * Rough Dilectric in *bsdfs/roughDielectrics*; it was implemented as described in the paper, using the Beckmann function. * in *common.h*, a *MicrofacetHelper* class has been added; it contains the useful functions to compute the microfacet coefficients. ### Validation * **Conductor**. Here is an example of a smooth gold material.
My implementation in Nori Mitsuba reference
*Left is my implementation in Nori, right Mitsuba reference*
* **Rough Conductor**: the warpTests are correct
UV Mapping
![$\alpha=0.05$, $\theta=0$](data/cond0.05-0.png) ![$\alpha=0.05$, $\theta=0$](data/cond0.05-45.png) ![$\alpha=0.1$, $\theta=0$](data/cond0.1-0.png) ![$\alpha=0.1$, $\theta=0$](data/cond0.1-45.png) ![$\alpha=0.3$, $\theta=0$](data/cond0.3-0.png) ![$\alpha=0.3$, $\theta=0$](data/cond0.3-45.png) * Here are two examples of rough conductors: Aluminium, alpha=0.03
My implementation in Nori Mitsuba reference
*Left is my implementation in Nori, right Mitsuba reference*
Gold, alpha=0.01
My implementation in Nori Mitsuba reference
*Left is my implementation in Nori, right Mitsuba reference*
* **Rough Dielectric** (Bonus): the warptest is correct
UV Mapping UV Mapping
*Left is my implementation in Nori, right Mitsuba reference*
![$\alpha=0.05$, $\theta=0$](data/diel0.05-0.png) ![$\alpha=0.05$, $\theta=0$](data/diel0.05-45.png) ![$\alpha=0.1$, $\theta=0$](data/diel0.1-0.png) ![$\alpha=0.1$, $\theta=0$](data/diel0.1-45.png) ![$\alpha=0.3$, $\theta=0$](data/diel0.3-0.png) ![$\alpha=0.3$, $\theta=0$](data/diel0.3-45.png) ## Feature 4: Beer-Lambert Law See Homogeneous participating media. It is used for my liquid. ## Feature 5: Mesh design I did implement the majority of the objects of my scene: the table, wall, bottle, cards, soldier cards, photo frame, chess queens, and plate. I also used some physical simulation for the cards to lay on the table. I also painted the texture when needed!
Mesh Disign
## Feature 6: Image Based Lighting ### Description !!! "Simulate natural illumination from a environment map texture." It is used in my scene to provide the lightings and the background. ### Design I implemented the Image Based Lighting as described in the pbr book. * The file *HSW.cpp* contains the class needed to deal with some environment map: * The class *MipMap*, creating a MipMap from a BitMap. * The class *HSWHelper*, which performs the hierarchical sample warping * The sampling is done as described in TD3: using mipmaps and hierarchical sample warping. * Then, a new instance of emitter is created, EnvLight in *envLight.cpp*. It implements the common functions of emitter, plus some function to go from a direction to a pixel, and from pixel to direction. * This emitter is added to the "envLights" of the scenes * Then, when doing the path tracing, if the ray intersects nothing, it calls the envLight and evaluate. Otherwize, it is just a simple emitter. * The envMap can have a transform toWord input, useful to define its orientation. ### Validation The warptest is correct (it works very well when setting the same number of x and y samples for the histogram as there is of pixels):
WarpTest WarpTest
My implementation in Nori Mitsuba reference
*Left My implementation in Nori, right Mitsuba reference*
## Feature 7: Homogeneous participating media ### Description !!! "Model multiple scattering and absorption in a participating medium. This can be used to model for example fog/god rays, colored liquids (e.g. orange juice), skin, translucent plastic, etc. If used right, this adds a lot of realism to a scene. See PBRTv3 Chapter 11​, ​15" I used this feature both for the marble of the chess queen and for the liquid in the bottle. ### Design * I created a new nori object: EMedium described in *medium.h*. I also added a *MediumQueryRecord*. A medium has to sample phase, distance, and evaluate them. * I created an instance of medium: *HomogeneousMedium*. It can deal with isotropic and anisotropic (function Henyey–Greenstein) phases. Some parameters can be set to do some approximations: with *isBeerLambert*, the function *samplePhase* do not change the direction ; with *isIsotropic*, *samplePhase* samples uniformly, adapting the $A_s$ with a factor (1-g) as seens in the course. * Path tracer: I mixed the path_mis with the volumetric path tracer described in the course. Indeed, I kept it simple when it is inside a medium: because of the interfaces, I couldn't benefit from a path mis when inside the medium. * I implemented several volumetric path tracers. But considering my scene, the one that is useful is the *path_mis_vol_multi*, which can handle multiple (small) objets containing medium. * These objects need a bsdf attached, so I created a *medium_inter* bdsf that does nothing. It can also be used with dielectrics. ### Validation Here are some results: * Some Chardonnay liquid ($\eta_{int}=1.5$) with and without the Beer Lambert option. Since g is almost 1, it should not change a lot:
hg anisotropic Beer-Lambert
*Left is hg anisotropic, right Beer-Lambert*
The coefficient of absorption and scattering are the ones from mitsuba documentation ("Acquiring Scattering Properties of Participating Media by Dilution" by Narasimhan, Gupta, Donner, Ramamoorthi, Nayar, Jensen (SIGGRAPH 2006))). * A marble medium. A dieletric ($\eta_{int}=1.5$) is attached.
hg anisotropic
Again, the coefficient of absorption and scattering are the ones from mitsuba documentation. * Some smoke with a "medium_interface" bsdf, comparing the anisotropic and isotropic phases with two different values of g: g=0.92 and g=0.5; when doing the anisotropic version, the cofficient of absoption is changed as done i the course. The smallest g is, the more similare the results are. The coefficient of absorption is set at 0.20, and of scattering at 0.15.
hg anisotropic g=0.92 isotropic g=0.92
*Left hg anisotropic g=0.92, right isotropic g=0.92*
hg anisotropic g=0.5 isotropic g=0.5
*Left hg anisotropic g=0.5, right isotropic g=0.5*
* Here is some smoke but this time more scattering than absorbing (0.3 and 0.02). g=0.7.
anisotropic isotropic
*Left anisotropic g=0.5, right isotropic*
(I had some troubles dealing with medium on mitsuba2, therefore I do not have any comparison) ## Feature 8: Magic Mirror effect ### Description The goal of this effect is to make an object appear only in the mirror. ### Design * I implemented a new integrator, *path_mis_mirror*, that contains a boolean indicating if a ray has gone behind the mirror * I added the property "isTheLookingGlass" and "isBehindmirror" to objetcs. I had to change the class *mesh.cpp*, *bsdf.cpp*, *diffuse.cpp*, *mirror.cpp* * I also had to add new *rayIntersectMirror* functions, depending on the previous booleans. I added them in *scene.cpp*, *accel.cpp* and *mesh.cpp* * For the final render, I used the *path_vol_multi_mirror* which can deal both with objects behind mirror and with mediums. ### Validation I implemented a very simple scene in homework 5, having some objects appearing only in the mirror:
Italian Trulli
The shelf is the mesh [Cabinet](www.blendswap.com/blends/view/25841), from blendswap. Bonus Image ======== I did render a second image, not sent for the competition, here it is! The environment map is ballroom, also from https://hdrihaven.com/, with 1024 samples per pixel.
Which one do you prefer? Feedback ======== Thanks to the teaching assistants, who were so helpful at many time, and of course to Professor Wenzel Jakob for his lectures.