[Projekt] Basic3D / Irwin3D / Violent3D

Hier könnt ihr euch selbst, eure Homepage, euren Entwicklerstammtisch, Termine oder eure Projekte vorstellen.
Forumsregeln
Bitte Präfixe benutzen. Das Präfix "[Projekt]" bewirkt die Aufnahme von Bildern aus den Beiträgen des Themenerstellers in den Showroom. Alle Bilder aus dem Thema Showroom erscheinen ebenfalls im Showroom auf der Frontpage. Es werden nur Bilder berücksichtigt, die entweder mit dem attachement- oder dem img-BBCode im Beitrag angezeigt werden.

Die Bildersammelfunktion muss manuell ausgeführt werden, die URL dazu und weitere Details zum Showroom sind hier zu finden.

This forum is primarily intended for German-language video game developers. Please don't post promotional information targeted at end users.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

[Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von xq »

Hallo werte ZFXler!

Ich habe mal wieder etwas rumgehackt und dabei ist eine kleine Software-Rendering-Library rausgefallen: Basic3D

An Features habe ich schon implementiert:

Irwin3D
Ein Raycaster, der im Moment einfache Line Lists rendert und keine Höhenunterscheidung kann (sieht also aus wie Wolfenstein3D):
Bild

Violent3D
Ein Rasterizer, der vortransformierte Polygone auf den Bildschirm malt und dabei einen Tiefenbuffer verwendet, ganz klassisch langweilig also:
Bild

Das Ziel des ganzen ist es, mir ein Framework zu bauen, mit dem ich (in einem noch "geheimen" Projekt) dann angemessene 3D-Grafik habe.

Worauf ich bei der Entwicklung geachtet habe, ist die Austauschbarkeit einiger Datentypen sowie die Vermeidung von dynamischer Speicherverwaltung. Das hat den Nachteil, dass alle Klassen schon zu Compilezeit wissen müssen, wie groß ihr späterer Framebuffer sein muss, dafür habe ich kein einziges malloc oder new in meinem Code.

Den Code gibts wie üblich bei GitHub: https://github.com/MasterQ32/Basic3D

Freue mich über Anmerkungen und Kommentare, noch geiler wärs natürlich, wenn jemand was damit bastelt ;)

Updates kommen hoffentlich auch noch welche, vorallem für den Rasterizer, der ist grade noch etwas langsam.

Liebe Grüße
Felix

PS.: Ach ja, Codebeispiele!

Code: Alles auswählen

Image<320, 240> image;
image.clear(0x00, 0x00, 0x80);

Renderer<320, 240> renderer(image);

// setup a material for rendering with color
Material mtlWhite = { pixel_t(0xFF, 0xFF, 0xFF), nullptr };
renderer.Material = &mtlWhite;

// rasterize the quad
std::array<Vertex<fixed>, 4> vertices
{
	Vertex<fixed> { Vector3<fixed>(16, 16, 0.5), Vector2<fixed>(0, 0) },
	Vertex<fixed> { Vector3<fixed>(16, 48, 0.5), Vector2<fixed>(0, 1) },
	Vertex<fixed> { Vector3<fixed>(48, 16, 0.5), Vector2<fixed>(1, 0) },
	Vertex<fixed> { Vector3<fixed>(48, 48, 0.5), Vector2<fixed>(1, 1) },
};
renderer.drawTriangle(vertices[0], vertices[1], vertices[2]);
renderer.drawTriangle(vertices[2], vertices[1], vertices[3]);
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
joggel

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von joggel »

Sehr cool!!
Macht mich auf jeden fall neugierig!!
joeydee
Establishment
Beiträge: 1039
Registriert: 23.04.2003, 15:29
Kontaktdaten:

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von joeydee »

Klasse. Gibts einen bestimmten Grund für den Software-Weg oder einfach nur aus Interesse?
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von xq »

Klasse. Gibts einen bestimmten Grund für den Software-Weg oder einfach nur aus Interesse?
Ich wollte das zum einen schon immer mal machen, aber zum anderen hab ich auch noch ein embedded-Projekt vor, wo ich keine Grafikkarte habe, aber gerne 3D-Grafik hätte. Darum bau ich mir mal ein paar Softwarelösungen


Nachtrag: Ach ja, es geht voran mit dem Rasterizer:
Bild
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von xq »

Es geht voran, gab ein paar Verbesserungen im Allgemeinen (viel mehr Template-Kram, man kann jetzt auch den Pixel-Datentyp austauschen), zudem gibts ein neues Modul für 2D-Kram:

Bild
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
DerAlbi
Establishment
Beiträge: 269
Registriert: 20.05.2011, 05:37

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von DerAlbi »

Huuii! Embedded-Software-Renderer :-D Das weckt auch Erinnerungen bei mir..
Ich hatte so etwas auch implementiert, komplett auf Fixkomma basiert. Ich hatte perspektivisch korrekte Interpolation aber nie wirklich durchgezogen, da mein Mikrocontroller damals 32 (23?) Takte für ne Division brauchte.
Insgesamt hatte ich es aber geschafft, auf nur 17 Takte pro texturierten (mit Mip-Mapping und Filterung), beleuchteten Pixel (über Vertex-Farben) zu kommen.
Das war damals ein AVR32 AP7000 mit OOO-Pipeline (etwa 1.8 instr./clk). Bei 160MHz war da 320x240 flüssig drin. Farb-Interpolation ging über SIMD und Assembler.
Ich hatte die "Shader" als Template implementiert: da gabs dann einen Shader, der konnte nur Vertexfarben mit Licht, ein anderer konnte ungefiltert Texturieren, ein anderer konnte filtern usw..

Edit: Ich finde es wirklich interessant, wie unterschiedlich unsere Implementationen sind. Ganz verstanden habe ich deine 3-ecks Zeichenroutine allerdings nicht..
Du machst das Cliping z.B. im Screenspace im Pixelshader.. (oder?)
Das hatte ich mir damals verboten weil es den Code an solch einer Kritischen stelle verschlechtert. Ich habe dafür vor jedem rendern alle meine Tris geclipt. Also alles, was außerhalb des Frustums war verworfen (culling bietet sich bei dem Schritt auch an) und alles, was das Frustum schneidet an den Schnittkanten re-trianguliert.

Habe ich das richtig verstanden, dass du bei einem 3-eck die gesamte Bounding-Box abscannst und dann pro Pixel prüfst, ob der zu malende Pixel überhaupt im 3eck liegt?
Ich hatte die 3ecks-punkte von oben nach unten sortiert. Ich bin dann einfach Zeile für Zeile von Seiten-Vektor zu Seiten-Vector gelaufen. Das stellt algorithmisch sicher, dass man nur Pixel des 3ecks bearbeitet.
Dateianhänge
Sw3D.png
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von xq »

DerAlbi hat geschrieben:Huuii! Embedded-Software-Renderer :-D Das weckt auch Erinnerungen bei mir..
Ich hatte so etwas auch implementiert, komplett auf Fixkomma basiert. Ich hatte perspektivisch korrekte Interpolation aber nie wirklich durchgezogen, da mein Mikrocontroller damals 32 (23?) Takte für ne Division brauchte.
Insgesamt hatte ich es aber geschafft, auf nur 17 Takte pro texturierten (mit Mip-Mapping und Filterung), beleuchteten Pixel (über Vertex-Farben) zu kommen.
Das war damals ein AVR32 AP7000 mit OOO-Pipeline (etwa 1.8 instr./clk). Bei 160MHz war da 320x240 flüssig drin. Farb-Interpolation ging über SIMD und Assembler.
Ich hatte die "Shader" als Template implementiert: da gabs dann einen Shader, der konnte nur Vertexfarben mit Licht, ein anderer konnte ungefiltert Texturieren, ein anderer konnte filtern usw..
Ja, ich werd auf nem ARM Cortex-M3 mit 180 MHz rumrödeln, wahrscheinlich auch mit Fixkomma-Arithmetik. Werde aber einigen Support durch nen FPGA haben (cheate also ein bisschen)
DerAlbi hat geschrieben: Edit: Ich finde es wirklich interessant, wie unterschiedlich unsere Implementationen sind. Ganz verstanden habe ich deine 3-ecks Zeichenroutine allerdings nicht..
Du machst das Cliping z.B. im Screenspace im Pixelshader.. (oder?)
Das hatte ich mir damals verboten weil es den Code an solch einer Kritischen stelle verschlechtert. Ich habe dafür vor jedem rendern alle meine Tris geclipt. Also alles, was außerhalb des Frustums war verworfen (culling bietet sich bei dem Schritt auch an) und alles, was das Frustum schneidet an den Schnittkanten re-trianguliert.

Habe ich das richtig verstanden, dass du bei einem 3-eck die gesamte Bounding-Box abscannst und dann pro Pixel prüfst, ob der zu malende Pixel überhaupt im 3eck liegt?
Ich hatte die 3ecks-punkte von oben nach unten sortiert. Ich bin dann einfach Zeile für Zeile von Seiten-Vektor zu Seiten-Vector gelaufen. Das stellt algorithmisch sicher, dass man nur Pixel des 3ecks bearbeitet.
Ja, das ist grade noch das absolute Minimum, das war jetzt erst mal der Teil "hauptsache es funktioniert". Bin grade dabei, zu verstehen, wie ich die Dreiecke in Scanlines umwandeln kann (also wie du sortiert rendern)

Pixelshader via Template wäre vielleicht ne Option bei mir, muss ich mal gucken. Irgendeine Art von Pixel Processing wäre auf jeden Fall praktisch, grade um auch Texturen und so Kram besser wechseln zu können...
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von xq »

So, es geht voran mit der Implementierung am neuen Rasterizer:

Dreiecks-Füller, obere Hälfte: Check
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
DerAlbi
Establishment
Beiträge: 269
Registriert: 20.05.2011, 05:37

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von DerAlbi »

Jo, das sieht gut aus! So soll es sein :-)
Ein M3 ist aber bisschen.. hmmh... naja dem fehlen halt SIMD für die Farben und zur Reduktion des Registerdrucks. Aber er hat nen DIV in 12 clks! Division muss aber aber dennoch per Pixel umgehen.. ich habe mir dafür pro 3ecks-Seite alle d_Value/ScanLineCount vorberechnet (Value als Platzhalter für alles, was man interpolieren muss), sodass dann beim Rastern nur noch Fixkomma-Additionen mit d_Value auf einen Startwert hat.
Nimm im Rasterizer maximal ein 16-Bit langes FP-Format, sonst haust du dir bei der Multiplikation wertvolle Register kaputt (32*32=64 dauert auch > 2x so lang).
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von xq »

Den Rasterizer würde ich auch einfach gerne im FPGA implementieren, da hab ich eh noch viel geilere Optionen, um rumzutricksen, was Performance angeht. Im Moment ist der Scanline Rasterizer auf jeden Fall schlechter als der mit dem Triangle Check
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von xq »

Danke für den Vorschlag mit den Shadern:

Code: Alles auswählen

template<typename pixel_t = Basic3D::Pixel32, typename real = Basic3D::real_t>
struct TextureShader
{
	Basic3D::Texture<pixel_t> * texture;

	pixel_t shade(Vertex<real> const & vtx, bool & discard) const
	{
		auto color = texture->sample(
			int(real(texture->width - 1) * Basic3D::fract(vtx.uv.x)),
			int(real(texture->height - 1) * Basic3D::fract(vtx.uv.y)));
		if(!Basic3D::alphaTest(color))
			discard = true;
		return color;
	}
};
Habe jetzt auch nochmal rum optimiert und bin jetzt bei äquivalenter Performance zum Triangle-Check-Algorithmus, bin aber doch etwas überrascht, dass es nicht wirklich performanter ist...
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
DerAlbi
Establishment
Beiträge: 269
Registriert: 20.05.2011, 05:37

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von DerAlbi »

Ich hab mal den URALTEN Code rausgekramt. Ich war damals jung. kein Hübscher Code, aber evtl eine Inspiration. Dass es bei dir so lahm ist, finde ich komisch. Das sollte VIEL schneller sein, als der brute-force bounding-box check.
Aber man muss die Interpolationen über das 3eck auch ordentlich vorbereiten...

Was dich in der Datei interessiert ist in RasterizerTemplate.h die CRasterizerRoutines::DrawAfffine.
Ich habe aber auch mal den Rest drin gelassen, falls du mein Vertex-Processing überfliegen magst.
Dateianhänge
3D.7z
(11.78 KiB) 192-mal heruntergeladen
smurfer
Establishment
Beiträge: 195
Registriert: 25.02.2002, 14:55

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von smurfer »

Hey,

schönes Projekt, habe ich früher auch mal umgesetzt, allerdings nur, weil es noch keine 3D-Karten gab :D.

Dass der Scanline so langsam ist, finde ich auch merkwürdig. Ich weiß nicht, wie du mit Steigungen der Kanten umgehst (also Anfang und Ende der horizontalen Linien zum Füllen). Statt nach Geradengleichung zu multiplizieren, solltest Du -- falls Du es nicht schon tust -- mit Überläufen wie beim Linienalgorithmus von Bresenham arbeiten: https://de.wikipedia.org/wiki/Bresenham-Algorithmus

Beste Grüße
scheichs
Establishment
Beiträge: 845
Registriert: 28.07.2010, 20:18

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von scheichs »

smurfer hat geschrieben:Dass der Scanline so langsam ist, finde ich auch merkwürdig.
Das ist doch grade das Schöne an solchen Projekten. Der Moment, in dem man das Problem entdeckt, und es dann um den Faktor 100 schneller läuft... :D ;)
DerAlbi
Establishment
Beiträge: 269
Registriert: 20.05.2011, 05:37

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von DerAlbi »

Das finde ich einen merkwürdigen Vorschlag :-O
Wenn man nicht mit der Geradengleichung arbeitet, wie soll man dann denn z.B: über das 3eck hinweg interpolieren?? Natürlich darf man nicht Multiplizieren [Startpunkt * (ScanlineNumber/Linienlänge)*Richtungsvektor], sondern man sollte [ScanlineStart = Startpunkt; dScanline = (1/Linienlänge)*Richtungswektor; ScanlineStart += dScanline; ] haben um auf doppelt so schnelle Addition zurückzugreifen anstatt zu multiplizieren.
Wie man bei Bresenham verfolgt, wo man gerade im 3eck ist, ist mir unklar - und das basiert schon wieder auf Sprüngen und Vergleiche und if und else... ist doch alles Taktverschwendung auf Pixelebene. (im Vergleich zum Vorbereiten von n Additionen)
smurfer
Establishment
Beiträge: 195
Registriert: 25.02.2002, 14:55

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von smurfer »

Hm, mag sein, vielleicht ist das sehr veraltetes Halbwissen. So habe ich es mir zumindest in den 90gern aus Büchern angelesen, oder ich bin gerade völlig auf dem falschen Dampfer.
So ganz verstanden habe ich nicht, was Du meinst, Albi. Ich kenne es etwa so:
  • Nach Y-Koordinate sortieren
  • Zeilenweise horizontale Linien zeichnen
    • Start- und Endpunkt durch Bresenham vorgegeben
Gerade noch einmal geschaut, nicht dass mich meine Erinnerung trügt: Wikipedia sagt zum Rastern
Kantenlisten-Algorithmen bestimmen für jede Kante des Polygons die Schnittpunkte mit den Bildzeilen. Diese können direkt berechnet werden, oder es können Algorithmen zur Rasterung von Linien verwendet werden.
und unter den Algorithmen zur Rasterung von Linien taucht eben auch der Bresenham auf. Das ist zumindest das, was ich meinte, kann aber wie gesagt gnadenlos veraltet sein.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von xq »

scheichs hat geschrieben:Das ist doch grade das Schöne an solchen Projekten. Der Moment, in dem man das Problem entdeckt, und es dann um den Faktor 100 schneller läuft... :D ;)
Jap, ich hab gestern abend "mal kurz" nen Faktor von 10 rausgeholt, in dem ich die Polygone vor dem Zeichnen gegen das Frustrum clippe (im Screenspace) und komplett verwerfe, wenn sie außerhalb liegen. Danach nochmal ne Optimierung über die Pixel, die ich tatsächlich angucke / zeichne und schwupp war ich auf der alten Performance (+-5%)
DerAlbi hat geschrieben:Natürlich darf man nicht Multiplizieren [Startpunkt * (ScanlineNumber/Linienlänge)*Richtungsvektor], sondern man sollte [ScanlineStart = Startpunkt; dScanline = (1/Linienlänge)*Richtungswektor; ScanlineStart += dScanline; ] haben um auf doppelt so schnelle Addition zurückzugreifen anstatt zu multiplizieren.
Ja, so mach ich das auch. Vor dem Start des Zeichnens die Scanline-Positionen berechnen und dann die X-Steigung der Geraden bestimmten. War gestern aber wohl noch zu blöd, um zu kapieren, dass ich die Y-Steigung gar nicht mitziehen brauche, da die ja eh immer 1.0 ist
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
DerAlbi
Establishment
Beiträge: 269
Registriert: 20.05.2011, 05:37

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von DerAlbi »

Smurfer, ich verstehe das schon, aber ich denke dass die Komplexität das Algorithmus hier eine Rolle spielt. Ich denke ein ordentlicher Linien-Algo wird optisch eventuelle besser aussehen, aber gerade im Embedded-Bereich sucht man hier eher Trade-offs. Wenn man einen komplexen Algo durch simple Addition ersetzen kann [während man ein sehr ähnliches Ergebnis bekommt], braucht man nicht lange über seine Optionen nachdenken.

MasterQ32, hast du jetzt die 3ecke komplett am Screen geclippt? (also auch raushängende 3ecke abschneiden und retriangulieren?)
Zuletzt geändert von DerAlbi am 26.03.2018, 14:50, insgesamt 2-mal geändert.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von xq »

DerAlbi hat geschrieben:MasterQ32, hast du jetzt die 3ecke komplett am Screen geclippt? (also auch raushängende 3ecke abschneiden und retriangulieren?)
Ne, ich clippe den Bereich des Dreiecks, den ich fülle. Damit muss ich die Berechnung für die Steigungen und so nur einmal machen und nicht das Dreieck in zwei Dreiecke aufteilen. Das dürfte imho nacher weniger Instructions geben, grade bei eher kleinen Dreiecken
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
smurfer
Establishment
Beiträge: 195
Registriert: 25.02.2002, 14:55

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von smurfer »

DerAlbi hat geschrieben:[...] Wenn man einen komplexen Algo durch simple Addition ersetzen kann [während man ein sehr ähnliches Ergebnis bekommt], braucht man nicht lange über seine Optionen nachdenken. [...]
Danke für den Hinweis, ich hatte über die von MasterQ verwendete und von Dir erwähnte Variante nicht großartig nachgedacht, erst nach diesem Hinweis. Ich hatte für mich immer noch abgespeichert: Bresenham, da schneller als Multiplikation mit Steigung.
DerAlbi
Establishment
Beiträge: 269
Registriert: 20.05.2011, 05:37

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von DerAlbi »

Btw: wenn ich sowas in der INNERSTEN SCHLEIFE sehe..

Code: Alles auswählen

real const a12 = areaOfTris(p1, p2, p);
real const a23 = areaOfTris(p2, p3, p);
real const a31 = areaOfTris(p3, p1, p);
real const f1 = a23 / totalArea;
real const f3 = a12 / totalArea;
real const f2 = a31 / totalArea;
Dann haust du da ernsthaft 3 divisionen hin.. Das alleine kostet mehr Takte als eine Schleifeniteration incl Shader jemals dauern sollte. Und areaOfTris hat ein std::abs drin.. also wieder ein Branch. Da musste unbedingt nochmal drüber.
:-) Divisionen musst du komplett vermeiden. Speichere dir die Inversen und multipliziere damit.
Ich bin da gerade so aufdringlich, weil das ein umdenken in deinen Datenstrukturen zur Folge hat (welche Daten du dir zurecht legst).. das muss man von vornherein planen und geht nicht sonderlich gut als after-tought.
Das dürfte imho nacher weniger Instructions geben, grade bei eher kleinen Dreiecken
Wenn ich so drüber nachdenke könntest du hier recht haben. Das Aufsetzen einer 3eck-Rasterisierung hat mehr overhead als ein min/max pro Scanline. hmmh. Danke :-)
Irgendwann mach ich das mal wieder ^_^.
Die Near und Far-Plane muss man aber Clippen und retriangulieren, weil da ein 3eck auch mitten im Bild abgeschnitten werden kann. (oder?)
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von xq »

DerAlbi hat geschrieben:Dann haust du da ernsthaft 3 divisionen hin.. Das alleine kostet mehr Takte als eine Schleifeniteration incl Shader jemals dauern sollte.
Wie gesagt, ich hab erst mit den Optimierungen angefangen ;) Zudem muss ich mir das mit den Baryzentrischen Koordinaten nochmal genau angucken, da ich die eventuell auch über die Liniengleichung berechnen könnte (also nur eine Addition anstelle von drei Mults)
DerAlbi hat geschrieben:Ich bin da gerade so aufdringlich, weil das ein umdenken in deinen Datenstrukturen zur Folge hat (welche Daten du dir zurecht legst).. das muss man von vornherein planen und geht nicht sonderlich gut als after-tought.
Joar, aber ich mach das hier ohne Referenzen oder Vorlagen, mit dem Hintergedanken, dass ich in grade solche Sachen reinrenne und das für die Zukunft dann besser weiß als "ich hab das mal wo gelesen, dass man das so macht".
DerAlbi hat geschrieben:Die Near und Far-Plane muss man aber Clippen und retriangulieren, weil da ein 3eck auch mitten im Bild abgeschnitten werden kann. (oder?)
Hm, gute Frage. Da ich ja eh nen Z-Test mache, verwerfe ich alles vor bzw. hinter den Near-/Far-Planes im Pixel Processing. Muss da auch nochmal durchgehen, da sind grade noch ganz viele Divisionen drin und so weiter ):
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von xq »

Optimierungslog:
reference: 25106 us

eliminate division (totalArea): 21581 us

eliminate division (maxZ - minZ): 18195 us

eliminate vector2 use (fp0, fp1): 18168 us
Die Werte hier sind mit einer statischen Szene gerendert, über längere Zeit, also recht gut vergleichbar.

Ergebnis: hat noch glitches, läuft doch aber langsam mal ganz flüssig


Der Log meint, dass die Renderzeiten kurz mal für ein Frame eskaliert sind, kann aber wohl auch daran liegen, dass der Rechner Dinge gemacht hat.
rasterizer time: 18157 us / min: 15143 us / mean: 17292 us / max: 20367 us
rasterizer time: 57016 us / min: 15143 us / mean: 17435 us / max: 57016 us
rasterizer time: 18587 us / min: 15143 us / mean: 17440 us / max: 57016 us
Aber grundlegend sieht das doch langsam mal gut aus, was Zeiten angeht, jetzt muss es nur noch richtig werden :D

Nachtrag: Habe noch Frustum Culling implementiert, hat mir das ganze nochmal um 30% verbessert:
rasterizer time: 12668 us / min: 10553 us / mean: 11836 us / max: 14136 us
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
DerAlbi
Establishment
Beiträge: 269
Registriert: 20.05.2011, 05:37

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von DerAlbi »

Hmmh, also da bekommt man gleich lust den alten code mal zu überarbeiten und sich auch mal wieder ranzusetzen. wäre eigentlich cool, wenn man um die wette benchmarkt - aber das wäre echt viel arbeit und ich hab ein anderes (Dauer-)Projekt am laufen.
bzgl deiner Timings möchte ich anmerken, dass du gerade auf nem x86 arbeitest. Der hat register-renaming, OOO-Execution usw.. Ein CortexM3 wird andere Bottlenecks haben (z.B. würden die Divisionen mehr kosten usw.)
Ich würde deshalb empfehlen, dass du erstmal die Bugs aufm PC rausmachst und die weitere Optimierung (hast ja jetzt schon eine ordentliche Referenz), auf dem µC machst. Das Interessante wird sein, dass das, was für x86 optimal ist, nicht für M3 optimal ist, aber das was für M3 gut ist, wird auch auf x86 gut sein.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von xq »

bzgl deiner Timings möchte ich anmerken, dass du gerade auf nem x86 arbeitest. Der hat register-renaming, OOO-Execution usw.. Ein CortexM3 wird andere Bottlenecks haben (z.B. würden die Divisionen mehr kosten usw.)
Ich würde deshalb empfehlen, dass du erstmal die Bugs aufm PC rausmachst und die weitere Optimierung (hast ja jetzt schon eine ordentliche Referenz), auf dem µC machst. Das Interessante wird sein, dass das, was für x86 optimal ist, nicht für M3 optimal ist, aber das was für M3 gut ist, wird auch auf x86 gut sein.
Ist mir bewusst, daher habe ich auch keine x86-spezifischen optimierungen gemacht, also irgendwie auf Cache Koherenz oder ähnliches geachtet, habe auch keine Sprünge reduziert. Aber sowas wie Divisionen und generell unnötige Berechnungen vermeiden bringt auf jeder Plattform was.

Ich werd mir heute oder morgen in der Firma mal ein System mit Cortex-M3 und Display besorgen, dann kann ich da auch anfangen, zu Benchmarken. Leider wird das erst mal auch nicht vergleichbar mit meiner Zielplattform, da das Display an dem System seriell angeschlossen ist, nicht parallel (und darum sacklahm wird)
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
DerAlbi
Establishment
Beiträge: 269
Registriert: 20.05.2011, 05:37

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von DerAlbi »

Das wird nicht sacklahm [wegen des seriellen Displays]. Du renderst in ein Dual-Backbuffer, wobei dann immer einer davon per DMA auf die SPI gehauen wird und gut. Da merkst du gar nichts davon. Wichtig ist, dass du dich darauf konzentrierst beim Rendern alles innerhalb der Register halten zu können, damit der Bus nicht ständig zwei Herren dienen muss. Man kann die DMA/Bus-Matrix aber auch so einstellen, dass die Anzahl an garantiert aufeinander folgender Speicherzugriffe vom DMA nur 1 ist. Du brauchst ja effektiv auf solchen Displays nicht mehr als 30Hz Update-rate, also verkrüpple das SPI-Interface einfach..
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von xq »

Ich hab auf meiner Testplattform nur bis zu 64kB RAM, da is nix mit Framebuffer im Speicher halten. Rendern und raus damit ;)
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
DerAlbi
Establishment
Beiträge: 269
Registriert: 20.05.2011, 05:37

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von DerAlbi »

Hmmh. Welche Auflösung hast du denn? 320x240 (steht im code) ist bei 16bit Farbtiefe schon kacke (150kb). Abhängig von deiner Auflösung ist dann der Mikrocontroller einfach die falsche Wahl. Wenn du sowas wie 3D-Rendering integrieren willst geht das nicht ohne entsprechende Hardware. (mir fehlt bei deinem M3 schon der SIMD-Teil, was ein echtes Problem für Texturierung ist)
Die Scanlines der 3ecke kann man zwar direkt raushauen, aber dann brauchst du nicht wirklich z-buffern, weil es eh flackern wird.
Überdenke nochmal dein System. Software muss auf die Hardware passen und auch andersrum :-)
Du scheinst ja noch keine fertige Hardware zu haben, da ist noch Spielraum..

Man kann bei einem großen Display die 3ecke beim Clippen nach der Transformation+Projektion in Bildschrim-Bereiche sortieren. Dann könntest du immerhin 2 Backbuffer mit 320x48 haben und dich von oben nach unten durcharbeiten.
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von xq »

Ja, das mit dem RAM ist mir schon klar... ;)
Überdenke nochmal dein System. Software muss auf die Hardware passen und auch andersrum :-)
Die Hardware für das System wird noch ein paar Monate Entwicklungszeit benötigen und hat dann dementsprechend auch mehr Power. Trotzdem juickts mich eben in den Fingern, das ganze generell mal auf nem ARM zum Laufen zu bekommen, und ich hab das Equipment dafür eben schon zur Verfügung, sogar mit korrektem Display, das später verwendet wird.
Wenn du sowas wie 3D-Rendering integrieren willst geht das nicht ohne entsprechende Hardware. (mir fehlt bei deinem M3 schon der SIMD-Teil, was ein echtes Problem für Texturierung ist)
Für solche Sachen hab ich später nen FPGA, da ist dann die Funktionalität für Pixelmischer und so weiter vorhanden ;)

Was mich zur Zeit primär interessiert, ist, wie performant der Raycaster auf dem ARM läuft, der Rasterizer juckt mich tatsächlich weniger :P
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
DerAlbi
Establishment
Beiträge: 269
Registriert: 20.05.2011, 05:37

Re: [Projekt] Basic3D / Irwin3D / Violent3D

Beitrag von DerAlbi »

Was bauste denn? ^_^
Antworten