2016-10-11 3 views
1

Я пытаюсь реализовать эту версию SSAO с этого урока:SSAO затенение движется странно с камерой (вычислительное GBuffer неправильно)

http://www.learnopengl.com/#!Advanced-Lighting/SSAO

Вот что я в конечном итоге с моим рендеринга текстур.

enter image description here

Когда я двигаю камеру тени, кажется, следуют

enter image description here

Кажется, мне не хватает какой-то умножение матриц с камерой.

КОД

GBuffer вершинных

#version 330 core 
layout (location = 0) in vec3 vertexPosition; 
layout (location = 1) in vec3 vertexNormal; 

out vec3 position; 
out vec3 normal; 

uniform mat4 m; 
uniform mat4 v; 
uniform mat4 p; 
uniform mat4 n; 

void main() 
{ 
    vec4 viewPos = v * m * vec4(vertexPosition, 1.0f); 
    position = viewPos.xyz; 
    gl_Position = p * viewPos; 
    normal = vec3(n * vec4(vertexNormal, 0.0f)); 
} 

GBuffer Фрагмент

#version 330 core 
layout (location = 0) out vec4 gPosition; 
layout (location = 1) out vec3 gNormal; 
layout (location = 2) out vec4 gColor; 

in vec3 position; 
in vec3 normal; 

const float NEAR = 0.1f; 
const float FAR = 50.0f; 
float LinearizeDepth(float depth) 
{ 
    float z = depth * 2.0f - 1.0f; 
    return (2.0 * NEAR * FAR)/(FAR + NEAR - z * (FAR - NEAR)); 
} 

void main() 
{ 
    gPosition.xyz = position; 
    gPosition.a = LinearizeDepth(gl_FragCoord.z); 
    gNormal = normalize(normal); 
    gColor.rgb = vec3(1.0f); 
} 

SSAO вершинных

#version 330 core 

layout (location = 0) in vec3 vertexPosition; 
layout (location = 1) in vec2 texCoords; 

out vec2 UV; 

void main(){ 
    gl_Position = vec4(vertexPosition, 1.0f); 
    UV = texCoords; 
} 

SSAO Фрагмент

#version 330 core 

out float FragColor; 
in vec2 UV; 

uniform sampler2D gPositionDepth; 
uniform sampler2D gNormal; 
uniform sampler2D texNoise; 
uniform vec3 samples[32]; 
uniform mat4 projection; 

// parameters (you'd probably want to use them as uniforms to more easily tweak the effect) 
int kernelSize = 32; 
float radius = 1.0; 

// tile noise texture over screen based on screen dimensions divided by noise size 
const vec2 noiseScale = vec2(1024.0f/4.0f, 1024.0f/4.0f); 

void main() 
{ 
    // Get input for SSAO algorithm 
    vec3 fragPos = texture(gPositionDepth, UV).xyz; 
    vec3 normal = texture(gNormal, UV).rgb; 
    vec3 randomVec = texture(texNoise, UV * noiseScale).xyz; 
    // Create TBN change-of-basis matrix: from tangent-space to view-space 
    vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal)); 
    vec3 bitangent = cross(normal, tangent); 
    mat3 TBN = mat3(tangent, bitangent, normal); 
    // Iterate over the sample kernel and calculate occlusion factor 
    float occlusion = 0.0; 
    for(int i = 0; i < kernelSize; ++i) 
    { 
     // get sample position 
     vec3 sample = TBN * samples[i]; // From tangent to view-space 
     sample = fragPos + sample * radius; 

     // project sample position (to sample texture) (to get position on screen/texture) 
     vec4 offset = vec4(sample, 1.0); 
     offset = projection * offset; // from view to clip-space 
     offset.xyz /= offset.w; // perspective divide 
     offset.xyz = offset.xyz * 0.5 + 0.5; // transform to range 0.0 - 1.0 

     // get sample depth 
     float sampleDepth = -texture(gPositionDepth, offset.xy).w; // Get depth value of kernel sample 

     // range check & accumulate 
     float rangeCheck = smoothstep(0.0, 1.0, radius/abs(fragPos.z - sampleDepth)); 
     occlusion += (sampleDepth >= sample.z ? 1.0 : 0.0) * rangeCheck; 
    } 
    occlusion = 1.0 - (occlusion/kernelSize); 
    FragColor = occlusion; 
} 

Я прочитал и увидел кого-то был подобный вопрос и принял матрицу вида в SSAO шейдера и умножили sampleDepth:

float sampleDepth = (viewMatrix * -texture(gPositionDepth, offset.xy)).w; 

Но кажется как будто это еще хуже.

Heres другой вид сверху вершины, где вы можете увидеть тени двигаться с камерой

enter image description here

Если я устанавливаю свою камеру определенным образом вещи выстраивают

enter image description here

ответ

0

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

+0

Моя нормальная матрица - glm :: mat4 n = glm :: transpose (glm :: inverse (view * model)); Поэтому я бы умножался в вершинном шейдере normal = vec3 (v * n * vec4 (vertexNormal, 0.0f)); ? Как это сделать для освещения? – namenamesoseji

+0

Также у вас есть пример того, как должен выглядеть мой обычный буфер?Когда я ищу в Интернете для отложенного рендеринга gbuffer и ssao, иногда обычный буфер имеет разные цвета – namenamesoseji

+0

У меня нет примера, но ваша нормальная матрица должна быть 'glm :: mat4 n = view * glm :: transpose (glm :: inverse (модель)) '. Вы не должны переставлять и инвертировать матрицу представления. –