我一直在努力将SSAO应用到我正在编写的引擎中,并且出现了一个重大问题。在我意识到我的SSAO工作不正常之前,一切都很顺利。我发现有两件事我的SSAO错了,我无法弄清楚如何补救它们。
我的着色器代码在本文末尾,在此之前我将描述图像的问题。
首先,如下面的屏幕截图所示,根据观看角度出现了一些奇怪的文物。到目前为止,我假设我实现View矩阵的方式是错误的。我已经做了很多关于这一切应该如何工作的研究,我在理论上理解它。然而,在实践中事情并没有像我期望的那样改变。
其次,每当我接近块时,我会在屏幕边缘出现非常奇怪的三角形阴影,如下一个屏幕截图所示。 [![屏幕周围的奇数三角形阴影] [2]] [2]
这两张照片显示了我遇到的主要问题。我使用延迟类型渲染器将几何体渲染为几个纹理(位置,法线,颜色)导入这些纹理并使用它们来操纵最终输出。前两个代码块分别是顶点和片段着色器,用于将几何体转换为纹理。
顶点着色器 #version 430核心
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核心
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纹理的方式。这使得所有内核样本都非常奇怪。我修好了,现在我得到的东西就像下面的图片,其中一半的屏幕较暗,一半的屏幕在一侧较亮而在另一侧较暗。对比线随相机移动。
对此问题的任何帮助都会非常感激!
答案 0 :(得分:0)
我发现有两处错误,这些错误大部分可以解决当前帖子所涉及的问题。
首先,我在kernelMap中传递的格式已关闭,因此所有值都偏斜了。
第二,我无法弄清楚为什么,但是当我将位置和法线值传递给世界空间中的Lightingfragment着色器,然后将视图矩阵和投影矩阵应用于它们时,结果会很奇怪。但是,如果我将视图矩阵和投影矩阵应用于BaseGeometry着色器中的位置和法线值,然后将其还原到Lighting着色器中,则一切运行正常。
如果我发现更多信息,我会很乐意在这里发布以更新任何将来的搜索者。