Blender  V2.93
coverage.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "render/coverage.h"
18 #include "render/buffers.h"
19 
21 #include "kernel/kernel_types.h"
23 
24 #include "kernel/kernel_globals.h"
26 
27 #include "util/util_map.h"
28 
30 
31 static bool crypomatte_comp(const pair<float, float> &i, const pair<float, float> j)
32 {
33  return i.first > j.first;
34 }
35 
37 {
38  int pass_offset = 0;
39  if (kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) {
40  finalize_buffer(coverage_object, pass_offset);
41  pass_offset += kernel_data.film.cryptomatte_depth * 4;
42  }
43  if (kernel_data.film.cryptomatte_passes & CRYPT_MATERIAL) {
44  finalize_buffer(coverage_material, pass_offset);
45  pass_offset += kernel_data.film.cryptomatte_depth * 4;
46  }
47  if (kernel_data.film.cryptomatte_passes & CRYPT_ASSET) {
48  finalize_buffer(coverage_asset, pass_offset);
49  }
50 }
51 
53 {
54  kg->coverage_object = kg->coverage_material = kg->coverage_asset = NULL;
55 
56  if (kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE) {
57  if (kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) {
58  coverage_object.clear();
59  coverage_object.resize(tile.w * tile.h);
60  }
61  if (kernel_data.film.cryptomatte_passes & CRYPT_MATERIAL) {
62  coverage_material.clear();
63  coverage_material.resize(tile.w * tile.h);
64  }
65  if (kernel_data.film.cryptomatte_passes & CRYPT_ASSET) {
66  coverage_asset.clear();
67  coverage_asset.resize(tile.w * tile.h);
68  }
69  }
70 }
71 
72 void Coverage::init_pixel(int x, int y)
73 {
74  if (kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE) {
75  const int pixel_index = tile.w * (y - tile.y) + x - tile.x;
76  if (kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) {
77  kg->coverage_object = &coverage_object[pixel_index];
78  }
79  if (kernel_data.film.cryptomatte_passes & CRYPT_MATERIAL) {
80  kg->coverage_material = &coverage_material[pixel_index];
81  }
82  if (kernel_data.film.cryptomatte_passes & CRYPT_ASSET) {
83  kg->coverage_asset = &coverage_asset[pixel_index];
84  }
85  }
86 }
87 
88 void Coverage::finalize_buffer(vector<CoverageMap> &coverage, const int pass_offset)
89 {
90  if (kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE) {
91  flatten_buffer(coverage, pass_offset);
92  }
93  else {
94  sort_buffer(pass_offset);
95  }
96 }
97 
98 void Coverage::flatten_buffer(vector<CoverageMap> &coverage, const int pass_offset)
99 {
100  /* Sort the coverage map and write it to the output */
101  int pixel_index = 0;
102  int pass_stride = tile.buffers->params.get_passes_size();
103  for (int y = 0; y < tile.h; ++y) {
104  for (int x = 0; x < tile.w; ++x) {
105  const CoverageMap &pixel = coverage[pixel_index];
106  if (!pixel.empty()) {
107  /* buffer offset */
108  int index = x + y * tile.stride;
109  float *buffer = (float *)tile.buffer + index * pass_stride;
110 
111  /* sort the cryptomatte pixel */
112  vector<pair<float, float>> sorted_pixel;
113  for (CoverageMap::const_iterator it = pixel.begin(); it != pixel.end(); ++it) {
114  sorted_pixel.push_back(std::make_pair(it->second, it->first));
115  }
116  sort(sorted_pixel.begin(), sorted_pixel.end(), crypomatte_comp);
117  int num_slots = 2 * (kernel_data.film.cryptomatte_depth);
118  if (sorted_pixel.size() > num_slots) {
119  float leftover = 0.0f;
120  for (vector<pair<float, float>>::iterator it = sorted_pixel.begin() + num_slots;
121  it != sorted_pixel.end();
122  ++it) {
123  leftover += it->first;
124  }
125  sorted_pixel[num_slots - 1].first += leftover;
126  }
127  int limit = min(num_slots, sorted_pixel.size());
128  for (int i = 0; i < limit; ++i) {
129  kernel_write_id_slots(buffer + kernel_data.film.pass_cryptomatte + pass_offset,
130  2 * (kernel_data.film.cryptomatte_depth),
131  sorted_pixel[i].second,
132  sorted_pixel[i].first);
133  }
134  }
135  ++pixel_index;
136  }
137  }
138 }
139 
140 void Coverage::sort_buffer(const int pass_offset)
141 {
142  /* Sort the coverage map and write it to the output */
143  int pass_stride = tile.buffers->params.get_passes_size();
144  for (int y = 0; y < tile.h; ++y) {
145  for (int x = 0; x < tile.w; ++x) {
146  /* buffer offset */
147  int index = x + y * tile.stride;
148  float *buffer = (float *)tile.buffer + index * pass_stride;
149  kernel_sort_id_slots(buffer + kernel_data.film.pass_cryptomatte + pass_offset,
150  2 * (kernel_data.film.cryptomatte_depth));
151  }
152  }
153 }
154 
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
void sort(btMatrix3x3 &U, btVector3 &sigma, btMatrix3x3 &V, int t)
Helper function of 3X3 SVD for sorting singular values.
int get_passes_size()
Definition: buffers.cpp:66
void init_pixel(int x, int y)
Definition: coverage.cpp:72
void finalize()
Definition: coverage.cpp:36
void init_path_trace()
Definition: coverage.cpp:52
BufferParams params
Definition: buffers.h:77
int stride
Definition: buffers.h:143
RenderBuffers * buffers
Definition: buffers.h:152
device_ptr buffer
Definition: buffers.h:146
static CCL_NAMESPACE_BEGIN bool crypomatte_comp(const pair< float, float > &i, const pair< float, float > j)
Definition: coverage.cpp:31
unordered_map< float, float > CoverageMap
Definition: coverage.h:26
#define kernel_data
#define CCL_NAMESPACE_END
ccl_device_inline void kernel_sort_id_slots(ccl_global float *buffer, int num_slots)
CCL_NAMESPACE_BEGIN ccl_device_inline void kernel_write_id_slots(ccl_global float *buffer, int num_slots, float id, float weight)
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
@ CRYPT_ASSET
Definition: kernel_types.h:404
@ CRYPT_ACCURATE
Definition: kernel_types.h:405
@ CRYPT_OBJECT
Definition: kernel_types.h:402
@ CRYPT_MATERIAL
Definition: kernel_types.h:403
#define min(a, b)
Definition: sort.c:51