RayTracer Theory and Practice

Everything else that doesn't fall into one of the other PB categories.
MrMat
Enthusiast
Enthusiast
Posts: 762
Joined: Sun Sep 05, 2004 6:27 am
Location: England

Post 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!
Mat
Dreglor
Enthusiast
Enthusiast
Posts: 759
Joined: Sat Aug 02, 2003 11:22 pm
Location: OR, USA

Post 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) 
~Dreglor
MrMat
Enthusiast
Enthusiast
Posts: 762
Joined: Sun Sep 05, 2004 6:27 am
Location: England

Post 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!
Mat
Dreglor
Enthusiast
Enthusiast
Posts: 759
Joined: Sat Aug 02, 2003 11:22 pm
Location: OR, USA

Post 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
~Dreglor
MrMat
Enthusiast
Enthusiast
Posts: 762
Joined: Sun Sep 05, 2004 6:27 am
Location: England

Post 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.
Mat
MrMat
Enthusiast
Enthusiast
Posts: 762
Joined: Sun Sep 05, 2004 6:27 am
Location: England

Post 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
Mat
Dreglor
Enthusiast
Enthusiast
Posts: 759
Joined: Sat Aug 02, 2003 11:22 pm
Location: OR, USA

Post 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
~Dreglor
MrMat
Enthusiast
Enthusiast
Posts: 762
Joined: Sun Sep 05, 2004 6:27 am
Location: England

Post by MrMat »

hehe, i'll leave you to make any further optimisations! It feels like a game of Elite at the moment!
Mat
Dreglor
Enthusiast
Enthusiast
Posts: 759
Joined: Sat Aug 02, 2003 11:22 pm
Location: OR, USA

Post by Dreglor »

Let There Be Light! :D
Image
the code is a real mess right now though :\
~Dreglor
MrMat
Enthusiast
Enthusiast
Posts: 762
Joined: Sun Sep 05, 2004 6:27 am
Location: England

Post by MrMat »

Wow that looks great! Is it fast?
Mat
remi_meier
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Dec 20, 2003 6:19 pm
Location: Switzerland

Post by remi_meier »

Just a question: Did you read DarkDragon's first post?
Athlon64 3700+, 1024MB Ram, Radeon X1600
MrMat
Enthusiast
Enthusiast
Posts: 762
Joined: Sun Sep 05, 2004 6:27 am
Location: England

Post 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 :)
Mat
remi_meier
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Dec 20, 2003 6:19 pm
Location: Switzerland

Post 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 :wink:
Athlon64 3700+, 1024MB Ram, Radeon X1600
MrMat
Enthusiast
Enthusiast
Posts: 762
Joined: Sun Sep 05, 2004 6:27 am
Location: England

Post by MrMat »

Thanks for the link Remi! It's great theres so much interest in such a fun area of computer graphics :D
Mat
Dreglor
Enthusiast
Enthusiast
Posts: 759
Joined: Sat Aug 02, 2003 11:22 pm
Location: OR, USA

Post 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
~Dreglor
Post Reply