Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/render/buffers.cpp')
-rw-r--r--intern/cycles/render/buffers.cpp123
1 files changed, 60 insertions, 63 deletions
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index f901885e679..66b8ef73acc 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -42,6 +42,7 @@ BufferParams::BufferParams()
denoising_data_pass = false;
denoising_clean_pass = false;
+ denoising_prefiltered_pass = false;
Pass::add(PASS_COMBINED, passes);
}
@@ -73,6 +74,7 @@ int BufferParams::get_passes_size()
if(denoising_data_pass) {
size += DENOISING_PASS_SIZE_BASE;
if(denoising_clean_pass) size += DENOISING_PASS_SIZE_CLEAN;
+ if(denoising_prefiltered_pass) size += DENOISING_PASS_SIZE_PREFILTERED;
}
return align_up(size, 4);
@@ -88,6 +90,20 @@ int BufferParams::get_denoising_offset()
return offset;
}
+int BufferParams::get_denoising_prefiltered_offset()
+{
+ assert(denoising_prefiltered_pass);
+
+ int offset = get_denoising_offset();
+
+ offset += DENOISING_PASS_SIZE_BASE;
+ if(denoising_clean_pass) {
+ offset += DENOISING_PASS_SIZE_CLEAN;
+ }
+
+ return offset;
+}
+
/* Render Buffer Task */
RenderTile::RenderTile()
@@ -153,81 +169,62 @@ bool RenderBuffers::get_denoising_pass_rect(int type, float exposure, int sample
return false;
}
- float invsample = 1.0f/sample;
- float scale = invsample;
- bool variance = (type == DENOISING_PASS_NORMAL_VAR) ||
- (type == DENOISING_PASS_ALBEDO_VAR) ||
- (type == DENOISING_PASS_DEPTH_VAR) ||
- (type == DENOISING_PASS_COLOR_VAR);
+ float scale = 1.0f;
+ float alpha_scale = 1.0f/sample;
+ if(type == DENOISING_PASS_PREFILTERED_COLOR ||
+ type == DENOISING_PASS_CLEAN ||
+ type == DENOISING_PASS_PREFILTERED_INTENSITY) {
+ scale *= exposure;
+ }
+ else if(type == DENOISING_PASS_PREFILTERED_VARIANCE) {
+ scale *= exposure*exposure * (sample - 1);
+ }
- float scale_exposure = scale;
- if(type == DENOISING_PASS_COLOR || type == DENOISING_PASS_CLEAN) {
- scale_exposure *= exposure;
+ int offset;
+ if(type == DENOISING_PASS_CLEAN) {
+ /* The clean pass isn't changed by prefiltering, so we use the original one there. */
+ offset = type + params.get_denoising_offset();
}
- else if(type == DENOISING_PASS_COLOR_VAR) {
- scale_exposure *= exposure*exposure;
+ else if (type == DENOISING_PASS_PREFILTERED_COLOR && !params.denoising_prefiltered_pass) {
+ /* If we're not saving the prefiltering result, return the original noisy pass. */
+ offset = params.get_denoising_offset() + DENOISING_PASS_COLOR;
+ scale /= sample;
+ }
+ else {
+ offset = type + params.get_denoising_prefiltered_offset();
}
- int offset = type + params.get_denoising_offset();
int pass_stride = params.get_passes_size();
int size = params.width*params.height;
- if(variance) {
- /* Approximate variance as E[x^2] - 1/N * (E[x])^2, since online variance
- * update does not work efficiently with atomics in the kernel. */
- int mean_offset = offset - components;
- float *mean = buffer.data() + mean_offset;
- float *var = buffer.data() + offset;
- assert(mean_offset >= 0);
-
- if(components == 1) {
- for(int i = 0; i < size; i++, mean += pass_stride, var += pass_stride, pixels++) {
- pixels[0] = max(0.0f, var[0] - mean[0]*mean[0]*invsample)*scale_exposure;
- }
+ float *in = buffer.data() + offset;
+
+ if(components == 1) {
+ for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
+ pixels[0] = in[0]*scale;
}
- else if(components == 3) {
- for(int i = 0; i < size; i++, mean += pass_stride, var += pass_stride, pixels += 3) {
- pixels[0] = max(0.0f, var[0] - mean[0]*mean[0]*invsample)*scale_exposure;
- pixels[1] = max(0.0f, var[1] - mean[1]*mean[1]*invsample)*scale_exposure;
- pixels[2] = max(0.0f, var[2] - mean[2]*mean[2]*invsample)*scale_exposure;
- }
+ }
+ else if(components == 3) {
+ for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
+ pixels[0] = in[0]*scale;
+ pixels[1] = in[1]*scale;
+ pixels[2] = in[2]*scale;
}
- else {
- return false;
+ }
+ else if(components == 4) {
+ /* Since the alpha channel is not involved in denoising, output the Combined alpha channel. */
+ assert(params.passes[0].type == PASS_COMBINED);
+ float *in_combined = buffer.data();
+
+ for(int i = 0; i < size; i++, in += pass_stride, in_combined += pass_stride, pixels += 4) {
+ pixels[0] = in[0]*scale;
+ pixels[1] = in[1]*scale;
+ pixels[2] = in[2]*scale;
+ pixels[3] = saturate(in_combined[3]*alpha_scale);
}
}
else {
- float *in = buffer.data() + offset;
-
- if(components == 1) {
- for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
- pixels[0] = in[0]*scale_exposure;
- }
- }
- else if(components == 3) {
- for(int i = 0; i < size; i++, in += pass_stride, pixels += 3) {
- pixels[0] = in[0]*scale_exposure;
- pixels[1] = in[1]*scale_exposure;
- pixels[2] = in[2]*scale_exposure;
- }
- }
- else if(components == 4) {
- assert(type == DENOISING_PASS_COLOR);
-
- /* Since the alpha channel is not involved in denoising, output the Combined alpha channel. */
- assert(params.passes[0].type == PASS_COMBINED);
- float *in_combined = buffer.data();
-
- for(int i = 0; i < size; i++, in += pass_stride, in_combined += pass_stride, pixels += 4) {
- pixels[0] = in[0]*scale_exposure;
- pixels[1] = in[1]*scale_exposure;
- pixels[2] = in[2]*scale_exposure;
- pixels[3] = saturate(in_combined[3]*scale);
- }
- }
- else {
- return false;
- }
+ return false;
}
return true;