Ray Tracing and Photon Mapping

Discuss any general programming issues here
Post Reply
jalih
Posts: 276
Joined: Fri Jun 18, 2010 8:08 pm
Location: Finland

Ray Tracing and Photon Mapping

Post by jalih »

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...
jalih
Posts: 276
Joined: Fri Jun 18, 2010 8:08 pm
Location: Finland

Re: Ray Tracing and Photon Mapping

Post by jalih »

Photon mapping still needs some work but now spheres and light source can be dragged around in view...
jalih
Posts: 276
Joined: Fri Jun 18, 2010 8:08 pm
Location: Finland

Re: Ray Tracing and Photon Mapping

Post by jalih »

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...

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
User avatar
airsoftsoftwair
Posts: 5443
Joined: Fri Feb 12, 2010 2:33 pm
Location: Germany
Contact:

Re: Ray Tracing and Photon Mapping

Post by airsoftsoftwair »

Interesting, but of course a little bit slow :)
ArtBlink
Posts: 484
Joined: Mon Nov 01, 2010 10:37 am
Location: Albert - France
Contact:

Re: Ray Tracing and Photon Mapping

Post by ArtBlink »

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%)
ArtBlink
Posts: 484
Joined: Mon Nov 01, 2010 10:37 am
Location: Albert - France
Contact:

Re: Ray Tracing and Photon Mapping

Post by ArtBlink »

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...
jalih
Posts: 276
Joined: Fri Jun 18, 2010 8:08 pm
Location: Finland

Re: Ray Tracing and Photon Mapping

Post by jalih »

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!

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
ArtBlink
Posts: 484
Joined: Mon Nov 01, 2010 10:37 am
Location: Albert - France
Contact:

Re: Ray Tracing and Photon Mapping

Post by ArtBlink »

Yeah... It is to beautiful... i love that ;-)

Respect
Post Reply