Task 6: “Level sampling” with mipmaps for texture mapping
Finally, update RasterizerImp::rasterize_textured_triangle(...) to support sampling different mipmap levels (MipLevels). 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 aSampleParamsstructsp, along with other values required by the struct, and passsptoTexture::get_level - Calculate the difference vectors
sp.p_dx_uv - sp.p_uvandsp.p_dy_uv - sp.p_uvinsideTexture::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
lsmandpsmvariables 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_LINEARandpsm == 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_levelby the maximum level (i.e. size of the mipmap) and have that value returned byTexture::sampleas 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_triangleTexture::sampleTexture::get_level
Extra Credit (1 pt): 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_ZEROandP_NEAREST,L_ZEROandP_LINEAR,L_NEARESTandP_NEAREST, as well asL_NEARESTandP_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.
- As a reminder, your screenshots need to be generated by using the
'S'hotkey, not using your operating systems native screenshotting mechanism. You can refer back to our guide on Using the GUI on how to generate these images, and where to find them once they’re generated.
- Extra credit: If you implemented any extra filtering methods, describe them and show comparisons between your results with the other above methods.