Friday, December 16, 2011

Volume Rendering

Game Plan -

  • Hit a sphere
  • Have sphere call its shader
    • Shader : "Oh! I'm a Volume Shader..."
    • Shader finds second hit point (behind sphere)
    • Shader marches by some delta for some number of steps across distance between hitpoints (which we know because we found them both) in the direction of the original hit direction
    • Each step applies the over operator (more info found here

You can see the steps in the red ball above.




Added Perlin Noise to the volume by tweaking the alpha value according to PerlinNoise3D function.





Applied Beer's Law (at every delta) to prevent intensity having a dependence on number steps.  Also had ray continue out back. (Forgot negative sign in exponent in above picture.)

Changed to negative exponent.

Next, added lighting -
Process :

  • March through volume
  • At every step, march through ray pointing to light until you exit the volume
  • Calculate the light attenuation at that current position and use that in the "blending operator" so that the total light that accumulates and is sent to the camera includes the correct intensity of light from every point along the originally marched path    

Here is my scene without lighting :



And now WITH light: 

Light color - (.9, .4, .9), 
Noise -


thisTrans.x() = exp( sin(- hr.thingHit->_absorbCoeff.x() * noise_scale * absPert.x()) * delta);
thisTrans.y() = 0 ; //exp( - hr.thingHit->_absorbCoeff.x() * noise_scale * absPert.y() * delta);
thisTrans.z() = ( exp( tan(- hr.thingHit->_absorbCoeff.x() * noise_scale * absPert.z()) * delta));


Trig functions in exponents = awesome. (Discovery attributed to Steven!)

(sin and perlin - alpha)


Not exactly a plasma ball (yet), but not too shabby.

Tuesday, December 13, 2011

Refraction

Visualizing the difference between the Refraction angle and the View angle :

vec3f findRefracted(vec3f L, vec3f N, float n1, float n2)
{
// 
//
vec3f R (0.f, 0.f, 0.f);
float LdN = L.dot(N);
float cos2 = 1 - (1 - pow(LdN,2))*pow((n1/n2),2);
cos2 = sqrt(cos2);
R = - (n1/n2) * (L - LdN * N) + cos2 * -N;
// what I had before....R = - N * LdN + (N * (-LdN) - L) * (n1/n2);
return R;
}



In VizShader :


vec3f unitvec = refractVec.dot(viewDir) ;


In the center, the refracted ray is going straight through ( same direction as the view dir) and the dot product between two parallel rays is 0 - so we get black. The differences are symmetric going out from the center.



Dec 13 2011


Breaking it Down - Visualizing the Components:

Tasks- Visualize the following: 

  • View direction
  • Reflection direction
  • Normals 
  • Refraction directions
    • hit 1
    • hit 2
  • Time between hits (distance)
Notes on Expectations : 
  • View viz outer rim will match Reflection viz outer rim 
    • (Grazing angle of reflection will match View almost identically)
  • Reflection will look like Normal directions compressed and shifted toward viewer
  • Refraction will be similar to View direction colors
  • When indices of refraction are equal, refraction directions and view directions will match.
  • Distance between hits will be greatest in center and diminish toward outer rim.


Ready, set, GO!

View Direction (Pointing away from Sphere)



Reflection Direction (View Pointing Away)
Normals 




Refraction Directions: 

Enter/Exit
Hmmmm.... Shouldn't it be a symmetrical gradient outward?


Good References:
http://www.flipcode.com/archives/reflection_transmission.pdf
http://hyperphysics.phy-astr.gsu.edu/hbase/phyopt/freseq.html

Wednesday, November 23, 2011

SVN

  • Used these instructions to get SVN setup.
  • Basics : (run from local computer - /Users/smg/smgsvn/svnrepository)
    • svn co svn+ssh://smgonzal@trucks.cs.unm.edu/nfs/student/s/smgonzal/svnrepository/
    • svn add example.txt
    • svn commit -m "blah"
    • emacs example.txt 
    • svn update example.txt 
    • svn commit -m "blah blah"
  • Followed this tutorial summarized below: 
                                Quick Reference: 
            Task:                                                         Command: 
          
          Revision Details 

                        Specific Revision................................   svn log -v -r#          
                                                                                      (# is revision number) 
                        Specific File .......................................   svn log -v a_File.txt            
                                                                                                                
          Add a_File.txt ..................................................  svn add a_File.txt
          
          Commit ............................................................ svn commit a_File.txt

          Update ............................................................. svn up
          
                    


Tuesday, November 22, 2011

Texture Mapping

November 22, 2011
Texture Mapping

Theta Phi Switched


Prior to Recalculation                                                           After Recalculation 
I recalculated the theta-phi /XYZ mapping with Scott, but my results were almost identical, meaning the error lies elsewhere.
  




Visualizing Theta                                                                    Visualizing Phi
We are looking down the Y axis. I am not seeing an obvious gradient from black to red (0 to 2PI) for theta. There is a slight hint around the edges (visible on the red left edge) of darkening. I set the sphere's local orthogonal basis to correspond with the world's coordinate system. 

World ------> Sphere
X                    u
Y                    v
Z                    w
Since I am measuring theta counterclockwise from the sphere's v axis, the red/black seam is expected when looking down the Y axis when the world and sphere axes correspond.
I measured phi from the sphere's positive w axis ( currently corresponding to the world's Z ). The top should be black and fade downward to bright green.







Visualizing Theta and Phi Together - Front and Rear View 
It doesn't wrap around after all... hmmm....



Noise After Angles Verified
It looks similar to the first error mentioned. One interesting thing to note is the color range - Cyan, Magenta, Yellow. Complimentary.


After Truncating Floats : Front and Back View
I added a check to verify I was accessing data with base values divisible by three and discovered this was not the case. Floats were being used as index values, but C++ does not inherently cast them to integers. Truncating the floats to ints before using them to calculate dataLocation (the index for the float array where I store my data) gave... TEXTURE! (Kind of - it is repeating...)




I found that multiplying by 16 PI limited the repetitions in theta to only front and back. Why though?
Time to revisit the 3R-->2R calculations....


November 29, 2011

The atan2 function returns values from -pi to +pi, which is what I needed. Replacing atan with atan2 (and no longer dividing by 16 PI) :





What about:

  • Making a 'Mask' from the image - reading in specular coeff.
  • Greater specular reflection from water 

// Give water greater specular 
if (currColor.z() > currColor.x() && currColor.z() > currColor.y() && currColor.z() > .2
{
shadeRec.color = rvDotl * vec3f(.5f);
}
else 
{
shadeRec.color = rvDotl * vec3f(.1f);
}



Next: 
Added Texture* _specData element to Zeugs
Read in data to determine specular coefficients (embedded into red value of map ... see below)

Resulting image: 



Friday, November 18, 2011

Perlin Noise

Weird lines, ay? I was recreating my PNoise object each time. Creating it only once and using that one each time eliminated the lines.

Like squiggles from a three-year old. Mumsy was never so proud.

Thursday, November 17, 2011

"Oh String Stream...

...That I were a character in your buffer.... "

November 17, 2011
Intro to the Almighty String Stream 


File IO Spike (link)



November 22, 2011

- Indexing data

- Displayed texture alone on screen
     + strange colors
     + Using unsigned chars fixed it
- theta and phi switched 

 http://www.dreamincode.net/forums/topic/95826-stringstream-tutorial/
 http://www.cplusplus.com/reference/iostream/stringstream/
 http://stackoverflow.com/questions/2693631/read-ppm-file-and-store-it-in-an-array-coded-with-casd

Viewing a PPM File

November 15, 2011
Step 1: Intro to PPM File Format

 
What is in a PPM file? 


     PPM file description: http://netpbm.sourceforge.net/doc/ppm.html

   
   
    This 5 x 3 pixel image (drawn in GIMP, using only 255 and 0 for RGB values) gave the following when opened in TextEdit:
   
P6                                                                       // "Magic Number" Image type
# CREATOR: GIMP PNM Filter Version 1.1   // Comment
5 3                                                                    // Image Width and Height
255                                                                     // Max color value
ˇˇQˇQˇQˇ6ˇ6ˇ                                                    // Actual Data?


At first glance, I wanted each character to correspond to a specific color because the pattern almost matched. I looked up the individual ASCII characters and their binary forms to further investigate...


ASCIIDECIMALBINARYCOLOR I WANT IT TO BE
NA?       3200100000 Red??
ˇ      13610001000 Black??
Q       8101010001 Green??
6       6 00000110 Blue??


**HOWEVER**

P 6 means the data is stored in a binary format. Each pixel uses three bytes of data - one byte each for R, G, and B. ( Max color value makes sense : 2^8 = 256 ). 

                    Expected # Bytes = Width x Height x 3 = 15 x 3 = 45 bytes.

If a char is 1 byte, why am I only seeing 12 characters? What happened to the other 33 bytes? Are there characters I cannot see?


PPM code references: http://www.cse.unr.edu/~bebis/CS302/





November 16, 2011


The TextEdit version of my PPM image was NOT what I expected. From my understanding, it should have been something like:

00000000 00000000 00000000 --for black    
11111111 00000000 00000000 --for red          
00000000 11111111 00000000 --for green
00000000 00000000 11111111 --for blue

I coded a tack to read from the file, store it in a char array, and print it to the screen. The data portion was seemingly missing... (Turns out the ascii codes for 0 and 255 are not visible characters.)


Changed the colors from 255 (1111 1111 = (null) ) to 125 ( 0111 1101 = } ) and 0 (0000 0000) to 33 (00100001 = !), I would expect to see :
!!!   }!!   !!!   }!!  !!!
!}!   !!!   !}!   !!!   !{!
!!!   !!}   !!!   !!}   !!!




Instead, I opened the .ppm with TextEdit and got this:
P6
# CREATOR: GIMP PNM Filter Version 1.1
5 3
255
ˇˇˇˇˇˇˇ
Maybe TextEdit isn't the correct way to view the data. How does it open files? Can it open files with binary, and does it display binary as ascii?

For a different viewing method, I consulted J Bowles who showed me the following terminal commands for a more reliable way of viewing:


od -xc ColorTestGrid.ppm | less
od -bc ColorTestGrid.ppm | less 
Detailed description found HERE.


These (as well as emacs) gave:


P6
# CREATOR: GIMP PNM Filter Version 1.1
5 3
255
!!!}!!!!!}!!!!!!}!!!!!}!!!!!}!!!!!!}!!!!!}!!!
 As expected. Viewing mystery solved!


References : http://www.cplusplus.com/doc/tutorial/files/
                    http://en.wikipedia.org/wiki/Netpbm_format
                    http://www.asciitable.com/
                    http://linux.about.com/library/cmd/blcmdl_od.htm
                

Tuesday, November 15, 2011

Boxed In...


November 5, 2011


  • Made BVH and Boxes independent.
  • Verbose Variable names
  • Recursion Recursion Re…
  • Modular approach



November 7, 2011


Errors / Issues / Progress:

  • Traverse - Used wrong root node (BvhRecord did not need one in it)
  •  Leaf nodes not sure what to do with themselves (wasn't boxing them)
  • visualized by level
  • Weird container boxes (not containing by level)
  • Added keyboard detection (press "l" for new level)


Levels 1 - 8 (Progressively)


November 8, 2011



 There IS A DIFFERENCE between " ++a " and " a + 1 "... I was incrementing the levels in my recursive MakeBVH function twice as often as I wanted because I was using ++a. 

Discovery and Progress:
  • Repost re-runs display function. (This is why it is re-making the tree every time I hit "l")
  • Brought sphere and plane intersect into header "Definitions.h" file. 
    • intersect must know members of sphere and plane, but sphere and plane contain definition file. 
    • Tried forward declarations, but need members not just pointer to class
    • Finally just passed in necessary info in basic datatype form (vec, int, float, etc.)


Statistics : 


Main Loop Duration Method Number Spheres Number Intersections
5 seconds Trace All 80 20.9 M
3 seconds BVH 80 2.9 M
23 seconds Trace All 356 29.8 M
6 seconds BVH 356 7.6 M
Unknown Trace All 1024 Est: 536.8 M
8 seconds BVH 1024 9.9 M




The time benefit of BVH increased with the number of spheres in the scene. Trace All crashed with 1024 spheres, but I estimated intersections were :


Num_Rays (imgH x imgW = 512 x 512 ) X Num_Spheres X 2 (1024 x 2 --> doubled b/c front and back hitPts) = approx 536.8 M






Some Resources used Along the Way: 


http://stackoverflow.com/questions/529071/xcode-automatically-deactivating-breakpoints


http://msdn.microsoft.com/en-us/library/windows/desktop/ms740560(v=vs.85).aspx
http://www.cplusplus.com/forum/beginner/4471/
http://pubs.opengroup.org/onlinepubs/7908799/xsh/systime.h.html
http://web.me.com/haroldsoh/tutorials/technical-skills/microsecond-timing-in-cc-wi.html


    Saturday, November 12, 2011

    Restructuring

    November 10, 2011
    • Implemented Singleton on Enviro class
    • Used Strategy for Shader, Tracer classes
    • Allowed Shader to use BVH tracer ....  Expected speed up. Instead, reflections broke.
      • Still going through traverse function (run time is the same)
      • No visible sign of reflections

    Thursday, November 10, 2011

    Random Spheres

    November 8, 2011

    Not so great for testing BVH... They're all squished in the same vicinity! 


    November 10, 2011


    Clipping...
    Fixed clipping! (Was using slight epsilon to decrease box size for easier debugging.)


    Tuesday, October 25, 2011

    Viewing Tree Depth

    This version of my program partitions a unit cube and places them in a BVH tree. It renders the resulting bounding boxes (cubes) whose nodes have the desired tree depth.




    I used this for timing. When generating and rendering a tree with a total depth of 6, it took ~14 - 20 seconds (for rendering boxes of depth one vs. depth six). A total depth of three took about 2-3 seconds, regardless of how many boxes I rendered. It seems strange that it should take so long.

    I believe the ability to view by layer will help me debug my code as I develop an algorithm to group geometric shapes.

    Silly Errors Along the way:

    • Swapping min and max corners when declaring boxes
    • Not overloading operators (like = )
    • Not returning anything for a non-void function.

    Wednesday, October 12, 2011

    Operator Overload

    October 12, 2011

    I was receiving the EX_BAD_ACCESS error because I had not defined the = operator for BoundingBoxes.

    I discussed the possibility of using pointers to bounding boxes instead of the actual thing, but the easiest solution at present seems to be overloading the = operator.

    This site proved helpful in explaining the process.

    Edit/Update


    Rather than overloading the operator, I set the elements individually equal to each other (setting minCorner and maxCorner manually.) This was an easy option because so few elements make up a bounding box. For larger complex objects, = or pointers would be more ideal.

    Tuesday, October 11, 2011

    Preparing for BVH

    Step One : Hit a Box Square


    Silly Error # 0: Not checking all necessary boundaries:

    I forget what caused the speckled/noisy consistency. I think I was making normal t values negative, which later caused me to disregard them...

    Success:

    The slight distortion is correct because the eye is at (0,5,2). +Z is up.

    Step Two: Hit a Box



    Silly Error # 1: Checking wrong Axes-




    Silly Error # 2: Adding negative signs to t value for the...fun of it.


    Finally successful:

    I chose to shade according to axis. Faces with a normal parallel to X got red, Y got green, and Z got blue.
    I was worried that I was missing the sides, so I changed the eye position to (3,5,2). This verified I was getting all sides.