Commit: 0eed757b5e39bfa45d5aa269ffba472054c2e04c Author: Sergey Sharybin Date: Mon May 31 16:46:25 2021 +0200 Branches: cycles-x https://developer.blender.org/rB0eed757b5e39bfa45d5aa269ffba472054c2e04c
Cycles X: Move top-level pass access log to a base class What this change allows to do is to share top-level logic of pixel access between various implementations (CPU, GPU), while keeping the actual pixel processing very small. Currently there are no functional changes, as well no measurable difference in timing spent in getting tile pixels. Differential Revision: https://developer.blender.org/D11477 =================================================================== M intern/cycles/integrator/CMakeLists.txt M intern/cycles/integrator/pass_accessor.cpp M intern/cycles/integrator/pass_accessor.h A intern/cycles/integrator/pass_accessor_cpu.cpp A intern/cycles/integrator/pass_accessor_cpu.h M intern/cycles/render/session.cpp =================================================================== diff --git a/intern/cycles/integrator/CMakeLists.txt b/intern/cycles/integrator/CMakeLists.txt index e2497e80352..9896ed9a2f3 100644 --- a/intern/cycles/integrator/CMakeLists.txt +++ b/intern/cycles/integrator/CMakeLists.txt @@ -25,6 +25,7 @@ set(SRC path_trace.cpp tile.cpp pass_accessor.cpp + pass_accessor_cpu.cpp path_trace_work.cpp path_trace_work_cpu.cpp path_trace_work_gpu.cpp @@ -42,6 +43,7 @@ set(SRC_HEADERS path_trace.h tile.h pass_accessor.h + pass_accessor_cpu.h path_trace_work.h path_trace_work_cpu.h path_trace_work_gpu.h diff --git a/intern/cycles/integrator/pass_accessor.cpp b/intern/cycles/integrator/pass_accessor.cpp index e5d91772109..0a9f3243cc8 100644 --- a/intern/cycles/integrator/pass_accessor.cpp +++ b/intern/cycles/integrator/pass_accessor.cpp @@ -30,142 +30,6 @@ PassAccessor::PassAccessInfo::PassAccessInfo(const Pass &pass, { } -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(RenderBuffers *render_buffers, - const PassInfo &pass_info, - const int num_samples, - const float exposure) - : pass_info_(pass_info), - 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); - - 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); -} - PassAccessor::PassAccessor(const PassAccessInfo &pass_access_info, int num_components, float exposure, @@ -177,67 +41,34 @@ PassAccessor::PassAccessor(const PassAccessInfo &pass_access_info, { } -bool PassAccessor::get_render_tile_pixels(RenderBuffers *render_buffers, float *pixels) +bool PassAccessor::get_render_tile_pixels(const RenderBuffers *render_buffers, float *pixels) const { if (render_buffers->buffer.data() == nullptr) { return false; } - const BufferParams ¶ms = render_buffers->params; - - const float *buffer_data = render_buffers->buffer.data(); - const float *in = buffer_data + pass_access_info_.offset; - const int pass_stride = params.pass_stride; - const int size = params.width * params.height; - const PassType type = pass_access_info_.type; const PassInfo pass_info = Pass::get_info(type); - const Scaler scaler(render_buffers, pass_info, num_samples_, exposure_); - if (num_components_ == 1 && type == PASS_RENDER_TIME) { -#if 0 - /* Render time is not stored by kernel, but measured per tile. */ - const float val = (float)(1000.0 * render_time / (params.width * params.height * sample)); - for (int i = 0; i < size; i++, pixels++) { - pixels[0] = val; - } -#endif - } - else if (num_components_ == 1) { - DCHECK_EQ(pass_info.num_components, 1) + if (num_components_ == 1) { + DCHECK_EQ(pass_info.num_components, num_components_) << "Number of components mismatch for pass type " << pass_info.type; /* Scalar */ - if (type == PASS_DEPTH) { - for (int i = 0; i < size; i++, in += pass_stride, pixels++) { - const float f = *in; - pixels[0] = (f == 0.0f) ? 1e10f : f * scaler.scale_exposure(i); - } + if (type == PASS_RENDER_TIME) { + /* TODO(sergey): Needs implementation. */ + } + else if (type == PASS_DEPTH) { + get_pass_depth(render_buffers, pixels); } else if (type == PASS_MIST) { - for (int i = 0; i < size; i++, in += pass_stride, pixels++) { - 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. */ - pixels[0] = saturate(1.0f - f * scaler.scale_exposure(i)); - } + get_pass_mist(render_buffers, pixels); } else if (type == PASS_SAMPLE_COUNT) { - /* 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). */ - const float scale = 1.0f / num_samples_; - for (int i = 0; i < size; i++, in += pass_stride, pixels++) { - const float f = *in; - pixels[0] = __float_as_uint(f) * scale; - } + get_pass_sample_count(render_buffers, pixels); } else { - for (int i = 0; i < size; i++, in += pass_stride, pixels++) { - const float f = *in; - pixels[0] = f * scaler.scale_exposure(i); - } + get_pass_float(render_buffers, pixels); } } else if (num_components_ == 3) { @@ -252,44 +83,15 @@ bool PassAccessor::get_render_tile_pixels(RenderBuffers *render_buffers, float * /* RGBA */ if (type == PASS_SHADOW) { - for (int i = 0; i < size; i++, in += pass_stride, pixels += 3) { - const float weight = in[3]; - const float weight_inv = (weight > 0.0f) ? 1.0f / weight : 1.0f; - - const float3 shadow = make_float3(in[0], in[1], in[2]) * weight_inv; - - pixels[0] = shadow.x; - pixels[1] = shadow.y; - pixels[2] = shadow.z; - } + get_pass_shadow3(render_buffers, pixels); } else if (pass_info.divide_type != PASS_NONE) { /* RGB lighting passes that need to divide out color */ - const int pass_divide = render_buffers->params.get_pass_offset(pass_info.divide_type); - DCHECK_NE(pass_divide, PASS_UNUSED); - - const float *in_divide = buffer_data + pass_divide; - - for (int i = 0; i < size; i++, in += pass_stride, in_divide += pass_stride, pixels += 3) { - const float3 f = make_float3(in[0], in[1], in[2]); - const float3 f_divide = make_float3(in_divide[0], in_divide[1], in_divide[2]); - const float3 f_divided = safe_divide_e @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs