PDA

View Full Version : Ray Tracer Question


H3ro
03-26-2007, 04:12 PM
In my quest for attempting to learn programming and especially graphic related programming I have decided (or, people have recommended) to write a simple Ray Tracer. To get me started I bought “Physically based rendering : From theory to implementation” This turned out to be a great book in explaining all the different parts of the Ray Tracer, but unfortunately it does not really explain very well how all the parts work together.

I am looking for a simple Ray Tracer example, with source code which I can download and investigate to see how the different parts work together. The best for me would be to find a RT source where there is no reflection or anything like that, as I am only interested in the basic. I have found this (http://www.devmaster.net/articles/raytracing_series/part1.php)tutorial, but the source is made almost without comments so it does not really help me.

Thanks for your time.

Carina
03-27-2007, 06:56 AM
For the basics you might want to check:
http://www.amazon.co.uk/Realistic-Ray-Tracing-Peter-Shirley/dp/1568811985/

It explains things quite well and with plenty of code, without being quite as overwhelming as the PBRT book can sometimes be.

With regards to online tutorials, I don't know of any particularly great ones. If I recall correctly the one you mention is indeed pretty void of useful comments. And, again iirc, it's raytracing functions use variables p, P, pi, PI (amongst others) without any explanation of what they are, and none of them have anything to do with the actual number PI. :shrug:

H3ro
03-27-2007, 11:56 AM
Thanks for your reply, but unfortunately I don’t have money for a new book right now, so I am stuck with browsing the net. I posted a similar question over at gamedev.net, and one of the persons there gave me a link which looks great. Going to check it out more thoroughly when I am finished with making my chicken dinner thingy (Love laptops, can use them everywhere, even in the kitchen)


Btw, how is Bath? I see you are teaching there. I was thinking of applying, but unfortunately my grades will probably not be high enough so I dropped it.

Edit: I wanted to hare the link, but forgot it while I was typing. SO here it is:
LINK (http://www.ultimategameprogramming.com/demoDownload.php?category=RayTracing&page=1)

Carina
03-27-2007, 05:23 PM
Thanks for your reply, but unfortunately I don’t have money for a new book right now, so I am stuck with browsing the net. I posted a similar question over at gamedev.net, and one of the persons there gave me a link which looks great.

Well if you run into any particular problems let us know and we'll try to help.

Btw, how is Bath? I see you are teaching there. I was thinking of applying, but unfortunately my grades will probably not be high enough so I dropped it.

Bath is very nice. City is beautiful and the university is very good at sciences. Obviously I don't know what your grades are like but if they're just below what you think they'll accept it would probably be worth applying, and make sure you come across as very enthusiastic about the prospect of studying at the university. It never hurts to approach undergraduate admissions at the department you would like to study directly, and not just rely on your UCAS application, or a brief discussion with the university-wide admissions offices.

If it's computer science you're thinking about applying for, I would definitely apply. There's a lull in applicants in computer science at a lot of universities (due to tuition fees having risen etc), so there's possibly more room for maneuver than you might think.

dgoberna
04-11-2007, 01:39 AM
I have found this (http://www.devmaster.net/articles/raytracing_series/part1.php)tutorial, but the source is made almost without comments so it does not really help me.

That tutorial is really nice, i knew it time ago. It explains preety clearly the very basic concepts behind a raytracer, that is what you really need to make one. How to put things together is up to you, you only need to know how to write a pixel (on screen or a image file) and how a raytracer works. The latter is explained in that tutorial.

other tutorials:

http://www.flipcode.com/articles/article_raytrace01.shtml <-- the best tutorial i've seen
http://www.mandelbrot-dazibao.com/Ray/Ray.htm <- goes directly to the point, but is nice
http://google.com <-- lots of tutorials

good luck, i encourage you to try it, its a lot of fun and very addictive!!

H3ro
04-11-2007, 10:16 AM
http://www.flipcode.com/articles/ar...aytrace01.shtml (http://www.flipcode.com/articles/article_raytrace01.shtml) <-- the best tutorial i've seen

I dont really like that one. The code is so hard to read, but the text in the page is nice I gues.

------------------------------------------

I am working on the part of the Ray tracer that creates a ray. But from looking at examples I kind of get a bit confused.

Here is what I have, does it look correct?
// Main render stuff
void Engine::renderScene()
{
// A loop for every scene
for (int sceneNo = 0; sceneNo > getNumberOfScenes(); sceneNo++)
{
// A loop for the x (lenght) of the scene
for (int x = 0; x > widht; x++)
{
// A loop for the y (hight) of the scene
for (int y = 0; y > hight; y++)
{
// Create a ray
// ----------------------------------------------------
// A vriable for the direction
Vector3D rayDirection(x,y,0);

// A variable for where the ray starts. This is basicly
// the position of the camera in the scene
Point rayStart(0,0,-100);

Ray currentRay(rayStart, rayDirection);


// Check if it itersect with an object
// save color
}
}
}

std::cout << "\n---------------------------" << std::endl;
std::cout << " Sceene is rendered, all done" << std::endl;
}

So far I am finished with scene, math, color and material classes, so I have got a bit of work done. Let me know if anyone is interested in seeing them (even though they are very basic) I am happy to share.

Thanks for your time again.

HollyWoodland
04-12-2007, 08:37 AM
Hi H3ro

Here's my pseudocode for my ray tracer - it basically has the main iterative algorithm and then where you have written "//save colour" I call a shade() function. This function uses the standard formula (calling itself recursively) to combine ambient, diffuse and specular lighting then returns a single colour to the main algorithm:

main():

FOR each pixel on the screen
Construct the ray vector from camera to pixel
Find closest intersection
SHADE point of intersection
Place the colour in the pixel


shade():

IF there is no intersection point
THEN
RETURN background colour
ELSE
Construct shadow ray vectors
Compute DIRECT colour

IF the object is REFLECTIVE
THEN
Construct reflection ray vector
Find closest intersection
SHADE point of intersection
END IF

IF the object is TRANSPARENT
THEN
Construct transmission ray vector
Find closest intersection
SHADE point of intersection
END IF

COMPUTE final colour
RETURN colour
END IF



















Here's the formula used in the "COMPUTE final colour" step:

I = Idirect + (IR * kR) + (IT * kT )

Idirect is the colour calculated from local illumination.
kR is the reflection coefficient.
IR is the colour returned by the reflection ray.
kT is the transparency coefficient
IT is the colour returned by the transmission ray.



If you don't want reflection or transparency you can just ignore the last 4 parameters and the 2 IF statements in the shade algorithm and just return the DIRECT colour.

I can give you the formula for calculating Idirect and IR/IT if you want - or you can find it on my website: http://www.holly-woodland.com/Projects/Lucifer/LuciferProjectReport.pdf
(around page 46)

let me know if you have any questions
Holly

PS - sorry for the excessive spacing - it keeps reverting my changes

H3ro
04-12-2007, 08:53 AM
Hi H3ro

Here's my pseudocode for my ray tracer -

Thank you very much for that. Its nice to see the pseudocode insted of real code, as it forces me to do some of the thinking myself:)

Shaderhacker
04-17-2007, 03:38 AM
// A vriable for the direction
Vector3D rayDirection(x,y,0);



Why is your z component zero? What z-axis would you like your camera to look down? (- or +) direction? If negative Vector3D rayDirection (x,y,-1) or positive (x,y,1).

-M

H3ro
04-17-2007, 07:20 AM
Why is your z component zero? What z-axis would you like your camera to look down? (- or +) direction? If negative Vector3D rayDirection (x,y,-1) or positive (x,y,1).

-M

You are right, but at the time I did not really know that, so I guess that for some reasons I assumed Z to be zero as the picture is 2D (X and Y). I am now close to finishing the raytracer(it the most basic raytacer ever), I just have to figure out/ make a function for saving the output as a picture.

Right now I get the output as text, so its kind of booring. (Added text to see if the rays hit the sphers in my scene and so on) And the raytracer supports only spheres, not even lights at this stage, but I am planing on expanding it as I learn more. Even though it is kind of booring I am exstremly proud as this is my first project of this size.

I think I own some people at this forum a big thanks again for kind words and help so, thanks:)

HollyWoodland
04-17-2007, 01:21 PM
H3ro let us know how it goes - i'd love to see some pics when you have them :-)

I would give you some advice for the final bit but I did mine in Java (don't ask why!) and there are some nice little classes and functions for creating images - starting with an array of ints to store the pixel colours. I can just suggest lots of googling :-)


//create java awt image from "pixels" int array
Image img = createImage(new MemoryImageSource(width, height,
ColorModel.getRGBdefault(), pixels, 0, width));

// Find a jpeg writer
Iterator iter = ImageIO.getImageWritersByFormatName("jpg");
ImageWriter writer = (ImageWriter)iter.next();

// Prepare output file
ImageOutputStream ios = ImageIO.createImageOutputStream(outfile);
writer.setOutput(ios);

// Write the image
writer.write(null, new IIOImage( img , null, null));

HollyWoodland
04-17-2007, 01:22 PM
Ps - shaderhacker - any chance Disney want to set up shop in London ;-)

H3ro
04-17-2007, 01:24 PM
I am really struggeling with saving the output as a picture, never thought it should be that hard.

I have been googling alot, and found a lot of tutorials for how to load pictures and rotate them, but not how to save them

Does anyone know of a good example or a tutorial?

Thanks for the java code, I allreade have the array of ints just need to save them some how:P

thanks

HollyWoodland
04-17-2007, 01:44 PM
restrict your searches to "c++ jpeg encoder" or "c++ jpeg library" - there are several that have already been written and are available for download.

http://corona.sourceforge.net/
http://www.ijg.org/
http://www.yov408.com/html/codespot.php?gg=47
http://www.cs.sfu.ca/~bbastani/personal/courses/820/Assg2/

if you want to write your own encoder then I suggest you start by learning how JPEG compression works and what the file format looks like

try this link and also check out wikipedia

http://massmind.org/techref/datafile/jpeg/guts.htm

HollyWoodland
04-17-2007, 01:45 PM
also this one http://www.smalleranimals.com/jpegfile.htm

Shaderhacker
04-17-2007, 02:44 PM
Ps - shaderhacker - any chance Disney want to set up shop in London ;-)

Well, if they did.. then I'd have to move! :)

P.S. He doesn't need to learn compression schemes and such to output an image. He could just write a pure RGB class that stores each pixels color component and then open a file for writing, and write the buffer from the class. I think there are some file formats that may be BGR or RBG or something like that which he can store the color components as.

-M

T-bat
04-17-2007, 02:57 PM
What about uncompressed TGA? It can have alpha channel and is easy to implement:)

Robert Bateman
04-17-2007, 03:09 PM
Or better yet, use devIL to load and save a variety of image formats.

HollyWoodland
04-17-2007, 03:16 PM
oooh devIL looks interesting - might have to play around with that :-)


(http://openil.sourceforge.net/about.php)

H3ro
04-17-2007, 04:26 PM
Ok, now I have something. I used the same saveFile function that an other simple raytracer uses.

Here is the code for it:
Note: This is not my code, I have borrowed it from someone else. I will make my own saveFile function later, but I am just a bit to eager to see if my raytracer works.

bool WriteTGA(char *file, int width, int height, unsigned char *outImage)
{
FILE *pFile = 0;
unsigned char tgaHeader[12] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned char header[6];
unsigned char bits = 0;
int colorMode = 0;
unsigned char tempColors = 0;

// Open file for output.
pFile = fopen(file, "wb");

// Check if the file opened or not.
if(!pFile) { fclose(pFile); return false; }

// Set the color mode, and the bit depth.
colorMode = 3;
bits = 24;

header[0] = width % 256; header[1] = width / 256; header[2] = height % 256;
header[3] = height / 256; header[4] = bits; header[5] = 0;

char uselessChar = 0;
fwrite(tgaHeader, sizeof(tgaHeader), 1, pFile);
fwrite(header, sizeof(header), 1, pFile);

// Now switch image from RGB to BGR.
for(int index = 0; index < width * height * colorMode; index += colorMode)
{
tempColors = outImage[index];
outImage[index] = outImage[index + 2];
outImage[index + 2] = tempColors;
}

// Finally write the image.
fwrite(outImage, width * height * colorMode, 1, pFile);

// close the file.
fclose(pFile);

return true;
}


And here is my code that sends info to the above function:

// Create an array for holding the color of the screen
unsigned char *colorBuffer[300 * 400 * 3];
unsigned int r = 0, g = 0, b = 0;
......

if ( traceResult.hit == 1 )
{
Material currentMaterial = testSphere.getMaterial();

r = currentMaterial.getR();
g = currentMaterial.getG();
b = currentMaterial.getB();


*colorBuffer[arrayTracer + 0] = r;
*colorBuffer[arrayTracer + 1] = g;
*colorBuffer[arrayTracer + 2] = b;


std::cout << "The sphere hit is colored: " << colorBuffer[arrayTracer + 0]
<< "," << colorBuffer[arrayTracer + 1] << ","
<< colorBuffer[arrayTracer + 2]
<< std::endl;
}

// If the ray misses, set the color to black
else
{
*colorBuffer[arrayTracer + 0] = 255;
*colorBuffer[arrayTracer + 1] = 255;
*colorBuffer[arrayTracer + 2] = 255;
}
}
}
WriteTGA("RayTracedScene.tga", widht, hight, *colorBuffer);
}


I dont get any errors while trying to run it, but the program itselfs terminates when it start, so something is wrong. Someone have the time to take a look at the above stuff?

Thanks

Shaderhacker
04-17-2007, 06:32 PM
unsigned char *colorBuffer[300 * 400 * 3] <====== ouch! Even though that's valid, it's pretty messy to maintain.

This is just nit-picking, but try making something like:

#define X_RES 300
#define Y_RES 400

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

If you insist on 8-bits per channel:

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

std::vector<RGB> colorBuffer[X_RES * Y_RES];

In any case:
colorBuffer[i].r = currentMaterial.getR();
colorBuffer[i].g = currentMaterial.getG();
colorBuffer[i].b = currentMaterial.getB();

a LOT cleaner and meaningful..:)

Oh, and clear the buffer to black first so you don't have to have the extra else{} clause if you don't hit a sphere.

Btw, you don't have enough information for me to see what is wrong..

-M

H3ro
04-17-2007, 07:19 PM
Shaderhacker (http://forums.cgsociety.org/member.php?u=99620): Thanks for your input. I was planning to make a dynamic array for it later on, but I guess I forgot it. The use of a sturcture to store the info is greate, but as the function for saving the picture takes a *char as input I decided to make it simple and use a char myself.

I would not call it nit-picking, the thing you pointed out is accully really importand imho.


The problem is fixed now, I was making to many pointers I guess
unsigned char *colorBuffer[300 * 400 * 3];
Should be:
unsigned char colorBuffer[300 * 400 * 3]

H3ro
04-17-2007, 07:26 PM
http://img235.imageshack.us/img235/5821/raytracedscenekb8.jpg


Thats the first picture rendered with my rayTracer :D How cool is that?
The only problem is that the two spheres are placed at the same place in the picture even though they are not in the scene, but that can be fixed.

Shaderhacker
04-17-2007, 07:49 PM
Excellent! Congrats!:thumbsup:

-M

H3ro
04-17-2007, 08:36 PM
I am having truble with displaying more than one object at the time. It will only output the last object for some reason.

Cant really understand why this happens. Any ideas?

T-bat
04-17-2007, 08:42 PM
Looking great :)

HollyWoodland
04-17-2007, 08:54 PM
Yay - you have a first pic :-D

I can't see where you initialise/assign your testSphere object ( used in Material currentMaterial = testSphere.getMaterial();) so i'm guessing here.....

I assume you have some kind of function that finds the closest point of intersection on the ray? and within that function maybe you check each object in the scene for a hit and return the closest one?
if that's the case are you sure you are returning the closest object and not just the first object in the list?

alternatively you might not be checking all the objects and only checking intersections on one object?

maybe if you post your code for checking closest intersect then we could help more

H3ro
04-17-2007, 09:03 PM
Here is the code that checks for intersection:
// Check if a ray is hitting the sphere
TraceRes Sphere::checkForIntersection(Ray r)
{
// Print stuff
//std::cout << "tracing stuff" << std::endl;


// Hold the result of the check
TraceRes result;

// Get the origion of the ray
Point rayOrigion = r.getOrigin();

// Get the distance between the sphere and the ray origion
Vector3D sphereToRayDirection;
sphereToRayDirection.setX( position.getX() - rayOrigion.getX() );
sphereToRayDirection.setY( position.getY() - rayOrigion.getY() );
sphereToRayDirection.setZ( position.getZ() - rayOrigion.getZ() );

// Get the length of the ray in order to hit the sphere
float lenght = Dot(sphereToRayDirection,sphereToRayDirection);

// Find the intersection point by doing the Dot product of the
// direction btween the ray and sphere, and the direction of the ray
float intersectionPoint = Dot(sphereToRayDirection, r.getDirection());

// If the result is less then 0, the ray does not hit the sphere
// if it is larger than 0 we must do some more checking
if (intersectionPoint < 0)
{
// Miss
result.hit = 0;
result.distance = 0;

return result;
}

// Some more checking to be sure
float squaredInterPoint = ( (radius * radius) - lenght +
(intersectionPoint * intersectionPoint) );

// If it is now less than 0, it misses the sphere for sure
if (squaredInterPoint < 0)
{
// Miss
result.hit = 0;
result.distance = 0;

return result;
}

// If the ray hits the sphere:
result.hit = 1;
result.distance = intersectionPoint - sqrt(squaredInterPoint);

return result;

}

And here is the "main" raytracer code. This as awful right now as I have been moving things around trying to see if it could get it to work:

// Main render stuff
void Engine::renderScene()
{
// Load the direction list
Vector3D *directionList = generateRayDirections(widht, hight, depth);

// Initialise the ray
Point rayStart(0,0,-255);
Vector3D tempDirection;
Ray currentRay(rayStart,tempDirection);

// Create a variable for hodling the scene
Scene thisScene = *currentScene[0];

// Get the toal amount of objects in the scene
int totalObjects = thisScene.getAmountOfObjects();

// A variable for holding the information about the sphere
// we check for intersection later
Sphere testSphere;

// Create an array for holding the color of the screen
unsigned char colorBuffer[300 * 400 * 3];
unsigned int r = 0, g = 0, b = 0;

// Foor keeping track of where we are in the pixel array for storing
// colors
int arrayTracer = 0;

// Store the result from the intersection test
TraceRes traceResult;
bool hit;


// This is where the raytracing is done. Here we create a ray
// and trace it through the sceene to see if there is an
// intersection. Then we set the color at the correspoding pixel
// We make a loop for the hight and the width in order to trace
// all pixels
for (int y = 0; y < hight; y++)
{
for (int x = 0; x < widht; x++, arrayTracer+=3)
{
// Set the ray to trace through the current pixel
currentRay.setDirection(directionList[x + y * widht]);

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

// Loop through all the spheres to find the closest one.
for (int currentSphere = 0; currentSphere <= totalObjects;
currentSphere++)
{
// Reset the result for each new sphere, just to be sure
traceResult.distance = 0;
traceResult.hit = 0;

// Set the pixel to black
colorBuffer[arrayTracer + 0] = 0;
colorBuffer[arrayTracer + 1] = 0;
colorBuffer[arrayTracer + 2] = 0;

// Variable for holding the sphere we are testeing
testSphere = thisScene.getSphere(currentSphere);

// Check if the sphere intersect with the current ray
traceResult = testSphere.checkForIntersection(currentRay);

// If the ray hits, get the color of the sphere
if ( traceResult.hit == 1 )
{
hit = 1;

// Find closest sphere
if (traceResult.distance > closesSphereDistance )
{
closesSphereDistance = traceResult.distance;
closestSphere = currentSphere;
}
}
else
{
hit = 0;
}
}

// We now know which sphere is closest
// Find the color of it
if ( hit == 1 )
{
// Find the material of the sphere
testSphere = thisScene.getSphere(closestSphere);
Material currentMaterial = testSphere.getMaterial();

// Assign the color to the pixel
colorBuffer[arrayTracer + 0] = currentMaterial.getR();
colorBuffer[arrayTracer + 1] = currentMaterial.getG();
colorBuffer[arrayTracer + 2] = currentMaterial.getB();
}

}
}
// Save the picture
WriteTGA("RayTracedScene.tga", widht, hight, colorBuffer);

std::cout << "\n---------------------------" << std::endl;
std::cout << " Sceene is rendered, all done" << std::endl;
}

That was a lot of code =\

Shaderhacker
04-17-2007, 11:01 PM
Make sure that your Sphere classes defined from your Scene class have different center points. I'm assuming that they aren't located in the same spot in the scene.

Also, to troubleshoot, you should run it through some debugger. Or worse case, place cout() statements in the intersection code.

-M

Shaderhacker
04-17-2007, 11:42 PM
Looking a little more at your intersect code.. It's basically not correct.

You can't assume that the dot product between the ray direction and the vector between the center of the sphere and the origin of the ray will always yield an intersection. It depends on the size of your radius.

Plus you don't check if the sphere is behind you.

1) Check for ray being behind you.
Vector3D rayDir (r.getDirection());
float sphereToRaySquared = Dot(sphereToRayDirection,sphereToRayDirection);
float rayDotsphere = Dot(rayDir * sphereToRayDirection);
float rayDotsphereSquared = rayDotsphere * rayDotsphere;
if ( rayDotsphere < 0 ) and ( rayDotsphereSquared > (Sphere.radius * Sphere.radius) )
then
// you are behind the ray direction

2) You need to test the projected length of the dot product between the sphereToRaySquared and the rayDirSquared. Subtract them and that's your projected length squared. Use projected length squared to test against the Sphere.radiusSquared to see if you actually miss the sphere (ie. if ( projLengthSquared() > Sphere.radiusSquared() ).

3) To get your intersection points. Subtract the value you get from computing projLengthSquared() from the Sphere.radiusSquared and then take the square root of that. This will be your offset value (o). Then just test again to make sure your sphereToRaySquared > Sphere.radiusSquared(). If so, that's your first t value (t1 = o - rayDotsphere). t2 = o + rayDotSphere to get your second intersection value (or if you are inside the sphere).

-M

H3ro
04-18-2007, 06:30 AM
Thanks for your input Shadershack. To be honest I never thought of checking if the sphere was behind the ray or not. Going to fix this later today at school or something, atleast then I have something to do during Norwegian classes:P

As you mentioned, the two spheres have different center points, I have checked that a thousand times by now

The weird thing is that it will only draw one sphere. If I delete sphere[0], sphere[1] is made correctly. And if sphere[1] is removed, sphere[0] is made. It is allways the last sphere that gets draw. I am having great truble understanding why, as the program work pixel by pixel, not object by object.

Guess I have to do some 'cout' debugging to figure out what is wrong, as I dont know how to use the debugger. So many things to learn...

I have fixed the problem with the sphere being color like you see in the picture I posted before. The sphere is now one colored :)

T-bat
04-18-2007, 07:18 AM
Just quessing :)

1. if (traceResult.distance > closesSphereDistance)
shouldn't it be the other way around?
if (traceResult.distance < closestSphereDistance)

2. I think you are overwriting hit variable. Try setting it to 0 before you check for closest intersection and comment out that else part.

H3ro
04-18-2007, 11:55 AM
I am working on fixing my problem when I have more then one object, but to be honest I am kind of lost.

From what the output is, it looks the ray hits the wrong sphere and for some reasons place it at a random location.

Here is my sceene:


void Scene::createScene()
{
//Create a container for all the spheres
sphereList = new Sphere*[100];

// Create the scene
// ------------------------------------------

// Sphere1 - a blue one
// A few variables for the first sphere
Vector3D pos1(50,0,0);
Material blue(0,0,200);
// Create the first sphere
sphereList[0] = new Sphere;
sphereList[0]->setPosition(pos1);
sphereList[0]->setRadius(50);
sphereList[0]->setMaterial(blue);


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

// 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);
*/

// ------------------------------------------
// Done with the scene

// Set how many spheres there are, to make stuff
// easier
noOfObjects = 2;

// Print some info
std::cout << "Scene sucsesfully created" << std::endl;
std::cout << "Two spheres created! " << std::endl;
}


One thing I find weird is that if I change noOfObjects, the blue sphere moves(the blue is the only one that is draw to the picture for some reason)

If noOfObjects = 0 (its is used to acces members in an array) I get this:
http://img144.imageshack.us/img144/2005/onesphereyg0.jpg

If noOfObjects = 1 I get this:
http://img294.imageshack.us/img294/7135/twospherescy0.jpg

And if noOfObjects = 2 I get the first picture again.

Maybe I have some pointers that point to the wrong thing? Can that be the case?

EDIT:
I found out that closes sphere allways equals the last sphere in my array

// Find closest sphere
if (traceResult.distance < closesSphereDistance )
{
closesSphereDistance = traceResult.distance;
closestSphere = currentSphere;
}

So I guess I am getting closer to finding my problem. I can see how this causes the object to have the same color no matter where it is placed (see above picture) but not why I only get one sphere.

HollyWoodland
04-18-2007, 07:26 PM
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

billrobertson42
04-18-2007, 08:50 PM
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.

HollyWoodland
04-19-2007, 08:19 AM
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;

H3ro
04-19-2007, 09:37 AM
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 :)

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.
http://img241.imageshack.us/img241/5278/raytracedscenecb4.jpg
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:)

H3ro
04-19-2007, 01:11 PM
I solved it, it was way to easy accually. But now it works:)

http://img175.imageshack.us/img175/3523/raytracedsceneyb8.jpg

Kind of sexy :)

HollyWoodland
04-20-2007, 09:40 AM
excellent :-D

what was the problem?

H3ro
04-20-2007, 11:16 AM
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`?

HollyWoodland
04-20-2007, 03:44 PM
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

H3ro
04-20-2007, 03:58 PM
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.

H3ro
04-20-2007, 07:21 PM
Ok, I have given up the code posted above and decided to try the algorithm from an other tutorial (http://www.devmaster.net/articles/raytracing_series/part7.php)insted.

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 :) ) 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 :)


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
}
}

billrobertson42
04-21-2007, 05:51 AM
Please keep posting. :D

Shaderhacker
04-21-2007, 07:32 AM
Ok, I have given up the code posted above and decided to try the algorithm from an other tutorial (http://www.devmaster.net/articles/raytracing_series/part7.php)insted.

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 :) ) 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 :)


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
}
}




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;

}

H3ro
04-22-2007, 10:04 AM
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

H3ro
04-22-2007, 05:18 PM
http://img73.imageshack.us/img73/7874/raytracedscenefz7.jpg

Woho, next step reached :)

Shaderhacker
04-23-2007, 03:35 AM
http://img73.imageshack.us/img73/7874/raytracedscenefz7.jpg

Woho, next step reached :)

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

HollyWoodland
04-23-2007, 09:10 AM
woohoo! go H3ro!! isn't it satisfying to see the results of something you've made from scratch :-) 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

H3ro
04-23-2007, 11:17 AM
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 :-) 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
[/url]
books-wise i've got the classic Foley book: Introduction to Computer Graphics
[url="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"]http://www.amazon.com/Introduction-...77319231&sr=8-3 (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 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 :)

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

UrbanFuturistic
04-23-2007, 12:54 PM
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.

H3ro
04-23-2007, 03:04 PM
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;
}
}
}

HollyWoodland
04-24-2007, 03:30 PM
typedef struct {
unsigned int r;
unsigned int g;
unsigned int b;
unsigned int a;
}RGB;


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

Robert Bateman
04-24-2007, 04:01 PM
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;

HollyWoodland
04-24-2007, 04:53 PM
cool - thanks Rob - that's what i thought

H3ro
04-26-2007, 06:28 PM
Ok, now I'm back again, with some more questions:P

I have rewritten most of the raytracer, so it can more easily take different types of objects, and removed alot of nasty stuff and crap.

I am now at the point where the other raytracer was, so nothing new. But this time something weird has happened, I have transparency, but no clue why :P

Here is the code:

Color addDiffuse(int closestPrim, Ray &r, Vector3D &intersectionPoint, Scene &thisScene)
{
Color primCol;
primCol.r = 0;
primCol.g = 0;
primCol.b = 0;

for (int currentLight = 0; currentLight <= thisScene.getNrLights(); currentLight++)
{
// Find the closest Primitive and the material of it
Primitive *closestPrimitive = thisScene.getPrimitive(closestPrim);
Material *primColor = closestPrimitive->getMaterial();

// Find the light we are currently using and the color of it
Light *testLight = thisScene.getLight(currentLight);
Color lightColor = testLight->getColor();

// Find the normal
Vector3D normal = intersectionPoint - closestPrimitive->getPos();
normal.normalize();

// Find the light direction
Vector3D lightDir = testLight->getPos() - intersectionPoint;
lightDir.normalize();

float dot = Dot(normal, lightDir);
if (dot < 0)
dot = 0;

// Find the color
primCol.r += (int)(dot * primColor->getDiffuse() * primColor->getR() * lightColor.r);
primCol.g += (int)(dot * primColor->getDiffuse() * primColor->getG() * lightColor.g);
primCol.b += (int)(dot * primColor->getDiffuse() * primColor->getB() * lightColor.b);

// Clamp he color
if (primCol.r >= 255)
primCol.r = 255;
if (primCol.g >= 255)
primCol.g = 255;
if (primCol.b >= 255)
primCol.b = 255;
}
return primCol;
}


Any ideas anyone?

EDIT: Firefox with spell checker now installed:)

:)

CapBBeard
04-27-2007, 06:47 AM
I only have time for a quick look but it appears that your diffuse code is fine (I think; again, I only glossed over it). One thing to check is that you're only computing the surface of the closest ray (and not adding up the result from all objects the ray could intersect).

Double check all sections of code where you're adding colours together, chances are that's where the problem is originating from :)

H3ro
04-27-2007, 07:21 AM
Thanks for your reply. That was the first thing I suspected as well, but the problem is that there is not adding up of colors. Or there is one, where I add the effects of all the lights, but as there is only one light in my scene this should not cause the effect.

// Find the color
primCol.r += (int)(dot * primColor->getDiffuse() * primColor->getR() * lightColor.r);
primCol.g += (int)(dot * primColor->getDiffuse() * primColor->getG() * lightColor.g);
primCol.b += (int)(dot * primColor->getDiffuse() * primColor->getB() * lightColor.b);

I have also tried to change the above code from "+=" to "=" but the result is the same. After what I know about raytracing(limited knowledge) it should be impossible to have transparency without shooting some secondary rays to find whats behind the original object?

The part belove here is the "core" part of the raytracer, if that in someway can help.


// This is where the raytracing is done. Here we create a ray
// and trace it through the scene to see if there is an
// intersection. Then we set the color at the corresponding pixel
// We make a loop for the hight and the width in order to trace
// all pixels
for (int y = 0; y < hight; y++)
{
for (int x = 0; x < widht; x++, arrayTracer+=3)
{
//std::cout << x << "," << y << ": We are here" << std::endl;
// Set the ray to trace through the current pixel
currentRay.setDirection(directionList[x + y * widht]);

// Variables for checking which objects that are closest to the
// camera
float closestDistance = 1000000;
int closestPrimitive = -1;


// Loop through all the primitives in the scene and return the
// the closest one
for (int currentPrimitive = 0; currentPrimitive <=totalPrimitves;
currentPrimitive++)
{
// Find the primitive we are currently testing against
Primitive* testObject = thisScene.getPrimitive(currentPrimitive);

// Check if the ray hits the current object
intersectionRes = testObject->intersectionTest(currentRay);

// If the ray hits something, check if its the closest object
if (intersectionRes.hit == 1)
{
// Find closest primitive by comparing distance
if (intersectionRes.distance < closestDistance )
{
closestDistance = intersectionRes.distance;
closestPrimitive = currentPrimitive;
}
}
}

// We now know if the ray has hit something and what the closest object is
if (closestPrimitive != -1)
{
// Store the color
Color currentColor;

// Find the intersectionPoint between the ray and the closest
// primitive
Vector3D interPoint = currentRay.getDirection();
interPoint.scale(intersectionRes.distance);
interPoint = interPoint + PointToVector3D(currentRay.getOrigin());

// Add diffuse lighting
currentColor = addDiffuse(closestPrimitive, interPoint, thisScene);

// Add the color to the colorBuffer
colBuffer[arrayTracer + 0] = currentColor.r;
colBuffer[arrayTracer + 1] = currentColor.g;
colBuffer[arrayTracer + 2] = currentColor.b;

}
}

H3ro
04-28-2007, 08:37 AM
Now i have tried to use the ray/sphere intersection code from my "old" raytracer, and the old diffuse code. But I still got this weird transparancy bug, so I don't think the problem is in any of those parts. Frankly, I am very very lost now. I have checked the whole thing a thousand times without any luck. When trying to render spheres of different sizes where all of them are positioned at 0,0,0 it looks like there is something wrong with the intersection code or that the program are having trouble with deciding which of the spheres that are closest. But when I try to debug it all works fine.

I think I am going to leave this project for a while now, before I get really angry and smash my computer or something.

Anyway, here is the whole project (Dev-c++) if anyone enjoys things like this.

Thanks for all the help, I'm going to get back to this sometime and try to fix it, maybe when my programming skills have gotten a bit better or something. Back to basic:)

Shaderhacker
04-29-2007, 03:03 AM
Now i have tried to use the ray/sphere intersection code from my "old" raytracer, and the old diffuse code. But I still got this weird transparancy bug, so I don't think the problem is in any of those parts. Frankly, I am very very lost now. I have checked the whole thing a thousand times without any luck. When trying to render spheres of different sizes where all of them are positioned at 0,0,0 it looks like there is something wrong with the intersection code or that the program are having trouble with deciding which of the spheres that are closest. But when I try to debug it all works fine.

I think I am going to leave this project for a while now, before I get really angry and smash my computer or something.

Anyway, here is the whole project (Dev-c++) if anyone enjoys things like this.

Thanks for all the help, I'm going to get back to this sometime and try to fix it, maybe when my programming skills have gotten a bit better or something. Back to basic:)

Did you ever fix your dot product bug in your intersection code? You can't just take the dot product of the ray direction vector and the vector from the eye to the center of the sphere and if they are > 0 then that's an intersection. You must compute the length of the vector between the center point of the sphere and a point on the ray direction vector that is parallel to the radius. To do this, you must solve the pythagorean theorem from the two vectors that you use to compute the dot product. Once you get the length of that vector, you can then compare it to the radius. If it's greater than the radius, then it misses the sphere EVEN if the dot product is > 0. This is probably your problem.

-M

H3ro
04-29-2007, 01:54 PM
I think so, I have tryed to do it the same way as they do it in the devmaster wiki about ray/sphere intersection

Link (http://www.devmaster.net/wiki/Ray-sphere_intersection)


// 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;
}
}
}

CGTalk Moderation
04-29-2007, 01:54 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.