Upload
dylan-jared-riley
View
215
Download
0
Tags:
Embed Size (px)
Citation preview
CS 4363/6353
TEXTURE MAPPING PART II
WHAT WE KNOW• We can open image files for reading
• We can load them into texture buffers
• We can link that texture buffer to a variable in the fragment shader
• We can access the texture in the fragment shader using a sampler2D
RECTANGLE TEXTURES• There’s another mode called GL_TEXTURE_RECTANGLE
• Works just like GL_TEXTURE_2D, but…
• Texture coordinate range is the width and height of the image (not normalized)
• Can’t be mipmapped
• Texture coordinates cannot repeat
• Do not support compression
• Useful for when you need to process image data (image processing), not just texture
• Typically, you create an orthographic projection with 0,0 on the bottom left
• First quadrant of the Cartesian system
OpenGL SuperBible Example
CUBE MAPPING• Used for “skyboxes”
• Used for faking reflections
• Comprised of 6 individual images
• Treated as one texture
• Can be mipmapped (glGenerateMipmap (GL_TEXTURE_CUBE_MAP))
• We’re going to have 3 texture coordinates!
• S
• T
• R
• It’s easiest to think of this as a normal because the cube “surrounds” you
Neg X
Neg Y
Neg ZPos X
Pos Y
Pos Z
OpenGL SuperBible – Chapter 7
LOADING CUBE MAPS• Create/Bind a buffer like normal
• Still load using glTexImage2D, but must pass:
• GL_TEXTURE_CUBE_MAP_POSITIVE_X
• GL_TEXTURE_CUBE_MAP_NEGATIVE_X
• GL_TEXTURE_CUBE_MAP_POSITIVE_Y
• GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
• GL_TEXTURE_CUBE_MAP_POSITIVE_Z
• GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
• Example:
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA,w, h, 0, GL_BGR, GL_UNSIGNED_BYTE, bitmap_data);
TEXTURE PARAMETERS• Still have MAG and MIN filters, but…
• Specify it’s a GL_TEXTURE_CUBE_MAP
• Specify how to wrap each texture coordinate
• ExampleglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
SKYBOXES• Literally just a giant box with a texture on it
• It follows the camera!
• It doesn’t rotate with the camera
• How do we map the cube map to the cube?
• What are the texture coordinates?
SKYBOXES• Literally just a giant box with a texture on it
• It follows the camera!
• It doesn’t rotate with the camera
• How do we map the cube map to the cube?
• What are the texture coordinates? The same as their positions!
SKYBOXES• Literally just a giant box with a texture on it
• It follows the camera!
• It doesn’t rotate with the camera
• How do we map the cube map to the cube?
• What are the texture coordinates?
• How do we sample the texture in our fragment shader?
Using a sampleCube variable
// Skybox Shader by Richard S. Wright, Jr.
#version 330
in vec4 vVertex;
uniform mat4 mvpMatrix;
varying vec3 vVaryingTexCoord;
void main (void) {
vVaryingTexCoord = normalize (vVertex.xyz);
gl_Position = mvpMatrix * vVertex;
}
#version 330
out vec4 vFragColor;
uniform samplerCube cubeMap;
varying vec3 vVaryingTexCoord;
void main (void) {
vFragColor = texture (cubeMap, vVaryingTexCoord);
}
REFLECTIONS
OpenGL SuperBible – Chapter 7
// Reflection Shader – Richard S. Wright Jr.
#version 330
in vec4 vVertex;
in vec3 normal;
uniform mat4 mvpMatrix;
uniform mat4 mvMatrix;
uniform mat3 normalMatrix; // Just the rots of the mv
uniform mat4 mInverseCamera; // The camera matrix inverted
smooth out vec3 vVaryingTexCoord;
void main (void) {
// Normal in eye space – only rots
vec3 vEyeNormal = normalMatrix * vNormal;
// Vertex in eye space
vec4 vVert4 = mvMatrix * vVertex;
vec3 vEyeVertex = normalize(vVert4.xyz/vVert4.w);
// Calculate a reflection vector, then invert it
vec4 vCoords = vec4(reflect(vEyeVertex, vEyeNormal), 1.0);
vCoords = mInverseCamera * vCoords;
vVaryingTexCoord.xyz = normalize(vCoords.xyz);
gl_Position = mvpMatrix * vVertex;
}
USING MULTIPLE TEXTURES• Second texture useful for:
• Adding multiple colors together
• Using it as a bump map
• Using it as a specular map
• Using it as a transparency map
FOR COLOR ALONE
BUMP MAPPING• Used to approximate very rough surfaces
• Using the second texture to adjust the normals of the surface
• Per fragment, not per vertex
• In the case below, all N◦L is the same
BUMP MAPPING• Used to approximate very rough surfaces
• Using the second texture to adjust the normals of the surface
• Per fragment, not per vertex
• In the case below, all N◦L is not the same
• Gives off a different amount of light!
• Note – the geometry has not changed!
EXAMPLE
EXAMPLE FROM BOOK
AN EXTREME EXAMPLE
http://www.chromesphere.com/Tutorials/Vue6/Optics-Basic.html
PARALLAX MAPPING• Approximate parallax
• Changes the texture coordinate based on view vector and normal
• Need a height map
http://www.jpjorge.com/index.php?headfile=portfolio.php&topic=4
http://www.virtualworldlets.net/Resources/Hosted/Resource.php?Name=ParallaxFlash
BILLBOARDING• Image always faces the camera (think of the math!)
• Typically has transparency
• Useful for trees
• Useful for particle effects
http://www.neotos.de/en/content/megaview-jogl-opengl-java-3d-engine
POINT SPRITES• OpenGL 1.5
• Based on billboarding
• Can place a 2D texture using a single point!
• Previously, needed two triangles
• 1/4th the bandwidth
• No aligning the quad to face the camera
• Using them
• Bind a 2D texture
• Draw using
glPolygonMode (GL_FRONT, GL_POINTS)
http://www.whatsthelatest.net/tutorials/run-macs-flurry-screensaver-windows-xp/
TEXTURE ARRAYS• Packing several images into a single texture units (GL_TEXTURE0)
• Good for 2D animations
• Similar use:• glBindTexture (GL_TEXTURE_2D_ARRAY, texBufID);
• glTexParameteri (GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
• However, to load the image, we are now in 3D!
glTexImage3D (GL_TEXTURE_2D_ARRAY, level, internal_format, w, h, depth, border, format, NULL);
• The depth parameter specifies how many images are in the array
LOADING THE ARRAYSfor (int i = 0; i < num_images; i++) {
data = loadBitmap (“image”+i+”.bmp”);
glTexSubImage(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, w,h, 1, GL_BGR, GL_UNSIGNED_BYTE, data);
}
ACCESSING THE IMAGES• Normally, you specify the image index from the client side
GLuint loc = glGetUniform (progID, “image_num”);
glUniform1f (loc, counter); // some int
• Then, in the vertex shader, use it as the 3 rd texture coordinate:
uniform float image_num;
in vec4 vTexCoords;
smooth out vec3 imageTexCoords;
void main (void) {
imageTexCoords.st = vTexCoords.st;
imageTexCoords.p = image_num;
…
}
YOUR FRAGMENT SHADER• Must have a sampler2DArray variable
• Must use the texture2DArray function
uniform sampler2DArray texture;
smooth in vec3 imageTexCoords;
out vFragColor;
void main () {
vFragColor = texture2DArray (texture, imageTexCoods.stp);
}