Task 6: “Level sampling” with mipmaps for texture mapping (25 pts)
Finally, update RasterizerImp::rasterize_textured_triangle(...)
to support sampling different mipmap levels (MipLevel
s). The GUI toggles RasterizerImp
’s LevelSampleMethod
variable lsm
using the L key. Please implement the following level sampling methods in the helper function Texture::sample
.
- When
lsm == L_ZERO
, you should sample from the zero-thMipLevel
, as in Part 5. - When
lsm == L_NEAREST
, you should compute the nearest appropriate mipmap level and pass that level as a parameter to the nearest or bilinear sample function. - When
lsm == L_LINEAR
, you should compute the mipmap level as a continuous number. Then compute a weighted sum of using one sample from each of the adjacent mipmap levels as described in lecture.
In addition, implement Texture::get_level
as a helper function. You will need $(\frac{du}{dx}, \frac{dv}{dx})$ and $(\frac{du}{dy}, \frac{dv}{dy})$ to calculate the correct mipmap level. In order to get these values corresponding to a point $(x,y)$ inside a triangle, you must perform the following.
- Calculate the uv barycentric coordinates of $(x,y)$, $(x+1,y)$, and $(x,y+1)$ in
rasterize_textured_triangle(...)
assp.p_uv
,sp.p_dx_uv
, andsp.p_dy_uv
, assign them to aSampleParams
structsp
, along with other values required by the struct, and passsp
toTexture::get_level
- Calculate the difference vectors
sp.p_dx_uv - sp.p_uv
andsp.p_dy_uv - sp.p_uv
insideTexture::get_level
, and finally - Scale up the difference vectors accordingly by the width and height of the full-resolution texture image.
With these, you can proceed with the calculation from the lecture slides.
Notes:
- The
lsm
andpsm
variables can be set independently and interacted independently. In other words, all combinations ofpsm==[P_NEAREST, P_LINEAR] x lsm==[L_ZERO, L_NEAREST, L_LINEAR]
are valid. - When
lsm == L_LINEAR
andpsm == P_LINEAR
, this is known as trilinear sampling, or trilinear texture filtering, as described in lecture. - You may find it helpful to visualize what parts of the image use different levels of the mipmap. One way to do this is by normalizing the value returned by
Texture::get_level
by the maximum level (i.e. size of the mipmap) and have that value returned byTexture::sample
as a color. Zoom in and out of the image to see how the levels change. This is a great way to both debug your implementation as well as gain intuition about level sampling! See below for two examples, where we zoom out/in to illustrate how the computed levels change. - Please be careful do not make copies of an entire Miplevel. Make sure you always use a pointer or a reference to access the miplevel. Copying entire miplevels as arguments is extremely slow!
For convenience, here is a list of functions you will need to modify:
RasterizerImp::rasterize_textured_triangle
Texture::sample
Texture::get_level
Extra Credit: Implement anisotropic filtering or summed area tables. Show comparisons of your method to nearest, bilinear, and trilinear sampling. Use clock()
to measure the relative performance of the methods.
For Your Write-Up: Task 6
- Explain level sampling in your own words and describe how you implemented it for texture mapping.
- You can now adjust your sampling technique by selecting pixel sampling, level sampling, or the number of samples per pixel. Describe the tradeoffs between speed, memory usage, and antialiasing power between the three various techniques.
- Using a png file you find yourself, show us four versions of the image, using the combinations of
L_ZERO
andP_NEAREST
,L_ZERO
andP_LINEAR
,L_NEAREST
andP_NEAREST
, as well asL_NEAREST
andP_LINEAR
.- To use your own png, make a copy of one of the existing svg files in svg/texmap/ (or create your own modelled after one of the provided svg files). Then, near the top of the file, change the texture filename to point to your own png. From there, you can run ./draw and pass in that svg file to render it and then save a screenshot of your results.
- Note: Choose a png that showcases the different sampling effects well. You may also want to zoom in/out, use the pixel inspector, etc. to demonstrate the differences.
- Extra credit: If you implemented any extra filtering methods, describe them and show comparisons between your results with the other above methods.