Seite 1 von 1

Flexibler Shadercode

Verfasst: 29.03.2014, 13:47
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

Re: Flexibler Shadercode

Verfasst: 29.03.2014, 21:07
von antisteo
Anstatt einer Markup-Sprache benutze ich einfach einen Algorithmus, der die Shader-Quellcode-Strings aufgrund der Flags zusammensetzt.

Re: Flexibler Shadercode

Verfasst: 29.03.2014, 21:30
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

Re: Flexibler Shadercode

Verfasst: 30.03.2014, 18:41
von antisteo

Code: Alles auswählen

if color then fragment += 'result = color;' else fragment += 'result = texture2d(tex);

Re: Flexibler Shadercode

Verfasst: 31.03.2014, 00:19
von Chromanoid
Bei Langeweile könnte eine Implementierung von sowas auch ganz nett sein: http://libsh.org/

Re: Flexibler Shadercode

Verfasst: 31.03.2014, 16:44
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!

Re: Flexibler Shadercode

Verfasst: 31.03.2014, 18:53
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?

Re: Flexibler Shadercode

Verfasst: 31.03.2014, 20:19
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.

Re: Flexibler Shadercode

Verfasst: 31.03.2014, 22:34
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.

Re: Flexibler Shadercode

Verfasst: 01.04.2014, 09:34
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).

Re: Flexibler Shadercode

Verfasst: 01.04.2014, 19:36
von Chromanoid
Naja, mir C# kann man ja relativ leicht auch nach Auslieferung kompilieren. Das ist ja praktisch das gleiche, wie Lua einzusetzen...

Re: Flexibler Shadercode

Verfasst: 01.04.2014, 19:41
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

Re: Flexibler Shadercode

Verfasst: 01.04.2014, 19:45
von Chromanoid
Ah, stimmt verstehe. Da müsste man wohl mehr Zeit als gedacht reinstecken. Bin gespannt von Deiner finalen Lösung zu lesen!

Re: Flexibler Shadercode

Verfasst: 03.04.2014, 11:22
von xq
So, habe die ganze Sache jetzt implementiert:
Thread Post

Ich bin ganz zufrieden damit, spart einem sehr viel Arbeit.