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