Артефакты глубины резкости - PullRequest
0 голосов
/ 23 июня 2019

Во время тестирования DOF были обнаружены артефакты, как показано на рисунке:

enter image description here

код шейдера фрагмента:

#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
}

А вот и результат:

1st 2nd

На этих изображениях фокус находится на небе, а близкие объекты имеют очень острые края. И с увеличением разницы в глубине этот артефакт становится более выраженным.

Я бы хотел полностью решить проблему, а не маскировать. Но если это можно хорошо замаскировать, то этот вариант мне тоже подойдет.

Буду признателен за любую помощь.

...