This page was last updated: February 27, 2024
There is an alternative Project #7 for the mac users who do not have access to a system capable of doing Geometry Shaders. If you are able to use Geometry Shaders, you are required to do this one.
The word "quantize" means to take something that is continuous, and give it discrete (fixed) locations instead. Some programs refer to this as "snapping".
In this project, we are going to take the triangles of a polygonal object, compute their centroid, quantize the location of that centroid, and then bend the triangle vertices around that centroid in a partial sphere. You will add more vertices to each triangle using the triangle interpolation (like in the sphere subdivision shader).
Entire Dragon | Zoomed-in Detail |
##OpenGL GLIB Perspective 70 LookAt 0 0 3 0 0 0 0 1 0 Vertex quantsph.vert Geometry quantsph.geom Fragment quantsph.frag Program QuantSph \ uLevel <0 3 5> \ uDiam <0.01 0.5 1.0> \ uQuantize <0.5 2. 6.> \ uKa <0. .1 1.> \ uKd <0. .6 1.> \ uKs <0. .3 1.> \ uShininess <1. 15. 20> Obj dragon010.obj
uniform int uLevel; // how many levels to subdivide the triangle uniform float uQuantize; // the quantization multiplier uniform float uDiam; // diameter of the spheresThe other uniform variables you see in the above glib file can have their values hardcoded.
#version 330 compatibility void main( ) { gl_Position = gl_Vertex; }We will do the matrix multiplication in the geometry shader. We do it this way because the GS is going to generate completely new vertices. It will not actually end up displaying any of the original triangle vertices.
layout( triangles ) in; layout( triangle_strip, max_vertices=204 ) out;
out vec3 gN; // normal vector out vec3 gL; // vector from point to light out vec3 gE; // vector from point to eyeThe meaning of these variables is the same as vN, vL, and vE when we were doing per-fragment lighting from the vertex shader.
vec3 V0, V1, V2; vec3 V01, V02; vec3 CG; float Diam; vec3 LIGHTPOS = vec3( ??, ??, ?? ); // feel free to just set the light position to a fixed loation: void main( ) { V0 = gl_PositionIn[0].xyz; V1 = gl_PositionIn[1].xyz; V2 = gl_PositionIn[2].xyz; V01 = V1 - V0; V02 = V2 - V0; CG = ( V0 + V1 + V2 ) / 3.; CG = Quantize( CG );
float Quantize( float f ) { f *= uQuantize; int fi = int( f ); f = float( fi ) / uQuantize; return f; }You will actually be quantizing the 3 floats in a vec3.
void ProduceVertex( float s, float t ) { vec3 v = ????? // do the vertex (s,t) interpolation v = ????? // make v's cordinates be with respect to the CG v = v * ????? // roughly same code as morphing the cow into a sphere of radius uDiam/2. v = ????? // put v back in the global space (ie, un-do the second line of code) vec4 ECposition = gl_ModelViewMatrix * vec4(v,1.); vec3 n = ????? // on a sphere, the normal is a vector from the sphere center (CG) to the vertex n = ????? // multiply the new normal by the proper matrix and normalize it // will be needed by the fragment shader to perform per-fragment lighting: gN = ????? gL = ????? gE = ????? // finally multiply the vertex by the combined matrices: gl_Position = ????? * vec4(??,??); EmitVertex(); }
Add a ChromaDepth feature that colors the scene by eye coordinate depth: Red in the front, Blue in the back, and Green in the middle. Include an option which turns the use of ChromaDepth on and off.
I have glasses which will use the ChromaDepth colors to make your scene look really 3D, although you (and we) will know if it is working without having the glasses. Please do not touch the plastic lenses on the glasses. Human fingerprints are nearly impossible to get off them.
uRedDepth and uBlueDepth are meant to be the Z depths in eye coordinates at which the ChromaDepth color interpolation starts and ends. You can make these variable, or you can hardcode them if you find good values for them.
// in the geometry shader: out float gZ; . . . gZ = -ECposition.z;
// in the fragment shader: in float gZ; . . . vec3 Rainbow( float t ) { t = clamp( t, 0., 1. ); // 0.00 is red, 0.33 is green, 0.67 is blue float r = 1.; float g = 0.0; float b = 1. - 6. * ( t - (5./6.) ); if( t <= (5./6.) ) { r = 6. * ( t - (4./6.) ); g = 0.; b = 1.; } if( t <= (4./6.) ) { r = 0.; g = 1. - 6. * ( t - (3./6.) ); b = 1.; } if( t <= (3./6.) ) { r = 0.; g = 1.; b = 6. * ( t - (2./6.) ); } if( t <= (2./6.) ) { r = 1. - 6. * ( t - (1./6.) ); g = 1.; b = 0.; } if( t <= (1./6.) ) { r = 1.; g = 6. * t; } return vec3( r, g, b ); } . . . vec3 myColor = ????? vec3 mySpecularColor = vec3( 1.0, 1.0, 1.0 ); if( uUseChromaDepth ) { float t = (2./3.) * ( abs(gZ) - uRedDepth ) / ( uBlueDepth - uRedDepth ); t = clamp( t, 0., 2./3. ); myColor = Rainbow( t ); }
If you want to see more ChromaDepth examples, click here.
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 centroid of each triangle | 20 |
The vertices created by the triangle subdivision form a partial sphere using uDiam | 40 |
Per-fragment lighting works correctly | 20 |
Extra Credit | 5 |
Potential Total | 105 |
Be sure that your video demonstrates all the features that you want credit for.