CS373 Part2 Lecture16to17 TextureMapping
CS373 Part2 Lecture16to17 TextureMapping
Chapter 2:
Texture Mapping
2.1 2D Texture Mapping
2.2 OpenGL texture mapping example
2.3 Notes on OpenGL texturing code
2.4 Texture mapping of surfaces
2.5 Bump mapping
2.6 Displacement mapping
2.7 3D Texturing
2.8 Texture synthesis
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 2
Modelling a large brick with individual polyhedral bricks is very
cumbersome.
A much easier solution is to model each side of the wall with a
single polygon and to map the image of a brick wall onto it.
+ =
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 3
Simple idea - Take a (rectangular) image to "stick on" to polygon
• WARNING: When using older OpenGL versions the image width and
height must be a power of 2 (e.g. 256 pixels)
Associate with the bottom-left, bottom-right, top-left and top-right corner of
the image the texture coordinates (0,0), (1,0), (0,1), and (1,1), respectively.
Specify texture coordinates (s,t) for each vertex of the polygon.
Texture map (array of texels) Polygon with texture coordinates Textured polygon
(0.7, 1)
(0, 1) (1, 1) (0.7, 1)
(1, 0.1)
(0, 0)
(0, 0) (1, 0) (0, 0) (1, 0.1)
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 4
What happens to a texture mapped polygon if we transform it?
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
glTexCoord2f(1, 0); glVertex3f(3, 0, 0);
glTexCoord2f(1, 1); glVertex3f(3, 3, 0);
glTexCoord2f(0, 1); glVertex3f(0, 3, 0);
glEnd();
glRotatef(45,0,0,1); glScalef(2,0.5,1);
? ?
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 5
How can we rotate a texture by 900 without rotating the polygon?
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
glTexCoord2f(1, 0); glVertex3f(3, 0, 0);
glTexCoord2f(1, 1); glVertex3f(3, 3, 0);
glTexCoord2f(0, 1); glVertex3f(0, 3, 0);
glEnd();
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 6
Texture values may be
• copied directly to the output image, or
• used to modulate (i.e. multiply) the colour or alpha value of
the shaded polygon, or
• blended with shaded polygon
Can specify that texture map repeats indefinitely
• "Tiles" the polygons it is applied to
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 8
An easy format for storing images is ‘ppm’ (Portable Pixel Map).
• The first "line" is a PPM identifier, e.g. "P3“.
• The next line consists of the width and height of the image.
• The last part of the header gives the maximum value of the colour components for
the pixels.
• In addition to the above required lines, a comment can be placed anywhere with a
"#" character, the comment extends to the end of the line.
• The following lines specify the pixels of the image as RGB components (left to right,
top to bottom).
First pixel
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 9
Store the texture into a 2D array of RGBA values. In C this
corresponds to a 1D array of size width*height*4.
GLubyte *texture; // The texture image
int texName; // ID of texture
// load texture
ifstream textureFile;
textureFile.open("Sulley3.ppm", ios::in);
if (textureFile.fail()){
cout << "\n Error loading the texture";
cout.flush(); exit(0);}
skipLine(textureFile); skipLine(textureFile);
textureFile >> textureWidth;
textureFile >> textureHeight;
int maxRGBValue; textureFile >> maxRGBValue;
texture = new GLubyte[textureWidth*textureHeight*4];
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 10
Want that the first texel of the texture map corresponds to the texture
coordinate (0,0) (which is at the bottom-left of the image)
• Have to reverse columns of the image, i.e. the first rows of pixels in the
image becomes the last rows of texels in the texture map.
int m,n,c;
for(m=textureHeight-1;m>=0;m--)
for(n=0;n<textureWidth;n++){
textureFile >> c;
texture[(m*textureWidth+n)*4]=(GLubyte) c;
textureFile >> c;
texture[(m*textureWidth+n)*4+1]=(GLubyte) c;
textureFile >> c;
texture[(m*textureWidth+n)*4+2]=(GLubyte) c;
texture[(m*textureWidth+n)*4+3]=(GLubyte) 255;}
textureFile.close();
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 11
// Ask OpenGL to generate a unique ID for the texture "Wrap" both s and
glGenTextures(1, &texName); t (i.e. "tile" the
texture) if texture
// Do the rest once for each texture map (only 1 in this case) parameters are >1.
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight,
0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
delete[] texture; Take "nearest
texel" from
texture map
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 12
// Output of the textured triangle
// Specify which texture to use (if multiple loaded)
glBindTexture(GL_TEXTURE_2D, texName);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_TEXTURE_2D); Replace each pixel on the polygon by the
texture (default - could omit this line)
glBegin(GL_TRIANGLES);
glTexCoord2f(0,0);
glVertex2f(0,0);
glTexCoord2f(1,0.1);
glVertex2f(1,0);
glTexCoord2f(0.7,1);
glVertex2f(0,1);
glEnd();
glDisable(GL_TEXTURE_2D);
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 13
glGenTextures(GLsizei n, GLuint *textures )
is a request for a given number of “texture handles”
• “Handles” are just integers used to identify texture maps.
They are returned in the given int array.
• In our example, only one is required.
glBindTexture(GLenum target, GLuint texture )
selects one of the texture maps as the current one
• target is GL_TEXTURE_2D if using a 2D texture.
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 14
The parameters GL_TEXTURE_WRAP_S and
GL_TEXTURE_WRAP_T specify how texture parameters (s,t)
outside the unit square (0,0) to (1,1) should be handled
• The repeat option tiles texture space with the given map
• Alternatively can clamp texture coordinates to the range [0,1].
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex3f(0,0,0);
glTexCoord2f(6,0);
glVertex3f(2,0,0);
glTexCoord2f(6,2);
glVertex3f(2,1,0);
glTexParameteri(GL_TEXTURE_2D,
glTexCoord2f(0,2); GL_TEXTURE_WRAP_S, GL_REPEAT);
glVertex3f(0,1,0);
glTexParameteri(GL_TEXTURE_2D,
glEnd(); GL_TEXTURE_WRAP_T, GL_CLAMP);
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 15
The parameter GL_TEXTURE_MAG_FILTER determines how to
interpolate between texel values when the pixel size is less
than the texel size
• GL_NEAREST or GL_LINEAR
Example: map a small glTexParameteri(
part of the texture image GL_TEXTURE_2D,
onto a large polygon GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glTexParameteri(
glVertex3f(0,0,0.2); GL_TEXTURE_2D,
glTexCoord2f(0.1,0); GL_TEXTURE_MAG_FILTER,
glVertex3f(2,0,0.2); GL_LINEAR);
glTexCoord2f(0.1,0.05);
glVertex3f(2,1,0.2);
glTexCoord2f(0,0.05);
glVertex3f(0,1,0.2);
glEnd(); Pixels on Texels of the
the screen texture map
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 16
The parameter GL_TEXTURE_MIN_FILTER determines how to average
texel values when the pixel size is greater than the texel size
• Either GL_NEAREST or GL_LINEAR or one of various MIP_MAPPING
options (see “The OpenGL Programming Guide”)
glTexParameteri(GL_TEXTURE_2D, glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER, GL_NEAREST); GL_TEXTURE_MIN_FILTER, GL_LINEAR);
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 17
Get aliasing problems if sampling texture at low sampling rates
• e.g. chequerboard pattern applied to a
ground plane that extends to the horizon
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 19
Which of the following statements about texture mapping is false?
(a) In order to repeat a texture image two times, we use the OpenGL constant GL_REPEAT and
use the texture coordinate 2.0 in the corresponding parameter direction.
(b) Texture mapping is useful for adding surface details to a model, without having to increase
the polygon count.
(c) Texture mapping with the mirror image of a texture image can be done by reversing one
texture coordinate during texture mapping, e.g., replacing s by 1-s.
(d) Texture mapping cannot be combined with shading, i.e., we cannot have shaded texture
mapped surfaces.
(e) In order to draw a model of a coke can, we need a 3D polygon mesh of the can, a 2D image of
the surface of the can (e.g., obtained by cutting open and flattening the can), and for each vertex
of the polygon mesh a 2D texture coordinate specifying the position of that point in the 2D image
of the can.
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 20
Up to now we only mapped textures onto individual polygons.
Mapping a texture onto a surface works analogously: simply
associate each vertex of the polygon mesh with a texture
coordinate. y
z dq
x
N=(x,0,z)
glBindTexture(GL_TEXTURE_2D, texName);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUAD_STRIP);
for (int segment=0; segment <= NUM_SEGMENTS; segment++){
s=(float) segment/(float) NUM_SEGMENTS;
theta=2.0f*Pi*s;
x = (float) cos(theta);
z = (float) sin(theta);
glTexCoord2f(1-s,0);
glVertex3f(x,bottomY,z);
glTexCoord2f(1-s,1);
glVertex3f(x,topY,z);
}
glEnd();
glDisable(GL_TEXTURE_2D);
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 22
glTexCoord2f(1-s,0);
glVertex3f(x,bottomY,z);
glTexCoord2f(1-s,1);
glVertex3f(x,topY,z);
(0,1) (1,1)
How can we “reverse” the
texture?
(0,0) (1,1) 23
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing
glTexCoord2f(1-s,0);
glVertex3f(x,bottomY,z);
glTexCoord2f(1-s,1);
glVertex3f(x,topY,z);
(0,1) (1,1)
How can we repeat
texture 5 times in s
direction and 2 times
in t direction?
(0,0) (1,1) 24
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing
glTexCoord2f(1-s,0);
glVertex3f(x,bottomY,z);
glTexCoord2f(1-s,1);
glVertex3f(x,topY,z);
(0,0) (1,1) 25
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing
glTexCoord2f(1-s,0);
glVertex3f(x,bottomY,z);
glTexCoord2f(1-s,1);
glVertex3f(x,topY,z);
(0,0) (1,1) 26
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing
Normal 2D texture mapping doesn't look right for uneven surfaces like
orange skin
• Texture should vary with illumination
© Jim Blinn,
University of Utah
Can get strong illusion of uneven surface by using a bump map to modulate
the surface normal before applying illumination calculations.
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 28
2D texture maps very limited for representing objects made
from textured 3D material like wood or marble
• e.g., consider how to stick a sheet of wood-grain veneer onto a sphere
to make it look like it was carved out of wood
3D volume of texels
Each polygon vertex has a 3D texture
coordinate
If polygon is rendered the position of a pixel in
the 3D texture space is determined and the
corresponding RGB/RGBA value is used.
Vertices which are shared between polygons (i.e., where polygons meet) have the
same texture coordinates. Assumed vertex A has the texture coordinates (0,0), which
texture coordinates do we have to define for the vertices B and C in order to get the
image shown below on the right?
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 31
The image on the right is used to texture map a square.
The texture mapping code to be used is:
glBegin(GL_QUADS);
glTexCoord2f(0.25,0);
glVertex3f(0,0,0);
glTexCoord2f(A,B);
glVertex3f(4,0,0);
glTexCoord2f(C,D);
glVertex3f(4,4,0);
glTexCoord2f(E,F);
glVertex3f(0,4,0);
glEnd();
© 2022 Burkhard Wuensche Dept. of Computer Science, University of Auckland COMPSCI 373 Computer Graphics & Image Processing 32