在自由度测试期间,伪影被发现,如图所示:
片段着色器代码:
#version 330
#define KERNEL_RADIUS 4
in vec2 texCoord;
layout (location = 0) out vec3 fragColor;
uniform sampler2D image;
uniform sampler2D positionMap;
uniform struct CinematicDOF {
float p; // plane in focus
float a; // aperture
float i; // image distance
} cinematicDOF;
float dof_kernel[KERNEL_RADIUS];
const int DOF_LCR_SIZE = KERNEL_RADIUS * 2 - 1; // left-center-right (lllcrrr)
const int DOF_MEAN = DOF_LCR_SIZE / 2;
void makeDofKernel(float sigma) {
float sum = 0; // For accumulating the kernel values
for (int x = DOF_MEAN; x < DOF_LCR_SIZE; x++) {
dof_kernel[x - DOF_MEAN] = exp(-0.5 * pow((x - DOF_MEAN) / sigma, 2.0));
// Accumulate the kernel values
sum += dof_kernel[x - DOF_MEAN];
}
sum += sum - dof_kernel[0];
// Normalize the kernel
for (int x = 0; x < KERNEL_RADIUS; x++) dof_kernel[x] /= sum;
}
void main() {
vec2 texOffset = 1.0 / textureSize(image, 0); // gets size of single texel
float p = -cinematicDOF.p;
float f = (p + cinematicDOF.i) / (p * cinematicDOF.i);
float d = -texture(positionMap, texCoord).z;
float sigma = abs((cinematicDOF.a * f * (p - d)) / (d * (p - f)));
makeDofKernel(sigma);
fragColor = texture(image, texCoord).rgb * dof_kernel[0];
#ifdef HORIZONTAL
for(int i = 1; i < KERNEL_RADIUS; i++) {
fragColor +=
dof_kernel[i] * (
texture(image, texCoord + vec2(texOffset.x * i, 0.0)).rgb +
texture(image, texCoord - vec2(texOffset.x * i, 0.0)).rgb
);
}
#else
for(int i = 1; i < KERNEL_RADIUS; i++) {
fragColor +=
dof_kernel[i] * (
texture(image, texCoord + vec2(0.0, texOffset.y * i)).rgb +
texture(image, texCoord - vec2(0.0, texOffset.y * i)).rgb
);
}
#endif
}
结果如下:
在这些图像中,焦点位于天空上,附近的对象具有非常清晰的边缘。随着深度差异的增加,这种伪影会更加明显。
我想彻底解决问题,而不是遮罩。但是,如果可以很好地掩盖它,那么该选项也将适合我。
感谢您的帮助。