In case anyone is confused, he is using pure C++ with fstream library (file stream - useful for creating and working with files of all types) to create a .ppm (portable pixel map / a very inefficient and uncompressed image filetype) file containing information of a sort of "snapshot" created using ray tracing techniques. The console is not a renderer, so when you compile this code do not expect to print the image. The code compiles and generates the .ppm file from source, which you can view with something like gimp or photoshop or fileviewer or most text editors.
@@yugiohonline26 Imagine this file type as a huge 2d array of color values. This code is programmatically generating the ppm file with a raytracing algorithim. If you want to view the file, open it with some software that can view ppm files.
Games usually use baked lighting where the vertexes of a mesh control how light is distributed across an object. As oppose to ray tracing which is a real time lighting option, but not the only solution.
How would you go about making a bounding box? i cant figure it out for the life of me and all the other "tutorials" ive seen use much more complex and messier code making it hard for someone whos new to the whole raytracing thing to follow along and actually understand whats going on.
If you're having an issue where this line: frameBuffer[y][x] = (blue + white * ft); causes the file format to not work but this: frameBuffer[y][x] =white; worked then the issue is that the file format may not be openable (with you're image viewer) if it has floats in it, so to fix it where you're writing the colours to the out file EG:( out
Nice video! For some reason, with the same parameters for the light and sphere, i'm getting different lighting. It's just a grey to white gradient. Any idea what this might be?
Make sure the output file extension ends with ".ppm" and that it writes "P3" at the beginning of the file. You may have "P2" and or ".pgm" which is grayscale.
Thank you for the fast reply. I was unclear with my question. The colors are allright. I meant i'm getting a different lighting pattern for the same light position and sphere. I'm using different code for the vector operations, but i doubt that is the problem, they produce the same outcome.
One thing I didn't understand which is why you made the direction vector of every ray constant (0,0,1), I think it must be calculated as the direction from the camera towards the pixel. I'm I right or wrong?
I ran the code in visual studio code and a ppm file "out.ppm" got generated. But it has nothing in it. It shows 0 bytes. Could you please tell what might be the error?
Discriminant formula is wrong, should be : disc = b*b-4*a*c not disc = b*b-4*c and therefore "a" should be : a = dot(d,d); But using dot product is a great idea, was thinking about how I could possibly write those long formulas for "a","b" and "c". And shouldn't t0 be (-b - sqrt(disc))/(2*a) and t1 be (-b + sqrt(disc))/(2*a) instead of just (-b +- sqrt(disc)) ?
a = dot(d,d) = 1. it's not gonna make a difference because d the direction vector is normalized and it's length is just 1. but the other formula should be divided by 2 because 2*a = 2;
Oh he just remembered a little bit of stuff from others videos and made a "tutorial" out of it, the dude does not actually understand what he is typing
Around the 14 minute mark when you first get the sphere rendered, for some reason my intersection is always returning true, resulting in a completely white image, any ideas?
line 9 : Vec3(double a, double b, double c) { x = a, y, b, z = c; } You forgot to set 'y' :) should be y = b. Also if you're using visual studio you should have gotten a warning telling you about it.
This is so frustrating! I get up to the 23 minute mark and it happens again! It looks like my code matches yours but I have different output! pastebin.com/XqAZuM24 Please help!
There's something I don't understand. You wrote : t = b-disc. Isn't this supposed to t = (b-disc)/2 ? Well it is, i'm sure about that, but is that an error you made ? Or is it on purpose ? Because it seems to work.
Recently for a project I checked 2-3 "crap" ray-tracers. This is the simplest / best one I am going to use. I ported everything to C++11. Put lots of consts and also optimized a bit. Get rid of C style pass by pointer and changed it to pass by reference. Get rid of the std::vector as well. I can see some other optimizations with: double const dt = dot(L.normalize(), N.normalize()); But I guess the optimizer will take care of it. I got the source from one of the other comments from Izmael. gist.github.com/nmmmnu/65f370578d9f7c8002b88bbd1ac693ea
This is probably the simplest, but it's also a hack. The "camera" is flat and has no perspective (that's why it's simple). So if you really want to use it for a bigger project you should look up camera rays.
I noticed this already :) I want to render this: www.flickr.com/photos/nmmmnu/32615496144/ In order to avoid creating millions of objects (this current image have 200K or so objects), it needs to change the code of the ray-tracer.
I think this is more of an orthographic raytracer, so you can use your own "camera" if you'd like. Though there really are better videos than this. Use it more as a guide than anything.
Hey Marcus, i followed through the video but when i run it, it generates an O file which cant be opened on Win 10. I did it on Code::Blocks. Please help.
@@MarcusMathiassen Thanks for the quick reply. Actually it worked like a champ. At 1st I didn't even realize I was looking for the ppm file, & I had even looked right at it a few times but gimp hadn't automatically associated itself with the format until I used it once, hence no icon. Thanks, useful stuff especially perhaps along with ffmpeg.
realcygnus Yeah, i used ffmpeg to stitch together 1000s of ppm files back then since i didnt know how to use OpenGL. Incredibly inefficient creating gigabytes of data for just a few frames of me zooming in on a mandelbrot.
@@MarcusMathiassen Yea incredibly inefficient ! If you only need non interactive clips of a scene that your system can't render in real time, then I suppose it could fall under "useful" . Or at least my Integrated Intel graphics almost had me convinced. lol
Titan Army what do you mean by "put in a view frustum"? I understand using a projection to map a perspective frustum into the canonical viewing volume, but I don’t see how this is equivalent to an orthographic tracer, so I feel like I’m missing something. What would be different to do a perspective tracer
Might be a bit hard to follow, so here's the full code.
github.com/MarcusMathiassen/BasicRaytracer30min
You could just have put that in description. Try adding time markers to the video like 9:30 Something
In case anyone is confused, he is using pure C++ with fstream library (file stream - useful for creating and working with files of all types) to create a .ppm (portable pixel map / a very inefficient and uncompressed image filetype) file containing information of a sort of "snapshot" created using ray tracing techniques. The console is not a renderer, so when you compile this code do not expect to print the image. The code compiles and generates the .ppm file from source, which you can view with something like gimp or photoshop or fileviewer or most text editors.
PPM is a very simple and easy ASCII format. I love it!
How would you print out the file in Windows?
@@yugiohonline26 What do you mean by print out?
@@yugiohonline26 Imagine this file type as a huge 2d array of color values. This code is programmatically generating the ppm file with a raytracing algorithim.
If you want to view the file, open it with some software that can view ppm files.
@@nintendoblood4835 Ok when I run g++ test.out or a.out it doesn't create a ppm file at all. Could it be because I'm on Windows?
This is very impressive. If you could make a video explaining line by line, that would be awseom
Thanks for sharing the code and such an illustrative video 😊
Hope you'll keep sharing such amazing stuff 👍
The silence is killing me! But awesome video!!
Maybe he is mute, no tongue? He could have shared the code and explain it rather than going "silent life"
WOW!
Never tought that from pure and clean code would be possible to render something.
This is really awesome!
not really, cameras do it with physical light, easier than this
Games usually use baked lighting where the vertexes of a mesh control how light is distributed across an object. As oppose to ray tracing which is a real time lighting option, but not the only solution.
@@maxbd2618 I think L means that no graphics libraries are used
This looks so good! Thanks for the tutorial...
Marcus these are amazing videos, thanks for helping
No problem :)
Thank you... great
Thank you very much man
Eres ua bestia amigo :3 Wou justo yo buscando cosas sobre Ryatracong y tu pones este video. Perdon si no hablo ingles xd
no hay problema
@@MarcusMathiassen :3
Real time ray tracing is what we want,ray tracing is simple.
How would you go about making a bounding box? i cant figure it out for the life of me and all the other "tutorials" ive seen use much more complex and messier code making it hard for someone whos new to the whole raytracing thing to follow along and actually understand whats going on.
Thank you
Here my calcul of intersection who is a bit more precise
if (discriminant < 0) // no intersection
return (0);
else if (discriminant == 0) // 1 intersection
t = - 0.5 * b;
else // 2 intersection
{
discriminant = sqrt(discriminant);
t0 = (-b - discriminant)/2;
t1 = (-b + discriminant)/2;
ray->t = (t0 < t1) ? t0 : t1;
return (1);
}
return (0);
If you're having an issue where this line: frameBuffer[y][x] = (blue + white * ft); causes the file format to not work but this: frameBuffer[y][x] =white; worked then the issue is that the file format may not be openable (with you're image viewer) if it has floats in it, so to fix it where you're writing the colours to the out file EG:( out
How located coordinate axises? X-axis to viewer, Y-axis - right, Z-axis - up?
27:27 so creepy that eye
if you dont comment whats the difference from simply read the completed code?
Nice video!
For some reason, with the same parameters for the light and sphere, i'm getting different lighting. It's just a grey to white gradient. Any idea what this might be?
Make sure the output file extension ends with ".ppm" and that it writes "P3" at the beginning of the file. You may have "P2" and or ".pgm" which is grayscale.
Thank you for the fast reply. I was unclear with my question. The colors are allright. I meant i'm getting a different lighting pattern for the same light position and sphere. I'm using different code for the vector operations, but i doubt that is the problem, they produce the same outcome.
Could you link me a screenshot of what you're seeing?
imgur.com/a/2OFPB
Is that the right screenshot? It doesnt have any gray to white gradient and no pattern. It´s solid red.
"Lemme just feed this object into this shit ton of linear algebra"
Pretty much describes most low level graphics programming.
One thing I didn't understand which is why you made the direction vector of every ray constant (0,0,1), I think it must be calculated as the direction from the camera towards the pixel. I'm I right or wrong?
You’re right. I think I made some type of faux orthographic raytracer but honestly I don’t remember.
@@MarcusMathiassen okay, thanks!
RTX ON
I ran the code in visual studio code and a ppm file "out.ppm" got generated. But it has nothing in it. It shows 0 bytes. Could you please tell what might be the error?
Discriminant formula is wrong, should be : disc = b*b-4*a*c not disc = b*b-4*c and therefore "a" should be : a = dot(d,d); But using dot product is a great idea, was thinking about how I could possibly write those long formulas for "a","b" and "c". And shouldn't t0 be (-b - sqrt(disc))/(2*a) and t1 be (-b + sqrt(disc))/(2*a) instead of just (-b +- sqrt(disc)) ?
a = dot(d,d) = 1. it's not gonna make a difference because d the direction vector is normalized and it's length is just 1. but the other formula should be divided by 2 because 2*a = 2;
Very cool! How difficult would it be to implement a GUI for this?
Using xcode´s interfacebuilder it shouldnt be too hard.
not "childs play" on wiondows
+Marcus Mathiassen did you use external libraries to get this to work because I saw that you called a ray and vec object
+Adam7868 my bad I rewatered it
Yeah, no it's all there. No external libraries.
When calculating the discriminant, isn't the formula (-b +- sqrt(b^2 - 4ac))/2? If so, why do you not divide by two in Sphere::intersect?
Oh he just remembered a little bit of stuff from others videos and made a "tutorial" out of it, the dude does not actually understand what he is typing
Around the 14 minute mark when you first get the sphere rendered, for some reason my intersection is always returning true, resulting in a completely white image, any ideas?
hard to say without seeing the code. Could you link it?
I've checked it over and I'm 90% it's the exact same as you have at that point, but I've copied it here: pastebin.com/2nNdbVgE thanks :)
line 9 : Vec3(double a, double b, double c) { x = a, y, b, z = c; }
You forgot to set 'y' :) should be y = b.
Also if you're using visual studio you should have gotten a warning telling you about it.
You are an absolute legend! Somehow I didn't get that warning :/ Thanks though! I can continue with the tutorial now :D
This is so frustrating! I get up to the 23 minute mark and it happens again! It looks like my code matches yours but I have different output! pastebin.com/XqAZuM24
Please help!
Hmm why my .ppm file does not exist anywhere, please help
There's something I don't understand.
You wrote : t = b-disc.
Isn't this supposed to t = (b-disc)/2 ? Well it is, i'm sure about that, but is that an error you made ? Or is it on purpose ? Because it seems to work.
You're right! That was an error. You're supposed to divide by two.
So does that mean that the sphere appears to be farther than it should ?
It's an error but the result is the same because t0 < t1 is equivalent to t0/2 < t1/2.
Recently for a project I checked 2-3 "crap" ray-tracers. This is the simplest / best one I am going to use.
I ported everything to C++11.
Put lots of consts and also optimized a bit.
Get rid of C style pass by pointer and changed it to pass by reference.
Get rid of the std::vector as well.
I can see some other optimizations with:
double const dt = dot(L.normalize(), N.normalize());
But I guess the optimizer will take care of it.
I got the source from one of the other comments from Izmael.
gist.github.com/nmmmnu/65f370578d9f7c8002b88bbd1ac693ea
Please can you send me that code?
sorry link was not pasted, I edited the reply
gist.github.com/nmmmnu/65f370578d9f7c8002b88bbd1ac693ea
This is probably the simplest, but it's also a hack. The "camera" is flat and has no perspective (that's why it's simple). So if you really want to use it for a bigger project you should look up camera rays.
I noticed this already :)
I want to render this: www.flickr.com/photos/nmmmnu/32615496144/
In order to avoid creating millions of objects (this current image have 200K or so objects), it needs to change the code of the ray-tracer.
@@nmmm2000 are you stil active in this project?
Shouldn't the ray origin be 0,0,0 and ray direction x,y,1 ?
I think this is more of an orthographic raytracer, so you can use your own "camera" if you'd like. Though there really are better videos than this. Use it more as a guide than anything.
I'm following this video, and for some reason the lighting on the top of the sphere is reversed... any ideas?
Check the getNormal function. It should be "(pi-c)/r" and not "(c-pi)/r".
Now its the other way around!
gyazo.com/1e9da70aaa9b28a255946783cb402ad9
Looks like the RGB values are going over 255. Just cap them between 0-255.
Now I'm getting this gyazo.com/cfc184cbeab8a07f5c38824a206daea8
If it has anything to do with t, turns out t is always t1. Here's my code for that
pastebin.com/65BXHpec
basic raytracer in 30min and 4 years of learning programming.
This was right after id taken 101 C++. So about 8 months.
@@MarcusMathiassen ok 8 months and 30 minutes.
Hey Marcus, i followed through the video but when i run it, it generates an O file which cant be opened on Win 10.
I did it on Code::Blocks. Please help.
Nabel Wangwe .o file? As in Object file? Pass it to «cl» to generate an .exe
Which color scheme is this?
"Behave" i think
NORM ERROR
ur joking! 42 right
what?
norminette?
yes; norminette) -42
anyone know hot to do this on windows 10 ? I got cygwin & gcc installed but you when run the exe nothing happens
realcygnus it should work on windows. How do you compile it?
@@MarcusMathiassen Thanks for the quick reply. Actually it worked like a champ. At 1st I didn't even realize I was looking for the ppm file, & I had even looked right at it a few times but gimp hadn't automatically associated itself with the format until I used it once, hence no icon. Thanks, useful stuff especially perhaps along with ffmpeg.
realcygnus Yeah, i used ffmpeg to stitch together 1000s of ppm files back then since i didnt know how to use OpenGL. Incredibly inefficient creating gigabytes of data for just a few frames of me zooming in on a mandelbrot.
@@MarcusMathiassen Yea incredibly inefficient ! If you only need non interactive clips of a scene that your system can't render in real time, then I suppose it could fall under "useful" . Or at least my Integrated Intel graphics almost had me convinced. lol
this video has no sound??
Yeah, i'll try voiceover on future ones.
So its an orthographic tracer. Why not just put a view frustrum in and call it a day?
Because i didn't know how at the time.
to understand the fundamentals. :)
I'm already tracer
Titan Army what do you mean by "put in a view frustum"? I understand using a projection to map a perspective frustum into the canonical viewing volume, but I don’t see how this is equivalent to an orthographic tracer, so I feel like I’m missing something. What would be different to do a perspective tracer
"iamverysmart"
Coding drunk?
I made this:
a) Output to a SFML Window (In Real Time!)
b) Make this render Video
c) Support many Spheres
Still quite shit, but its better i guess.
github?
apple sucks !!!
who the fuck uses mac ?????????????????????????