Después de haber implementado el renderizado diferido, probé suerte con una implementación SSAO usando este Tutorial . Desafortunadamente, no obtengo nada que se parezca a SSAO, puedes ver mi resultado a continuación.
Puede ver que se está formando un patrón extraño y no hay sombreado de oclusión donde sea necesario (es decir, entre los objetos y en el suelo). Los sombreadores que implementé son los siguientes:
#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);
}
Dibujo un quad de pantalla completa y paso texturas de profundidad y normal. Las normales están en RGBA16F con el canal alfa reservado para el factor AO en el paso borroso. Almaceno la profundidad en un búfer de profundidad no lineal (32F) y recupero la profundidad lineal usando:
float linearDepth = projAB.y / (depth - projAB.x);
donde projAB.y
se calcula como:
y projAB.x
como:
Estos se derivan de la matriz glm :: perspective (gluperspective). z_n y z_f son la distancia de recorte cercana y lejana.
Como se describe en el enlace que publiqué en la parte superior, el método crea muestras en un hemisferio con una distribución más alta cerca del centro. Luego usa vectores aleatorios de una textura para rotar el hemisferio aleatoriamente alrededor de la dirección Z y finalmente lo orienta a lo largo de la normalidad en el píxel dado. Como el resultado es ruidoso, un pase borroso sigue al pase SSAO.
De todos modos, la reconstrucción de mi posición no parece estar mal ya que también intenté hacer lo mismo, pero la posición pasó de una textura en lugar de ser reconstruida.
También intenté jugar con el Radio, el tamaño de la textura de ruido y el número de muestras y con diferentes tipos de formatos de textura, sin suerte. Por alguna razón al cambiar el Radio, nada cambia.
¿Alguien tiene alguna sugerencia? ¿Qué podría estar yendo mal?
fuente
Respuestas:
Encontré el problema. Fue un error realmente estúpido, no sabía que tenía que especificar
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
para obtener los valores de profundidad correctos y, por lo tanto, no estaba muestreando los valores de profundidad. Ahora obtengo un buen efecto SSAO:fuente