23 return M_2PI_F * (1 - cos_theta_o) +
25 2 *
theta_o * sin_theta_o + cos_theta_o);
45 float cos_a_b =
dot(a->axis,
b->axis);
47 float theta_e =
fmaxf(a->theta_e,
b->theta_e);
51 if (a->theta_o + 5e-4f >=
fminf(
M_PI_F, theta_d +
b->theta_o)) {
56 float theta_o = (theta_d + a->theta_o +
b->theta_o) * 0.5f;
64 if (cos_a_b < -0.9995f) {
70 float theta_r = theta_o - a->theta_o;
72 new_axis = a->axis *
cosf(theta_r) + ortho *
sinf(theta_r);
87 bool need_transformation)
88 : prim_id(prim_id), object_id(object_id)
93 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
95 Shader *shader =
static_cast<Shader *
>(mesh->get_used_shaders()[mesh->get_shader()[
prim_id]]);
97 for (
int i = 0; i < 3; i++) {
98 vertices[i] = mesh->get_verts()[triangle.
v[i]];
101 if (need_transformation) {
102 assert(!mesh->transform_applied);
103 const Transform &tfm =
object->get_tfm();
104 for (
int i = 0; i < 3; i++) {
110 float area =
triangle_area(vertices[0], vertices[1], vertices[2]);
117 centroid = (vertices[0] + vertices[1] + vertices[2]) / 3.0f;
121 if (is_front_only || is_back_only) {
124 cross(vertices[1] - vertices[0], vertices[2] - vertices[0]));
128 if ((need_transformation || mesh->transform_applied) &&
142 for (
int i = 0; i < 3; i++) {
152 const float size =
lamp->get_size();
173 strength *= M_1_PI_F;
184 strength *= 0.25f * M_1_PI_F;
213 strength *= 0.25f * M_1_PI_F;
223 strength *=
lamp->get_average_radiance() *
M_PI_F;
230 if (
lamp->get_shader()) {
231 strength *=
lamp->get_shader()->emission_estimate;
246 std::sort(emitters + start,
254bool LightTree::triangle_usable_as_light(
Mesh *mesh,
int prim_id)
256 int shader_index = mesh->get_shader()[prim_id];
257 if (shader_index < mesh->get_used_shaders().
size()) {
258 Shader *shader =
static_cast<Shader *
>(mesh->get_used_shaders()[shader_index]);
266void LightTree::add_mesh(
Scene *scene,
Mesh *mesh,
int object_id)
268 size_t mesh_num_triangles = mesh->num_triangles();
269 for (
size_t i = 0; i < mesh_num_triangles; i++) {
270 if (triangle_usable_as_light(mesh, i)) {
271 emitters_.emplace_back(scene, i, object_id);
279 uint max_lights_in_leaf)
280 : progress_(progress), max_lights_in_leaf_(max_lights_in_leaf)
282 KernelIntegrator *kintegrator = &dscene->
data.integrator;
284 local_lights_.reserve(kintegrator->num_lights - kintegrator->num_distant_lights);
285 distant_lights_.reserve(kintegrator->num_distant_lights);
290 int device_light_index = 0;
291 int scene_light_index = 0;
292 for (
Light *light : scene->lights) {
293 if (light->is_enabled) {
295 distant_lights_.emplace_back(scene, ~device_light_index, scene_light_index);
298 local_lights_.emplace_back(scene, ~device_light_index, scene_light_index);
301 device_light_index++;
309 for (
Object *
object : scene->objects) {
316 if (!object->usable_as_light()) {
321 mesh_lights_.emplace_back(
object, object_id);
325 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
326 auto map_it = offset_map_.find(mesh);
327 if (map_it == offset_map_.end()) {
336 if (local_lights_.empty() && distant_lights_.empty() && mesh_lights_.empty()) {
340 const int num_mesh_lights = mesh_lights_.size();
341 int num_local_lights = local_lights_.size() + num_mesh_lights;
342 const int num_distant_lights = distant_lights_.size();
345 std::unordered_map<Mesh *, std::tuple<LightTreeNode *, int, int>> unique_mesh;
347 emitters_.reserve(
num_triangles + num_local_lights + num_distant_lights);
349 Object *
object = scene->objects[emitter.object_id];
350 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
353 auto map_it = unique_mesh.find(mesh);
354 if (map_it == unique_mesh.end()) {
355 const int start = emitters_.size();
356 add_mesh(scene, mesh, emitter.object_id);
357 const int end = emitters_.size();
359 unique_mesh[
mesh] = std::make_tuple(emitter.root.get(), start, end);
360 emitter.root->object_id = emitter.object_id;
363 emitter.root->make_instance(std::get<0>(map_it->second), emitter.object_id);
365 object_offsets[emitter.object_id] = offset_map_[
mesh];
369 parallel_for_each(unique_mesh, [
this](
auto &map_it) {
371 int start = std::get<1>(map_it.second);
372 int end = std::get<2>(map_it.second);
373 recursive_build(
self, node, start, end, emitters_.data(), 0, 0);
381 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
383 LightTreeNode *reference = std::get<0>(unique_mesh.find(mesh)->second);
384 emitter.
measure = emitter.
root->measure = reference->measure;
393 if (!mesh->transform_applied && !emitter.
measure.
transform(object->get_tfm())) {
395 size_t mesh_num_triangles = mesh->num_triangles();
396 for (
size_t i = 0; i < mesh_num_triangles; i++) {
397 if (triangle_usable_as_light(mesh, i)) {
409 const int num_emissive_triangles = emitters_.size();
410 num_local_lights += num_emissive_triangles;
416 std::move(local_lights_.begin(), local_lights_.end(), std::back_inserter(emitters_));
417 std::move(mesh_lights_.begin(), mesh_lights_.end(), std::back_inserter(emitters_));
419 left, root_.get(), num_emissive_triangles, num_local_lights, emitters_.data(), 0, 1);
429 for (
int i = 0; i < num_distant_lights; i++) {
430 root_->get_inner().children[
right]->add(distant_lights_[i]);
433 sort_leaf(0, num_distant_lights, distant_lights_.data());
434 root_->get_inner().children[
right]->make_distant(num_local_lights, num_distant_lights);
436 root_->measure = root_->get_inner().children[
left]->measure +
437 root_->get_inner().children[
right]->measure;
438 root_->light_link = root_->get_inner().children[
left]->light_link +
439 root_->get_inner().children[
right]->light_link;
444 root_->light_link.shareable =
false;
446 std::move(distant_lights_.begin(), distant_lights_.end(), std::back_inserter(emitters_));
451void LightTree::recursive_build(
const Child child,
456 const uint bit_trail,
475 int split_dim = -1, middle;
476 if (should_split(emitters, start, middle, end, node->measure, node->light_link, split_dim)) {
478 if (split_dim != -1) {
480 std::nth_element(emitters + start,
484 return l.centroid[split_dim] < r.
centroid[split_dim];
489 if (middle - start > MIN_EMITTERS_PER_THREAD) {
491 [=] { recursive_build(left, node, start, middle, emitters, bit_trail, depth + 1); });
494 recursive_build(left, node, start, middle, emitters, bit_trail, depth + 1);
498 if (end - middle > MIN_EMITTERS_PER_THREAD) {
500 recursive_build(right, node, middle, end, emitters, bit_trail | (1u << depth), depth + 1);
504 recursive_build(right, node, middle, end, emitters, bit_trail | (1u << depth), depth + 1);
509 node->make_leaf(start, end - start);
525 measure = emitters[start].
measure;
531 middle = (start + end) / 2;
534 for (
int i = start; i < end; i++) {
535 centroid_bbox.
grow((emitters + i)->centroid);
539 const float max_extent =
max4(extent.
x, extent.
y, extent.
z, 0.0f);
542 float total_cost = 0.0f;
544 for (
int dim = 0; dim < 3; dim++) {
547 if (centroid_bbox.
size()[dim] == 0.0f && dim != 0) {
551 const float inv_extent = 1 / (centroid_bbox.
size()[dim]);
554 std::array<LightTreeBucket, LightTreeBucket::num_buckets> buckets;
555 for (
int i = start; i < end; i++) {
561 (emitter->
centroid[dim] - centroid_bbox.
min[dim]) * inv_extent;
564 buckets[bucket_idx].add(*emitter);
569 left_buckets.front() = buckets.front();
571 left_buckets[i] = left_buckets[i - 1] + buckets[i];
576 measure = left_buckets.back().measure + buckets.back().measure;
577 light_link = left_buckets.back().light_link + buckets.back().light_link;
585 if (centroid_bbox.
size()[dim] == 0.0f) {
590 if (total_cost == 0.0f) {
597 right_buckets.back() = buckets.back();
599 right_buckets[i] = right_buckets[i + 1] + buckets[i + 1];
603 const float regularization = max_extent * inv_extent;
606 const float right_cost = right_buckets[
split].measure.calculate();
607 const float cost = regularization * (left_cost + right_cost);
609 if (cost < total_cost && cost < min_cost) {
612 middle = start + left_buckets[
split].count;
616 return min_cost < total_cost || num_emitters > max_lights_in_leaf_;
628 return LightTreeBucket(a.measure +
b.measure, a.light_link +
b.light_link, a.count +
b.count);
MINLINE float safe_acosf(float a)
static void split(const char *text, const char *seps, char ***str, int *count)
ATTR_WARN_UNUSED_RESULT const BMLoop * l
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
device_vector< uint > object_lookup_offset
LightTree(Scene *scene, DeviceScene *dscene, Progress &progress, uint max_lights_in_leaf)
unique_ptr< LightTreeNode > create_node(const LightTreeMeasure &measure, const uint &bit_trial)
uint64_t light_link_receiver_used
LightTreeNode * build(Scene *scene, DeviceScene *dscene)
T * alloc(size_t width, size_t height=0, size_t depth=0)
local_group_size(16, 16) .push_constant(Type b
additional_info("compositor_sum_squared_difference_float_shared") .push_constant(Type output_img float dot(value.rgb, luminance_coefficients)") .define("LOAD(value)"
#define CCL_NAMESPACE_END
@ EMISSION_SAMPLING_FRONT
static void sort_leaf(const int start, const int end, LightTreeEmitter *emitters)
__forceinline LightTreeMeasure operator+(const LightTreeMeasure &a, const LightTreeMeasure &b)
OrientationBounds merge(const OrientationBounds &cone_a, const OrientationBounds &cone_b)
ccl_device float fast_tanf(float x)
ccl_device float fast_atanf(float x)
ccl_device_inline bool is_zero(const float2 a)
ccl_device_inline float average(const float2 a)
ccl_device_inline float2 safe_normalize(const float2 a)
ccl_device_inline float cross(const float2 a, const float2 b)
ccl_device_inline float2 fabs(const float2 a)
unsigned __int64 uint64_t
__forceinline float3 size() const
__forceinline void grow(const float3 &pt)
static const int num_buckets
LightTreeEmitter(Object *object, int object_id)
__forceinline bool is_triangle() const
unique_ptr< LightTreeNode > root
uint64_t light_set_membership
__forceinline bool is_light() const
void add(const uint64_t prim_set_membership)
bool transform(const Transform &tfm)
__forceinline void reset()
__forceinline float calculate()
__forceinline void add(const LightTreeMeasure &measure)
unique_ptr< LightTreeNode > children[2]
__forceinline Inner & get_inner()
__forceinline bool is_empty() const
float calculate_measure() const
void push(TaskRunFunction &&task)
void wait_work(Summary *stats=NULL)
CCL_NAMESPACE_END CCL_NAMESPACE_BEGIN ccl_device_inline float triangle_area(ccl_private const float3 &v1, ccl_private const float3 &v2, ccl_private const float3 &v3)
ccl_device_inline T max4(const T &a, const T &b, const T &c, const T &d)
ccl_device_inline void make_orthonormals(const float3 N, ccl_private float3 *a, ccl_private float3 *b)
ccl_device_inline int clamp(int a, int mn, int mx)