Alpha Blended Shader Optimieren

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Benutzeravatar
marcgfx
Establishment
Beiträge: 1593
Registriert: 18.10.2010, 23:26

Alpha Blended Shader Optimieren

Beitrag von marcgfx »

In Devader benutze ich für alle Objekte einen einzigen Shader. Depth-Test ist deaktiviert und ich rendere alle Polygone sortiert. Alle Effekte die ich benutzen kann sind demnach in diesem Shader definiert. Was eingesetzt werden soll ist abhängig vom "mode" Parameter. Der "mode" Parameter enthält zusätzlich Information zur Farbe und Opacity meines Objekts.

Die Nachkommastellen von "mode" beinhaltet Information über den angewendeten exklusiven Effekt, ursprünglich gab es davon 10.
0.0 - 0.1 : Sinus basiertes Blinken, wird für die Hexas verwendet
0.1 - 0.2 : -
0.2 - 0.3 : -
0.3 - 0.4 : Aufflackern einer Einheit wenn sie Schaden nimmt, bei vollen HP Weiss, fast tot Magenta
0.4 - 0.5 : Helligkeit
0.5 - 0.6 : -
0.6 - 0.7 : Rot Einfärben, 0.6999 ist komplett Rot
0.7 - 0.8 : Sterbendes Objekt, zerstäuben/zerfallender Effekt
0.8 - 0.9 : -
0.9 - 1.0 : Blending Mode, 0.9 Normal 0.9999 Additive

smode ist der Wert ab der zweiten Nachkommastelle, also von 0.9532 ist es 0.0532. Um besser damit arbeiten zu können wird der Wert mit 10 multipliziert -> 0.532. smode wird überwiegend benutzt um die Stärke eines Effekts festzulegen.

Typische Code für ein Effekt sieht bei mir so aus:

Code: Alles auswählen

//0.6<mode<=0.7 make red
c.rgb = (mode>0.6 && mode<=0.7) ? c.rgb*nmode+vec3(smode*c.a, 0.0, 0.0) : c.rgb;
Ich überprüfe ob er Effekt angewendet werden soll, wenn ja wird er angewendet, wenn nicht wird der urspüngliche Wert zurückgegeben. Das habe ich damals so gemacht um IF Bedingungen zu vermeiden, aber es erscheint mir schon von Anfang an bescheuert. Nur man liest überall, dass man keine IF/Branching verwenden soll. Es Funktioniert jedenfalls, aber GPU ist vor allem bei integrierten Graphikkarten schon mein Hauptproblem.

Am meisten Sinn würde ein Switch statement machen, wäre es normaler Code, da jeder Effekt exklusiv ist. Dazu kommt dass jeder Effekt pro Polygon garantiert immer gleich ist, also wäre zumindest ein Teil in den Vertex-Shader verlagerbar. Da ich mit Alpha-Blending alles sequentiell zeichnen muss, wird vermutlich die GPU die Polygone einzeln abarbeiten. Aber ich habe eigentlich keine Ahnung.

Dazu kommt, Ich weiss überhaupt nicht wie ich Shader testen soll. Trial and Error scheint das einzige zu sein, aber ich habe auch nicht ausreichend Testgeräte für sowas.

Was denkt ihr?

Code: Alles auswählen

	float smode = fract(mode*10.0);
	float nmode = 1.0-smode;

	//0.7<mode<=0.8 dying
	bool dying = mode>0.7 && mode<=0.8;
	float x = v_tex.x;
	float y = (dying && nmode<1.0 && nmode!=0.0) ? fallApart(pos, nmode, smode) : 1000.0;
	vec2 texpos = y==1000.0 ? pos : v_coord + vec2(x, y)*v_size;

	//if dying and coordinates for look up outside of texture bounds -> can be discarded or alpha = 0, what is better???
	if(dying && (y<0.0 || y>1.0 || x<0.0 || x>1.0)){
		//gl_FragColor = vec4(0.0,0.0,0.0,0.0);
		//return;
		discard;
	}

	//squared randomized value, only used if the object is dying
	float r2 = dying ? sqr(rand(pos+v_pos*vec2(smode,smode))) : 0;

	vec4 c = texture2D(u_image, texpos)*(dying && nmode<0.5 ? (r2>nmode*2.0 ? 0.0 : min(nmode*6.0,1.0)) : 1.0);

	//alpha value of received texture from atlas is 0 -> discard it
	if(c.a==0.0) discard;

	//0.6<mode<=0.7 make red
	c.rgb = (mode>0.6 && mode<=0.7) ? c.rgb*nmode+vec3(smode*c.a, 0.0, 0.0) : c.rgb;
	//0.9<mode additive blending
	bool additive = mode>0.9;
	c.a *= additive ? nmode : 1.0;
	//mode with bright elements being additive, dark elements normal composition
	bool shot = mode>0.5 && mode<=0.6;
	c.a *= (shot && c.a>0.0) ? (1.0-c.r)*(1.0+c.r*(0.3/c.a-nmode)) : 1.0;
	c.rgb = (shot) ? (c.rgb+c.r*0.2*max(smode,0.0))*(1.0+c.a*2.5)*max(smode-0.1,0.0) : c.rgb;
	//0.4<mode<=0.5 brightness
	c.rgb = (mode>0.4 && mode<=0.5) ? (c.rgb+c.r*0.2*max(smode,0.0))*(1.0+c.a*9.0)*max(smode-0.1,0.0) : c.rgb;

	//0.3<mode<=0.4 unit damage highlight
	bool hurt = (mode>0.3 && mode<=0.4);
	dec = hurt ? 0.0 : dec;
	float ca2 = 2.0*max(0.0,c.a-0.5);
	float mx = max(max(c.r,c.g),c.b);
	//smode = 0.0; dec = 0.0;
	float asmode = ca2*smode;
	c.rgba = hurt ? vec4(ca2*mx, min(1.0,(asmode-0.25)*1.75)*mx, 3.0*max(0.0,max(asmode-0.333,(0.125-smode)*ca2))*mx, ca2)*2.0 : c.rgba;

	//0.0<mode<=0.1 sinus blink
	c.rgb*= (mode<=0.1) ? (1.0+smode*abs(sin(smode*1000.0+u_time*fract(smode*10.0)))) : 1.0;
Benutzeravatar
Schrompf
Moderator
Beiträge: 4117
Registriert: 26.02.2009, 00:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Alpha Blended Shader Optimieren

Beitrag von Schrompf »

Hast Du denn nachgemessen, dass die Fillrate der GPU überhaupt Dein Problem ist? Ich weiß, das ist jetzt nicht die Antwort, die Du hören willst (die kommt noch), aber dessen solltest Du Dir zuerst sicher sein. Also a) wartest Du überhaupt auf die GPU, oder kann Dein Programm auch kleine GPUs gar nicht schnell genug mit Arbeit füttern? Und b) falls Du auf die GPU wartest, liegt es denn wirklich an der Fillrate? Also am Fragment Shader? Das kannst Du rauskriegen, wenn Du exakt das selbe Bild einfach in ein kleineres Fenster renderst und beobachtest, ob es dadurch schneller wird. In einer idealen Welt linear mit der Fensterfläche, also quadratisch mit der Fensterdiagonale.

Und zum Shader: dort ist nix Dramatisches zu sehen, ehrlich gesagt. Jeder einzelne Effekt besteht nur aus ein bissl MathOps. Der einzige Pfad, bei dem ich mir vorstellen könnte, dass er eine nennenswerte Belastung ist, ist der Sinus. Man kann heutigen GPUs schon ein bissl Branching zumuten - mit "heutig" meine ich alles der letzten zehn Jahre. Branching ist nur dann ein Problem, wenn nahe beieinander liegende Pixel verschiedene Pfade nehmen. Und bei Dir nehmen ja alle Pixel eines Sprites den selben Pfad, Du hast also nahezu perfekte Branch Coherence. Also probiere mal, echtes if() einzusetzen: zuerst beim Sinusblinken, dann testweise mal bei Allen.

Die echte Lösung wäre natürlich, verschiedene Shader für verschiedene Einsatzzwecke zu verwenden. Ich persönlich glaube, mit Deinem Bestreben nach "möglichst wenige DrawCalls" bist Du ein wenig über's Ziel hinausgeschossen. Der Sweet Spot der StateChange-Optimierung dürfte selbst bei gutem altem OpenGL bei ein paar Dutzend / ein paar wenigen Hundert Shaderwechseln liegen. Du bist bei Einem. Spekulation Es kann also gut sein, dass Du tatsächlich was raus holst, indem Du Shader Switches wieder einbaust. Vorausgesetzt, Du hast wie oben sicher festgestellt, dass wirklich die Fillrate der Flaschenhals ist.
Häuptling von Dreamworlds. Baut an was Neuem. Hilft nebenbei nur höchst selten an der Open Asset Import Library mit.
Benutzeravatar
marcgfx
Establishment
Beiträge: 1593
Registriert: 18.10.2010, 23:26

Re: Alpha Blended Shader Optimieren

Beitrag von marcgfx »

Danke Schrompf, die Antwort find ich schon super. Ich bin mir ziemlich sicher, dass es die Fillrate ist auf meinem mini PC mit integrierter Graphikkarte. Ebenso auf meinem MacBook/LinuxBook (beide schon 7+ Jahre alt). Reduziere ich die Auflösung läuft es überall deutlich besser ohne das ich sonst was ändern muss. Ob das linear ist, weiss ich ehrlich gesagt nicht :)

State Changes sind bei WebGL anscheinend viel schlimmer als bei OpenGL, da hier gewissen Sicherheitsmassnahmen zu mehr overhead führen. Wusste ich ehrlich gesagt nicht bis gestern abend. Der eigentliche Grund wieso ich nur einen Shader habe, ist weil ich keine State Wechsel machen kann (glaub ich zumindest). Da ich sequentiell rendere wegen Alpha-Blending müsste ich nach jedem Poly einen Statewechsel machen. Sicher bin ich mir nicht, ich habe es nie anders versucht.

Du sagst es ja richtig "Probiere". Werd ich machen, direkt zum switch statement. Mit einem Flag sollte ich recht einfach zwischen Versionen wechseln können. Ich hasse es eigentlich auf anderen Systemen testen zu müssen, weil ich dort eigentlich meine ganze Umgebung aufsetzen müsste. Also läuft es darauf aus, dass ich einen neuen Build mache den rüberkopiere und starte. Nicht sehr effizient, aber in diesem Fall macht es Sinn.
Spiele Programmierer
Establishment
Beiträge: 408
Registriert: 23.01.2013, 16:55

Re: Alpha Blended Shader Optimieren

Beitrag von Spiele Programmierer »

Leider ist es nicht einfach relativ allgemeingültige Aussagen zur Performance zu treffen. Einige Hersteller versuchen so viel wie irgendwie möglich geheim zu halten und es gibt einfach ne ganze Menge an Architekturen (besonders wenn man Handy-GPUs mitzählt).
Mein Wissensstand ist aber auch etwa das, was Schrompf schon gesagt hat: Verzweigungen sind kein Problem, solange alle GPU-Threads in einem Arbeitsblock die selbe Verzweigung nehmen. Falls das nicht der Fall ist, müssen alle verwendeten Verzweigungen ausgeführt werden und es werden ggf. unnütze Werte berechnet. Außerdem kann es Berichten zufolge zu Nachteilen bei der Registerallokation kommen, da auch für den kompliziertesten Code-Pfad genug Register bereitstehen müssen. Explizit überprüft habe ich das alles noch nicht, allerdings passt es zu meiner Erfahrung, dass Verzweigungen jetzt nicht so schlimm sind.

Hinblicklich darauf denke ich, dass es mit einem Shader schon nicht so schlecht ist. Ein paar Shader-Wechsel sind auch nicht dramatisch, allerdings spart man sich dann den Stress mit dem Hin- und- Herschalten zwischen verschiedenen Shadern. Wenn man abswechselnd mit dem einen Effekt und dann mit dem anderen Effekt zeichnen will, hat man ja sonst im schlimmsten Fall unbegrenzt viele Shader-Wechsel.

Ich würde allerdings ein switch verwenden und eine Ganzzahl direkt in den Shader durchgeben. Wenn du die Anzahl an Vergleichen und logischen Operatoren und so zusammenzählst, kommt man bei dir ja schon auf eine ganz schöne Menge. Außerdem willst du ja eigentlich explizite Verzweigungen, da die Ausführung bei dir extrem kohärent ist. Deswegen denke ich, dass in deinem Fall die "Conditional Move"-mäßige Formulierung richtig nach hinten los geht.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4117
Registriert: 26.02.2009, 00:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Alpha Blended Shader Optimieren

Beitrag von Schrompf »

Ich glaube, dass die ShaderCompiler ein switch eh nur zu einer Kette von if() kompilieren, weil es zumindest nach meiner diffusen Erinnerung im Intermediate Instruction Set von DX11 nix dergleichen gibt. Und die andere Art, wie ein CPU-Compiler switch umsetzt, ist eine Tabelle von Funktionszeigern. Funktionszeiger gibt es im InstructionSet der diversen Shader-Standards gar nicht, soweit ich weiß, auch wenn NVidia seit einigen Wochen mit C++17-Support, virtuellen Funktionen usw. wirbt. Und virtuelle Funktionen sind ja nix anderes als Funktionszeiger in ner Tabelle.

Aber mach, was Dir am Liebsten ist. Ausprobieren musst Du es eh.
Häuptling von Dreamworlds. Baut an was Neuem. Hilft nebenbei nur höchst selten an der Open Asset Import Library mit.
Benutzeravatar
marcgfx
Establishment
Beiträge: 1593
Registriert: 18.10.2010, 23:26

Re: Alpha Blended Shader Optimieren

Beitrag von marcgfx »

Am Ende liegt es vermutlich einfach am Alpha-Blending, aber ich versuch es jetzt noch etwas besser zu machen. Ein "switch" Statement gibt es anscheinend nicht in WebGL, zumindest gibt es eine Fehlermeldung und ich finde keine brauchbaren Infos dazu. Mein Code würde damit schon sehr viel hübscher ausschauen.

Code: Alles auswählen

	switch(state){
		 case(0): c.rgb *= 1.0+smode*abs(sin(smode*1000.0+u_time*fract(smode*10.0))); break;
		 case(3):
		 	dec = 0.0;
			float ca2 = 2.0*max(0.0,c.a-0.5);
		 	float mx = max(max(c.r,c.g),c.b);
		 	//smode = 0.0; dec = 0.0;
		 	float asmode = ca2*smode;
		 	c.rgba = vec4(ca2*mx, min(1.0,(asmode-0.25)*1.75)*mx, 3.0*max(0.0,max(asmode-0.333,(0.125-smode)*ca2))*mx, ca2)*2.0;
		 break;
		 case(4): c.rgb = (c.rgb+c.r*0.2*max(smode,0.0))*(1.0+c.a*9.0)*max(smode-0.1,0.0); break;
		 case(5): c.a *= (1.0-c.r)*(1.0+c.r*(0.3/c.a-nmode)); break;
		 case(6): c.rgb = c.rgb*nmode+vec3(smode*c.a, 0.0, 0.0); break;
		 case(9): c.a *= nmode; break;
	}
*** error in shader '[object WebGLShader]':ERROR: 0:119: 'switch' : Illegal use of reserved word
ERROR: 0:119: 'switch' : syntax error


Also doch IF ... zumindest kann mir keiner vorwerfen, dass ich es nicht versucht habe :) und ich bin schon etwas gespannt ob die Anpassung irgendwas bewirkt.
Spiele Programmierer
Establishment
Beiträge: 408
Registriert: 23.01.2013, 16:55

Re: Alpha Blended Shader Optimieren

Beitrag von Spiele Programmierer »

Hast du nicht in dem anderen Thread geschrieben, dass du inzwischen WebGL 2 verwendest? Ich kenne WebGL zwar nicht, aber laut dem Internet, basiert es auf OpenGLES 3.0. OpenGLES 3.0 unterstützt eigentlich schon switch-Ausdrücke. Kann es sein, dass du einfach noch nicht OpenGLES 3.0 GLSL verwendest? Also das du in deinem Shader noch nicht #version 300 es deklarierst?

Falls du doch nicht WebGL 2 verwenden kannst, würde ich vorschlagen, dass du die expliziten Verzweigungen wenigstens als binäre Suche schreibst. Also erstmal prüfen ob der Integer größer gleich 5 ist und so weiter. Dann brauchst du nur 3 Vergleiche anstatt Duzende wie in dem Code, wie du ihn zu Beginn gezeigt hast.

@Schrompf
Ich glaube nicht, dass DirectX 11 da so representativ ist. Das ist inzwischen mehr als 10 Jahre alt und selbst als es noch nicht so alt war, meine ich mich erinnern zu können, dass es bereits kritische Stimmen gab, dass der aggressive Compiler zu viele Informationen aus dem Quellcode verliert.

Wenn ich z.B. in die AMD GCN3 Dokumentation gucke, gibt es dort eine Sektion 4.6 "Arbitrary Divergent Control Flow", in der ein Fork/Join-Mechanismus beschrieben wird (Link). Ich vermute, dass andere Hardware-Hersteller ähnliche Funktionen bereitstellen. Insbesondere wenn man GPGPU machen will, wäre es ja schon sehr ungünstig, wenn so ein Mechanismus nicht zur Verfügung steht.
Benutzeravatar
marcgfx
Establishment
Beiträge: 1593
Registriert: 18.10.2010, 23:26

Re: Alpha Blended Shader Optimieren

Beitrag von marcgfx »

Oha, ja da hab ich mich ziemlich vertan. Danke @Spiele Programmierer. Ja ich habe heute morgen auf webgl2 umgestellt, aber es gab keine Konsequenzen. Jetzt weiss ich auch warum. Diese direktive habe ich nicht deklariert. Habe es eben mal gemacht und da kommen doch noch ein paar Umstellungen auf mich zu. Sehr gut zu wissen!!!

Ohne switch sieht der Code so aus:

Code: Alles auswählen

		if (state < 6) {
			if (state < 4) {
				if (state == 0) {
					c.rgb *= 1.0 + smode * abs(sin(smode * 1000.0 + u_time * fract(smode * 10.0)));
				} else {
					dec = 0.0;
					float
					ca2 = 2.0 * max(0.0, c.a - 0.5);
					float
					mx = max(max(c.r, c.g), c.b);
					//smode = 0.0; dec = 0.0;
					float
					asmode = ca2 * smode;
					c.rgba = vec4(ca2 * mx, min(1.0, (asmode - 0.25) * 1.75) * mx, 3.0 * max(0.0, max(asmode - 0.333, (0.125 - smode) * ca2)) * mx, ca2) * 2.0;
				}
			} else if (state == 4) {
				c.rgb = (c.rgb + c.r * 0.2 * max(smode, 0.0)) * (1.0 + c.a * 9.0) * max(smode - 0.1, 0.0);
			} else {//5
				additive = 1.0;
				c.a *= (1.0 - c.r) * (1.0 + c.r * (0.3 / c.a - nmode));
			}

		} else if (state == 6) {
			c.rgb = c.rgb * nmode + vec3(smode * c.a, 0.0, 0.0);
		} else {
			c.a *= nmode;
			additive = 1.0;
		}
Benutzeravatar
marcgfx
Establishment
Beiträge: 1593
Registriert: 18.10.2010, 23:26

Re: Alpha Blended Shader Optimieren

Beitrag von marcgfx »

Hat jetzt doch geklappt mit dem switch statement schon viel hübscher anzusehen. Danke an alle für die Hilfe! Ob es schneller ist wird sich noch zeigen.
Benutzeravatar
marcgfx
Establishment
Beiträge: 1593
Registriert: 18.10.2010, 23:26

Re: Alpha Blended Shader Optimieren

Beitrag von marcgfx »

Ein weiterer (vermutlich) rechenintensiver Schritt ist in meinem Shader ist die Hue-Rotation. Dafür wird der RGB Wert zuerst in HSV umgewandelt, der HSV Wert wird manipuliert und wieder in RGB konvertiert.

Code: Alles auswählen

vec3 rgb2hsv(vec3 c) {
	vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
	vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
	vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
	float d = q.x - min(q.w, q.y);
	float e = 1.0e-10;
	return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
vec3 hsv2rgb(vec3 c) {
	vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
	vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
	return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

...
vec3 hsv = rgb2hsv(ref);
hsv.x += hue;
hsv.y *=sat;
hsv.z *= brightness;
vec3 col = hsv2rgb(hsv);
...
	
Da ich heute schon die gute Idee hatte die Helligkeit über einen Array-Lookup zu lösen anstatt über eine Formel, hab ich mir gedacht ich könnte das auch mit der Hue-Rotation versuchen. Meine Annahme war, dass ich die RGB Kanäle einzeln Hue-Rotieren kann um sie danach wieder zusammenzufügen. Da es in Devader nur 100 mögliche Hue Werte gibt, berechne ich für diese Werte jeweils die RGB Umwandlung. Dies Ergibt einen fixen Float-Array mit 300 Einträgen. Weiss nicht ob sowas schlecht ist?

Code: Alles auswählen

int index = hue*3;
vec3 hue3 = vec3(rgbHue[index++],rgbHue[index++],rgbHue[index]);
vec3 col = ref.r * hue3 + ref.g *hue3.gbr + ref.b * hue3.brg;
Erstaunlicherweise hat alles sofort geklappt. Sogar meine Annahme das Grün und Blau mit gbr respektive brg multipliziert werden müssen.

Bild
Benutzeravatar
marcgfx
Establishment
Beiträge: 1593
Registriert: 18.10.2010, 23:26

Re: Alpha Blended Shader Optimieren

Beitrag von marcgfx »

Wenn ich schon dabei bin, muss ich auch diese Frage stellen die vermutlich keine einfache Antwort hat. Ab wann lohnt es sich Kalkulationen in den Vertex-Shader zu verlagern? Ich habe ein paar leichte Variableninitialisierungen, die ich schon auslagern könnte. Gibt es einen overhead für die Werte die zwischen Vertex und Fragment-Shader übergeben werden?

Diese Werte sind pro Polygon immer gleich:

Code: Alles auswählen

	//texture position in atlas
	vec2 pos = v_coord + v_tex * v_size;
	//detect positive or negative mode
	float stp = step(0.0,v_mode);
	//mode contains alpha/hue/effect
	float mode = mix(-(v_mode+1.0), v_mode, stp);
	//remove effect information
	float dec = floor(mode);
	//only effect information
	mode = fract(mode);
	//effect specific value, usually some kind of fade of two states
	float smode = fract(mode*10.0);
	//the other value to calculate a*nmode + b*smode situations
	float nmode = 1.0-smode;
	
	//effect
	int state = int(mode*10.0);
	
	//saturation
	float sat = mix( u_envm.a, u_enva.a, stp);//either player or foe
	//palette
	float cen = mod(dec,1000.0);
	//alpha
	float d = (dec/1000.0);
	float alpha = floor(d)/50.0;
	//colors or grays
	float condition = float(cen>=500.0);
	//hue
	float hue = fract(cen/100.0);
	//hue index
	int index = int(mod(cen,100.0))*3;
	//rgb convertion value
	vec3 hue3 = vec3(rgbHue[index++],rgbHue[index++],rgbHue[index]);
Ich habe jetzt beim schreiben alles kommentiert, sehe schon ein paar Sachen die sich lohnen zum auslagern. Nur schon der neue hue lookup wäre schon super zum auslagern... das muss einfach effizienter sein.
Benutzeravatar
Krishty
Establishment
Beiträge: 7335
Registriert: 26.02.2009, 12:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Alpha Blended Shader Optimieren

Beitrag von Krishty »

marcgfx hat geschrieben:
19.11.2020, 00:48
Wenn ich schon dabei bin, muss ich auch diese Frage stellen die vermutlich keine einfache Antwort hat. Ab wann lohnt es sich Kalkulationen in den Vertex-Shader zu verlagern? Ich habe ein paar leichte Variableninitialisierungen, die ich schon auslagern könnte. Gibt es einen overhead für die Werte die zwischen Vertex und Fragment-Shader übergeben werden?
Berechnung pro Vertex statt pro Pixel hat einen Gewinn (normalerweise weniger Vertices als Pixel), aber auch Kosten (Interpolatoren im Rasterizer werden höher ausgelastet). Die Antwort hängt also vom Verhältnis Vertices-zu-Pixel und der Last auf dem Rasterizer ab.

HLSL-Shader haben ein nointerpolate-Schlüsselwort für Werte, die sich pro Polygon nicht ändern und nicht interpoliert werden müssen. Damit kann man die Last auf den Rasterizer reduzieren.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
xq
Establishment
Beiträge: 1445
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: Alpha Blended Shader Optimieren

Beitrag von xq »

Krishty hat geschrieben:
19.11.2020, 01:14
HLSL-Shader haben ein nointerpolate-Schlüsselwort für Werte, die sich pro Polygon nicht ändern und nicht interpoliert werden müssen. Damit kann man die Last auf den Rasterizer reduzieren.
Das ganze nennt sich flat in OpenGL
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Wer checkt diese Shaderprogrammierung denn?
JCL: Kein Mensch zwingt Sie jedoch, mit Shadern oder ueberhaupt mit Gamestudio zu arbeiten. Es gibt schliesslich auch andere schoene Hobbies, wie zum Beispiel das Sammeln von Bierdeckeln – JCL quotes
Benutzeravatar
marcgfx
Establishment
Beiträge: 1593
Registriert: 18.10.2010, 23:26

Re: Alpha Blended Shader Optimieren

Beitrag von marcgfx »

Auf flat bin ich vorhin selbst gestossen, aufgrund einer Fehlermeldung. Das es die Last reduziert ist jedenfalls sehr gut zu wissen, da ich 9 Werte neu so übertrage. Danke @Krishty und @xq!!

Mein 300 Einträge Array für die Hue-Rotation wird jetzt nur noch im Vertex-Shader abgefragt und der gewünschte Eintrag wird übergeben. Jetzt muss ich mich nur noch trauen die Änderungen auf dem Mini-PC zu testen. Ich befürchte es wird ernüchternd sein, deshalb lieber über das Erreichte freuen.
Antworten