Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

11.03.2010, 19:59

Shader basics

Hallo Welt,

ich fange gerade damit an, mich mit Shadern und allem auseinanderzusetzen und hab dazu ein paar Fragen.

Bisher haben alle Tutorials oder sonstiges Material, was ich dazu gelesen habe, irgendwie suggeriert, dass es einen riesigen Shader für die gesamte Szene gibt, der alles verarbeitet.
Das muss aber doch nicht sein oder? Ich kann mir doch pro Objekt verschiedene Shader setzen oder nicht?

Und was passiert, wenn ich mit einem Shader in eine Textur schreiben will? Einen Vertex-Shader brauche ich dann vermutlich nicht mehr, aber sagen wir mal, ich will der Einfachheit halber z.B. sowas machen, wie eine Textur, die irgendwo virtuell im Speicher liegt (z.B. eine Heightmap) samplen und einfach mit Hilfe eines Shaders in eine neue Textur schreiben. Wie komme ich denn dann an die Heightmap dran?

2

11.03.2010, 20:40

Natürlich kannst du pro Objekt verschiedene Shader setzen ;)

In eine Textur schreiben, kannst du mit Render - To Texture.
Einfach, die Ziel-Textur als Render-Target setzen, und dann ein Quad über die Gesamte Oberfläche, mit dem PIxel Shader Zeichnen.
Wenn du die Heightmap schon im Speicher hast, dann kommst du dran mit tex2D () und dem Richtigen Sampler.

3

13.03.2010, 21:04

Danke, das hilft mir schonmal sehr weiter. Bin mir nur noch nicht sicher, welche Koordinaten ich an die texture lookup function übergeben muss. Sagen wir also wieder ich hab irgendwo im Speicher eine Textur und möchte den wissenschaftlichen Durchbruch mit einem Shader schaffen, der diese Textur pixelweise sampled und kopiert. D.h. ich müsste auf beiden Texturen Pixel pro Pixel durchgehen und den Wert rüberkopieren. Wie gebe ich der texture lookup function dann an, an welchem Pixel ich gerade in der Zieltextur "bin"?

Also z.B.: texture(die_tex_im_speicher, *die Texturkoordinaten kommen woher*);

Brauch ich da gl_Fragcoord oder gl_Pointcoor?

Raff noch nicht so ganz, was die beiden Variablen genau bedeuten.

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

4

13.03.2010, 22:00

Du setzt die Ziel-Textur als Ausgabe-Framebuffer und renderst dann dort hinein als würdest du auf den Bildschirm malen. Im Falle deiner Heightmap könntest du also entsprechend viele "Vierecke" (in Form von je 2 Dreiecken bzw. eines langen Trianglestrips pro Zeile) zeichnen deren Farbwert du dann in deinem Pixelshader ermittelst.

Zu Shadern generell:
Du kannst pro Zeichenaufruf jeweils einen Pixel und Vertexshader aktivieren und brauchst immer beide. Natürlich kannst du in einem der beiden einfach einen 5-Zeiler schreiben, wenn du dort nichts besonders anstellen willst.

Was die Objekte anbelangt: Da gibt's verschiedene Ansätze. Prinzipiell kannst du pro "Objekt" mehr oder minder unendlich viele Shader verwenden, sprich reflektierende Motorhaube und ebenfalls leicht reflektierende Fenster mit Refraction-Effekt etc. pp.., musst es halt nur in einzelnen Aufrufen dann Stück für Stück zeichnen.

Ich persönlich habe es so gelöst, dass ich einen ziemlich langen Vertex und Fragment-Shader habe, die jeweils alles können, sprich von einem direkten Licht bis hin zu 8 lokalen, mit Reflektion oder ohne, mit Schatten oder ohne etc. pp. und habe quasi jeden dieser Effekte in einen #IFDEF-Block gepackt. Wenn ich dann ein Material bei der Ausgabe das aller erste mal nutze, wird anhand der Effekte, die genutzt werden, dessen eine Flag-ID errechnet. Gibt es diesen Shader (diese ID) bereits in meiner Shader-Liste, wird er benutzt, wenn nicht, werden die dafür nötigen #defines am Anfang des Fragment/Vertex-Shader-Quelltextes eingefügt die Shader compiliert und zur Shader-Sammlung hinzugefügt.

Ob das nun das gelbe vom Ei ist, sei mal dahin gestellt, aber so hat man einen eigentlich sehr gut wartbaren Alleskönner-Code der darüber hinaus auch seine sehr gute Performance-Liefert, da bis auf wenige Uniforms, um die man halt nicht ganz herum kommt, fast keine Ifs oder für den Compiler nicht vorhersehbare For-Schleifen mehr vorhanden sind.

LG
Alyx

CBenni::O

1x Contest-Sieger

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

5

13.03.2010, 22:22

Wenn wir grad dabei sind:

In vielen Shadern braucht man Globale Variablen. Es heißt immer, die muss man halt im Programm setzen. Aber wie? Das steht nie da...
Hoffe, ihr versteht, was ich meine...
mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

13.03.2010, 22:34

Das funktioniert in D3D(9) über die entsprechenden Funktionen des Effect Systems oder über ne Constant Table oder über die SetPixelShaderConstant*() Funktionen, je nachdem...

CBenni::O

1x Contest-Sieger

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

7

13.03.2010, 22:55

Jetzt weiß ich es ganz genau :?

Aber danke... vllt hilft mir ja Google weiter... aber nen link zu einem Tutorial fände ich natürlich auch nicht schlecht ;)

mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

13.03.2010, 23:00

Ich ging natürlich davon aus dass du schonmal irgendwie mit Shadern gearbeitet hast (Da du ja nach dem Wie? und nicht dem Warum? gefragt hast). Da dem scheinbar doch nicht so is will ich mich anders ausdrücken: Globale Variablen sind in nem Shader die Parameter die der Shader von deinem Programm bekommt (z.B. die Farbe des Objektes das gerendert werden soll). Deswegen muss dein Programm die entsprechenden Werte da eben reinschreiben...

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

9

13.03.2010, 23:01

Ich nehme an CBenni meine D3D, womit dot es beantwortet hätte. Das Gegenstück zu den "globalen" Variablen in GL wäre glUniform bzw. glUniformArray mit den Typen float/vector/matrix/int (und deren jeweiligen untertypen wie 2D/3D/4D etc.)).

Ja, das mit dem Effekt-System ist schon was feines bei Direct3D, das würde das Ganze deutlich komfortabler machen :-).

LG
Alyx

10

13.03.2010, 23:11

Im Code sieht das etwa so aus:

C-/C++-Quelltext

1
2
3
FX->SetFloat(...);
FX->SetMatrix(...);
FX->SetValue(...);

usw.

Werbeanzeige