WebGL Loading Texture
Related Topics: GLSL Shader, Bitmap Font
Texture mapping is projecting a 2D image onto 3D model. It enhances the realism of the rendering by adding the surface details (texture) on a low-polygonal model and reducing lighting calculation.
Loading Texture
Another advantage of WebGL is that you do not need a separate library to load image files for WebGL texture mapping, because web browsers virtually support all image formats to read with <img> element.
webglUtils.js provides serveral functions to load textures for WebGL texture mapping depending on the texture types. These functions load a texture asynchronously from the given URL. When it is called, it returns the default 1x1 pixel texture object to the caller immediately while it is loading the target texture in background. After loading is completed, it will replace with the loaded texture object for you.
webglUtils | |
---|---|
Function | Description |
loadTexture(gl, url, repeat) | Load and configure a normal texture |
loadNormalmap(gl, url, repeat) | Load and configure a normalmap texture |
loadOcclusionmap(gl, url, repeat) | Load and configure an ambient occlusion (AO) texture (gl.LUMINANCE only) |
loadCubemap(gl, url) | Load and configure 6 cubemap textures (suffix 0 ~ 5 in the file name) |
setupDefaultTexture(gl, texId, type) | Assign a default texture map to the given texture object, texId
Suppoted texture types:
|
The following code is an example of loading a diffuse texture and drawing a model by mapping the texture onto the surface of the cube.
// global var
let gl = {};
...
// load diffuse texture
gl.tex0 = loadTexture(gl, "grid512.png", true);
// OR, assign 1x1 pixel white (default) texture
gl.tex0 = gl.createTexture();
setupDefaultTexture(gl, gl.tex0, TextureType.TEXTURE);
...
// bind texture before drawing
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, gl.tex0);
...
// draw model with VBO
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.ibo);
gl.drawElements(gl.TRIANGLES, gl.ibo.indexCount, gl.UNSIGNED_SHORT, 0);
...
The following is a typical texture setup for a normal texture with trilinear filtering with mipmaps and repeating mode on. Please see setupTexture() how the loaded texture is configured for other types.
// global var
let gl = {};
...
// example of loading and configuring normal texture
let image = new Image();
image.src = textureUrl;
image.onload = () =>
{
let texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
// copy bitmap to texture object
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
// tri-linear filter
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
// repeat mode for wrap
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
// generate mipmaps
gl.generateMipmap(gl.TEXTURE_2D);
gl.bindTexture(gl.TEXTURE_2D, null);
};
...
GLSL Shader for Texture Mapping
Once you load and create a textue object, you need to pass the texture map to the GLSL shader program with sample2D uniform and the texture coordinates, (s, t) as an additional vertex attribute. To read a texel value at the given texture coordinate from the texture map, use texture2D() or texture() for GLSL v3.
The following is an example of a shader program to apply a texture mapping.
// Vertex Shader for Texture Mapping
// vertex attributes
attribute vec3 vertexPosition; // vertex pos in object space
attribute vec2 vertexTexCoord0; // texture coord
// uniforms
uniform mat4 matrixModelViewProjection; // model-view-projection matrix
// output varying variables
varying vec2 texCoord0; // texture coord
void main(void)
{
// transform vertex position to clip space
gl_Position = matrixModelViewProjection * vec4(vertexPosition, 1.0);
// pass tex coord to fragment shader
texCoord0 = vertexTexCoord0;
}
// Fragment Shader for Texture Mapping
// uniforms
uniform sampler2D map0; // texture map #1
// input varying variables from vertex shader
varying vec2 texCoord0; // texture coord
void main(void)
{
// get texel from texture map
vec4 texel = texture2D(map0, texCoord0);
gl_FragColor = vec4(texel.rgb, 1.0);
}
Example
This example loads a texture and applys it to a cube. You can choose your own texture to display.
Fullscreen Demo: test_texture.html
GitHub Repo: test_texture.html