Software Renderer
-
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.
-
Vertexwahn schrieb:
Hab aufgehört daran zu arbeiten, weil mir dann klar war wie Gourad Shading, Phong Shading, TextureMapping usw. funktioniert bzw. die Fixed Pipeline
[/quote]
du weisst doch nun selbst, dass die theorie zu wissen nie die erfahrung der praxis ersetzen kann
btw scheint mir dein Hodgman-Sutherland nur 2d zu sein

ich schreib auch zwei bis drei rasterizer pro jahr :), macht soviel spass wie raytracer :).
ist dein rasterizer immer wasserdicht und subpixel/texel genau?

-
rapso schrieb:
btw scheint mir dein Hodgman-Sutherland nur 2d zu sein

Clipping findet ja auch im Zweidimensionalen statt, nach der Projektion.
-
TomasRiker schrieb:
rapso schrieb:
btw scheint mir dein Hodgman-Sutherland nur 2d zu sein

Clipping findet ja auch im Zweidimensionalen statt, nach der Projektion.
nein, clipping findet im post-projective-space vor der projektion (also vorm divide) statt, ansonsten haettest du z waerte (edit: bzw w) die 0 oder <0 sind (jetzt auf einen positiven z-buffer bezogen), was zu extremen fehlern fuehren wuerde.
-
OK, stimmt, kommt auch drauf an was man unter der Projektion versteht.
"Nach der Transformation durch die Projektionsmatrix" (im Clip Space ;))Das sind natürlich dann noch dreidimensionale Koordinaten.
-
TomasRiker schrieb:
OK, stimmt, kommt auch drauf an was man unter der Projektion versteht.
"Nach der Transformation durch die Projektionsmatrix" (im Clip Space ;))egal was man darunter versteht, es bleibt clipping mit 3d-coordinaten, er hat in seinem paper leider nur 2d beschrieben.
-
Mein Weg vom Vertex zur Fensterkoordinate sieht nun so aus:
void Renderer::TransformVertex(int* dst_x, int* dst_y, Vector4* src_vertex) { // http://www.opengl.org/resources/faq/technical/transformations.htm // Get clip coords Vector4 eyeCoords = (*src_vertex) * this->worldMatrix; Vector4 clipCoords = eyeCoords * this->projectionMatrix; // Get normalized device coordinates clipCoords.x /= clipCoords.w; clipCoords.y /= clipCoords.w; clipCoords.z /= clipCoords.w; // 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); }Stimmt das vom Prinzip her? Weil ich glaube, dass meine Ausgabe falsch ist. Aus den Vertizes (-100 | 0 | 20) und (100 | 0 | 20) werden die Bildschirmkoordinaten (320 | 240) und (319 | 240). Der rechtere der beiden Vertizes ist am Ende der linke Pixel, da stimmt ja irgendwas nich...
Wenn ich bei einem Vertex die y-Koordinate kleiner mache, ist die y-Koordinate des Pixels größer. Also auch vertauscht... Bzw, 0|0 ist normalerweise die linkere untere Ecke, oder? Dann liegt hier das Problem mit den y-Werten, weil 0|0 bei mir oben links liegt, aber das ist ja schnell gefixt...
Meine Projektionsmatrix erstelle ich wie D3DXMatrixPerspectiveFovLH:
void Renderer::SetPerspectiveProjection(float fovY, float aspect, float zNear, float zFar) { float yScale = atan(fovY / 2.0f); float xScale = yScale / aspect; this->projectionMatrix.Zero(); this->projectionMatrix._11 = xScale; this->projectionMatrix._22 = yScale; this->projectionMatrix._33 = zFar / (zFar - zNear); this->projectionMatrix._34 = 1.0f; this->projectionMatrix._43 = -zNear * zFar / (zFar - zNear); }Meine Initialisierung sieht so aus:
renderer.SetViewport(0, 0, 640, 480); renderer.SetPerspectiveProjection(1.3f, (float)640 / 480, 0.1f, 100.0f);Vielen Dank,
Tim
-
... oben geändert
-
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 nachvollziehengreets
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

-
http://www.amazon.com/Tricks-Programming-Gurus-Advanced-Graphics-Rasterization/dp/0672318350
das buch ist auch ganz gut

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

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