Наличие некоторых странных артефактов и странных теневых треугольников с помощью SSAO Opengl Implmentation - PullRequest
0 голосов
/ 03 июня 2018

Я работал над внедрением SSAO в движок, который я пишу, и появилась большая проблема.Все шло довольно хорошо, пока я не понял, что мой SSAO работает неправильно.Я могу найти две вещи, которые не подходят для моего SSAO, и я не могу понять, как их исправить.

Мой код шейдера находится в конце этого поста, перед тем как я буду описыватьпроблемы с изображениями.

Во-первых, как видно на скриншоте ниже, в зависимости от угла обзора появляются странные артефакты.Пока что я предполагаю, что способ реализации матрицы представления неверен.Я провел много исследований о том, как все это должно работать, и я понимаю это теоретически.Однако на практике все не меняется, как я ожидал.Strange artifacting on ssao shader.

Во-вторых, всякий раз, когда я приближаюсь к блокам, я получаю очень странные тени треугольника, которые появляются по краям экрана, как показано на следующем снимке экрана.[! [Нечетные треугольные тени вокруг экрана] [2]] [2]

Эти два изображения показывают основные проблемы, с которыми я сталкиваюсь.Я использую рендерер с отложенным типом для рендеринга геометрии в несколько текстур (положение, нормали, цвет), импортирую эти текстуры и использую их для манипулирования конечным результатом.Первые два кодовых блока - это вершинный и фрагментный шейдеры соответственно для перевода геометрии в текстуры.

Vertex Shader # версия 430 core

layout(location=0) in mat4 modelMatrix;
layout(location=4) in vec4 VertexPosition;
layout(location=5) in vec4 VertexNormal;
layout(location=6) in vec3 VertexColor;
layout(location=7) in vec2 TextureCoords;
out vec4 vNormal;
out vec3 vColor;
out vec4 shaderCoord;
out vec2 texCoords;

layout(location=8) uniform mat4 V;
layout(location=12) uniform mat4 P;



void main()
{

    shaderCoord = (V*modelMatrix * VertexPosition);

     mat4 normalMatrix = transpose(inverse(V*modelMatrix));
    vNormal = (normalMatrix*VertexNormal);

    texCoords = TextureCoords;
    vColor = VertexColor;
    gl_Position =  P*shaderCoord;
}

Фрагментный шейдер

#version 430 core

in vec4 vNormal;
in vec3 vColor;
in vec4 shaderCoord;
in vec2 texCoords;
layout (location=0) out vec4 NormalBuffer;
layout (location=1) out vec4 ColorBuffer;
layout (location=2) out vec4 PositionBuffer;
layout (location=3) out vec4 TextureCoordBuffer;
out float fragDepth;

//Start of the main function.
void main()
{   
    NormalBuffer = vec4(normalize(vNormal).xyz, 1.0);
    ColorBuffer = vec4(vColor, 1.0);
    PositionBuffer = vec4(shaderCoord.xyz, 1.0);
    TextureCoordBuffer = vec4(texCoords, 0.0, 1.0);
    fragDepth = gl_FragCoord.z;
}

Как видите, я перевожу все из мирового пространства в пространство обзора, прежде чем записать их в текстуры.Я бы предпочел держать их в мировом пространстве, но когда я это делаю, весь экран выглядит белым с редкими намеками на тени, но фон меняется между белым и черным в зависимости от угла наклона камеры.

Далее идут мои шейдеры SSAOЧтобы реализовать их, я следовал нескольким учебникам, чтобы они, вероятно, выглядели знакомыми.Если учебник был правильным, следующие два шейдера должны работать правильно, но это не так.

Vetex-шейдер, который просто создает квад и применяет к нему окончательную текстуру.#version 430 core

layout (location=0) in vec3 VertexPosition;
layout (location=1) in vec2 TextureCoords;

out vec2 texCoords;

void main (){
    texCoords = TextureCoords;
    gl_Position = vec4(VertexPosition, 1.0);
}

Фрагментный шейдер для SSAO

#version 430 core

in vec2 texCoords;

layout (location=0) out vec4 fColor;

uniform sampler2D NormalBuffer;
uniform sampler2D positionBuffer;

uniform sampler2DArrayShadow shadowMap;
uniform sampler1D SSAOKernelMap;
uniform sampler2D SSAONoiseMap; 

layout(location=12) uniform mat4 P;
layout(location=8) uniform mat4 V;

uniform uint kernelSize;
uniform vec2 windowSize;

//Define Variables for SSAO Processing.
float radius = 0.5;
float SSAOBias = 0.025;
float power = 1.5;
//mat4 biasMatrix = mat4(0.5,0.0,0.0,0.0,0.0,0.5,0.0,0.0,0.0,0.0,0.5,0.0,0.5,0.5,0.5,1.0);

void main()
{   
    //Retrieve from textures
    vec3 shaderCoord = (texture(positionBuffer, texCoords)).xyz;
    vec3 vNormal = normalize((texture(NormalBuffer, texCoords)).rgb);
    //process SSAO
    vec2 NoiseScale = vec2(windowSize.x/4.0, windowSize.y/4.0);
    vec3 randVec = normalize(texture(SSAONoiseMap, texCoords*NoiseScale).xyz);

    vec3 tangent = normalize(randVec - vNormal * dot(randVec, vNormal));
    vec3 bitTangent = cross(vNormal, tangent);
    mat3 TBN = mat3(tangent, bitTangent, vNormal);

    //Begin Processing of SSAO with inputed Kernel Samples
    float Occlusion = 0.0;
    for(int i=0; i<kernelSize; i++){
        vec4 kernelSample = texture(SSAOKernelMap, i);
        vec3 TSample = TBN*kernelSample.rgb;
        TSample = shaderCoord + TSample * radius;

        vec4 newCoord = vec4(TSample, 1.0);
        newCoord = P*newCoord;
        newCoord.xyz /= newCoord.w;
        newCoord.xyz = newCoord.xyz * 0.5 + 0.5;


        float sampleDepth = texture(positionBuffer,newCoord.xy).z;
        //float rangeCheck = smoothstep(0.0,1.0, radius / abs(shaderCoord.z-sampleDepth));
        Occlusion += (sampleDepth >= TSample.z+SSAOBias?1.0:0.0);
    }
    Occlusion =  1.0 - (Occlusion/kernelSize);
    fColor = vec4(vec3(Occlusion),1.0f);
}

Это вся информация, которую я могу представить на начальном этапе.Любая помощь, которую вы, ребята, можете оказать, была бы чрезвычайно полезной!Если любая другая информация поможет, пожалуйста, дайте мне знать, и я буду рад предоставить.

РЕДАКТИРОВАТЬ: Я понял, что одной из моих проблем был способ доступа к 1D-текстуре выше.Это сделало все образцы ядра очень странными.Я исправил это, и теперь я получаю что-то вроде изображения ниже, где половина экрана темнее, а половина светлее с одной стороны и темнее с другой.Линия контрастности перемещается вместе с камерой.Wierd line

Любая помощь в этом вопросе будет очень признателен!

1 Ответ

0 голосов
/ 03 июля 2018

Я обнаружил две ошибки, которые в основном решили проблему, о которой идет речь в этом текущем сообщении.

Во-первых, формат, который я передавал в kernelMap, был отключен, и поэтому все значения были довольно искажены.

Во-вторых, я не смог понять, почему, но когда я передал положение и нормальные значения шейдеру Lightingfragment в мировом пространстве, а затем применил к ним матрицы вида и проекции, они получились бы очень странно.Однако, если я применил матрицы вида и проекции к положению и нормальным значениям в шейдере BaseGeometry, то вернул это приложение в шейдере Lighting, и все работает отлично.

Если я найду дополнительную информацию, я с удовольствием выложу здесьобновить любые будущие поисковики.

...