Frage zu GLSL-Syntax

Moderator: Graphische Datenverarbeitung 1

oerms
Erstie
Erstie
Beiträge: 13
Registriert: 21. Apr 2010 17:34

Frage zu GLSL-Syntax

Beitrag von oerms » 27. Okt 2010 17:09

Hallo zusammen,

ich mache anscheinend einen Fehler in der GLSL-Syntax, den ich partout nicht entdecken kann.

Das fragliche Stück Code ist im Fragment Shader und soll ein Toon Shader für bis zu acht Lichtquellen werden. Die Einträge in isEnabled (int, da kein bool übergeben werden kann) werden von main.cpp geschrieben und zeigen an, welche Quelle an ist. Die Übergabe dieses Arrays an den Shader ist erfolgreich getestet worden.

Das Problem: Wenn die erste Quelle an ist, wird alles schwarz. Wenn kein Quelle an ist, wird (richtigerweise) in den ersten Fall der letzten if-Abfrage gesprungen.

Code: Alles auswählen

varying vec3 normal;
uniform int isEnabled[8];

	void main()
	{
		vec3 n = normalize(normal);
		int count = 0;
		int i;
		float intensity = 0.0;
		vec4 color;

		vec4 colorend = vec4( 0.0, 0.0, 0.0, 1.0 );
		
		for ( i = 0; i < 8; i= i+1 )
		{
		    if ( isEnabled[i] > 0 )
		    {
		    	intensity = dot( vec3( gl_LightSource[i].position ), n );
		    	color = gl_LightSource[i].diffuse;
		
		    	if (intensity > 0.95)
			    {color = color;}
		    	else if ( intensity > 0.5 )
			    {color = color * 0.6;}
		    	else if ( intensity > 0.25 )
			    {color = color * 0.4;}
		    	else
			    {color = color * 0.2;}

		    	colorend = colorend + color;
		    
		    	count = count + 1;
		    }
		}

		if ( count == 0 )
		{
		    gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
		}
		else
		{ 
		    gl_FragColor = colorend / count;
		}

} 
Vermutung: Irgendein blöder Syntax-/Zuweisungsfehler.

Grüße und vielen Dank für die Hilfe...

thomas_kalbe
Nerd
Nerd
Beiträge: 570
Registriert: 10. Jun 2006 14:58

Re: Frage zu GLSL-Syntax

Beitrag von thomas_kalbe » 27. Okt 2010 17:49

einen Syntaxfehler kann ich nicht entdecken, dann hätte es auch nicht kompiliert.

ein paar Vermutungen:
- wird die alpha-Komponente der fragcolor womöglich größer 1?
Vielleicht wäre es besser, die Farbe am Schluss so zusammenzubauen
fragcolor = vec4(colorend.xyz / count, 1.0);
Auch die übrigen Farbkomponenten dürfen nicht überlaufen. Das stellst Du, soweit ich das sehe, nicht sicher (ein Clamp auf 0,1 ?)

- öfters gibt es Probleme mit dynamischen Array-Zugriffen; vielleicht klappt es mit einer Art Loop Unrolling?
Was passiert, wenn Du auf das isEnabled-Array verzichtest, d.h. alle Lichter als Enabled ansiehst?

Bei Bedarf können wir auch nochmal gerne zusammen drüberschauen.

t.

oerms
Erstie
Erstie
Beiträge: 13
Registriert: 21. Apr 2010 17:34

Re: Frage zu GLSL-Syntax

Beitrag von oerms » 27. Okt 2010 18:09

Zum ersten Punkt: Der Mittelwert kann nie größer werden als der maximale Wert, ein Teilen durch count verhindert also Überlaufen. (Habe die colorend auf reine Nuller initialisiert und es geht nicht.)

Zum zweiten Punkt: Wir haben zuerst zwei Lichter definiert und Funktionen zum An- und Ausschalten geschrieben. Funktioniert mit den Standardshadern wunderbar. Funktionierte auch mit hardkodiertem Shader für zwei Quellen wunderbar (inklusive aller Operationen auf vec4-Objekte, i = i + 1 statt i++ usw. ist nur "falls der Kram dran schuld ist").
Nur jetzt mit der Loop macht er etwas, was wir beide in der Gruppe nicht verstehen...

edit: Es sieht danach aus, als ob count nicht den richtigen Wert bekommt. Passiert irgendetwas blödes vom Kaliber Teilen von zwei Integern und anschließendem Abrunden? Ich kann nicht sehen, wo das sein sollte...
Um genau zu sein:
Wenn nur Licht 0 an ist, springt er in die letzte else.
Wenn nur Licht 1 an ist, springt er aber nicht. Sollte er aber, da count ja eigentlich beim zweiten Durchlauf der for-Schleife auf Eins gesetzt wird.

Antworten

Zurück zu „Graphische Datenverarbeitung 1“