Page 2 of 9
Posted: Mon Jun 20, 2005 9:59 am
by MrMat
In TestSphere the first 9 variables should be floats instead of longs. There is no need to calculate a (it is always 1 since the direction is normalised). I think C should have the radius of the sphere squared subtracted from it (although they appear to have missed it out on the DevMaster site). Also you need to set the position/radius of the Test sphere. It should work then!
Posted: Mon Jun 20, 2005 5:51 pm
by Dreglor
ok, i changed the values to these
and changed the type to float on those nine values
then used
Code: Select all
Test\center\x=0
Test\center\y=0
Test\center\z=0
Test\radius=5.989
Origin\x=0
Origin\y=0
Origin\z=-6
Direction\x=x
Direction\y=y
Direction\z=6
and i add the squared radius into C like you said and it worked kinda werid though with certain values
it is as big as i can get it before i get negitive values (inside?)
i also put in radius in there.
Code: Select all
radius.f=*Sphere\radius
c.f=(Pow(Originx-Spherex,2)+Pow(Originy-Spherey,2)+Pow(Originz-Spherez,2))-Pow(radius,2)
Posted: Mon Jun 20, 2005 6:24 pm
by MrMat
Sorry i missed there's a bug in the VectorNormalize procedure. The 3 "If *this\x < #Tolarance" lines should have Abs() around the *this\x. I think you've left the a's in (you can replace them with 1) in the TestSphere procedure (the normalise bug didn't show up with the a removed so i missed it earlier).
Here's what i'm running (sorry i fiddled with some formatting/spelling in your code!):
Code: Select all
#ScreenWidth=320
#ScreenHeight=240
#Tolerance=0.0001
Structure xyz
x.f
y.f
z.f
EndStructure
Structure Sphere
center.xyz
radius.f
EndStructure
Procedure VectorNormalize(*this.xyz)
m.f = Sqr(*this\x * *this\x + *this\y * *this\y + *this\z * *this\z)
If m < =#Tolerance
m = 1
Else
*this\x = *this\x / m
*this\y = *this\y / m
*this\z = *this\z / m
EndIf
If Abs(*this\x) < #Tolerance
*this\x = 0
EndIf
If Abs(*this\y) < #Tolerance
*this\y = 0
EndIf
If Abs(*this\z) < #Tolerance
*this\z = 0
EndIf
EndProcedure
Procedure.f TestSphere(*Direction.xyz,*Origin.xyz,*Sphere.Sphere)
dirx.f=*Direction\x
diry.f=*Direction\y
dirz.f=*Direction\z
Originx.f=*Origin\x
Originy.f=*Origin\y
Originz.f=*Origin\z
Spherex.f=*Sphere\center\x
Spherey.f=*Sphere\center\y
Spherez.f=*Sphere\center\z
Sphererad.f=*Sphere\radius
b.f=2*(dirx*(Originx-Spherex)+diry*(Originy-Spherey)+dirz*(Originz-Spherez))
c.f=Pow(Originx-Spherex,2)+Pow(Originy-Spherey,2)+Pow(Originz-Spherez,2)-Pow(Sphererad,2)
D.f=Pow(b,2)-4*c
If D>0 ;hit the sphere
t.f=(-b - Sqr(D)) / 2 ; Could return +ve or -ve number!
ElseIf D=0 ;glazing the sphere
t.f=-1
ElseIf D<0 ;missed completely
t.f=-2
EndIf
ProcedureReturn t
EndProcedure
Origin.xyz
Direction.xyz
Testing.Sphere
Testing\center\x=0
Testing\center\y=0
Testing\center\z=100
Testing\radius=100
Origin\x=0
Origin\y=0
Origin\z=-256
InitSprite()
OpenWindow(0,0,0,#ScreenWidth,#ScreenHeight,#PB_Window_ScreenCentered|#PB_Window_SystemMenu,"Ray Test")
StartDrawing(WindowOutput())
Repeat
For y=-#ScreenHeight/2 To (#ScreenHeight/2)-1 Step 1
For x=-#ScreenWidth/2 To (#ScreenWidth/2)-1 Step 1
Direction\x=x
Direction\y=y
Direction\z=256
VectorNormalize(Direction)
t.f=TestSphere(Direction,Origin,Testing)
posx=x+(#ScreenWidth/2)
posy=y+(#ScreenHeight/2)
If t>0 ; Red - Hit (object has +ve parameter t)
Plot(posx,posy,RGB(255,0,0))
ElseIf t=-1 ; Green - Glazing; Could be returned incorrectly (when (-b - Sqr(D)) / 2 = -1)
Plot(posx,posy,RGB(0,255,0))
ElseIf t=-2 ; Blue - Missed; Could be returned incorrectly (when (-b - Sqr(D)) / 2 = -2)
Plot(posx,posy,RGB(0,0,255))
Else ; White - Hit (object has -ve parameter t)
Plot(posx,posy,RGB(255,255,255))
EndIf
Next x
Next y
Origin\z + 10
Until WindowEvent()=#PB_Event_CloseWindow
StopDrawing()
There's a possibility the TestSphere procedure could return the incorrect value because if D>0 the return value could be negative but apart from that i think it's working ok!
Posted: Mon Jun 20, 2005 8:09 pm
by Dreglor
Awsome thanks for picking that out mrmat

now i just know that if test sphere returns a negitive it's behind the origin
now i need lighting and reflections/refactions and it will become a simple raytracer
i do notice that the intersection code it pretty fast right now i wonder if its the drawing part thats really slowing it down ?
edit : i did some quick tests and the drawing add quite a bit
rendering a 800x600 window with windowoutput() renders 1750ms
with out the drawing code its 950ms thats 800ms diffrence
im sure i can speed that up though
Posted: Mon Jun 20, 2005 8:23 pm
by MrMat
Glad to help
For a speed increase it might be faster to replace the Pow(x,2) lines with x*x (if it is then perhaps the compiler should do that for us!). The RGB's could be calculated once outside the loop instead and the plots could be done directly to screen memory.
Posted: Mon Jun 20, 2005 8:50 pm
by MrMat
It seems a lot faster now. I think it was plotting to a windowed screen that made the biggest difference:
Code: Select all
#ScreenWidth = 320
#ScreenHeight = 240
#Tolerance = 0.0001
Structure xyz
x.f
y.f
z.f
EndStructure
Structure Sphere
center.xyz
radius.f
EndStructure
Procedure VectorNormalize(*this.xyz)
m.f = Sqr(*this\x * *this\x + *this\y * *this\y + *this\z * *this\z)
If m < = #Tolerance
m = 1
Else
*this\x = *this\x / m
*this\y = *this\y / m
*this\z = *this\z / m
EndIf
If Abs(*this\x) < #Tolerance
*this\x = 0
EndIf
If Abs(*this\y) < #Tolerance
*this\y = 0
EndIf
If Abs(*this\z) < #Tolerance
*this\z = 0
EndIf
EndProcedure
Procedure.f TestSphere(*Direction.xyz,*Origin.xyz,*Sphere.Sphere)
offx.f = *Origin\x - *Sphere\center\x
offy.f = *Origin\y - *Sphere\center\y
offz.f = *Origin\z - *Sphere\center\z
Sphererad.f = *Sphere\radius
b.f = 2 * (*Direction\x * offx + *Direction\y * offy + *Direction\z * offz)
c.f = offx * offx + offy * offy + offz * offz - Sphererad * Sphererad
D.f = b * b - 4 * c
If D > 0 ;hit the sphere
t.f = (-b - Sqr(D)) / 2 ; Could return +ve or -ve number!
ElseIf D = 0 ;glazing the sphere
t.f = -1
ElseIf D < 0 ;missed completely
t.f = -2
EndIf
ProcedureReturn t
EndProcedure
Origin.xyz
Direction.xyz
Testing.Sphere
Testing\center\x=0
Testing\center\y=0
Testing\center\z=100
Testing\radius=100
Origin\x=0
Origin\y=0
Origin\z=-512
InitSprite()
OpenWindow(0,0,0,#ScreenWidth,#ScreenHeight,#PB_Window_ScreenCentered|#PB_Window_SystemMenu,"Ray Test")
OpenWindowedScreen(WindowID(),0,0,#ScreenWidth,#ScreenHeight,1,0,0)
col1 = RGB(255,0,0)
col2 = RGB(0,255,0)
col3 = RGB(0,0,255)
col4 = RGB(255,255,255)
halfheight = #ScreenHeight/2
halfwidth = #ScreenWidth/2
Repeat
ClearScreen(0, 0, 255)
StartDrawing(ScreenOutput())
For y = -halfheight To halfheight - 1
For x = -halfwidth To halfwidth - 1
Direction\x = x
Direction\y = y
Direction\z = 256
VectorNormalize(Direction)
t.f = TestSphere(Direction, Origin, Testing)
posx = x + halfwidth
posy = y + halfheight
If t>0 ; Red - Hit (object has +ve parameter t)
Plot(posx, posy, col1)
ElseIf t=-1 ; Green - Glazing; Could be returned incorrectly (when (-b - Sqr(D)) / 2 = -1)
Plot(posx, posy, col2)
ElseIf t=-2 ; Blue - Missed; Could be returned incorrectly (when (-b - Sqr(D)) / 2 = -2)
;Plot(posx, posy, col3)
Else ; White - Hit (object has -ve parameter t)
Plot(posx, posy, col4)
EndIf
Next x
Next y
Origin\z + 10
StopDrawing()
FlipBuffers()
Until WindowEvent() = #PB_Event_CloseWindow
Posted: Mon Jun 20, 2005 9:05 pm
by Dreglor
wow your fast, i was just to post my own optimaztion that did exactly what yours did
there are a few small harder opimzations i could do like drawing buffer it may not work in windowed mode though
Posted: Mon Jun 20, 2005 9:10 pm
by MrMat
hehe, i'll leave you to make any further optimisations! It feels like a game of Elite at the moment!
Posted: Tue Jun 21, 2005 3:25 am
by Dreglor
Let There Be Light!

the code is a real mess right now though :\
Posted: Tue Jun 21, 2005 10:17 am
by MrMat
Wow that looks great! Is it fast?
Posted: Tue Jun 21, 2005 1:14 pm
by remi_meier
Just a question: Did you read DarkDragon's first post?
Posted: Tue Jun 21, 2005 1:22 pm
by MrMat
Yes! The screenshots in the German forum look great. Alas i can't read a word of it but it looks like they're doing some awesome stuff

Posted: Tue Jun 21, 2005 1:29 pm
by remi_meier
Just asked because Blade said "Never seen a PB example..."
NicTheQuick has released a raytracing Userlib
http://mitglied.lycos.de/NicTheQuick198 ... 0RTEngine/
so you can test a little bit with the source code. He didn't release the source
of the engine because he probably wants to make money with it. But you
surely can ask him for some tips

Posted: Tue Jun 21, 2005 1:31 pm
by MrMat
Thanks for the link Remi! It's great theres so much interest in such a fun area of computer graphics

Posted: Tue Jun 21, 2005 8:56 pm
by Dreglor
yeah i saw that to bad it doesn't have its source :\
well the with the lighting its 20fps
with out it's 40fps
the lighting is directional it not a point light yet
right now im am working on a system to incorperate muiltible objects with diffrent types