CS 455 Lecture 12 – Texture Mapping
March 10, 2015 by Chris Johnson. Filed under cs455, lectures, spring 2015.
Agenda
- what ?s
- adding detail without geometry
- uv coordinates
Texture
class
- interpolation
- repetition
While You’re Waiting
- I have an image of Campbell’s Soup label that is 480 pixels wide and 201 pixels tall. What must be the relative dimensions of the soup can upon which the label is affixed?
TODO
- As a lab exercise, create an interactive renderer of a Campbell’s soup can. Find
can.obj
and labels.ppm
in repo/models
. The can has radius 1 and height 2.631. It is centered on the origin. Use a texture to put the label on the side of the can. How can you determine its texture coordinates? A vertex’s y-coordinate can be range mapped to [0, 1] to get a texture’s v coordinate. The u coordinate is proportional to the angle we’ve wound around the can to reach the vertex. How do we get that angle? By mapping a vertex’s xz-coordinates from Cartesian coordinates to polar coordinates, which are a radius-angle pair. Since we really only care about the angle, we ignore the radius and focus on the fact that tan a = z / x
. Use GLSL’s atan(opp, adj)
to solve for a
, and then range map to [0, 1].
Texture Mapping
- Load in an image, noting its width, height, pixel data, and number of color channels. See the
Image
class in libtwodee
or use your own. Shoot for dimensions that are powers of two. Otherwise, you may need to specify the byte alignment:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- Create a texture, specifying its texture unit and texture parameters:
Texture texture = new Texture(0);
texture->Wrap(Texture::REPEAT);
texture->Channels(Texture::RGB);
texture->Magnify(Texture::MAGNIFY_NEAREST);
texture->Minify(Texture::MINIFY_LINEAR);
texture->Upload(image.GetWidth(), image.GetHeight(), image.GetPixels());
- Associate texture coordinates with each vertex either as a vertex attribute or computed in the shader.
- Add a
sampler2D
uniform to the shader where you’d like to do texture lookup:
uniform sampler2D tex;
- In
OnDraw
or OnInitialize
, register the texture with the sampler2D
uniform:
shader_program->SetUniform("tex", *texture);
- Retrieve the texture data using the
texture2D
function:
vec3 rgb = texture2D(tex, ftexcoords).rgb;
float alpha = texture2D(tex, ftexcoords).a;
float red = texture2D(tex, ftexcoords).r;
- Incorporate the texture sample into your rendering in any way you please: as albedo, as an offset to the vertex data, as a mask to filter out fragments, and so on.
Haiku
on texture mapping
I’m know this place well
Just like the back of my hand
Where the map’s tattooed
show