Raytracer
Übersicht BlitzBasic
 BlitzBasic  Codearchiv
 Codearchiv|   | Mr.KeksBetreff: Raytracer |  Di, Dez 28, 2004 17:20 Antworten mit Zitat   | 
|---|---|---|
| Ich bin heute zufällig über einen alten Code von mir gestolpert. Ich habe jetzt ein wenig dran rumgebastelt und von einer gewissen Tiefenungenauigkeit abgesehen, ist es nichtmal so schlecht finde ich.     Features: - unflexibel - eklige Kanten durch zu wenig Substeps - unheimlich lahm   - Licht/Schatten - 2x2-Antialias - Kugeln - Würfel - Plane - weder dreh- noch skalierbar - keine Texturen, dafür schön bunt - Ein paar hübsche Debug-Kreise vor dem Rendern. WARNUNG: WENN IHR WÄHREND DES RENDERNS WAS ANDERES MIT EUREM PC MACHT, KANN ES ZU EINEM PROGRAMMABSTURZ (ODER MEHR?) KOMMEN! (Danke an Trash, der es freundlicherweise ausprobiert hat.) Code: [AUSKLAPPEN] Type entity
 Field x#,y#,z# Field sx#=1,sy#=1,sz#=1 Field typ Field rad Field col End Type Type light Field e.entity End Type Global width = 160, hwidth = width/2 Global height= 120, hheight= height/2 Global amb_r = 150 Global amb_g = 130 Global amb_b = 80 Graphics width,height,32,3 AddEntity(0,-13,1,2,0,$707070) ; Plane erstellen AddEntity(0,0,91,1,10,$000099) ; Blaue Kugel erstellen AddEntity(10,0,40,1,10,$990000) ; Rote Kugel erstellen AddEntity(-10,-8,65,1,10,$009900) ; Grüne Kugel AddEntity(-4,-8,35,4,3,$ffff00) ; Gelber Würfel AddEntity(5,50,60,3,120,$9099F0) ; Licht (blau) AddEntity(-25,20,60,3,120,$f0a010) ; Licht (orange) DrawPreview() WaitKey() RayTrace() WaitKey() SaveBuffer FrontBuffer(),"rendered.bmp" Function AddEntity(x#,y#,z#,typ,rad,col) e.entity= New entity e\x = x e\y = y e\z = z e\typ = typ e\rad = rad e\col = col Select e\typ Case 3 ; licht l.light = New light l\e = e End Select Return Handle(e) End Function Function DrawPreview() For e.entity = Each entity x# = e\x / e\z *100 y# = e\y / e\z *100 rad# = Float(e\rad) / Float(e\z) * 100 Color 0,0,e\col Select e\typ Case 1 Oval hwidth+x-rad, hheight-y-rad, rad*2,rad*2,0 Case 2 If y < 0 Rect 0,hheight,width,hheight ElseIf y > 0 Rect 0,0,width,hheight EndIf End Select Next End Function Function RayTrace() LockBuffer FrontBuffer() For x = 0 To width-1 For y = 0 To height-1 ; Antialias col1 = SendRay(x-.25,y-.25) col2 = SendRay(x+.25,y-.25) col3 = SendRay(x-.25,y+.25) col4 = SendRay(x+.25,y+.25) r=(((col1 And $FF0000)/$10000)+((col2 And $FF0000)/$10000)+((col3 And $FF0000)/$10000)+((col4 And $FF0000)/$10000))/4.0 g=(((col1 And $FF00)/$100)+((col2 And $FF00)/$100)+((col3 And $FF00)/$100)+((col4 And $FF00)/$100))/4.0 b=((col1 And $FF)+(col2 And $FF)+(col3 And $FF)+(col4 And $FF))/4.0 col= r*$10000 + g*$100 + b WritePixelFast x,y,col,FrontBuffer() Next AppTitle Int(Float(x)/Float(width)*100.00)+"%" Next UnlockBuffer FrontBuffer() End Function Function SendRay(x1#,y1#) vx# = (x1-hwidth)/width;Cos((x1-hwidth)*180/width) vy# = -.5-(y1-height)/height*.8;Cos((height-y1)*135/height) vz# = 1;-(vx+vy)/2 Local x#,y#,z# ;x = x1 ;y = y1 range = 400 Repeat i = i + 1 x = x + vx y = y + vy z = z + vz eh = GetColl(x,y,z) If eh <> 0 n# = -.5 Repeat ; positionsgenauigkeit (Zahlenraten =)) x = x + vx * n y = y + vy * n z = z + vz * n kol = GetColl(x,y,z) If kol n = -Abs(n)/2 Else n = Abs(n)/2 EndIf Until Abs(n)<.005 e.entity = Object.entity(eh) col = e\col bright_r# = amb_r bright_g# = amb_g bright_b# = amb_b For l.light = Each light vis = GetVisible(l\e\x,l\e\y,l\e\z, x,y,z, 3) bright_r# = bright_r# + ((l\e\col And $FF0000)/$10000)*vis bright_g# = bright_g# + ((l\e\col And $FF00)/$100)*vis bright_b# = bright_b# + ((l\e\col And $FF))*vis Next r=((col And $FF0000)/$10000)*(range-i)/range * bright_r/255 g=((col And $FF00)/$100)*(range-i)/range * bright_g/255 b=(col And $FF)*(range-i)/range * bright_b/255 If r > 255 Then r = 255 If g > 255 Then g = 255 If b > 255 Then b = 255 col= r*$10000 + g*$100 + b i = range EndIf Until i >= range Return col End Function Function GetVisible(x1#,y1#,z1#, x2#,y2#,z2#, detail#=1) dist#= CDist#(x1#,y1#,z1#,x2#,y2#,z2#) x# = x1# y# = y1# z# = z1# vx# = (-x1#+x2#)/dist#/detail# vy# = (-y1#+y2#)/dist#/detail# vz# = (-z1#+z2#)/dist#/detail# Repeat i = i + 1 x = x + vx y = y + vy z = z + vz eh = GetColl(x,y,z,.2) If eh <> 0 Return 0 EndIf Until i >= dist*detail-2 Return 1 End Function Function GetColl(x#,y#,z#,tollerance#=0) ; zero tollerance ;) For e.entity = Each entity Select e\typ Case 1 If CDist(e\x,e\y,e\z,x,y,z) < e\rad-tollerance# Then Return Handle(e) Case 2 If y+1 > e\y+tollerance# And y-1 < e\y-tollerance# Then Return Handle(e) Case 3 Case 4 If Abs(e\x-x) < e\rad-tollerance# And Abs(e\y-y) < e\rad-tollerance# And Abs(e\z-z) < e\rad-tollerance# Then Return Handle(e) EndIf End Select Next End Function Function CDist#(x1#,y1#,z1#,x2#,y2#,z2#) Return Sqr(((x1-x2)^2)+(y1-y2)^2+(z1-z2)^2) End Function | ||
| MrKeks.net | ||
- Zuletzt bearbeitet von Mr.Keks am Di, Dez 28, 2004 18:19, insgesamt einmal bearbeitet
|   | maximilian |  Di, Dez 28, 2004 17:44 Antworten mit Zitat   | 
|---|---|---|
| ZIEMLICH cool, aber ich blicke da überhaupt nicht durch!   Dachte, das Thema wäre so undurchsichtig, dass das jemand aus dieser Community schaffen würde.  Habe ich mich wohl geirrt.   Wie wärs mit Texture Mapping? LordChaos | ||
| Variety is the spice of life. One day ignore people, next day annoy them. | ||
|   | Vertex |  Di, Dez 28, 2004 18:32 Antworten mit Zitat   | 
|---|---|---|
| Fetten Respekt! Dürfte Backward Raytracing sein ,oder? Erklähr mal ein wenig wie das ding funktioniert. mfg olli | ||
| vertex.dreamfall.at | GitHub | ||
|   | Mr.Keks |  Di, Dez 28, 2004 19:56 Antworten mit Zitat   | 
|---|---|---|
| es ist eigentlich nichts besonders tolles =). es werden einfach rays für jeden pixel ausgesandt. wenn die etwas treffen, dann spielt das programm zahlenraten, um die ziemlich großen abstände, in denen auf kollision geprüft wird, zu kompensieren. [hätte ich es mir umständlich machen wollen, hätte ich natürlich auch nach schnittpunktformeln suchen können  .] so ermittelt das programm also die halbwegs genaue kollisionsposition. mit der kann man allehand anstellen, indem man weitere rays durch die gegend jagt: schatten, spiegelungen, glanz, brechungen (die sind wohl das schwierigste bei meiner methode..). ich habe jetzt erstmal nur schatten eingebaut. es wird einfach nur eine art entityvisible zwischen dem punkt der lichtquelle und dem treffer des letzten pixelrays durchgeführt und dann werden die farben etwas gemischt. das zu coden war ne sache von einem nachmittag. es ist auch nicht für mehr als eine spielerei ausgelegt: das entitysystem ist sehr simpel und es gibt auch keine matrixsachen für drehung und skalierung... wobei ich die vielleicht doch noch einbaue - ist ja nicht sonderlich schwer (man muss nur den auf kollision mit einem objekt zu prüfenden punkt an das objekt anpassen, indem man ihn entgegen den entitymaßen relativ dreht und skaliert - sagt mir zumindest mein krankes hirn ^^...) so, habe jetzt mehr substeps eingebaut. ihre genauigkeit liegt von der entfernung zur cam ab... | ||
| MrKeks.net | ||
|   | Mr.Keks |  Di, Dez 28, 2004 22:57 Antworten mit Zitat   | 
|---|---|---|
| Habe jetzt noch ein wenig was verändert. Neuerungen: - mehr Substeps bei den Schatten - skalierbare Objekte - drehbare Objekte (bis jetzt nur an y-Achse) - deutlich langsamer Ich werde mir für die Matrix besonders in Sachen Drehung wohl noch was überlegen müssen. Das verdoppelt nämlich die Renderdauer, weshalb ich in dieser Version nur y-Drehung habe. Ich habe hierzu mal ein paar Zeilen in Vertex' 3d-Lib gelesen (auch meinen Respekt dafür  ) und denke, ich kann mit den Formeln das ganze sehr gut optimieren, wenn ich sie erstmal vollständig durchschaut habe ^^. Wenn ich hiermit fertig bin, möchte ich mit Materialien weitermachen. Habe ich erstmal Formeln für UV-Koordinaten und Normals zu den Grundformen, sind auch Spielereien wie Displacementmapping kein Problem mehr. Außerdem plane ich, auch noch Kegel und Zylinder, die ja auch keinen großen Aufwandt darstellen. Und mir ist eine Idee gekommen, wie ich Booleans und sowas hinbekomme  . (Macht Spaß so ganz ohne Tutorials, nur mit seinem eigenen Kopf bewaffnet. Lege ich auch allen Neulingen ans Herz! Das ist der Sinn des Hobbycodens!) Code: [AUSKLAPPEN] Type entity
 Field x#,y#,z# ; Field sx#=1,sy#=1,sz#=1 ; Matrixkrams Field rx#,ry#,rz# ; Field typ ; 1: Light, 2: Plane, 3: Sphere, 4: Cube, 5: Cylynder, 6: Cone Field rad Field col End Type Type light Field e.entity End Type Global width = 160, hwidth = width/2 Global height= 120, hheight= height/2 Global amb_r = 150 Global amb_g = 130 Global amb_b = 80 Graphics width,height,32,3 AddEntity(0,-13,1,2,0,$707070) ; Plane erstellen AddEntity(0,0,91,3,10,$000099) ; Blaue Kugel erstellen AddEntity(10,0,40,3,10,$990000) ; Rote Kugel erstellen sphere = AddEntity(-10,-8,65,3,10,$009900) ; Grüne Kugel ScaleEnt sphere,1,.5,2 cube = AddEntity(-4,-8,35,4,3,$ffff00) ; Gelber Würfel RotateEnt cube,10,40,0 AddEntity(5,50,60,1,120,$9099F0) ; Licht (blau) AddEntity(-25,20,60,1,120,$f0a010) ; Licht (orange) DrawPreview() WaitKey() RayTrace() WaitKey() SaveBuffer FrontBuffer(),"rendered.bmp" Function AddEntity(x#,y#,z#,typ,rad,col) e.entity= New entity e\x = x e\y = y e\z = z e\sx = 1 e\sy = 1 e\sz = 1 e\typ = typ e\rad = rad e\col = col Select e\typ Case 1 ; licht l.light = New light l\e = e End Select Return Handle(e) End Function Function ScaleEnt(ent,sx#,sy#,sz#) e.entity= Object.entity(ent) e\sx = sx e\sy = sy e\sz = sz End Function Function RotateEnt(ent,rx#,ry#,rz#) e.entity= Object.entity(ent) e\rx = rx e\ry = ry e\rz = rz End Function Function DrawPreview() For e.entity = Each entity x# = e\x / e\z *100 y# = e\y / e\z *100 rad# = Float(e\rad) / Float(e\z) * 100 Color 0,0,e\col Select e\typ Case 3 Oval hwidth+x-rad, hheight-y-rad, rad*2,rad*2,0 Case 2 If y < 0 Rect 0,hheight,width,hheight ElseIf y > 0 Rect 0,0,width,hheight EndIf End Select Next End Function Function RayTrace() LockBuffer FrontBuffer() For x = 0 To width-1 For y = 0 To height-1 ; Antialias col1 = SendRay(x-.25,y-.25) col2 = SendRay(x+.25,y-.25) col3 = SendRay(x-.25,y+.25) col4 = SendRay(x+.25,y+.25) r=(((col1 And $FF0000)/$10000)+((col2 And $FF0000)/$10000)+((col3 And $FF0000)/$10000)+((col4 And $FF0000)/$10000))/4.0 g=(((col1 And $FF00)/$100)+((col2 And $FF00)/$100)+((col3 And $FF00)/$100)+((col4 And $FF00)/$100))/4.0 b=((col1 And $FF)+(col2 And $FF)+(col3 And $FF)+(col4 And $FF))/4.0 col= r*$10000 + g*$100 + b WritePixelFast x,y,col,FrontBuffer() Next AppTitle Int(Float(x)/Float(width)*100.00)+"%" If KeyHit(1) Then Exit Next UnlockBuffer FrontBuffer() End Function Function SendRay(x1#,y1#) vx# = (x1-hwidth)/width;Cos((x1-hwidth)*180/width) vy# = -.5-(y1-height)/height*.8;Cos((height-y1)*135/height) vz# = 1;-(vx+vy)/2 Local x#,y#,z# ;x = x1 ;y = y1 range = 400 Repeat i = i + 1 x = x + vx y = y + vy z = z + vz eh = GetColl(x,y,z) If eh <> 0 n# = -.5 Repeat ; positionsgenauigkeit (Zahlenraten =)) x = x + vx * n y = y + vy * n z = z + vz * n kol = GetColl(x,y,z) If kol n = -Abs(n)/2 Else n = Abs(n)/2 EndIf Until Abs(n)*8<.005*i/100.0 e.entity = Object.entity(eh) col = e\col bright_r# = amb_r bright_g# = amb_g bright_b# = amb_b For l.light = Each light vis = GetVisible(l\e\x,l\e\y,l\e\z, x,y,z, (range-i)*10/range) bright_r# = bright_r# + ((l\e\col And $FF0000)/$10000)*vis bright_g# = bright_g# + ((l\e\col And $FF00)/$100)*vis bright_b# = bright_b# + ((l\e\col And $FF))*vis Next r=((col And $FF0000)/$10000)*(range-i)/range * bright_r/255 g=((col And $FF00)/$100)*(range-i)/range * bright_g/255 b=(col And $FF)*(range-i)/range * bright_b/255 If r > 255 Then r = 255 If g > 255 Then g = 255 If b > 255 Then b = 255 col= r*$10000 + g*$100 + b i = range EndIf Until i >= range Return col End Function Function GetVisible(x1#,y1#,z1#, x2#,y2#,z2#, detail#=1) dist#= CDist#(x1#,y1#,z1#,x2#,y2#,z2#) x# = x1# y# = y1# z# = z1# vx# = (-x1#+x2#)/dist#/detail# vy# = (-y1#+y2#)/dist#/detail# vz# = (-z1#+z2#)/dist#/detail# Repeat i = i + 1 x = x + vx y = y + vy z = z + vz eh = GetColl(x,y,z,.1) If eh <> 0 Return 0 EndIf Until i >= dist*detail-2 Return 1 End Function Function GetColl(x1#,y1#,z1#,tollerance#=0) ; zero tollerance ;) For e.entity = Each entity x# = -x1+e\x x# = x#/e\sx# y# = -y1+e\y y# = y#/e\sy# z# = -z1+e\z z# = z#/e\sz# If e\ry <> 0 angy# = ATan2(x,z)-e\ry disty# = CDist#(0,0,0,x,0,z) x = Cos(angy) * disty z = Sin(angy) * disty EndIf Select e\typ Case 1 Case 2 If y < -tollerance#+1 And y > -1+tollerance# Then Return Handle(e) Case 3 If CDist(0,0,0,x,y,z) < e\rad-tollerance# Then Return Handle(e) Case 4 If Abs(x) < e\rad+tollerance# And Abs(y) < e\rad+tollerance# And Abs(z) < e\rad-tollerance# Then Return Handle(e) EndIf End Select Next End Function Function CDist#(x1#,y1#,z1#,x2#,y2#,z2#) Return Sqr(((x1-x2)^2)+(y1-y2)^2+(z1-z2)^2) End Function | ||
| MrKeks.net | ||
|   | rambo256 |  Di, Dez 28, 2004 23:54 Antworten mit Zitat   | 
|---|---|---|
| Für diejenigen die nich noch längr als bei ersten mal warten wollen/können hier mal ein Screen vom Endprodukt: @Impac (=Inarie  ): Saubere Arbeit  Aber da is noch was am Speed zu machen *rofl*   | ||
| Asus F53z Das Leben ist eine reine Konkatenation... | ||
- Zuletzt bearbeitet von rambo256 am Do, Dez 30, 2004 12:02, insgesamt einmal bearbeitet
|   | Triton |  Mi, Dez 29, 2004 0:25 Antworten mit Zitat   | 
|---|---|---|
| Ich warte jetzt seit 10 min - kommt da noch was? | ||
| Coding: silizium-net.de | Portfolio: Triton.ch.vu | ||
|   | rambo256 |  Mi, Dez 29, 2004 0:27 Antworten mit Zitat   | 
|---|---|---|
| sieht man doch an der Prozentanzeige   wenn die bei >=99 ist,dann kommt da was   | ||
| Asus F53z Das Leben ist eine reine Konkatenation... | ||
|   | fanta@Kacke_am_Dampfen |  Mi, Dez 29, 2004 0:31 Antworten mit Zitat   | 
|---|---|---|
| Ich warte auch schon ewig und da kommt nix mehr und wie hast du das geschafft dass da ne prozentanzeige isch? | ||
|   | Vertex |  Mi, Dez 29, 2004 0:34 Antworten mit Zitat   | 
|---|---|---|
| drücke mal eine taste   | ||
| vertex.dreamfall.at | GitHub | ||
|   | DA |  Mi, Dez 29, 2004 0:34 Antworten mit Zitat   | 
|---|---|---|
| Moin,  http://www.blitzbase.de/befehle2d/apptitle.htm Thx DarkAngel | ||
| Deutscher Blitz Basic Chat | ||
|   | fanta@Kacke_am_Dampfen |  Mi, Dez 29, 2004 0:45 Antworten mit Zitat   | 
|---|---|---|
| Nein ich meinte warum bei ihm eine Prozentzahl erscheint und bei mir nicht, darum war Vertex's Antwort schon richtig. | ||
| lettorTrepuS |  Mi, Dez 29, 2004 9:46 Antworten mit Zitat   | |
|---|---|---|
| -aus Sicherheitsgründen gelöscht- Diese Information ist mit Ihrer Sicherheitsfreigabe leider nicht erhältlich, Bürger. | ||
|   | Mr.Keks |  Mi, Dez 29, 2004 10:03 Antworten mit Zitat   | 
|---|---|---|
| hmm? wo hast du das denn alles gelesen?  ich habe kein assemblerwissen und ich sitze auch noch keine woche dran. das mit dem z-buffer habe ich mir auch schon überlegt... aber er bringt wahrscheinlich eher weniger, da alle berechnungen für jeden pixel durchgeführt werden und ich später nicht mehr darauf zugreife. sinnvoll wäre aber vielleicht ein entitybuffer, für materialabhängigen glow und ähnliche, erst nach dem rendern erfolgende berechnungen. dreiecke sind - wie du schon sagtest - ziemlich lahm und mit meiner rendermethode auch ziemlich ungünstig... da hätte ich besser mit strahlen/form-schnittpunkt-formeln arbeiten müssen. | ||
| MrKeks.net | ||
| lettorTrepuS |  Mi, Dez 29, 2004 12:46 Antworten mit Zitat   | |
|---|---|---|
| -aus Sicherheitsgründen gelöscht- Diese Information ist mit Ihrer Sicherheitsfreigabe leider nicht erhältlich, Bürger. | ||
| Gombolo |  Mi, Dez 29, 2004 12:58 Antworten mit Zitat   | |
|---|---|---|
| Ausser spielereien ist zu Zeit nicht viel möglich mit dieser Technik. Jemand hat mal die Quake Engine auf Raytracing umgebaut. Er benutzt 20 AMD Rechner um das ganze in Realtime spielen zu können   http://graphics.cs.uni-sb.de/~sidapohl/egoshooter/ Hardware: http://www.saarcor.de/ Hier gibt es mehr. http://graphics.cs.uni-sb.de/RTGames/ | ||
| Heute ist der erste Tag vom Rest deines Lebens http://gombolo.go.funpic.de/ | ||
| lettorTrepuS |  Mi, Dez 29, 2004 18:59 Antworten mit Zitat   | |
|---|---|---|
| -aus Sicherheitsgründen gelöscht- Diese Information ist mit Ihrer Sicherheitsfreigabe leider nicht erhältlich, Bürger. | ||
|   | Mr.Keks |  Mi, Dez 29, 2004 23:32 Antworten mit Zitat   | 
|---|---|---|
| ... Das ist nun aber eher OT!     na, wer kann erkennen, was auf der Sphere steht?!   P.S.: Ich heiße BTW auch nicht Impac... Nichtmal INpac heißt Impac..   | ||
| MrKeks.net | ||
|   | rambo256 |  Do, Dez 30, 2004 12:00 Antworten mit Zitat   | 
|---|---|---|
| [ot] sry,neue Tastatur,neues Gefühl,also entschuldigt bitte,wenn ich in der nächsten woche noch ein paar Rechtschreibfehler hab... [/ot] Yeah Inarie rulez   | ||
| Asus F53z Das Leben ist eine reine Konkatenation... | ||
| David |  Do, Dez 30, 2004 12:09 Antworten mit Zitat   | |
|---|---|---|
| Hi! Gombolo hat Folgendes geschrieben: Ausser spielereien ist zu Zeit nicht viel möglich mit dieser Technik. 
 Was heist hier Spielereien??? Mit Raytracing kann man viel machen, nicht nur Spielereien. Ach, Quake3 Raytraced... Ich mags nicht! Sieht nich schön aus, wie ich finde...   grüße | ||
Übersicht
 BlitzBasic
 BlitzBasic  Codearchiv
 Codearchiv
					Powered by phpBB © 2001 - 2006, phpBB Group
				



