首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SSAO阴影移动奇怪与相机(计算gbuffer错误)

SSAO阴影移动奇怪与相机(计算gbuffer错误)
EN

Stack Overflow用户
提问于 2016-10-11 03:59:41
回答 1查看 476关注 0票数 1

我试图用本教程实现这个版本的ssao:

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

这里是我的渲染纹理结束的结果。

当我移动相机时,阴影似乎跟着我。

好像我错过了某种矩阵乘法的相机。

代码

gBuffer顶点

代码语言:javascript
复制
#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片段

代码语言:javascript
复制
#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顶点

代码语言:javascript
复制
#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片段

代码语言:javascript
复制
#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:

代码语言:javascript
复制
float sampleDepth = (viewMatrix * -texture(gPositionDepth, offset.xy)).w;

但似乎这只会让事情变得更糟。

这是另一幅从上到上的视图,你可以看到阴影随着摄像机的移动。

如果我用某种方式定位我的相机,事情就会排列起来

EN

回答 1

Stack Overflow用户

发布于 2016-10-11 16:12:31

虽然我只能在n顶点着色器中假定你的法线矩阵的值,但似乎你不把法线存储在视图空间中,而是在世界空间。由于SSAO计算是在屏幕空间中完成的,这可以(至少部分)解释意外行为。在这种情况下,您要么需要将视图矩阵v乘以法线,然后再将它们存储到gBuffer (可能更有效,但可能会干扰其他阴影计算),或者在检索它们之后。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39970311

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档