从标题中可以看出,我正在尝试在使用延迟渲染和环境光遮蔽的同时创建镜面反射。对于环境光遮挡,我专门使用 ssao 算法。
为了创建镜子,我使用的基本思想是将所有模型反射到镜子的另一侧,然后只渲染通过镜子可见的部分。
使用延迟渲染,我决定在创建 gBuffer 期间执行此操作。为了实现反射物体的正确照明,我确保 gBuffer 中反射物体的位置和法线与它们的“非反射”版本相同。这样,实际模型及其图像都会收到相同的照明。
我的问题现在与 ssao 算法有关。似乎反射对象被计算为高度遮挡,这导致您可以在镜子中看到黑色区域:
我注意到这些黑色区域只出现在我看不到的地方。没有镜子我能看到的东西上没有意想不到的黑点。
请注意,gBuffer 中的数据都在视图空间中。所以那里一定有联系。也许在 ssao 期间使用的随机样本或其法线计算不正确。
所以,这是环境光遮蔽的片段着色器:
void main()
{
vec3 fragPos = texture(gPosition, TexCoords).xyz;
vec3 normal = texture(gNormal, TexCoords).rgb;
vec3 randomVec = texture(texNoise, TexCoords * noiseScale).xyz;
vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
vec3 bitangent = cross(normal, tangent);
mat3 TBN = mat3(tangent, bitangent, normal);
float occlusion = 0.0;
float kernelSize=64;
for(int i = 0; i < kernelSize; ++i)
{
// get sample position
vec3 sample = TBN * samples[i]; // From tangent to view-space
sample = fragPos + sample * radius;
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;
float sampleDepth = texture(gPosition, offset.xy).z;
float rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z -
sampleDepth));
occlusion += (sampleDepth >= sample.z + bias ? 1.0 : 0.0) * rangeCheck;
}
occlusion = 1.0 - (occlusion / kernelSize);
//FragColor = vec4(1,1,1,1);
occl=vec4(occlusion,occlusion,occlusion,1);
}
关于为什么会出现这些黑色区域的任何想法或纠正它们的建议?我可以忽略反射中的环境光遮挡,但我对此并不满意。
也许,如果环境光遮蔽着色器使用反射对象的位置和法线,就不会有问题。但是后来我会遇到在缓冲区中保存更多东西的麻烦,所以我现在放弃了这个想法。