Wednesday, April 10, 2013
Tuesday, April 2, 2013
Thursday, March 21, 2013
Monday, February 25, 2013
Complex Geometry and Interactive Raytracing
It took me a while to complete the algorithm that extrapolates normals in a triangle. The trick is to compute the area of each triangle defines by the intersection point and the three vertices. Once you get that, just find the weighted mean, and you're done. Here is the code:
float4 v0
= triangle.p0 - intersection;
float4 v1
= triangle.p1 - intersection;
float4 v2
= triangle.p2 - intersection;
float
a0 = 0.5f*vectorLength(crossProduct( v1,v2 ));
float
a1 = 0.5f*vectorLength(crossProduct( v0,v2 ));
float
a2 = 0.5f*vectorLength(crossProduct( v0,v1 ));
normal =
(triangle.n0*a0 + triangle.n1*a1 + triangle.n2*a2)/(a0+a1+a2);
As simple as that :-)
Monday, February 4, 2013
Mandelbrot Set as a texture
GPUs are amazing, I tried to use the Mandelbrot set as a texture, because it's amazingly beautiful and easy to implement. The algorithm I used is the following:
__device__ void
mandelbrotSet( const SceneInfo& sceneInfo, const float x, const float y,
float4& color )
{
float W = (float)gTextureWidth;
float H = (float)gTextureHeight;
float MinRe = -2.f;
float MaxRe = 1.f;
float MinIm = -1.2f;
float MaxIm = MinIm
+ (MaxRe - MinRe) * H/W;
float
Re_factor = (MaxRe - MinRe) / (W - 1.f);
double Im_factor = (MaxIm - MinIm) / (H - 1.f);
float
MaxIterations = 20.f+sceneInfo.pathTracingIteration.x;
float c_im = MaxIm - y*Im_factor;
float c_re =
MinRe + x*Re_factor;
float Z_re = c_re;
float Z_im = c_im;
bool isInside = true;
unsigned n;
for( n = 0; isInside && n < MaxIterations;
++n )
{
float Z_re2 = Z_re*Z_re;
float Z_im2 = Z_im*Z_im;
if ( Z_re2+Z_im2>4.f )
{
isInside = false;
}
Z_im = 2.f*Z_re*Z_im+c_im;
Z_re = Z_re2 - Z_im2+c_re;
}
color.x += Z_re/64.f;
color.y += Z_im/64.f;
color
*= (n/MaxIterations);
}
GPUs amaze me for making it possible to enjoy real-time computation of ray-traced images, with the Mandelbrot set... as a texture.
Sunday, February 3, 2013
3D Parametric Curves are cool
3D Parametric Curves are cool because they
make it easy to construct beautiful shapes out of simple mathematical formulas.
Since I am lazy and not good at modeling 3D scenes, I thought that using these
equations was probably the best way to get nice images.
The following curves are made of cylinders, following the paths defined by the parametric curves.
void trefoilKnot(float R, float t, float4& p)
{
p.x = R*(sin(t)+2.f*sin(2.f*t));
p.y = R*(cos(t)-2.f*cos(2.f*t));
p.z = R*(-sin(3.f*t));
}
void torus(float R, float t, float4& p )
{
p.x = R*(3.f*cos(t)+cos(10.f*t)*cos(t));
p.y = R*(3.f*sin(t)+cos(10.f*t)*sin(t));
p.z = R*sin(10.f*t);
}
void star(float R, float t, float4& p )
{
p.x = R*(2.f*sin(3.f*t)*cos(t));
p.y = R*(2.f*sin(3.f*t)*sin(t));
p.z = R*sin(3.f*t);
}
void spring(float R, float t, float4& p)
{
p.x = R*cos(t);
p.y = R*sin(t);
p.z = R*cos(t);
}
void heart(float R, float u, float v, float4& p)
{
p.x = R*4.f*pow(sin(u),3.f);
p.y = R*0.25f*(13*cos(u)-5*cos(2.f*u)-2.f*cos(3.f*u)-cos(4.f*u));
p.z = 0.f;
}
void thing(float R, float t, float4 a, float4& p)
{
p.x = R*(sin(t)+a.x*sin(a.y*t));
p.y = R*(cos(t)-a.x*cos(a.y*t));
p.z = R*(-sin(a.z*t));
}
void moebius(float R, float u, float v, float s, float du, float dv, float4& p )
{
p.x = 2.f*R*(cos(u)+v*cos(u/2)*cos(u));
p.y = 2.f*R*(sin(u)+v*cos(u/2)*sin(u));
p.z = 2.f*R*(v*sin(u/2));
}
Sunday, January 13, 2013
Raytracing on the web
I had this in mind for quite a while but never got the chance to implement it. But there it is: A ray-traced molecule visualizer available on the web. The following syntax enables access to a remote HTTP service using the GPU to generate the JPEG image.
http://localhost/get?molecule=XXXX[&scheme=0|1|2][&structure=0|1|2|3][&rotation=<float>,<float>,<float>][&quality=<integer>]
http://localhost/get?molecule=XXXX[&scheme=0|1|2][&structure=0|1|2|3][&rotation=<float>,<float>,<float>][&quality=<integer>]
Parameters:
- molecule=XXXX
- 4 capital letters identifiying the molecule. The list bellow is the only one you can use for now).
- scheme=[0|1|2]
- 0: Standard
- 1: Chain
- 2: Residue
- example: scheme=2
- structure=[0|1|2|3]
- 0: Real size atoms
- 1: Fixed size atoms
- 2: Sticks
- 3: Sticks and atoms
- 4: Backbone
- example: structure=1
- rotation=[x,y,z] Rotates the molecule according to x,y and
z. Note that x,y,and z are real numbers specifying degrees of rotation for each
axe.
- example: rotation=45,0,0
- quality=[1-100]
- Identifies the number of iterations to process. The higher the better, and slower...
- bkcolor=[r,g,b] Specifies the red, green and blue values for background color.
- example: bkcolor=255,0,127
- postprocessing=[0|1|2]
- 0: None
- 1: Depth of field
- 2: Ambient occlusion
- size=[0|1|2|3|4]
- 0: 512x512
- 1: 768x768
- 2: 1024x1024
- 3: 1600x1600
- 4: 2048x2048
Sunday, December 30, 2012
Ellipsoids finally added to the ray-tracing engine
It took me a little while to correctly implement the ray-ellipsoid intersection function but there it is :-)
float4 O_C =
ray.origin-ellipsoid.center;
float4 dir =
ray.direction;
normalizeVector( dir
);
float a =
((dir.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x))
+
((dir.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y))
+
((dir.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z));
float b =
((2.f*O_C.x*dir.x)/(ellipsoid.size.x*ellipsoid.size.x))
+
((2.f*O_C.y*dir.y)/(ellipsoid.size.y*ellipsoid.size.y))
+
((2.f*O_C.z*dir.z)/(ellipsoid.size.z*ellipsoid.size.z));
float c =
((O_C.x*O_C.x)/(ellipsoid.size.x*ellipsoid.size.x))
+ ((O_C.y*O_C.y)/(ellipsoid.size.y*ellipsoid.size.y))
+
((O_C.z*O_C.z)/(ellipsoid.size.z*ellipsoid.size.z))
- 1.f;
float d =
((b*b)-(4.f*a*c));
if (
d<0.f || a==0.f || b==0.f || c==0.f )
return false;
d = sqrt(d);
float t1
= (-b+d)/(2.f*a);
float t2
= (-b-d)/(2.f*a);
if(
t1<=EPSILON && t2<=EPSILON ) return
false; // both
intersections are behind the ray origin
back =
(t1<=EPSILON || t2<=EPSILON); // If only one
intersection (t>0) then we are inside the ellipsoid and the intersection is at
the back of the ellipsoid
float t=0.f;
if(
t1<=EPSILON )
t = t2;
else
if(
t2<=EPSILON )
t = t1;
else
t=(t1<t2) ? t1 : t2;
if(
t<EPSILON ) return false;
// Too close to intersection
intersection = ray.origin + t*dir;
normal =
intersection-ellipsoid.center;
normal.x =
2.f*normal.x/(ellipsoid.size.x*ellipsoid.size.x);
normal.y =
2.f*normal.y/(ellipsoid.size.y*ellipsoid.size.y);
normal.z =
2.f*normal.z/(ellipsoid.size.z*ellipsoid.size.z);
normal.w = 0.f;
normal *= (back) ?
-1.f : 1.f;
normalizeVector(normal);
return true;
Sunday, December 2, 2012
Meet Taro, Ken and Ai, my new friends ;)
It's snowing outside, and it's freezing cold, so I decided to use my GPU to warm me up. Taro, Ken and Ai came out from this sunday of december.
Download the Windows Theme!!
Download the Windows Theme!!
Monday, November 19, 2012
RayCharts
Excited to announce that I will soon be releasing a ray-traced chart component. Here are a few screenshots of the pre-beta release.
Friday, November 16, 2012
Using textures to control refraction
Textures, just like in bump mapping, can be used to alterate the normal to a surface. If you combine it with refraction, ray-tracing can generate some cheap and pretty cool effects.
Subscribe to:
Posts (Atom)

















































