2021-01-02 21:42:02 +03:00
|
|
|
/*
|
|
|
|
* Copyright 2021 elven cache. All rights reserved.
|
2022-01-15 22:59:06 +03:00
|
|
|
* License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
|
2021-01-02 21:42:02 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef FS_DENOISE_SPATIAL_IMPLEMENTATION_SH
|
|
|
|
#define FS_DENOISE_SPATIAL_IMPLEMENTATION_SH
|
|
|
|
|
|
|
|
#include "../common/common.sh"
|
|
|
|
#include "parameters.sh"
|
|
|
|
#include "normal_encoding.sh"
|
|
|
|
|
|
|
|
SAMPLER2D(s_color, 0); // input color, signal to be denoised
|
|
|
|
SAMPLER2D(s_normal, 1); // scene's gbuffer normal, used for edge stopping function
|
|
|
|
SAMPLER2D(s_depth, 2); // scene's depth, used for edge stopping function
|
|
|
|
|
|
|
|
void main()
|
|
|
|
{
|
|
|
|
vec2 texCoord = v_texcoord0;
|
|
|
|
|
|
|
|
// read center pixel
|
|
|
|
vec4 color = texture2D(s_color, texCoord);
|
|
|
|
vec3 normal = NormalDecode(texture2D(s_normal, texCoord).xyz); // * 2.0 - 1.0;
|
|
|
|
float depth = texture2D(s_depth, texCoord).x;
|
|
|
|
// want depth gradient for edge stopping function
|
|
|
|
float depthGradient = abs(dFdx(depth)) + abs(dFdy(depth));
|
|
|
|
|
|
|
|
float du = u_texCoordStep * u_viewTexel.x;
|
|
|
|
float dv = u_texCoordStep * u_viewTexel.y;
|
|
|
|
|
|
|
|
#if USE_SPATIAL_5X5
|
|
|
|
float gaussianWeights[5];
|
|
|
|
gaussianWeights[0] = 1.0/16.0;
|
|
|
|
gaussianWeights[1] = 4.0/16.0;
|
|
|
|
gaussianWeights[2] = 6.0/16.0;
|
|
|
|
gaussianWeights[3] = 4.0/16.0;
|
|
|
|
gaussianWeights[4] = 1.0/16.0;
|
|
|
|
float initialWeight = (gaussianWeights[2]*gaussianWeights[2]);
|
|
|
|
int centerIdx = 2;
|
|
|
|
|
|
|
|
vec4 accumulateColor = color * initialWeight;
|
|
|
|
float accumulateWeight = initialWeight;
|
|
|
|
|
|
|
|
for (int yy = 0; yy < 5; ++yy)
|
|
|
|
{
|
|
|
|
for (int xx = 0; xx < 5; ++xx)
|
|
|
|
{
|
|
|
|
#else
|
|
|
|
float gaussianWeights[3];
|
|
|
|
gaussianWeights[0] = 1.0/4.0;
|
|
|
|
gaussianWeights[1] = 2.0/4.0;
|
|
|
|
gaussianWeights[2] = 1.0/4.0;
|
|
|
|
float initialWeight = (gaussianWeights[1]*gaussianWeights[1]);
|
|
|
|
int centerIdx = 1;
|
|
|
|
|
|
|
|
vec4 accumulateColor = color * initialWeight;
|
|
|
|
float accumulateWeight = initialWeight;
|
|
|
|
|
|
|
|
for (int yy = 0; yy < 3; ++yy)
|
|
|
|
{
|
|
|
|
for (int xx = 0; xx < 3; ++xx)
|
|
|
|
{
|
|
|
|
#endif // USE_SPATIAL_5X5
|
|
|
|
if ((centerIdx == xx) && (centerIdx == yy)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
float xOffset = float(xx) - float(centerIdx);
|
|
|
|
float yOffset = float(yy) - float(centerIdx);
|
|
|
|
vec2 sampleTexCoord = texCoord;
|
|
|
|
sampleTexCoord.x += xOffset * du;
|
|
|
|
sampleTexCoord.y += yOffset * dv;
|
|
|
|
|
|
|
|
vec4 sampleColor = texture2D(s_color, sampleTexCoord);
|
|
|
|
vec3 sampleNormal = NormalDecode(texture2D(s_normal, sampleTexCoord).xyz);
|
|
|
|
float normalWeight = pow(saturate(dot(normal, sampleNormal)), u_sigmaNormal);
|
|
|
|
|
|
|
|
float sampleDepth = texture2D(s_depth, sampleTexCoord).x;
|
|
|
|
float depthDelta = depth - sampleDepth;
|
|
|
|
float depthWeight = exp(-abs(depthDelta) / max(1e-5, u_sigmaDepth*u_sigmaDepth));
|
|
|
|
|
|
|
|
float weight = depthWeight * normalWeight;
|
|
|
|
|
|
|
|
// apply gaussian
|
|
|
|
weight *= (gaussianWeights[xx]*gaussianWeights[yy]);
|
|
|
|
|
|
|
|
accumulateColor += sampleColor * weight;
|
|
|
|
accumulateWeight += weight;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
accumulateColor /= max(accumulateWeight, 1e-5);
|
|
|
|
|
|
|
|
gl_FragColor = accumulateColor;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // FS_DENOISE_SPATIAL_IMPLEMENTATION_SH
|