CS 457/557 -- Winter Quarter 2018

Project #2

Noisy Elliptical Dots

100 Points

Due: January 29


This page was last updated: January 23, 2018


Requirements:

  1. Create a GLIB file that produces parameter sliders for:

    ParameterWhat It Does
    uAdEllipse diameter #1
    uBdEllipse diameter #2
    uNoiseAmpNoise Amplitude
    uNoiseFreqNoise Frequency
    uTolWidth of the blend between ellipse and non-ellipse areas

    The .glib file, including the Extra Credit parameters, might look like this:

    ##OpenGL GLIB
    LookAt  0 0 3  0 0 0  0 1 0
    Perspective 70
    
    Vertex   ovalnoise.vert
    Fragment ovalnoise.frag
    Program  OvalNoise                                               \
            uAd <.01 .05 .5>  uBd <.01 .05 .5>                       \
            uNoiseAmp <0. 0. 1.>  uNoiseFreq <0. 1. 10.>      	 \
            uAlpha <0. 1. 1.>                                        \
            uTol <0. 0. 1.>
    
    
    Color 1. .9 0
    Sphere
    

  2. The NoiseFreq parameter is the frequency of the noise function, i.e., it multiplies what goes into the noise function.

  3. The NoiseAmp parameter is the amplitude of the noise function, i.e., it multiplies the noise value.

  4. The effects of the NoiseAmp and NoiseFreq parameters should look something like this:
      NoiseAmp NoiseFreq

  5. The uTol parameter is the width of a smoothstep( ) blend between the ellipse and non-ellipse areas, thus smoothing the abrupt color transition.

    uTol

  6. You can have as many other slider-based uniform variables as you wish.

  7. Apply lighting. The easiest way to do this would be to just use diffuse in per-vertex lighting, looking at the cosine of the angle between the surface normal and the vector to the light source:

    out float	vLightIntensity;
    
    const vec3 LIGHTPOS   = vec3( -2., 0., 10. );
       . . .
    vec3 tnorm      = normalize( gl_NormalMatrix * gl_Normal );	// transformed normal
    vec3 ECposition = ( gl_ModelViewMatrix * gl_Vertex ).xyz;
    vLightIntensity  = abs(  dot( normalize(LIGHTPOS - ECposition), tnorm )  );
    

    Of course, you can make this as sophisticated as you want, including interpolating the transformed normal through the rasterizer and using per-fragment lighting.

  8. The ellipses must be created procedurally, i.e., with equations in a Fragment Shader program. (No texture images.)

  9. As we discussed in class, get a noise value based on the current fragment's model coordinates. Use all 4 octaves available. Then use that value to alter the ds and dt values. Then use those new ds and dt values to determine the correct color to use.
    // read the glman noise texture and convert it to a range of [-1.,+1.]:
    
    nv  = texture3D( Noise3, uNoiseFreq*vMCposition );
    float n = nv.r + nv.g + nv.b + nv.a;    //  1. -> 3.
    n = n - 2.;                             // -1. -> 1.
    
    // determine the color based on the noise-modified (s,t):
    
    float sc = float(numins) * uAd  +  Ar;
    float ds = st.s - sc;                   // wrt ellipse center
    float tc = float(numint) * uBd  +  Br;
    float dt = st.t - tc;                   // wrt ellipse center
    
    float oldDist = sqrt( ds*ds + dt*dt );
    float newDist = << use the noise value >>
    float scale = newDist / oldDist;        // this could be < 1., = 1., or > 1.
    
    ds *= scale;                            // scale by noise factor
    ds /= Ar;                               // ellipse equation
    
    dt *= scale;                            // scale by noise factor
    dt /= Br;                               // ellipse equation
    
    float d = ds*ds + dt*dt;
    

  10. The choice of geometry is up to you. You are allowed to contrive the size to make it work.

Using Objects Other Than A Sphere

You can try this with any solid objects you want. However, be aware that not all solid objects have built-in s-t (texture) coordinates. In glman, the sphere, torus, and teapot have them. The others don't. (Blame this on GLUT...) Many of the hundreds of .obj files available on the net have them. (You can check this by editing the .obj file and ensuring that there are lines beginning with "vt".) Also, be aware that not all .obj objects have built-in surface normals (nx,ny,nz). (You can check this by editing the .obj file and ensuring that there are lines beginning with "vn".)

If you want to use the signature object, get the giraffe file, giraffe.obj, here. Include it in your GLIB file like this:
Obj giraffe.obj

Extra Credit (+5 points)

Add uniform variable uAlpha that changes the opacity of the non-ellipse areas. When uAlpha == 0., do a discard; instead of setting alpha.

ParameterWhat It Does
uAlphaOpacity of non-ellipse areas

uAlpha

Extra Credit #2 (+5 points)

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 a checkbox called uUseChromaDepth which turns ChromaDepth on and off.

Glasses are in boxes on the east side of the CGEL. Feel free to keep a pair.

uChromaRed and uChromaBlue are meant to be the Z depths in eye coordinates at which the ChromaDepth color interpolation starts and ends.

I'd recommend putting them both on sliders, so that you can play with the values. Remember that, in eye coordinates, the eye is at the origin looking in -Z. Thus, uChromaRed and uChromaBlue need to be negative.

Checkboxes are added to the glman user interface like this:

. . . uUseChromaDepth <false> . . .

and are used in the shader program as:

uniform bool uUseChromaDepth;

. . .

	if( uUseChromaDepth )
	{
		float t = (2./3.) * ( Z - uChromaRed ) / ( uChromaBlue - uChromaRed );
		t = clamp( t, 0., 2./3. );
		TheColor = ChromaDepth( t );
	}
	else
	{
		. . .
	}

ChromaDepth

If you normalize a distance t so that it is t=0. in the front of the object and t=.667 in the back, here is code to assign the colors. (It is actually just the hue-only part of the rainbow color scale.)


vec3
Rainbow( float t )
{
	t = clamp( t, 0., 1. );

	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 );
}

Note that this code implements the full (H,S=1.,V=1.) to (R,G,B) conversion. You need to keep t between 0. and (2./3.) because you are only interested in the Red-Green-Blue color range. This code is good to keep around. There are lots of good visualization uses for it too.

Be sure to show the Extra Credit(s) in your video!

Hints:

The Turn-In Process:

Your turnin will be done at http://engr.oregonstate.edu/teach and will consist of:

  1. All source files (.glib, .vert, .frag). You can zip this all together if you want.
  2. A PDF report with a title, your name, your email address, nice screen shots from your program, and the link to the Kaltura video demonstrating that your project does what the requirements ask for. Narrate your video so that you can tell us what it is doing.
  3. Be sure your video's protection is set to unlisted.
  4. Do not put your PDF into your zip file. Leave it out separately so my collect-all-the-PDFs script can find it.

Submissions are due at 23:59:59 on the listed due date.

Grading:

FeaturePoints
Correct changes in uAd and uBd20
Correct changes in uNoiseAmp30
Correct changes in uNoiseFreq30
Correct changes in uTol20
EC #1: Correct changes in uAlpha5
EC #2: Correct ChromaDepth5
Potential Total110