42 const int size = width * height;
43 const int num_channels = 3;
56 for (
int y = 0; y < height; y++) {
57 for (
int x = 0; x < width; x++) {
58 float u = (x + 0.5f) / width;
59 float v = (y + 0.5f) / height;
66 d_input_data[x + y * width] = in;
74 float *d_output_data = d_output.data();
76 for (
int y = 0; y < height; y++) {
77 for (
int x = 0; x < width; x++) {
78 pixels[y * width +
x].x = d_output_data[(y * width +
x) * num_channels + 0];
79 pixels[y * width +
x].y = d_output_data[(y * width +
x) * num_channels + 1];
80 pixels[y * width +
x].z = d_output_data[(y * width +
x) * num_channels + 2];
110 SOCKET_INT(map_resolution,
"Map Resolution", 0);
111 SOCKET_FLOAT(average_radiance,
"Average Radiance", 0.0f);
136 SOCKET_NODE(shader,
"Shader", Shader::get_node_type());
171 const Shader *effective_shader = (shader) ? shader : scene->default_light;
232 foreach (
Light *light, scene->lights) {
246 bool has_portal =
false, has_background =
false;
247 foreach (
Light *light, scene->lights) {
248 light->is_enabled = light->has_contribution(scene);
249 has_portal |= light->is_portal;
253 bool background_enabled =
false;
254 int background_resolution = 0;
256 if (has_background) {
261 Shader *shader = scene->background->get_shader(scene);
262 const bool disable_mis = !(has_portal || shader->has_surface_spatial_varying);
264 VLOG_INFO <<
"Background MIS has been disabled.\n";
266 foreach (
Light *light, scene->lights) {
268 light->is_enabled = !disable_mis;
269 background_enabled = !disable_mis;
270 background_resolution = light->map_resolution;
289 KernelIntegrator *kintegrator = &dscene->
data.integrator;
290 if (kintegrator->use_light_tree) {
296 progress.
set_status(
"Updating Lights",
"Computing distribution");
299 size_t num_triangles = 0;
301 const int num_lights = kintegrator->num_lights;
302 const size_t max_num_triangles = std::numeric_limits<int>::max() - 1 - kintegrator->num_lights;
303 foreach (
Object *
object, scene->objects) {
308 if (!object->usable_as_light()) {
313 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
314 int mesh_num_triangles =
static_cast<int>(mesh->num_triangles());
316 for (
int i = 0; i < mesh_num_triangles; i++) {
317 int shader_index = mesh->get_shader()[i];
318 Shader *shader = (shader_index < mesh->get_used_shaders().size()) ?
319 static_cast<Shader *
>(mesh->get_used_shaders()[shader_index]) :
320 scene->default_surface;
327 if (num_triangles > max_num_triangles) {
329 "Number of emissive triangles exceeds the limit, consider using Light Tree or disabling "
330 "Emission Sampling on some emissive materials");
334 const size_t num_distribution = num_triangles + num_lights;
337 kintegrator->num_distribution = num_distribution;
339 VLOG_INFO <<
"Use light distribution with " << num_distribution <<
" emitters.";
343 float totarea = 0.0f;
349 foreach (
Object *
object, scene->objects) {
354 if (!object->usable_as_light()) {
359 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
380 if (!(object->get_is_shadow_catcher())) {
384 size_t mesh_num_triangles = mesh->num_triangles();
385 for (
size_t i = 0; i < mesh_num_triangles; i++) {
386 int shader_index = mesh->get_shader()[i];
387 Shader *shader = (shader_index < mesh->get_used_shaders().size()) ?
388 static_cast<Shader *
>(mesh->get_used_shaders()[shader_index]) :
389 scene->default_surface;
392 distribution[offset].totarea = totarea;
393 distribution[offset].prim = i + mesh->prim_offset;
394 distribution[offset].mesh_light.shader_flag = shader_flag;
395 distribution[offset].mesh_light.object_id = object_id;
399 if (!t.
valid(&mesh->get_verts()[0])) {
402 float3 p1 = mesh->get_verts()[t.
v[0]];
403 float3 p2 = mesh->get_verts()[t.
v[1]];
404 float3 p3 = mesh->get_verts()[t.
v[2]];
406 if (!transform_applied) {
419 const float trianglearea = totarea;
424 if (num_lights > 0) {
425 float lightarea = (totarea > 0.0f) ? totarea / num_lights : 1.0f;
426 foreach (
Light *light, scene->lights) {
427 if (!light->is_enabled) {
431 distribution[offset].totarea = totarea;
432 distribution[offset].prim = ~light_index;
433 distribution[offset].mesh_light.object_id =
OBJECT_NONE;
434 distribution[offset].mesh_light.shader_flag = 0;
435 totarea += lightarea;
443 distribution[num_distribution].totarea = totarea;
444 distribution[num_distribution].prim = 0;
445 distribution[num_distribution].mesh_light.object_id =
OBJECT_NONE;
446 distribution[num_distribution].mesh_light.shader_flag = 0;
448 if (totarea > 0.0f) {
449 for (
size_t i = 0; i < num_distribution; i++) {
450 distribution[i].totarea /= totarea;
452 distribution[num_distribution].totarea = 1.0f;
460 kintegrator->use_direct_light = (totarea > 0.0f);
464 kintegrator->distribution_pdf_triangles = 0.0f;
465 kintegrator->distribution_pdf_lights = 0.0f;
467 if (trianglearea > 0.0f) {
468 kintegrator->distribution_pdf_triangles = 1.0f / trianglearea;
470 kintegrator->distribution_pdf_triangles *= 0.5f;
475 kintegrator->distribution_pdf_lights = 1.0f / num_lights;
476 if (trianglearea > 0.0f) {
477 kintegrator->distribution_pdf_lights *= 0.5f;
500 const int left_child,
501 const int right_child)
504 knode.
energy = node.measure.energy;
506 knode.
bbox.min = node.measure.bbox.min;
507 knode.
bbox.max = node.measure.bbox.max;
509 knode.
bcone.axis = node.measure.bcone.axis;
510 knode.
bcone.theta_o = node.measure.bcone.theta_o;
511 knode.
bcone.theta_e = node.measure.bcone.theta_e;
517 if (node.is_leaf() || node.is_distant()) {
521 else if (node.is_inner()) {
532 int &next_node_index);
538 int &next_node_index)
541 for (
int i = 0; i < node.get_leaf().num_emitters; i++) {
542 int emitter_index = i + node.get_leaf().first_emitter_index;
554 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
556 mesh->get_used_shaders()[mesh->get_shader()[emitter.
prim_id]]);
573 if (!(object->get_is_shadow_catcher())) {
578 kemitter.
mesh_light.shader_flag = shader_flag;
589 flatten.
light_array[~emitter.light_id] = emitter_index;
604 auto map_it = flatten.
instances.find(reference_node);
606 if (instance_node != reference_node) {
608 std::swap(instance_node->
type, reference_node->
type);
611 instance_node->
type &= ~LIGHT_TREE_INSTANCE;
615 flatten, instance_node, knodes, kemitters, next_node_index);
618 kinstance_node.
bit_trail = node.bit_trail;
635 int &next_node_index)
638 const int node_index = next_node_index++;
639 int left_child = -1, right_child = -1;
641 if (node->is_leaf() || node->is_distant()) {
644 else if (node->is_inner()) {
658 assert(node->is_instance());
670 int &next_node_index)
673 if (node->is_leaf() || node->is_distant()) {
677 assert(node->is_inner());
698 int &next_node_index)
700 assert(!node->is_instance());
703 int node_index, left_child = -1, right_child = -1;
707 if (depth == 0 && !(node->light_link.set_membership & light_link_mask)) {
709 node_index = next_node_index++;
712 else if (node->light_link.shareable && node->light_link.shared_node_index != -1) {
714 return std::make_pair(node->light_link.shared_node_index, node->measure);
716 else if (node->is_leaf() || node->is_distant()) {
718 node_index = next_node_index++;
719 int first_emitter = -1;
720 int num_emitters = 0;
722 for (
int i = 0; i < node->get_leaf().num_emitters; i++) {
726 if (first_emitter == -1) {
727 first_emitter = node->get_leaf().first_emitter_index + i;
734 assert(first_emitter != -1);
738 if (node->is_leaf()) {
739 new_node.
make_leaf(first_emitter, num_emitters);
746 assert(node->is_inner());
758 only_node = right_node;
761 only_node = left_node;
765 flatten, only_node, light_link_mask, depth + 1, knodes, next_node_index);
767 assert(only_index != -1);
768 knodes[only_index].bit_skip++;
769 return std::make_pair(only_index, only_measure);
773 node_index = next_node_index++;
776 flatten, left_node, light_link_mask, depth + 1, knodes, next_node_index);
778 flatten, right_node, light_link_mask, depth + 1, knodes, next_node_index);
780 new_node.
measure = left_measure;
783 left_child = left_index;
784 right_child = right_index;
788 if (knodes.size() <= node_index) {
789 knodes.resize(node_index + 1);
793 if (node->light_link.shareable) {
794 node->light_link.shared_node_index = node_index;
797 return std::make_pair(node_index, new_node.
measure);
805 KernelIntegrator *kintegrator = &dscene->
data.integrator;
807 if (!kintegrator->use_light_tree) {
812 progress.
set_status(
"Updating Lights",
"Computing tree");
816 LightTree light_tree(scene, dscene, progress, 8);
838 kintegrator->use_direct_light = num_emitters > 0;
843 memset(klight_link_sets, 0,
sizeof(dscene->
data.light_link_sets));
845 VLOG_INFO <<
"Use light tree with " << num_emitters <<
" emitters and " << light_tree.
num_nodes
848 if (!use_light_linking) {
853 int next_node_index = 0;
858 int next_node_index = 0;
866 light_link_nodes.resize(light_tree.
num_nodes);
868 flatten, root, light_link_nodes.data(), kemitters, next_node_index);
869 light_link_nodes.resize(next_node_index);
880 klight_link_sets[tree_index].light_tree_root =
882 flatten, root, tree_mask, 0, light_link_nodes, next_node_index)
889 memcpy(knodes, light_link_nodes.data(), light_link_nodes.size() *
sizeof(*knodes));
891 VLOG_INFO <<
"Specialized light tree for light linking, with "
892 << light_link_nodes.size() - light_tree.
num_nodes <<
" additional nodes.";
907 int cdf_width = res_x + 1;
909 for (
int i = start; i < end; i++) {
911 float3 env_color = (*pixels)[i * res_x];
914 cond_cdf[i * cdf_width].
x = ave_luminance *
sin_theta;
915 cond_cdf[i * cdf_width].
y = 0.0f;
917 for (
int j = 1; j < res_x; j++) {
918 env_color = (*pixels)[i * res_x + j];
921 cond_cdf[i * cdf_width + j].
x = ave_luminance *
sin_theta;
922 cond_cdf[i * cdf_width + j].
y = cond_cdf[i * cdf_width + j - 1].
y +
923 cond_cdf[i * cdf_width + j - 1].
x / res_x;
926 const float cdf_total = cond_cdf[i * cdf_width + res_x - 1].
y +
927 cond_cdf[i * cdf_width + res_x - 1].
x / res_x;
931 cond_cdf[i * cdf_width + res_x].
x = cdf_total;
933 if (cdf_total > 0.0f) {
934 const float cdf_total_inv = 1.0f / cdf_total;
935 for (
int j = 1; j < res_x; j++) {
936 cond_cdf[i * cdf_width + j].
y *= cdf_total_inv;
940 cond_cdf[i * cdf_width + res_x].
y = 1.0f;
949 KernelIntegrator *kintegrator = &dscene->
data.integrator;
950 KernelBackground *kbackground = &dscene->
data.background;
953 bool background_mis =
false;
956 foreach (
Light *light, scene->lights) {
958 background_light = light;
959 background_mis |= light->use_mis;
963 kbackground->portal_weight = kintegrator->num_portals > 0 ? 1.0f : 0.0f;
964 kbackground->map_weight = background_mis ? 1.0f : 0.0f;
965 kbackground->sun_weight = 0.0f;
968 if (!background_light || !background_light->is_enabled) {
969 kbackground->map_res_x = 0;
970 kbackground->map_res_y = 0;
971 kbackground->use_mis = (kbackground->portal_weight > 0.0f);
975 progress.
set_status(
"Updating Lights",
"Importance map");
978 Shader *shader = scene->background->get_shader(scene);
980 float sun_average_radiance = 0.0f;
981 foreach (
ShaderNode *node, shader->graph->nodes) {
982 if (node->type == EnvironmentTextureNode::get_node_type()) {
986 environment_res.
x =
max(environment_res.
x, (
int)metadata.
width);
987 environment_res.
y =
max(environment_res.
y, (
int)metadata.
height);
990 if (node->type == SkyTextureNode::get_node_type()) {
999 if ((vec_src->
type != TextureCoordinateNode::get_node_type()) ||
1000 (vec_in->
link != vec_src->
output(
"Generated")))
1002 environment_res.
x =
max(environment_res.
x, 4096);
1003 environment_res.
y =
max(environment_res.
y, 2048);
1009 float latitude = sky->get_sun_elevation();
1010 float longitude = sky->get_sun_rotation() +
M_PI_2_F;
1019 sun_direction.
x, sun_direction.
y, sun_direction.
z, half_angle);
1022 kbackground->sun_weight = 4.0f;
1024 environment_res.
x =
max(environment_res.
x, 512);
1025 environment_res.
y =
max(environment_res.
y, 256);
1032 kbackground->use_sun_guiding = (num_suns == 1);
1033 if (!kbackground->use_sun_guiding) {
1034 kbackground->sun_weight = 0.0f;
1035 environment_res.
x =
max(environment_res.
x, 4096);
1036 environment_res.
y =
max(environment_res.
y, 2048);
1040 kbackground->use_mis = (kbackground->portal_weight + kbackground->map_weight +
1041 kbackground->sun_weight) > 0.0f;
1044 int2 res =
make_int2(background_light->map_resolution, background_light->map_resolution / 2);
1047 res = environment_res;
1048 if (res.
x > 0 && res.
y > 0) {
1049 VLOG_INFO <<
"Automatically set World MIS resolution to " << res.
x <<
" by " << res.
y
1054 if (res.
x == 0 || res.
y == 0) {
1056 VLOG_INFO <<
"Setting World MIS resolution to default\n";
1058 kbackground->map_res_x = res.
x;
1059 kbackground->map_res_y = res.
y;
1069 int cdf_width = res.
x + 1;
1073 double time_start =
time_dt();
1076 const int rows_per_task =
divide_up(10240, res.
x);
1077 parallel_for(blocked_range<size_t>(0, res.
y, rows_per_task),
1078 [&](
const blocked_range<size_t> &r) {
1079 background_cdf(r.begin(), r.end(), res.x, res.y, &pixels, cond_cdf);
1083 marg_cdf[0].
x = cond_cdf[res.
x].
x;
1084 marg_cdf[0].
y = 0.0f;
1086 for (
int i = 1; i < res.
y; i++) {
1087 marg_cdf[i].
x = cond_cdf[i * cdf_width + res.
x].
x;
1088 marg_cdf[i].
y = marg_cdf[i - 1].
y + marg_cdf[i - 1].
x / res.
y;
1091 float cdf_total = marg_cdf[res.
y - 1].
y + marg_cdf[res.
y - 1].
x / res.
y;
1092 marg_cdf[res.
y].
x = cdf_total;
1094 float map_average_radiance = cdf_total *
M_PI_2_F;
1095 if (sun_average_radiance > 0.0f) {
1100 background_light->set_average_radiance(0.8f * map_average_radiance +
1101 0.2f * sun_average_radiance);
1104 background_light->set_average_radiance(map_average_radiance);
1107 if (cdf_total > 0.0f) {
1108 for (
int i = 1; i < res.
y; i++) {
1109 marg_cdf[i].
y /= cdf_total;
1113 marg_cdf[res.
y].
y = 1.0f;
1115 VLOG_WORK <<
"Background MIS build time " <<
time_dt() - time_start <<
"\n";
1125 size_t num_lights = 0;
1126 size_t num_portals = 0;
1127 size_t num_background_lights = 0;
1128 size_t num_distant_lights = 0;
1129 bool use_light_mis =
false;
1131 foreach (
Light *light, scene->lights) {
1132 if (light->is_enabled) {
1136 num_distant_lights++;
1139 use_light_mis |= (light->size > 0.0f && light->use_mis);
1142 use_light_mis |= light->use_mis;
1145 num_distant_lights++;
1146 num_background_lights++;
1149 if (light->is_portal) {
1155 KernelIntegrator *kintegrator = &dscene->
data.integrator;
1156 kintegrator->use_light_tree = scene->integrator->get_use_light_tree();
1157 kintegrator->num_lights = num_lights;
1158 kintegrator->num_distant_lights = num_distant_lights;
1159 kintegrator->num_background_lights = num_background_lights;
1160 kintegrator->use_light_mis = use_light_mis;
1162 kintegrator->num_portals = num_portals;
1163 kintegrator->portal_offset = num_lights;
1168 int light_index = 0;
1169 int portal_index = num_lights;
1171 foreach (
Light *light, scene->lights) {
1174 if (light->is_portal) {
1177 float3 extentu = light->get_axisu() * (light->sizeu * light->size);
1178 float3 extentv = light->get_axisv() * (light->sizev * light->size);
1183 float area = len_u * len_v;
1184 if (light->ellipse) {
1187 float invarea = (area != 0.0f) ? 1.0f / area : 1.0f;
1188 if (light->ellipse) {
1195 klights[portal_index].
co = light->get_co();
1197 klights[portal_index].
area.
len_u = len_u;
1199 klights[portal_index].
area.
len_v = len_v;
1201 klights[portal_index].
area.
dir = dir;
1202 klights[portal_index].
tfm = light->tfm;
1209 if (!light->is_enabled) {
1213 Shader *shader = (light->shader) ? light->shader : scene->default_light;
1214 int shader_id = scene->shader_manager->get_shader_id(shader);
1215 float random = (
float)light->random_id * (1.0f / (
float)0xFFFFFFFF);
1217 if (!light->cast_shadow) {
1218 shader_id &= ~SHADER_CAST_SHADOW;
1221 if (!light->use_camera) {
1224 if (!light->use_diffuse) {
1227 if (!light->use_glossy) {
1230 if (!light->use_transmission) {
1233 if (!light->use_scatter) {
1236 if (!light->is_shadow_catcher) {
1240 klights[light_index].
type = light->light_type;
1241 klights[light_index].
strength[0] = light->strength.x;
1242 klights[light_index].
strength[1] = light->strength.y;
1243 klights[light_index].
strength[2] = light->strength.z;
1246 shader_id &= ~SHADER_AREA_LIGHT;
1248 float radius = light->size;
1249 float invarea = (radius == 0.0f) ? 1.0f / 4.0f :
1250 (light->normalize) ? 1.0f / (4.0f *
M_PI_F * radius * radius) :
1254 float eval_fac = invarea * M_1_PI_F;
1256 if (light->use_mis && radius > 0.0f) {
1260 klights[light_index].
co = light->get_co();
1263 klights[light_index].
spot.
is_sphere = light->get_is_sphere() && radius != 0.0f;
1266 shader_id &= ~SHADER_AREA_LIGHT;
1269 float angle = light->angle / 2.0f;
1271 if (light->use_mis && angle > 0.0f) {
1275 const float one_minus_cosangle = 2.0f *
sqr(
sinf(0.5f * angle));
1276 const float pdf = (angle > 0.0f) ? (M_1_2PI_F / one_minus_cosangle) : 1.0f;
1278 klights[light_index].
co = dir;
1282 klights[light_index].
distant.
eval_fac = (light->normalize && angle > 0) ?
1287 0.5f /
sinf(0.5f * angle);
1290 uint visibility = scene->background->get_visibility();
1292 dscene->
data.background.light_index = light_index;
1294 shader_id &= ~SHADER_AREA_LIGHT;
1311 float light_size = light->size;
1312 float3 extentu = light->get_axisu() * (light->sizeu * light_size);
1313 float3 extentv = light->get_axisv() * (light->sizev * light_size);
1318 float area = len_u * len_v;
1319 if (light->ellipse) {
1322 float invarea = (light->normalize && area != 0.0f) ? 1.0f / area : 1.0f;
1323 if (light->ellipse) {
1328 const float half_spread = 0.5f * light->spread;
1329 const float tan_half_spread = light->spread ==
M_PI_F ?
FLT_MAX :
tanf(half_spread);
1334 const float normalize_spread = half_spread > 0.05f ? 1.0f / (tan_half_spread - half_spread) :
1335 3.0f /
powf(half_spread, 3.0f);
1339 if (light->use_mis && area != 0.0f && light->spread > 0.0f) {
1343 klights[light_index].
co = light->get_co();
1345 klights[light_index].
area.
len_u = len_u;
1347 klights[light_index].
area.
len_v = len_v;
1349 klights[light_index].
area.
dir = dir;
1354 const float cos_half_spot_angle =
cosf(light->spot_angle * 0.5f);
1355 const float spot_smooth = 1.0f / ((1.0f - cos_half_spot_angle) * light->spot_smooth);
1356 const float tan_half_spot_angle =
tanf(light->spot_angle * 0.5f);
1358 const float len_w_sq =
len_squared(light->get_dir());
1359 const float len_u_sq =
len_squared(light->get_axisu());
1360 const float len_v_sq =
len_squared(light->get_axisv());
1361 const float tan_sq =
sqr(tan_half_spot_angle);
1369 1.0f + tan_sq *
fmaxf(len_u_sq, len_v_sq) / len_w_sq);
1372 light->size *
sqrtf(1.0f + len_w_sq / (tan_sq *
fminf(len_u_sq, len_v_sq)));
1375 klights[light_index].
shader_id = shader_id;
1377 klights[light_index].
max_bounces = light->max_bounces;
1379 klights[light_index].
use_caustics = light->use_caustics;
1381 klights[light_index].
tfm = light->tfm;
1386 klights[light_index].
lightgroup = dscene->
data.background.lightgroup;
1389 auto it = scene->lightgroups.find(light->lightgroup);
1390 if (it != scene->lightgroups.end()) {
1391 klights[light_index].
lightgroup = it->second;
1404 VLOG_INFO <<
"Number of lights sent to the device: " << num_lights;
1419 if (scene->update_stats) {
1420 scene->update_stats->light.times.add_entry({
"device_update", time});
1424 VLOG_INFO <<
"Total " << scene->lights.size() <<
" lights.";
1427 test_enabled_lights(scene);
1429 device_free(device, dscene, need_update_background);
1431 device_update_lights(dscene, scene);
1432 if (progress.get_cancel()) {
1436 if (need_update_background) {
1437 device_update_background(device, dscene, scene, progress);
1438 if (progress.get_cancel()) {
1443 device_update_distribution(device, dscene, scene, progress);
1444 if (progress.get_cancel()) {
1448 device_update_tree(device, dscene, scene, progress);
1449 if (progress.get_cancel()) {
1453 device_update_ies(dscene);
1454 if (progress.get_cancel()) {
1458 update_flags = UPDATE_NONE;
1459 need_update_background =
false;
1473 if (free_background) {
1495 if (filename.empty() || !
path_read_text(filename.c_str(), content)) {
1510 for (slot = 0; slot <
ies_slots.size(); slot++) {
1518 for (slot = 0; slot <
ies_slots.size(); slot++) {
1543 if (slot < 0 || slot >=
ies_slots.size()) {
1562 if (slot->
users == 0) {
1570 for (slot_end =
ies_slots.size(); slot_end; slot_end--) {
1583 int packed_size = 0;
1594 for (
int i = 0; i <
ies_slots.size(); i++) {
1595 int size =
ies_slots[i]->ies.packed_size();
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
ATTR_WARN_UNUSED_RESULT const BMVert * v
ccl_device_inline float sin_theta(const float3 w)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
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, size_t size)=0
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
void device_update_ies(DeviceScene *dscene)
int add_ies(const string &ies)
vector< IESSlot * > ies_slots
void device_update_tree(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
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 device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
bool need_update_background
void remove_ies(int slot)
void device_update_background(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress)
int last_background_resolution
bool has_background_light(Scene *scene)
void tag_update(Scene *scene, uint32_t flag)
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)
void set_status(const string &status_, const string &substatus_="")
void set_error(const string &error_message_)
bool eval(const ShaderEvalType type, const int max_num_inputs, const int num_channels, const function< int(device_vector< KernelShaderEvalInput > &)> &fill_input, const function< void(device_vector< float > &)> &read_output)
ShaderInput * input(const char *name)
ShaderOutput * output(const char *name)
float get_sun_average_radiance()
Transform compute_transform()
TextureMapping tex_mapping
T * alloc(size_t width, size_t height=0, size_t depth=0)
#define CCL_NAMESPACE_END
draw_view in_light_buf[] float
IMETHOD void random(Vector &a)
addDelta operator for displacement rotational velocity.
static uint hash_string(const char *str)
#define LIGHT_LINK_SET_MAX
@ PATH_RAY_VOLUME_SCATTER
@ SHADER_EXCLUDE_SHADOW_CATCHER
@ SHADER_EXCLUDE_TRANSMIT
#define LIGHT_LINK_MASK_ALL
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()
#define SOCKET_FLOAT(name, ui_name, default_value,...)
#define SOCKET_INT(name, ui_name, default_value,...)
#define SOCKET_NODE(name, ui_name, node_type,...)
#define SOCKET_TRANSFORM(name, ui_name, default_value,...)
#define SOCKET_UINT(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_STRING(name, ui_name, default_value,...)
#define SOCKET_UINT64(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 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 background_cdf(int start, int end, int res_x, int res_y, const vector< float3 > *pixels, float2 *cond_cdf)
static void light_tree_node_copy_to_device(KernelLightTreeNode &knode, const LightTreeNode &node, const int left_child, const int right_child)
static CCL_NAMESPACE_BEGIN void shade_background_pixels(Device *device, DeviceScene *dscene, int width, int height, vector< float3 > &pixels, Progress &progress)
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)
unsigned __int64 uint64_t
float half_inv_sin_half_angle
struct KernelLightTreeEmitter::@1445::@1448 light
struct KernelLightTreeEmitter::@1445::@1447 triangle
EmissionSampling emission_sampling
struct KernelLightTreeEmitter::@1445::@1449 mesh
struct KernelLightTreeNode::@1440::@1444 instance
struct KernelLightTreeNode::@1440::@1442 leaf
struct KernelLightTreeNode::@1440::@1443 inner
uint64_t light_set_membership
uint64_t shadow_set_membership
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()
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
bool has_shadow_linking() const
void tag_update(Scene *scene)
bool has_light_linking() const
bool has_contribution(Scene *scene)
bool valid(const float3 *verts) const
void insert(const char *x, int y)
static NodeType * add(const char *name, CreateFunc create, Type type=NONE, const NodeType *base=NULL)
void dereference_all_used_nodes()
vector< Object * > objects
std::unique_lock< std::mutex > thread_scoped_lock
CCL_NAMESPACE_BEGIN double time_dt()
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 float sqr(float a)
ccl_device_inline float inversesqrtf(float f)
ccl_device_inline size_t divide_up(size_t x, size_t y)