This page was last updated: January 17, 2023
I will be making up an alternative Project #7 for those who do not have access to a system capable of doing Geometry Shaders.
The word "quantize" means to take something that is continuous, and give it discrete (fixed) locations instead.
In this project, we are going to quantize an object in cyclindrical coordinates. You will add more detail to each triangle using the triangle interpolation (like in the sphere subdivision shader). You will then turn each x-y-z into a radius and height, quantize both quantities, then convert them back to x-y-z.
![]() | ![]() |
A Little Quantization | A Lot of Quantization |
##OpenGL GLIB Perspective 70 LookAt 0 0 3 0 0 0 0 1 0 Vertex cylquant.vert Geometry cylquant.geom Fragment cylquant.frag Program CylQuant \ uLevel <0 3 3> \ uQuantize <1. 50. 50.> \ uColor { 1.00 0.65 0.40 } Obj bunny010n.obj
out vec3 vNormal; . . . in vec3 vNormal[3];
layout( triangles ) in; layout( triangle_strip, max_vertices=204 ) out;
out float gLightIntensity; . . . in float gLightIntensity;
out vec3 gNs, gEs, gLs; . . . in vec3 gNs, gEs, gLs;
vec3 v = V0 + s*V01 + t*V02;where we created new (x,y,z)'s to form triangle strips. You can use the code from the Sphere Subdivision geometry shader as a start.
Use the same equation to also create new (nx,ny,nz)'s:
vec3 n = N0 + s*N01 + t*N02;and then multiply by gl_NormalMatrix.
float Sign( float f ) { if( f >= 0. ) return 1.; return -1.; } float Quantize( float f ) { f *= uQuantize; f += 0.5 * Sign(f); // round-off int fi = int( f ); f = float( fi ) / uQuantize; return f; }
const float PI = 3.14159265; float atan2( float y, float x ) { if( x == 0. ) { if( y >= 0. ) return PI/2.; else return -PI/2.; } return atan(y,x); }
float radius = length( v.xz ); float theta = atan2( v.z, v.x ); float height = v.y;
Leave the angle theta alone, and quantize both radius and height;
v.xz = radius * vec2( cos(theta), sin(theta) ); v.y = height;
V0, V1, and V2 are the corner points of the original triangle. V01 = V1 - V0 V02 = V2 - V0 N0, N1, and N2 are the corner normals of the original triangle. N01 = N1 - N0 N02 = N2 - N0 for each new triangle created by the triangle subdivision: { for each (s,t) corner point in that new triangle: { Turn that (s,t) into an (nx,ny,nz) using the triangle interpolation equation Transform and normalize that (nx,ny,nz) Use the (nx,ny,nz) to produce gLightIntensity Turn that same (s,t) into an (x,y,z) using the triangle interpolation equation Turn the (x,y,z) into (radius,height) Quantize radius and height, leaving theta alone Turn the quantized (radius,height) back into (x,y,z) Multiply the resulting (x,y,z) by the ModelviewProjection matrix to produce gl_Position EmitVertex( ); } }
Be sure that your PDF file is turned-in separately (not part of a .zip file).
Feature | Points |
---|---|
uLevel correctly subdivides each triangle | 20 |
uQuantize correctly quantizes the x-z radius of each vertex | 30 |
uQuantize correctly quantizes the y of each vertex | 30 |
Whatever you do for lighting is able to distinquish between the different faces | 20 |
Potential Total | 100 |
Be sure that your video demonstrates all features that you want credit for.