[GLSL] Pixelungenauigkeit im Fragment Shader
Verfasst: 16.08.2015, 17:04
Hi,
ich arbeite gerade an einer GUI-Lib für Eyetracking im Rahmen meiner HIWI-Anstellung (mehr zum EU-Projekt bei dem ich mitarbeite hier: http://www.mamem.eu/project/abstract/). Für das Rendering benutze ich OpenGL 3.3 Core und das klappt aktuell unter Linux und Windows sehr gut. Nun gibt es Buttons, welche Icons besitzen. Das Mesh eines solchen Buttons ist ein einfaches Quad. Das Icon und jegliche Interaktion wird über den Fragment Shader visualiert. Dieser ist dementsprechend etwas komplexer, funktioniert an sich aber wie erwartet. Es gibt aber je nach gerenderter Auflösung genau eine Pixelverschiebung an den Rändern des Icons, welches mittig auf den Button gerendert werden soll und daher mithilfe eines vec2 (iconUVScale) korrekt gezerrt wird. Damit wird gewährleistet, dass das Icon immer die korrekten Seitenrelationen hat, egal wie der Button aussieht:
Das ist nur ein Ausschnitt des Shaders. Im Endeffekt skaliere und verschiebe ich die Texturkoordianten so, dass das Icon in die Mitte des Buttons kommt. Dann mache ich eine Maske aus den Texturkoordinaten, sodass bei jenen mit Werten von 0 bis 1 eine 1 vorliegt und ansonsten 0 (iconAlphaMask). Die Maske wird dann in der letzten Zeile mit dem Alpha des Icons multipliziert damit dann um das Icon der Button sichtbar werden kann. Ich hab den Abschnitt mit dem Floor auch mal durch If und Else ersetzt um die Maske zu erzeugen und kam zum gleichen Problem. Der Effekt tritt sowohl unter Windows mit AMD als auf Intel unter Linux auf, sprich es liegt nicht am Treiber. Keine Ahnung, wie das Subtrahieren, Skalieren und Addieren sowas verursachen kann, weil der auf dem Screenshot gezeigte Fehler vom horizontalen Verlauf der Texturkoordinaten (uv.r) beeinflusst wird und dieser auf jeder vertikalen Höhe exakt gleich sein sollte.
Wahrscheinlich schwierig zu verstehen, hoffentlich hatte jemand schonmal ein vergleichbares Problem und eine Lösung!
ich arbeite gerade an einer GUI-Lib für Eyetracking im Rahmen meiner HIWI-Anstellung (mehr zum EU-Projekt bei dem ich mitarbeite hier: http://www.mamem.eu/project/abstract/). Für das Rendering benutze ich OpenGL 3.3 Core und das klappt aktuell unter Linux und Windows sehr gut. Nun gibt es Buttons, welche Icons besitzen. Das Mesh eines solchen Buttons ist ein einfaches Quad. Das Icon und jegliche Interaktion wird über den Fragment Shader visualiert. Dieser ist dementsprechend etwas komplexer, funktioniert an sich aber wie erwartet. Es gibt aber je nach gerenderter Auflösung genau eine Pixelverschiebung an den Rändern des Icons, welches mittig auf den Button gerendert werden soll und daher mithilfe eines vec2 (iconUVScale) korrekt gezerrt wird. Damit wird gewährleistet, dass das Icon immer die korrekten Seitenrelationen hat, egal wie der Button aussieht:
Code: Alles auswählen
#version 330 core
out vec4 fragColor;
in vec2 uv;
uniform sampler2D icon;
uniform vec2 iconUVScale; // Correction
void main() {
vec2 iconUV = uv - 0.5; // Move coordinates
iconUV = vec2(iconUV.r * iconUVScale.x, iconUV.g * iconUVScale.y) + 0.5; // Scale coordinates and move back
vec4 iconValue = texture2D(icon, iconUV).rgba; // Catching value of pixel
float iconAlphaMask = clamp(floor(iconUV.r + 1), 0, 1) - clamp(floor(iconUV.r), 0, 1); // Horizontal mask
iconAlphaMask *= clamp(floor(iconUV.g + 1), 0, 1) - clamp(floor(iconUV.g), 0, 1); // Vertical mask
iconValue.a *= iconAlphaMask; // Mask to hide outer icon areas
...
Wahrscheinlich schwierig zu verstehen, hoffentlich hatte jemand schonmal ein vergleichbares Problem und eine Lösung!