VisExercises

Exercise #04

Visualisierung Übungsblatt #04


Medical 3D Data: Transfer Functions and Iso Surfaces



1. GLSL Shader Editor:
Fügen Sie dem Programm-Code aus der vorhergehenden Aufgabe einen GLSL Shader Editor hinzu. Sie benötigen dazu die folgenden Code-Abschnitte:

Im Globalen Namensraum:

GLuint prog_id;
const char shader[] = "";

In der Methode initializeOpenGL():

prog_id = lglCompileGLSLProgram(shader);
create_lgl_Qt_ShaderEditor("shader", &prog_id);

In der Methode renderOpenGL():

lglUseProgram(prog_id, false);

2. GLSL Shader:
Binden Sie die 3D Textur an einen 3D Sampler “sampler”, indem Sie den Namen des Samplers und die Textur-Objekt-Id der 3D Textur an lglSampler3D() übergeben (anstelle von lglTexture3D).

Fügen Sie außerdem mit Hilfe des Shader Editors den folgenden GLSL Shader hinzu:

#version 120
attribute vec4 vertex_position;
attribute vec4 vertex_texcoord;
uniform mat4 mv;
uniform mat4 mvp;
varying vec3 frag_texcoord;
void main()
{
   frag_texcoord = ...;
   gl_Position = mvp * ...;
}
---
#version 120
uniform sampler3D sampler;
varying vec3 frag_texcoord;
void main()
{
   vec4 color = texture3D(...);
   gl_FragColor = color;
}

Implementieren Sie in obigem Code die fehlenden Stellen für eine 3D Texturierung, die wir im GLSL Shader selber programmieren müssen, weil wir nun keine Fixed-Function Pipeline sondern eine Programmable Pipeline verwenden. Analog gilt dies auch für den Alpha-Test, den wir ebenfalls selber programmieren.

Sie sollten nun dieselbe Darstellung wie in der letzten Aufgabe erhalten - mit dem Unterschied, dass Sie nun einen programmierbaren Shader einsetzen.

Mit diesem werden wir nun im Folgenden die Schnittbilddarstellung des MRI-Head.pvm Datensatzes verbessern.

3. GLSL Per-Fragment Operations:
Verändern Sie den Fragment-Shader, so dass Skalarwerte nicht mehr gezeichnet werden, die nahezu 0 sind (GLSL: discard).

VIS-Colormap

4. GLSL Color-Mapping:
Verändern Sie den Fragment-Shader, so dass hohe Skalarwerte rötlicher dargestellt werden. Das Ergebnis ist auf der rechten Seite dargestellt. Optional: machen Sie niedrige Skalarwerte bläulicher (Cool-Warm-Shading).

5. GLSL Transferfunktionen:
Verändern Sie den den Fragment-Shader, so dass eine Transferfunktion verwendet wird, die einer Isokontur entspricht. Für die Isokontur stehe ein Peak in der Transferfunktion in Form einer schmalen Rechteck-Funktion. Den dazugehörigen Peak färben Sie bitte rot, alles andere farblos, grau oder transparent - je nach Geschmack.

VIS-TF

Identifizieren Sie einen konkreten Peak zu einem entsprechenden normalisierten Isowert $s_{iso}$, der eine bestimmte Struktur wie z.B. die Hirnrinde charakterisiert.

Dokumentieren Sie dies mit einem Screenshot.

6. Interaktion (optional):
Überladen Sie die Methode mouseMoveEvent(QMouseEvent *event) der QLGLWindow Klasse, greifen Sie in der Event-Struktur die X- und Y-Koordinaten der Maus ab und verschieben Sie damit den Peak der MPR-Darstellung entsprechend, wenn die rechte Maustaste gedrückt ist (linke Maustaste rotiert).

7. Isoflächen:
Laden Sie denselben Datensatz in den QtV3 und extrahieren Sie die Isofläche zum Isowert $s_{iso}$, den sie vorher identifiziert hatten, mit Hilfe des unteren eingeklappten UI-Bereichs.

Tipp: der zu extrahierende Isowert wird per linker Windowing-Grenze eingestellt.

Sind Sie mit der Darstellung zufrieden oder ist ein prinzipielles Problem erkennbar?

Dokumentieren Sie dies abschließend mit einem Screenshot Ihrer Isofläche.


Hausaufgaben:

  • Zeichnen Sie einen in 5 Tetraeder zerlegten Hexaeder von Hand!
  • Ein Eckpunkt des Hexaeders soll unterhalb des Isowertes liegen, alle anderen oberhalb.
    • Klassifizieren Sie alle Tetraeder und ermitteln Sie die Gesamtzahl der Dreiecke einer entsprechenden extrahierten Isofläche.
    • Zeichnen Sie schematisch die sich ergebende Isofläche. Am besten eignet sich dazu eine Explosionszeichnung aller 5 Tetraeder.
  • Angenommen wir betrachten eine bildebenenparallele Schicht (view-aligned slice), wie sie beim Volume Rendering vorkommt. Angenommen, die Schicht habe die Dicke $d$ und den Absorptionskoeffizienten $\mu$. Wie können wir mit Hilfe von OpenGL die Abschwächung durch diese Schicht mit Hilfe von Alpha-Blending simulieren?
    • D.h. Was für ein Alphawert benötigen wir für die Abschwächung von Licht auf einem Wegstück von $d=1cm$ mit einem Abschwächungskoeffizienten von $0.1cm^{-1}$ (Wasser)?
    • Wie sieht es bei $d=2cm$ und $d=4cm$ aus?

Options: