290 likes | 302 Views
This tutorial explores texture mapping techniques in computer graphics, including cube maps and using multiple textures for effects like bump mapping, specular mapping, and transparency mapping.
E N D
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
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 Y Neg Z Neg X Pos Z Pos X Pos Y 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 • 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 vec3vVaryingTexCoord; void main (void) { vVaryingTexCoord = normalize (vVertex.xyz); gl_Position = mvpMatrix* vVertex; } #version 330 out vec4 vFragColor; uniform samplerCubecubeMap; 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
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!
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 Arrays for (inti = 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 GLuintloc = glGetUniform (progID, “image_num”); glUniform1f (loc, counter); // some int • Then, in the vertex shader, use it as the 3rd 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); }