Jump to content

  • Log In with Google      Sign In   
  • Create Account


#Actualjbadams

Posted 15 February 2013 - 04:30 AM

Hi, I'm implementing raytracing to become familiar with it.

So far, I create two spheres.
Sphere 1 is at (0, 0, 5), radius = 1
Sphere 2 is at (0, 10, 50), radius = 20

Camera is at (0, 0, -1)

This is the Sphere class [only the hit function is interesting]
class Sphere : Surface
{
Material material;
Vector3 center;
float radius;

this()
{
}

this(const ref Vector3 _center, float _radius)
{
center = _center;
radius = _radius;
}

bool hit(const Ray r, float p0, float p1, ref HitInfo hitInfo) const
{
Vector3 d = r.d, e = r.e, c = center;

float discriminant = dot(d, e-c) * dot(d, e-c) - dot(d, d) * (dot(e-c, e-c) - radius * radius);
if( discriminant >= 0 )
{
//float t1 = (dot(-d, e-c) + sqrt(discriminant)) / dot(d, d);
float t2 = (dot(-d, e-c) - sqrt(discriminant)) / dot(d, d);

// TODO: don't forget to change this if needed
if( t2 < p0 || t2 > p1 )
return false;

hitInfo.t = t2;
hitInfo.hitPoint = e + d * t2;
hitInfo.ray = d;
hitInfo.surfaceNormal = (hitInfo.hitPoint - c) * 2; // is this correct?
}

return discriminant >= 0; // TODO: implement
}

Box boundingBox() const
{
Vector3 min = {center.x - radius * 0.5f, center.y - radius * 0.5f, center.z - radius * 0.5f};
Vector3 max = {center.x + radius * 0.5f, center.y + radius * 0.5f, center.z + radius * 0.5f};

Box b = {min, max};

return b;
}

Vector3 shade(HitInfo hitInfo) const
{
return material.shade(hitInfo);
}
}
So, Spheres need to have a Material, that decides how they are going to be drawn.
In the simplest case, my material can be:
class SimpleColor : Material
{
private Vector3 color;

this(ubyte r, ubyte g, ubyte b)
{
color.x = r / 255.0f;
color.y = g / 255.0f;
color.z = b / 255.0f;
}

Vector3 shade(HitInfo hitInfo) const
{
return color;
}
}
So, I chose red and green colours. Everything looks fine.
[img=http://[url%3Dhttp://i50.tinypic.com/35b7b49.png]http://i50.tinypic.com/35b7b49.png[/url]]



The next step was to make the shade function a bit more complicated:
Vector3 shade(HitInfo hitInfo) const
{
Vector3 l = {0, 1, 0}; // let's say that the light is at this position. (It's hardcoded for now - just for the test)
Vector3 lightVector = l - hitInfo.hitPoint; // vector from the hit point to the light

// TODO: fix
if( hitInfo.surfaceNormal.dot(lightVector) <= 0 )
{
return color * 0;
}
else
{
return color * hitInfo.surfaceNormal.dot(lightVector);
}
}
So I just return the colour multipled by the dot product of the surface normal and the light direction vector. What I get is this:
[img=http://[url%3Dhttp://i45.tinypic.com/29zeek1.png]http://i45.tinypic.com/29zeek1.png[/url]]

Are all those normals negative? Or am I doing something wrong? (I bet I am smile.png )

: Fixed tags.


#1sheep19

Posted 13 December 2012 - 06:17 PM

Hi, I'm implementing raytracing to become familiar with it.

So far, I create two spheres.
Sphere 1 is at (0, 0, 5), radius = 1
Sphere 2 is at (0, 10, 50), radius = 20

Camera is at (0, 0, -1)

This is the Sphere class [only the hit function is interesting]
class Sphere : Surface
{
Material material;
Vector3 center;
float radius;

this()
{
}

this(const ref Vector3 _center, float _radius)
{
  center = _center;
  radius = _radius;
}

bool hit(const Ray r, float p0, float p1, ref HitInfo hitInfo) const
{
  Vector3 d = r.d, e = r.e, c = center;
 
  float discriminant = dot(d, e-c) * dot(d, e-c) - dot(d, d) * (dot(e-c, e-c) - radius * radius);
  if( discriminant >= 0 )
  {
   //float t1 = (dot(-d, e-c) + sqrt(discriminant)) / dot(d, d);
   float t2 = (dot(-d, e-c) - sqrt(discriminant)) / dot(d, d);
  
   // TODO: don't forget to change this if needed
   if( t2 < p0 || t2 > p1 )
    return false;
  
   hitInfo.t = t2;
   hitInfo.hitPoint = e + d * t2;
   hitInfo.ray = d;
   hitInfo.surfaceNormal = (hitInfo.hitPoint - c) * 2; // is this correct?
  }
 
  return discriminant >= 0; // TODO: implement
}

Box boundingBox() const
{
  Vector3 min = {center.x - radius * 0.5f, center.y - radius * 0.5f, center.z - radius * 0.5f};
  Vector3 max = {center.x + radius * 0.5f, center.y + radius * 0.5f, center.z + radius * 0.5f};
 
  Box b = {min, max};
 
  return b;
}

Vector3 shade(HitInfo hitInfo) const
{
  return material.shade(hitInfo);
}
}

So, Spheres need to have a Material, that decides how they are going to be drawn.
In the simplest case, my material can be:

class SimpleColor : Material
{
private Vector3 color;

this(ubyte r, ubyte g, ubyte b)
{
  color.x = r / 255.0f;
  color.y = g / 255.0f;
  color.z = b / 255.0f;
}

Vector3 shade(HitInfo hitInfo) const
{
  return color;
}
}

So, I chose red and green colours. Everything looks fine.
Posted Image



The next step was to make the shade function a bit more complicated:
Vector3 shade(HitInfo hitInfo) const
{
  Vector3 l = {0, 1, 0}; // let's say that the light is at this position. (It's hardcoded for now - just for the test)
  Vector3 lightVector = l - hitInfo.hitPoint; // vector from the hit point to the light
 
  // TODO: fix
  if( hitInfo.surfaceNormal.dot(lightVector) <= 0 )
  {
   return color * 0;
  }
  else
  {
   return color * hitInfo.surfaceNormal.dot(lightVector);
  }
}

So I just return the colour multipled by the dot product of the surface normal and the light direction vector. What I get is this:
Posted Image

Are all those normals negative? Or am I doing something wrong? (I bet I am :) )

PARTNERS