OpenGL shaders and programming models that provide object ...
Transcript of OpenGL shaders and programming models that provide object ...
OpenGL shaders
É We discussed forms of local illumination in the ray tracing lectures.
É We also saw that there were reasons you might want to modify these:e.g. procedural textures for bump maps.
É Ideally the illumination calculations would be entirely programmable.
É OpenGL shaders facilitate high performance programmability.
É They have been available as extensions since OpenGL 1.5 (2003), butcore within OpenGL 2.0 (2004).
É We will focus on vertex and fragment shaders, but there are othertypes: e.g. geometry shaders, and more recent shaders fortessellation and general computing.
COSC342 OpenGL shaders and programming models that provide object persistence 2
GL Shading Language—GLSL
É C-like syntax. (No surprises given the OpenGL lineage . . . )
É However, compared to ‘real’ use of C, GLSL programmers are furtheraway from the actual hardware.
É Usually the GLSL code will be passed as a string into the OpenGLlibrary you are using.
É Only supports limited number of data types: e.g. float, double, . . .
É Adds some special types of its own: e.g. vector types vec2, vec4.
É Unlike most software, GLSL is typically compiled every time you loadup your functions—there isn’t a standardised GL machine code.
COSC342 OpenGL shaders and programming models that provide object persistence 3
GLSL on the hardware
É The GLSL syntax just provides a standard way to specify functions.
É Different vendors may use vastly different hardware implementations.
É (Or indeed the CPU may be doing the GLSL work, e.g. Mesa.)
É On any hardware accelerated system, the GLSL code will be run in amassively parallel way.
É Crucially, it’s usually a single-instruction multiple-data (SIMD)approach.
É This means that conditional branches and structures such as loopsmay be problematic. (Particularly if threads need to diverge.)
COSC342 OpenGL shaders and programming models that provide object persistence 4
Vertex shaders
É Vertex shaders run in the vertex processor: recall that this replacedthe “Transform” stage of the GL pipeline.
É Vertex shaders are given inputs including:É uniform variables that hold the same value for all vertices;É attributes that provide data per vertex: e.g. position, normal, colour,
texture coordinates.
É Vertex shaders produce results by:É assigning to predefined variables such as gl position—the vertex’s
screen-space position;É setting custom vertex attributes whose values are to be interpolated
and provided to fragment shaders.
COSC342 OpenGL shaders and programming models that provide object persistence 5
Fragment shaders
É Fragment shaders run in the fragment processor: recall that thisreplaced the “Shade” stage of the GL pipeline.É e.g. you could use a fragment shader to implement Phong shading.
É Variables that were varying outputs of the vertex shader are(constant) inputs to the fragment shader.
É Fragment shaders cause effects by assigning to predefined variables.É e.g. gl FragColour is a vec4 that the fragment shader can set to give
this fragment (almost a pixel) an RGBA value.É Fragment shaders can also set the depth value for z-buffering.
COSC342 OpenGL shaders and programming models that provide object persistence 6
GLSL implementation of flat, constant, blue shading
É Not a particularly useful type of shading, but it does give us usefullyminimal shader code.
É Our vertex shader will just ensure that vertices are transformed toscreen coordinates—
void main() {
gl_Position = gl_ModelViewProjectionMatrix *
gl_Vertex;
}
É Our fragment shader sets all fragments to be blue—
void main() {
gl_FragColor = vec4 (0.0, 0.0, 1.0, 1.0);
}
COSC342 OpenGL shaders and programming models that provide object persistence 7
(Simplified) GLSL Gouraud shading
Vertex shader:
varying vec4 color;
void main() {
vec3 n= normalize(gl_NormalMatrix * gl_Normal);
vec3 l= normalize(vec3(gl_LightSource [0]. position));
vec3 diffuseReflection = vec3(gl_LightSource [0].
diffuse) * max(0.0, dot(n, l));
color = vec4(diffuseReflection , 1.0);
gl_Position = gl_ModelViewProjectionMatrix *
gl_Vertex;
}
Fragment shader:
varying vec4 color;
void main() { gl_FragColor = color; }
COSC342 OpenGL shaders and programming models that provide object persistence 8
GLSL Phong shading sketch—vertex and fragment shaders
varying vec4 e; varying vec3 n;
void main() { e = gl_ModelViewMatrix * gl_Vertex;
n = normalize(gl_NormalMatrix * gl_Normal);
gl_Position = ... }
varying vec4 e; varying vec3 n;
void main() {
vec3 nn = normalize(n);
vec3 ne = -normalize(vec3(e));
vec3 l = ...;
vec3 specularReflection;
if (dot(nn , l) < 0.0)
specularReflection = vec3 (0.0, 0.0, 0.0);
else { specularReflection = vec3(gl_LightSource[index ].
specular) * vec3(gl_FrontMaterial.specular) * pow(max
(0.0, dot(reflect(-l, nn), ne)), gl_FrontMaterial.
shininess); }
gl_FragColor = vec4(ambient ... + diffuse ... +
specularReflection , 1.0);
}
COSC342 OpenGL shaders and programming models that provide object persistence 9
An aside: fractals
É Fractals are shapes that have infinite detail.
É (This implies that they must be procedurally generated.)
É Often they have self-similarity: e.g. recursive structures.
É You have encountered a fractal shape in COSC342 already: theSierpinski Gasket (fractal triangle) in the first OpenGL lab.
É A fractal such as the figure to the righthas a finite volume . . . but yet has aninfinite surface area!
É Simple equations can produce intricateresults: e.g. iterate zn+1 = z2
n+ c for
complex numbers z and c to generatethe Mandelbrot set.
COSC342 OpenGL shaders and programming models that provide object persistence 10
A vertex shader for a procedural texture . . .
uniform float real; // fractal ’s "x"
uniform float imag; // fractal ’s "y"
uniform float w; // width
uniform float h; // height
varying float xpos; // changes across polygon
varying float ypos;
void main(void)
{
xpos = clamp(gl_Vertex.x, 0.0 ,1.0)*w+real;
ypos = clamp(gl_Vertex.y, 0.0 ,1.0)*h+imag;
// perform update of GLSL global variables
gl_Position = gl_ModelViewProjectionMatrix *
gl_Vertex;
}
COSC342 OpenGL shaders and programming models that provide object persistence 11
. . . and the corresponding fragment shader
varying float xpos ,ypos;
void main (void)
{
float iter = 0.0, square = 0.0, max_square = 3.0;
float r = 0.0, i = 0.0;
float rt = 0.0, it = 0.0;
while(iter < 1.0 && square < max_square)
{
rt = (r*r) - (i*i) + xpos;
it = (2.0 * r * i) + ypos;
r = rt;
i = it;
square = (r*r)+(i*i);
iter += 0.005;
}
gl_FragColor = vec4 (iter , sin(iter *20.00) , sin(
iter *2.00) , 1.0);
}
COSC342 OpenGL shaders and programming models that provide object persistence 12
Using the Pyglet library for Python to load GLSL
vertex_shader_src = """
uniform float real ,w,imag ,h;
varying float xpos ,ypos;
void main(void) {
xpos = clamp(gl_Vertex.x, 0.0 ,1.0)*w+real;
ypos = clamp(gl_Vertex.y, 0.0 ,1.0)*h+imag;
gl_Position = gl_ModelViewProjectionMatrix *
gl_Vertex;
}
"""
program = gl.glCreateProgram ()
vertex_shader = self.create_shader(vertex_shader_src ,
gl.GL_VERTEX_SHADER)
gl.glAttachShader(self.program , vertex_shader)
gl.glLinkProgram(self.program)
message = self.get_program_log(self.program)
if message:
raise ShaderException(message)
COSC342 OpenGL shaders and programming models that provide object persistence 13
Persistent object modelling
É In OpenGL, you draw it, and it’s on-screen (more or less).É ... however you can’t later ask OpenGL what objects were drawn.
É (Although you can ask OpenGL to tell you pixel values.)
É Nonetheless, you probably want the next frame you are going to drawto be closely related to the one you just drew.
É Ideally you could explain to a graphics framework what your objectsare, and it can maintain this state for you.
É There are many ways to acquire this functionality, such as throughgame engines (e.g. Unity3D, Blender, etc.), and scene-graph libraries.
COSC342 OpenGL shaders and programming models that provide object persistence 15
Scene graphs
É When building a computer model of a bicycle—just as you wouldwhen building a real bicycle—you are likely to use discrete parts.
É A scene graph allows us to store a model that retains theseconstituent components.
COSC342 OpenGL shaders and programming models that provide object persistence 16
Parameterised scene graphs
É Duplicated objects in our sceneshould share the same nodes inthe scene-graph.
É Note that we can use nodes tohold matrices, as well asgeometry.
É The transformations in a matrixnode will apply to all children ofthat node.
COSC342 OpenGL shaders and programming models that provide object persistence 17
Further decomposition of our bicycle scene graph
É In the case of our bicycle model,we can apply further geometricdecomposition:
É a wheel is itself made up ofsubcomponents
...
COSC342 OpenGL shaders and programming models that provide object persistence 18
Standard Vector Graphics (SVG)
É The persistence mechanism for SVG is the HTML DOM.
<!DOCTYPE html><!-- i.e. HTML5 -->
<html><body>
<svg style="border :1px solid black;" width="100"
height="100">
<circle id="my -circle" cx="40" cy="30" r="25"
stroke="blue" stroke -width="2" fill="green" />
</svg>
</body></html>
É JavaScript can find and dynamically modify DOM elements:
var c = document.getElementById("my -circle");
c.setAttribute("cx" ,50);
c.setAttribute("fill","orange");
COSC342 OpenGL shaders and programming models that provide object persistence 19
WebGL
É Another important web technology for graphics is WebGL.É Defines a standard way to access to OpenGL from web browsers.
É Specifically, it’s based on OpenGL ES 2.0, and supports GLSL.
É In terms of syntax, the resulting web workload is a dog’s breakfast.É Development is likely to involve HTML, CSS, JavaScript, GLSL, in
addition to WebGL’s OpenGL-style naming.É However serious web development is unlikely to involve manual editing
of all these types of files (e.g. given frameworks, libraries, IDEs, etc).
É WebGL is likely to be very useful in popularising OpenGL further.
É It also allows mixing in of other web technologies.
COSC342 OpenGL shaders and programming models that provide object persistence 20
WebGL “hello world” does not sensibly fit on one slide
<!DOCTYPE html>
<html><head><title >WebGL example </title></head>
<body><script type="text/javascript">
... shaders , data bulk -loading ...
function draw() {
var gl = document.getElementById("webgl").
getContext("experimental -webgl"); ...
var prog = shaderProgram(gl ,
"attribute vec3 pos; void main() { gl_Position = vec4(
pos , 2.0); }",
"void main() { gl_FragColor = vec4 (0.5, 0.5, 1.0, 1.0)
; }"); ...
attributeSetFloats(gl, prog , "pos", 3, [-1, 0, 0,
0, 1, 0, 0, -1, 0, 1, 0, 0]);
gl.drawArrays(gl.TRIANGLE_STRIP , 0, 4);
} ... </script >
<canvas id="webgl" width="640" height="480"></canvas >
</body></html>
COSC342 OpenGL shaders and programming models that provide object persistence 21
three.js: a JavaScript library that helps 3D web coding
var scene = new THREE.Scene();
var S_W = window.innerWidth , S_H = window.innerHeight;
var camera = new THREE.PerspectiveCamera( 45, S_W / S_H ,
0.1, 20000); scene.add(camera);
camera.position.set (0 ,150 ,400);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer( {antialias:true} );
renderer.setSize(S_W , S_H);
var container = document.getElementById( ’ThreeJS ’ );
container.appendChild( renderer.domElement );
var light = new THREE.PointLight (0 xffffff);
light.position.set (100 ,150 ,200);
scene.add(light);
var geometry = new THREE.SphereGeometry( 100, 32, 16 );
var material = new THREE.MeshLambertMaterial( { color: 0
x8888ff } );
var mesh = new THREE.Mesh( geometry , material );
mesh.position.set(0,40,0);
scene.add(mesh);
renderer.render( scene , camera );
COSC342 OpenGL shaders and programming models that provide object persistence 22