gpt4 book ai didi

c++ - GLSL-SSAO : Getting undesired results when fetching depth position

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:53:43 25 4
gpt4 key购买 nike

我正在尝试根据本教程实现 SSAO:http://john-chapman-graphics.blogspot.com/2013/01/ssao-tutorial.html .我似乎不明白如何实现这一点,而且我的片段着色器中不断出现不希望的结果。

首先,我将我的着色器设置为传入深度缓冲区、相机的投影矩阵和 4x4 噪声纹理。 ssao 内核已经初始化并也传递到着色器中。我还从深度缓冲区中采样法线。

编辑:起初我以为我得到的深度位置不正确,所以我添加了一个名为 positionFromDepth 的新函数,但它似乎仍然不起作用...

我的片段着色器:

uniform sampler2D uDepthBuffer;
uniform sampler2D uNoiseTexture;

uniform mat4 uProjection; // camera's projection matrix
uniform mat4 uInverseMatrix; // inverse of projection matrix
uniform vec2 uNoiseScale; // vec2(1024.0 / 4.0, 768.0 / 4.0)

const int MAX_KERNEL_SIZE = 128;

uniform int uSampleKernelSize;
uniform vec3 uSampleKernel[MAX_KERNEL_SIZE];

uniform float uRadius;

const float zNear = 0.1;
const float zFar = 2579.5671;

float linearizeDepth(float near, float far, float depth) {
return 2.0 * near / (far + near - depth * (far - near));
}

vec3 positionFromDepth(vec2 texcoords) {
float d = linearizeDepth(zNear, zFar, texture2D(uDepthBuffer, texcoords).r);
vec4 pos = uInverseMatrix * vec4(texcoords.x * 2.0 - 1.0,
texcoords.y * 2.0 - 1.0,
d * 2.0 - 1.0, 1.0);

pos.xyz /= pos.w;

return pos.xyz;
}

vec3 normal_from_depth(float depth, vec2 texcoords) {
const vec2 offset1 = vec2(0.0, 0.001);
const vec2 offset2 = vec2(0.001, 0.0);

float depth1 = linearizeDepth(zNear, zFar, texture2D(uDepthBuffer, texcoords + offset1).r);
float depth2 = linearizeDepth(zNear, zFar, texture2D(uDepthBuffer, texcoords + offset2).r);

vec3 p1 = vec3(offset1, depth1 - depth);
vec3 p2 = vec3(offset2, depth2 - depth);

vec3 normal = cross(p1, p2);
normal.z = -normal.z;

return normalize(normal);
}

void main() {
vec2 texcoord = gl_TexCoord[0].st;

vec3 origin = positionFromDepth(texcoord);

float d = texture2D(uDepthBuffer, texcoord).r;
vec3 normal = normal_from_depth(linearizeDepth(zNear, zFar, d), texcoord) * 2.0 - 1.0;
normal = normalize(normal);

vec3 rvec = texture2D(uNoiseTexture, texcoord * uNoiseScale).rgb * 2.0 - 1.0;
vec3 tangent = normalize(rvec - normal * dot(rvec, normal));
vec3 bitangent = cross(normal, tangent);
mat3 tbn = mat3(tangent, bitangent, normal);

float occlusion = 0.0;

for(int i = 0; i < uSampleKernelSize; i++) {
vec3 sample = tbn * uSampleKernel[i];
sample = sample * uRadius + origin.xyz;

vec4 offset = vec4(sample, 1.0);
offset = uProjection * offset;
offset.xy /= offset.w;
offset.xy = offset.xy * 0.5 + 0.5;

float sampleDepth = positionFromDepth(offset.xy).z;
occlusion += (sampleDepth <= sample.z ? 1.0 : 0.0);
}

occlusion = 1.0 - (occlusion / float(uSampleKernelSize));
gl_FragColor = vec4(pow(occlusion, 4.0));
}

当我四处移动相机时,被遮挡的样本会发生变化。结果看起来像这样:

Result from SSAO shader

我假设我在对深度位置进行采样时做错了什么,但也许我在投影矩阵上也做错了。 uProjection 矩阵应该转置还是反转?谁能确定问题所在?

也请忽略我还没有进行模糊处理这一事实。

最佳答案

这里有几件事需要考虑。您已将原始的 linearizeDepth 方程替换为不同的方程。原始的 linearizeDepth 函数是基于这个 formula .

请注意,如果您尝试根据此公式推导函数,您会发现 linearizeDepth 函数返回的实际上是 Z 的倒数,而不仅仅是 Z。

我不能说这会在多大程度上影响 SSAO 算法,但考虑到我从自己研究代码中学到的东西,我会非常小心地修改我不完全理解的等式部分。从本质上讲,我不确定代码是否会继续执行它应该执行的操作。

具体来说,我相信 linearizeDepth 在这种情况下的目的不是在 z 轴上均匀分布明暗(我相信,这就是你在这里所做的),而是更便宜取消投影 Z' 坐标。

关于c++ - GLSL-SSAO : Getting undesired results when fetching depth position,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23588078/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com