Commit: ab1c7a717d0afa75e5c218641a8f068c6baf4465
Author: Lukas Stockner
Date:   Tue Jul 26 03:36:31 2016 +0200
Branches: soc-2016-cycles_denoising
https://developer.blender.org/rBab1c7a717d0afa75e5c218641a8f068c6baf4465

Render API/Cycles: Add separate "keep highlights" parameter to the end_result 
function to fix Save Buffers with Denoising

===================================================================

M       intern/cycles/blender/blender_session.cpp
A       intern/cycles/kernel/kernel_filter_old.h
M       source/blender/makesrna/intern/rna_render.c
M       source/blender/render/extern/include/RE_engine.h
M       source/blender/render/intern/source/external_engine.c

===================================================================

diff --git a/intern/cycles/blender/blender_session.cpp 
b/intern/cycles/blender/blender_session.cpp
index b520fb6..84bcd26 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -318,9 +318,10 @@ static BL::RenderResult 
begin_render_result(BL::RenderEngine& b_engine,
 static void end_render_result(BL::RenderEngine& b_engine,
                               BL::RenderResult& b_rr,
                               bool cancel,
+                              bool highlight,
                               bool do_merge_results)
 {
-       b_engine.end_result(b_rr, (int)cancel, (int)do_merge_results);
+       b_engine.end_result(b_rr, (int)cancel, (int) highlight, 
(int)do_merge_results);
 }
 
 static void add_pass(BL::RenderEngine& b_engine,
@@ -368,12 +369,12 @@ void 
BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_upda
                        update_render_result(b_rr, b_rlay, rtile);
                }
 
-               end_render_result(b_engine, b_rr, highlight, true);
+               end_render_result(b_engine, b_rr, true, highlight, true);
        }
        else {
                /* write result */
                write_render_result(b_rr, b_rlay, rtile);
-               end_render_result(b_engine, b_rr, false, true);
+               end_render_result(b_engine, b_rr, false, false, true);
        }
 }
 
@@ -420,7 +421,7 @@ void BlenderSession::render()
 
                /* layer will be missing if it was disabled in the UI */
                if(b_single_rlay == b_rr.layers.end()) {
-                       end_render_result(b_engine, b_rr, true, false);
+                       end_render_result(b_engine, b_rr, true, true, false);
                        continue;
                }
 
@@ -526,7 +527,7 @@ void BlenderSession::render()
                }
 
                /* free result without merging */
-               end_render_result(b_engine, b_rr, true, false);
+               end_render_result(b_engine, b_rr, true, true, false);
 
                if(session->progress.get_cancel())
                        break;
diff --git a/intern/cycles/kernel/kernel_filter_old.h 
b/intern/cycles/kernel/kernel_filter_old.h
new file mode 100644
index 0000000..fac52ec
--- /dev/null
+++ b/intern/cycles/kernel/kernel_filter_old.h
@@ -0,0 +1,748 @@
+/*
+ * Copyright 2011-2013 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+CCL_NAMESPACE_BEGIN
+
+/* Performs Singular Value Decomposition on A, fills V and S2 (containing the 
squares of the singular values) and returns the estimated rank */
+ccl_device int orig_svd(float *A, float *V, float *S2, int n)
+{
+       int  i, j, k, EstColRank = n, RotCount = n, SweepCount = 0;
+       int slimit = 8;
+       float eps = 1e-8f;
+       float e2 = 10.f * n * eps * eps;
+       float tol = 0.1f * eps;
+       float vt, p, x0, y0, q, r, c0, s0, d1, d2;
+
+       for(int r = 0; r < n; r++)
+               for(int c = 0; c < n; c++)
+                       V[r*n+c] = (c == r)? 1.0f: 0.0f;
+
+       while (RotCount != 0 && SweepCount++ <= slimit) {
+               RotCount = EstColRank * (EstColRank - 1) / 2;
+
+               for (j = 0; j < EstColRank-1; ++j) {
+                       for (k = j+1; k < EstColRank; ++k) {
+                               p = q = r = 0.0;
+
+                               for (i = 0; i < n; ++i) {
+                                       x0 = A[i * n + j];
+                                       y0 = A[i * n + k];
+                                       p += x0 * y0;
+                                       q += x0 * x0;
+                                       r += y0 * y0;
+                               }
+
+                               S2[j] = q;
+                               S2[k] = r;
+
+                               if (q >= r) {
+                                       if (q <= e2 * S2[0] || fabsf(p) <= tol 
* q)
+                                               RotCount--;
+                                       else {
+                                               p /= q;
+                                               r = 1.f - r/q;
+                                               vt = sqrtf(4.0f * p * p + r * 
r);
+                                               c0 = sqrtf(0.5f * (1.f + r / 
vt));
+                                               s0 = p / (vt*c0);
+
+                                               // Rotation
+                                               for (i = 0; i < n; ++i) {
+                                                       d1 = A[i * n + j];
+                                                       d2 = A[i * n + k];
+                                                       A[i * n + j] = 
d1*c0+d2*s0;
+                                                       A[i * n + k] = 
-d1*s0+d2*c0;
+                                               }
+                                               for (i = 0; i < n; ++i) {
+                                                       d1 = V[i * n + j];
+                                                       d2 = V[i * n + k];
+                                                       V[i * n + j] = d1 * c0 
+ d2 * s0;
+                                                       V[i * n + k] = -d1 * s0 
+ d2 * c0;
+                                               }
+                                       }
+                               } else {
+                                       p /= r;
+                                       q = q / r - 1.f;
+                                       vt = sqrtf(4.f * p * p + q * q);
+                                       s0 = sqrtf(0.5f * (1.f - q / vt));
+                                       if (p < 0.f)
+                                               s0 = -s0;
+                                       c0 = p / (vt * s0);
+
+                                       // Rotation
+                                       for (i = 0; i < n; ++i) {
+                                               d1 = A[i * n + j];
+                                               d2 = A[i * n + k];
+                                               A[i * n + j] = d1 * c0 + d2 * 
s0;
+                                               A[i * n + k] = -d1 * s0 + d2 * 
c0;
+                                       }
+                                       for (i = 0; i < n; ++i) {
+                                               d1 = V[i * n + j];
+                                               d2 = V[i * n + k];
+                                               V[i * n + j] = d1 * c0 + d2 * 
s0;
+                                               V[i * n + k] = -d1 * s0 + d2 * 
c0;
+                                       }
+                               }
+                       }
+               }
+               while (EstColRank >= 3 && S2[EstColRank-1] <= S2[0] * tol + tol 
* tol)
+                       EstColRank--;
+       }
+       return EstColRank;
+}
+
+ccl_device void orig_cholesky(float *A, int n, float *L)
+{
+       for (int i = 0; i < n; ++i) {
+               for (int j = 0; j <= i; ++j) {
+                       float s = 0.0f;
+                       for (int k = 0; k < j; ++k)
+                               s += L[i * n + k] * L[j * n + k];
+                       L[i * n + j] = (i == j) ? sqrtf(A[i * n + i] - s) : 
(1.0f / L[j * n + j] * (A[j * n + i] - s));
+               }
+       }
+}
+
+#define Buf_F(x, y, o) (buffers[((y) * w + (x)) * kernel_data.film.pass_stride 
+ (o)])
+#define Buf_F3(x, y, o) *((float3*) (buffers + ((y) * w + (x)) * 
kernel_data.film.pass_stride + (o)))
+#define Buf_F4(x, y, o) *((float4*) (buffers + ((y) * w + (x)) * 
kernel_data.film.pass_stride + (o)))
+
+ccl_device_inline void filter_get_color_passes(KernelGlobals *kg, int &m_C, 
int &v_C)
+{
+       m_C = kernel_data.film.pass_denoising + 20;
+       v_C = kernel_data.film.pass_denoising + 23;
+}
+
+ccl_device void kernel_filter1_pixel(KernelGlobals *kg, float *buffers, int x, 
int y, int w, int h, int samples, int halfWindow, float bandwidthFactor, 
FilterStorage* storage)
+{
+       float invS = 1.0f / samples;
+       float invSv = 1.0f / (samples - 1);
+
+       int2 lo = make_int2(max(x - halfWindow, 0), max(y - halfWindow, 0));
+       int2 hi = make_int2(min(x + halfWindow, w-1), min(y + halfWindow, h-1));
+       int num = (hi.x - lo.x + 1) * (hi.y - lo.y + 1);
+
+       int m_D = kernel_data.film.pass_denoising + 12, v_D = 
kernel_data.film.pass_denoising + 13,
+           m_N = kernel_data.film.pass_denoising, m_T = 
kernel_data.film.pass_denoising + 6,
+           v_N = kernel_data.film.pass_denoising + 3, v_T = 
kernel_data.film.pass_denoising + 9,
+           m_C, v_C;
+       filter_get_color_passes(kg, m_C, v_C);
+
+       float3 meanT = make_float3(0.0f, 0.0f, 0.0f);
+       float3 meanN = make_float3(0.0f, 0.0f, 0.0f);
+       float meanD = 0.0f;
+
+       for(int py = lo.y; py <= hi.y; py++) {
+               for(int px = lo.x; px <= hi.x; px++) {
+                       meanT += Buf_F3(px, py, m_T) * invS;
+                       meanN += Buf_F3(px, py, m_N) * invS;
+                       meanD += Buf_F (px, py, m_D) * invS;
+               }
+       }
+       meanT /= num;
+       meanN /= num;
+       meanD /= num;
+
+#ifdef WITH_CYCLES_DEBUG_FILTER
+       storage->means[0] = meanN.x;
+       storage->means[1] = meanN.y;
+       storage->means[2] = meanN.z;
+       storage->means[3] = meanT.x;
+       storage->means[4] = meanT.y;
+       storage->means[5] = meanT.z;
+       storage->means[6] = meanD;
+#endif
+
+       float delta[9], transform[81], norm;
+       int rank;
+       /* Generate transform */
+       {
+               float top_nD = 0.0f;
+               float3 top_nN = make_float3(0.0f, 0.0f, 0.0f);
+               float3 top_nT = make_float3(0.0f, 0.0f, 0.0f);
+               for(int py = lo.y; py <= hi.y; py++) {
+                       for(int px = lo.x; px <= hi.x; px++) {
+/* Instead of going for the highest value, which might be a firefly, the code 
uses the 5th highest value
+ * (kind of like a median filter, but we want to keep near the maximum for 
non-firefly pixels).
+ * To do that, the 5 highest values are kept around and every value is 
insertion-sorted into it if it belongs there.
+ * In the end, we can then just pick the smallest of the 5 values and have our 
percentile filter in linear time. */
+/*#define UPDATE_TOP(top, v, len) \
+       if(top[0] < v) { \
+               top[0] = v; \
+               for(int i = 0; i < (len)-1; i++) { \
+                       if(top[i+1] >= top[i]) break; \
+                       float t = top[i+1]; \
+                       top[i+1] = top[i]; \
+                       top[i] = t; \
+               } \
+       }*/
+#define UPDATE_TOP(top, v, len) if(top < v) top = v;
+#define UPDATE_TOP3(top, v, len) if(top.x < fabsf(v.x)) top.x = fabsf(v.x); 
if(top.y < fabsf(v.y)) top.y = fabsf(v.y); if(top.z < fabsf(v.z)) top.z = 
fabsf(v.z);
+                               float nD = fabsf(Buf_F(px, py, m_D) * invS - 
meanD);
+                               UPDATE_TOP(top_nD, nD, 5)
+                               float3 nN = (Buf_F3(px, py, m_N) * invS - 
meanN);
+                               UPDATE_TOP3(top_nN, nN, 5)
+                               float3 nT = (Buf_F3(px, py, m_T) * invS - 
meanT);
+                               UPDATE_TOP3(top_nT, nT, 5)
+#undef UPDATE_TOP
+                       }
+               }
+
+               float nD = 1.0f / max(top_nD, 0.01f);
+               float3 nN = 1.0f / max(top_nN, make_float3(0.01f, 0.01f, 
0.01f));
+               float3 nT = 1.0f / max(top_nT, make_float3(0.01f, 0.01f, 
0.01f));
+
+               norm = 0.0f;
+               for(int i = 0; i < 81; i++)
+                       transform[i] = 0.0f;
+               for(int py = lo.y; py <= hi.y; py++) {
+                       for(int px = lo.x; px <= hi.x; px++) {
+                               delta[0] = ((float) px - x) / halfWindow;
+                               delta[1] = ((float) py - y) / halfWindow;
+                               delta[2] = (Buf_F(px, py, m_D) * invS - meanD) 
* nD;
+                               float3 dN = (Buf_F3(px, py, m_N) * invS - 
meanN) * nN;
+                               delta[3] = dN.x;
+                               delta[4] = dN.y;
+                               delta[5] = dN.z;
+                               float3 dT = (Buf_F3(px, py, m_T) * invS - 
meanT) * nT;
+                               delta[6] = dT.x;
+                               delta[7] = dT.y;
+                               delta[8] = dT.z;
+
+                               for(int r = 0; r < 9; r++)
+                                       for(int c = r; c < 9; c++)
+                                               transform[9*r+c] += 
delta[r]*delta[c];
+
+                               //norm += 10.0f * nD * nD * Buf_F(px, py, v_D) 
* invSv * invS;
+                               norm += nD*nD*Buf_F(px, py, v_D) * invSv * invS 
+ 3.0f * average(nN * nN * Buf_F3(px, py, v_N) * invSv * invS) + 3.0f * 
average(nT * nT * Buf_F3(px, py, v_T) * invSv * invS);
+                       }
+               }
+
+               /* Here, transform is self-adjoint (TODO term symmetric?) by 
construction, so one half can be copied from the other one */
+               for(int r = 1; r < 9; r++)
+                       for(int c = 0; c < r; c++)
+                               transform[9*r+c] = transform[9*c+r];
+
+               float V[81], S[9];
+               rank = orig_svd(transform, V, S, 9);
+
+               for(int i = 0; i < 9; i++) {
+                       S[i] = sqrtf(fabsf(S[i]));
+#ifdef WITH_CYCLES_DEBUG_FILTER
+                       storage->singular[i] = S[i];
+#endif
+               }
+
+#ifdef WITH_CYCLES_DEBUG_FILTER
+               storage->scales[0] = nN.x;
+               storage-

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to