[Bf-blender-cvs] [4a08cc5529b] cycles-x: Cycles X: Move pass pixel processors to kernel_film

Sergey Sharybin noreply at git.blender.org
Thu Jun 3 16:00:00 CEST 2021


Commit: 4a08cc5529b18c0b7725e76cffd5028e28935b73
Author: Sergey Sharybin
Date:   Wed Jun 2 14:12:04 2021 +0200
Branches: cycles-x
https://developer.blender.org/rB4a08cc5529b18c0b7725e76cffd5028e28935b73

Cycles X: Move pass pixel processors to kernel_film

Currently no functional changes, just keep moving towards unifying
calculation logic between CPU and GPU.

There combined pass is equal in timing within a noise level, the
shadow catcher matte pass with approximated shadow is about 7%
faster (probably, due to difference in inline policy).

Differential Revision: https://developer.blender.org/D11478

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

M	intern/cycles/integrator/pass_accessor_cpu.cpp
M	intern/cycles/integrator/pass_accessor_cpu.h
M	intern/cycles/kernel/kernel_film.h
M	intern/cycles/kernel/kernel_types.h

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

diff --git a/intern/cycles/integrator/pass_accessor_cpu.cpp b/intern/cycles/integrator/pass_accessor_cpu.cpp
index f61607c5a5d..32e16d859c4 100644
--- a/intern/cycles/integrator/pass_accessor_cpu.cpp
+++ b/intern/cycles/integrator/pass_accessor_cpu.cpp
@@ -18,444 +18,113 @@
 
 #include "util/util_logging.h"
 
-CCL_NAMESPACE_BEGIN
-
-namespace {
-
-/* Helper class which takes care of calculating sample scale and exposure scale for render passes,
- * taking adaptive sampling into account. */
-class Scaler {
- public:
-  Scaler(const RenderBuffers *render_buffers,
-         const PassType &pass_type,
-         const int num_samples,
-         const float exposure)
-      : pass_info_(Pass::get_info(pass_type)),
-        pass_stride_(render_buffers->params.pass_stride),
-        num_samples_inv_(1.0f / num_samples),
-        exposure_(exposure),
-        sample_count_pass_(get_sample_count_pass(render_buffers))
-  {
-    /* Pre-calculate values when adaptive sampling is not used. */
-    if (!sample_count_pass_) {
-      scale_ = pass_info_.use_filter ? num_samples_inv_ : 1.0f;
-      scale_exposure_ = pass_info_.use_exposure ? scale_ * exposure_ : scale_;
-    }
-  }
-
-  inline float scale(const int pixel_index) const
-  {
-    if (!sample_count_pass_) {
-      return scale_;
-    }
-
-    return (pass_info_.use_filter) ? 1.0f / (sample_count_pass_[pixel_index * pass_stride_]) :
-                                     1.0f;
-  }
-
-  inline float scale_exposure(const int pixel_index) const
-  {
-    if (!sample_count_pass_) {
-      return scale_exposure_;
-    }
-
-    float scale, scale_exposure;
-    scale_and_scale_exposure(pixel_index, scale, scale_exposure);
-
-    return scale_exposure;
-  }
-
-  inline void scale_and_scale_exposure(int pixel_index, float &scale, float &scale_exposure) const
-  {
-    if (!sample_count_pass_) {
-      scale = scale_;
-      scale_exposure = scale_exposure_;
-      return;
-    }
-
-    scale = this->scale(pixel_index);
-    scale_exposure = (pass_info_.use_exposure) ? scale * exposure_ : scale;
-  }
-
- protected:
-  const uint *get_sample_count_pass(const RenderBuffers *render_buffers)
-  {
-    const int pass_sample_count = render_buffers->params.get_pass_offset(PASS_SAMPLE_COUNT);
-    if (pass_sample_count == PASS_UNUSED) {
-      return nullptr;
-    }
-
-    return reinterpret_cast<const uint *>(render_buffers->buffer.data()) + pass_sample_count;
-  }
-
-  const PassInfo pass_info_;
-  const int pass_stride_;
-
-  const float num_samples_inv_ = 1.0f;
-  const float exposure_ = 1.0f;
-
-  const uint *sample_count_pass_ = nullptr;
-
-  float scale_ = 0.0f;
-  float scale_exposure_ = 0.0f;
-};
-
-} /* namespace */
-
-static float4 shadow_catcher_calc_pixel(const float scale,
-                                        const float scale_exposure,
-                                        const float *in_combined,
-                                        const float *in_catcher,
-                                        const float *in_matte)
-{
-  const float3 color_catcher = make_float3(in_catcher[0], in_catcher[1], in_catcher[2]) *
-                               scale_exposure;
-
-  const float3 color_combined = make_float3(in_combined[0], in_combined[1], in_combined[2]) *
-                                scale_exposure;
-
-  const float3 color_matte = make_float3(in_matte[0], in_matte[1], in_matte[2]) * scale_exposure;
-
-  const float transparency = in_combined[3] * scale;
-  const float alpha = saturate(1.0f - transparency);
+// clang-format off
+#include "kernel/device/cpu/compat.h"
+#include "kernel/device/cpu/globals.h"
+#include "kernel/kernel_types.h"
+#include "kernel/kernel_film.h"
+// clang-format on
 
-  const float3 shadow_catcher = safe_divide_even_color(color_combined,
-                                                       color_catcher + color_matte);
-
-  /* Restore pre-multipled nature of the color, avoiding artifacts on the edges.
-   * Makes sense since the division of premultiplied color's "removes" alpha from the
-   * result. */
-  const float3 pixel = (1.0f - alpha) * one_float3() + alpha * shadow_catcher;
-
-  return make_float4(pixel.x, pixel.y, pixel.z, 1.0f);
-}
-
-static float4 shadow_catcher_calc_matte_with_shadow(const float scale,
-                                                    const float scale_exposure,
-                                                    const float *in_combined,
-                                                    const float *in_catcher,
-                                                    const float *in_matte)
-{
-  /* The approximation of the shadow is 1 - average(shadow_catcher_pass). A better approximation
-   * is possible.
-   *
-   * The matte is alpha-overed onto the shadow (which is kind of alpha-overing shadow onto footage,
-   * and then alpha-overing synthetic objects on top). */
-
-  const float4 shadow_catcher = shadow_catcher_calc_pixel(
-      scale, scale_exposure, in_combined, in_catcher, in_matte);
-
-  const float3 color_matte = make_float3(in_matte[0], in_matte[1], in_matte[2]) * scale_exposure;
-
-  const float transparency = in_matte[3] * scale;
-  const float alpha = saturate(1.0f - transparency);
-
-  return make_float4(color_matte[0],
-                     color_matte[1],
-                     color_matte[2],
-                     (1.0f - alpha) * (1.0f - average(float4_to_float3(shadow_catcher))) + alpha);
-}
+CCL_NAMESPACE_BEGIN
 
 /* --------------------------------------------------------------------
- * Float (scalar) passes.
+ * Kernel processing.
  */
 
-void PassAccessorCPU::get_pass_depth(const RenderBuffers *render_buffers, float *pixels) const
-{
-  const Scaler scaler(render_buffers, pass_access_info_.type, num_samples_, exposure_);
-
-  run_get_pass_processor(
-      render_buffers, pixels, [scaler](const int pixel_index, const float *in, float *pixel) {
-        const float f = *in;
-        pixel[0] = (f == 0.0f) ? 1e10f : f * scaler.scale_exposure(pixel_index);
-      });
-}
-
-void PassAccessorCPU::get_pass_mist(const RenderBuffers *render_buffers, float *pixels) const
+void PassAccessorCPU::init_kernel_film_convert(KernelFilmConvert *kfilm_convert,
+                                               const RenderBuffers *render_buffers) const
 {
-  const Scaler scaler(render_buffers, pass_access_info_.type, num_samples_, exposure_);
+  const BufferParams &params = render_buffers->params;
+  const PassInfo &pass_info = Pass::get_info(pass_access_info_.type);
 
-  run_get_pass_processor(
-      render_buffers, pixels, [scaler](const int pixel_index, const float *in, float *pixel) {
-        const float f = *in;
-        /* Note that we accumulate 1 - mist in the kernel to avoid having to
-         * track the mist values in the integrator state. */
-        pixel[0] = saturate(1.0f - f * scaler.scale_exposure(pixel_index));
-      });
-}
+  kfilm_convert->pass_offset = pass_access_info_.offset;
 
-void PassAccessorCPU::get_pass_sample_count(const RenderBuffers *render_buffers,
-                                            float *pixels) const
-{
-  /* TODO(sergey): Consider normalizing into the [0..1] range, so that it is possible to see
-   * meaningful value when adaptive sampler stopped rendering image way before the maximum
-   * number of samples was reached (for examples when number of samples is set to 0 in
-   * viewport). */
+  kfilm_convert->pass_use_exposure = pass_info.use_exposure;
+  kfilm_convert->pass_use_filter = pass_info.use_filter;
 
-  const float scale = 1.0f / num_samples_;
+  kfilm_convert->pass_divide = params.get_pass_offset(pass_info.divide_type);
 
-  run_get_pass_processor(
-      render_buffers, pixels, [scale](const int /*pixel_index*/, const float *in, float *pixel) {
-        const float f = *in;
-        pixel[0] = __float_as_uint(f) * scale;
-      });
-}
-
-void PassAccessorCPU::get_pass_float(const RenderBuffers *render_buffers, float *pixels) const
-{
-  const Scaler scaler(render_buffers, pass_access_info_.type, num_samples_, exposure_);
+  kfilm_convert->pass_combined = params.get_pass_offset(PASS_COMBINED);
+  kfilm_convert->pass_sample_count = params.get_pass_offset(PASS_SAMPLE_COUNT);
+  kfilm_convert->pass_motion_weight = params.get_pass_offset(PASS_MOTION_WEIGHT);
+  kfilm_convert->pass_shadow_catcher = params.get_pass_offset(PASS_SHADOW_CATCHER);
+  kfilm_convert->pass_shadow_catcher_matte = params.get_pass_offset(PASS_SHADOW_CATCHER_MATTE);
 
-  run_get_pass_processor(
-      render_buffers, pixels, [scaler](const int pixel_index, const float *in, float *pixel) {
-        const float f = *in;
-        pixel[0] = f * scaler.scale_exposure(pixel_index);
-      });
-}
+  if (pass_info.use_filter) {
+    kfilm_convert->scale = 1.0f / num_samples_;
+  }
+  else {
+    kfilm_convert->scale = 1.0f;
+  }
 
-/* --------------------------------------------------------------------
- * Float3 passes.
- */
-void PassAccessorCPU::get_pass_shadow3(const RenderBuffers *render_buffers, float *pixels) const
-{
-  run_get_pass_processor(
-      render_buffers, pixels, [](const int /*pixel_index*/, const float *in, float *pixel) {
-        const float weight = in[3];
-        const float weight_inv = (weight > 0.0f) ? 1.0f / weight : 1.0f;
+  if (pass_info.use_exposure) {
+    kfilm_convert->exposure = exposure_;
+  }
+  else {
+    kfilm_convert->exposure = 1.0f;
+  }
 
-        const float3 shadow = make_float3(in[0], in[1], in[2]) * weight_inv;
+  kfilm_convert->scale_exposure = kfilm_convert->scale * kfilm_convert->exposure;
 
-        pixel[0] = shadow.x;
-        pixel[1] = shadow.y;
-        pixel[2] = shadow.z;
-      });
+  kfilm_convert->use_approximate_shadow_catcher = pass_access_info_.use_approximate_shadow_catcher;
 }
 
-void PassAccessorCPU::get_pass_divide_even_color(const RenderBuffers *render_buffers,
-                                                 float *pixels) const
+template<typename Processor>
+inline void PassAccessorCPU::run_get_pass_kernel_processor(const RenderBuffers *render_buffers,
+                                                           float *pixels,
+                                                           const Processor &processor) const
 {
-  c

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list