Texture Mapping and Texture Coordinates
In today's lecture, I want to understand texture coordinates and the use of textures from within shaders.
I want to discuss important technicalities about how to load and access texture files and slightly more complicated uses of textures.
Afterwards, I wanted to discuss slightly more complicated use of textures (textures that are significantly more complicated will be the main focus next week).
Textures allow us to "wallpaper" triangles with images. It has more fine-grained control of the appearance than vertex colors alone.
Then we consider a triangle we want "textured with this image, and supply the texture coordinates for each vertex".
Then we consider a triangle we want "textured". These coordinates indicate where in the system the triangle draws. Lastly, the triangle inherits that same texture content when placed back into the 3D world.
attribute vec22 vTexCoord;
varying vec2 fTexCoord;
and fTexCoord = vTexCoord after having stuff inside of the fragment shader.
Now samplers are textures that are seen from the shader's perspective as evidence. Samplers support "lookup"operations with float-valued coordinates that retrieve the underlying color from a texture image.
This is interpolated like
vec3 textColor = texture2D(texSampler1, fTexCoord).xyz;
From a hardware point of view, these samplers reside in GPU's texture memory, which reside in the graphics pipeline.
Texture coordinates need to be treated as any other attribute, as far as initialization/buffering is concerned. Here is the coordinates for the texture
// vertex texture coordinates
var vertexTextureCoords = new Float32Array(
[ 0, 0, 1, 0, 1, 1, 0, 1,
1, 0, 1, 1, 0, 1, 0, 0,
0, 1, 0, 0, 1, 0, 1, 1,
0, 0, 1, 0, 1, 1, 0, 1,
1, 1, 0, 1, 0, 0, 1, 0,
1, 1, 0, 1, 0, 0, 1, 0 ]);
[...]
// a buffer for textures
var textureBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, textureBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertexTextureCoords, gl.STATIC_DRAW);
textureBuffer.itemSize = 2;
textureBuffer.numItems = 24;
Finally, texture images need to be loaded into JavaScript. This is also evidenced in the homework.
[...]
// Set up texture
var texture1 = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
var image1 = new Image();
var texture2 = gl.createTexture();
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, texture2);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
var image2 = new Image();
function initTextureThenDraw()
{
image1.onload = function() { loadTexture(image1,texture1); };
image1.crossOrigin = "anonymous";
image1.src = "https://farm6.staticflickr.com/5564/30725680942_e3bfe50e5e_b.jpg";
image2.onload = function() { loadTexture(image2,texture2); };
image2.crossOrigin = "anonymous";
image2.src = "https://farm6.staticflickr.com/5726/30206830053_87e9530b48_b.jpg";
window.setTimeout(draw,200);
}
[...]
this code loads everything.
The first step is the create a Graphics Library "Texture object", indicating to the library that I am working with a specific texture mapping unit and associate the WebGL texture to the texture mapping unit (tmu).
GPUs have at least 8 Texture Mapping Units, if not more.
Then load a placeholder image and create a JavaScript object to hold the actual image once we have a chance to do it.
Afterwards, a function is written to do the actual "loading" of the texture images. It is the function initTextureThenDraw(). Afterwards, I call it at the end of the setup function to invoke the commands.
We should specify that images be downloaded from a URL, as follows:
function initTextureThenDraw()
{
image1.onload = function() { loadTexture(image1,texture1); };
image1.crossOrigin = "anonymous";
image1.src = "https://farm6.staticflickr.com/5564/30725680942_e3bfe50e5e_b.jpg";
image2.onload = function() { loadTexture(image2,texture2); };
image2.crossOrigin = "anonymous";
image2.src = "https://farm6.staticflickr.com/5726/30206830053_87e9530b48_b.jpg";
window.setTimeout(draw,200);
}
Afterwards, we can use MipMapping to avoid aliasing.
If your shader or texture goes outside of the [0,1] range you have to control it using the following lines of code:
// Optional ... if your shader & texture coordinates go outside the [0,1] range
// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
// gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
The final thing I need to do is to handle the textures during the draw() loop. This is the code respresented by the following lines:
gl.bindBuffer(gl.ARRAY_BUFFER, textureBuffer);
gl.vertexAttribPointer(shaderProgram.texcoordAttribute, textureBuffer.itemSize,
gl.FLOAT, false, 0, 0);
// Bind texture
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, texture2);



Comments
Post a Comment