SSAO работает, но имеет странное наложение красного цвета - PullRequest
0 голосов
/ 10 июня 2018

Ssao работает, но есть странное наложение красного цвета из-за того, что Ssao использует только красный канал, конечно , это показано на рисунке ниже.

Красный SSAO ПроблемаRed SSAO Problem

Однако, когда я делаю glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); красный цвет уходит, но ссао тоже идет.

Результат после выполнения glClear ().Нет SSAO большеResult after doing glClear(). No SSAO anymore

Вот весь код, который вам нужен ...

// ------------------------------ LIGHT PASS -------------------------------- //
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    shaders[LIGHT_PASS]->UseProgram();  // Bind light pass shader

    // Parse the camera position
    LightPass::Render(Content::_map->GetCamera(), Content::_map->GetCamera()->GetPosition());   

    GBuffer::Render();  // bind the gbuffer textures (includes SSAO)

    renderQuad();   // Render the screen rectangle
    // -------------------------------------------------------------------- //

Код доступа к геометрии ..

// ----------------------------- GEOMETRY PASS ----------------------------- //
    GBuffer::Bind();    // Bind the world gbuffer frame buffer
    shaders[GEOMETRY_PASS]->UseProgram();   // Bind geometry shader
    GeometryPass::Render();     // Render geometry
    glBindFramebuffer(GL_FRAMEBUFFER, 0);   // Unbind the gbuffer
    // --------------------------------------------------------------------- //

SSAOКод доступа ..

static inline void Initialise(unsigned int ssao_program, unsigned int ssaoblur_program) 
    {
        program = ssao_program;
        program2 = ssaoblur_program;

        // SSAO color fbo
        glGenTextures(1, &ssaoColorBuffer);
        glBindTexture(GL_TEXTURE_2D, ssaoColorBuffer);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 1920, 1080, 0, GL_RGB, GL_FLOAT, NULL);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoColorBuffer, 0);
        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
            std::cout << "SSAO Framebuffer not complete!" << std::endl;

        glBindFramebuffer(GL_FRAMEBUFFER, 0);

        // blur fbo
        glGenFramebuffers(1, &ssaoBlurFBO);
        glBindFramebuffer(GL_FRAMEBUFFER, ssaoBlurFBO);

        // SSAO color buffer
        glGenTextures(1, &ssaoColorBufferBlur);
        glBindTexture(GL_TEXTURE_2D, ssaoColorBufferBlur);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 1920, 1080, 0, GL_RGB, GL_FLOAT, NULL);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoColorBufferBlur, 0);
        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
            std::cout << "SSAO Framebuffer not complete!" << std::endl;

        glBindFramebuffer(GL_FRAMEBUFFER, 0);

        std::uniform_real_distribution<GLfloat> randomFloats(0.0, 1.0); // generates random floats between 0.0 and 1.0
        std::default_random_engine generator;

        for (unsigned int i = 0; i < 64; ++i)
        {
            glm::vec3 sample(randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) * 2.0 - 1.0, randomFloats(generator));
            sample = glm::normalize(sample);
            sample *= randomFloats(generator);
            float scale = float(i) / 64.0;

            // scale samples s.t. they're more aligned to center of kernel
            scale = lerp(0.1f, 1.0f, scale * scale);
            sample *= scale;
            ssaoKernel.push_back(sample);
        }

        for (unsigned int i = 0; i < 16; i++)
        {
            glm::vec3 noise(randomFloats(generator) * 2.0 - 1.0, randomFloats(generator) * 2.0 - 1.0, 0.0f); // rotate around z-axis (in tangent space)
            ssaoNoise.push_back(noise);
        }
        glGenTextures(1, &noiseTexture);
        glBindTexture(GL_TEXTURE_2D, noiseTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, 4, 4, 0, GL_RGB, GL_FLOAT, &ssaoNoise[0]);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

        glUseProgram(ssao_program);
        glUniform1i(glGetUniformLocation(ssao_program, "gPosition"), 0); // the positions texture in the gbuffer
        glUniform1i(glGetUniformLocation(ssao_program, "gNormal"), 1); // the normals texture in the gbuffer
        glUniform1i(glGetUniformLocation(ssao_program, "texNoise"), 2); // the albedospec texture within the gbuffe

        glUseProgram(ssaoblur_program);
        glUniform1i(glGetUniformLocation(ssaoblur_program, "ssaoInput"), 0); // the positions texture in the gbuffer
    }

static inline void Render(Camera* _camera) 
    {
        // generate SSAO texture
        glBindFramebuffer(GL_FRAMEBUFFER, ssaoFBO);
        glClear(GL_COLOR_BUFFER_BIT);
        glUseProgram(program);

        for (unsigned int i = 0; i < 64; ++i)
            glUniform3fv(glGetUniformLocation(program, ("samples[" + std::to_string(i) + "]").c_str()), 1, glm::value_ptr(ssaoKernel[i]));

        glUniformMatrix4fv(glGetUniformLocation(program, "proj"), 1, GL_FALSE, glm::value_ptr(_camera->GetProjectionMatrix()));

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, GBuffer::GetPositions());
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, GBuffer::GetNormals());
        glActiveTexture(GL_TEXTURE2);
        glBindTexture(GL_TEXTURE_2D, noiseTexture);

        renderQuad();

        glBindFramebuffer(GL_FRAMEBUFFER, 0);

        // Blur ssao texture
        glBindFramebuffer(GL_FRAMEBUFFER, ssaoBlurFBO);
        glClear(GL_COLOR_BUFFER_BIT);

        glUseProgram(program2);

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, ssaoColorBuffer);

        renderQuad();

        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }

GBuffer vertex shader ..

#version 420 core

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 texcoord;
layout(location = 2) in vec3 normal;
layout(location = 3) in vec3 tangent;

out vec3 _texcoord;
out vec3 _normal;
out vec3 _tangent;
out vec3 _frag_pos;

uniform mat4 mod;
uniform mat4 view;
uniform mat4 proj;


void main()
{
    vec4 view_space = view * mod * vec4(position, 1.0);
    _frag_pos = view_space.xyz;
    _texcoord = texcoord;

    _normal = ((view * mod) * vec4(normal, 0.0)).xyz;
    _tangent = (mod * vec4(tangent, 0.0)).xyz;

    gl_Position = proj * view_space;
}

GBuffer фрагментный шейдер ...

#version 420 core

layout(location = 0) out vec3 gPosition;    // Position texel colour
layout(location = 1) out vec3 gNormal;  // Normal texel colour
layout(location = 2) out vec4 gAlbedo;  // Albedo texel colour
layout(location = 3) out vec3 gSpecular;    // Cubemap texel colour
layout(location = 4) out vec3 gMetalness;   // Cubemap texel colour

in vec3 _texcoord;
in vec3 _normal;
in vec3 _tangent;
in vec3 _frag_pos;

uniform vec3        camera_pos;

uniform sampler2D   normal;     // Normal map
uniform sampler2D   albedo;     // Albedo and specular map
uniform sampler2D   specular;   // Specular map
uniform sampler2D   metalness;  // Metalness map

uniform samplerCube cubemap;    // Local cubemap reflection sampler


vec3 TBN()
{
    vec3 Normal = normalize(_normal);   // Optimise normal
    vec3 Tangent = normalize(_tangent);     // Optimise tangent

    vec3 Bitangent = cross(Tangent, Normal);    // Calculate bitangent
    vec3 BumpMapNormal = texture(normal, vec2(_texcoord).st).rgb;   // Assign rgb values from normal map

    BumpMapNormal = 2.0 * BumpMapNormal - vec3(1.0, 1.0, 1.0);  // normalise the normal map between -1 to 1

    mat3 TBN = mat3(Tangent, Bitangent, Normal);    // Create tangent, bitangent and normal matrix

    vec3 NewNormal;     // Create a new normal variable
    NewNormal = TBN * vec3(BumpMapNormal.r, -BumpMapNormal.g, BumpMapNormal.b);     // Flip green component for OpenGL
    NewNormal = normalize(NewNormal);   // Normalise the new normal

    return NewNormal;   // Return the newly calculated normal
}

vec4 Convolute()
{
    vec4 result = vec4(0.0);

    const float kernel[] = float[25] ( 0,1,2,1,0,
                                       1,2,3,2,1,
                                       2,3,4,3,2,
                                       1,2,3,2,1,
                                       0,1,2,1,0);

    vec2 delta = 1.0 / textureSize(albedo, 0);
    int index = 24;

    for (int j = -1; j <= 1; j++)
    {
        for (int i = -1; i <= 1; i++)
        {
            //for (int k = -1; k <= 1; k++)
            result += kernel[index--] * texture(albedo, vec2(_texcoord).st + (vec2(i, j) * delta));
        }
    }

    result /= 25.0;
    return result;
}

void main()
{
    gPosition = _frag_pos;
    gNormal = normalize(TBN());

    vec3 I = normalize(_frag_pos - camera_pos);     // Calculate eye to fragment direction
    vec3 R = reflect(I, normalize(TBN()));  // Reflect I with the vertex normal
    float M = texture(metalness, vec2(_texcoord.st)).r;

    //vec4 gaussian = Convolute();
    gAlbedo = texture(albedo, vec2(_texcoord.st));  // Assign albedo
    gSpecular = texture(specular, vec2(_texcoord.st)).rgb;  // Assign specular
    gMetalness = (texture(cubemap, R).rgb) * M;     // Assign metalness
}

light shader ...

#version 420 core

out vec4 FragColor;

in vec2 _texcoord;


uniform vec3        camera_pos;
uniform sampler2D   gPosition;
uniform sampler2D   gNormal;
uniform sampler2D   gAlbedo;
uniform sampler2D   gSpecular;
uniform sampler2D   gMetalness;
uniform sampler2D   gSsao;

uniform vec3 lightPos;


void main(void)
{
    vec3 FragPos = texture(gPosition, _texcoord).rgb;
    vec3 Normal = texture(gNormal, _texcoord).rgb;
    vec3 Diffuse = texture(gAlbedo, _texcoord).rgb;
    float Emissive = texture(gAlbedo, _texcoord).a;
    vec3 Specular = texture(gAlbedo, _texcoord).rgb;
    vec3 Metalness = texture(gMetalness, _texcoord).rgb;    // Reflection pass

    float AmbientOcclusion = texture(gSsao, _texcoord).r;

    vec3 light_colour = vec3(1.0f, 0.8, 0.7);

    vec3 lighting = vec3(0.3 * Diffuse * AmbientOcclusion);
    vec3 viewDir = normalize(-FragPos);
    vec3 lightDir = normalize(lightPos - FragPos);
    vec3 diffuse = max(dot(Normal, lightDir), 0.0) * Diffuse * light_colour;    // Light colour

    vec3 halfwayDir = normalize(lightDir + viewDir);
    float spec = pow(max(dot(Normal, halfwayDir), 0.0), 32.0);
    vec3 specular = (Specular * light_colour) * spec;

    vec3 metalness = Metalness * Diffuse;

    lighting += diffuse + specular + metalness;

    FragColor = vec4(lighting, 1.0);
}

Любой другой код нужно просто спросить.спасибо за любую помощь

РЕДАКТИРОВАТЬ Проблема исправлена, была вызвана отражением кубической карты, все работало сейчас

1 Ответ

0 голосов
/ 10 июня 2018

Если искать текстуру, а конкретный канал текстуры не присутствует в текстуре, то функция texture вернет 0.0 для зеленого и синего каналов и 1.0 для альфа-канала.

Это может быть изменено параметрами текстуры Swizzle GL_TEXTURE_SWIZZLE_R, GL_TEXTURE_SWIZZLE_G, GL_TEXTURE_SWIZZLE_B и GL_TEXTURE_SWIZZLE_A.

Если вы хотите, чтобы зеленый исиний канал возвращает то же значение, что и красный канал, тогда это можно сделать так:

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED );

Примените эти параметры к объектам текстуры ssaoColorBuffer и ssaoColorBufferBlur, чтобы решить проблему.

См. Спецификация профиля ядра API OpenGL 4.6;15,2.ШЕЙДЕР ИСПОЛНЕНИЕ;стр. 487 ]:

Когда поиск текстуры выполняется в фрагментном шейдере, GL вычисляет значение отфильтрованной текстуры ... и преобразует его в базовый цвет текстуры Cb, как показано в таблице.15.1,

Texture Base Texture base color Internal Format    Cb              Ab
RED                                                (Rt, 0, 0)      1
RG                                                 (Rt, Gt, 0)     1
RGB                                                (Rt, Gt, Bt)    1
RGBA                                               (Rt, Gt, Bt)    At

Таблица 15.1: Соответствие отфильтрованных текстурных компонентов базовым компонентам текстуры.

с последующим переворотом компонентов Cb, управляемых значениямипараметры текстуры TEXTURE_SWIZZLE_R, TEXTURE_SWIZZLE_G, TEXTURE_SWIZZLE_B и TEXTURE_SWIZZLE_A.Если значение TEXTURE_SWIZZLE_R обозначено swizzler, swizzling вычисляет первый компонент Cs в соответствии с

if (swizzler == RED)
Cs[0] = Cb[0];
else if (swizzler == GREEN)
Cs[0] = Cb[1];
else if (swizzler == BLUE)
Cs[0] = Cb[2];
else if (swizzler == ALPHA)
Cs[0] = Ab;
else if (swizzler == ZERO)
Cs[0] = 0;
else if (swizzler == ONE)
Cs[0] = 1; // float or int depending on texture component type
...