39 const int size = width * height;
40 const int num_channels = 3;
53 for (
int y = 0;
y < height;
y++) {
54 for (
int x = 0;
x < width;
x++) {
55 float const u = (
x + 0.5f) / width;
56 float const v = (
y + 0.5f) / height;
63 d_input_data[
x +
y * width] =
in;
71 float *d_output_data = d_output.data();
73 for (
int y = 0;
y < height;
y++) {
74 for (
int x = 0;
x < width;
x++) {
75 pixels[
y * width +
x].x = d_output_data[(
y * width +
x) * num_channels + 0];
76 pixels[
y * width +
x].y = d_output_data[(
y * width +
x) * num_channels + 1];
77 pixels[
y * width +
x].z = d_output_data[(
y * width +
x) * num_channels + 2];
107 SOCKET_INT(map_resolution,
"Map Resolution", 0);
108 SOCKET_FLOAT(average_radiance,
"Average Radiance", 0.0f);
140 for (
const Node *node : get_used_shaders()) {
141 if (node->is_modified()) {
163 if ((get_sizeu() * get_sizev() * get_size() == 0.0f) ||
178 return (used_shaders.empty()) ?
nullptr :
static_cast<Shader *
>(used_shaders[0]);
206 return (
area == 0.0f) ? 4.0f :
area;
220 const float half_angle =
angle / 2.0f;
221 return (half_angle > 0.0f) ?
M_PI_F *
sqr(
sinf(half_angle)) : 1.0f;
240 if (!object->get_geometry()->is_light()) {
244 Light *light =
static_cast<Light *
>(
object->get_geometry());
259 size_t num_lights = 0;
260 bool has_portal =
false;
262 if (!object->get_geometry()->is_light()) {
266 Light *light =
static_cast<Light *
>(
object->get_geometry());
268 has_portal |= light->is_portal;
271 background_lights.push_back(light);
277 VLOG_INFO <<
"Total " << num_lights <<
" lights.";
279 bool background_enabled =
false;
280 int background_resolution = 0;
282 if (!background_lights.empty()) {
290 VLOG_INFO <<
"Background MIS has been disabled.\n";
292 for (
Light *light : background_lights) {
293 light->is_enabled = !disable_mis;
294 background_enabled = !disable_mis;
295 background_resolution = light->map_resolution;
310 const uint visibility =
object->get_visibility();
311 uint shader_flag = 0;
328 if (!(object->get_is_shadow_catcher())) {
340 KernelIntegrator *kintegrator = &dscene->
data.integrator;
341 if (kintegrator->use_light_tree) {
347 progress.set_status(
"Updating Lights",
"Computing distribution");
350 size_t num_triangles = 0;
352 const int num_lights = kintegrator->num_lights;
353 const size_t max_num_triangles = std::numeric_limits<int>::max() - 1 - kintegrator->num_lights;
364 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
365 const int mesh_num_triangles =
static_cast<int>(mesh->
num_triangles());
367 for (
int i = 0;
i < mesh_num_triangles;
i++) {
368 const int shader_index = mesh->get_shader()[
i];
369 Shader *shader = (shader_index < mesh->get_used_shaders().
size()) ?
370 static_cast<Shader *
>(mesh->get_used_shaders()[shader_index]) :
378 if (num_triangles > max_num_triangles) {
380 "Number of emissive triangles exceeds the limit, consider using Light Tree or disabling "
381 "Emission Sampling on some emissive materials");
385 const size_t num_distribution = num_triangles + num_lights;
388 kintegrator->num_distribution = num_distribution;
390 VLOG_INFO <<
"Use light distribution with " << num_distribution <<
" emitters.";
394 float totarea = 0.0f;
408 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
414 for (
size_t i = 0;
i < mesh_num_triangles;
i++) {
415 const int shader_index = mesh->get_shader()[
i];
416 Shader *shader = (shader_index < mesh->get_used_shaders().
size()) ?
417 static_cast<Shader *
>(mesh->get_used_shaders()[shader_index]) :
421 distribution[offset].
totarea = totarea;
424 distribution[offset].
object_id =
object->index;
428 if (!t.
valid(mesh->get_verts().data())) {
431 float3 p1 = mesh->get_verts()[t.
v[0]];
432 float3 p2 = mesh->get_verts()[t.
v[1]];
433 float3 p3 = mesh->get_verts()[t.
v[2]];
435 if (!transform_applied) {
446 const float trianglearea = totarea;
451 if (num_lights > 0) {
452 const float lightarea = (totarea > 0.0f) ? totarea / num_lights : 1.0f;
454 if (!object->get_geometry()->is_light()) {
458 Light *light =
static_cast<Light *
>(
object->get_geometry());
459 if (!light->is_enabled) {
463 distribution[offset].
totarea = totarea;
464 distribution[offset].
prim = ~light_index;
465 distribution[offset].
object_id =
object->index;
467 totarea += lightarea;
475 distribution[num_distribution].
totarea = totarea;
476 distribution[num_distribution].
prim = 0;
480 if (totarea > 0.0f) {
481 for (
size_t i = 0;
i < num_distribution;
i++) {
484 distribution[num_distribution].
totarea = 1.0f;
492 kintegrator->use_direct_light = (totarea > 0.0f);
496 kintegrator->distribution_pdf_triangles = 0.0f;
497 kintegrator->distribution_pdf_lights = 0.0f;
499 if (trianglearea > 0.0f) {
500 kintegrator->distribution_pdf_triangles = 1.0f / trianglearea;
502 kintegrator->distribution_pdf_triangles *= 0.5f;
507 kintegrator->distribution_pdf_lights = 1.0f / num_lights;
508 if (trianglearea > 0.0f) {
509 kintegrator->distribution_pdf_lights *= 0.5f;
532 const int left_child,
533 const int right_child)
564 int &next_node_index);
570 int &next_node_index)
573 for (
int i = 0;
i < node.
get_leaf().num_emitters;
i++) {
585 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
587 mesh->get_used_shaders()[mesh->get_shader()[emitter.
prim_id]]);
601 flatten.
light_array[~emitter.light_id] = emitter_index;
616 auto map_it = flatten.
instances.find(reference_node);
618 if (instance_node != reference_node) {
621 std::swap(instance_node->
type, reference_node->
type);
628 flatten, instance_node, knodes, kemitters, next_node_index);
648 int &next_node_index)
651 const int node_index = next_node_index++;
653 int right_child = -1;
684 int &next_node_index)
712 int &next_node_index,
713 bool can_share =
true)
720 int right_child = -1;
726 node_index = next_node_index++;
735 node_index = next_node_index++;
736 int first_emitter = -1;
737 int num_emitters = 0;
739 for (
int i = 0;
i < node->
get_leaf().num_emitters;
i++) {
743 if (first_emitter == -1) {
751 assert(first_emitter != -1);
756 new_node.
make_leaf(first_emitter, num_emitters);
775 only_node = right_node;
778 only_node = left_node;
785 flatten, only_node, light_link_mask, depth + 1, knodes, next_node_index,
false);
788 knodes[only_index].bit_skip++;
789 return std::make_pair(only_index, only_measure);
793 node_index = next_node_index++;
796 flatten, left_node, light_link_mask, depth + 1, knodes, next_node_index);
798 flatten, right_node, light_link_mask, depth + 1, knodes, next_node_index);
800 new_node.
measure = left_measure;
803 left_child = left_index;
804 right_child = right_index;
808 if (knodes.size() <= node_index) {
809 knodes.resize(node_index + 1);
817 return std::make_pair(node_index, new_node.
measure);
825 KernelIntegrator *kintegrator = &dscene->
data.integrator;
827 if (!kintegrator->use_light_tree) {
832 progress.set_status(
"Updating Lights",
"Computing tree");
844 flatten.
scene = scene;
858 kintegrator->use_direct_light = num_emitters > 0;
863 memset(klight_link_sets, 0,
sizeof(dscene->
data.light_link_sets));
865 VLOG_INFO <<
"Use light tree with " << num_emitters <<
" emitters and " << light_tree.
num_nodes
868 if (!use_light_linking) {
873 int next_node_index = 0;
878 int next_node_index = 0;
886 light_link_nodes.resize(light_tree.
num_nodes);
888 flatten, root, light_link_nodes.data(), kemitters, next_node_index);
889 light_link_nodes.resize(next_node_index);
900 klight_link_sets[tree_index].light_tree_root =
902 flatten, root, tree_mask, 0, light_link_nodes, next_node_index)
909 memcpy(knodes, light_link_nodes.data(), light_link_nodes.size() *
sizeof(*knodes));
911 VLOG_INFO <<
"Specialized light tree for light linking, with "
912 << light_link_nodes.size() - light_tree.
num_nodes <<
" additional nodes.";
931 const int cdf_width = res_x + 1;
933 for (
int i = start;
i < end;
i++) {
935 float3 env_color = (*pixels)[
i * res_x];
938 cond_cdf[
i * cdf_width].
x = ave_luminance *
sin_theta;
939 cond_cdf[
i * cdf_width].
y = 0.0f;
941 for (
int j = 1; j < res_x; j++) {
942 env_color = (*pixels)[
i * res_x + j];
945 cond_cdf[
i * cdf_width + j].
x = ave_luminance *
sin_theta;
946 cond_cdf[
i * cdf_width + j].
y = cond_cdf[
i * cdf_width + j - 1].
y +
947 cond_cdf[
i * cdf_width + j - 1].
x / res_x;
950 const float cdf_total = cond_cdf[
i * cdf_width + res_x - 1].
y +
951 cond_cdf[
i * cdf_width + res_x - 1].
x / res_x;
955 cond_cdf[
i * cdf_width + res_x].
x = cdf_total;
957 if (cdf_total > 0.0f) {
958 const float cdf_total_inv = 1.0f / cdf_total;
959 for (
int j = 1; j < res_x; j++) {
960 cond_cdf[
i * cdf_width + j].
y *= cdf_total_inv;
964 cond_cdf[
i * cdf_width + res_x].
y = 1.0f;
973 KernelIntegrator *kintegrator = &dscene->
data.integrator;
974 KernelBackground *kbackground = &dscene->
data.background;
975 Light *background_light =
nullptr;
977 bool background_mis =
false;
981 if (!object->get_geometry()->is_light()) {
985 Light *light =
static_cast<Light *
>(
object->get_geometry());
987 background_light = light;
988 background_mis |= light->use_mis;
992 kbackground->portal_weight = kintegrator->num_portals > 0 ? 1.0f : 0.0f;
993 kbackground->map_weight = background_mis ? 1.0f : 0.0f;
994 kbackground->sun_weight = 0.0f;
997 if (!background_light || !background_light->is_enabled) {
998 kbackground->map_res_x = 0;
999 kbackground->map_res_y = 0;
1000 kbackground->use_mis = (kbackground->portal_weight > 0.0f);
1004 progress.set_status(
"Updating Lights",
"Importance map");
1009 float sun_average_radiance = 0.0f;
1011 if (node->
type == EnvironmentTextureNode::get_node_type()) {
1015 environment_res.
x =
max(environment_res.
x, (
int)metadata.
width);
1016 environment_res.
y =
max(environment_res.
y, (
int)metadata.
height);
1019 if (node->
type == SkyTextureNode::get_node_type()) {
1028 if ((vec_src->
type != TextureCoordinateNode::get_node_type()) ||
1029 (vec_in->
link != vec_src->
output(
"Generated")))
1031 environment_res.
x =
max(environment_res.
x, 4096);
1032 environment_res.
y =
max(environment_res.
y, 2048);
1038 const float latitude = sky->get_sun_elevation();
1039 const float longitude = sky->get_sun_rotation() +
M_PI_2_F;
1047 kbackground->sun =
make_float4(sun_direction, half_angle);
1050 kbackground->sun_weight = 4.0f;
1052 environment_res.
x =
max(environment_res.
x, 512);
1053 environment_res.
y =
max(environment_res.
y, 256);
1060 kbackground->use_sun_guiding = (num_suns == 1);
1061 if (!kbackground->use_sun_guiding) {
1062 kbackground->sun_weight = 0.0f;
1063 environment_res.
x =
max(environment_res.
x, 4096);
1064 environment_res.
y =
max(environment_res.
y, 2048);
1068 kbackground->use_mis = (kbackground->portal_weight + kbackground->map_weight +
1069 kbackground->sun_weight) > 0.0f;
1072 int2 res =
make_int2(background_light->map_resolution, background_light->map_resolution / 2);
1075 res = environment_res;
1076 if (res.
x > 0 && res.
y > 0) {
1077 VLOG_INFO <<
"Automatically set World MIS resolution to " << res.
x <<
" by " << res.
y
1082 if (res.
x == 0 || res.
y == 0) {
1084 VLOG_INFO <<
"Setting World MIS resolution to default\n";
1086 kbackground->map_res_x = res.
x;
1087 kbackground->map_res_y = res.
y;
1097 const int cdf_width = res.
x + 1;
1101 const double time_start =
time_dt();
1104 const int rows_per_task =
divide_up(10240, res.
x);
1105 parallel_for(blocked_range<size_t>(0, res.
y, rows_per_task),
1106 [&](
const blocked_range<size_t> &r) {
1107 background_cdf(r.begin(), r.end(), res.x, res.y, &pixels, cond_cdf);
1111 marg_cdf[0].
x = cond_cdf[res.
x].
x;
1112 marg_cdf[0].
y = 0.0f;
1114 for (
int i = 1;
i < res.
y;
i++) {
1115 marg_cdf[
i].
x = cond_cdf[
i * cdf_width + res.
x].
x;
1116 marg_cdf[
i].
y = marg_cdf[
i - 1].
y + marg_cdf[
i - 1].
x / res.
y;
1119 const float cdf_total = marg_cdf[res.
y - 1].
y + marg_cdf[res.
y - 1].
x / res.
y;
1120 marg_cdf[res.
y].
x = cdf_total;
1122 const float map_average_radiance = cdf_total *
M_PI_2_F;
1123 if (sun_average_radiance > 0.0f) {
1128 background_light->set_average_radiance(0.8f * map_average_radiance +
1129 0.2f * sun_average_radiance);
1132 background_light->set_average_radiance(map_average_radiance);
1135 if (cdf_total > 0.0f) {
1136 for (
int i = 1;
i < res.
y;
i++) {
1137 marg_cdf[
i].
y /= cdf_total;
1141 marg_cdf[res.
y].
y = 1.0f;
1143 VLOG_WORK <<
"Background MIS build time " <<
time_dt() - time_start <<
"\n";
1153 size_t num_lights = 0;
1154 size_t num_portals = 0;
1155 size_t num_background_lights = 0;
1156 size_t num_distant_lights = 0;
1157 bool use_light_mis =
false;
1160 if (!object->get_geometry()->is_light()) {
1164 Light *light =
static_cast<Light *
>(
object->get_geometry());
1165 if (light->is_enabled) {
1169 num_distant_lights++;
1172 use_light_mis |= (light->size > 0.0f && light->use_mis);
1175 use_light_mis |= light->use_mis;
1178 num_distant_lights++;
1179 num_background_lights++;
1182 if (light->is_portal) {
1188 KernelIntegrator *kintegrator = &dscene->
data.integrator;
1189 kintegrator->use_light_tree = scene->
integrator->get_use_light_tree();
1190 kintegrator->num_lights = num_lights;
1191 kintegrator->num_distant_lights = num_distant_lights;
1192 kintegrator->num_background_lights = num_background_lights;
1193 kintegrator->use_light_mis = use_light_mis;
1195 kintegrator->num_portals = num_portals;
1196 kintegrator->portal_offset = num_lights;
1201 int light_index = 0;
1202 int portal_index = num_lights;
1205 if (!object->get_geometry()->is_light()) {
1209 Light *light =
static_cast<Light *
>(
object->get_geometry());
1217 if (light->is_portal) {
1220 const float3 extentu = axisu * (light->sizeu * light->size);
1221 const float3 extentv = axisv * (light->sizev * light->size);
1227 const float area = light->
area(object->get_tfm());
1228 float invarea = (area != 0.0f) ? 1.0f / area : 1.0f;
1229 if (light->ellipse) {
1234 klights[portal_index].
co = co;
1236 klights[portal_index].
area.
len_u = len_u;
1238 klights[portal_index].
area.
len_v = len_v;
1241 klights[portal_index].
object_id =
object->index;
1247 if (!light->is_enabled) {
1254 if (!light->cast_shadow) {
1260 klights[light_index].
type = light->light_type;
1261 klights[light_index].
strength[0] = light->strength.x;
1262 klights[light_index].
strength[1] = light->strength.y;
1263 klights[light_index].
strength[2] = light->strength.z;
1268 const float radius = light->size;
1269 const float invarea = (light->normalize) ? 1.0f / light->
area(object->get_tfm()) : 1.0f;
1272 const float eval_fac = invarea *
M_1_PI_F;
1274 if (light->use_mis && radius > 0.0f) {
1278 klights[light_index].
co = co;
1281 klights[light_index].
spot.
is_sphere = light->get_is_sphere() && radius != 0.0f;
1286 const float angle = light->angle / 2.0f;
1288 if (light->use_mis &&
angle > 0.0f) {
1292 const float one_minus_cosangle = 2.0f *
sqr(
sinf(0.5f *
angle));
1293 const float pdf = (
angle > 0.0f) ? (
M_1_2PI_F / one_minus_cosangle) : 1.0f;
1300 1.0f / light->
area(object->get_tfm()) :
1309 dscene->
data.background.light_index = light_index;
1328 const float light_size = light->size;
1329 const float3 extentu = axisu * (light->sizeu * light_size);
1330 const float3 extentv = axisv * (light->sizev * light_size);
1336 const float area = light->
area(object->get_tfm());
1337 float invarea = light->normalize ? 1.0f / area : 1.0f;
1338 if (light->ellipse) {
1343 const float half_spread = 0.5f *
fmaxf(light->spread, 0.0f);
1344 const float tan_half_spread = light->spread ==
M_PI_F ?
FLT_MAX :
tanf(half_spread);
1349 const float normalize_spread = (half_spread > 0.0f) ?
1350 (half_spread > 0.05f ?
1351 1.0f / (tan_half_spread - half_spread) :
1352 3.0f /
powf(half_spread, 3.0f)) :
1355 if (light->use_mis && area != 0.0f && light->spread > 0.0f) {
1359 klights[light_index].
co = co;
1361 klights[light_index].
area.
len_u = len_u;
1363 klights[light_index].
area.
len_v = len_v;
1370 const float cos_half_spot_angle =
cosf(light->spot_angle * 0.5f);
1371 const float spot_smooth = 1.0f / ((1.0f - cos_half_spot_angle) * light->spot_smooth);
1372 const float tan_half_spot_angle =
tanf(light->spot_angle * 0.5f);
1377 const float tan_sq =
sqr(tan_half_spot_angle);
1385 1.0f + tan_sq *
fmaxf(len_u_sq, len_v_sq) / len_w_sq);
1388 light->size *
sqrtf(1.0f + len_w_sq / (tan_sq *
fminf(len_u_sq, len_v_sq)));
1391 klights[light_index].
shader_id = shader_id;
1392 klights[light_index].
object_id =
object->index;
1394 klights[light_index].
max_bounces = light->max_bounces;
1395 klights[light_index].
use_caustics = light->use_caustics;
1400 VLOG_INFO <<
"Number of lights sent to the device: " << num_lights;
1416 scene->
update_stats->light.times.add_entry({
"device_update", time});
1458 const bool free_background)
1469 if (free_background) {
1506 for (slot = 0; slot <
ies_slots.size(); slot++) {
1514 for (slot = 0; slot <
ies_slots.size(); slot++) {
1522 ies_slots.push_back(make_unique<IESSlot>());
1539 if (slot < 0 || slot >=
ies_slots.size()) {
1558 if (slot->users == 0) {
1566 for (slot_end =
ies_slots.size(); slot_end; slot_end--) {
1575 int packed_size = 0;
1577 packed_size += slot->ies.packed_size();
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v
ccl_device_inline float sin_theta(const float3 w)
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Shader * get_shader(const Scene *scene)
device_vector< KernelLightTreeEmitter > light_tree_emitters
device_vector< KernelLightTreeNode > light_tree_nodes
device_vector< uint > object_to_tree
device_vector< float2 > light_background_marginal_cdf
device_vector< uint > object_lookup_offset
device_vector< float > ies_lights
device_vector< float2 > light_background_conditional_cdf
device_vector< KernelLightDistribution > light_distribution
device_vector< uint > triangle_to_tree
device_vector< uint > light_to_tree
device_vector< KernelLight > lights
virtual void const_copy_to(const char *name, void *host, const size_t size)=0
Geometry(const NodeType *node_type, const Type type)
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
void device_update_ies(DeviceScene *dscene)
void device_update_tree(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
vector< unique_ptr< IESSlot > > ies_slots
int add_ies_from_file(const string &filename)
void device_update_lights(DeviceScene *dscene, Scene *scene)
void test_enabled_lights(Scene *scene)
void device_free(Device *device, DeviceScene *dscene, const bool free_background=true)
void remove_ies(const int slot)
void device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
bool need_update_background
int add_ies(const string &content)
void tag_update(Scene *scene, const uint32_t flag)
void device_update_background(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
int last_background_resolution
bool has_background_light(Scene *scene)
bool last_background_enabled
std::atomic< int > num_nodes
const LightTreeEmitter * get_emitters() const
uint64_t light_link_receiver_used
LightTreeNode * build(Scene *scene, DeviceScene *dscene)
size_t num_emitters() const
bool eval(const ShaderEvalType type, const int max_num_inputs, const int num_channels, const std::function< int(device_vector< KernelShaderEvalInput > &)> &fill_input, const std::function< void(device_vector< float > &)> &read_output)
ShaderInput * input(const char *name)
ShaderOutput * output(const char *name)
bool has_surface_spatial_varying
EmissionSampling emission_sampling
NODE_DECLARE unique_ptr< ShaderGraph > graph
float get_sun_average_radiance()
Transform compute_transform()
TextureMapping tex_mapping
T * alloc(const size_t width, const size_t height=0, const size_t depth=0)
#define LIGHT_LINK_SET_MAX
#define CCL_NAMESPACE_END
VecBase< float, D > normalize(VecOp< float, D >) RET
#define assert(assertion)
static uint hash_string(const char *str)
@ PATH_RAY_VOLUME_SCATTER
@ SHADER_EXCLUDE_SHADOW_CATCHER
@ SHADER_EXCLUDE_TRANSMIT
ccl_device_inline float sqr(const float a)
ccl_device_inline float inversesqrtf(const float f)
ccl_device_inline float len_squared(const float2 a)
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 float2 normalize_len(const float2 a, ccl_private float *t)
ccl_device_inline float2 fabs(const float2 a)
ccl_device_inline float3 one_float3()
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
ccl_device_inline float triangle_area(const ccl_private float3 &v1, const ccl_private float3 &v2, const ccl_private float3 &v3)
#define SOCKET_FLOAT(name, ui_name, default_value,...)
#define SOCKET_INT(name, ui_name, default_value,...)
#define NODE_DEFINE(structname)
#define SOCKET_COLOR(name, ui_name, default_value,...)
#define SOCKET_BOOLEAN(name, ui_name, default_value,...)
#define SOCKET_ENUM(name, ui_name, values, default_value,...)
bool path_read_text(const string &path, string &text)
static void light_tree_emitters_copy_and_flatten(LightTreeFlatten &flatten, const LightTreeNode *node, KernelLightTreeNode *knodes, KernelLightTreeEmitter *kemitters, int &next_node_index)
static uint light_object_shader_flags(Object *object)
static CCL_NAMESPACE_BEGIN void shade_background_pixels(Device *device, DeviceScene *dscene, const int width, const int height, vector< float3 > &pixels, Progress &progress)
static int light_tree_flatten(LightTreeFlatten &flatten, const LightTreeNode *node, KernelLightTreeNode *knodes, KernelLightTreeEmitter *kemitters, int &next_node_index)
static void light_tree_leaf_emitters_copy_and_flatten(LightTreeFlatten &flatten, const LightTreeNode &node, KernelLightTreeNode *knodes, KernelLightTreeEmitter *kemitters, int &next_node_index)
static void light_tree_node_copy_to_device(KernelLightTreeNode &knode, const LightTreeNode &node, const int left_child, const int right_child)
static void background_cdf(int start, const int end, const int res_x, const int res_y, const vector< float3 > *pixels, float2 *cond_cdf)
static std::pair< int, LightTreeMeasure > light_tree_specialize_nodes_flatten(const LightTreeFlatten &flatten, LightTreeNode *node, const uint64_t light_link_mask, const int depth, vector< KernelLightTreeNode > &knodes, int &next_node_index, bool can_share=true)
float half_inv_sin_half_angle
struct KernelLightTreeEmitter::@356200223170132330320170070041130000221032010070::@172104031172370276031323017374032051315124063022 mesh
struct KernelLightTreeEmitter::@356200223170132330320170070041130000221032010070::@325141344336311151332364035310340071171367304366 light
EmissionSampling emission_sampling
struct KernelLightTreeEmitter::@356200223170132330320170070041130000221032010070::@236317302131176144314033160004221054174362324170 triangle
struct KernelLightTreeNode::@377247211160321275045111202060143352174123115352::@147137002365230272241313027070044041350111220032 leaf
struct KernelLightTreeNode::@377247211160321275045111202060143352174123115352::@164037376102142200071133114324262371123223123045 instance
struct KernelLightTreeNode::@377247211160321275045111202060143352174123115352::@344000132072154240246265111115054310255155233173 inner
KernelDistantLight distant
float half_cot_half_spot_angle
float cos_half_spot_angle
float cos_half_larger_spread
__forceinline bool is_mesh() const
__forceinline bool is_triangle() const
unique_ptr< LightTreeNode > root
uint64_t light_set_membership
__forceinline bool is_light() const
const uint * object_lookup_offset
const LightTreeEmitter * emitters
std::unordered_map< LightTreeNode *, int > instances
__forceinline void add(const LightTreeMeasure &measure)
unique_ptr< LightTreeNode > children[2]
__forceinline Inner & get_inner()
__forceinline bool is_leaf() const
void make_leaf(const int first_emitter_index, const int num_emitters)
LightTreeNode * get_reference()
std::variant< Leaf, Inner, Instance > variant_type
void make_distant(const int first_emitter_index, const int num_emitters)
__forceinline bool is_inner() const
LightTreeLightLink light_link
__forceinline bool is_instance() const
__forceinline Leaf & get_leaf()
__forceinline bool is_distant() const
bool has_contribution(const Scene *scene, const Object *object)
void tag_update(Scene *scene)
void get_uv_tiles(ustring map, unordered_set< int > &tiles) override
void compute_bounds() override
void apply_transform(const Transform &tfm, const bool apply_to_motion) override
PrimitiveType primitive_type() const override
Shader * get_shader() const
float area(const Transform &tfm) const
bool valid(const float3 *verts) const
size_t num_triangles() const
Triangle get_triangle(const size_t i) const
void insert(const char *x, const int y)
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=nullptr)
void dereference_all_used_nodes()
Node(const NodeType *type, ustring name=ustring())
bool usable_as_light() const
unique_ptr< LightManager > light_manager
unique_ptr< SceneUpdateStats > update_stats
unique_ptr< ShaderManager > shader_manager
unique_ptr_vector< Object > objects
std::unique_lock< std::mutex > thread_scoped_lock
CCL_NAMESPACE_BEGIN double time_dt()
ccl_device_inline size_t divide_up(const size_t x, const size_t y)