Ray Tracer Question


#35

Although it’s too harsh of a guideline to follow all of the time, in general you don’t want to override non-abstract methods for that very reason.

I’ve been burned (badly) by that one.


#36

just noticed 2 bugs in your code - probably not causing the current issue but still…

 
	// Sphere3 - a green one
// A few variables for the second sphere
Vector3D pos3(0,-50,0);
Material green(200,0,0);
// Create the second sphere
sphereList[2] = new Sphere;
sphereList[2]->setPosition(pos2);
sphereList[2]->setRadius(50);
sphereList[2]->setMaterial(green);

/*
// Sphere3 - a light source
sphereList[2] = new Sphere;
sphereList[2]->setLight(1);
*/

FIRSTLY
you are initialising your green material to the same colour as your red material
Material green(200,0,0);
when i imagine you actually want
Material green(0,200,0);

SECONDLY:
in the same code (above) you are reassigning sphereList[2] to a whole new memory location (before you set the light)- not only will this mean you will lose the position, radius and material settings but you will also cause a bit of a memory leak .

i’m pretty sure you were’nt intending on that so I suggest you remove the second occurrence of sphereList[2] = new Sphere;


#37

I have been spending a night at my girlfriends place, and you have been trying to help me with my code. Makes me feel kind of bad. But I appreciate it :slight_smile:

SECONDLY:
in the same code (above) you are reassigning sphereList[2] to a whole new memory location (before you set the light)- not only will this mean you will lose the position, radius and material settings but you will also cause a bit of a memory leak .

i’m pretty sure you were’nt intending on that so I suggest you remove the second occurrence of sphereList[2] = new Sphere;

This does not really affect my code, as there is no support for lights and the light creation has been commented out from the start, its just a reminder to me that I need to add it later on.

FIRSTLY
you are initialising your green material to the same colour as your red material
Material green(200,0,0);
when i imagine you actually want
Material green(0,200,0);

Thanks for pointing that out, must have missed that.

check that your Scene.getSphere(currentSphere) function is returning the correct sphere

it’s often the simple things (like forgetting to replace a stub function) that screw up code

I thought there might have been something wrong with that part as well, but it looks like it works ok.

just noticed 2 bugs in your code - probably not causing the current issue but still…

I agree, but the color thing made it easier to see what is wrong. Now it looks like the other spheres are only visible if they are inside of the green one.

It looks like there is something wrong with determing which sphere is closest. So I will look into that. ShaderHacker made a post about some errors in my intersection code, so the the problem might be there.

But I think there are one more problem, that causes the spheres to only be displayed if they are inside of the green one. I am open for suggestions to why this happes.

Although it’s too harsh of a guideline to follow all of the time, in general you don’t want to override non-abstract methods for that very reason.

I’ve been burned (badly) by that one.

Can you please explain a bit more? Not really sure what you are saying here.

Thanks again for all help and support:)


#38

I solved it, it was way to easy accually. But now it works:)

Kind of sexy :slight_smile:


#39

excellent :smiley:

what was the problem?


#40

My problem was here:
clostesSphere should be less than 0 and closesSphereDistance should be high to ensure that a new distance is assigned to i when I check for spheres.


 			// A variable for checking which sphere is closest
 			float closesSphereDistance = -1;
 			int closestSphere = 0;
 

Right now I am trying to add lights to it, but I am stuggeling a bit with adding it. Somehow I get a flat color, so it looks like the picture above, just a bit lighter.

Any ideas`?


#41

oh how annoying - it’s always simple things!

are you calculating the colour using equations for ambient, diffuse and specular? and you’re using the angle of incidence etc etc?

it’s these things that will make it look 3d so if you are just combining the object colour and the light colour then it will appear flat


#42

I think its defuse lightning I am doing.

Here is the code for it:


 // We have now looped through all the spheres in the scene and found
			// the closest one
			// Find the color of it
			if ( closestSphere != -1 )
			{

				//std::cout << closesSphereDistance << std::endl;
				
				float r, g, b = 0;
				
				// Check which if there is a light affecting the sphere
				for (int currentLight = 0; currentLight <= thisScene.getAmountOfObjects(); currentLight++)
				{
					Vector3D sphereRayIntersection;
					Point rayOrg = currentRay.getOrigin();
					
					// Add the start point of the ray and the direction of the sphere together
					// and mult. it with the distance to closest sphere
					sphereRayIntersection = currentRay.getDirection();
					sphereRayIntersection.setX(rayOrg.getX() + (sphereRayIntersection.getX() * closesSphereDistance ));
					sphereRayIntersection.setY(rayOrg.getY() + (sphereRayIntersection.getY() * closesSphereDistance ));
					sphereRayIntersection.setZ(rayOrg.getZ() + (sphereRayIntersection.getZ() * closesSphereDistance ));
					
					
					// Find the normal to the sphere at point of intersection
					Sphere thisSphere = thisScene.getSphere(closestSphere);
					Vector3D normal;
					float oneOverRadius = 1/thisSphere.getRadius();
					
					normal = sphereRayIntersection - thisSphere.getPosition();
					normal.scale(oneOverRadius);
					
					normal.normalize();
					
					// Get the light direction
					Vector3D lightDir;
					
					Sphere thisLight = thisScene.getLight(currentLight);
					lightDir = thisLight.getPosition() - sphereRayIntersection;
									 
					lightDir.normalize();
   
					// Find light coefficient
					float lightCoef = AbsDot(lightDir,normal);
					if (lightCoef < 0)
					   lightCoef = 0;
					   
					
					// Get the color of the light and how much it affects the sphere
					Material thisMaterial = thisLight.getMaterial();
					
					float lightR = thisMaterial.getR() * lightCoef;
					float lightG = thisMaterial.getG() * lightCoef;
					float lightB = thisMaterial.getB() * lightCoef;
					
					
					// Add the effect of the light to the color of the sphere
					Material sphereColor = thisSphere.getMaterial();
					
					 r = ((sphereColor.getR() * lightR) / 255 );
					 g = ((sphereColor.getG() * lightG) / 255);
					 b = ((sphereColor.getB() * lightB) / 255);
					 
					 
					
					// Make sure that the color is not higher than 255
					if (r > 255)
					   r = 255;
					if (g > 255)
					   g = 255;
					if (b > 255)
					   b = 255;
					   
					   //std::cout << r << "," << g << "," << b << std::endl;
				}
					   
				// Assign the color to the pixel
				int colorR = r;
				int colorG = g;
				int colorB = b;
				
				colorBuffer[arrayTracer + 0] = colorR;
				colorBuffer[arrayTracer + 1] = colorG;
				colorBuffer[arrayTracer + 2] = colorB;
				
			}   

Going to do some reading today on the topic of adding light, as I am not 100% sure how its done.


#43

Ok, I have given up the code posted above and decided to try the algorithm from an other tutorialinsted.

I find the code in that tutorial kind of confusing as the variable names and commenst are weird. So I have rewriten it in my own words insted. Is this right?

I am not sure what everything here does, as my math knowledge is kind of limited (going to cover this next year :slight_smile: ) so I was wondering if someone could comment in a bit or something to give me a clue of what is going one.

Kind of feeling like I am flooding the forum here:p When you are tierdof me, just ask me to shut up :slight_smile:


for(each light in the scene)
{
		 // dist = the distance between the ray.org and the intersectionPoint
		 Vector lenght = Sphere.position - (ray.org + ray.dir * dist)
		 Normalize(lenght)
		 
		 Vector normal = Normal(ray.org + ray.dir + dist)
		 
		 dotProduct = Dot(normal, light)
		 if(dotPoroduct > 0)
		 {
			 DiffuseColor = dotPoroduct * sphere.diffuseValue
			 finalColor += DiffuseColor * sphere.color * lightColor
		 }
}



#44

Please keep posting. :smiley:


#45

This seems almost correct.

for (each light)
{
Vector Normal = intersection_pt - sphere.position;

Normal.normalize(); // normalize the normal

Vector LightDir = light.position - intersection_pt;

LightDir.normalize(); // normalize the light vector

float dot = clamp(0, 1, Dot(Normal, LightDir));

finalColor += dot * sphere.diffuseValue (this is a scalar value to increase the diffuse effect) * sphere.color * lightColor;

}


#46

for (each light)
{
Vector Normal = intersection_pt - sphere.position;

Normal.normalize(); // normalize the normal

Vector LightDir = light.position  - intersection_pt;

LightDir.normalize(); // normalize the light vector

float dot = clamp(0, 1, Dot(Normal, LightDir));

 finalColor += dot * sphere.diffuseValue (this is a scalar value to increase the diffuse effect) * sphere.color * lightColor;

}

Thanks for sharing, I will try to add it do my own code tonight.

The more and more I work on this project I realize that I have a fundamental problem, as I lack knowledge in math and fundamental computer graphics. So I guess I have to find the money to get myself a new book. Could anyone recomend a book which covers the math in computer graphics? Not just has it as an introduction before the other topic starts, but that has math as one of its main topics. Other topics I would like to know more about is rendering/raytracing and physic simulation. So, do anyone by chance know of a book that would work for me?

Thanks in advance


#47

Woho, next step reached :slight_smile:


#48

How many lights do you have in the scene? The bottom of the spheres seems off unless you have a light placed near the bottom of the sphere and pointed up.

Btw, congrats on the next level! :thumbsup:

I’ll leave you to exploring now. Good Luck!

Cheers,

-M


#49

woohoo! go H3ro!! isn’t it satisfying to see the results of something you’ve made from scratch :slight_smile: i think i’ve still got the pic of my v first ray-traced sphere (yes i know i’m a little bit sad)

books-wise i’ve got the classic Foley book: Introduction to Computer Graphics
http://www.amazon.com/Introduction-Computer-Graphics-James-Foley/dp/0201609215/ref=sr_1_3/103-9288412-5006250?ie=UTF8&s=books&qid=1177319231&sr=8-3

I had to buy it for a course at uni but i really think it’s worthwhile. it doesn’t cover things like differential equations but it does all your vector/matrix math very clearly - as well as projections, parametric curves/surgaces, solid modelling etc. there are a couple of chapters that are’nt interesting to me at all (Input Devices, Graphics Hardware etc) but it gives you a nice theoretical coverage of main topics. Only problem is that it doesn’t go into detail on everything - but it’s a great all-rounder. And i found that you can google anything that’s missing.

finally - try the sticky at the top of this forum - i think there’s a book review there


#50

How many lights do you have in the scene? The bottom of the spheres seems o unless you have a light placed near the bottom of the sphere and pointed up.

There is only one light in the scene, so there is a small bug somewhere. I guess it has something to do with my light being to bright(have to do finalColor / 1000000 to get something usefull).

woohoo! go H3ro!! isn’t it satisfying to see the results of something you’ve made from scratch :slight_smile: i think i’ve still got the pic of my v first ray-traced sphere (yes i know i’m a little bit sad)

Hehe, its like a baby:P It was kind of satisfying to see that something that I have spendt that much time

books-wise i’ve got the classic Foley book: Introduction to Computer Graphics
http://www.amazon.com/Introduction-…77319231&sr=8-3

I will see if I can get my hands on it, thanks for recomending:)

I am now in the progres of rewriting the whole program (lot of crap and “hacks” to make it work) so that it can support more interesting objects than just spheres. Finally the book I first bought are starting to make some sense to me, so hopefully I will be able to use it as a reference instead of browsing for tutorials and sourcecode online.

I will post more when I have something interesting to show :slight_smile:

Thanks for all support, would never got this to work if it was not for the help I got from you guys.


#51

By the looks of it, I’d say you’re calculating how perpendicular/parralel the normal on the sphere is without taking into account whether its facing towards or away from the light (+/- relative). I’m afraid I’m not especially well ATM so maybe someone else can demonstrate the math relative to a non-planar object?

Also, the Introduction book may not go into great detail, but the other book listed under ‘better together’ is one I’ve recommended many a time, is by the same authors and goes into stupid levels of detail… and by stupid I mean BSc (Honours) levels of detail.


#52

Now I have rewritten my intersection code so that it takes into account if its starts inside of an object. I am not sure how to calc the intersection point, but I think it is done by:
(ray.dir + distanceBetweenRayAndSphere) + ray.start

Is that right?


 // The intersectiontest between a sphere and a ray:
 result Sphere::intersectionTest(Ray r)
 {
 	   // A variable for holding the result
 	   result res;
 	   
 	   // Change the point where the ray starts into a vector to
 	   // ease calculations later on
 	   Point rayOrgP = r.getOrigin();
 	   Vector3D rayOrg(rayOrgP.getX(), rayOrgP.getY(), rayOrgP.getZ());
 	   
 	   // Find a vector from the ray origin to the center of the sphere,
 	   Vector3D RaySphereDirection = getPos() - rayOrg;
 	   
 	   float DotRaySphereDirection = Dot(RaySphereDirection, RaySphereDirection);
 	   
 	   // Check if the ray starts inside of the sphere
 	   if (DotRaySphereDirection < (radius * radius))
 	   {
 		   // Find t
 		   float t = Dot(RaySphereDirection, r.getDirection());
 		   float t2 = (radius * radius) - DotRaySphereDirection + (t * t) / 
 					  (Dot(r.getDirection(),r.getDirection()));
 		   float distance = t - sqrt(t2);
 		   
 		   // The ray hits the inside of the sphere
 		   res.hit = -1;
 		   res.distance = distance;
 		   //res.intersectionPoint = ??
 		   
 		   return res;
 	   }
 	   else
 	   {
 		   float t = Dot(RaySphereDirection,r.getDirection());
 		   if (t < 0)
 		   {
 				 // The ray points away from the sphere
 				 // MISS
 				 res.hit = 0;
 				 
 				 return res;
 		   }
 		   float t2 = (radius * radius) - DotRaySphereDirection + (t * t) /
 					  (Dot(r.getDirection(),r.getDirection()));
 					  
 		   if (t2 > 0)
 		   {
 				  // The ray hits the outside
 				  res.hit = 1;
 				  res.distance = t - sqrt(t2);
 				  //res.intersectionPoint = ??
 		   }
 		   else
 		   {
 			   res.hit = 0;
 		   }
 	   }	  
 }
 

#53

Shaderhacker - is this the C equivalent of:

struct RGB{
unsigned int r;
unsigned int g;
unsigned int b;
unsigned int a;
};

???

or is there a subtle difference?
cheers
Holly


#54

In strict C, this struct :

 
  struct RGB{
  unsigned int r;
    unsigned int g;
    unsigned int b;
    unsigned int a;
};
  

would need to instanced with :


  struct RGB someInstance;
  

so, you could do :


  typedef struct RGB RGB;
  
  RGB someInstance;
  

or, you could collapse the entire thing to :

 
   typedef struct {
  unsigned int r;
  unsigned int g;
  unsigned int b;
  unsigned int a;
} RGB;
   

which would typedef the entire struct definition to RGB. In C++, this was one of the first things that got simplified, so to maintain portability :

 
   struct RGB {
  unsigned int r;
  unsigned int g;
  unsigned int b;
  unsigned int a;
};
   

can be instanced (in C++) with either :

 
  struct RGB someInstance;
  
  // or 
  RGB someInstance;