GLSL - tek geçişli gauss bulanıklığı


18

Tek geçişli gauss bulanıklığı yapmak için parça gölgelendiriciyi uygulamak mümkün mü? Ben iki geçişli bulanıklık (gauss ve kutu bulanıklık) uygulama çok buldum:

ve bunun gibi.

Gauss bulanıklığını evrişim olarak uygulamayı düşünüyorum (aslında evrişimdir, yukarıdaki örnekler sadece yakınlıklardır):

http://en.wikipedia.org/wiki/Gaussian_blur

Yanıtlar:


33

Evet, olabilir (çekirdek genişliği n için) çekirdek tüm n ^ 2 pikselleri örnekleyerek, tek bir geçişte Gauss bulanıklığı uygulanması. Genellikle iki geçişte satır ve sütunlarda çalıştırmak daha hızlıdır , çünkü o zaman O (n ^ 2) yerine örneklemek için O (n) pikseliniz vardır. Bu bir tahmin değildir, çünkü Gauss bulanıklığı matematiksel olarak ayrılabilir.


1
İşte güzel, esnek tek geçişli Blur Shader: shadertoy.com/view/XdfGDH
Ray Hulha

7

GLSL ile hızlı Gauss bulanıklaştırmasının püf noktası, GPU'nun donanımda doğrusal enterpolasyon sağladığı gerçeğinden yararlanmaktır. Bu nedenle, tek bir ön getirme veya sekiz 3D voksel ile dört 2D pikseli etkili bir şekilde örnekleyebilirsiniz. Nerede numune alacağınıza karar vererek çıktıyı ağırlıklandırabilirsiniz. Kesin referans Sigg ve Hadwiger'in çevrimiçi bulabileceğiniz "Hızlı Üçüncü Dereceden Doku Filtreleme" dir.

Okunabilir bir açıklama için "Doğrusal örneklemeyle verimli Gauss bulanıklığı" web sayfasını bulun. Belirtildiği gibi, Gauss bulanıklığı geniş çekirdeklerle ayrılabilir olduğundan, boyut başına bir geçiş yapmak en etkilidir.

Bununla birlikte, bu hileyi tek bir geçişte sıkı bir çekirdeğe sahip bir Gauss'a yaklaşmak için de kullanabilirsiniz. Aşağıdaki örnekte 3D çekirdeği üst dilim = [1 2 1; 2 4 2; 1 2 1]; orta dilim = [2 4 2; 4 8 4; 2 4 2]; alt dilim = [1 2 1; 2 4 2; 1 2 1]. Her boyutta +/- 0,5 voksel örnekleyerek bunu 27 yerine 8 doku getirmesiyle yaparsınız. Bunu bir MRIcroGL gölgelendirici dosyası olarak GLSL'de gösteriyorum. MRIcroGL'nin "Shader" klasörü. Programı yeniden başlattığınızda ray cast görüntünüzün bulanık olduğunu göreceksiniz. "DoBlur" onay kutusunu tıklatmak bulanıklığı açar ve kapatır. Tümleşik Intel GPU'yu dizüstü bilgisayarımda ve "chris_t1" kullanma MRIcroGL ile gelen görüntü Bulanıklaştırma olmadan 70 fps (1 doku getirme) ve bulanıklaştırma ile 21 fps (8 getirme) alıyorum. Kodun çoğu sadece klasik bir ışın tekeri, "doBlur" koşullu sorunuzu kuşatır.

//-------a.txt dosyası şöyle

//pref
doBlur|bool|true
//vert
void main() {
    gl_TexCoord[1] = gl_MultiTexCoord1;
    gl_Position = ftransform();
}
//frag
uniform int loops;
uniform float stepSize, sliceSize, viewWidth, viewHeight;
uniform sampler3D intensityVol;
uniform sampler2D backFace;
uniform vec3 clearColor;
uniform bool doBlur;
void main() {
    // get normalized pixel coordinate in view port (e.g. [0,1]x[0,1])
    vec2 pixelCoord = gl_FragCoord.st;
    pixelCoord.x /= viewWidth;
    pixelCoord.y /= viewHeight; 
    // starting position of the ray is stored in the texture coordinate
    vec3 start = gl_TexCoord[1].xyz;
    vec3 backPosition = texture2D(backFace,pixelCoord).xyz;
    vec3 dir = backPosition - start;
    float len = length(dir);
    dir = normalize(dir);
    vec3 deltaDir = dir * stepSize;
    vec4 colorSample,colAcc = vec4(0.0,0.0,0.0,0.0);
    float lengthAcc = 0.0;
    float opacityCorrection = stepSize/sliceSize;
    //ray dithering http://marcusbannerman.co.uk/index.php/home/42-articles/97-vol-render-optimizations.html
    vec3 samplePos = start.xyz + deltaDir* (fract(sin(gl_FragCoord.x * 12.9898 + gl_FragCoord.y * 78.233) * 43758.5453));
    //offset to eight locations surround target: permute top/bottom, anterior/posterior, left/right
    float dx = 0.5; //distance from target voxel
    vec3 vTAR = vec3( dx, dx, dx)*sliceSize;
    vec3 vTAL = vec3( dx, dx,-dx)*sliceSize;
    vec3 vTPR = vec3( dx,-dx, dx)*sliceSize;
    vec3 vTPL = vec3( dx,-dx,-dx)*sliceSize;
    vec3 vBAR = vec3(-dx, dx, dx)*sliceSize;
    vec3 vBAL = vec3(-dx, dx,-dx)*sliceSize;
    vec3 vBPR = vec3(-dx,-dx, dx)*sliceSize;
    vec3 vBPL = vec3(-dx,-dx,-dx)*sliceSize;
    for(int i = 0; i < loops; i++) {
        if (doBlur) {
            colorSample = texture3D(intensityVol,samplePos+vTAR);
            colorSample += texture3D(intensityVol,samplePos+vTAL);
            colorSample += texture3D(intensityVol,samplePos+vTPR);
            colorSample += texture3D(intensityVol,samplePos+vTPL);
            colorSample += texture3D(intensityVol,samplePos+vBAR);
            colorSample += texture3D(intensityVol,samplePos+vBAL);
            colorSample += texture3D(intensityVol,samplePos+vBPR);
            colorSample += texture3D(intensityVol,samplePos+vBPL);
            colorSample *= 0.125; //average of 8 sample locations
        } else
            colorSample = texture3D(intensityVol,samplePos);
        colorSample.a = 1.0-pow((1.0 - colorSample.a), opacityCorrection);      
        colorSample.rgb *= colorSample.a; 
        //accumulate color
        colAcc = (1.0 - colAcc.a) * colorSample + colAcc;
        samplePos += deltaDir;
        lengthAcc += stepSize;
        // terminate if opacity > 95% or the ray is outside the volume
        if ( lengthAcc >= len || colAcc.a > 0.95 ) break;
    }
    colAcc.rgb = mix(clearColor,colAcc.rgb,colAcc.a);
    gl_FragColor = colAcc;
}

2
Daniel Rákos'un doğrusal örneklemesiyle verimli Gauss bulanıklığı ( Christian Cann Schuldt Jensen tarafından yapılan yoruma da dikkat edin ).
Benji XVI
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.