Software Renderer



  • ... oben geändert


  • Mod

    xindon schrieb:

    // Get window coordinates
    	*dst_x = (int)((clipCoords.x + 1.0f) * (this->viewportWidth / 2.0f) + this->viewportLeft);
    	*dst_y = (int)((clipCoords.y + 1.0f) * (this->viewportHeight / 2.0f) + this->viewportBottom);
    }
    

    das glaub ich nicht Tim 😉
    *0.5+0.5f, dann sind die 0 bis 1 und dann * widht bzw height
    dein + * + kann ich nicht so recht nachvollziehen

    greets
    rapso



  • Ich hab das vom DGL Wiki: http://wiki.delphigl.com/index.php/GlViewport

    edit: Habs geändert, kommt exakt das selbe raus 🙂 Wenn dus ausmultiplizierst, siehstes 😉 Es ist letztendlich das selbe.

    Ich fass meine Fragen am besten nochmal zusammen 🙂 ... :

    1. Stimmt der Weg vom Vertex zum Pixel soweit (TransformVertex Methode)

    2. Ist der Bildschirmursprung unten links oder oben links?

    3. Setzen der Projektionsmatrix korrekt?

    Vielen Dank für Antworten 🙂





  • Hier mal mein Softwarerenderer aber in einer anderen Sprache:

    ; - Constants / Globals ------------------------------------
    ; Matrices
    Const SR_MODELVIEW  = 1
    Const SR_PROJECTION = 2
    
    ; Depthrange Far / Near
    Global gDepthRange#[1]
    
    ; Viewport X, Y, Width, Height
    Global gViewport[3]
    
    ; Matrices
    Global gModelview.TMatrix
    Global gProjection.TMatrix
    Global gMatrixMode
    Global gActMatrix.TMatrix
    
    ; Vertexpipeline
    Global gObject.TVector
    Global gEye.TVector
    Global gClip.TVector
    Global gDevice.TVector
    Global gWindow.TVector
    
    ; Temp
    Global gTmpVector.TVector
    Global gTmpMatrix.TMatrix
    Global gTmpMatrix2.TMatrix
    ; ----------------------------------------------------------
    
    ; - Functions ----------------------------------------------
    Function srInit()
    	gDepthRange[0] = 0.0
    	gDepthRange[1] = 1.0
    
    	gViewport[0] = 0
    	gViewport[1] = 0
    	gViewport[2] = GraphicsWidth()
    	gViewport[3] = GraphicsHeight()
    
    	gModelview  = New TMatrix
    	gProjection = New TMatrix
    	gMatrixMode = SR_MODELVIEW
    	gActMatrix  = gModelview
    
    	gObject = New TVector
    	gEye    = New TVector
    	gClip   = New TVector
    	gDevice = New TVector
    	gWindow = New TVector
    
    	gTmpVector  = New TVector
    	gTmpMatrix  = New TMatrix
    	gTmpMatrix2 = New TMatrix
    End Function
    
    Function srDestroy()
    	Delete gModelview
    	Delete gProjection
    	Delete gActMatrix
    
    	Delete gObject
    	Delete gEye
    	Delete gClip
    	Delete gDevice
    	Delete gWindow
    
    	Delete gTmpVector
    	Delete gTmpMatrix
    	Delete gTmpMatrix2
    End Function
    
    Function srDepthRange(Near#, Far#)
    	If Near < 0.0 Then Near = 0.0
    	If Near > 1.0 Then Near = 1.0
    	gDepthRange[0] = Near
    
    	If Far < 0.0 Then Far = 0.0
    	If Far > 1.0 Then Far = 1.0
    	gDepthRange[1] = Far
    End Function
    
    Function srViewport(X, Y, Width, Height)
    	gViewport[0] = X
    	gViewport[1] = X
    	gViewport[2] = Width
    	gViewport[3] = Height
    End Function
    
    Function srMatrixMode(Mode)
    	Select Mode
    		Case SR_MODELVIEW
    			gActMatrix = gModelview
    
    		Case SR_PROJECTION
    			gActMatrix = gProjection
    
    		Default
    			RuntimeError("Matrix mode does not exist")
    	End Select
    
    	gMatrixMode = Mode
    End Function
    
    Function srLoadIdentity()
    	MatrixIdentity(gActMatrix)
    End Function
    
    Function srRotate(Angle#, X#, Y#, Z#)
    	MatrixRotate(gTmpMatrix2, Angle, X, Y, Z)
    	MatrixMatrixMultiply(gTmpMatrix2, gActMatrix, gActMatrix)
    End Function
    
    Function srTranslate(X#, Y#, Z#)
    	MatrixTranslate(gTmpMatrix2, X, Y, Z)
    	MatrixMatrixMultiply(gTmpMatrix2, gActMatrix, gActMatrix)
    End Function
    
    Function srScale(X#, Y#, Z#)
    	MatrixScale(gTmpMatrix2, X, Y, Z)
    	MatrixMatrixMultiply(gTmpMatrix2, gActMatrix, gActMatrix)
    End Function
    
    Function srPerspective(Zoom#, Aspect#, Far#, Near#)
    	MatrixPerspective(gTmpMatrix2, Zoom, Aspect, Far, Near)
    	MatrixMatrixMultiply(gTmpMatrix2, gActMatrix, gActMatrix)
    End Function
    
    Function srDebugMatrix()
    	MatrixDebug(gActMatrix)
    End Function
    
    Function srVertex(X#, Y#, Z#, W#=1.0)
    	gObject\X = X
    	gObject\Y = Y
    	gObject\Z = Z
    	gObject\W = W
    	srVertexProcessor()
    End Function
    
    Function srDrawVertex()
    	WritePixel(gWindow\X, gWindow\Y, $FFFFFF)
    End Function
    
    Function srVertexProcessor()
    	Local OX, OY
    
    	; Eye = M x Object
    	MatrixVectorMultiply(gModelview, gObject, gEye)
    
    	; Clip = P x Object
    	MatrixVectorMultiply(gProjection, gEye, gClip)
    
    	; Normalized Device Coords
    	gDevice\X = gClip\X/gClip\W
    	gDevice\Y = gClip\Y/gClip\W
    	gDevice\Z = gClip\Z/gClip\W
    
    	; Viewport transformation
    	OX = gViewport[2]/2 + gViewport[0]
    	OY = gViewport[3]/2 + gViewport[1]
    
    	gWindow\X = (gViewport[2]/2.0)*gDevice\X + OX
    	gWindow\Y = (gViewport[3]/2.0)*-gDevice\Y + OY
    	gWindow\Z = ((gDepthRange[1] - gDepthRange[0])/2.0)*gDevice\Z + (gDepthRange[0] + gDepthRange[1])/2.0
    End Function
    ; ----------------------------------------------------------
    
    ; - Math ---------------------------------------------------
    Type TVector
    	Field X#
    	Field Y#
    	Field Z#
    	Field W#
    End Type
    
    Type TMatrix
    	Field AA#, AB#, AC#, AD#
    	Field BA#, BB#, BC#, BD#
    	Field CA#, CB#, CC#, CD#
    	Field DA#, DB#, DC#, DD#
    End Type
    
    Function MatrixIdentity(M.TMatrix)
    	M\AA = 1.0 : M\AB = 0.0 : M\AC = 0.0  : M\AD = 0.0
    	M\BA = 0.0 : M\BB = 1.0 : M\BC = 0.0  : M\BD = 0.0
    	M\CA = 0.0 : M\CB = 0.0 : M\CC = 1.0  : M\CD = 0.0
    	M\DA = 0.0 : M\DB = 0.0 : M\DC = 0.0  : M\DD = 1.0
    End Function
    
    Function MatrixRotate(M.TMatrix, Angle#, X#, Y#, Z#)
    	Local C#, S#, RLength#
    
    	C = Cos(Angle)
    	S = Sin(Angle)
    
    	; Normalize Vector
    	RLength = 1.0/Sqr(X*X + Y*Y + Z*Z)
    	X = X*RLength
    	Y = Y*RLength
    	Z = Z*RLength
    
    	M\AA = X*X*(1.0 - C) + C
    	M\AB = X*Y*(1.0 - C) - Z*S
    	M\AC = X*Z*(1.0 - C) + Y*S
    	M\AD = 0.0
    
    	M\BA = Y*X*(1.0 - C) + Z*S
    	M\BB = Y*Y*(1 - C) + C
    	M\BC = Y*Z*(1.0 - C) - X*S
    	M\BD = 0.0
    
    	M\CA = X*Z*(1.0 - C) - Y*S
    	M\CB = Y*Z*(1.0 - C) + X*S
    	M\CC = Z*Z*(1.0 - C) + C
    	M\CD = 0.0
    
    	M\DA = 0.0
    	M\DB = 0.0
    	M\DC = 0.0
    	M\DD = 1.0
    End Function
    
    Function MatrixTranslate(M.TMatrix, X#, Y#, Z#)
    	M\AA = 1.0 : M\AB = 0.0 : M\AC = 0.0  : M\AD = X
    	M\BA = 0.0 : M\BB = 1.0 : M\BC = 0.0  : M\BD = Y
    	M\CA = 0.0 : M\CB = 0.0 : M\CC = 1.0  : M\CD = Z
    	M\DA = 0.0 : M\DB = 0.0 : M\DC = 0.0  : M\DD = 1.0
    End Function
    
    Function MatrixScale(M.TMatrix, X#, Y#, Z#)
    	M\AA = X   : M\AB = 0.0 : M\AC = 0.0  : M\AD = 0.0
    	M\BA = 0.0 : M\BB = Y   : M\BC = 0.0  : M\BD = 0.0
    	M\CA = 0.0 : M\CB = 0.0 : M\CC = Z    : M\CD = 0.0
    	M\DA = 0.0 : M\DB = 0.0 : M\DC = 0.0  : M\DD = 1.0
    End Function
    
    Function MatrixPerspective(M.TMatrix, Zoom#, Aspect#, Near#, Far#)
    	M\AA = Zoom/Aspect : M\AB = 0.0  : M\AC = 0.0                       : M\AD = 0.0
    	M\BA = 0.0         : M\BB = Zoom : M\BC = 0.0                       : M\BD = 0.0
    	M\CA = 0.0         : M\CB = 0.0  : M\CC = (Far + Near)/(Near - Far) : M\CD = (2.0*Far*Near) / (Near - Far)
    	M\DA = 0.0         : M\DB = 0.0  : M\DC = -1.0                      : M\DD = 0.0
    End Function
    
    Function MatrixDebug(M.TMatrix)
    	DebugLog M\AA + " " + M\AB + " " + M\AC + " " + M\AD
    	DebugLog M\BA + " " + M\BB + " " + M\BC + " " + M\BD
    	DebugLog M\CA + " " + M\CB + " " + M\CC + " " + M\CD
    	DebugLog M\DA + " " + M\DB + " " + M\DC + " " + M\DD
    End Function
    
    Function MatrixMatrixMultiply(X.TMatrix, Y.TMatrix, R.TMatrix)
    	gTmpMatrix\AA = X\AA*Y\AA + X\AB*Y\BA + X\AC*Y\CA + X\AD*Y\DA
    	gTmpMatrix\AB = X\AA*Y\AB + X\AB*Y\BB + X\AC*Y\CB + X\AD*Y\DB
    	gTmpMatrix\AC = X\AA*Y\AC + X\AB*Y\BC + X\AC*Y\CC + X\AD*Y\DC
    	gTmpMatrix\AD = X\AA*Y\AD + X\AB*Y\BD + X\AC*Y\CD + X\AD*Y\DD
    
    	gTmpMatrix\BA = X\BA*Y\AA + X\BB*Y\BA + X\BC*Y\CA + X\BD*Y\DA
    	gTmpMatrix\BB = X\BA*Y\AB + X\BB*Y\BB + X\BC*Y\CB + X\BD*Y\DB
    	gTmpMatrix\BC = X\BA*Y\AC + X\BB*Y\BC + X\BC*Y\CC + X\BD*Y\DC
    	gTmpMatrix\BD = X\BA*Y\AD + X\BB*Y\BD + X\BC*Y\CD + X\BD*Y\DD
    
    	gTmpMatrix\CA = X\CA*Y\AA + X\CB*Y\BA + X\CC*Y\CA + X\CD*Y\DA
    	gTmpMatrix\CB = X\CA*Y\AB + X\CB*Y\BB + X\CC*Y\CB + X\CD*Y\DB
    	gTmpMatrix\CC = X\CA*Y\AC + X\CB*Y\BC + X\CC*Y\CC + X\CD*Y\DC
    	gTmpMatrix\CD = X\CA*Y\AD + X\CB*Y\BD + X\CC*Y\CD + X\CD*Y\DD
    
    	gTmpMatrix\DA = X\DA*Y\AA + X\DB*Y\BA + X\DC*Y\CA + X\DD*Y\DA
    	gTmpMatrix\DB = X\DA*Y\AB + X\DB*Y\BB + X\DC*Y\CB + X\DD*Y\DB
    	gTmpMatrix\DC = X\DA*Y\AC + X\DB*Y\BC + X\DC*Y\CC + X\DD*Y\DC
    	gTmpMatrix\DD = X\DA*Y\AD + X\DB*Y\BD + X\DC*Y\CD + X\DD*Y\DD
    
    	R\AA = gTmpMatrix\AA : R\AB = gTmpMatrix\AB : R\AC = gTmpMatrix\AC : R\AD = gTmpMatrix\AD
    	R\BA = gTmpMatrix\BA : R\BB = gTmpMatrix\BB : R\BC = gTmpMatrix\BC : R\BD = gTmpMatrix\BD
    	R\CA = gTmpMatrix\CA : R\CB = gTmpMatrix\CB : R\CC = gTmpMatrix\CC : R\CD = gTmpMatrix\CD
    	R\DA = gTmpMatrix\DA : R\DB = gTmpMatrix\DB : R\DC = gTmpMatrix\DC : R\DD = gTmpMatrix\DD
    End Function
    
    Function MatrixVectorMultiply(A.TMatrix, B.TVector, R.TVector)
    	gTmpVector\X = A\AA*B\X + A\AB*B\Y + A\AC*B\Z + A\AD*B\W
    	gTmpVector\Y = A\BA*B\X + A\BB*B\Y + A\BC*B\Z + A\BD*B\W
    	gTmpVector\Z = A\CA*B\X + A\CB*B\Y + A\CC*B\Z + A\CD*B\W
    	gTmpVector\W = A\DA*B\X + A\DB*B\Y + A\DC*B\Z + A\DD*B\W
    
    	R\X = gTmpVector\X
    	R\Y = gTmpVector\Y
    	R\Z = gTmpVector\Z
    	R\W = gTmpVector\W
    End Function
    ; ----------------------------------------------------------
    
    ; - Example ------------------------------------------------
    Global Angle#, Z#
    Global Stream%, Count%, Index%
    
    Graphics 640, 480, 0, 2
    SetBuffer BackBuffer()
    
    Stream = ReadFile("test.3d")
    Count = ReadInt(Stream)
    
    Dim Vertices#(Count - 1, 2)
    For Index = 0 To Count - 1
    	Vertices(Index, 0) = ReadFloat(Stream)
    	Vertices(Index, 2) = ReadFloat(Stream) ; kleiner Hack, weil 3DS ein anderes koor. system hat
    	Vertices(Index, 1) = ReadFloat(Stream)
    Next
    
    CloseFile Stream
    
    srInit()
    
    srMatrixMode(SR_PROJECTION)
    srLoadIdentity()
    srPerspective(1.0, 640.0/480.0, 0.1, 100.0)
    srDepthRange(0.0, 1.0)
    
    srMatrixMode(SR_MODELVIEW)
    Z = -30.0
    While Not KeyDown(1)
    	Angle = Angle + 2.0
    
    	Cls()
    
    	If KeyDown(200) Then Z = Z - 0.5
    	If KeyDown(208) Then Z = Z + 0.5
    
    	srLoadIdentity()
    	srRotate(Angle, 0.0, 1.0, 0.0)
    	srTranslate(0.0, 0.0, Z)
    
    	For Index = 0 To Count - 1
    		srVertex(Vertices(Index, 0), Vertices(Index, 1), Vertices(Index, 2))
    		srDrawVertex()
    	Next
    
    	Flip(0)
    Wend
    
    End
    ; ----------------------------------------------------------
    

    Ist OpenGL nach empfunden. Kann nur GL_POINTS rendern, wenn man das so will. Mit Scanlineimplentierung sind dann auch schnell Texturemapping, Lighting usw. realisiert, aber keine Zeit dafür 😛 Ist sicher nicht gerade die ideale Sprache dafür, aber das habe ich mal für jemanden als Hilfestellung geschrieben.

    >>Screenshot<<

    mfg olli



  • Okay danke 🙂 Mein Aufbau ist eigentlich der selbe, also hab ich vielleicht irgendwo en kleinen Fehler bei der Matrix Multiplikation oder so, ich schaus mir nochmal an.

    Vielen Dank auf jeden Fall. Ich find' die Sprache nur irgendwie... seltsam 😛



  • Wenn du einen Software Renderer schreiben willst, wie wär's, wenn der auf Raytracing basiert? Wäre auf jeden Fall mal was anderes als gewöhnliche Rasterizer, und wird in Zukunft wahrscheinlich an Bedeutung gewinnen. 🙂


  • Mod

    groovemaster schrieb:

    Wenn du einen Software Renderer schreiben willst, wie wär's, wenn der auf Raytracing basiert? Wäre auf jeden Fall mal was anderes als gewöhnliche Rasterizer

    wieso? die meisten schreiben einen raytracer weil es so trivial ist damit anzufangen, ein guter software renderer ist dagegen sehr selten und komplex.

    und wird in Zukunft wahrscheinlich an Bedeutung gewinnen. 🙂

    glaub nicht jedem marketing 😉



  • rüdiger schrieb:

    Computergrafik | ISBN: 3826609085

    Das Buch kann ich dir nur empfehlen. Das letzte mal als ich es einem Freund empfohlen habe, war es gerade im Ausverkauf bei Amazon für 10€ zu haben, also ein Preis den man nicht bereuen wird.

    http://www.terrashop.info/82660908/artikel.php



  • Blue-Tiger schrieb:

    rüdiger schrieb:

    Computergrafik | ISBN: 3826609085

    Das Buch kann ich dir nur empfehlen. Das letzte mal als ich es einem Freund empfohlen habe, war es gerade im Ausverkauf bei Amazon für 10€ zu haben, also ein Preis den man nicht bereuen wird.

    http://www.terrashop.info/82660908/artikel.php

    Ich hab mir das Buch da schon vorn paar Wochen für die 4€ gekauft 😛



  • Ich hab das Buch auch, allerdings find ich es sehr sehr trocken geschrieben. Ich konnt mich bisher noch nie dazu motivieren es ganz durchzulesen. Aber bei 3,95€ bei Terrashop kann man imho nichts falsch machen (am besten noch was dazu bestellen, sonst lohnen die Versandkosten nicht).



  • Woohoo, es sieht jetzt aus wie in OpenGL 🙂 Also die gleichen Koordinaten und die gleichen perspektivischen Parameter (FOV, Aspect, zNear und zFar).

    Ein Problem, bzw eine Frage habe ich noch:
    Wenn ich die normalisierten Gerätekoordinaten habe, reicht der z-Wert von -1 bis +1.
    Aber ist es normal, dass die so ungleichmäßig verteilt sind?

    Folgende Werte krieg ich für z-Werte im world space (zNear = 0.1, zFar = 100.0), z' ist die normalisierte Gerätekoordinate:

    z = -0.05    z' = -3.002 // vor zNear, wird also gekickt
    z = -0.1     z' = -1 // genau auf zNear
    z = -0.2     z' = 0.00100102
    z = -0.3     z' = 0.334668
    z = -5.0     z' = 0.9619
    z = -20.0    z' = 0.991992
    z = -50      z' = 0.997998
    z = -100     z' = 1 // genau auf zFar
    z = -105     z' = 1.0001 // hinter zFar, wird auch gekickt
    

    Man sieht, dass sich die Werte schnell extrem dicht unter der 1 ansiedeln. Stimmt das so? Aber wieso ist das? Wenn die Werte linear verteilt wären, wäre der zBuffer doch viel genauer, oder?

    Dankeschön,
    Tim


  • Mod

    xindon schrieb:

    Aber wieso ist das?

    wenn du in der 9ten klasse sein wirst, werdet ihr eventuell Hyperbel behandeln, das wird dir dann des raetsels loesung geben 😉



  • rapso schrieb:

    xindon schrieb:

    Aber wieso ist das?

    wenn du in der 9ten klasse sein wirst, werdet ihr eventuell Hyperbel behandeln, das wird dir dann des raetsels loesung geben 😉

    grml *g*

    Im Grunde wollte ich nur wissen, ob die Werte stimmen... ich fass das jetzt mal als 'ja' auf...


  • Mod

    fass es als "informier dich, das richtige stichwort hast du" auf 😉



  • rapso schrieb:

    und wird in Zukunft wahrscheinlich an Bedeutung gewinnen. 🙂

    glaub nicht jedem marketing 😉

    Schau mal hier. Ich glaube nicht, dass die das nur aufgrund von Marketing machen. Komplettes Echtzeit Raytracing steckt sicherlich noch in den Kinderschuhen, aber das kann sich durchaus ändern. Ich denke nicht, dass Rastergrafik bereits das Ende der Fahnenstange sein soll. Und dank Multicore und Streaming CPUs/GPUs stehen da auch hardwareseitig noch einige vielversprechende Möglichkeiten in Zukunft zur Verfügung.


  • Mod

    groovemaster schrieb:

    rapso schrieb:

    und wird in Zukunft wahrscheinlich an Bedeutung gewinnen. 🙂

    glaub nicht jedem marketing 😉

    Schau mal hier.

    steht nichts neues.

    groovemaster schrieb:

    Ich glaube nicht, dass die das nur aufgrund von Marketing machen.

    ich glaube schon.

    groovemaster schrieb:

    Komplettes Echtzeit Raytracing steckt sicherlich noch in den Kinderschuhen, aber das kann sich durchaus ändern.

    jo, wenn es mal besser laufen wuerde als bisherige algorithmen, doch das ist nicht in aussicht.

    groovemaster schrieb:

    Ich denke nicht, dass Rastergrafik bereits das Ende der Fahnenstange sein soll.

    eventuell solltest du momentane technologie besser verstehen um das beurteilen zu koennen. einfach nur nen ganzen absatz mit behauptungen zu schreiben ist kein wirkliches argument.

    groovemaster schrieb:

    Und dank Multicore und Streaming CPUs/GPUs stehen da auch hardwareseitig noch einige vielversprechende Möglichkeiten in Zukunft zur Verfügung.

    Diese technologie wird gemacht als anpassung an die bisherigen algorithmen z.b. rasterizen. streaming ist z.b. sehr kontraproduktiv zu ratracing.



  • Mit dem Cell-Prozessor kann man, wie schon gezeigt wurde, bereits recht gut Echtzeit-Raytracing betreiben.
    Dabei kann man z.B. jede der 8 SPUs jeweils ein Bündel von Strahlen berechnen lassen, und zwar parallel. Raytracing lässt sich ja sehr gut parallelisieren, genau wie die Rasterisierung.
    Ich denke auch, dass Echtzeit-Raytracing über kurz oder lang das Scanline-Rendering ablösen wird.


  • Mod

    TomasRiker schrieb:

    Mit dem Cell-Prozessor kann man, wie schon gezeigt wurde, bereits recht gut Echtzeit-Raytracing betreiben.

    das wurde auf so ziemlich jeder hardware gezeigt. auf GPUs, PowerPCs, FPGAs und natuerlich x86/x64 systemen. nur ist die leistungssteigerung bei GPUs immer weiter ueberlegen wird, besonders in richtung der mitlerweile fast voll dynamischen welten ist raytracing nichts praktibables.

    Dabei kann man z.B. jede der 8 SPUs jeweils ein Bündel von Strahlen berechnen lassen, und zwar parallel. Raytracing lässt sich ja sehr gut parallelisieren, genau wie die Rasterisierung.

    und wieso denkst du dann das:

    Ich denke auch, dass Echtzeit-Raytracing über kurz oder lang das Scanline-Rendering ablösen wird.



  • @rapso
    Ganz ruhig. Hast du einen schlechten Tag gehabt? Oder warum gehst du gleich so ab? Erstens habe ich nur das geschrieben, was ich über die zukünftige Raytracing Entwicklung _denke_. Du liegst daher vollkommen schief, mir irgendwelche Behauptungen zu unterstellen. Und ich habe auch nie behauptet, dass Raytracing bisherige Verfahren vollkommen ablösen wird. Ich denke nur, dass Raytracing an Bedeutung gewinnen wird. Und vllt. wird es irgendwann auch kommerzielle Spiele damit geben.


Anmelden zum Antworten