Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mo Jun 03, 2024 20:41

Foren-Übersicht » Programmierung » Shader
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Parallax Mapping mit fxPascal
BeitragVerfasst: Mi Feb 11, 2004 22:46 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Dez 13, 2002 12:18
Beiträge: 1063
Nachdem vor kurzem eine neue Bumpmapping Methode auf OpenGL.org präsentiert (oder besser gesagt wieder entdeckt) wurde, wollte ich mal ausprobieren, wie das sogenannte "Parallax Mapping" mit fxPascal umgesetzt werden kann.
Erst war die Enttäuschung groß - fxPascal "verschluckte" Variablen, auf der Sourcefourge Seite gab es aber glücklicherweise eine neue Version (von heute!), bei der dieser Fehler nicht mehr auftrat.

Der Code für das Parallax Mapping sieht dann folgendermaßen aus (ich komme mir zwar wie ein Behinderter vor, wenn ich Shader programmiere und eine Stunde oder mehr für ein paar Codezeilen brauche, weil es ziemliches Neuland ist - mit fxPascal geht es aber relativ problemlos)

das Vertexprogramm:
Code:
  1. {$optimize-}
  2. program VertexProgram1;
  3. uses arb_vertex_program, arb_position_invariant;
  4.  
  5. // input:
  6. // texture #0 = color map
  7. // texture #1 = normal map
  8. // texture #2 = offset map
  9. // vertex.attrib[6] = tangent
  10.  
  11. // output:
  12. // texcoord[0] offset in texture map
  13. // texcoord[1] tangent space light0 vector
  14. // texcoord[2] tangent space eye vector
  15.  
  16. // remarks
  17. // binormal is computed on the fly
  18. // light is taken from light source 0
  19. // viewer position is taken from modelview.invtrans
  20.  
  21. var
  22.   binormal, eyevec,
  23.   light0pos, light0vec: vec4;
  24.  
  25. begin
  26.   // compute binormal
  27.   binormal := cross(vertex.attrib[6], vertex.normal);
  28.  
  29.   // vector pointing to light 0
  30.   with state do
  31.     light0pos := MatrixMult4(matrix.modelview.inverse, light[0].position);
  32.   light0vec := vertex.position - light0pos;
  33.  
  34.   // transform light0 vector into tangent space
  35.   with vertex do
  36.     result.texcoord[1] := MatrixMult3(Matrix(attrib[6], binormal, normal), light0vec);
  37.   result.texcoord[1].w := 1.0;
  38.  
  39.   // vector pointing to eye
  40.   eyevec := vertex.position - state.matrix.modelview.invtrans.row[3];
  41.  
  42.   // transform eye vector into tangent space
  43.   with vertex do
  44.     result.texcoord[2] := MatrixMult3(Matrix(attrib[6], binormal, normal), eyevec);
  45.   result.texcoord[2].w := 1.0;
  46.  
  47.   result.color:=vertex.color;
  48.   result.texcoord[0]:=vertex.texcoord[0];
  49. end;
  50.  


und das Fragmentprogramm:
Code:
  1. {$optimize-}
  2. program FragmentProgram1;
  3. uses arb_fragment_program;
  4.  
  5. // input:
  6. // texture #0 = color map
  7. // texture #1 = normal map
  8. // texture #2 = offset map
  9. // texcoord[0] offset in texture map
  10. // texcoord[1] tangent space light0 vector
  11. // texcoord[2] tangent space eye vector
  12.  
  13. var
  14.   eyevects,
  15.   rgb, normal, height, bump, total,
  16.   light0tsvec,
  17.   newtexcoord: vec4;
  18.  
  19. begin
  20.   // normalize tangent space eye vector
  21.   eyevects := normalize(fragment.texcoord[2]);
  22.  
  23.   // calculate offset and new texture coordinate
  24.   height := texture2d(2, fragment.texcoord[0]);
  25.   newtexcoord := (height * 0.04 - 0.02) * eyevects + fragment.texcoord[0];
  26.  
  27.   // get texture data
  28.   rgb := texture2d(0, newtexcoord);
  29.   normal := normalize(texture2d(1, newtexcoord) * 2.0 - 1.0);
  30.  
  31.   // normalize light0 vector
  32.   light0tsvec := normalize(fragment.texcoord[1]);
  33.  
  34.   // normal dot lightdir
  35.   bump := dot3(normal, light0tsvec);
  36.  
  37.   // compute total effect
  38.   total := sat(bump * state.light[0].diffuse + state.lightmodel.ambient);
  39.  
  40.   // and multiply by regular texture map color
  41.   result.color := sat(rgb * total);
  42. end;
  43.  


Leider muss ich die Codeoptimierung ausschalten, damit das Programm korrekt generiert wird (es gibt keinen Absturz, der Assembler Source scheint aber falsch zu rechnen). Das "Leider" ist hier ehrlich gemeint, denn an sich ist es eine wahre Freude, fxPascal dabei zuzusehen, Optimierungen in den Assemblercode einzubauen, auf die ich selbst gar nicht gekommen wäre. Normalerweise funktioniert es ja auch, bei komplexeren Shadern mit vielen Variablen, scheint da irgend etwas durcheinander zu kommen. Bei abgeschalteter Optimierung kompilieren die Shader aber korrekt, was auch keine geringe Leistung ist.

Es gibt natürlich auch einen Screenshot - Carad berechnet die Tangenten fürs TBN Mapping in ein Vertexattribut, wenn man genau hinsieht, erkennt man, dass 9 Shader benötigt werden, um Parallax Mapping zu implementieren:
1) RenderSettings: Einschalten der Vertex- und Fragmentprogramme
2) TextureSettings: Aktivierung TexUnit #0, 2D-Texturen
3) Textur: Decal-Map
4) TextureSettings: Aktivierung TexUnit #1, 2D-Texturen
5) Textur: Normal-Map
6) TextureSettings: Aktivierung TexUnit #3, 2D-Texturen
7) Textur: Height-Map
8) Vertex Programm
9) Fragment Programm

Das alles klappt auch einwandfrei, die Komponenten werden alle richtig berechnet, darauf bin ich auch recht stolz, zeigt es doch dass BaseGraph und Carad recht allgemeingültig sind, da auch "neue" Algorithmen interaktiv implementiert werden können, ohne dass sie fest verdrahtet im Programm vorliegen müssen.
Leider kann Carad noch keine Vertexattribute als DelphiSource abspeichern, sobald ich diese Funktion eingebaut habe stelle ich das fertige Demo mit Source online.


Dateianhänge:
Dateikommentar: ScreenShot aus der Carad IDE, beachtenswert die 9 Shader fürs Parallax Bumpmapping, sowie die neuen TSynEdit Fenster für fxPascal Source (viel schöner als der TRichText Hack).
ParMap.jpg
ParMap.jpg [ 46.74 KiB | 3112-mal betrachtet ]

_________________
Viel Spaß beim Programmieren,
Mars
http://www.basegraph.com/
Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Feb 11, 2004 23:50 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Ich werde mal versuchen den Fehler zu finden. Bei den Optimierungen scheint es da viele Spezialfälle zu geben. Mich wundert ein wenig, daß die neue Version 0.4 von heute sein soll. Die habe ich doch schon seit ein paar Wochen aktualisiert. Da es außer den Korrekturen zu den Fehler, die Mars gefunden hat, keine Änderungen gab, habe ich das hier nicht extra gepostet.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Feb 12, 2004 01:24 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Dez 13, 2002 12:18
Beiträge: 1063
Hmm, jedenfalls meldete das CVS Programm, dass eine neue Version online sei - und das Datum war dann das Heutige (intern steht noch 0.3 drin).

Übrigens habe ich Carad nun soweit aktualisiert, dass es Vertexattribute speichert. Vielleicht hilft das ja ein Stück weit - ich habe das Projekt mit dglOpenGL und fxPascal erstellt, der fxPascal Code ist in Parallax.pas zu finden und kann dort ohne Weiteres direkt geändert werden.

http://mcad.delphigl.com/Parallax.zip
(Benötigt GL_ARB_vertex_program und GL_ARB_fragment_program Unterstützung)

@dglOpenGL
die Kompilierung der neuesten BaseGraph Bibliotheken mit der aktuellen Version klappte nicht, weil dort nur die GL_FOG_COORDINATE_xxx Konstante vorhanden sind (laut Spezifikation heißen die nun GL_FOG_COORD_xxx), außerdem gibt es VBOs nur als ARB-Variante (da Core Feature von GL 1.5 sollten die auch als ARB-lose Definitionen zur Verfügung stehen).
Ich habe beides hinzugefügt, vielleicht kann man die neue Version (1.3c) auch auf DelphiGL einpflegen.

[edit]
wer das Parallax Mapping auf älteren Grafikkarten in Aktion sehen möchte, muss nur die neuesten MesaGL DLLs (z.B. von hier: http://www.basegraph.com/bg/ger/info.html ins Projektverzeichnis kopieren - überraschenderweise ist das gar nicht so langsam wie befürchtet (im Standardfenster 2 bis 3 Frames pro Sekunde bei mir).

_________________
Viel Spaß beim Programmieren,
Mars
http://www.basegraph.com/


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 3 Beiträge ] 
Foren-Übersicht » Programmierung » Shader


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 11 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.269s | 19 Queries | GZIP : On ]