ไม่ได้ผลลัพธ์ที่ต้องการด้วยการใช้ SSAO


12

หลังจากนำการเรนเดอร์มาใช้แล้วฉันลองเสี่ยงโชคด้วยการใช้ SSAO โดยใช้บทช่วยสอนนี้ น่าเสียดายที่ฉันไม่ได้รับสิ่งที่ดูเหมือน SSAO คุณสามารถดูผลลัพธ์ของฉันด้านล่าง

ssao ล้มเหลว

คุณสามารถเห็นได้ว่ามีลวดลายแปลก ๆ บางอย่างและไม่มีเงาบังแดดที่จะต้องมี (เช่นระหว่างวัตถุและบนพื้นดิน) เฉดสีที่ฉันติดตั้งมีดังนี้:


#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);
}

ฉันวาดรูปสี่เหลี่ยมเต็มหน้าจอและส่งผ่านความลึกและพื้นผิวปกติ เกณฑ์ปกติอยู่ใน RGBA16F โดยมีช่องอัลฟาจองไว้สำหรับปัจจัย AO ในการเบลอพาส ฉันเก็บความลึกในบัฟเฟอร์ความลึกแบบไม่เชิงเส้น (32F) และกู้คืนความลึกเชิงเส้นโดยใช้:


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

โดยที่projAB.yคำนวณเป็น:

ป้อนคำอธิบายรูปภาพที่นี่

และprojAB.xเป็น:

ป้อนคำอธิบายรูปภาพที่นี่

สิ่งเหล่านี้ได้มาจากเมทริกซ์ glm :: perspective (gluperspective) z_n และ z_f เป็นระยะทางใกล้และไกล

ตามที่อธิบายไว้ในลิงค์ที่ฉันโพสต์ไว้ด้านบนวิธีการสร้างตัวอย่างในซีกโลกที่มีการกระจายที่สูงกว่าใกล้กับศูนย์กลาง จากนั้นใช้เวกเตอร์แบบสุ่มจากพื้นผิวเพื่อหมุนซีกโลกสุ่มรอบทิศทาง Z และในที่สุดก็ orients ตามปกติที่พิกเซลที่กำหนด เนื่องจากผลลัพธ์ที่ได้จะมีเสียงรบกวนจึงทำให้ภาพพร่ามัวเป็นไปตามเส้นทาง SSAO

อย่างไรก็ตามการสร้างตำแหน่งของฉันไม่ได้ผิดเพราะฉันพยายามทำแบบเดียวกัน แต่ด้วยตำแหน่งที่ส่งจากพื้นผิวแทนที่จะถูกสร้างขึ้นใหม่

ฉันยังลองเล่นกับ Radius ขนาดพื้นผิวของเสียงรบกวนและจำนวนตัวอย่างและด้วยรูปแบบพื้นผิวที่แตกต่างกันโดยไม่มีโชค ด้วยเหตุผลบางอย่างเมื่อเปลี่ยนรัศมีไม่มีอะไรเปลี่ยนแปลง

ไม่มีใครมีข้อเสนอแนะใด ๆ ? มีอะไรผิดปกติหรือเปล่า?


ฉันคิดว่าความพร่ามัวจะต้องผ่านแยกต่างหาก คุณสามารถโพสต์ภาพหน้าจอของ shader ของคุณโดยไม่เบลอได้หรือไม่?
knight666

เบลอพาสแยกจากกันคุณสามารถตรวจสอบภาพหน้าจอก่อนเบลอได้
Grieverheart

คำตอบ:


6

ฉันพบปัญหา มันเป็นความผิดพลาดที่โง่มากฉันไม่รู้ว่าคุณต้องระบุglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);เพื่อให้ได้ค่าความลึกที่ถูกต้องดังนั้นฉันจึงไม่ได้สุ่มค่าความลึก ตอนนี้ฉันได้เอฟเฟกต์ SSAO ที่ดี:

ป้อนคำอธิบายรูปภาพที่นี่


อย่าลังเลที่จะตั้งค่าสถานะนี้เป็นคำตอบที่ถูกต้องเพื่อให้ผู้คนรู้ว่าคุณพบวิธีแก้ปัญหาของคุณแล้ว: P
SomeGuy

ใช่น่าเสียดายที่ฉันต้องรอหนึ่งวันเพื่อให้สามารถตั้งค่าสถานะคำตอบของฉันว่าถูกต้อง: S
Grieverheart

ความผิดพลาดของฉันไม่ได้ตรวจสอบการประทับเวลา
บางคนซื้อ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.