-
Notifications
You must be signed in to change notification settings - Fork 2
Recitation 04 Texture Mapping
Texture mapping is an important step in rendering photorealistic images. In most of the cases, the process deals with wrapping (or mapping) a texture image around(onto) a given 3D surface to be rendered. While some geometric shapes such as sphere, and cylinder have inherent mapping functions, finding an appropriate texture mapping function for real world objects with complex geometries remains a challenge. Usually texture (uv) coordinates are provided for object (e.g.,triangle mesh) vertices which are then interpolated to get the texture coordinates of triangle fragments(interior points of triangles). In this recitation, you will learn and implement bilinear interpolation based texture mapping for rendering a floor (two triangles) in ray tracing.
In texture mapping, when uv coordinates are not mapped to the exact centers of texels, we interpolate the texture value using the values of four neighboring pixels. Bilinear interpolation is commonly used. First we express the texture-space sample point in terms of (real-valued) texel coordinates, then we read the values of the four neighboring texels and interpolate them in horizontal and vertical directions to get the texture value (as shown in Figure 2).
Please clone GraphicsLab into some folder. For this example, it will be cloned into the Desktop (~/Deskop). You can do this by opening git bash terminal and entering the following (alternatively, you can download the source code zip archive to the Desktop and extract it):
git clone https://github.com/jijup/GraphicsLab ~/Desktop/GraphicsLab
Once it is cloned (or unzipped), build the solution using CMake. Please follow the instructions from here.
The code provided to you renders a grass covered floor to the screen. It does this by ray tracing two triangles where if a ray intersects with the triangle, then the intersection point (closest to the camera) is set to a color value from the grass texture, otherwise the point is set to white. In the given code, one ray is generated per pixel, and is used to determine the color of the pixel. Multiple texture images such as sand, water, rock etc. are given under Textures
folder. You may try different textures by changing the argument intex.loadTexture()
and render the floor.
The first task for you is to compute the texture(uv) coordinates of the Intersection
point. A method called getTextureCoords()
can be found in Triangle.cpp
. Your task is to write the code for texture coordinate interpolation. To do so, first get the Barycentric coordinates of the Intersection
point. Then use the barycentric coordinates to interpolate the texture coordinates of the triangle vertices. Note that the texture coordinates are avaibale for each triangle, text_coord1
, text_coord2
, text_coord3
. Use first elements of texture coordinates to compute uv[0]
and the second elements to compute uv[1]
.
Vec2 Triangle::getTextCoord(const Vec3& point) {
Vec3 baryCoords = -------------;
Vec2 uv;
uv[0] = ----------------;
uv[1] = ----------------;
return uv;
}
The second task for you is to implement bilinear interplation to determine the texture values. We will get the uv
corrresponding to Intersection
point using getTextureCoords()
of the Triangle
class. We will use thus obtained uv
values to get the color value for the Intersection
point. You will find an incomplete method called texture_lookup_bilinear()
in Texture.cpp
. The method is for implementing bilinear interpolation. You have to complete the code. You may use the following code (given in Figure 3) and the discussion on bilinear interpolation in one of the above sections while completing the method.
cv::Vec3b Texture::texture_lookup_bilinear(const Vec2& uv) {
float uv0 = --------;
float uv1 = --------;
int i0 = floor(uv0);
int j0 = floor(uv1);
//Bound the values between 0 and height/width
i0 = clamp_w(i0);
j0 = clamp_h(j0);
//Next higher pixels in u and v directions
int i1 = (i0 < height - 1) ? i0 + 1 : i0;
int j1 = (j0 < width - 1) ? j0 + 1 : j0;
//Parameters for interpolation
float au = --------;
float av = --------;
float bu = 1.0f - au;
float bv = 1.0f - av;
//Get the texture colrs of the four pixels
cv::Vec3b pixel00 = get_pixel(i0, j0);
cv::Vec3b pixel01 = get_pixel(i0, j1);
cv::Vec3b pixel10 = get_pixel(i1, j0);
cv::Vec3b pixel11 = get_pixel(i1, j1);
//Find the interpolated color
cv::Vec3b pixelColor;
pixelColor[0] = -------------------;
pixelColor[1] = -------------------;
pixelColor[2] = -------------------;
return pixelColor;
}
Please place Texture
directory in the same directory where your executable is generated (e.g., build/texturing/Debug
or build/texturing/Release
).