Flexibler Shadercode

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Benutzeravatar
xq
Establishment
Beiträge: 1590
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Flexibler Shadercode

Beitrag von xq »

Hallo!

Ich bastel grade fleißig an dem Shader-System meiner Engine und habe festgestellt: Ich brauche irgendeine Art von Markup-Sprache für die Shader (ähnlich Unitys Shaderlab).
Kurzinfo: OpenGL 4, .NET

Da meine Shader von der Engine dynamisch compiliert werden sollen je nach Anforderungen an den Shader (Deferred, Forward, Tiled Forward, ...), ich aber dem User immer noch Kontrolle über Custom-Shader geben möchte dachte ich mir folgendes:

Ein Shader besteht mindestens aus Vertex- und Fragment-Shader, Tesselation und Geometry ist ja optional. Ein Deferred-Renderer benötigt ja aber für Custom-Objekt-Shader mit Tesselation deren Vertex-Shader, Tesselation-Stage, aber nicht den Fragment-Shader.
Daher hat mein System die Möglichkeit, einen Shader zu selektieren. Die Selektion erfolgt nach Shader-Klasse (Der Name des Renderers) und einigen Override-Shadern (Obiges Beispiel: Fragment-Shader für Geometry-Stage).

Ich habe jetzt ein bisschen rumprobiert und bin zu dem Schluss gekommen, dass Lua eine schöne Möglichkeit für die Markup-Language wäre:

Code: Alles auswählen

-- We compile with GLSL Version 3.3
shader.version = "330"

-- Add a global shader source file that is accessible from all shaders:
shader.add
{
	type = "global",
	source = 
[[
	uniform mat4 matWorld;
	uniform mat4 matView;
	uniform mat4 matProjection;
	uniform sampler2D meshDiffuseTexture;
]]
}

-- Add a vertex shader. The input variables and layout is specified by the input entry
shader.add
{
	type = "vertex",
	input = "mesh",
	source = 
[[
	out vec2 uv;

	void main()
	{
		vec4 pos = vec4(vertexPosition, 1);
		gl_Position = matProjection * matView * matWorld * pos;
		
		uv = vertexUV;
	}
]]
}

-- Add a fragment shader. Simple alpha-testing shader.
shader.add
{
	type = "fragment",
	source = 
[[
	layout(location = 0) out vec4 color;
	in vec2 uv;
	void main()
	{
		color = texture(meshDiffuseTexture, uv);
		if(color.a < 0.5f) discard;
	}
]]
}
Das schöne daran ist, dass der GLSL-Code ohne Veränderung in Lua einfügbar ist, da in GLSL weder [[ noch ]] vorkommt. Zudem kann man sogar Endsystemabhängigen Shadercode produzieren, welcher "dynamisch" Konstanten ändern kann.

Was meint ihr? Kann man das so ohne Probleme nutzen oder stößt man dabei irgendwann auf unschöne Probleme?

Grüße
Felix
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
antisteo
Establishment
Beiträge: 941
Registriert: 15.10.2010, 09:26
Wohnort: Dresdem

Re: Flexibler Shadercode

Beitrag von antisteo »

Anstatt einer Markup-Sprache benutze ich einfach einen Algorithmus, der die Shader-Quellcode-Strings aufgrund der Flags zusammensetzt.
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
Benutzeravatar
xq
Establishment
Beiträge: 1590
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: Flexibler Shadercode

Beitrag von xq »

Wie würde dass dann genau aussehen? Ich hatte eine Lösung mit #ifdef-Blöcken, aber das war irgendwie nicht sehr befriedigend
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
antisteo
Establishment
Beiträge: 941
Registriert: 15.10.2010, 09:26
Wohnort: Dresdem

Re: Flexibler Shadercode

Beitrag von antisteo »

Code: Alles auswählen

if color then fragment += 'result = color;' else fragment += 'result = texture2d(tex);
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4286
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Flexibler Shadercode

Beitrag von Chromanoid »

Bei Langeweile könnte eine Implementierung von sowas auch ganz nett sein: http://libsh.org/
Benutzeravatar
xq
Establishment
Beiträge: 1590
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: Flexibler Shadercode

Beitrag von xq »

@antisteo: Das ist ja mit meiner Lösung ohne weitere möglich, aber für große Shader wird sowas meist unschön.
@Chromanoid: Werd ich mir mal anschauen!
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4286
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Flexibler Shadercode

Beitrag von Chromanoid »

Ich würde mir sonst allg. mal Template-Engines für C++ anschauen. Die sind oft nicht ganz so invasiv wie herkömmliche Scriptsprachen. https://code.google.com/p/ctemplate oder das dort genannte https://github.com/breckinloggins/ngtemplate vielleicht?
Benutzeravatar
xq
Establishment
Beiträge: 1590
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: Flexibler Shadercode

Beitrag von xq »

Da meine Engine in C# programmiert wird, ist eine C++-Template-Bib nicht unbedingt das richtige dafür ;)
Zudem nutzen beide Systeme {{ und }} als Delimiter, was für GLSL-Code-Templates ebenfalls nicht unbedingt ideal ist, da die Zeichen so auch valide GLSL-Syntax sein können.

LibSh sieht zwar ganz nett aus, aber da steckt mir als Enduser der Library zu viel Aufwand dahinter, da man noch eine zusätzliche Shadersprache lernen müsste, zudem ist die Library zuletzt 2007 aktualisiert worden, wird also weder Geometry Shader noch Tesselation unterstützen.

Aber trotzdem ein großes Danke für die Links!

Ich habe inzwischen meine Lua-Lösung implementiert und bin doch überraschend zufrienden. Ich konnte die Anzahl an Objektshaderfiles in der Engine von 4 auf 2 reduzieren, da der Geometry-Pass-Shader und der Object-Pass-Shader des Deferred Renderes wegfallen.

Zudem habe ich laufzeitbedingt compilierte Shader, was mir ermöglicht, für versch. Plattformen versch. Shader zu implementieren oder auch ein einziges Shaderfile zu erstellen, welches einzelne Features an/abschalten kann.

Grüße
Felix

PS.: Die Diskussion darf gerne weitergehen, mein System mit ein paar Alternativen zu vergleichen und eventuelle Probleme zu finden ist ja immer noch Priorität.
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4286
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Flexibler Shadercode

Beitrag von Chromanoid »

Ah, das hatte ich überlesen. sorry, das hier sieht interessant aus, T4-Textvorlagen (Templating direkt mit C# Code): http://msdn.microsoft.com/de-de/library/ee844259.aspx (ich glaube das würde ich nehmen)
@{{ es gibt ja immer auch Escape-Character, aber Du hast natürlich Recht.
Benutzeravatar
xq
Establishment
Beiträge: 1590
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: Flexibler Shadercode

Beitrag von xq »

Ich hab mir nochmal Gedanken zu Templating gemacht und hab festgestellt, dass es nicht unbedingt so pralle ist. Ich hab zwar durch Templating die gleichen Grundvoraussetzungen (bedingte Kompilierung) wie mit Lua erfüllt, kann aber keine beliebigen Meta-Daten einfügen, welche dann später in der Engine abgerufen werden können.
Zudem möchte ich noch ein Uniform-Aliasing einfügen, welches dem User erlaubt, Mehr als einen Namen für ein Uniform zu definieren (take code, make it fit).
Sobald ich wieder an meinem Rechner bin, werde ich auch mal noch ein paar Beispiele in meinem Engine-Thread dazu posten.

@Chromanoid: T4 ist eine verdammt coole Technik, aber ist halt Compiletime und nicht Runtime. Da ich gerne ein Shader-Tool für meine Engine anbieten möchte, ist mir eine Runtime-Lösung lieber (man will ja nicht nach jeder Code-Anpassung im Shader das Spiel/Tool neu compiliert und gestartet werden soll).
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4286
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Flexibler Shadercode

Beitrag von Chromanoid »

Naja, mir C# kann man ja relativ leicht auch nach Auslieferung kompilieren. Das ist ja praktisch das gleiche, wie Lua einzusetzen...
Zuletzt geändert von Chromanoid am 01.04.2014, 19:45, insgesamt 2-mal geändert.
Benutzeravatar
xq
Establishment
Beiträge: 1590
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: Flexibler Shadercode

Beitrag von xq »

Ja gut, nur dass ich mir damit den global Namespace vollhau, den ich bei Lua direkt nach dem Laden einfach wieder freigeben kann ;)
Zudem ist Lua im Gegensatz zum CSC ja doch recht resourcenschonend und es ist leichter zu lernen
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4286
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Flexibler Shadercode

Beitrag von Chromanoid »

Ah, stimmt verstehe. Da müsste man wohl mehr Zeit als gedacht reinstecken. Bin gespannt von Deiner finalen Lösung zu lesen!
Benutzeravatar
xq
Establishment
Beiträge: 1590
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: Flexibler Shadercode

Beitrag von xq »

So, habe die ganze Sache jetzt implementiert:
Thread Post

Ich bin ganz zufrieden damit, spart einem sehr viel Arbeit.
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

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