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