coverage.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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. #include "render/coverage.h"
  17. #include "kernel/kernel_compat_cpu.h"
  18. #include "kernel/split/kernel_split_data.h"
  19. #include "kernel/kernel_globals.h"
  20. #include "kernel/kernel_id_passes.h"
  21. #include "kernel/kernel_types.h"
  22. #include "util/util_map.h"
  23. #include "util/util_vector.h"
  24. CCL_NAMESPACE_BEGIN
  25. static bool crypomatte_comp(const pair<float, float> &i, const pair<float, float> j)
  26. {
  27. return i.first > j.first;
  28. }
  29. void Coverage::finalize()
  30. {
  31. int pass_offset = 0;
  32. if (kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) {
  33. finalize_buffer(coverage_object, pass_offset);
  34. pass_offset += kernel_data.film.cryptomatte_depth * 4;
  35. }
  36. if (kernel_data.film.cryptomatte_passes & CRYPT_MATERIAL) {
  37. finalize_buffer(coverage_material, pass_offset);
  38. pass_offset += kernel_data.film.cryptomatte_depth * 4;
  39. }
  40. if (kernel_data.film.cryptomatte_passes & CRYPT_ASSET) {
  41. finalize_buffer(coverage_asset, pass_offset);
  42. }
  43. }
  44. void Coverage::init_path_trace()
  45. {
  46. kg->coverage_object = kg->coverage_material = kg->coverage_asset = NULL;
  47. if (kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE) {
  48. if (kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) {
  49. coverage_object.clear();
  50. coverage_object.resize(tile.w * tile.h);
  51. }
  52. if (kernel_data.film.cryptomatte_passes & CRYPT_MATERIAL) {
  53. coverage_material.clear();
  54. coverage_material.resize(tile.w * tile.h);
  55. }
  56. if (kernel_data.film.cryptomatte_passes & CRYPT_ASSET) {
  57. coverage_asset.clear();
  58. coverage_asset.resize(tile.w * tile.h);
  59. }
  60. }
  61. }
  62. void Coverage::init_pixel(int x, int y)
  63. {
  64. if (kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE) {
  65. const int pixel_index = tile.w * (y - tile.y) + x - tile.x;
  66. if (kernel_data.film.cryptomatte_passes & CRYPT_OBJECT) {
  67. kg->coverage_object = &coverage_object[pixel_index];
  68. }
  69. if (kernel_data.film.cryptomatte_passes & CRYPT_MATERIAL) {
  70. kg->coverage_material = &coverage_material[pixel_index];
  71. }
  72. if (kernel_data.film.cryptomatte_passes & CRYPT_ASSET) {
  73. kg->coverage_asset = &coverage_asset[pixel_index];
  74. }
  75. }
  76. }
  77. void Coverage::finalize_buffer(vector<CoverageMap> &coverage, const int pass_offset)
  78. {
  79. if (kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE) {
  80. flatten_buffer(coverage, pass_offset);
  81. }
  82. else {
  83. sort_buffer(pass_offset);
  84. }
  85. }
  86. void Coverage::flatten_buffer(vector<CoverageMap> &coverage, const int pass_offset)
  87. {
  88. /* Sort the coverage map and write it to the output */
  89. int pixel_index = 0;
  90. int pass_stride = tile.buffers->params.get_passes_size();
  91. for (int y = 0; y < tile.h; ++y) {
  92. for (int x = 0; x < tile.w; ++x) {
  93. const CoverageMap &pixel = coverage[pixel_index];
  94. if (!pixel.empty()) {
  95. /* buffer offset */
  96. int index = x + y * tile.stride;
  97. float *buffer = (float *)tile.buffer + index * pass_stride;
  98. /* sort the cryptomatte pixel */
  99. vector<pair<float, float>> sorted_pixel;
  100. for (CoverageMap::const_iterator it = pixel.begin(); it != pixel.end(); ++it) {
  101. sorted_pixel.push_back(std::make_pair(it->second, it->first));
  102. }
  103. sort(sorted_pixel.begin(), sorted_pixel.end(), crypomatte_comp);
  104. int num_slots = 2 * (kernel_data.film.cryptomatte_depth);
  105. if (sorted_pixel.size() > num_slots) {
  106. float leftover = 0.0f;
  107. for (vector<pair<float, float>>::iterator it = sorted_pixel.begin() + num_slots;
  108. it != sorted_pixel.end();
  109. ++it) {
  110. leftover += it->first;
  111. }
  112. sorted_pixel[num_slots - 1].first += leftover;
  113. }
  114. int limit = min(num_slots, sorted_pixel.size());
  115. for (int i = 0; i < limit; ++i) {
  116. kernel_write_id_slots(buffer + kernel_data.film.pass_cryptomatte + pass_offset,
  117. 2 * (kernel_data.film.cryptomatte_depth),
  118. sorted_pixel[i].second,
  119. sorted_pixel[i].first);
  120. }
  121. }
  122. ++pixel_index;
  123. }
  124. }
  125. }
  126. void Coverage::sort_buffer(const int pass_offset)
  127. {
  128. /* Sort the coverage map and write it to the output */
  129. int pass_stride = tile.buffers->params.get_passes_size();
  130. for (int y = 0; y < tile.h; ++y) {
  131. for (int x = 0; x < tile.w; ++x) {
  132. /* buffer offset */
  133. int index = x + y * tile.stride;
  134. float *buffer = (float *)tile.buffer + index * pass_stride;
  135. kernel_sort_id_slots(buffer + kernel_data.film.pass_cryptomatte + pass_offset,
  136. 2 * (kernel_data.film.cryptomatte_depth));
  137. }
  138. }
  139. }
  140. CCL_NAMESPACE_END