Hi all,
Last night I saw this posting on BlitzMax forums.
I thought it was kinda neat and made a quick attempt to rewrite it in Hollywood. About half an hour later and some hard typing, the raytracing part with default illumination model seems to be working as it should. There is still something wrong with the photon mapping part but I can probably figure it out later today. I will also try to implement interactive part of the program.
I will try to post the source later today...
Ray Tracing and Photon Mapping
Re: Ray Tracing and Photon Mapping
Photon mapping still needs some work but now spheres and light source can be dragged around in view...
Re: Ray Tracing and Photon Mapping
Here is the source for Ray Tracer without the photon mapping.
I'm still trying to figure out what is wrong with photon mapping, but meanwhile have fun with this!
Don't forget to try drag spheres and lightsource around the screen...
I'm still trying to figure out what is wrong with photon mapping, but meanwhile have fun with this!
Don't forget to try drag spheres and lightsource around the screen...
Code: Select all
; Simple Ray Tracer based on example written by Grant Schindler
; and BlitzMax port by Adam Piette.
;
; Bugs are mine, obviously!
;
@DISPLAY {Height = 512, Width = 512, Title = "Simple Interactive Progressive Ray Tracer"}
Global szImg = 512
Global nrTypes = 2
Global nrObjects = { 2, 5 }
Global gAmbient = 0.1
Global gOrigin = { 0.0, 0.0, 0.0 }
Global Light = { 0.0, 1.2, 3.75 }
Global spheres = { { 1.0, 0.0, 4.0, 0.5 }, { -0.6, -1.0, 4.5, 0.5 } }
Global planes = { { 0.0, 1.5 }, { 1.0, -1.5 }, { 0.0, -1.5 }, { 1.0, 1.5 }, { 2.0, 5.0 } }
Global nrPhotons = 1000
Global nrBounces = 3
Global sqRadius = 0.7
Global exposure = 50.0
Global numPhotons = { {0, 0}, {0,0,0,0,0} }
Dim photons[2][5][5000][3][3]
Global gIntersect = False
Global gType
Global gIndex
Global gSqDist
Global gDist = -1.0
Global gPoint = { 0.0, 0.0, 0.0 }
Function raySphere(idx, r, o)
Local s = sub3(spheres[idx], o)
Local radius = spheres[idx][3]
Local A = dot3(r, r)
Local B = -2.0 * dot3(s, r)
Local C = dot3(s, s) - (radius * radius)
Local D = B * B - 4.0 * A * C
If D > 0.0
Local sign
If C < -0.00001 Then sign = 1.0 Else sign = -1.0
Local lDist = (-B + sign * Sqrt(D)) / (2.0 * A)
checkDistance(lDist, 0, idx)
EndIf
EndFunction
Function rayPlane(idx, r, o)
Local axis = planes[idx][0]
If r[axis] <> 0.0
Local lDist = (planes[idx][1] - o[axis]) / r[axis]
CheckDistance(lDist, 1, idx)
EndIf
EndFunction
Function rayObject(typ, idx, r, o)
If typ = 0
raySphere(idx, r, o)
Else
rayPlane(idx, r, o)
EndIf
EndFunction
Function checkDistance(lDist, p, i)
If lDist < gDist And lDist > 0.0
gType = p
gIndex = i
gDist = lDist
gIntersect = True
EndIf
EndFunction
Function lightDiffuse(N, P)
Local L = normalize3(sub3(Light, P))
Return(dot3(N, L))
EndFunction
Function sphereNormal(idx, P)
Return(normalize3(sub3(P, spheres[idx])))
EndFunction
Function planeNormal(idx, P, O)
Local axis = Int(planes[idx][0])
Local N = { 0.0, 0.0, 0.0 }
N[axis] = O[axis] - planes[idx][1]
Return(normalize3(N))
EndFunction
Function surfaceNormal(Typ, index, P, Inside)
If Typ = 0
Return(sphereNormal(index, P))
Else
Return(planeNormal(index, P, Inside))
EndIf
EndFunction
Function lightObject(Typ, idx, P, lightAmbient)
Local i = lightDiffuse(surfaceNormal(Typ, idx, P, Light), P)
Return(Min(1.0, Max(i, lightAmbient)))
EndFunction
Function raytrace(ray, origin)
gIntersect = False
gDist = 999999.9
For Local t = 0 To nrTypes - 1 Step 1
For Local i = 0 To nrObjects[t] - 1 Step 1
rayObject(t, i, ray, origin)
Next
Next
EndFunction
Function computePixelColor(x, y)
Local rgbc = { 0.0, 0.0, 0.0 }
Local ray = { x/szImg - 0.5, - (y/szImg - 0.5), 1.0 }
raytrace(ray, gOrigin)
If gIntersect
gPoint = mul3c(ray, gDist)
If gType = 0 And gIndex = 1
ray = reflect(ray, gOrigin)
raytrace(ray, gPoint)
If gIntersect Then gPoint = add3(mul3c(ray, gDist), gPoint)
EndIf
Local tType = gType
Local tIndex = gIndex
Local i = gAmbient
raytrace(sub3(gPoint, Light), Light)
If tType = gType And tIndex = gIndex
i = lightObject(gType, gIndex, gPoint, gAmbient)
EndIf
rgbc[0] = i
rgbc[1] = i
rgbc[2] = i
rgbc = GetColorRGB(rgbc, tType, tIndex)
EndIf
Return(rgbc)
EndFunction
Function reflect(ray, fromPoint)
Local N = surfaceNormal(gType, gIndex, gPoint, fromPoint)
Return(normalize3(Sub3(ray, mul3c(N, (2.0 * dot3(ray, N))))))
EndFunction
Function filterColor(rgbIn, r, g, b)
Local rgbOut = { r, g, b }
For Local c = 0 To 2
rgbOut[c] = Min(rgbOut[c], rgbIn[c])
Next
Return(rgbOut)
EndFunction
Function GetColorRGB(rgbIn, Typ, index)
If Typ = 1 And index = 0
Return(filterColor(rgbIn, 0.0, 1.0, 0.0))
ElseIf Typ = 1 And index = 2
Return(filterColor(rgbIn, 1.0, 0.0, 0.0))
Else
Return(filterColor(rgbIn, 1.0, 1.0, 1.0))
EndIf
EndFunction
Function normalize3(v)
Local L = Sqrt(dot3(v, v))
Return(mul3c(v, 1.0 / L))
EndFunction
Function sub3(a, b)
Local result = { a[0] - b[0], a[1] - b[1], a[2] - b[2] }
Return(result)
EndFunction
Function add3(a, b)
Local result = { a[0] + b[0], a[1] + b[1], a[2] + b[2] }
Return(result)
EndFunction
Function mul3c(a, c)
Local result = { c * a[0], c * a[1], c * a[2] }
Return(result)
EndFunction
Function dot3(a, b)
Local result = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
Return(result)
EndFunction
Function rand3(s)
Local s2 = s * 2
Local r = { RndF() * s2 - s, RndF() * s2 - s, RndF() * s2 - s }
Return(r)
EndFunction
Function gatedSqDist3(a, b, sqradius)
Local c = a[0] - b[0]
Local d = c * c
If d > sqradius Then Return(False)
c = a[1] - b[1]
d = d + c * c
If d > sqradius Then Return(False)
c = a[2] - b[2]
d = d + c * c
If d > sqradius Then Return(False)
gSqDist = d
Return(True)
EndFunction
Function odd(x)
Return(x & 1)
EndFunction
Global empty = True
Global pRow, pCol, pIteration, pMax
Global xx, yy
Function draw()
If empty
render()
xx = xx + 1
If xx > 10
xx = 0
yy = yy + 1
EndIf
Else
;
EndIf
EndFunction
Function render()
Local x, y
Local iterations = 0
Local rgbc = { 0.0, 0.0, 0.0 }
Local imax = Max(pMax, 256)
If mouseDragging Then imax = 1024
While iterations < imax
If pCol >= pMax
pRow = pRow + 1
pCol = 0
If pRow >= pMax
pIteration = pIteration + 1
pRow = 0
pMax = Int(2^pIteration)
EndIf
EndIf
Local pNeedDrawing = 0
If pIteration = 1 Or odd(pRow) Or ((Not odd(pRow)) And odd(pCol)) Then pNeedDrawing = 1
x = pCol * (szImg/pMax)
y = pRow * (szImg/pMax)
pCol = pCol + 1
If pNeedDrawing
iterations = iterations + 1
rgbc = mul3c(computePixelColor(x, y), 255.0)
Local col = RGB(rgbc[0],rgbc[1], rgbc[2])
SetFillStyle(#FILLCOLOR)
Box(x, y, (szImg/pMax), (szImg/pMax), col)
EndIf
Wend
If pRow = szImg - 1 Then empty = False
EndFunction
Function resetRender()
pRow = 0
pCol = 0
pIteration = 1
pMax = 2
empty = True
EndFunction
Global MouseDragging = False
Function GrabObject()
SphereIndex = 2 ; Default to lightsource
; Try to project screen coords to world space
Local mx = (MouseX() - (szImg/2))/(szImg/2)
Local my = -(MouseY() - (szImg/2))/(szImg/2)
Local mouse3 = { mx, my, (0.5 * (spheres[0][2] + spheres[1][2])) }
If (gatedSqDist3(mouse3,spheres[0],spheres[0][3]))
sphereIndex = 0
ElseIf gatedSqDist3(mouse3,spheres[1],spheres[1][3])
sphereIndex = 1
EndIf
mouseDragging = True
EndFunction
; Simple hack for dragging, try to project screen coords to world space
Function DragObject()
If sphereIndex < nrObjects[0] ; Drag Sphere
spheres[sphereIndex][0] = ((MouseX() - (szImg/2)) /(szImg/2))/0.5
spheres[sphereIndex][1] = -((MouseY() - (szImg/2))/(szImg/2))/0.5
Else ;Drag Light
Light[0] = ((MouseX() - (szImg/2))/(szImg/2))/0.5
Light[1] = -((MouseY() - (szImg/2))/(szImg/2))/0.5
EndIf
resetRender()
EndFunction
BeginDoubleBuffer()
EscapeQuit(True)
Repeat
If IsLeftMouse()
If Not MouseDragging
GrabObject()
Else
DragObject()
EndIf
Else
MouseDragging = False
EndIf
draw()
Flip()
Forever
- airsoftsoftwair
- Posts: 5443
- Joined: Fri Feb 12, 2010 2:33 pm
- Location: Germany
- Contact:
Re: Ray Tracing and Photon Mapping
Interesting, but of course a little bit slow
Re: Ray Tracing and Photon Mapping
It's normal...
The code is slow because they are a lot of function... 1 Fonction call is slowing the PRG by approximatively 35%.
Or in this code, they are 27 fonction calls!!!
i have make speed test on lot of hollywood command.
When i make 1 prg with 1 function, my prg is more speeder than a prg where they are a lot of function...
For example:
In a small prg (10 line)
When i execute it with no function, i have 70 ticks, when i add 1 function, i have 115 ticks !!!!! (-40%)
The code is slow because they are a lot of function... 1 Fonction call is slowing the PRG by approximatively 35%.
Or in this code, they are 27 fonction calls!!!
i have make speed test on lot of hollywood command.
When i make 1 prg with 1 function, my prg is more speeder than a prg where they are a lot of function...
For example:
In a small prg (10 line)
When i execute it with no function, i have 70 ticks, when i add 1 function, i have 115 ticks !!!!! (-40%)
Re: Ray Tracing and Photon Mapping
I have just combine some function, in original code, i have 75 Tick and just if i combine some function, i turn at 40 ticks
In general time, just before line by line function... With original code, i have 6403 ticks, but with combined code (not at all optimized) i have 6128 ticks, i win 4%
I combine just checkdistance function in rayobject function, i have 5843 Ticks...
In general time, just before line by line function... With original code, i have 6403 ticks, but with combined code (not at all optimized) i have 6128 ticks, i win 4%
I combine just checkdistance function in rayobject function, i have 5843 Ticks...
Re: Ray Tracing and Photon Mapping
Hello,
I have traced the problem with photon mapping part to be in shadowPhoton() function. I also had to change sqRadius global variable from 0.7 to 0.3, to get it look about right in most cases. I don't know if it got something to do with the way Hollywood does it's math stuff or is there still some kind of an error hidden somewhere?
Tell me, if you can figure it out. shadowPhoton() function call is currently commented out in emitPhotons() function.
And yeh, this one is really slow!
I have traced the problem with photon mapping part to be in shadowPhoton() function. I also had to change sqRadius global variable from 0.7 to 0.3, to get it look about right in most cases. I don't know if it got something to do with the way Hollywood does it's math stuff or is there still some kind of an error hidden somewhere?
Tell me, if you can figure it out. shadowPhoton() function call is currently commented out in emitPhotons() function.
And yeh, this one is really slow!
Code: Select all
@DISPLAY {Height = 512, Width = 512}
Global szImg = 512
Global nrTypes = 2t
Global nrObjects = { 2, 5 }
Global gAmbient = 0.1
Global gOrigin = { 0.0, 0.0, 0.0 }
Global Light = { 0.0, 1.2, 3.75 }
Global spheres = { { 1.0, 0.0, 4.0, 0.5 }, { -0.6, -1.0, 4.5, 0.5 } }
Global planes = { { 0.0, 1.5 }, { 1.0, -1.5 }, { 0.0, -1.5 }, { 1.0, 1.5 }, { 2.0, 5.0 } }
Global nrPhotons = 1000
Global nrBounces = 3
Global lightPhotons = True
Global sqRadius = 0.3 ;0.7
Global exposure = 50.0
Global numPhotons = { {0, 0}, {0,0,0,0,0} }
Dim photons[2][5][5000][3][3]
Global gIntersect = False
Global gType
Global gIndex
Global gSqDist
Global gDist = -1.0
Global gPoint = { 0.0, 0.0, 0.0 }
Function raySphere(idx, r, o)
Local s = sub3(spheres[idx], o)
Local radius = spheres[idx][3]
Local A = dot3(r, r)
Local B = -2.0 * dot3(s, r)
Local C = dot3(s, s) - (radius * radius)
Local D = B * B - 4.0 * A * C
If D > 0.0
Local sign
If C < -0.00001 Then sign = 1.0 Else sign = -1.0
Local lDist = (-B + sign * Sqrt(D)) / (2.0 * A)
checkDistance(lDist, 0, idx)
EndIf
EndFunction
Function rayPlane(idx, r, o)
Local axis = planes[idx][0]
If r[axis] <> 0.0
Local lDist = (planes[idx][1] - o[axis]) / r[axis]
CheckDistance(lDist, 1, idx)
EndIf
EndFunction
Function rayObject(typ, idx, r, o)
If typ = 0
raySphere(idx, r, o)
Else
rayPlane(idx, r, o)
EndIf
EndFunction
Function checkDistance(lDist, p, i)
If lDist < gDist And lDist > 0.0
gType = p
gIndex = i
gDist = lDist
gIntersect = True
EndIf
EndFunction
Function lightDiffuse(N, P)
Local L = normalize3(sub3(Light, P))
Return(dot3(N, L))
EndFunction
Function sphereNormal(idx, P)
Return(normalize3(sub3(P, spheres[idx])))
EndFunction
Function planeNormal(idx, P, O)
Local axis = Int(planes[idx][0])
Local N = { 0.0, 0.0, 0.0 }
N[axis] = O[axis] - planes[idx][1]
Return(normalize3(N))
EndFunction
Function surfaceNormal(Typ, index, P, Inside)
If Typ = 0
Return(sphereNormal(index, P))
Else
Return(planeNormal(index, P, Inside))
EndIf
EndFunction
Function lightObject(Typ, idx, P, lightAmbient)
Local i = lightDiffuse(surfaceNormal(Typ, idx, P, Light), P)
Return(Min(1.0, Max(i, lightAmbient)))
EndFunction
Function raytrace(ray, origin)
gIntersect = False
gDist = 999999.9
For Local t = 0 To nrTypes - 1 Step 1
For Local i = 0 To nrObjects[t] - 1 Step 1
rayObject(t, i, ray, origin)
Next
Next
EndFunction
Function computePixelColor(x, y)
Local rgbc = { 0.0, 0.0, 0.0 }
Local ray = { x/szImg - 0.5, - (y/szImg - 0.5), 1.0 }
raytrace(ray, gOrigin)
If gIntersect
gPoint = mul3c(ray, gDist)
If gType = 0 And gIndex = 1
ray = reflect(ray, gOrigin)
raytrace(ray, gPoint)
If gIntersect Then gPoint = add3(mul3c(ray, gDist), gPoint)
EndIf
If lightPhotons
rgbc = gatherPhotons(gPoint, gType, gIndex)
Else
Local tType = gType
Local tIndex = gIndex
Local i = gAmbient
raytrace(sub3(gPoint, Light), Light)
If tType = gType And tIndex = gIndex Then i = lightObject(gType, gIndex, gPoint, gAmbient)
rgbc[0] = i
rgbc[1] = i
rgbc[2] = i
rgbc = GetColorRGB(rgbc, tType, tIndex)
EndIf
EndIf
Return(rgbc)
EndFunction
Function reflect(ray, fromPoint)
Local N = surfaceNormal(gType, gIndex, gPoint, fromPoint)
Return(normalize3(Sub3(ray, mul3c(N, (2.0 * dot3(ray, N))))))
EndFunction
Function gatherPhotons(p, Typ, id)
Local energy = { 0.0, 0.0, 0.0 }
Local N = surfaceNormal(Typ, id, p, gOrigin)
For Local i = 0 To numPhotons[Typ][id] - 1 Step 1
If gatedSqDist3(p, photons[Typ][id][i][0], sqRadius)
Local weight = Max(0.0, -dot3(N, photons[Typ][id][i][1]))
weight = weight * (1.0 - Sqrt(gSqDist)) / exposure
energy = add3(energy, mul3c(photons[Typ][id][i][2], weight))
EndIf
Next
Return(energy)
EndFunction
Function emitPhotons()
;SeedRnd(0) ; Sorry, no equilevant in Hollywood you get different photons on every run
For Local t = 0 To nrTypes - 1 Step 1
For Local i = 0 To nrObjects[t] - 1 Step 1
numPhotons[t][i] = 0
Next
Next
Local test = nrPhotons
If view3D Then test = nrPhotons * 3.0
For Local i = 0 To test - 1 Step 1
Local bounces = 1
Local rgbc = { 1.0, 1.0, 1.0 }
Local ray = normalize3(rand3(1.0))
Local prevPoint = CopyTable(Light)
While prevPoint[1] >= Light[1]
prevPoint = add3(Light, mul3c(normalize3(rand3(1.0)), 0.75))
Wend
If Abs(prevPoint[0]) > 1.5 Or Abs(prevPoint[1]) > 1.2 Or gatedSqDist3(prevPoint, spheres[0], spheres[0][3]* spheres[0][3]) Then bounces = nrBounces + 1
raytrace(ray, prevPoint)
While gIntersect And bounces <= nrBounces
gPoint = add3(mul3c(ray, gDist), prevPoint)
rgbc = mul3c(GetColorRGB(rgbc, gType, gIndex), 1.0 / Sqrt(bounces))
storePhoton(gType, gIndex, gPoint, ray, rgbc)
drawPhoton(rgbc, gPoint)
;shadowPhoton(ray)
ray = reflect(ray, prevPoint)
raytrace(ray, gPoint)
prevPoint = CopyTable(gPoint)
bounces = bounces + 1
Wend
Next
EndFunction
Function storePhoton(Typ, id, location, direction, energy)
photons[Typ][id][numPhotons[Typ][id]][0] = CopyTable(location)
photons[Typ][id][numPhotons[Typ][id]][1] = CopyTable(direction)
photons[Typ][id][numPhotons[Typ][id]][2] = CopyTable(energy)
numPhotons[Typ][id] = numPhotons[Typ][id] + 1
EndFunction
Function shadowPhoton(ray)
Local shadow = { -0.25, -0.25, -0.25 }
Local bumpedPoint = add3(gPoint, mul3c(ray, 0.00001))
raytrace(ray, bumpedPoint)
Local shadowPoint = add3(mul3c(ray, gDist), bumpedPoint)
storePhoton(gType, gIndex, shadowPoint, ray, shadow)
EndFunction
Function filterColor(rgbIn, r, g, b)
Local rgbOut = { r, g, b }
For Local c = 0 To 2
rgbOut[c] = Min(rgbOut[c], rgbIn[c])
Next
Return(rgbOut)
EndFunction
Function GetColorRGB(rgbIn, Typ, index)
If Typ = 1 And index = 0
Return(filterColor(rgbIn, 0.0, 1.0, 0.0))
ElseIf Typ = 1 And index = 2
Return(filterColor(rgbIn, 1.0, 0.0, 0.0))
Else
Return(filterColor(rgbIn, 1.0, 1.0, 1.0))
EndIf
EndFunction
Function normalize3(v)
Local L = Sqrt(dot3(v, v))
Return(mul3c(v, 1.0 / L))
EndFunction
Function sub3(a, b)
Local result = { a[0] - b[0], a[1] - b[1], a[2] - b[2] }
Return(result)
EndFunction
Function add3(a, b)
Local result = { a[0] + b[0], a[1] + b[1], a[2] + b[2] }
Return(result)
EndFunction
Function mul3c(a, c)
Local result = { c * a[0], c * a[1], c * a[2] }
Return(result)
EndFunction
Function dot3(a, b)
Local result = a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
Return(result)
EndFunction
Function rand3(s)
Local s2 = s * 2
Local r = { RndF() * s2 - s, RndF() * s2 - s, RndF() * s2 - s }
Return(r)
EndFunction
Function gatedSqDist3(a, b, sqradius)
Local c = a[0] - b[0]
Local d = c * c
If d > sqradius Then Return(False)
c = a[1] - b[1]
d = d + c * c
If d > sqradius Then Return(False)
c = a[2] - b[2]
d = d + c * c
If d > sqradius Then Return(False)
gSqDist = d
Return(True)
EndFunction
Function odd(x)
Return(x & 1)
EndFunction
Global empty = True
Global view3D = False
Global pRow, pCol, pIteration, pMax
Function draw()
If view3D
If empty
Cls
;drawInterface()
emitPhotons()
empty = False
EndIf
Else
If empty
render()
xx = xx + 1
If xx > 10
xx = 0
yy = yy + 1
;DebugPrint(pMax, pRow)
EndIf
EndIf
EndIf
EndFunction
Function render()
Local x, y
Local iterations = 0
Local rgbc = { 0.0, 0.0, 0.0 }
Local imax = Max(pMax, 256)
If mouseDragging Then imax = 1024
While iterations < imax
If pCol >= pMax
pRow = pRow + 1
pCol = 0
If pRow >= pMax
pIteration = pIteration + 1
pRow = 0
pMax = Int(2^pIteration)
EndIf
EndIf
Local pNeedDrawing = 0
If pIteration = 1 Or odd(pRow) Or ((Not odd(pRow)) And odd(pCol)) Then pNeedDrawing = 1
x = pCol * (szImg/pMax)
y = pRow * (szImg/pMax)
pCol = pCol + 1
If pNeedDrawing
iterations = iterations + 1
rgbc = mul3c(computePixelColor(x, y), 255.0)
Local col = RGB(rgbc[0],rgbc[1], rgbc[2])
SetFillStyle(#FILLCOLOR)
Box(x, y, (szImg/pMax), (szImg/pMax), col)
EndIf
Wend
If pRow = szImg - 1 Then empty = False
EndFunction
Function resetRender()
pRow = 0
pCol = 0
pIteration = 1
pMax = 2
empty = True
If lightPhotons And Not view3D Then emitPhotons()
EndFunction
Function drawPhoton(rgbc, p)
If view3D And p[2] > 0.0
Local x = (szImg/2) + Int(szImg * p[0] / p[2])
Local y = (szImg/2) + Int(szImg * -p[1] / p[2])
If y <= szImg
Local col = RGB(255.0 * rgbc[0], 255.0 * rgbc[1], 255.0 * rgbc[2])
Plot(x, y, col)
EndIf
EndIf
EndFunction
Global MouseDragging = False
Function GrabObject()
SphereIndex = 2 ; Default to lightsource
; Try to project screen coords to world space
Local mx = (MouseX() - (szImg/2))/(szImg/2)
Local my = -(MouseY() - (szImg/2))/(szImg/2)
Local mouse3 = { mx, my, (0.5 * (spheres[0][2] + spheres[1][2])) }
If (gatedSqDist3(mouse3,spheres[0],spheres[0][3]))
sphereIndex = 0
ElseIf gatedSqDist3(mouse3,spheres[1],spheres[1][3])
sphereIndex = 1
EndIf
mouseDragging = True
EndFunction
; Simple hack for dragging, try to project screen coords to world space
Function DragObject()
If sphereIndex < nrObjects[0] ; Drag Sphere
spheres[sphereIndex][0] = ((MouseX() - (szImg/2)) /(szImg/2))/0.5
spheres[sphereIndex][1] = -((MouseY() - (szImg/2))/(szImg/2))/0.5
Else ;Drag Light
Light[0] = ((MouseX() - (szImg/2))/(szImg/2))/0.5
Light[1] = -((MouseY() - (szImg/2))/(szImg/2))/0.5
EndIf
resetRender()
EndFunction
EscapeQuit(True)
emitPhotons()
resetRender()
BeginDoubleBuffer()
Repeat
If IsLeftMouse()
If Not MouseDragging
GrabObject()
Else
DragObject()
EndIf
Else
MouseDragging = False
EndIf
draw()
Flip()
Forever
Re: Ray Tracing and Photon Mapping
Yeah... It is to beautiful... i love that
Respect
Respect