Images as Textures

This simple feature "5.3 Images as Textures" enables the user to replace constant albedo colors with arbitrary png-images to texture their objects in the scene. This is a great way to add detail and realism to the scene without having to physically model everything on the geometry level.

preview


Implementation

The basic structure of this class is the same as the checkerboard.cpp implementation. First, we need to be able to load the png image into Nori. For this, I used a preexisting png-loader called lodepng. Lodepng reads the image and saves the content into an unsigned char vector. One pixel is represented by a block of 4 chars with the respective RGBA values. This is implemented in the constructor of this class. Additionally, I added the ability to scale the texture with a simple 2D vector. I use the same convention as in Blender for the scaling, e.g., if the scale value is 2, the texture will be repeated twice for each axis.

In the eval method, the uv coordinates are mapped to the image space. I assume that the uv coordinates are always scaled to [0,1]. We can simply calculate the image-u by multiplying uv.x() with the image width and the scaling term. Image-v is calculated analogously. After u and v have been mapped to the image space, we need to calculate the corresponding index in the image vector: idx = (v * image_width + u) * 4. The index is multiplied by 4 because each pixel consists of 4 chars (RGBA). To ensure the texture can be repeated, the index is mapped to the vector length by using the modulo operator: idx = idx % image_size. Finally, the obtained RGB values are divided by 255 to map them to [0,1]. The user can specify in the xml file, whether the values should be treated as raw, or whether the value should be transformed to RGB space by using toLinearRGB().

Usage:

<bsdf type="...">
 <texture type="image_texture" name="albedo">
  <boolean name="raw" value="false"/>
  <string name="filename" value="texture.png"/>
  <vector name="scale" value="2,2"/>
 </texture>
</bsdf>

The following files have been modified or added to implement this feature:

  • include/nori/lodepng.h
  • src/lodepng.cpp
  • src/imagetexture.cpp

Validation

To validate the textures, I simply rendered a numbered checkerboard pattern onto different objects and compared the results to the same scene rendered by Mitsuba and Blender. Using numbered checkerboard pattern also allows us to see whether the texture is mapped as expected.

The numbered checkerboard texture image is from here and the other image is our proposal concept:

Checkerboard Mine


Comparison to Mistuba

First, I'm going to show 2 comparisons with Mitsuba to show that the expected output is produced for the mapping and the colors. The only visible difference here is that Mitsuba's result seems to be a little sharper than mine. This is probably either due to differences in the integrator, or simply that Mitsuba includes more advanced methods such as mipmapping. However, the overall result looks correct.

Plane

Mine Mitsuba

Sphere

Mine Mitsuba


Additional Results

Scale Effect

The effect of texture scaling is displayed in the comparison between non-scaled default texture map and the scaled version.

  • uv-scale: (4, 2)
Scaled Not Scaled

Raw vs linearRGB

Here I show the difference in vibrancy if we forget to convert the raw values from the PNG into the RGB space. Both results are rendered Nori.

Raw Linear RGB