2016-09-18 3 views
2

This führt die Methode des Volume-Rendering mit veralteter API von OpenGL ein. Aber jetzt möchte ich das Volume-Rendering mit GLSL abschließen und habe einige Teile davon fertiggestellt. Meine Frage ist, wie man das Mischen durchführt. In dem obigen Link wird das Vermischen durch die folgenden Codes beendet:Wie funktioniert das Mischen in Volume Rendering mit GLSL?

glEnable(GL_BLEND); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

Aber wie kann ich das Mischen mit GLSL beenden?

ich versuchte, die folgende Gleichung zu verwenden:

C = Cs*As + Cd(1 - As) 

Cs die Farbe des Quellobjekts ist. Cd ist die Farbe des Zielobjekts. Wie ist das Alpha des Quellobjekts. Und mein Code in Fragment-Shader ist wie folgt:

...... 
vec3 dir = backPoint - frontPoint; 
float len = length(dir); 
float stepSize = 0.01; 
vec3 deltaDir = normalize(dir)*stepSize; 
float deltaLen = length(deltaDir); 
float accLen = 0; 
float accAlpha = 0; 
float sampleAlpha = 0; 
vec4 accColor = vec4(0.0); 

vec3 samplePoint = frontPoint; 
vec4 sampleColor; 
while(accLen < len && accColor.a <= 1.0){ 
    sampleColor = texture(texture3D, samplePoint); 

    accColor = sampleColor*sampleColor.a + accColor*(1-sampleColor.a); 

    accLen += deltaLen; 
    samplePoint += deltaDir; 
} 
color = accColor; 
...... 

In meinem Projekt, ließ ich den Wert von r, g, b, a der 3D-Textur gleich zu sein. Aber ich kann das Ergebnis des einen der obigen Links nicht erhalten. Können Sie mir helfen, das Mischproblem mit GLSL zu lösen?

+0

Mischen wird von HW selbst gemacht, nicht von Shadern in GLSL, also sollten Sie 'glEnable' und' glBlendFunc' in Ihrem GLSL-Projekt belassen und aus dem Fragment-Shader nur die Farbe ausgeben, um die Mischungsgleichung nicht zu verarbeiten. Das würde nur funktionieren, wenn Sie jedes Blended-Primitiv als separaten Render-Durchlauf zu/von der Textur ausführen, was wahnsinnig langsam ist ... es sei denn, die Anzahl der Primitiven ist nicht hoch. – Spektre

+0

Zum Beispiel siehe [mein einfacher atmosphärischer Streushader in GLSL] (http://StackOverflow.com/a/19659648/2521214), der natives Mischen von gfx-Karten und GLSL-Shadern kombiniert (obwohl im 2-Pass-Rendering, aber das hat nichts zu tun mit Blending) – Spektre

+1

Dies ist Raycasting und Blending ist in der Tat Teil des Algorithmus. – kaerimasu

Antwort

1

Es ist normal, die Berechnungen im vormultiplizierten Alpha-Farbraum durchzuführen. Es passt besser zur Emissionsabsorption der volumatischen Phänomene. Die entsprechenden Gleichungen sind:

C = Cs + (1 - As)*Cd 
A = 1 - (1 - As)*(1 - Ad) = As + (1 - As)*Ad 

Obwohl es möglich ist, die Berechnungen in nicht-integriertem Alphafarbraum zu tun, wäre es eine Division durch die Alpha-Werte erfordern und in der Regel komplizierter. (Ihr Code funktioniert in nicht-premultiplied und dauert nicht berücksichtigt ...)

So die OpenGL Set-up Mischen Sie verwenden:

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 

und verwenden Sie diese Formel im Shader:

accColor = sampleColor + accColor*(1-sampleColor.a); 

Sie müssen dies auch beim Erstellen Ihrer 3D-Texturen berücksichtigen. Zum Beispiel eine Textur, wo für alle Pixel R = G = B = A eine weiße neblige Substanz entspricht, also muss man sie über einen dunklen Hintergrund schauen.

Verwandte Themen