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()) {
164 if ((get_sizeu() * get_sizev() * get_size() == 0.0f) ||
179 return (used_shaders.empty()) ?
nullptr :
static_cast<Shader *
>(used_shaders[0]);
207 return (
area == 0.0f) ? 4.0f :
area;
221 const float half_angle =
angle / 2.0f;
222 return (half_angle > 0.0f) ?
M_PI_F *
sqr(
sinf(half_angle)) : 1.0f;
241 if (!object->get_geometry()->is_light()) {
245 Light *light =
static_cast<Light *
>(
object->get_geometry());
260 size_t num_lights = 0;
261 bool has_portal =
false;
263 if (!object->get_geometry()->is_light()) {
267 Light *light =
static_cast<Light *
>(
object->get_geometry());
269 has_portal |= light->is_portal;
272 background_lights.push_back(light);
275 num_lights += light->is_enabled;
278 LOG_INFO <<
"Total " << num_lights <<
" lights.";
280 bool background_enabled =
false;
281 int background_resolution = 0;
283 if (!background_lights.empty()) {
289 for (
Light *light : background_lights) {
291 if (light->is_enabled) {
292 background_enabled =
true;
293 background_resolution = light->map_resolution;
297 if (!background_enabled) {
298 LOG_INFO <<
"Background MIS has been disabled.";
313 const uint visibility =
object->get_visibility();
314 uint shader_flag = 0;
331 if (!(object->get_is_shadow_catcher())) {
343 KernelIntegrator *kintegrator = &dscene->
data.integrator;
344 if (kintegrator->use_light_tree) {
350 progress.
set_status(
"Updating Lights",
"Computing distribution");
353 size_t num_triangles = 0;
355 const int num_lights = kintegrator->num_lights;
356 const size_t max_num_triangles = std::numeric_limits<int>::max() - 1 - kintegrator->num_lights;
367 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
368 const int mesh_num_triangles =
static_cast<int>(mesh->
num_triangles());
370 for (
int i = 0;
i < mesh_num_triangles;
i++) {
371 const int shader_index = mesh->get_shader()[
i];
372 Shader *shader = (shader_index < mesh->get_used_shaders().
size()) ?
373 static_cast<Shader *
>(mesh->get_used_shaders()[shader_index]) :
381 if (num_triangles > max_num_triangles) {
383 "Number of emissive triangles exceeds the limit, consider using Light Tree or disabling "
384 "Emission Sampling on some emissive materials");
388 const size_t num_distribution = num_triangles + num_lights;
391 kintegrator->num_distribution = num_distribution;
393 LOG_INFO <<
"Use light distribution with " << num_distribution <<
" emitters.";
397 float totarea = 0.0f;
411 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
417 for (
size_t i = 0;
i < mesh_num_triangles;
i++) {
418 const int shader_index = mesh->get_shader()[
i];
419 Shader *shader = (shader_index < mesh->get_used_shaders().
size()) ?
420 static_cast<Shader *
>(mesh->get_used_shaders()[shader_index]) :
424 distribution[offset].
totarea = totarea;
427 distribution[offset].
object_id =
object->index;
431 if (!t.
valid(mesh->get_verts().data())) {
434 float3 p1 = mesh->get_verts()[t.
v[0]];
435 float3 p2 = mesh->get_verts()[t.
v[1]];
436 float3 p3 = mesh->get_verts()[t.
v[2]];
438 if (!transform_applied) {
449 const float trianglearea = totarea;
454 if (num_lights > 0) {
455 const float lightarea = (totarea > 0.0f) ? totarea / num_lights : 1.0f;
457 if (!object->get_geometry()->is_light()) {
461 Light *light =
static_cast<Light *
>(
object->get_geometry());
462 if (!light->is_enabled) {
466 distribution[offset].
totarea = totarea;
467 distribution[offset].
prim = ~light_index;
468 distribution[offset].
object_id =
object->index;
470 totarea += lightarea;
478 distribution[num_distribution].
totarea = totarea;
479 distribution[num_distribution].
prim = 0;
483 if (totarea > 0.0f) {
484 for (
size_t i = 0;
i < num_distribution;
i++) {
487 distribution[num_distribution].
totarea = 1.0f;
495 kintegrator->use_direct_light = (totarea > 0.0f);
499 kintegrator->distribution_pdf_triangles = 0.0f;
500 kintegrator->distribution_pdf_lights = 0.0f;
502 if (trianglearea > 0.0f) {
503 kintegrator->distribution_pdf_triangles = 1.0f / trianglearea;
505 kintegrator->distribution_pdf_triangles *= 0.5f;
510 kintegrator->distribution_pdf_lights = 1.0f / num_lights;
511 if (trianglearea > 0.0f) {
512 kintegrator->distribution_pdf_lights *= 0.5f;
535 const int left_child,
536 const int right_child)
567 int &next_node_index);
573 int &next_node_index)
576 for (
int i = 0;
i < node.
get_leaf().num_emitters;
i++) {
588 Mesh *mesh =
static_cast<Mesh *
>(
object->get_geometry());
590 mesh->get_used_shaders()[mesh->get_shader()[emitter.
prim_id]]);
604 flatten.
light_array[~emitter.light_id] = emitter_index;
619 auto map_it = flatten.
instances.find(reference_node);
621 if (instance_node != reference_node) {
624 std::swap(instance_node->
type, reference_node->
type);
631 flatten, instance_node, knodes, kemitters, next_node_index);
651 int &next_node_index)
654 const int node_index = next_node_index++;
656 int right_child = -1;
687 int &next_node_index)
715 int &next_node_index,
716 bool can_share =
true)
723 int right_child = -1;
729 node_index = next_node_index++;
738 node_index = next_node_index++;
739 int first_emitter = -1;
740 int num_emitters = 0;
742 for (
int i = 0;
i < node->
get_leaf().num_emitters;
i++) {
746 if (first_emitter == -1) {
754 assert(first_emitter != -1);
759 new_node.
make_leaf(first_emitter, num_emitters);
778 only_node = right_node;
781 only_node = left_node;
788 flatten, only_node, light_link_mask, depth + 1, knodes, next_node_index,
false);
791 knodes[only_index].bit_skip++;
792 return std::make_pair(only_index, only_measure);
796 node_index = next_node_index++;
799 flatten, left_node, light_link_mask, depth + 1, knodes, next_node_index);
801 flatten, right_node, light_link_mask, depth + 1, knodes, next_node_index);
803 new_node.
measure = left_measure;
806 left_child = left_index;
807 right_child = right_index;
811 if (knodes.size() <= node_index) {
812 knodes.resize(node_index + 1);
820 return std::make_pair(node_index, new_node.
measure);
828 KernelIntegrator *kintegrator = &dscene->
data.integrator;
830 if (!kintegrator->use_light_tree) {
835 progress.
set_status(
"Updating Lights",
"Computing tree");
839 LightTree light_tree(scene, dscene, progress, 8);
847 flatten.
scene = scene;
861 kintegrator->use_direct_light = num_emitters > 0;
866 memset(klight_link_sets, 0,
sizeof(dscene->
data.light_link_sets));
868 LOG_INFO <<
"Use light tree with " << num_emitters <<
" emitters and " << light_tree.
num_nodes
871 if (!use_light_linking) {
876 int next_node_index = 0;
881 int next_node_index = 0;
889 light_link_nodes.resize(light_tree.
num_nodes);
891 flatten, root, light_link_nodes.data(), kemitters, next_node_index);
892 light_link_nodes.resize(next_node_index);
903 klight_link_sets[tree_index].light_tree_root =
905 flatten, root, tree_mask, 0, light_link_nodes, next_node_index)
912 memcpy(knodes, light_link_nodes.data(), light_link_nodes.size() *
sizeof(*knodes));
914 LOG_INFO <<
"Specialized light tree for light linking, with "
915 << light_link_nodes.size() - light_tree.
num_nodes <<
" additional nodes.";
934 const int cdf_width = res_x + 1;
936 for (
int i = start;
i < end;
i++) {
938 float3 env_color = (*pixels)[
i * res_x];
941 cond_cdf[
i * cdf_width].
x = ave_luminance *
sin_theta;
942 cond_cdf[
i * cdf_width].
y = 0.0f;
944 for (
int j = 1; j < res_x; j++) {
945 env_color = (*pixels)[
i * res_x + j];
948 cond_cdf[
i * cdf_width + j].
x = ave_luminance *
sin_theta;
949 cond_cdf[
i * cdf_width + j].
y = cond_cdf[
i * cdf_width + j - 1].
y +
950 cond_cdf[
i * cdf_width + j - 1].
x / res_x;
953 const float cdf_total = cond_cdf[
i * cdf_width + res_x - 1].
y +
954 cond_cdf[
i * cdf_width + res_x - 1].
x / res_x;
958 cond_cdf[
i * cdf_width + res_x].
x = cdf_total;
960 if (cdf_total > 0.0f) {
961 const float cdf_total_inv = 1.0f / cdf_total;
962 for (
int j = 1; j < res_x; j++) {
963 cond_cdf[
i * cdf_width + j].
y *= cdf_total_inv;
967 cond_cdf[
i * cdf_width + res_x].
y = 1.0f;
976 KernelIntegrator *kintegrator = &dscene->
data.integrator;
977 KernelBackground *kbackground = &dscene->
data.background;
978 Light *background_light =
nullptr;
980 bool background_mis =
false;
984 if (!object->get_geometry()->is_light()) {
988 Light *light =
static_cast<Light *
>(
object->get_geometry());
990 background_light = light;
991 background_mis |= light->use_mis;
995 kbackground->portal_weight = kintegrator->num_portals > 0 ? 1.0f : 0.0f;
996 kbackground->map_weight = background_mis ? 1.0f : 0.0f;
997 kbackground->sun_weight = 0.0f;
1000 if (!background_light || !background_light->is_enabled) {
1001 kbackground->map_res_x = 0;
1002 kbackground->map_res_y = 0;
1003 kbackground->use_mis = (kbackground->portal_weight > 0.0f);
1007 progress.
set_status(
"Updating Lights",
"Importance map");
1012 float sun_average_radiance = 0.0f;
1014 if (node->
type == EnvironmentTextureNode::get_node_type()) {
1018 environment_res.
x =
max(environment_res.
x, (
int)metadata.
width);
1019 environment_res.
y =
max(environment_res.
y, (
int)metadata.
height);
1022 if (node->
type == SkyTextureNode::get_node_type()) {
1024 if (sky->get_sun_disc()) {
1031 if ((vec_src->
type != TextureCoordinateNode::get_node_type()) ||
1032 (vec_in->
link != vec_src->
output(
"Generated")))
1034 environment_res.
x =
max(environment_res.
x, 4096);
1035 environment_res.
y =
max(environment_res.
y, 2048);
1041 const float latitude = sky->get_sun_elevation();
1042 const float longitude = sky->get_sun_rotation() +
M_PI_2_F;
1053 kbackground->sun_weight = 4.0f;
1055 environment_res.
x =
max(environment_res.
x, 512);
1056 environment_res.
y =
max(environment_res.
y, 256);
1063 kbackground->use_sun_guiding = (num_suns == 1);
1064 if (!kbackground->use_sun_guiding) {
1065 kbackground->sun_weight = 0.0f;
1066 environment_res.
x =
max(environment_res.
x, 4096);
1067 environment_res.
y =
max(environment_res.
y, 2048);
1071 kbackground->use_mis = (kbackground->portal_weight + kbackground->map_weight +
1072 kbackground->sun_weight) > 0.0f;
1075 int2 res =
make_int2(background_light->map_resolution, background_light->map_resolution / 2);
1078 res = environment_res;
1079 if (res.
x > 0 && res.
y > 0) {
1080 LOG_INFO <<
"Automatically set World MIS resolution to " << res.
x <<
" by " << res.
y;
1084 if (res.
x == 0 || res.
y == 0) {
1086 LOG_INFO <<
"Setting World MIS resolution to default";
1088 kbackground->map_res_x = res.
x;
1089 kbackground->map_res_y = res.
y;
1099 const int cdf_width = res.
x + 1;
1103 const double time_start =
time_dt();
1106 const int rows_per_task =
divide_up(10240, res.
x);
1107 parallel_for(blocked_range<size_t>(0, res.
y, rows_per_task),
1108 [&](
const blocked_range<size_t> &r) {
1109 background_cdf(r.begin(), r.end(), res.x, res.y, &pixels, cond_cdf);
1113 marg_cdf[0].
x = cond_cdf[res.
x].
x;
1114 marg_cdf[0].
y = 0.0f;
1116 for (
int i = 1;
i < res.
y;
i++) {
1117 marg_cdf[
i].
x = cond_cdf[
i * cdf_width + res.
x].
x;
1118 marg_cdf[
i].
y = marg_cdf[
i - 1].
y + marg_cdf[
i - 1].
x / res.
y;
1121 const float cdf_total = marg_cdf[res.
y - 1].
y + marg_cdf[res.
y - 1].
x / res.
y;
1122 marg_cdf[res.
y].
x = cdf_total;
1124 const float map_average_radiance = cdf_total *
M_PI_2_F;
1125 if (sun_average_radiance > 0.0f) {
1130 background_light->set_average_radiance(0.8f * map_average_radiance +
1131 0.2f * sun_average_radiance);
1134 background_light->set_average_radiance(map_average_radiance);
1137 if (cdf_total > 0.0f) {
1138 for (
int i = 1;
i < res.
y;
i++) {
1139 marg_cdf[
i].
y /= cdf_total;
1143 marg_cdf[res.
y].
y = 1.0f;
1155 size_t num_lights = 0;
1156 size_t num_portals = 0;
1157 size_t num_background_lights = 0;
1158 size_t num_distant_lights = 0;
1159 bool use_light_mis =
false;
1162 if (!object->get_geometry()->is_light()) {
1166 Light *light =
static_cast<Light *
>(
object->get_geometry());
1167 if (light->is_enabled) {
1171 num_distant_lights++;
1174 use_light_mis |= (light->size > 0.0f && light->use_mis);
1177 use_light_mis |= light->use_mis;
1180 num_distant_lights++;
1181 num_background_lights++;
1184 if (light->is_portal) {
1190 KernelIntegrator *kintegrator = &dscene->
data.integrator;
1191 kintegrator->use_light_tree = scene->
integrator->get_use_light_tree();
1192 kintegrator->num_lights = num_lights;
1193 kintegrator->num_distant_lights = num_distant_lights;
1194 kintegrator->num_background_lights = num_background_lights;
1195 kintegrator->use_light_mis = use_light_mis;
1197 kintegrator->num_portals = num_portals;
1198 kintegrator->portal_offset = num_lights;
1203 int light_index = 0;
1204 int portal_index = num_lights;
1207 if (!object->get_geometry()->is_light()) {
1211 Light *light =
static_cast<Light *
>(
object->get_geometry());
1219 if (light->is_portal) {
1222 const float3 extentu = axisu * (light->sizeu * light->size);
1223 const float3 extentv = axisv * (light->sizev * light->size);
1229 const float area = light->
area(object->get_tfm());
1230 float invarea = (area != 0.0f) ? 1.0f / area : 1.0f;
1231 if (light->ellipse) {
1236 klights[portal_index].
co = co;
1238 klights[portal_index].
area.
len_u = len_u;
1240 klights[portal_index].
area.
len_v = len_v;
1243 klights[portal_index].
object_id =
object->index;
1249 if (!light->is_enabled) {
1256 if (!light->cast_shadow) {
1262 klights[light_index].
type = light->light_type;
1263 klights[light_index].
strength[0] = light->strength.x;
1264 klights[light_index].
strength[1] = light->strength.y;
1265 klights[light_index].
strength[2] = light->strength.z;
1270 const float radius = light->size;
1271 const float invarea = (light->normalize) ? 1.0f / light->
area(object->get_tfm()) : 1.0f;
1274 const float eval_fac = invarea *
M_1_PI_F;
1276 if (light->use_mis && radius > 0.0f) {
1280 klights[light_index].
co = co;
1283 klights[light_index].
spot.
is_sphere = light->get_is_sphere() && radius != 0.0f;
1288 const float angle = light->angle / 2.0f;
1290 if (light->use_mis &&
angle > 0.0f) {
1294 const float one_minus_cosangle = 2.0f *
sqr(
sinf(0.5f *
angle));
1295 const float pdf = (
angle > 0.0f) ? (
M_1_2PI_F / one_minus_cosangle) : 1.0f;
1302 1.0f / light->
area(object->get_tfm()) :
1311 dscene->
data.background.light_index = light_index;
1330 const float light_size = light->size;
1331 const float3 extentu = axisu * (light->sizeu * light_size);
1332 const float3 extentv = axisv * (light->sizev * light_size);
1338 const float area = light->
area(object->get_tfm());
1339 float invarea = light->normalize ? 1.0f / area : 1.0f;
1340 if (light->ellipse) {
1345 const float half_spread = 0.5f *
fmaxf(light->spread, 0.0f);
1346 const float tan_half_spread = light->spread ==
M_PI_F ?
FLT_MAX :
tanf(half_spread);
1351 const float normalize_spread = (half_spread > 0.0f) ?
1352 (half_spread > 0.05f ?
1353 1.0f / (tan_half_spread - half_spread) :
1354 3.0f /
powf(half_spread, 3.0f)) :
1357 if (light->use_mis && area != 0.0f && light->spread > 0.0f) {
1361 klights[light_index].
co = co;
1363 klights[light_index].
area.
len_u = len_u;
1365 klights[light_index].
area.
len_v = len_v;
1372 const float cos_half_spot_angle =
cosf(light->spot_angle * 0.5f);
1373 const float spot_smooth = 1.0f / ((1.0f - cos_half_spot_angle) * light->spot_smooth);
1374 const float tan_half_spot_angle =
tanf(light->spot_angle * 0.5f);
1379 const float tan_sq =
sqr(tan_half_spot_angle);
1387 1.0f + tan_sq *
fmaxf(len_u_sq, len_v_sq) / len_w_sq);
1390 light->size *
sqrtf(1.0f + len_w_sq / (tan_sq *
fminf(len_u_sq, len_v_sq)));
1393 klights[light_index].
shader_id = shader_id;
1394 klights[light_index].
object_id =
object->index;
1396 klights[light_index].
max_bounces = light->max_bounces;
1397 klights[light_index].
use_caustics = light->use_caustics;
1402 LOG_INFO <<
"Number of lights sent to the device: " << num_lights;
1418 scene->
update_stats->light.times.add_entry({
"device_update", time});
1460 const bool free_background)
1471 if (free_background) {
1508 for (slot = 0; slot <
ies_slots.size(); slot++) {
1516 for (slot = 0; slot <
ies_slots.size(); slot++) {
1524 ies_slots.push_back(make_unique<IESSlot>());
1541 if (slot < 0 || slot >=
ies_slots.size()) {
1560 if (slot->users == 0) {
1568 for (slot_end =
ies_slots.size(); slot_end; slot_end--) {
1577 int packed_size = 0;
1579 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
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 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)
#define LIGHT_LINK_SET_MAX
#define CCL_NAMESPACE_END
#define assert(assertion)
VecBase< float, D > normalize(VecOp< float, D >) RET
static uint hash_string(const char *str)
@ PATH_RAY_VOLUME_SCATTER
@ SHADER_EXCLUDE_SHADOW_CATCHER
@ SHADER_EXCLUDE_TRANSMIT
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 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)
float3 sun_direction(float sun_cos_theta)
float half_inv_sin_half_angle
struct KernelLightTreeEmitter::@100244224035147311323362061026206066304156105230::@145257001270125053357336343156215202056055243242 light
struct KernelLightTreeEmitter::@100244224035147311323362061026206066304156105230::@155115103153173066061151154125014102203306247176 mesh
EmissionSampling emission_sampling
struct KernelLightTreeEmitter::@100244224035147311323362061026206066304156105230::@126172035204211036214107167014276257320000170324 triangle
struct KernelLightTreeNode::@075060275333356206225201163255143122031204113015::@064327011010203173153234374026232040346041241257 instance
struct KernelLightTreeNode::@075060275333356206225201163255143122031204113015::@121232343267032302300332005257270111102366024356 inner
struct KernelLightTreeNode::@075060275333356206225201163255143122031204113015::@354167317357124241334100100220231122277063225056 leaf
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)