Everything should be made as simple as possible, but not simpler. (Albert Einstein)

Monday, July 20, 2015

Interactive Computer Graphics with WebGL

https://www.coursera.org/course/webgl/

Assignment 1. 
Tesselation and rotation with WebGL. Rotation on tesselated polygon resulted in a twisting effect.


Disclaimer: The sharing of codes in public repository is mandatory, ruled by the assignment rubric. It's not violation to the Honour Code.
This is assignment #1 of the University of New Mexico's "Interactive Computer Graphics with WebGL".

I use JQuery and JQuery UI for user-interface.

Code: https://github.com/flyingdisc/InteractiveWebGL/tree/gh-pages
Demo: https://flyingdisc.github.io/InteractiveWebGL/twist.html

-------------------------------------------------------

Assignment 2. Drawing with the mouse. 

There's problem with drawing thick line in WebGL in Windows OS. The gl.lineWidth() won't work, since in Windows, browsers use ANGLE. http://www.browserleaks.com/webgl
Test your browser, http://alteredqualia.com/tmp/webgl-linewidth-test/

An example of workaround is explained in this forum's discussion,
 https://forum.libcinder.org/topic/smooth-thick-lines-usinggeometry-shader

So, the idea is to replace rendering of (single) line with thin rectangle. Here is illustration,
  
A piece of line P1 to P2, will be rendered by thin rectangle [a, b, d, c]. In WebGL, the rectangle can be rendered by using two triangles, [a, b, c] and [b, c, d]. Variable "n" is normal, see the code. 
(Thank you to Dave Orton for helping me understanding this fat-line tweak.) 

The UI is by JQuery + JQuery UI. The beehive color picker is W3Schools color picker.

Here is the screenshot, yeah I know it's like a kids drawing, but that is the assignment, simple but working for full point =)

BTW, the wi-fi bird is mine =P

Code: https://github.com/flyingdisc/InteractiveWebGL/tree/gh-pages
Demo: https://flyingdisc.github.io/InteractiveWebGL/mousedraw.html

-------------------------------------------------------

Assignment 3. Geometric CAD. 
This is 3D geometric, they are sphere, cone, cylinder.

First step is determining vertex position buffer data, and vertex color buffer data (enableVertexAtrribArray) or single uniform (disable) in the GLSL.
Now, we need to assign Z value in the vec3 variable (x, y, z), as it's 3D.

Vertex position buffer data must be calculated for each shape, they are different for sphere, cone or cylinder. Geometry and trigonometry will help. In this case, I calculate them first separately, then save them in JavaScript file. So all the arrays are hard-coded. This will save time when loading, than to recalculate for each loading.

Then, determining index array (in case using drawElements, no need for drawArrays). Also, normal array for lighting. Actually lighting is optional in this assignment 3.

As usual, UI is JQuery. This is appetizer... =)
(Line is not smooth, since we use mediump precision.)

This is my older UI: (The flower is for girls..)
This is my newer UI, to support object selection. (Final UI is different..., see demo).

An object can be selected from the list, then to be transformed (translate, scale, rotate), or to be deleted. 

Some screenshots:




Code: https://github.com/flyingdisc/InteractiveWebGL/tree/gh-pages
Demo: https://flyingdisc.github.io/InteractiveWebGL/geomcad.html 

----------------------------------------------------------------

Assignment 4. Adding Lighting to Geometric 3D. 

Youtube: 
https://www.youtube.com/watch?v=io3fAWP5Q6g

There's problem with the lecture's normal matrix, this way,
    var normalMatrix = [ 
        vec3(modelViewMatrix[0][0], modelViewMatrix[0][1], modelViewMatrix[0][2]), 
        vec3(modelViewMatrix[1][0], modelViewMatrix[1][1], modelViewMatrix[1][2]), 
        vec3(modelViewMatrix[2][0], modelViewMatrix[2][1], modelViewMatrix[2][2]) 
    ]; 
 
That way, on object rotation the light will also be rotated.
The lecture's example only involving rotation, so that normal matrix should be appropriate, but with more transformation: translation and scaling, it won't work. 

The workaround is, to use different normal matrix, inversed then transposed, calculated from model-view matrix,
    var normalMatrix = inverseMat3(flatten(modelViewMatrix)); 
    normalMatrix = transpose(normalMatrix); 

    gl.uniformMatrix3fv(this.program.normalMatrix, false, flatten(normalMatrix) ); 

The "inverseMat3" is my function, because the lecture's MV.js has no inverse() function for matrix. It's to inverse a 3x3 matrix. It's modified from gl-matrix.js.
This way, on object rotation the light is consistent. 

Main UI: (adapted from assignment #3)
Two moving lights, both are turned on, so they have two speculars.
It's animation, two lights are moving for each frame, they can be paused.
First light is moving in counter-clockwise circular track, second light is moving in clockwise rectangular track, both in x-y plane, but z coordinate can be set via UI (for distance attenuation).
Original colors (Global-color is turned off)
Single light only (light #2 is on),
Single light only (light #1 is on),

Other screenshots, "goblet of wine".... low amount of tesselation, sorry. 

All parameters of ambient, diffuse, specular can be set via color-picker.
To handle multiple lights, I use array in the shader.

Demo: https://flyingdisc.github.io/InteractiveWebGL/lightcad.html
(simplification, without the goblet)

----------------------------------------------------------------

Assignment 5. Texture Mapping to a Sphere. 

Simply add texture of checkerboard and image to a sphere, animation (rotated sphere), simple UI,
Image texture,


I'm also doing experiment with environment mapping. Still not perfect, under development (if I have spare time, I hope I have 48 hours a day =D).
http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter07.html
This is based on cube maps with six environment textures (neg-x, neg-y, neg-z, pos-x, pos-y, pos-z)

The six textures of the cube's six surfaces,
Pictures are "borrowed" from http://www.humus.name/index.php?page=Textures&ID=81
Licensed under a Creative Commons Attribution 3.0 Unported License.






----------------------------------------------------------------