Optimized WebGL Morphing

Transform Vertices & Texels

Preliminary Morphing Tutorial Introduction Software Applications Prepare 3D Models Combine Both 3D Models Combine Both Textures See the Texture Convert for WebGL Allocate the VBO Shader Timing Morph Textures Vertex Shader Fragment Shader Summary See More!

Introduction

The morphing pyramid to cube example interactively animates the transition between a grey brick pyramid and a colorful cube. Learn how to transform both vertices and textures during a morphing animation sequence. This tutorial offers insights into optimized WebGL development. This tutorial discusses some techniques to create fast loading and lightweight WebGL morphing animation. This article explains how to assign portions of one vertex buffer object to different attributes. The example demonstrates mixing both vertices and texels, based on animation timing.

This article explains how to compact data for use with WebGL. The subject matter is at an intermediate level. It's assumed readers know how to load vertex buffer objects and textures. This tutorial also builds on knowledge from the morphing animation tutorial.

The morphing pyramid to cube example uploads just one vertex buffer object (VBO). The VBO combines four features. The VBO includes both sets of mesh vertices and both sets of texel coordinates. The VBO includes all vertices and texture coordinates to define the shape and color of both mesh elements. VBOs offer efficient use of the graphics processing unit (GPU) for rapid display of graphics. The morphing pyramid to cube example packs as much as possible into one VBO. The fewer VBOs the better for speed, as long as the VBO does not exceed the processor's maximum size for a VBO.

Additionally the morphing pyramid to cube uploads just one texture for both mesh models. Animated interactive morphing adjusts texture coordinates based on timing. Seven Thunder Software used the free 3D DAE Translator to convert models from DAE format into arrays for use with WebGL. You're welcome to use the 3D DAE Translator or any other utility that converts from a 3D modeling format to a set of JavaScript arrays.

Software Applications

Applications used to create the morphing pyramid to cube include Photoshop, 3DS Max, and Eclipse. Seven Thunder Software uses 3DS Max, however free or inexpensive 3D modeling and rendering software most likely includes similar features.

Prepare 3D Models

This section briefly explains how to combine two models and two textures into one model and one texture.

Combine Both 3D Models

With 3D modeling software such as 3DS Max, model, map, and attach the pyramid and cube. Create and map the pyramid. Create and map the cube. Attach the pyramid to the cube. The final result is one mesh with both shapes.

Combine Both Textures

With graphical editing software such as Photoshop, create one image which includes both textures. You can place the textures side by side or stack the textures on top of each other. However the final result must have dimensions which can be represented as powers of two. For example a 512 x 512 pixel texture can be represented as 29 x 29. 512 can be represented as a power of 2 because 29 = 512.

Assign the image as a diffuse map in 3DS Max. Edit texture coordinates with 3DS Max's UVW Unwrap feature. Move model texels such that they align correctly with the map. The follow texture maps the cube's colors with the top area of the image, and the pyramid colors with the bottom area of the image.

Texture Map Combines Colorful Cube & Pyramid Bricks

Rainbow Texture Map

Convert for WebGL

Now that you have combined both models and textures together, convert the data into a set of JavaScript arrays for use with WebGL. Download 3D DAE Translator if you like, or use whatever works to convert from a 3D modeling format to JavaScript arrays.

Allocate the VBO

Create and upload a VBO. The VBO includes two sections. The first section of the VBO includes vertices and texels describing the pyramid. The second section includes vertices and texels describing the cube. The vertex shader needs to associate attributes with portions of the VBO.

Describe the format of data within the VBO with WebGL's vertexAttribPointer() function. The 3D DAE Translator prepares interleaved vertices and texels. The first three entries in the vertex-texel array represent X,Y,Z vertex coordinates. The next two entries represent S,T texel coordinates. The next three entries represent X,Y,Z vertex coordinates, and so on until all vertices and texels are included in the array. The following listing shows part of the pyramid-cube's vertex-texel array.

The line 50.000000,50.000000,-50.000000, is the first set of vertices. The line 0.487070,0.949212, is the first set of texels.

this.aVertices = new Float32Array([
50.000000,50.000000,-50.000000,
0.487070,0.949212,
50.000000,-50.000000,-50.000000,
0.482617,0.810769,
-50.000000,-50.000000,-50.000000,
...
]);

The morphing pyramid to cube vertex shader includes two attributes which process vertices. The attribute vec4 a_position represents the pyramid's vertices. The attribute vec4 a_position_morph represents the cube's vertices.

The following JavaScript listing demonstrates one method to prepare attribute a_position_morph, to process the cube's vertices. The reference entity.nOffset is an integer offset within the VBO where the cube's data begins. The pyramid's data begins at zero and ends at entity.nOffset - 1.

First obtain a pointer to the vertex shader's attribute named a_position_morph. Second use vertexAttribPointer() to declare which data within the VBO should process through a_position_morph. Third enable the attribute a_position_morph.

entity.aPositionMorph = gl.getAttribLocation
(
controller.program, 
"a_position_morph"
);
    
//stride, offset
gl.vertexAttribPointer
(
entity.aPositionMorph, 
3, 
gl.FLOAT, 
gl.FALSE, 
20, 
entity.nOffset
);
  
   
gl.enableVertexAttribArray
( 
entity.aPositionMorph
);

Shader Timing

The 3d swimming fish example times morph transitions per animation frame with the vertex shader uniform uf_time. In other words one uniform named uf_time, handles the timing of morphing transitions between meshes. The morphing animation tutorial provides more details regarding application of timing between JavaScript and the vertex shader.

Vertex Shader Morph Textures

The morphing pyramid to cube example and the swimming fish example use different vertex shaders because the morphing pyramid to cube example discussed here morphs or blends vertices and textures. The swimming fish only morphs vertices. The morphing pyramid to cube example uploads just one texture, but prepares two attributes to process different sections of the same texture.

The following JavaScript listing demonstrates assigning a specific set of texels to the attribute referenced by entity.aTexCoord. Variable entity.aTexCoord points to attribute vec2 a_tex_coord1 in the vertex shader.

WebGL function vertexAttribPointer() instructs the GPU to process 2 floating point values through a_tex_coord1. The floating point values are located 20 Bytes apart in the VBO. Attribute a_tex_coord1 should begin processing at 12 Bytes from the cube's vertex entries in the VBO.

In other word's entity.nOffset represents the location within the VBO where the cube's vertices begin. Each vertex coordinate uses four Bytes. There are three coordinates per vertex. Each vertex includes one X, one Y, and one Z coordinate. Four Bytes times three coordinates equals twelve. Therefore the texels begin at the twelfth Byte from the cube's vertices.

gl.vertexAttribPointer
(
 entity.aTexCoord, 
 2, 
 gl.FLOAT, 
 gl.FALSE, 
 20, 
 entity.nOffset+12
);   

The morphing animation tutorial explains how to use the WebGL mix() function to blend vertices together. The result morphs vertices based on the value within uniform uf_time. This article demonstrates how to use the WebGL mix() function to blend texels together. The result morphs textures based on the value within uniform uf_time.

The following listing demonstrates blending texels within attribute a_tex_coord1 with texels within attribute a_tex_coord0. The result is assigned to varying v_tex_coord0. Attribute a_tex_coord0 processes texels from the pyramid portion of the texture map. Attribute a_tex_coord1 processes texels from the cube portion of the texture map. The WebGL mix() function returns a texel coordinate representing a percentage between the two sections of the texture. A more accurate texture blend would sample and mix the color values between both portions of the texture. This example simply takes an intermediate texture coordinate.

v_tex_coord0 = mix(
 a_tex_coord1,
 a_tex_coord0,
 uf_time
);  

The Vertex Shader

The following vertex shader morphs both textures and vertices. JavaScript uploads a value to uniform uf_time for each frame of animation. Uniform uf_time indicates the percentage of base and target vertices and texels to blend with the WebGL mix() function. Notice mix() is called twice. The first call passes vertex attribute parameters to mix(). The second call passes texel attribute parameters to mix().

attribute vec4 a_position;  
attribute vec4 a_position_morph; 
attribute vec2 a_tex_coord0;
varying vec2 v_tex_coord0;

attribute vec2 a_tex_coord1;
varying vec2 v_tex_coord1;
           
uniform mat4 um4_matrix;
uniform mat4 um4_pmatrix; 
uniform float uf_time;
           
void main(void) {
vec4 v4_mix = mix(
 a_position_morph,
 a_position,
 uf_time
);

gl_Position = um4_pmatrix * um4_matrix * v4_mix;

v_tex_coord0 = mix(
 a_tex_coord1,
 a_tex_coord0,
 uf_time
);   
}

Fragment Shader

The morphing pyramid to cube example uses the same fragment shader as the swimming fish. The shader just samples the texture at the texel passed through varying v_tex_coord0.

Summary

The morphing pyramid to cube example interactively animates the transition between a grey brick pyramid and a colorful cube. This tutorial offered insights into optimized WebGL development. This article discussed some techniques to create fast loading and lightweight WebGL morphing animation. This lesson explained how to assign portions of one vertex buffer object to different attributes. This example demonstrated mixing both vertices and texels, based on animation timing.

Have fun and love learning! Enjoy more WebGL Morph Animation Examples.

WebGL Morph Animation Examples

Copyright © 2015 Seven Thunder Software. All Rights Reserved.
WebGL Games E-Book Screen Shots