Dark Bit Factory & Gravity
PROGRAMMING => Freebasic => Topic started by: Voltage on March 22, 2007
-
Howdy all,
I've been doing some research and a little coding, and I have come up with a realtime raytracer in FB.
Does anyone here have any previous experience with ray tracing? I have a coupla questions, specifically to do with optimizations.
I don't have the code with me right now, but I'll post some code and an .exe a bit later.
EDIT: Added source and .exe
-
I've done 5 different versions, my latest (complete version) being done in FB with a hell of alot of inline ASM.
If you have any questions try to get on msn or something; some of the techniques that are really important in RTRT are really hard to explain in posts. But if I have to I'll try to explain them here :)
Feel free to ask.
-
Looks like you need to familiarize yourself with adaptive subsampling :D
Contrary to what most people believe, normal raytracer optimizations *WILL NOT* work well enough for RTRT's in demos. Trust me ;)
But, adaptive subsampling is the father of all raytracer optimizations. And since virtually nobody has done any good explanations on how it's done, I will :)
First, you must divide the screen into squares. I use 8x8 to start. What you do is loop through the screen in these squares. For each square, trace only the corners of each square. If the rays hit the same object and were all either inside/outside a shadow, just bilinearly interpolate colors/shading/texture coords/etc. accross the square. Else, divide the square into 4 more squares; each half the original's size. Then call your square routine for each new square. This continues until the the original criteria has been met or the square is 1x1 pixel in size.
Any questions? ;)
-
Looks like you need to familiarize yourself with adaptive subsampling
I get it, and I like it. That was a very clear explaination, thanks matey matey.
Plus after I implement it, I can say that I've done "adaptive subsampling", and that rocks!
Do you have your engines available for downloading somewhere or do you care to share?
-
Do you have msn?
Right now I don't have access to them.
Basically, there's things to remember when coding a RTRT:
1. You are insane for trying to do triangles in realtime :P . The only primitives mine support (except my first tracer thta wasn't RT) are spheres, planes, and cylinders.
2. You can't be entirely against giving up looks for speed.
3. Think differently - one method may look like nice code but could be very slow.
4. Because of number 1, when you get pretty far in your tracer, we'll talk about CSG.
5. You're off to a great start :)
-
msn + Voltage = FALSE
I can't get a damned account/passport with them for some strange reason, I have tried on more than one occasion. Way back in the day, I had voltage@hotmail.com but due to lack of use, it expired.
I have been using Yahoo Messenger, without a hiccup for 5 years-ish, so if you Yahoo, my user name is voltage_123, or mail at voltage_123 @ yahoo dot com
1) Yes I am insane. But I didn't realise that tri's were so computationally expensive! Thanks for the heads up.
2) I am willing to give up looks for speed.
3) While I am learning, I will stick to clean readable code, but I am more than willing to inline ASM the shit out of it, when the time comes.
4) Sounds great, I understand the concepts but I have never implemented them, bring on the CSG
5) Thanks mate. :)
I'll go and have toy with adaptive subsampling
-
@Thygrion + Voltage: With the newer versions of MSN Messenger, you can add Yahoo Contacts.
Welldone Voltage on your Ray Tracing! :)
-
It can depend a lot on what you want to raytrace. One thing you might consider is called 'first hit optimisation'. You render your scene into a 1bit buffer using standard triangle rasterisation instead of raytracing, and where the 1bits are you trace a ray for that pixel, for the 0 bits you draw the background.
Other people here have done more work on it. Specular reflection can be accelerated with some success. The more diffuse effects you want, the harder it gets (multiple rays need to be spawned at each intersection).
Jim
-
@Clyde: Thanks mate, and thanks for the MSN tip.
@Jim: I had considered something similar to 1st hit optimisation, like a mask, it would work esp well if there was a lot of background being drawn. With spheres you could actually use a scaled sprite to cover the sphere as the mask, that would be very fast. That combined with subsampling could produce some funky optimisations. I'm like a kid in a candy shop at the moment. :) I've wanted to do realtime raytracing for about 10 years.
-
I noticed you were using PSet, which is quite slow. I don't know if you'll eventually use something like tinyptc but you can replace the Psets with direct access to the screenbuffer which will speed things up a bit.
Sub PutPixel(x As Integer, y As Integer, clr As Uinteger)
Dim As Integer Ptr scrbuff
scrbuff = Screenptr
Screenlock
Poke Integer, scrbuff + (x + y * 320), clr
Screenunlock
End Sub
And of course there are some asm examples posted on the board as well.
-
I messed around with your code a bit and put the screen updates inline. This draws a page and then displays it. My changes are marked RDC. This is a bit faster on my machine. Anyway, just some ideas.
'Ray Tracer v0.1
'by Voltage 21/3/2007
'****************** NEED to update the surface normals after moving the triangles !! ******** Then lighting should work
'*** TO DO ***
'Current Goals
'DONE! - Cast a ray through each screen coord
'DONE! - Check for intersection with triangle
'DONE! - Find closest triangle that intersected
'DONE! - Draw appropriate diffuse colour
'DONE! - Basic Shadows
'Specular lighting
'Texture maps
'Reflection
'Spheres
'Optimizations - Bounding boxes/other?
'Option Explicit
Type VectorType
x As Double
y As Double
z As Double
End Type
Type RayType
origin As VectorType
Dir As VectorType
ShadowRay As Integer
CurrentObject As Integer
End Type
Type IntersectionType
Dist As Double
Object As Integer
u As Double
v As Double
End Type
Type TriangleType
v1 As VectorType
v2 As VectorType
v3 As VectorType
Plane As RayType
R As Ubyte
G As Ubyte
B As Ubyte
End Type
Declare Function Vec_Length(v As VectorType) As Double
Declare Function Vec_Normalize(v As VectorType) As VectorType
Declare Function FindClosestIntersection(Ray As RayType) As InterSectionType
Declare Function TriangleIntersect(R As RayType, T As TriangleType) As IntersectionType
Declare Function Vec_CrossProduct(v1 As VectorType, v2 As VectorType) As VectorType
Declare Function Vec_DotProduct(v1 As VectorType, v2 As VectorType) As Double
Declare Function Vec_Subtract(v1 As VectorType, v2 As VectorType) As VectorType
Declare Sub SetupScene
Declare Function CalculateColour(Object As Integer, R As RayType, L As Double) As Integer
Const SCR_W=640
Const SCR_H=400
Const ViewDistance = 300
Const NUMTRIANGLES = 5
Const EPSILON=0.000001
Const TRUE = -1
Const FALSE = 0
Const SP=4
Screen 14,32
Dim MyRay As RayType
Dim MyIntersection As IntersectionType
Dim Shared Triangles(1 To NUMTRIANGLES) As TriangleType
Dim As Integer x,y,a,colour
Dim Shared As VectorType LightSource
'RDC'
dim sbuff as integer ptr
dim baseclr as uinteger = rgb(20, 20, 20)
'**************************************************************************************************************
'**************************************************************************************************************
'**************************************************************************************************************
'**************************************************************************************************************
'************************** ************************************
'************************** MAIN CODE ************************************
'************************** ************************************
'**************************************************************************************************************
'**************************************************************************************************************
'**************************************************************************************************************
'**************************************************************************************************************
'Light Source
LightSource.x = 30
LightSource.y = -100
LightSource.z = -90
'View point
MyRay.origin.x=100
MyRay.origin.y=100
MyRay.origin.z=-ViewDistance
MyRay.ShadowRay = FALSE ' This ray is not checking InShadow
MyRay.CurrentObject=-1
SetupScene
'RDC'
sbuff = screenptr
Do
'RDC'
screenlock
For y=0 To 200
For x=0 To 200
'Setup Ray for each screen pixel
MyRay.Dir.x = x - MyRay.origin.x
MyRay.Dir.y = y - MyRay.origin.y
MyRay.Dir.z = 0 - MyRay.origin.z
'Normalize the direction ray
MyRay.Dir = Vec_Normalize(MyRay.Dir)
'Find the closest interection (if any)
MyIntersection = FindClosestIntersection(MyRay)
If MyIntersection.Dist>0 Then
Colour = CalculateColour(MyIntersection.Object,MyRay,MyIntersection.Dist)
'RDC'
poke integer, sbuff + (x + y * 320), Colour
'PSet (x,y), Colour
Else
'RDC'
poke integer, sbuff + (x + y * 320), baseclr
'PSet (x,y),rgb(20,20,20)
End If
If Inkey$=Chr$(27) Then
'RDC'
screenunlock
Exit Do
end if
Next x
Next y
'RDC'
screenunlock
Triangles(3).v2.y+=SP
If Triangles(3).v2.y>200 Then Triangles(3).v2.y=0
Triangles(3).v1.x+=SP
If Triangles(3).v1.x>200 Then Triangles(3).v1.x=0
Triangles(3).v3.x-=SP
If Triangles(3).v3.x<0 Then Triangles(3).v3.x=200
Triangles(2).v2.y-=SP
If Triangles(2).v2.y<0 Then Triangles(2).v2.y=200
Triangles(2).v1.x+=SP
If Triangles(2).v1.x>200 Then Triangles(2).v1.x=0
Triangles(1).v2.x+=SP
If Triangles(1).v2.x>200 Then Triangles(1).v2.x=0
For a=1 To NUMTRIANGLES
Triangles(a).Plane.Dir = Vec_Normalize(Vec_CrossProduct(Vec_Subtract(Triangles(a).v2,Triangles(a).v1),Vec_Subtract(Triangles(a).v3,Triangles(a).v1)))
Next a
Loop
'**************************************************************************************************************
'**************************************************************************************************************
'**************************************************************************************************************
'**************************************************************************************************************
'************************** ************************************
'************************** FUNCTIONS AND SUBS ************************************
'************************** ************************************
'**************************************************************************************************************
'**************************************************************************************************************
'**************************************************************************************************************
'**************************************************************************************************************
Function Vec_Length(v As VectorType) As Double
Vec_Length=Sqr(v.x*v.x+v.y*v.y+v.z*v.z)
End Function
Function Vec_Normalize(v As VectorType) As VectorType
Dim l As Double
l=Vec_Length(v)
v.x=v.x/l
v.y=v.y/l
v.z=v.z/l
Vec_Normalize = v
End Function
Function FindClosestIntersection(Ray As RayType) As InterSectionType
Dim Result As InterSectionType
Dim a As Integer
Dim Intersect As InterSectionType
'Set the default return values
Result.Dist=-1
Result.Object=-1
For a=1 To NUMTRIANGLES
If Ray.ShadowRay = TRUE Then
'The next check is so we don't check for intersections with the intersect point object
If a<>Ray.CurrentObject Then
Intersect = TriangleIntersect(Ray, Triangles(a))
If Intersect.Dist>0 Then
Result.Dist = 1
Exit Function
End If
End If
Else
Intersect = TriangleIntersect(Ray, Triangles(a))
If Intersect.Dist>0 Then
If Result.Dist<>-1 Then
If Intersect.Dist < Result.Dist Then
Result.Dist = Intersect.Dist
Result.Object = a
Result.u = Intersect.u
Result.v = Intersect.v
End If
Else
Result.Dist = Intersect.Dist
Result.Object = a
Result.u = Intersect.u
Result.v = Intersect.v
End If
End If
End If
Next a
FindClosestIntersection = Result
End Function
Function TriangleIntersect(R As RayType, T As TriangleType) As IntersectionType
Dim Result As IntersectionType
Dim As VectorType Edge1, Edge2, TVec, PVec, QVec
Dim As Double Det, Inv_Det
Edge1 = Vec_Subtract(T.v2 , T.v1)
Edge2 = Vec_Subtract(T.v3 , T.v1)
PVec = Vec_CrossProduct(R.Dir, Edge2)
Det = Vec_DotProduct(Edge1, PVec)
If Det > EPSILON Then
TVec = Vec_Subtract(R.Origin, T.v1)
Result.u = Vec_DotProduct(TVec, PVec)
If Result.u<0.0 Or Result.u>Det Then
Result.Dist = -1
TriangleIntersect = Result
Exit Function
End If
QVec = Vec_CrossProduct(TVec, Edge1)
Result.v = Vec_DotProduct(R.Dir, QVec)
If Result.v<0.0 Or (Result.u + Result.v)>Det Then
Result.Dist = -1
TriangleIntersect = Result
Exit Function
End If
Else
If Det < (-EPSILON) Then
TVec = Vec_Subtract(R.Origin, T.v1)
Result.u = Vec_DotProduct(TVec, PVec)
If (Result.u>0.0 Or Result.u<Det) Then
Result.Dist = -1
TriangleIntersect = Result
Exit Function
End If
QVec = Vec_CrossProduct(TVec, Edge1)
Result.v = Vec_DotProduct(R.Dir, QVec)
If (Result.v>0.0 Or (Result.u + Result.v)<Det) Then
Result.Dist = -1
TriangleIntersect = Result
Exit Function
End If
Else
Result.Dist = -1
TriangleIntersect = Result
Exit Function
End If
End If
Inv_Det = 1.0 / Det
Result.Dist = Vec_DotProduct(Edge2, QVec) * Inv_Det
Result.u = Result.u * Inv_Det
Result.v = Result.v * Inv_Det
TriangleIntersect = Result
End Function
Function Vec_CrossProduct(v1 As VectorType, v2 As VectorType) As VectorType
Dim Result As VectorType
Result.x = v1.y * v2.z - v1.z * v2.y
Result.y = v1.z * v2.x - v1.x * v2.z
Result.z = v1.x * v2.y - v1.y * v2.x
Vec_CrossProduct = Result
End Function
Function Vec_DotProduct(v1 As VectorType, v2 As VectorType) As Double
Vec_DotProduct = v1.x*v2.x + v1.y*v2.y + v1.z*v2.z
End Function
Function Vec_Subtract(v1 As VectorType, v2 As VectorType) As VectorType
Dim Result As VectorType
Result.x = v1.x - v2.x
Result.y = v1.y - v2.y
Result.z = v1.z - v2.z
Vec_Subtract = Result
End Function
Sub SetupScene
Dim a As Integer
For a=1 To NUMTRIANGLES
Read Triangles(a).v1.x
Read Triangles(a).v1.y
Read Triangles(a).v1.z
Read Triangles(a).v2.x
Read Triangles(a).v2.y
Read Triangles(a).v2.z
Read Triangles(a).v3.x
Read Triangles(a).v3.y
Read Triangles(a).v3.z
Triangles(a).Plane.Origin = Triangles(a).v1
'Calc the plane normal from the verts
Triangles(a).Plane.Dir = Vec_Normalize(Vec_CrossProduct(Vec_Subtract(Triangles(a).v2,Triangles(a).v1),Vec_Subtract(Triangles(a).v3,Triangles(a).v1)))
Read Triangles(a).r
Read Triangles(a).g
Read Triangles(a).b
Next a
End Sub
Function CalculateColour(Object As Integer, R As RayType, L As Double) As Integer
Dim As Double DP
Dim As VectorType I,IL
Dim As IntersectionType AnIntersection
Dim As RayType ARay
'Get the intersection point
I.x=R.Origin.x + r.Dir.x * L
I.y=R.Origin.y + r.Dir.y * L
I.z=R.Origin.z + r.Dir.z * L
'Create a vector from the intersection point to the light source
IL = Vec_Normalize(Vec_Subtract(LightSource,I))
'Get the dot product of the normal and this new vector
DP = Abs(Vec_DotProduct(IL, Triangles(Object).Plane.Dir))
If DP>0 Then
'Check if intersection point is in the shadow of another object
ARay.Origin = I
ARay.Dir = IL
ARay.ShadowRay = TRUE
ARay.CurrentObject = Object
AnIntersection = FindClosestIntersection(ARay)
'In shadow?
If AnIntersection.Dist>0 Then
'Use these results to calc the light value
DP=DP/3
End If
CalculateColour = Rgb(Triangles(Object).r*DP,Triangles(Object).g*DP,Triangles(Object).b*DP)
Else
CalculateColour = 0
End If
End Function
'**************************************************************************************************************
'**************************************************************************************************************
'**************************************************************************************************************
'**************************************************************************************************************
'************************** ************************************
'************************** DATA ************************************
'************************** ************************************
'**************************************************************************************************************
'**************************************************************************************************************
'**************************************************************************************************************
'**************************************************************************************************************
'Triangle Data (v1,v2,v3,r,g,b)
Data 5,5,0
Data 195,100,0
Data 80,160,0
Data 255,0,0
Data 50,20,-20
Data 140,125,0
Data 40,190,20
Data 0,255,0
Data 160,180,-20
Data 60,50,0
Data 140,45,20
Data 0,0,255
Data 0,180,-100
Data 0,180,100
Data 200,180,100
Data 255,255,00
Data 200,180,100
Data 200,180,-100
Data 0,180,-100
Data 255,255,0
'BESETTINGS (don't change!):
'BECURSOR=70A
'BETOGGLE=111111111
'BETARGET=1
Oh, and I compared this to tinyptc and this method was actually faster than both tinyptc and tinyptc_ext, at least on my machine.
-
Thing is with thousands of calculations for intersections, reflections and colours, per pixel, the overhead for pset is totally irrelevant.
Jim
-
@RDC - I ran the profiler on my original code, and PSET didn't even reach 0.1% of the execution time. Thanks anyway, but the maths/algorithm need to optimised well before the drawing functions in this situation.
-
What a great thread! And Voltage, great work and thanks Thygrion for the explanations. Without wanting to sound too harsh though, if you're going to pimp msn here then I might as well close the site and turn it into a chat room.
Harsh?
Sorry, it's not meant to be and of course, msn can be really helpful to explain this sort of stuff, the trouble with it is always that everyone else on the forum wonders how things are going and only one person benefits from the advice.
In fact, I even go as far as this when somebody PM's me with a question on coding, I always give a deliberately vague answer and ask the person to post the question on the board.
I hope that you'll carry on with the topic here, I can't force you of course, but it would be a shame to solicit something as interesting as this away from here.
Cheers :)
-
Sorry Nick :)
I myself have never done first-hit optimisation, simply because all my scenes I used in my tracers had objects that covered the entire screen.
I believe it's faster NOT to use it anyway. I mean, with adaptive subsampling and first-hit optimisation, one kinda ruins the other. I prefer subsampling because it has more possibilities than first-hit.
Just my opinion.
As far as CSG goes, I'm going to keep that under wraps for now. I'll explain it when the tracer evolves to a point where it's ready, simply because I don't want to present algorithms that will severely complicate the code before the code works correctly without them.
-
I was just pointing out that PSet is slower compared to other methods for display in FB, not that it would make the program a speed demon. I just thought I would try and be helpful.
-
Oh I was totallynot trying to flame you, I meant I wouldn't use first-hit optimisation.
I was sharing an opinion and giving different views on different optimisations, that's all. Sorry!!
-
I think it's probably me he's talking to. Sorry mate.
Another possibility with first hit is to render the surface normals into a buffer (by interpolation), instead of having to work them out for each pixel.
Jim
-
Here's the next version. It uses a basic sub sampling algorithm to halve the number of rays being traced. :clap:
I wrote a big long explaination but again IE crashed on me when using these forums. :'(
-
That is quite noticeably faster I didnt know that raytracing could be done in realtime. Are you planning on including reflections and refractions at some point? Good work on those optimisations btw.
-
Awesome work.
Btw, no one needs to apologize here. I'm not miffed. Sorry if it came across that way. I was just explaining my reason for posting.
-
Nice, very fast indeed :)
-
@Rain_Storm:
'Specular lighting
'Texture maps
'Reflection
'Spheres
'Optimizations - Adaptive Sub-sampling/Bounding boxes/other?
The above are lines from the source code.... I will most definately be adding reflections and other various raytracing cool stuff. But the adaptive sub sampling REALLY wet my whistle :) ... so to speak, so I implemented that first.
My goal, and reason for attempting a real time raytracer is that I want to create a demo worthy of the elite scene. So I will try (any probably fail many times) to create a scene worthy demo.
So whats next?
I think specular lighting, then relfections, then maybe refractions...... I'll keep posting code as I make progress.
@Thygrion: Have I earned the right to see your funky code yet? Send us the goods :)
-
then relfections
lol, I had a coupla wines tonight :)
-
That is quite a lot faster :D Well done voltage!
-
Try doing something with spheres, because it is amazingly faster, but not realtime here.
Maybe my goals are just different :P
-
hm... I came accross a little mean there...
What I meant was it's alot faster and great work. What size squares are being used initially? I think it's just the triangles that's making it slow..if not try 8x8 squares.
Still not realtime here, but it's getting close.
This inspired me to retry accomplishing this goal in C++. I'll post some previews when I get this retarted dialog box working (with code ;) ). Hope it helps!
Keep on keeping on, this is shaping up.
-
Spheres would be cool and I would imagine spheres to be much faster than polygons since circle and spheres can be defined simply as a distance from center point so less points to consider but then again you wanna bounce that ray off the sphere so that might be more complex keep up the good work man
-
right you are :)
spheres are defined by a sphere function (3D circle function).
cylinders are defined (the way I do them ;) ) by a 2D circle function and height stuff.
planes are all defined as a simple function, too.
So spheres, cylinders, and planes are all much faster primitives to trace than triangles, and actually aren't any harder to do reflections/refractions on rays, since the same math is used.
-
Spheres would be the easiest primitives to texture map too if youd thought of adding textures as you could use the latitude and longitude of the sphere to generate your uv co-ordinates.. If I had source I would gladly share it with you Voltage, unfortunately I have never written a program like this myself, I don't think Thygrion is going to share his source with you so I will look into it this week as long as I get the time.
-
I would share it, but my C version isn't even a tracer yet (just a directX shell...) and my old freebasic tracers aren't accessable.
The only problem with texture mapping sheres with what you were explaining, Nick, (even though it is the best looking ;) ) is that the adaptive subsampling tends to screw it up. I've tried to fix it with no luck so far, but when I get it I'll gladly explain how :)
-
Thygrion: It should look fine if you force to go one step further in the sampling grid when the area covered by one square in the U,V space is too big.
-
some fine stuff youve made there, i've always been interested in raytracing, just never had the initative to give it a try. Keep it coming, great stuff :)
-
Hows about this Blitz topic: http://dbfinteractive.com/index.php?topic=165.0
-
Hey I'd forgotten about that post Clyde :) Nice find.
-
Woot for Clyde!!
Yup, that's my first raytracer :D
Not realtime, but my code is still structured the same way (mostly ;) )
Almost got the C version done, when I finish the interpolation it should work fine.
po1: You're right, but I meant a tiling problem...it goes from like u = 256 to u = 0 in one square and gets all wierd-looking....I'll show you if I have that problem in C.
-
Thygrion sphere ray-casting is damn simple, and the u0=255 and u1=0 case will induce a cascade of subsampling that will solve the pb.
I've not checked if you posted your code, and never touched FreeBasic, but the sub-sampling should test ONLY the primitives found at the 4 corners so it should be pretty fast.
FWIW, I made some RTRT in C/C++ back in the days, around 98, but that was just a bunch of spheres, planes, cylinders and cones
-
Thanks everyone for the info, interest and links....raytracing is addictive isn't it?
Attached is the current version:
- Added spheres
- Added specular lighting
Still to do
- FPS
- Recursive reflection
- Refraction
- Texturing
- Improve sub smapling routine - the current one is really crappy, I reckon I can at least double the speed of the tracer...
-
Wow, that looks amazing dude, grand job :)
-
Looking good.
-
Doesn't look bad!
Yeah I think a bit more speed is possible with more code on the algorithm...it seems like about 50% of your pixels are being traced, when usually I get around 20%.
-
Voltage, id say that if you can at least double the speed of the tracer as you say you can then you can have some more karma to go with the karma I'm giving you now.
The lighting looks really great, you have your plane in there too, just fabulous really and you posted your source too. wow!
Top quality stuff and when you have finished the optimisations, it will be even better to convert it over to tinyptc, sure the optimisation won't be as dramatic as what you've done so far, but it will still be significant enough to do it :)
-
Thats looking real nice man, You got my respect. I can only imagine how much work was involved in gettin to a stage where you felt confident enough to take on a project like this all by yourself
:cheers:
-
Nice one Voltage, looks like you've got further with this than i did. There is a slight bug there, on the floor plane one of the spheres only seems to be casting half a shadow, maybe only on to one triangle.
-
Got my first preview working :)
Give me 5 minutes and I'll have it up here.
-
Here it is, my C++ preview.
I'm going to recode alot of the engine's inner workings for more speed, because I can :)
Right now that's 24 spheres, all with specular lighting and shadows.
DO NOT RUN FULLSCREEN!!! I have yet to fix problems with it.
Also probably some errors with changing resolution. I don't care right now and won't until the tracer's as fast as I want it :P
-
Hooah! :goodpost: Looks great mate, I'm gonna have to try mine with 24 spheres at 320x200.
This thread is fast becoming the RTRT mecca.
I have mine down to casting 30% of the total rays, and I have found that a 6x6 sub sample works best (ie least number of rays needed).... although I'm not sub dividing my sub samples.
I will add reflections and post something up today.
@Stonemonkey: Shadow bug fixed. Thanks mate.
@Rain_Storm: Thanks, years of hair pulling. 31 now - 8 when I started programming = 23 years hobbist programmer :) Sad, very sad.
@Shockwave: Thanks for the comments and karma. What is karma? (in relation to this forum)
-
Here is a comparable (kinda) one to Thygrion's earlier posted raytracer....
Same resolution, same number of spheres, same effects.
-
Lookin good!
And just so you know (not that I think you don't, I'm just clarifying ;) ) I'm not competing with you - I'm competing with my old raytracers and posting my code to help you and/or anyone else who reads this thread.
-
This is not realtime, it takes ages but I thought I'd post the code anyway as there might be something useful in it somewhere. I did make an attempt at realtime but can't find it anywhere and might've lost it with my HD failure a while back.
-
Worth the wait for the render :)
Lovely stonemonkey!
-
Thanks Thygrion.
This is annoying, I've found an exe of my realtime effort but still no source. I hadn't heard of or thought of subdivision at the time so there's nothing like that in it.
-
I really like these ray tracers and my thought when i did my raycaster was to go on to one of these but to much work for me ;::(
So GOOD work voltage and Stonemonkey
-
Stonemonkey, I was not prepared for the quality of that image, it looks simply excellent. Thygrion, that looks wonderful! I was surprised at the nice speed of it! Voltage, ditto, and it's great to see a basic language being pused to produce things like this.
-
Thanks, the image can be impoved a bit with oversampling which reduces the jaggies and smooths the image by changing line 1443 from
raytrace_world(world,display,0)
to
raytrace_world(world,display,1)
but be prepared for a long wait as it's really really slow.
-
Hi!
That's really cool!
Greetings
stef
-
Welcome aboard stef :hi:
That was one hell of a render stonemonkey well worth waiting for.
These tracers are really well done thanks guys for sharing your code (not that I'm planning on taking on a tracer anytime soon) this thread will definately prove invaluable to somebody its become a one stop shop
;D well done for you efforts
-
Great stuff Stonemonkey! The chess board looks amazing, that would have taken some time to model mate.
..... pawn takes rounded cube.......
And I see you have reflections in your realtime code, that rocks, and has inspired me to get relfections up and running in mine.
@Thygrion: :telloff: Who do you think you are! ......;) No probs here. The more info/interest/demos/source that are posted here the better for everyone involved. And that info about sub sampling was like a nerds wet dream :) Thanks mate.
-
No problem :)
When I start adding CSG to mine I'll try to explain almost everything with my updates.
Here's a small update.
I fixed some....ah hell just read the readme :P
run rtrtmask.exe, and you can see how little tracing is actually done.
The point of all my tracers and why they're faster than alot of others is because I try to use a non struct/class/type approach and try to store everything on only arrays.
Probably at the end of this, when I reach my goals for a tracer (And BTW thanks a hell of alot Voltage for refreshing my RTRT memory and getting me going again :D ) I'll probably see to writing a tutorial on all of this.
-
Pretty impressive stuff. How many recursions are allowed?
Jim
-
8x8 to 1x1 squares, so I think that's 4.
Stonemonkey: I think I have the source to your realtime attempt!! Might be an earlier one. I'm at church but when I have access to my machine at home I'll see if it's the one!
-
That would be cool if you have Thygrion, I've searched through a pile of backup discs and found nothing. Feel free to post it if you find it.
-
Code might be hanging around here too...somewhere...
@Thygrion - I mean when you get a hit and spawn a reflected ray, how many times can it be reflected?
Jim
-
At this point none; but I plan to have 2 layers of reflection, i.e. primary ray hits sphere, reflected ray hits wall, reflected ray hits sphere.
-
That looks really good! Runs nice and fast, about 35 fps here in 640 X 480 I'd say I wonder if it will run faster on the laptop (dual core processor).
-
I've got to say all this Ray stuff, is very interesting to read. And deserves to be a Star Post. I really like reading and seeing how things develope.
Keep it up dudes,
Clyde.
-
Stonemonkey: Sorry, haven't got the source, just the exe from when you made it.
Shockwave: It's even faster now, and is getting better!
Everyone especially Voltage ;) : I've been spending my time lately special-casing functions, i.e. merging my interpolation functions into my square functions and having one square function for each size of square. This is alot faster because I can take advantage of knowing the square size which means I can use numeric constants instead of variables, and also it saves function calls. Not to mention there are less variables passed to each function that IS called, so this is working pretty well ;) .
I have a little more work because I'm going to rewrite the interpolation for the 2x2 squares to make them faster, and I'm also going to optimize my shadow checks by storing the last object that casted a shadow's id and checking it FIRST for shadows in the next intersection. I forgot what this was called, but as far as I know it works very well.
After that I'll implement planes, followed by textures, and then I'll either do cylinders or just move straight to CSG.
-
Hey,
Cool idea for shadow checking.... Because the shadow ray exits the funciton as soon as it finds ANY intersection...... the most likely object to be casting a shadow, is the last one that was casting a shadow.
I will implement this also. You are an bottomless well of optimised raytracing knowledge :)
My sub sampler works heaps better with shadow edges now... I wasn't checking if the corners were all in or all out of shadow, but now I am. Now shadow edges are sexier, and I can raise the error metric that checks the difference between colours, which means less rays cast.
It's looking good.
Reflections are next, then I'm gonna change my sub sampler from a 6x6 non adaptive, to an 8x8 adaptive. The the shadow optimisation...... and then..... and then....... and then...... :kewl:
-
Attached is the latest version.... it does one reflection for each intersection point.
The shadows are fixed, and I included the shadow optimisation that Thygrion mentioned.
I also added a FPS counter and an interactive control for image quality...press keys 1-5.
I'm getting about 10 frames a sec on a Dual Core Athlon 64 3800+, with quality 3.
Still needs lots of optimisation, but I'm liking the results so far.
-
Looks good. Since you are on a Dual-Core you should split your algo into threads; it will run much faster that way as each core will process a thread.
-
Yep, very nice. The differences between pressing 1-5 could be quite useful in giving surfaces different properties if it's possible to vary that per object.
-
Here's my update.
Did lots of stuff, but DID NOT update rtmask.exe.
I'm not happy with the speed, and I have alot of ideas in mind to get it faster that are just general code optimizations rather than raytracer-specific ones.
The scene is an obvious Heaven Seven ripoff, but it's a good test scene :)
This will probably be my last source release; at a point code gets too precious to let go ;)
-
:goodpost: Excellent stuff looks so sweet you could eat it
-
Hi!
Really great work!
-
My gosh, they both look really neat.
Seeing your work and how it's been pushed forward during this thread is a real joy! Both are really really amazing, respect and Karma stuffs to both!
-
rdc's right - you might get a lot of benefit from subdividing the scene between CPUs. Even on my P4 HT I was able to double the speed of my Mandelbrot code using 2 threads, and if I'd used a cleverer algorithm to make sure both threads were fully occupied (not one rendering black for ages with the other having finished rendering coloured bits) I could have squeezed out a bit more.
Jim
-
@rdc n Jim: Sounds very interesting. How do I tell one core to do one thing, and the other another? I didn't know could, it just sounded fast when I bought the thing ::)
I am fully engaged in leanring how to write a raytracer though, so if it is too steep a learning curve, then I may wait until I've squeezed what I can from the tracer first.
-
Use the Windows API CreateThread. You can use that to start a procedure running. You can pass each proc a different set of parameters and set it off working on a different bit of the scene. Windows takes care of sharing the work between available CPUs.
So in pseudocode you might do something like
sub renderscreen
CreateThread(render_quarter, TOP_LEFT)
CreateThread(render_quarter, TOP_RIGHT)
CreateThread(render_quarter, BOTTOM_LEFT)
CreateThread(render_quarter, BOTTOM_RIGHT)
end sub
sub render_quarter(which_quarter_rect)
...raytrace the quarter
end sub
There are some things to worry about with multithreading which occur when one thread is updating a piece of data that the other thread is reading or updating. I don't see where that could occur in raytracing though.
<edit>
Freebasic has some of its own thread handling built in, so you may not need Windows API
http://www.freebasic.net/wiki/wikka.php?wakka=CatPgThreading (http://www.freebasic.net/wiki/wikka.php?wakka=CatPgThreading)
Jim
-
is it really that streight forward todo multithreading on the windows api i had it that it would be much harder.
how much benefit could be had from multithreading a normal cpu ie my lappy one a pentium m 1.8 i know i depends on what task your multithreading but say i done the abouve and renderd my scene through diffrent threads.
-
Yes, it can be that simple. I've just spent the last year with Intel sending me white papers on how to make multithreaded programs (want to sign up?). They're desperate for people to write their code multithreaded so they can sell more Core2 CPUS :) There are things you need to take into account, but you fix those when you need to (runtime library issues, shared data structure issues). Nearly all my programs use more than one thread now, where convenient.
On a single CPU you might find it slower. How much depends on the algorithm and the pattern of memory access.
Jim
-
As Jim mentioned FB has built-in thread support. See threads.bas in the example folder of your FB installation. When you use threads the CPU will automatically allocate a thread to a core, so all you need to do is to add thread support to your program.
Even on a single core CPU you can gain some benefits from using threads. For example, a thread can be calculating while another thread draws something on the screen. The drawing process may take longer than the calculation process, so when the drawing is done, a fresh set of calcs are waiting to be drawn. On a dual core the calcs and drawing would happen at the same time so it would be much faster. On a single core it would time slice, but may still be faster than a serial operation (calc-draw-calc, etc). You would just have to try it and see.
-
Is it a problem with multithreading that if one thread lags behind the rest than the whole program only runs as fast as the slowest thread?
-
Your program is only going to go as fast as the slowest part of the program, regardless of whether you use threads or not. A thread can bottleneck a program of course, but if you structure it correctly it is really not much different than a program that doesn't use threads. The only real danger of using threads is a deadlock, where two threads are waiting for each other to finish. However, this can be easily avoided by just using proper structure, and using some flag variables to indicate when a thread has completed.
There are a couple of approaches to using threading. One approach is to use the slow parts of the program to do additional work to gain an overall speed boost. As I mentioned above, if drawing takes more time than the calcs, you can do a fresh set of calcs while you draw a scene. This way the drawing routine is always working and doesn't have to wait for new calcs.
The other approach is to divide and conquer. If a routine is too slow, you can break it into parts and work on each part at the same time. If the drawing routine is too slow, you can break it into 2 threads each thread draws half of the screen. If the calcs are too slow, you can divide the calcs in the same manner with each thread doing part of the work.
You can also mix the two as well.: While one half of the screen is being draw, you are calculating the other half that will be passed to the render. While the second half is being drawn you are calculating the first half of the next frame.
How you approach it just depends on what bottlenecks you have that may benefit from threading and how to synchronize the different threads to handle the work. It isn't all that complicated, you just have to approach the problem with a clear idea of what you need to do and when you need to do it.
Threads aren't magic bullets either. Some program just don't benefit from threading. A ray-tracer though should be a good candidate for threading, especially on a dual core system. The more you can do simultaneously, the faster your program will be in the end.
-
One amendment to my previous post: I believe FB gfx lib isn't thread compliant so you wouldn't benefit from having threads do the actual drawing. (You might to want to double check this with the FB dev team on the FB forum.) However, you could sill use threads for calculations while the main program draws the frame. Anyway, it is just an option to keep in mind as you work on the program. :)
-
cool stuff Thygrion.
-
This is the latest update. Basically the point was to minimize subdividing around reflection objects, which explains most of the jpg-like artifacts.
I need to optimize the hell out of this CPU-eating beast, but when that's done and the tracer's done I'll comment it all and put it up here.
I like the image quality myself (I use the same cheats H7 uses ;) ), but tell me what you think.
As far as freebasic goes, I've found my old sources! Also reinstalled drivers so I can stream my neighbor's internet once more, so I'll try to post some stuff up tonight :)
-
Beautiful, textures and everything and it runs fast too.
Stunning stuff man.
-
If only it ran fast here :P
I know the problem is all the double-texture interpolation and such...I'm going to rewrite those routines (rtrt/engine/tracer.cpp, look at tracersquare8 etc....ouch!) and it should be alot better afterwords.
How's your tracer coming, Voltage? Haven't talked in awhile.
-
shiny!
-
Runs really fast here in all but the 640x480 resolution which is not quite realtime but still framerate isnt too bad at that res but its really good quality I notice that the walls seem to reflect more than one ball so how many times does the ray bounce around? its gotta be more than twice
-
Nah it's just twice. Which is why sometimes you can see a reflection of the ball on the ball and it almost looks like it has 8 walls rather than 4 :)
-
Hows it going Voltage dude?
-
*bump* accepted. :)
I haven't done much on this recently... we have a new baby(girl), just got engaged, and I have my Hapkido black belt grading on this Friday. Been a little busy. :o
I'm still fired up to make this thing a reality though, so thanks for the interest.
Voltage
-
Cool and welldone dude, best of luck on Friday.
Cheers,
Clyde.
-
Hope all goes well, I want a preview!! ;)
-
Congratulations on your baby girl btw Voltage :) I think I posted it in the shoutbox, but well, here it is again just in case :)
-
@Clyde and Shockwave: Thanks dudes.
@Thygrion: Preview of what? My engagement? ;) That's a little personal.
If you want I'll post a vid of my grading, I've gotta break some tiles for this one.
-
Lol...sorry I switched the subject there :P
I want another tracer preview!
-
This is so fucking great. I had to revive this topic, here is a screen for people who don't know what they are missing!
-
Wow, looks awesome... is it possible to get a compiled version? thx
-
Yep, go to page six and there is a compiled version attached to one of the posts :)
-
You've got my attention.
Time to dust off the keyboard and make some improvements.
-
If anyone ever mentions a realtime raytracing compo - I'm in.
Chris
-
If anyone ever mentions a realtime raytracing compo - I'm in.
I wonder how many entries we'd have if we did something like that...
And welcome back Voltage :)
-
It would be a compo for quality not quantity we would need to allow raycasting to improve the number of entries.
-
this is just about realtime on my new pc, core 2 duo 2.66 ghz and a nvidia 8800gts gfx card. one thing i'm wondering though, it's only using 30-40% of the processor, is it more memory hungry? or is it heavy somewhere else?
-
@Paul:
Try to split the math stuff in threads so any core have to work and could give you some speed boosting.
-
@va!n
How would i do that?