Generelle Fragen zu Shadern (hlsl)

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Benutzeravatar
fork
Beiträge: 4
Registriert: 11.01.2012, 20:25

Generelle Fragen zu Shadern (hlsl)

Beitrag von fork »

Hallo zusammen,

Ich moechte euch heute mit ein paar Fragen rund um Pixel- und Vertexshader quaelen :shock: . Fangen wir an! :D

Einige Fragen beziehen sich auf dieses Konstrukt:

Code: Alles auswählen

struct VS_OUTPUT
{
	float4 hpos : SV_POSITION;
	float2 texcoords : TEXCOORDS0;
	float3 normal : TEXCOORDS2;
	float3 pos : POSITION;
	float fog : FOG;
};
SV_POSITION: Wofuer steht SV? (ShaderVertex?)
Unterschied SV_POSITION und POSITION?
Wofuer "hpos" stehen koennte ist mir unklar, ist damit "homogenous" pos gemeint?

(Wieso) Gibt es fuer Normalen keinen "spezifizierer", da hier ueber "TEXCOORDS2" ausgewichen wird?
Fuer FOG gibts doch auch einen, und Normalen werden doch sicher haeufiger als fog gebraucht.

Ist es sinnvoll, World -, View-, und Projectionmatrix einzeln zu uebergeben oder besser eine einzige "worldviewprojection"-Matrix zu uebergeben? Vor- und Nachteile?

Zu:

Code: Alles auswählen

float4 PxShader(VS_OUTPUT input) : SV_Target0
Was spezifiziert "SV_Target0"? Vermutlich das "Standardziel". Was genau ist damit gemeint, was sind alternative Werte (SV_Target2?) und was ist damit erreichbar?


Muss die Reihenfolge der Member des Constant Buffers in Cpp-Datei und Shader uebereinstimmen?

Wie genau haut das mit dem Pixelshader hin?
Setze ich 'nen Shader a 'la

Code: Alles auswählen

devcon->PSSetShader(pixelshader, nullptr, 0)
, gefolgt von einer draw-methode werden "nur" die pixel des gezeichneten geshaded, richtig? Was muesste ich tun, moechte ich das ganze Programm in einen sepia-ton versetzen? Muss ich dafuer extra ein 4-eck anlegen, das dann vor die kamera halten, einfaerben und mit transparenz rendern?
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Generelle Fragen zu Shadern (hlsl)

Beitrag von Krishty »

fork hat geschrieben:SV_POSITION: Wofuer steht SV? (ShaderVertex?)
System Value; siehe http://msdn.microsoft.com/en-us/library ... stem_Value.
fork hat geschrieben:Unterschied SV_POSITION und POSITION?
SV_POSITION wird als Systemwert von der Laufzeitumgebung bzw. Hardware bereitgestellt, während es sich bei POSITION um einen Wert handelt, den der Anwendungsprogrammierer über die Deklaration seines Vertex-Formats bereitstellt.. POSITION ist ein Direct3D-9-Register, das dir die Hardware bereitstellt, um die Position des Vertex im Objektkoordinatensystem aus dem Vertex- in den Pixel-Shader zu übertragen.
fork hat geschrieben:(Wieso) Gibt es fuer Normalen keinen "spezifizierer", da hier ueber "TEXCOORDS2" ausgewichen wird? Fuer FOG gibts doch auch einen, und Normalen werden doch sicher haeufiger als fog gebraucht.
Die Texturkoordinatenregister haben sich zu Allzweckregistern etabliert, in denen alles übergeben wird, was nicht direkt durch die Hardware bereitgestellt wird. Da die Berechnung von Vertex Fog in Hardware geschieht, wird sie in einem eigenen Register bereitgestellt (wie auch die Vertexposition für den Pixel-Shader in SV_POSITION, die nach dem Vertex Shader von der Hardware für jedes Sample in Bildschirmkoordinaten umgerechnet wird!). Afaik gab es mal ein NORMAL-Register zu Direct3D-9-Zeiten, das immer nur zwecks Abwärtskompatibilität da war.
fork hat geschrieben:Ist es sinnvoll, World -, View-, und Projectionmatrix einzeln zu uebergeben oder besser eine einzige "worldviewprojection"-Matrix zu uebergeben? Vor- und Nachteile?
Matrixmultiplikationen kosten enorm viel; darum solltest du sie im Shader vermeiden. Es gibt allerdings auch Anwendungsbereiche, in denen eine Aufteilung zwingend nötig ist – beispielsweise bei Fällen von Vertex Skinning und Beleuchtung, wo du vom Objekt- ins Weltkoordinatensystem umrechnen können musst.
fork hat geschrieben:Was spezifiziert "SV_Target0"? Vermutlich das "Standardziel". Was genau ist damit gemeint, was sind alternative Werte (SV_Target2?) und was ist damit erreichbar?
Es besagt, welches Render Target mit dem Pixel beschrieben werden soll. Damit kannst du in mehrere Render Targets schreiben; bspw. um eins mit Farben zu füllen und weitere mit Normalen und Materialinformationen (für Deferred Shading), oder um die sechs Seiten einer Würfeltextur in einem Rutsch zu zeichnen.
fork hat geschrieben:Muss die Reihenfolge der Member des Constant Buffers in Cpp-Datei und Shader uebereinstimmen?
Nein. Falls die Reihenfolge unterschiedlich ist, musst du aber via packoffset() die tatsächliche Position der Daten von Hand angeben (bspw. float3 vec : packoffset(c3); um zu sagen, dass vec das vierte 16-Byte Register der Konstanten belegt, also 64 B vom Anfang deiner Daten beginnt). Der Shader Compiler kann halt nicht raten, wie der C++-Text aussieht, von dem der Shader irgendwann mal aufgerufen werden wird. (Wie es dabei mit dem FX-Framework aussieht, weiß ich nicht.)
fork hat geschrieben:Was muesste ich tun, moechte ich das ganze Programm in einen sepia-ton versetzen? Muss ich dafuer extra ein 4-eck anlegen, das dann vor die kamera halten, einfaerben und mit transparenz rendern?
Genau. Oder das Programm in eine Textur zeichnen lassen, die du im Pixel-Shader des Vierecks lädst, manipulierst und rausschreibst.

Ich muss bei meinem HDR Rendering sowieso erst alles in einen internen Puffer zeichnen, da die Farbtiefen von keinem Bildschirm unterstützt werden und deshalb nicht als Swap Chain zur Verfügung stehen. Am Ende setze ich einen Shader, der diese internen Daten ausliest, Tonemapping anwendet, Anti-Aliasing und Farbkorrektur darauf anwendet, und das dann in die Swap Chain im gewöhnlichen 32-Bit-RGB-Format schreibt. (Nur als Beispiel.)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Andre
Establishment
Beiträge: 186
Registriert: 21.12.2011, 20:33

Re: Generelle Fragen zu Shadern (hlsl)

Beitrag von Andre »

(Ninja'd)
SV_POSITION: Wofuer steht SV? (ShaderVertex?)
Unterschied SV_POSITION und POSITION?
Wofuer "hpos" stehen koennte ist mir unklar, ist damit "homogenous" pos gemeint?

(Wieso) Gibt es fuer Normalen keinen "spezifizierer", da hier ueber "TEXCOORDS2" ausgewichen wird?
Fuer FOG gibts doch auch einen, und Normalen werden doch sicher haeufiger als fog gebraucht.
Ab DirectX10 sind Semantics mit einem "SV_" davor eine sogenannte "System-Value". Das heißt, dass diese Variable direkt von der GPU zu irgendetwas gebraucht wird. Wobei SV_POSITION dort eigentlich SV_Position heißen müsste. Soweit ich weiß war die Groß- und Kleinschreibung dort ebenfalls wichtig.
Auf jedenfall holt sich die GPU aus SV_Position die auf den Bildschirm projizierte Koordinate von dem Vertex, welches eben durch den VertexShader gegangen ist.

Diese Sachen wie FOG und NORMAL scheinen noch ein Überbleibsel aus DirectX9 zu sein, wo diese wohl noch etwas zu sagen hatten. Heute kann man diese Semantics eher zum besseren Verständnis benutzen.
Es kann aber auch sein, dass man sich diese Teile aber auch komplett selber ausdenken darf, wenn ich mal die Doku und dein Codeschnipsel hier vergleiche. Ich hab mich bis jetzt immer strickt nach Doku gerichtet. :lol:
Jedenfalls beim VertexShader-Input weiß ich, dass man das darf. Dafür legt man aber auch sein eigenes VertexLayout an.
Ist es sinnvoll, World -, View-, und Projectionmatrix einzeln zu uebergeben oder besser eine einzige "worldviewprojection"-Matrix zu uebergeben? Vor- und Nachteile?
Der Vorteil an einer WorldViewProjection-Matrix ist, dass man nur ein mul() zu machen braucht um sein Vertex zu Transformieren. Allerdings wird der Shader die drei Matrizen auch erkennen und selber zusammen fassen können. Wie genau dies nun von statten ging weiß ich leider auch nicht genau.
Du wirst allerdings höchstwahrscheinlich auch eine seperate World- und View-Matrix brauchen.
Was spezifiziert "SV_Target0"? Vermutlich das "Standardziel". Was genau ist damit gemeint, was sind alternative Werte (SV_Target2?) und was ist damit erreichbar?
SV_Target0 ist das selbe wie SV_Target. Benutzen tut man es, wenn man mit MRTs arbeitet, also "MultipleRenderTargets". Man kann nämlich mehr als ein Rendertarget einsetzen, wenn man mit einem nicht auskommt. Techniken wie DeferredShading brauchen dies, da man sowohl Farbinformationen, als auch die Normals und noch einiges andere in einer Textur braucht.
Ohne MRTs müsste man seine Scene viel öfter rendern. Soweit ich weiß kann man ab DX10 bis zu 8 MRTs benutzen. Und dafür gibt es dann auch SV_Target-Variablen von 0 bis 7.
Was muesste ich tun, moechte ich das ganze Programm in einen sepia-ton versetzen? Muss ich dafuer extra ein 4-eck anlegen, das dann vor die kamera halten, einfaerben und mit transparenz rendern?
Das fällt unter PostProcessing. Du könntest natürlich auch jedem Shader deiner Objekte diesen sepia-ton geben, aber das wird schnell unflexibel. Mit deiner Vermutung, dass man ein "Fullscreen-Quad" dazu braucht liegst du ebenfalls richtig. Man kann auch ein "Fullscreen-Triangle" benutzen . ;)
Antworten