Skip to content
This repository has been archived by the owner on Nov 27, 2024. It is now read-only.

Commit

Permalink
New node: Smart Denoise.
Browse files Browse the repository at this point in the history
  • Loading branch information
ttddee committed Feb 9, 2022
1 parent c8f9db5 commit 8a36fc6
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 0 deletions.
1 change: 1 addition & 0 deletions resources.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,6 @@
<file>shaders/colormap_comp.spv</file>
<file>shaders/extractcolor_comp.spv</file>
<file>shaders/contours_comp.spv</file>
<file>shaders/smartdenoise_comp.spv</file>
</qresource>
</RCC>
74 changes: 74 additions & 0 deletions shaders/smartdenoise.comp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Copyright (c) 2018-2019 Michele Morrone
// All rights reserved.
//
// https://michelemorrone.eu - https://BrutPitt.com
//
// [email protected] - [email protected]
// twitter: @BrutPitt - github: BrutPitt
//
// https://github.com/BrutPitt/glslSmartDeNoise/
//
// This software is distributed under the terms of the BSD 2-Clause license
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// Adapted by Till Dechent for Cascade Image Editor

#version 430

layout (local_size_x = 16, local_size_y = 16) in;
layout (binding = 0, rgba32f) uniform readonly image2D inputBack;
layout (binding = 1, rgba32f) uniform readonly image2D inputFront;
layout (binding = 2, rgba32f) uniform image2D resultImage;

layout(set = 0, binding = 3) uniform InputBuffer
{
layout(offset = 0) float sigma;
layout(offset = 4) float threshold;
} sb;

#define INV_SQRT_OF_2PI 0.39894228040143267793994605993439 // 1.0/SQRT_OF_2PI
#define INV_PI 0.31830988618379067153776752674503

float kSigma = 3.0;

void main()
{
ivec2 imageSize = imageSize(inputBack);

ivec2 pixelCoords = ivec2(gl_GlobalInvocationID.xy);

vec4 pixel = imageLoad(inputBack, pixelCoords).rgba;

float radius = round(kSigma*sb.sigma);
float radQ = radius * radius;

float invSigmaQx2 = .5 / (sb.sigma * sb.sigma); // 1.0 / (sigma^2 * 2.0)
float invSigmaQx2PI = INV_PI * invSigmaQx2; // 1/(2 * PI * sigma^2)

float invThresholdSqx2 = .5 / (sb.threshold * sb.threshold); // 1.0 / (sigma^2 * 2.0)
float invThresholdSqrt2PI = INV_SQRT_OF_2PI / sb.threshold; // 1.0 / (sqrt(2*PI) * sigma^2)

vec4 centrPx = pixel;

float zBuff = 0.0;
vec4 aBuff = vec4(0.0);

vec2 d;
for (d.x=-radius; d.x <= radius; d.x++) {
float pt = sqrt(radQ-d.x*d.x); // pt = yRadius: have circular trend
for (d.y=-pt; d.y <= pt; d.y++) {
float blurFactor = exp( -dot(d , d) * invSigmaQx2 ) * invSigmaQx2PI;

vec4 walkPx = imageLoad(inputBack, ivec2(pixelCoords + d));
vec4 dC = walkPx-centrPx;
float deltaFactor = exp( -dot(dC, dC) * invThresholdSqx2) * invThresholdSqrt2PI * blurFactor;

zBuff += deltaFactor;
aBuff += deltaFactor*walkPx;
}
}
vec4 result = aBuff/zBuff;

imageStore(resultImage, pixelCoords, result);
}
Binary file added shaders/smartdenoise_comp.spv
Binary file not shown.
26 changes: 26 additions & 0 deletions src/nodedefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ namespace Cascade
NODE_TYPE_SHADER,
NODE_TYPE_SHARPEN,
NODE_TYPE_SHUFFLE,
NODE_TYPE_SMART_DENOISE,
NODE_TYPE_SOLARIZE,
NODE_TYPE_UNPREMULT,
NODE_TYPE_WRITE,
Expand Down Expand Up @@ -218,6 +219,7 @@ namespace Cascade
{ NODE_TYPE_SHADER, "GLSL Shader" },
{ NODE_TYPE_SHARPEN, "Sharpen" },
{ NODE_TYPE_SHUFFLE, "Shuffle" },
{ NODE_TYPE_SMART_DENOISE, "Smart Denoise" },
{ NODE_TYPE_SOLARIZE, "Solarize" },
{ NODE_TYPE_UNPREMULT, "Unpremult" },
{ NODE_TYPE_WRITE, "Write Image" }
Expand Down Expand Up @@ -960,6 +962,26 @@ namespace Cascade
1
};

const static NodeInitProperties smartDenoiseNodeInitProperties =
{
NODE_TYPE_SMART_DENOISE,
nodeStrings[NODE_TYPE_SMART_DENOISE],
NODE_CATEGORY_FILTER,
{ NODE_INPUT_TYPE_RGB_BACK },
{ NODE_OUTPUT_TYPE_RGB },
{
{ UI_ELEMENT_TYPE_PROPERTIES_HEADING, nodeStrings[NODE_TYPE_SMART_DENOISE] },
{ UI_ELEMENT_TYPE_SLIDER_BOX_DOUBLE, "Sigma,1.0,20.0,0.01,7.0" },
{ UI_ELEMENT_TYPE_SLIDER_BOX_DOUBLE, "Threshold,0.01,1.0,0.01,0.195" }
},
FRONT_INPUT_ALWAYS_CLEAR,
BACK_INPUT_RENDER_UPSTREAM_OR_CLEAR,
ALPHA_INPUT_ALWAYS_CLEAR,
OUTPUT_RENDER_UPSTREAM_OR_CLEAR,
":/shaders/smartdenoise_comp.spv",
1
};

// TODO: Use std::map instead of QMap, then we don't need the lookup function
[[maybe_unused]] static NodeInitProperties getPropertiesForType(const NodeType t)
{
Expand Down Expand Up @@ -1099,6 +1121,10 @@ namespace Cascade
{
return contoursNodeInitProperties;
}
else if(t == NODE_TYPE_SMART_DENOISE)
{
return smartDenoiseNodeInitProperties;
}
throw std::runtime_error("Node type not found.");
}
}
Expand Down

0 comments on commit 8a36fc6

Please sign in to comment.