introduction to computer graphics with webglbackspaces.net/temp/webglmoocslidepdfs/week3.pdf2...
TRANSCRIPT
1
1
Introduction to Computer Graphics with WebGL
Ed Angel
Initializing Shaders
Computer Graphics with WebGL © Ed Angel, 2014
initShaders()
• Read shaders • Compile shaders • Create a program object • Link everything together • Link variables in application with variables in shaders
- Vertex attributes - Uniform variables
2Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Program Object
• Container for shaders - Can contain multiple shaders - Other GLSL functions
var program = gl.createProgram();
gl.attachShader( program, vertShdr ); gl.attachShader( program, fragShdr ); gl.linkProgram( program );
3Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
2
Reading a Shader
• Shaders are added to the program object and compiled • Usual method of passing a shader is as a null-terminated
string using the function gl.shaderSource( fragShdr, fragElem.text );
• If shader is in HTML file, we can get it into application by getElementById method
• If the shader is in a file, we can write a reader to convert the file to a string
4Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Adding a Vertex Shader
var vertShdr;var vertElem = document.getElementById( vertexShaderId );
vertShdr = gl.createShader( gl.VERTEX_SHADER );
gl.shaderSource( vertShdr, vertElem.text );gl.compileShader( vertShdr );
// after program object createdgl.attachShader( program, vertShdr );
5Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Shader Reader • Following code may be a security issue with some
browsers if you try to run it locally - Cross Origin Request
6
function getShader(gl, shaderName, type) { var shader = gl.createShader(type); shaderScript = loadFileAJAX(shaderName);if (!shaderScript) { alert("Could not find shader source: "+shaderName); }}
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
3
Precision Declaration
• In GLSL for WebGL we must specify desired precision in fragment shaders
- artifact inherited from OpenGL ES - ES must run on very simple embedded devices that
may not support 32-bit floating point - All implementations must support mediump - No default for float in fragment shader
• Can use preprocessor directives (#ifdef) to check if highp supported and, if not, default to mediump
7Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Pass Through Fragment Shader
#ifdef GL_FRAGMENT_SHADER_PRECISION_HIGH precision highp float;#else precision mediump float;#endif
varying vec4 fcolor;void main(void){ gl_FragColor = fcolor;}
8Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Error Checking 1 var vertElem = document.getElementById( vertexShaderId );
if ( !vertElem ) { alert( "Unable to load vertex shader ” + vertexShaderId ); return -1;}
9Computer Graphics with WebGL © Ed Angel, 2014
4
Error Checking 2 else {vertShdr = gl.createShader( gl.VERTEX_SHADER ); gl.shaderSource( vertShdr, vertElem.text ); gl.compileShader( vertShdr );
if ( !gl.getShaderParameter(vertShdr, gl.COMPILE_STATUS) ) { alert("Vertex shader failed to compile. The error log is:” + "<pre>” + gl.getShaderInfoLog( vertShdr ) + "</pre>”); return -1; } }
10Computer Graphics with WebGL © Ed Angel, 2014
1
1
Introduction to Computer Graphics with WebGL
Ed Angel
Shaders
Computer Graphics with WebGL © Ed Angel, 2014
GLSL
• OpenGL ES Shading Language (ESSL)
• Some key differences between ESSL and recent versions of the OpenGL Shading Language
- ESSL requires fragment shader to set precision - varying qualifiers replaced by in and out gl_FragColor deprecated
2Computer Graphics with WebGL © Ed Angel, 2014
3
Data Types
• C types: int, float, bool • Vectors:
- float vec2, vec3, vec4 - Also int (ivec) and boolean (bvec)
• Matrices: mat2, mat3, mat4 - Stored by columns - Standard referencing m[row][column]
• C++ style constructors - vec3 a =vec3(1.0, 2.0, 3.0) - vec2 b = vec2(a)
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
2
4
No Pointers
• There are no pointers in GLSL • We can use C type structs which can be copied back
from functions • Because matrices and vectors are basic types they
can be passed into and output from GLSL functions, e.g.
mat3 func(mat3 a)• variables passed by copying
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
5
Qualifiers • GLSL has many of the same qualifiers as C/C++ such
as const
• Need others due to the nature of the execution model • Variables can change
- Once per primitive (uniform qualified) - Once per vertex (attribute qualified) - Once per fragment (varying qualified) - At any time in the application
• Vertex attributes are output by the vertex shader are interpolated by the rasterizer into fragment attributes
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
6
Attribute Qualifier
• Attribute-qualified variables can change at most once per vertex
• There are a few built in variables such as gl_Position but most have been deprecated
• User defined (in application program) attribute vec4 color attribute float temperature attribute vec3 velocity
• recent versions of GLSL use in and out qualifiers to get data to and from shaders
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
3
7
Uniform Qualified
• Variables that are constant for an entire primitive
• Can be changed in application and sent to shaders
• Cannot be changed in shader
• Used to pass information to shader such as the time or a rotation angle for transformations
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
8
Varying Qualified
• Variables that are passed from vertex shader to fragment shader
• Automatically interpolated by the rasterizer • With WebGL, GLSL uses the varying qualifier in both
shaders varying vec4 color;
• More recent versions of WebGL use out in vertex shader and in in the fragment shader out vec4 color; //vertex shaderin vec4 color; // fragment shader
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Our Naming Convention
• attributes passed to vertex shader have names beginning with v (v Position, vColor) in both the application and the shader
- Note that these are different entities with the same name
• Variable variables begin with f (fColor) in both shaders - must have same name
• Uniform variables are unadorned and can have the same name in application and shaders
9Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
4
10
Example: Vertex Shader
attribute vec4 vColor;varying vec4 fColor;void main(){ gl_Position = vPosition; fColor = vColor;}
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
11
Corresponding Fragment Shader
precision mediump float;
varying vec3 fColor;void main(){ gl_FragColor = fColor;}
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Sending Colors from Application
12
var cBuffer = gl.createBuffer();gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" );gl.vertexAttribPointer( vColor, 3, gl.FLOAT, false, 0, 0 );gl.enableVertexAttribArray( vColor );
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
5
Sending a Uniform Variable
13
// in application
vec4 color = vec4(1.0, 0.0, 0.0, 1.0);colorLoc = gl.getUniformLocation( program, ”color" ); gl.uniform4f( colorLoc, color);
// in fragment shader (similar in vertex shader)
uniform vec4 color;
void main(){ gl_FragColor = color;}
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
14
Operators and Functions
• Standard C functions - Trigonometric - Arithmetic
• Geometry helper functions - Normalize, reflect, length
• Overloading of vector and matrix types mat4 a;vec4 b, c, d;c = b*a; // a column vector stored as a 1d array d = a*b; // a row vector stored as a 1d array
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
15
Swizzling and Selection
• Can refer to array elements by element using [] or selection (.) operator with x, y, z, w r, g, b, a s, t, p, q a[2], a.b, a.z, a.p are the same
• Swizzling operator lets us manipulate components vec4 a, b;a.yz = vec2(1.0, 2.0, 3.0, 4.0);b = a.yxzw;
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
1
1
Introduction to Computer Graphics with WebGL
Ed Angel
Color
Computer Graphics with WebGL © Ed Angel, 2014
2
Attributes
• Attributes determine the appearance of objects - Color (points, lines, polygons) - Size and width (points, lines) - Stipple pattern (lines, polygons) - Polygon mode
• Display as filled: solid color or stipple pattern • Display edges • Display vertices
• Only a few (gl_PointSize) are supported by WebGL functions
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
3
RGB color
• Each color component is stored separately in the frame buffer
• Usually 8 bits per component in buffer • Color values can range from 0.0 (none) to 1.0 (all) using floats or over the range from 0 to 255 using unsigned bytes
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
2
4
Indexed Color
• Colors are indices into tables of RGB values • Requires less memory
- indices usually 8 bits - not as important now
• Memory inexpensive • Need more colors for shading
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Setting Colors
• Colors are ultimately set in the fragment shader but can be determined in either shader or in the application
• Application color: pass to vertex shader as a uniform variable or as a vertex attribute
• Vertex shader color: pass to fragment shader as varying variable
• Fragment color: can alter via shader code
5Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
6
Smooth Color
• Default is smooth shading - Rasterizer interpolates vertex colors across visible
polygons • Alternative is flat shading
- Color of first vertex determines fill color - Handle in shader
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
3
7Computer Graphics with WebGL © Ed Angel, 2014
var colors = [1, 0, 0, 0, 1, 0, 0, 0, 1];var cbufferId = gl.createBuffer(); gl.bindBuffer( gl.ARRAY_BUFFER, cbufferId ); gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" )gl.vertexAttribPointer( vColor, 3, gl.FLOAT, false, 0, 0 );gl.enableVertexAttribArray( vColor );
Shaders
8Computer Graphics with WebGL © Ed Angel, 2014
//vertex shaderattribute vec4 vPosition;attribute vec4 vColor;varying vec4 fColor;
void main(){ gl_Position = vPosition; fColor = vColor;} //fragment shaderprecision mediump float;varying vec4 fColor;void main(){ gl_FragColor = fColor;}
Sending a Uniform Variable
9
// in application
vec4 color = vec4(1.0, 0.0, 0.0, 1.0);colorLoc = gl.getUniformLocation( program, ”color" ); gl.uniform4f( colorLoc, color);
// in fragment shader (similar in vertex shader)
uniform vec4 color;
void main(){ gl_FragColor = color;}
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
1
1
Introduction to Computer Graphics with WebGL
Ed Angel
Input and Interaction
Computer Graphics with WebGL © Ed Angel, 2014
2
Project Sketchpad
• Ivan Sutherland (MIT 1963) established the basic interactive paradigm that characterizes interactive computer graphics:
- User sees an object on the display - User points to (picks) the object with an input
device (light pen, mouse, trackball) - Object changes (moves, rotates, morphs) - Repeat
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
3
Graphical Input
• Devices can be described either by - Physical properties
• Mouse • Keyboard • Trackball
- Logical Properties • What is returned to program via API
– A position – An object identifier
• Modes - How and when input is obtained
• Request or event Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
2
4
Physical Devices
mouse trackball light pen
data tablet joy stick space ball Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
5
Logical Devices
• Consider the C and C++ code - C++: cin >> x; - C: scanf (“%d”, &x);
• What is the input device? - Can’t tell from the code - Could be keyboard, file, output from another
program • The code provides logical input
- A number (an int) is returned to the program regardless of the physical device
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
6
Graphical Logical Devices
• Graphical input is more varied than input to standard programs which is usually numbers, characters, or bits
• Two older APIs (GKS, PHIGS) defined six types of logical input
- Locator: return a position - Pick: return ID of an object - Keyboard: return strings of characters - Stroke: return array of positions - Valuator: return floating point number - Choice: return one of n items
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
3
7
Client Server Systems
• The X Window System introduced a client-server model for a network of workstations
- Client: OpenGL program - Graphics Server: bitmap display with a pointing device and a
keyboard
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Browser Client Server
• Server: location of URL - can be remote or local
• Client side: anything run in your browser • We generally write client side code
- Client side JS - Client code cannot affect server side directly - We can send data to server but data is processed
there by server side code
8Computer Graphics with WebGL © Ed Angel, 2014
9
Input Modes
• Input devices contain a trigger which can be used to send a signal to the operating system
- Button on mouse - Pressing or releasing a key
• When triggered, input devices return information (their measure) to the system
- Mouse returns position information - Keyboard returns ASCII code
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
4
10
Request Mode
• Input provided to program only when user triggers the device
• Typical of keyboard input - Can erase (backspace), edit, correct until enter
(return) key (the trigger) is depressed
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
11
Event Mode
• Most systems have more than one input device, each of which can be triggered at an arbitrary time by a user
• Each trigger generates an event whose measure is put in an event queue which can be examined by the user program
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
12
Event Types
• Window: resize, expose, iconify • Mouse: click one or more buttons • Motion: move mouse • Keyboard: press or release a key • Idle: nonevent
- Define what should be done if no other event is in queue
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
5
Browser Events
• Events have names recognized by JS and HTML - load - click - keypress
• Events have targets - object that caused the event - mouse, HTML button, HTML menu
• Respond to events with event listeners or handlers or callbacks which are registered
• event handlers receive an object with the properties of the event
13Computer Graphics with WebGL © Ed Angel, 2014
1
1
Introduction to Computer Graphics with WebGL
Ed Angel
Animation
Computer Graphics with WebGL © Ed Angel, 2014
2
Callbacks
• Programming interface for event-driven input uses callback functions or event listeners
- Define a callback for each event the graphics system recognizes
- Browsers enters an event loop and responds to those events for which it has callbacks registered
- The callback function is executed when the event occurs
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Execution in a Browser
3Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
2
Execution in a Browser
• Start with HTML file - Describes the page - May contain the shaders - Loads files
• Files are loaded asynchronously and JS code is executed
• Then what? • Browser is in an event loop and waits for an event
4Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
onload Event
• What happens with our JS file containing the graphics part of our application?
- All the “action” is within functions such as init() and render()
- Consequently these functions are never executed and we see nothing
• Solution: use the onload window event to initiate execution of the init function
- onload event occurs when all files read window.onload = init;
5Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Rotating Square
Consider the four points
Animate display by rerendering with different values of θ
6Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
3
Simple but Slow Method
7
for(var theta = 0.0; theta <thetaMax; theta += dtheta; {
vertices[0] = vec2(Math.sin(theta), Math.cos.(theta));vertices[1] = vec2(Math.sin(theta), -Math.cos.(theta));vertices[2] = vec2(-Math.sin(theta), -Math.cos.(theta));vertices[3] = vec2(-Math.sin(theta), Math.cos.(theta));
gl.bufferSubData(…………………….
render();}
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Better Way
• Send original vertices to vertex shader
• Send θ to shader as a uniform variable • Compute vertices in vertex shader • Render recursively
8Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Render Function
9
var thetaLoc = gl.getUniformLocation(program, "theta");
function render(){ gl.clear(gl.COLOR_BUFFER_BIT); theta += 0.1; gl.uniform1f(thetaLoc, theta); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); render();}
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
4
Vertex Shader
10
attribute vec4 vPosition;uniform float theta;
void main(){ gl_Position.x = -sin(theta) * vPosition.x + cos(theta) * vPosition.y; gl_Position.y = sin(theta) * vPosition.y + cos(theta) * vPosition.x; gl_Position.z = 0.0; gl_Position.w = 1.0;}
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Double Buffering
• Although we are rendering the square, it always into a buffer that is not displayed
• Browser uses double buffering - Always display front buffer - Rendering into back buffer - Need a buffer swap
• Prevents display of a partial rendering
11Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Triggering a Buffer Swap
• Browsers refresh the display at ~60 Hz - redisplay of front buffer - not a buffer swap
• Trigger a buffer swap though an event • Two options for rotating square
- Interval timer - requestAnimFrame
12Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
5
Interval Timer
• Executes a function after a specified number of milliseconds
- Also generates a buffer swap
• Note an interval of 0 generates buffer swaps as fast as possible
13
setInterval(render, interval);
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
requestAnimFrame
14
function render { gl.clear(gl.COLOR_BUFFER_BIT); theta += 0.1; gl.uniform1f(thetaLoc, theta); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); requestAnimFrame(render);}
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Add an Interval
15
function render(){ setTimeout( function() { requestAnimFrame(render); gl.clear(gl.COLOR_BUFFER_BIT); theta += 0.1; gl.uniform1f(thetaLoc, theta); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); }, 100);}
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
1
1
Introduction to Computer Graphics with WebGL
Ed Angel
Buttons and Menus
Computer Graphics with WebGL © Ed Angel, 2014
Adding a Button
• Let’s add a button to control the rotation direction for our rotating cube
• In the render function we can use a var direction which is true or false to add or subtract a constant to the angle
2
var direction = true; // global initialization
// in render()
if(direction) theta += 0.1;else theta -= 0.1;
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
The Button
• In the HTML file
- Uses HTML button tag - id gives an identifier we can use in JS file - Text “Change Rotation Direction” displayed in
button • Clicking on button generates a click event • Note we are using default style and could use CSS or
jQuery to get a prettier button
3
<button id="DirectionButton">Change Rotation Direction</button>
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
2
Button Event Listener
• We still need to define the listener - no listener and the event occurs but is ignored
• Two forms for event listener in JS file
4
var myButton = document.getElementById("DirectionButton");
myButton.addEventListener("click", function() { direction = !direction;});
document.getElementById("DirectionButton").onclick =function() { direction = !direction; };
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
onclick Variants
5
myButton.addEventListener("click", function() {if (event.button == 0) { direction = !direction; }});
myButton.addEventListener("click", function() {if (event.shiftKey == 0) { direction = !direction; }});
<button onclick="direction = !direction"></button>
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Controling Rotation Speed
6
var delay = 100;
function render() { setTimeout(function() { requestAnimFrame(render); gl.clear(gl.COLOR_BUFFER_BIT); theta += (direction ? 0.1 : -0.1); gl.uniform1f(thetaLoc, theta); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); }, delay); }
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
3
Menus
• Use the HTML select element • Each entry in the menu is an option element with an
integer value returned by click event
7
<select id="mymenu" size="3"> <option value="0">Toggle Rotation Direction</option> <option value="1">Spin Faster</option> <option value="2">Spin Slower</option> </select>
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Menu Listener
8
var m = document.getElementById("mymenu");m.addEventListener("click", function() { switch (m.selectedIndex) { case 0: direction = !direction; break; case 1: delay /= 2.0; break; case 2: delay *= 2.0; break; }});
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
1
1
Introduction to Computer Graphics with WebGL
Ed Angel
Keyboard and Sliders
Computer Graphics with WebGL © Ed Angel, 2014
Using keydown Event
2
window.addEventListener("keydown", function() { switch (event.keyCode) { case 49: // ’1’ key direction = !direction; break; case 50: // ’2’ key delay /= 2.0; break; case 51: // ’3’ key delay *= 2.0; break; }});
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Don’t Know Unicode
3
window.onkeydown = function(event) { var key = String.fromCharCode(event.keyCode); switch (key) { case ’1’: direction = !direction; break; case ’2’: delay /= 2.0; break; case ’3’: delay *= 2.0; break; }};
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
2
Slider Element
• Puts slider on page - Give it an identifier - Give it minimum and maximum values - Give it a step size needed to generate an event - Give it an initial value
• Use div tag to put below canvas
4
<div>speed 0 <input id="slide" type="range" min="0" max="100" step="10" value="50" />100 </div>
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
onchange Event Listener
5
document.getElementById("slide").onchange = function() { delay = event.srcElement.value; };
Angel and Shreiner: Interactive Computer Graphics 7E © Addison-Wesley 2015
Text Box • We can enter text using a dialogue box and then
manipulate this text in the JS file
• Simple event listener responds to onchange event and prints out the text entered
• The input tag has many other options and usually used with HTML forms
6Computer Graphics with WebGL © Ed Angel, 2014
<input type = "text" id = "testValue" style = "width.50px”></input>
document.getElementById("testValue").onchange = function(){ console.log(event.srcElement.value); };