shader Stereoscopy

Aus DGL Wiki
Version vom 11. März 2010, 15:16 Uhr von Joni (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „=Stereoskopischer Post-Processing-Shader= Zurück zur Shadersammlung {|{{Prettytable_B1}} width=100% !width=60%|Beschreibung !width=20%|Autor !width=20%|Versi…“)

(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

Stereoskopischer Post-Processing-Shader

Zurück zur Shadersammlung

Beschreibung Autor Version
Post-Processing-Shader für Stereoskopie Joni 1.0

Bilder

verschiedene Stereoskopie-Verfahren

Oben: Half-Color Anaglyph; mitte: Horizontal Interlaced (funktioniert nur bei maximaler Bildauflösung); unten: Full-Color Anaglyph

Beschreibung

Die hier vorgestellten Shader konvertieren mit verschiedenen Verfahren ein linkes und ein rechtes Eingabebild in ein stereoskopisches Bild. In dem folgenden Abschnitt werden die einzelnen Verfahren näher erläutert.

Horizontal Interlaced

Bei der zeilenverschachtelten Stereoskopie sind alle ungeraden Pixelzeilen für das linke Auge und alle geraden Pixelzeilen für das rechte Auge bestimmt. Verwendet wird dieses Verfahren u. A. von den Zalman- und den Hyundai-3D-Bildschirmen.

Vertical Interlaced

Analog zur zeilenverschachtelten Stereoskopie wird hier nach ungeraden und geraden Spalten sortiert. Verwendet wird dieses Verfahren u. A. für den Druck auf Linsenrasterkarten.

Checkerboard

Hier gehören jeweils die Pixel, die diagonal zueinander liegen, zu einem Auge. Die Aufteilung erinnert an ein Schachbrett, daher der Name. Verwendet wird das Verfahren u. A. von einigen Fernsehen von Samsung in Kombination mit einer Shutterbrille.

Half-Color Anaglyphen

Das Half-Color-Verfahren ist ein Anaglyphen-Verfahren für rot/cyan-Brillen, das im gegenüber dem True-Color-Anaglyphen-Verfahren, was auch im Stereoskopie-Tutorial verwendet wird, einen nennenswerten Vorteil bei farbiger Szene hat. Bei dem True-Color-Verfahren wird für den roten Kanal des finalen Bildes der rote Kanal des linken Bildes genommen, was zu Konflikten bei roten Objekten in der Szene führt. Diese erscheinen dann auf dem linken Auge mit voller Helligkeit und auf dem rechten Auge schwarz. Das Half-Color-Verfahren verwendet daher für den roten Farbkanal des finalen Bildes nicht den roten Kanal des linken Bildes, sondern dessen Helligkeit, die wie bei Graustufen mit der folgenden Formel berechnet wird:

luminance = 0.299*red + 0.587*green + 0.114*blue

Der Nachteil dieses Verfahrens ist, dass die Farben etwas verfälscht werden.

Optimized Anaglyphen

Dieses Verfahren ähnelt dem Half-Color-Verfahren, ignoriert aber bei dem linken Bild den Rotanteil vollständig und berechnet den finalen roten Kanal folgendermaßen:

red = 0.7*green + 0.3*blue

Dieses Verfahren erstellt noch etwas ruhigere Bilder als das Half-Color-Verfahren, verfälscht die Farben aber auch stärker. Zusätzlich kann bei dem Verfahren noch Gammakorrektur auf den roten Kanal angewandt werden.

Die oben beschriebenen Verfahren angewandt auf ein rotes Objekt

Besondere Vorraussetzungen

Um den Code sinnvoll zu benutzen, ist eine Anaglyphen-Brille oder ein stereoskopisches Gerät, das eins der o.g. Verfahren verwendet, nötig.

Anmerkungen

Für die Verwendung von Anaglyphen mit grün/magenta kann man die o.g. Verfahren entsprechend anpassen. Welches Verfahren sich dafür anbietet, ist zu testen, da der Autor keine solche Brille besitzt.

Das neu aufgekommene, patentierte ColorCode-Verfahren sieht zwar gelb/blauen Anaglyphen ähnlich, ist jedoch anders und nicht zu gelb/blau-Anaglyphen kompatibel. Da das Color-Code-Verfahren patentiert und nicht öffentlich bekannt ist, besteht leider keine Möglichkeit, es hier zu verwenden.

Für Shutterbrillen, Doppelprojektoren etc. ist man in OpenGL auf eine Treiberlösung angewiesen. Details dazu gibt es im Tutorial StereoSehen.

Code

Hier wird OpenGL 3.2 und GLSL-Version 1.5 verwendet, die Shader sollten jedoch problemlos mit jeder GLSL-Version funktionieren.

Vertex Shader

Da es sich um einen Post-Processing-Shader handelt, tut der Vertexshader nur das Nötigste: Er leitet Vertex- und Texturkoordinaten weiter.

#version 150

in  vec3 in_Position;
in  vec2 in_TexCoord;
out vec2 ex_TexCoord;

void main(void)
{
	gl_Position = vec4(in_Position, 1.0);
	ex_TexCoord = in_TexCoord;
}

Horizontal Interlaced

#version 150

precision highp float;

in  vec3 ex_Color;
in  vec2 ex_TexCoord;
out vec4 out_Color;

uniform sampler2D left;  //Linkes Bild
uniform sampler2D right; //Rechtes Bild

void main(void)
{
  //Horizontal Interlaced
  if (mod(trunc(gl_FragCoord.y), 2.0) < 0.5)
    out_Color = texture2D(left, vec2(ex_TexCoord));
  else
    out_Color = texture2D(right, vec2(ex_TexCoord));
}

Vertical Interlaced

#version 150

precision highp float;

in  vec3 ex_Color;
in  vec2 ex_TexCoord;
out vec4 out_Color;

uniform sampler2D left;
uniform sampler2D right;

void main(void)
{ 
  //Vertical Interlaced
  if (mod(trunc(gl_FragCoord.x), 2.0) < 0.5)
    out_Color = texture2D(left, vec2(ex_TexCoord));
  else
    out_Color = texture2D(right, vec2(ex_TexCoord));
}

Checkerboard

#version 150

precision highp float;

in  vec3 ex_Color;
in  vec2 ex_TexCoord;
out vec4 out_Color;

uniform sampler2D left;
uniform sampler2D right;

void main(void)
{
//Checkerboard
  bool d1 = (mod(trunc(gl_FragCoord.x), 2.0) < 0.5);
  bool d2 = (mod(trunc(gl_FragCoord.y), 2.0) < 0.5);
  if (d1==d2)
    out_Color = texture2D(left, vec2(ex_TexCoord));
  else
    out_Color = texture2D(right, vec2(ex_TexCoord));
}

Half-Color-Anaglyph

#version 150

precision highp float;

in  vec3 ex_Color;
in  vec2 ex_TexCoord;
out vec4 out_Color;

uniform sampler2D left;
uniform sampler2D right;

void main(void)
{
  //Half-Color Anaglyphen
  vec3 cleft = texture2D(left, vec2(ex_TexCoord)).xyz;
  vec3 cright = texture2D(right, vec2(ex_TexCoord)).xyz;
  out_Color.r = 0.299*cleft.r + 0.587*cleft.g + 0.114*cleft.b;  //Half-Color
  out_Color.g = cright.g;
  out_Color.b = cright.b;
}

Optimized-Anaglyph

#version 150

precision highp float;

in  vec3 ex_Color;
in  vec2 ex_TexCoord;
out vec4 out_Color;

uniform sampler2D left;
uniform sampler2D right;

void main(void)
{
  //Half-Color Anaglyphen
  vec3 cleft = texture2D(left, vec2(ex_TexCoord)).xyz;
  vec3 cright = texture2D(right, vec2(ex_TexCoord)).xyz;
  out_Color.r = 0.7*cleft.g + 0.3*cleft.b;            //ohne Gammakorrektur
  out_Color.r = pow(0.7*cleft.g + 0.3*cleft.b, 1.5);  //mit Gammakorrektur
  out_Color.g = cright.g;
  out_Color.b = cright.b;
}

Links

http://www.3dtv.at/knowhow/AnaglyphComparison_en.aspx

Siehe auch

Tutorial_StereoSehen