Texture Mapping Part II

advertisement
TEXTURE MAPPING PART II
CS 4363/6353
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 Z
OpenGL SuperBible – Chapter 7
Neg Y
Neg X
Pos Z
Pos X
Pos Y
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
•
Example
glTexParameteri(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
http://www.whatsthelatest.net/tutorials/run-macs-flurry-screensaver-windows-xp/
glPolygonMode (GL_FRONT, GL_POINTS)
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 ARRAYS
for (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);
}
Download