Project Report

Ganlin Zhang

Images as Textures

Relevant code:

  • src/textures/imagetexture.cpp

Implementation Details:

For this feature, an input texture image is loaded, then the texture of the object is decided by the input texture image. We write a class inheriting the Texture class, and the member function eval() would return the corresponding rgb value of input u v coordinate. To make the texture looks more smooth, we use bilinear interpolation on the quired position. Also, to make it more flexiable, parameter scale can be added to adjust the texture's scale.

Validation:

The texture image we used for testing:

without texture with texture

Bump Mapping

Relevant code:

  • src/bsdfs/bumpmap.cpp
  • src/geometry/mesh.cpp
  • src/geometry/sphere.cpp

Implementation Details:

For this feature, an input image is loaded as the bumpmap. We implement a bumpmap class inheriting from the BSDF class, which contains a actual BSDF and a image texture. When we need the BSDF information of the intersection point, first we adjust the frame of that point according to the input image texture, after that, the adjusted intersection would be passed to the actual BSDF and get the results. A member variable enhance is also added to adjust the strength of the bumpmap.

Validation:

The bumpmap image we used for testing:

bumpmap enhance=1 bumpmap enhance=0.05 without bumpmap

Simple Extra BSDF: Conductor

Relevant code:

  • src/bsdfs/conductor.cpp

Implementation Details:

We implement a ConductorBSDF class inheriting from the BSDF class, which contains three member variables: eta, k and specular_reflectance. Since it is a discrete BSDF, the eval() and pdf() function of it would directly return 0. For sample(), we use the conductor fresnel function by K.D. Moeller.

Validation:

We compare our result with the result from Mitsuba 3.

our result Mitsuba 3

Simple Extra BSDF: Blend BSDF

Relevant code:

  • src/bsdfs/blendbsdf.cpp

Implementation Details:

This feature intends to combine two different BSDF with a given weight factor. To achive this goal, we implement a BlendBSDF class inheriting from the BSDF class. This BlendBSDF requires to BSDF as input, a float weight factor weight is also needed to balance this two BSDF. For eval() and pdf() function, we call the two member BSDF and weight their result by the weight. For function sample(), we use a random variable to decide use which BSDF, and call the corresponding sample().

Validation:

Use BlendBSDF to combine Diffuse and Dielectric with different weight (0.00, 0.25, 0.50, 0.75, 1.00 from left to right). The result is shown below:

Use BlendBSDF to combine Diffuse and Conductor with different weight (0.00, 0.25, 0.50, 0.75, 1.00 from left to right). The result is shown below:

Use BlendBSDF to combine Dielectric and Conductor with different weight (0.00, 0.25, 0.50, 0.75, 1.00 from left to right). The result is shown below:

Stratified Sampling

Relevant code:

  • src/sample/stratified.cpp
  • src/core/render.cpp

Implementation Details:

For this feature, we implement a StratifiedSampler class inheriting from the Sampler class. Besides the sampleCount parameter, an additional dimension parameter is also added. Every sample would generate the predefined dimension, and each sample would distributed relatively evenly across the sample space. If the sample use more than the predefined dimension, it will sample value randomly.

Validation:

Here we compare the rendering result with stratified sampling and independent sampling. It can be seen clearly that the noise distribution of the one with stratified sampling is more even than the one with independent sampling.

stratified sampling independent sampling

stratified sampling independent sampling

Environment Map Emitter

Relevant code:

  • src/emitters/envmap.cpp
  • include/kombu/envmap.h
  • src/integrators/path_mats.cpp
  • src/integrators/path_mis.cpp

Implementation Details:

This feature intends to provide a background environment light to the rendered scene. It would load an image as the environment map as an emitter and wrap the image to a infinite large sphere. The return value of the emitter only depends on the angle of the sampled ray. In practice, we also need to give a shadow ray, whose length depends on the bounding sphere of the scene to enable the light sampling. Also, importance sample is done by calculating the pdf and cdf of the image. Bilinear interpolation is applied to make it looks more smooth. The implementation is based on this paper: https://web.cs.wpi.edu/~emmanuel/courses/cs563/S07/projects/envsample.pdf

Validation:

Here we compare our result with mitsuba 3. There are a diffuse sphere and a dielectric sphere in the scene to check the correcness.

our envmap mitsuba 3 envmap

This is the environment map for testing.

Disney BSDF (metallic, roughness, specular, sheen, sheen_tint)

Relevant code:

  • src/bsdf/disney_principled.cpp
  • include/kombu/disney_utils.h
  • include/kombu/principledhelpers.h

Implementation Details:

We implement 5 parameters of Disney Principled BSDF, which are roughness, specular, metallic, sheen and sheen_tint. This feature makes it possible to adjust the material of surface of certain object more flexiable to be adjusted. Basically, Disney BSDF is a mix of different material. metallic describes how much is the metal contributes to the material (0 is dielectric and 1 is metal). roughness controls the roughness of the surface by weighting diffuse and specular reflections. specular decribes the amount of incident specular reflection. Used to replace the rate of refraction. sheen is an additional grazing component, mainly for cloth, and sheen_tint controls the color of sheen. Our implementation uses this tutorial from UCSD and Mitsuba 3 as references.

Validation:

Let metallic be (0.00, 0.25, 0.50, 0.75, 1.00 from left to right), fix other parameters:

Let roughness be (0.00, 0.25, 0.50, 0.75, 1.00 from left to right), fix other parameters:

Let sheen be (0.00, 0.25, 0.50, 0.75, 1.00 from left to right), fix other parameters:

Let sheen_tint be (0.00, 0.25, 0.50, 0.75, 1.00 from left to right), fix other parameters:

Let specular be (0.00, 0.25, 0.50, 0.75, 1.00 from left to right), fix other parameters:

Compare metallic = 0 and metallic = 1:

metallic=0 metallic=1

Compare roughness = 0 and roughness = 1:

roughness=0 roughness=1

Compare sheen = 0 and sheen = 1:

sheen=0 sheen=1

Compare sheen_tint = 0 and sheen_tint = 1:

sheen_tint=0 sheen_tint=1

Compare specular = 0 and specular = 1:

specular=0 specular=1