05 Introduction to WebGL Programming Full
05 Introduction to WebGL Programming Full
Programming
Agenda
• Evolution of the OpenGL Pipeline
• Prototype Applications in WebGL
• OpenGL Shading Language (GLSL)
• Vertex Shaders
• Fragment Shaders
• Examples
Examples
Primitive Fragment
Setup and Coloring and Blending
Rasterization Texturing
Pixel
Data
Texture
Store
Vertex
Vertex
Transform and
Data
Lighting
Primitive Fragment
Setup and Coloring and Blending
Rasterization Texturing
Pixel
Data
Texture
An Evolutionary Change
• OpenGL 3.0 introduced the deprecation model
– the method used to remove features from OpenGL
• The pipeline remained the same until OpenGL
3.1 (released March 24th, 2009)
• Introduced a change in how OpenGL contexts
are used
Context Type Description
• OpenGL ES 2.0
• WebGL
Vertex Fragment
Rasterizer
Processing Processing
Vertex Fragment
Shader Shader
WebGL Programming in a Nutshell
// Configure WebGL
gl.useProgram( program );
function render()
{
gl.clear( gl.COLOR_BUFFER_BIT );
gl.drawArrays( gl.TRIANGLES, 0, 3 );
}
Representing Geometric Objects
GL_TRIANGLES GL_TRIANGLE_FAN
GL_TRIANGLE_STRIP
Our Second Program
var vertices = [
vec4( -0.5, -0.5, 0.5, 1.0 ), 6
7
vec4( -0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, 0.5, 0.5, 1.0 ), 1
2
vec4( 0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, -0.5, -0.5, 1.0 ),
vec4( -0.5, 0.5, -0.5, 1.0 ), 4 7
vec4( 0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, -0.5, -0.5, 1.0 ) 0 3
Cube Data (cont’d)
• We’ll also set up an array of RGBA colors
• We can use vec3 or vec4 or just JS array
var vertexColors = [
[ 0.0, 0.0, 0.0, 1.0 ], // black
[ 1.0, 0.0, 0.0, 1.0 ], // red
[ 1.0, 1.0, 0.0, 1.0 ], // yellow
[ 0.0, 1.0, 0.0, 1.0 ], // green
[ 0.0, 0.0, 1.0, 1.0 ], // blue
[ 1.0, 0.0, 1.0, 1.0 ], // magenta
[ 0.0, 1.0, 1.0, 1.0 ], // cyan
[ 1.0, 1.0, 1.0, 1.0 ] // white
Arrays in JS
function quad(a, b, c, d) {
var indices = [ a, b, c, a, c, d ];
for ( var i = 0; i < indices.length; ++i ) {
points.push( vertices[indices[i]] );
function colorCube() {
quad( 1, 0, 3, 2 );
7 6
quad( 2, 3, 7, 6 );
quad( 3, 0, 4, 7 ); 1
quad( 6, 5, 1, 2 ); 2
quad( 4, 5, 6, 7 );
4 7
quad( 5, 4, 0, 1 );
}
0 3
Storing Vertex Attributes
• Vertex data must be stored in a Vertex Buffer Object (VBO)
• To set up a VBO we must
– create an empty by calling gl.createBuffer(); ()
– bind a specific VBO for initialization by calling
• For contiguous groups of vertices, we can use the simple render function
function render()
{
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawArrays( gl.TRIANGLES, 0, numVertices );
requestAnimFrame( render );
}
• gl.drawArrays initiates vertex shader
• requestAnimationFrame needed for redrawing if anything is changing
• Note we must clear both the frame buffer and the depth buffer
• Depth buffer used for hidden surface removal
– enable HSR by gl.enable(gl.GL_DEPTH) in init()
Shaders and GLSL
Vertex Shaders
• A shader that’s executed for each vertex
– Each instantiation can generate one vertex
– Outputs are passed on to rasterizer where they are interpolated and
available to fragment shaders
– Position output in clip coordinates
mat4 m;
vec4 a, b, c;
b = a*m;
c = m*a;
Components and Swizzling
• For example:
vec3 v;
v[1], v.y, v.g, v.t - all refer to the same element
• Component swizzling:
•
vec3 a, b;
a.xy = b.yx;
Qualifiers
• attribute
– vertex attributes from application
• varying
– copy vertex attributes and other variables from vertex shaders to fragment
shaders
– values are interpolated by rasterizer
varying vec2 texCoord;
varying vec4 color;
• uniform
– shader-constant variable from application
• Built in
– Arithmetic: sqrt, power, abs
– Trigonometric: sin, asin
– Graphical: length, reflect
• User defined
Built-in Variables
• gl_Position
– (required) output position from vertex shader
• gl_FragColor
– (required) output color from fragment shader
• gl_FragCoord
– input fragment position
• gl_FragDepth
– input depth value in fragment shader
Simple Vertex Shader for Cube Example
void main()
{
fColor = vColor;
gl_Position = vPosition;
}
Simple Fragment Shader for Cube Example
• We’ve created a function for this course to make it easier to load your
shaders
– available at course website
initShaders(vFile, fFile );
loc =
gl.getUniformLocation( program,“name” );
Initializing Uniform Variable Values
Uniform Variables
gl.uniform4f( index, x, y, z, w );
• HTML file:
– contains shaders
– brings in utilities and application JS file
– describes page elements: buttons, menus
– contains canvas element
• JS file
– init()
• sets up VBOs
• contains listeners for interaction
• sets up required transformation matrices
• reads, compiles and links shaders
Buffering, Animation and Interaction
Double Buffering
• The processes of rendering into a frame buffer and displaying the
contents of the frame buffer are independent
function render()
{
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.uniform3fv(thetaLoc, theta);
time+=dt;
gl.uniform1f(timeLoc, time);
gl.drawArrays( gl.TRIANGLES, 0, numVertices );
requestAnimFrame( render );
}
// in vertex shader
gl.uniform3fv(thetaLoc, theta);
requestAnimFrame( render );
}
Transformations
Synthetic Camera Model
camera
tripod model
Transformations
• Transformations take us from one “space”
to another
– All of our transforms are 4×4 matrices
Modeling Modeling
Transform Transform
Object Coords.
Perspective
Model-View Projection Viewport 2D Window
Vertex Data Division
Transform Transform Transform Coordinates
(w)
Normalized
World Coords. Eye Coords. Clip Coords. Device
Camera Analogy and Transformations
• Projection transformations
– adjust the lens of the camera
• Viewing transformations
– tripod–define position and orientation of the viewing volume in
the world
• Modeling transformations
– moving the model
• Viewport transformations
– enlarge or reduce the physical photograph
3D Transformations
• A vertex is transformed by 4×4 matrices
– all affine operations are matrix multiplications
void main()
{
// Compute the sines and cosines of theta for
// each of the three axes in one computation.
vec3 angles = radians( theta );
vec3 c = cos( angles );
vec3 s = sin( angles );
Vertex Shader for Rotation of Cube
(cont’d)
color = vColor;
gl_Position = rz * ry * rx * vPosition;
}
Sending Angles from Application
// in init()
var theta = [ 0, 0, 0 ];
var axis = 0;
thetaLoc = gl.getUniformLocation(program, "theta");
// in render()
Property Description
Diffuse Base object color
Specular Highlight color
Ambient Low-light color
Emission Glow color
Shininess Surface smoothness
Adding Lighting to Cube
// vertex shader
in vec4 vPosition;
in vec3 vNormal;
out vec4 color;
void main()
{
// Transform vertex position into eye coordinates
vec3 pos = vec3(ModelView * vPosition);
z x screen
geometry
t image
s
Texture Mapping and the OpenGL Pipeline
Rasterizer Fragment
Shader
Pixels Pixel Pipeline
Applying Textures
• Three basic steps to applying a texture
1. specify the texture
• read or generate image
• assign to texture
• enable texturing
2. assign texture coordinates to vertices
3. specify texture parameters
• wrapping, filtering
Texture Objects
• Have WebGL store your images
– one image per texture object
• Create an empty texture object
t
1, 1 (s, t) = (0.2, 0.8)
(0, 1) A
a
c (0.4, 0.2)
b
B C
(0, 0) (1, 0) s (0.8, 0.4)
Applying the Texture in the Shader
void main()
{
gl_FragColor = fColor*texture2D( texture, fTexCoord );
}
Applying Texture to Cube
// add texture coordinate attribute to quad function
function quad(a, b, c, d)
{ pointsArray.push(vertices[a]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[0]);
pointsArray.push(vertices[b]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[1]);
.
.
Creating a Texture Image
var image1 = new Array()
for (var i =0; i<texSize; i++) image1[i] = new Array();
for (var i =0; i<texSize; i++)
for ( var j = 0; j < texSize; j++)
image1[i][j] = new Float32Array(4);
for (var i =0; i<texSize; i++) for (var j=0; j<texSize; j++) {
var c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0));
image1[i][j] = [c, c, c, 1]; }
void main()
{
color = vColor;
texCoord = vTexCoord;
gl_Position = vPosition;
}
Fragment Shader
varying vec4 color;
varying vec2 texCoord;
void main()
{
gl_FragColor = color * texture( texture,
texCoord );
}
What we haven’t talked about
• Off-screen rendering
• Compositing
• Cube maps
What’s missing in WebGL (for now)