This page does not represent the most current semester of this course; it is present merely as an archive.
You will submit one or more webpages. Each has
As with the WebGL warmup, you’ll submit
an HTML file and any number of js, glsl, json, and image files. Some
optional credit options may ask for additional HTML files. Also submit a
file named implemented.txt
listing any optional parts you
believe you completed.
Because you might have more than one HTML file, we specify exact file names for the HTML files.
This assignment, like all other assignments, is governed by the common components of MPs.
Submit a file named burst.html
that displays the
following animation.
The page should be initialized with 50 spheres. Each should be entirely within the bounding box at a random location with a random initial velocity. Each should be a random color. They should be large enough to clearly look like spheres, not just dots and small enough that most don’t overlap.
You should render the spheres either using a single sphere geometry that is rendered 50 times per frame (once per sphere object) or using points scaled to be the right size and colored to look like spheres.
Use just one single sphere geometry, not one per sphere. Render render that one geoemetry once per particle, as e.g.
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
// set up your view and projection matrices
for each particle {
// load a model matrix for this particle's position and size
// load a color for this particle
gl.drawElements(the, sphere, geometry)
}
We have an example 80-triangle sphere model you may use. It has radius 1, so you may need to scale it down either during import or with a model matrix.
Make a gl.DYNAMIC_DRAW
buffer that has each particle’s
center’s location. You may also want other attributes for radius and
color.
Rendering particles as points generally requires scaling the points
appropriately by setting gl_PointSize
for each particle in
the vertex shader. Somewhat annoyingly, gl_PointSize
is
given in pixels while all other coordinates in the vertex shader are
given in some type of normalized coordinate system.
The correct gl_PointSize
is the product of four
values:
Viewport size in pixels in either x or y.
You’ll have to pass this in as a uniform float
; you can get
it as gl.canvas.width
or
gl.canvas.height
.
Projection matrix scaling in the same axis. Assuming you are
using a standard perspective
projection matrix, this is either proj[0][0]
for x or proj[1][1]
for y, where proj
is your projection
matrix.
The inverse of the w
value for this point. That is
1/gl_Position.w
.
The diameter of the particle.
Inside your fragment shader you’ll have access to
gl_PointCoord
, a vec2
that is
vec2(0,0)
at the top-left corder of the point,
vec(0.5, 0.5)
in the center of the point, and
vec(1,1)
at the bottom-right corner of the point. To make
it just a circle, you can do
float r = length(gl_PointCoord*2.0 - vec2(1,1));
if (r > 1.0) discard;
The discard
keyword tells GLSL not to use the fragment
at all, and is handled in such a way that putting it in an
if
like this does not slow down the GPU the way
if
s usually do.
Spheres should move according to momentum and gravity. They should experience drag. They should bounce off of the invisible walls of the cube with non-zero non-one elasticity.
All of these should be physically plausible based on the elapsed time
between frames, as given by the argument to the callback of
requestAnimationFrame
.
We recommend using Euler’s method for your simulation.
burst.html
(5–65 points)Add an HTML element on top of the canvas that displays the current frames per second.
The HTML for this should be after the HTML for the cavnas element and should look like
<div id="fps" style="position:fixed; bottom:0; right:0; display:table"></div>
You may want to also add a color:rgb(255,95,5)
or the
like to the style
to help the text show up over your canvas
clear color.
and inside your requestAnimationFrame
callback you
should have code like
document.querySelector('#fps').innerHTML = text you want displayed
The FPS should be displayed with a fixed number of decimal places,
such as is created with the number.toFixed(places)
method.
Each spheres should have a different mass, with at least a 10-fold mass difference between the most and least massive. If you use variable radii, it is recommended but not required that masses be proportional to volume (i.e. radius3).
Sphere-sphere collision responses should respect these variable masses.
Add a control for the number of spheres to create and a spatial structure to make sphere-sphere collision detection either O(n) or O\big(n \log(n)\big). As the number of spheeres increases, their size should decrease so they all fit in the simulation with room to spare.
The easiest way to do this is
The above technique forms a baseline; it can be improved by cleverer grid sizing and distribution of pointers and by only allocating occupied grid cells. Hierarchical and axis-based structures can also be effective.
The result should allow making a very large number of spheres and should show roughly linear speed: if n spheres gives 30fps then 2n spheres should give something around 10–15fps.
fireworks.html
(20–65 points)Create a file fireworks.html
that shows a glowing
fireworks display.
Periodically, a burst of particles appear from roughly one position traveling away from one another. The position of each burst is different. The background is dark and the particles use additive blending so that they appear to be light sources and the more they overlap the brighter they appear; the particles are large enough seeing such overlaps is common.1 Individual particles exhibit weak gravity and strong drag. Each particle has a finite lifespan and is not drawn after it expires.
We recommend using gl.POINT
s to draw particles and make
each point dimmer near its edges than its center.
For 5 points, each burst should be of particles in a different color.
For 10 points, some (but not all) bursts should have multiple different colors of particles.
Have different types of bursts, randomly selected per burst. Some should still be the basic random velocities from the core fireworks requirement; others should be from this list. 5 points per item from the list, up to 15 points maximum.
boids.html
(20–45
points)Implement the boids flocking algorithm as described on its inventor’s webpage. For base credit, implement it in 2D with a support radius of no more than 10% of the screen’s size.
Both the original boids paper and Reynold’s website fail to fully describe how separation and cohesion differ. Cohesion steers towards the mean location of other boids within the support radius. Separation has several forms, but two easy ones are to either (a) steer away from the distance-weight average location of other boids within the support radius or (b) steer away from mean location of other boids within a significantly smaller radius.
When a boid hits the edge of the screen it should bounce off the edge, similar to how spheres bounce off the edge of the simulation domain for the required part of this assignment.
To keep boids moving, implement a minimum speed: if a boid slows below this, add speed to it.
Birds have to move to stay in flight and cannot turn very quickly. Simulate this in one of two ways:
boids3d.html
(10 points; requires Sphere-sphere
collisions)Make a 3D version of boids that move inside an invisible 3D box, similar to how prticles do for the required part of this assignment.
Instead of the separation force, use sphere-sphere collisions.