Không nhận được kết quả mong muốn khi triển khai SSAO


12

Sau khi thực hiện kết xuất hoãn lại, tôi đã thử vận ​​may với việc triển khai SSAO bằng Hướng dẫn này . Thật không may, tôi không nhận được bất cứ thứ gì trông giống như SSAO, bạn có thể thấy kết quả của tôi dưới đây.

thất bại ssao

Bạn có thể thấy có một số mô hình kỳ lạ đang hình thành và không có bóng che lấp ở nơi cần phải có (tức là ở giữa các vật thể và trên mặt đất). Các shader tôi thực hiện theo:


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

Tôi vẽ một quad toàn màn hình và vượt qua họa tiết Độ sâu và Bình thường. Các tiêu chuẩn nằm trong RGBA16F với kênh alpha dành riêng cho yếu tố AO trong đường chuyền mờ. Tôi lưu trữ độ sâu trong bộ đệm Độ sâu phi tuyến tính (32F) và khôi phục độ sâu tuyến tính bằng cách sử dụng:


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

Ở đâu projAB.y được tính là:

nhập mô tả hình ảnh ở đây

projAB.x như:

nhập mô tả hình ảnh ở đây

Chúng được lấy từ ma trận glm :: perspective (glupers perspective). z_n và z_f là khoảng cách clip gần và xa.

Như được mô tả trong liên kết tôi đã đăng ở trên cùng, phương pháp tạo các mẫu trong một bán cầu với phân phối cao hơn gần trung tâm. Sau đó, nó sử dụng các vectơ ngẫu nhiên từ một kết cấu để xoay bán cầu ngẫu nhiên xung quanh hướng Z và cuối cùng định hướng nó dọc theo bình thường tại pixel đã cho. Vì kết quả là nhiễu, một đường chuyền mờ theo sau đường chuyền SSAO.

Dù sao, việc tái cấu trúc vị trí của tôi dường như không sai vì tôi cũng đã thử làm như vậy nhưng với vị trí được truyền từ một kết cấu thay vì được xây dựng lại.

Tôi cũng đã thử chơi với Radius, kích thước kết cấu nhiễu và số lượng mẫu và với các loại định dạng kết cấu khác nhau, không có may mắn. Vì một số lý do khi thay đổi Bán kính, không có gì thay đổi.

Có ai có bất cứ đề nghị? Điều gì có thể đi sai?


Tôi nghĩ rằng mờ cần phải là một vượt qua riêng biệt. Bạn có thể đăng một ảnh chụp màn hình của shader của bạn mà không bị mờ?
hiệp sĩ666

Pass mờ là riêng biệt, bạn có thể kiểm tra ảnh chụp màn hình trước mờ .
Grieverlove

Câu trả lời:


6

Tôi tìm thấy vấn đề. Đó là một sai lầm thực sự ngu ngốc, tôi không biết bạn phải chỉ định glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);để có được các giá trị độ sâu chính xác và do đó, tôi đã không lấy mẫu các giá trị Độ sâu. Bây giờ tôi có được hiệu ứng SSAO đẹp:

nhập mô tả hình ảnh ở đây


Vui lòng gắn cờ đây là câu trả lời đúng để mọi người biết bạn đã tìm thấy giải pháp của bạn: P
Một số

Vâng, thật không may, tôi phải đợi một ngày để có thể đánh dấu câu trả lời của mình là chính xác: S.
Grieverlove

Lỗi của tôi, đã không kiểm tra dấu thời gian.
Một sốGuy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.