SSAO uygulamasıyla istenen sonuçları elde edemiyorum


12

Ertelenmiş oluşturma uyguladıktan sonra, bu Eğitimi kullanarak bir SSAO uygulaması ile şansımı denedim . Ne yazık ki, SSAO'ya benzeyen bir şey almıyorum, aşağıda sonucumu görebilirsiniz.

başarısız ssao denemesi

Bazı tuhaf desen şekillendirme olduğunu ve olması gereken yerde (yani nesneler arasında ve yerde) tıkanma gölgesi olmadığını görebilirsiniz. Uyguladığım gölgelendiriciler şunları takip ediyor:


#VS
#version 330 core

uniform mat4 invProjMatrix;

layout(location = 0) in vec3 in_Position;
layout(location = 2) in vec2 in_TexCoord;

noperspective out vec2 pass_TexCoord;
smooth out vec3 viewRay;

void main(void){
    pass_TexCoord = in_TexCoord;
    viewRay = (invProjMatrix * vec4(in_Position, 1.0)).xyz;
    gl_Position = vec4(in_Position, 1.0);
}

#FS
#version 330 core

uniform sampler2D DepthMap;
uniform sampler2D NormalMap;
uniform sampler2D noise;

uniform vec2 projAB;
uniform ivec3 noiseScale_kernelSize;
uniform vec3 kernel[16];
uniform float RADIUS;
uniform mat4 projectionMatrix;

noperspective in vec2 pass_TexCoord;
smooth in vec3 viewRay;

layout(location = 0) out float out_AO;

vec3 CalcPosition(void){
    float depth = texture(DepthMap, pass_TexCoord).r;
    float linearDepth = projAB.y / (depth - projAB.x);
    vec3 ray = normalize(viewRay);
    ray = ray / ray.z;
    return linearDepth * ray;
}

mat3 CalcRMatrix(vec3 normal, vec2 texcoord){
    ivec2 noiseScale = noiseScale_kernelSize.xy;
    vec3 rvec = texture(noise, texcoord * noiseScale).xyz;
    vec3 tangent = normalize(rvec - normal * dot(rvec, normal));
    vec3 bitangent = cross(normal, tangent);

    return mat3(tangent, bitangent, normal);
}

void main(void){

    vec2 TexCoord = pass_TexCoord;
    vec3 Position = CalcPosition();
    vec3 Normal = normalize(texture(NormalMap, TexCoord).xyz);

    mat3 RotationMatrix = CalcRMatrix(Normal, TexCoord);

    int kernelSize = noiseScale_kernelSize.z;

    float occlusion = 0.0;

    for(int i = 0; i < kernelSize; i++){
        // Get sample position
        vec3 sample = RotationMatrix * kernel[i];
        sample = sample * RADIUS + Position;
        // Project and bias sample position to get its texture coordinates
        vec4 offset = projectionMatrix * vec4(sample, 1.0);
        offset.xy /= offset.w;
        offset.xy = offset.xy * 0.5 + 0.5;
        // Get sample depth
        float sample_depth = texture(DepthMap, offset.xy).r;
        float linearDepth = projAB.y / (sample_depth - projAB.x);
        if(abs(Position.z - linearDepth ) < RADIUS){
            occlusion += (linearDepth <= sample.z) ? 1.0 : 0.0;
        }
    }
    out_AO = 1.0 - (occlusion / kernelSize);
}

Tam ekran dörtlü çiziyorum ve Derinlik ve Normal dokuları geçiyorum. Normaller RGBA16F içindedir ve alfa kanalı bulanıklık geçişinde AO faktörü için ayrılmıştır. Derinliği doğrusal olmayan bir Derinlik tamponunda (32F) saklar ve aşağıdakileri kullanarak doğrusal derinliği kurtarırım:


float linearDepth = projAB.y / (depth - projAB.x);

burada projAB.yşu şekilde hesaplanır:

resim açıklamasını buraya girin

ve projAB.xşöyle:

resim açıklamasını buraya girin

Bunlar glm :: perspektif (gluperspective) matrisinden türetilir. z_n ve z_f yakın ve uzak klip mesafesidir.

Üstte yayınladığım bağlantıda açıklandığı gibi, yöntem merkeze yakın daha yüksek dağılıma sahip bir yarımkürede örnekler oluşturur. Daha sonra yarımküreyi Z yönünde rastgele döndürmek için bir dokudan rastgele vektörler kullanır ve son olarak verilen pikselde normal boyunca yönlendirir. Sonuç gürültülü olduğu için SSAO geçişini bir bulanıklık geçişi izler.

Her neyse, aynı şeyi yapmaya çalıştığım için pozisyon rekonstrüksiyonum yanlış görünmüyor, ancak pozisyon yeniden yapılandırılmak yerine bir dokudan geçti.

Ayrıca Yarıçap, gürültü dokusu boyutu ve örnek sayısı ve farklı doku formatları ile şanssız oynamayı denedim. Nedense Yarıçapı değiştirirken hiçbir şey değişmez.

Kimsenin önerisi var mı? Neler yanlış gidiyor olabilir?


Bulanıklığın ayrı bir geçiş olması gerektiğini düşünüyorum. Bulanıklaştırıcı olmadan gölgelendiricinizin ekran görüntüsünü gönderebilir misiniz?
knight666

Bulanıklaştırma geçişi ayrıdır, bulanıklaştırma öncesi ekran görüntüsünü kontrol edebilirsiniz .
Grieverheart

Yanıtlar:


6

Sorunu buldum. Bu gerçekten aptalca bir hataydı, glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);doğru derinlik değerlerini almak için belirtmeniz gerektiğini bilmiyordum ve bu nedenle Derinlik değerlerini örneklemiyordum. Şimdi güzel bir SSAO etkisi elde ediyorum:

resim açıklamasını buraya girin


Bunu doğru yanıt olarak işaretlemekten çekinmeyin, böylece insanlar çözümünüzü bulduğunuzu biliyorlar: P
SomeGuy

Evet, maalesef cevabımı doğru olarak işaretleyebilmek için bir gün beklemek zorundayım: S.
Grieverheart

Benim hatam, zaman damgalarını kontrol etmedi.
SomeGuy
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.