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

Databyte

Alter Hase

  • »Databyte« ist der Autor dieses Themas

Beiträge: 1 040

Wohnort: Na zu Hause

Beruf: Student (KIT)

  • Private Nachricht senden

1

07.02.2010, 15:37

Ein paar fragen zu PixelShadern

Hi

Also ich habe ein paar fragen zur Pixelshadern...

1. Wenn man zum beispiel ein Raumschiff in einen Tarnmodus versetzen will und beim Unsichbarwerden das Schiff ein bisschen verschwimmen lassen will, kann man dafür ja am besten Pixelshader benutzen. So.. nur wann benutzt man diese ? Erst alle Raumschiffe rendern und dann nen Pixelshader auf das ganze bild anwenden ? oder bei jedem raumschiff den pixelshader laufen lassen ? aber der gilt ja auch immer nur für die pixel die das eigentliche raumschiff betreffen... oder macht man sowas gar nicht über pixelshader ?

2. Wenn man Pixelshader im Nachhinein anwenden will und zwar an mehreren stellen, muss man erst alles auf ein Surface rendern und dann halt immer wieder, bevor man es in den Backbuffen rendert ? Oder anders ?

3. Wenn ich jetzt nicht nur einen Shader benutzen möchte sondern mehrere geht das doch mit Fragmentshadern oder ? Also zum Beispiel soll das Raumschiff nicht nur getarnt weden, sondern auch noch von energieblitzen oder so überzogen sein...

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

07.02.2010, 15:56

Re: Ein paar fragen zu PixelShadern

Zitat von »"Databyte"«

1. Wenn man zum beispiel ein Raumschiff in einen Tarnmodus versetzen will und beim Unsichbarwerden das Schiff ein bisschen verschwimmen lassen will, kann man dafür ja am besten Pixelshader benutzen. So.. nur wann benutzt man diese ? Erst alle Raumschiffe rendern und dann nen Pixelshader auf das ganze bild anwenden ? oder bei jedem raumschiff den pixelshader laufen lassen ? aber der gilt ja auch immer nur für die pixel die das eigentliche raumschiff betreffen... oder macht man sowas gar nicht über pixelshader ?


Ja, Pixel Shader würden sich da vermutlich anbieten. Wann und wie man sie einsetzt hängt aber stark davon ab was für einen Effekt man konkret erreichen will.

Zitat von »"Databyte"«

2. Wenn man Pixelshader im Nachhinein anwenden will und zwar an mehreren stellen, muss man erst alles auf ein Surface rendern und dann halt immer wieder, bevor man es in den Backbuffen rendert ? Oder anders ?


Ja, man wird erst Zeug in Texturen rendern und dann diese Texturen mit entsprechenden Pixel Shadern in den Backbuffer rendern um was auch immer für Effekte zu erreichen. So eine Vorgehensweise fällt in den Bereich Post Processing.

Zitat von »"Databyte"«

3. Wenn ich jetzt nicht nur einen Shader benutzen möchte sondern mehrere geht das doch mit Fragmentshadern oder ? Also zum Beispiel soll das Raumschiff nicht nur getarnt weden, sondern auch noch von energieblitzen oder so überzogen sein...


"Fragment Shader" ist nur die etwas korrektere und in OpenGL übliche Bezeichnung für Pixel Shader. Du kannst nicht mehrere Pixel bzw Fragment Shader gleichzeitig anwenden. Du kannst aber z.B. das gleiche Modell mehrmals hintereinander mit verschiedenen Shadern rendern die so programmiert sind dass sich aus der Überlagerung ihrer Ergebnisse ein entsprechender Effekt ergibt oder z.B. einen kombinierten Shader aus mehreren einzelnen Shaderteilen zusammensetzen.

3

07.02.2010, 16:18

Da ich selber noch nie mit PixelShadern gearbeitet habe würde mich an dem Beispiel aber auch noch etwas interessieren.

Nehmen wir als simples Beispiel an, das Schiff soll durch diesen Tarnmodus einfach verblassen. Das würde Bedeuten, dass sich eigneltich nur der Alphawert vortlaufend ändert. Blos wie teilt man dem PixelSahder mit, in welchem Zeitraum des Vorganges er sich befindet? Gibt es da die Möglichkeit beim Rendern mindestens eine Zusatvariable zu übergeben?

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

4

07.02.2010, 16:34

Ja. Das kannst du mit Uniform Shader Inputs erreichen. Mit HLSL kannst du ganz einfach globale Variablen mit SetFloat des Effektes setzen.

Databyte

Alter Hase

  • »Databyte« ist der Autor dieses Themas

Beiträge: 1 040

Wohnort: Na zu Hause

Beruf: Student (KIT)

  • Private Nachricht senden

5

07.02.2010, 16:47

Re: Ein paar fragen zu PixelShadern

Zitat von »"dot"«

"Fragment Shader" ist nur die etwas korrektere und in OpenGL übliche Bezeichnung für Pixel Shader. Du kannst nicht mehrere Pixel bzw Fragment Shader gleichzeitig anwenden. Du kannst aber z.B. das gleiche Modell mehrmals hintereinander mit verschiedenen Shadern rendern die so programmiert sind dass sich aus der Überlagerung ihrer Ergebnisse ein entsprechender Effekt ergibt oder z.B. einen kombinierten Shader aus mehreren einzelnen Shaderteilen zusammensetzen.


Sry ich meinte FragmentManager... weil so wie hier beschrieben kann man ja mehrere Shader kombinieren... oder habe ich das falsch verstanden ?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

07.02.2010, 17:11

Re: Ein paar fragen zu PixelShadern

Zitat von »"Databyte"«

Sry ich meinte FragmentManager... weil so wie hier beschrieben kann man ja mehrere Shader kombinieren... oder habe ich das falsch verstanden ?


Das hast du richtig verstanden. In Direct3D9 kannst du einzelne Shader Fragmente kompilieren und zur Laufzeit verschiedene Fragmente dynamisch zu einem Shader linken. Der FragmentLinker ist allerdings etwas buggy und in D3D10 wieder abgeschafft. In D3D11 gibt es mit Dynamic Shader Linkage wieder eine ähnliche, wenn auch nicht gleiche Möglichkeit Shader dynamisch zu kombinieren.

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

7

07.02.2010, 17:24

Re: Ein paar fragen zu PixelShadern

Zitat von »"Databyte"«

Hi

Also ich habe ein paar fragen zur Pixelshadern...

1. Wenn man zum beispiel ein Raumschiff in einen Tarnmodus versetzen will und beim Unsichbarwerden das Schiff ein bisschen verschwimmen lassen will, kann man dafür ja am besten Pixelshader benutzen. So.. nur wann benutzt man diese ? Erst alle Raumschiffe rendern und dann nen Pixelshader auf das ganze bild anwenden ? oder bei jedem raumschiff den pixelshader laufen lassen ? aber der gilt ja auch immer nur für die pixel die das eigentliche raumschiff betreffen... oder macht man sowas gar nicht über pixelshader ?


Fängst gleich mit dem kompliziertesten Beispiel an :-). Was verstehst du denn genau unter "verschwimmen?" ^^ Wenn es seine eigentlich Silouette verlässt, brauchst du auf jeden Fall auch den VertexShader oder müsstest es erst in eine Textur rendern und die dann in einem Pixelshader verunschärfen... wobei letzteres halt Z-Buffer-technisch problematisch ist.

Zitat

2. Wenn man Pixelshader im Nachhinein anwenden will und zwar an mehreren stellen, muss man erst alles auf ein Surface rendern und dann halt immer wieder, bevor man es in den Backbuffen rendert ? Oder anders ?


Je nachdem was genau du machen willst. Bis vor einigen Jahren gab es ja zum Beispiel noch gar keine "Surfaces". Da war es dann gang und gebe z. Bsp. erst sämtliche Lightmaps zu zeichnen und anschließend multiplikativ die Basis-Texturen an die selbe Stelle, so dass sie dadurch dann ihre Beleuchtung erhalten haben.

Zitat


3. Wenn ich jetzt nicht nur einen Shader benutzen möchte sondern mehrere geht das doch mit Fragmentshadern oder ? Also zum Beispiel soll das Raumschiff nicht nur getarnt weden, sondern auch noch von energieblitzen oder so überzogen sein...


Ja. Ich weiß nicht wie's in DirectX aussieht, aber in OpenGL habe ich das im GLSL-Code dann einfach mit IFDEFs gelöst, die auf C++-Seite dann entsprechend am Quelltext-Anfang gesetzt werden, je nachdem was gebraucht wird. Sieht in der Praxis dann ca so aus:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
    #if COLORED_VERTICES==1
        #define AColorScale(X) (vsOutColor*(X))
    #else
        #define AColorScale(X) (X)
    #endif

    #if REFLECTION==1
        fragColor = AColorScale(vec4(mix(DiffColor.xyz,AddCol,AddCol.x*shin)+specu,DiffColor.w));
    #else
        fragColor = AColorScale(vec4(DiffColor.xyz+specu.xyz,DiffColor.w));     
    #endif


In dem Fall wird COLORED_VERTICES gesetzt, wenn das 3D-Model gefärbte Vertices hat. Ähnlich könnte man es auch mit Effekten lösen, sprich wenn Effekt an, dann compilier es mit rein, wenn Effekt aus dann lass es weg. Mit Uniforms wäre ich vorsichtig.
Es gibt Stellen, wo man einfach nicht drumrum kommt wie z.Bsp. Matritzen, aber für alles, was wirklich Effekt-spezifisch ist, sei es Shadow Maps, Reflekion, Refraktion, Bump Map & Co., sollte man auf keinen Fall mit Uniforms arbeiten, um diese an oder auszuschalten, denn die Grafikkarte führt den Quelltext trotzdem aus, das Ergebnis wird nur später ignoriert, sprich um so mehr Effekte du im Shader hast, um so langsamer wird dein Programm. Man darf also nicht denken, weil da ein if( Blitzeffekt ) {} steht und Blitzeffekt auf 0 steht, würde das keine Performance kosten, das kostet sogar sehr viel.
Intern sieht das nämlich dann so aus:

HLSL-Code:
Farbe = Rot;
if( Blitzeffekt )
{
Farbe = Farbe + 0.5;
}
Pixel = Farbe;

In der GPU:

Pixel = Farbe + (BlitzEffekt ? 0.5 : 0.0).

Und jetzt stell dir mal vor du hast nun nen Shader mit allen gängigen Effekten, von denen aber nur einer aktiv ist, dann rechnet er dir da 200 Berechnungen aus, von denen dann aber 199 Ergebnisse verworfen werden ;-).
Neuere GPUs sind da mittlerweile schon ein Stück schlauer und führen effektiveres Branching durch, aber generell sollte man den Code, der später wirklich bei der Grafikkarte landet so schlank wie nur irgend möglich halten oder darf sich hinterher über seine FPS nicht mehr wundern ;-).

EDIT: Ok, dot war mal wieder schneller :-). In Direct3D dann via FragmentLinker.. oder halt doch via IFDEF, wie mans mag, in GL geht nur letzteres :-P.

LG
Alyx

Tobiking

1x Rätselkönig

  • Private Nachricht senden

8

07.02.2010, 18:28

Bei einem Tarn Effekt für Raumschiffe würde ich zuerst an eine Art Refraktion denken. Man kann durch das Schiff durchgucken, aber der Hintergrund ist verschwommen/verzerrt. Vielleicht eine Art Glas Shader mit geeigneten IOR.

Werbeanzeige