Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/render/light.cpp
| Show First 20 Lines • Show All 156 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| Light::Light() : Node(node_type) | Light::Light() : Node(node_type) | ||||
| { | { | ||||
| } | } | ||||
| void Light::tag_update(Scene *scene) | void Light::tag_update(Scene *scene) | ||||
| { | { | ||||
| scene->light_manager->need_update = is_modified(); | scene->get_light_manager()->need_update = is_modified(); | ||||
| } | } | ||||
| bool Light::has_contribution(Scene *scene) | bool Light::has_contribution(Scene *scene) | ||||
| { | { | ||||
| if (strength == make_float3(0.0f, 0.0f, 0.0f)) { | if (strength == make_float3(0.0f, 0.0f, 0.0f)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (is_portal) { | if (is_portal) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (light_type == LIGHT_BACKGROUND) { | if (light_type == LIGHT_BACKGROUND) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| return (shader) ? shader->has_surface_emission : scene->default_light->has_surface_emission; | return (shader) ? shader->get_has_surface_emission() : | ||||
| scene->get_default_light()->get_has_surface_emission(); | |||||
| } | } | ||||
| /* Light Manager */ | /* Light Manager */ | ||||
| LightManager::LightManager() | LightManager::LightManager() | ||||
| { | { | ||||
| need_update = true; | need_update = true; | ||||
| need_update_background = true; | need_update_background = true; | ||||
| use_light_visibility = false; | use_light_visibility = false; | ||||
| last_background_enabled = false; | last_background_enabled = false; | ||||
| last_background_resolution = 0; | last_background_resolution = 0; | ||||
| } | } | ||||
| LightManager::~LightManager() | LightManager::~LightManager() | ||||
| { | { | ||||
| foreach (IESSlot *slot, ies_slots) { | foreach (IESSlot *slot, ies_slots) { | ||||
| delete slot; | delete slot; | ||||
| } | } | ||||
| } | } | ||||
| bool LightManager::has_background_light(Scene *scene) | bool LightManager::has_background_light(Scene *scene) | ||||
| { | { | ||||
| foreach (Light *light, scene->lights) { | foreach (Light *light, scene->get_lights()) { | ||||
| if (light->light_type == LIGHT_BACKGROUND && light->is_enabled) { | if (light->light_type == LIGHT_BACKGROUND && light->is_enabled) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| void LightManager::test_enabled_lights(Scene *scene) | void LightManager::test_enabled_lights(Scene *scene) | ||||
| { | { | ||||
| /* Make all lights enabled by default, and perform some preliminary checks | /* Make all lights enabled by default, and perform some preliminary checks | ||||
| * needed for finer-tuning of settings (for example, check whether we've | * needed for finer-tuning of settings (for example, check whether we've | ||||
| * got portals or not). | * got portals or not). | ||||
| */ | */ | ||||
| bool has_portal = false, has_background = false; | bool has_portal = false, has_background = false; | ||||
| foreach (Light *light, scene->lights) { | foreach (Light *light, scene->get_lights()) { | ||||
| light->is_enabled = light->has_contribution(scene); | light->is_enabled = light->has_contribution(scene); | ||||
| has_portal |= light->is_portal; | has_portal |= light->is_portal; | ||||
| has_background |= light->light_type == LIGHT_BACKGROUND; | has_background |= light->light_type == LIGHT_BACKGROUND; | ||||
| } | } | ||||
| bool background_enabled = false; | bool background_enabled = false; | ||||
| int background_resolution = 0; | int background_resolution = 0; | ||||
| if (has_background) { | if (has_background) { | ||||
| /* Ignore background light if: | /* Ignore background light if: | ||||
| * - If unsupported on a device | * - If unsupported on a device | ||||
| * - If we don't need it (no HDRs etc.) | * - If we don't need it (no HDRs etc.) | ||||
| */ | */ | ||||
| Shader *shader = scene->background->get_shader(scene); | Shader *shader = scene->get_background()->get_shader(scene); | ||||
| const bool disable_mis = !(has_portal || shader->has_surface_spatial_varying); | const bool disable_mis = !(has_portal || shader->get_has_surface_spatial_varying()); | ||||
| VLOG_IF(1, disable_mis) << "Background MIS has been disabled.\n"; | VLOG_IF(1, disable_mis) << "Background MIS has been disabled.\n"; | ||||
| foreach (Light *light, scene->lights) { | foreach (Light *light, scene->get_lights()) { | ||||
| if (light->light_type == LIGHT_BACKGROUND) { | if (light->light_type == LIGHT_BACKGROUND) { | ||||
| light->is_enabled = !disable_mis; | light->is_enabled = !disable_mis; | ||||
| background_enabled = !disable_mis; | background_enabled = !disable_mis; | ||||
| background_resolution = light->map_resolution; | background_resolution = light->map_resolution; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (last_background_enabled != background_enabled || | if (last_background_enabled != background_enabled || | ||||
| last_background_resolution != background_resolution) { | last_background_resolution != background_resolution) { | ||||
| last_background_enabled = background_enabled; | last_background_enabled = background_enabled; | ||||
| last_background_resolution = background_resolution; | last_background_resolution = background_resolution; | ||||
| need_update_background = true; | need_update_background = true; | ||||
| } | } | ||||
| } | } | ||||
| bool LightManager::object_usable_as_light(Object *object) | bool LightManager::object_usable_as_light(Object *object) | ||||
| { | { | ||||
| Geometry *geom = object->get_geometry(); | Geometry *geom = object->get_geometry(); | ||||
| if (geom->geometry_type != Geometry::MESH && geom->geometry_type != Geometry::VOLUME) { | if (!geom->is_mesh() && !geom->is_volume()) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* Skip objects with NaNs */ | /* Skip objects with NaNs */ | ||||
| if (!object->bounds.valid()) { | if (!object->get_bounds().valid()) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* Skip if we are not visible for BSDFs. */ | /* Skip if we are not visible for BSDFs. */ | ||||
| if (!(object->get_visibility() & (PATH_RAY_DIFFUSE | PATH_RAY_GLOSSY | PATH_RAY_TRANSMIT))) { | if (!(object->get_visibility() & (PATH_RAY_DIFFUSE | PATH_RAY_GLOSSY | PATH_RAY_TRANSMIT))) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* Skip if we have no emission shaders. */ | /* Skip if we have no emission shaders. */ | ||||
| /* TODO(sergey): Ideally we want to avoid such duplicated loop, since it'll | /* TODO(sergey): Ideally we want to avoid such duplicated loop, since it'll | ||||
| * iterate all geometry shaders twice (when counting and when calculating | * iterate all geometry shaders twice (when counting and when calculating | ||||
| * triangle area. | * triangle area. | ||||
| */ | */ | ||||
| foreach (Node *node, geom->get_used_shaders()) { | foreach (Node *node, geom->get_used_shaders()) { | ||||
| Shader *shader = static_cast<Shader *>(node); | Shader *shader = static_cast<Shader *>(node); | ||||
| if (shader->get_use_mis() && shader->has_surface_emission) { | if (shader->get_use_mis() && shader->get_has_surface_emission()) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| void LightManager::device_update_distribution(Device *, | void LightManager::device_update_distribution(Device *, | ||||
| DeviceScene *dscene, | DeviceScene *dscene, | ||||
| Scene *scene, | Scene *scene, | ||||
| Progress &progress) | Progress &progress) | ||||
| { | { | ||||
| progress.set_status("Updating Lights", "Computing distribution"); | progress.set_status("Updating Lights", "Computing distribution"); | ||||
| /* count */ | /* count */ | ||||
| size_t num_lights = 0; | size_t num_lights = 0; | ||||
| size_t num_portals = 0; | size_t num_portals = 0; | ||||
| size_t num_background_lights = 0; | size_t num_background_lights = 0; | ||||
| size_t num_triangles = 0; | size_t num_triangles = 0; | ||||
| bool background_mis = false; | bool background_mis = false; | ||||
| foreach (Light *light, scene->lights) { | foreach (Light *light, scene->get_lights()) { | ||||
| if (light->is_enabled) { | if (light->is_enabled) { | ||||
| num_lights++; | num_lights++; | ||||
| } | } | ||||
| if (light->is_portal) { | if (light->is_portal) { | ||||
| num_portals++; | num_portals++; | ||||
| } | } | ||||
| } | } | ||||
| foreach (Object *object, scene->objects) { | foreach (Object *object, scene->get_objects()) { | ||||
| if (progress.get_cancel()) | if (progress.get_cancel()) | ||||
| return; | return; | ||||
| if (!object_usable_as_light(object)) { | if (!object_usable_as_light(object)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| /* Count triangles. */ | /* Count triangles. */ | ||||
| Mesh *mesh = static_cast<Mesh *>(object->get_geometry()); | Mesh *mesh = static_cast<Mesh *>(object->get_geometry()); | ||||
| size_t mesh_num_triangles = mesh->num_triangles(); | size_t mesh_num_triangles = mesh->num_triangles(); | ||||
| for (size_t i = 0; i < mesh_num_triangles; i++) { | for (size_t i = 0; i < mesh_num_triangles; i++) { | ||||
| int shader_index = mesh->get_shader()[i]; | int shader_index = mesh->get_shader()[i]; | ||||
| Shader *shader = (shader_index < mesh->get_used_shaders().size()) ? | Shader *shader = (shader_index < mesh->get_used_shaders().size()) ? | ||||
| static_cast<Shader *>(mesh->get_used_shaders()[shader_index]) : | static_cast<Shader *>(mesh->get_used_shaders()[shader_index]) : | ||||
| scene->default_surface; | scene->get_default_surface(); | ||||
| if (shader->get_use_mis() && shader->has_surface_emission) { | if (shader->get_use_mis() && shader->get_has_surface_emission()) { | ||||
| num_triangles++; | num_triangles++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| size_t num_distribution = num_triangles + num_lights; | size_t num_distribution = num_triangles + num_lights; | ||||
| VLOG(1) << "Total " << num_distribution << " of light distribution primitives."; | VLOG(1) << "Total " << num_distribution << " of light distribution primitives."; | ||||
| /* emission area */ | /* emission area */ | ||||
| KernelLightDistribution *distribution = dscene->light_distribution.alloc(num_distribution + 1); | KernelLightDistribution *distribution = dscene->light_distribution.alloc(num_distribution + 1); | ||||
| float totarea = 0.0f; | float totarea = 0.0f; | ||||
| /* triangles */ | /* triangles */ | ||||
| size_t offset = 0; | size_t offset = 0; | ||||
| int j = 0; | int j = 0; | ||||
| foreach (Object *object, scene->objects) { | foreach (Object *object, scene->get_objects()) { | ||||
| if (progress.get_cancel()) | if (progress.get_cancel()) | ||||
| return; | return; | ||||
| if (!object_usable_as_light(object)) { | if (!object_usable_as_light(object)) { | ||||
| j++; | j++; | ||||
| continue; | continue; | ||||
| } | } | ||||
| /* Sum area. */ | /* Sum area. */ | ||||
| Mesh *mesh = static_cast<Mesh *>(object->get_geometry()); | Mesh *mesh = static_cast<Mesh *>(object->get_geometry()); | ||||
| bool transform_applied = mesh->transform_applied; | bool transform_applied = mesh->get_transform_applied(); | ||||
| Transform tfm = object->get_tfm(); | Transform tfm = object->get_tfm(); | ||||
| int object_id = j; | int object_id = j; | ||||
| int shader_flag = 0; | int shader_flag = 0; | ||||
| if (!(object->get_visibility() & PATH_RAY_DIFFUSE)) { | if (!(object->get_visibility() & PATH_RAY_DIFFUSE)) { | ||||
| shader_flag |= SHADER_EXCLUDE_DIFFUSE; | shader_flag |= SHADER_EXCLUDE_DIFFUSE; | ||||
| use_light_visibility = true; | use_light_visibility = true; | ||||
| } | } | ||||
| Show All 10 Lines | if (!(object->get_visibility() & PATH_RAY_VOLUME_SCATTER)) { | ||||
| use_light_visibility = true; | use_light_visibility = true; | ||||
| } | } | ||||
| size_t mesh_num_triangles = mesh->num_triangles(); | size_t mesh_num_triangles = mesh->num_triangles(); | ||||
| for (size_t i = 0; i < mesh_num_triangles; i++) { | for (size_t i = 0; i < mesh_num_triangles; i++) { | ||||
| int shader_index = mesh->get_shader()[i]; | int shader_index = mesh->get_shader()[i]; | ||||
| Shader *shader = (shader_index < mesh->get_used_shaders().size()) ? | Shader *shader = (shader_index < mesh->get_used_shaders().size()) ? | ||||
| static_cast<Shader *>(mesh->get_used_shaders()[shader_index]) : | static_cast<Shader *>(mesh->get_used_shaders()[shader_index]) : | ||||
| scene->default_surface; | scene->get_default_surface(); | ||||
| if (shader->get_use_mis() && shader->has_surface_emission) { | if (shader->get_use_mis() && shader->get_has_surface_emission()) { | ||||
| distribution[offset].totarea = totarea; | distribution[offset].totarea = totarea; | ||||
| distribution[offset].prim = i + mesh->prim_offset; | distribution[offset].prim = i + mesh->get_prim_offset(); | ||||
| distribution[offset].mesh_light.shader_flag = shader_flag; | distribution[offset].mesh_light.shader_flag = shader_flag; | ||||
| distribution[offset].mesh_light.object_id = object_id; | distribution[offset].mesh_light.object_id = object_id; | ||||
| offset++; | offset++; | ||||
| Mesh::Triangle t = mesh->get_triangle(i); | Mesh::Triangle t = mesh->get_triangle(i); | ||||
| if (!t.valid(&mesh->get_verts()[0])) { | if (!t.valid(&mesh->get_verts()[0])) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| Show All 16 Lines | void LightManager::device_update_distribution(Device *, | ||||
| float trianglearea = totarea; | float trianglearea = totarea; | ||||
| /* point lights */ | /* point lights */ | ||||
| float lightarea = (totarea > 0.0f) ? totarea / num_lights : 1.0f; | float lightarea = (totarea > 0.0f) ? totarea / num_lights : 1.0f; | ||||
| bool use_lamp_mis = false; | bool use_lamp_mis = false; | ||||
| int light_index = 0; | int light_index = 0; | ||||
| foreach (Light *light, scene->lights) { | foreach (Light *light, scene->get_lights()) { | ||||
| if (!light->is_enabled) | if (!light->is_enabled) | ||||
| continue; | continue; | ||||
| distribution[offset].totarea = totarea; | distribution[offset].totarea = totarea; | ||||
| distribution[offset].prim = ~light_index; | distribution[offset].prim = ~light_index; | ||||
| distribution[offset].lamp.pad = 1.0f; | distribution[offset].lamp.pad = 1.0f; | ||||
| distribution[offset].lamp.size = light->size; | distribution[offset].lamp.size = light->size; | ||||
| totarea += lightarea; | totarea += lightarea; | ||||
| ▲ Show 20 Lines • Show All 153 Lines • ▼ Show 20 Lines | void LightManager::device_update_background(Device *device, | ||||
| DeviceScene *dscene, | DeviceScene *dscene, | ||||
| Scene *scene, | Scene *scene, | ||||
| Progress &progress) | Progress &progress) | ||||
| { | { | ||||
| KernelBackground *kbackground = &dscene->data.background; | KernelBackground *kbackground = &dscene->data.background; | ||||
| Light *background_light = NULL; | Light *background_light = NULL; | ||||
| /* find background light */ | /* find background light */ | ||||
| foreach (Light *light, scene->lights) { | foreach (Light *light, scene->get_lights()) { | ||||
| if (light->light_type == LIGHT_BACKGROUND) { | if (light->light_type == LIGHT_BACKGROUND) { | ||||
| background_light = light; | background_light = light; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| /* no background light found, signal renderer to skip sampling */ | /* no background light found, signal renderer to skip sampling */ | ||||
| if (!background_light || !background_light->is_enabled) { | if (!background_light || !background_light->is_enabled) { | ||||
| kbackground->map_res_x = 0; | kbackground->map_res_x = 0; | ||||
| kbackground->map_res_y = 0; | kbackground->map_res_y = 0; | ||||
| kbackground->map_weight = 0.0f; | kbackground->map_weight = 0.0f; | ||||
| kbackground->sun_weight = 0.0f; | kbackground->sun_weight = 0.0f; | ||||
| kbackground->use_mis = (kbackground->portal_weight > 0.0f); | kbackground->use_mis = (kbackground->portal_weight > 0.0f); | ||||
| return; | return; | ||||
| } | } | ||||
| progress.set_status("Updating Lights", "Importance map"); | progress.set_status("Updating Lights", "Importance map"); | ||||
| assert(dscene->data.integrator.use_direct_light); | assert(dscene->data.integrator.use_direct_light); | ||||
| int2 environment_res = make_int2(0, 0); | int2 environment_res = make_int2(0, 0); | ||||
| Shader *shader = scene->background->get_shader(scene); | Shader *shader = scene->get_background()->get_shader(scene); | ||||
| int num_suns = 0; | int num_suns = 0; | ||||
| foreach (ShaderNode *node, shader->graph->nodes) { | foreach (ShaderNode *node, shader->get_graph()->get_nodes()) { | ||||
| if (node->type == EnvironmentTextureNode::node_type) { | if (node->get_type() == EnvironmentTextureNode::node_type) { | ||||
| EnvironmentTextureNode *env = (EnvironmentTextureNode *)node; | EnvironmentTextureNode *env = (EnvironmentTextureNode *)node; | ||||
| ImageMetaData metadata; | ImageMetaData metadata; | ||||
| if (!env->handle.empty()) { | if (!env->handle.empty()) { | ||||
| ImageMetaData metadata = env->handle.metadata(); | ImageMetaData metadata = env->handle.metadata(); | ||||
| environment_res.x = max(environment_res.x, metadata.width); | environment_res.x = max(environment_res.x, metadata.width); | ||||
| environment_res.y = max(environment_res.y, metadata.height); | environment_res.y = max(environment_res.y, metadata.height); | ||||
| } | } | ||||
| } | } | ||||
| if (node->type == SkyTextureNode::node_type) { | if (node->get_type() == SkyTextureNode::node_type) { | ||||
| SkyTextureNode *sky = (SkyTextureNode *)node; | SkyTextureNode *sky = (SkyTextureNode *)node; | ||||
| if (sky->get_sky_type() == NODE_SKY_NISHITA && sky->get_sun_disc()) { | if (sky->get_sky_type() == NODE_SKY_NISHITA && sky->get_sun_disc()) { | ||||
| /* Ensure that the input coordinates aren't transformed before they reach the node. | /* Ensure that the input coordinates aren't transformed before they reach the node. | ||||
| * If that is the case, the logic used for sampling the sun's location does not work | * If that is the case, the logic used for sampling the sun's location does not work | ||||
| * and we have to fall back to map-based sampling. */ | * and we have to fall back to map-based sampling. */ | ||||
| const ShaderInput *vec_in = sky->input("Vector"); | const ShaderInput *vec_in = sky->input("Vector"); | ||||
| if (vec_in && vec_in->link && vec_in->link->parent) { | if (vec_in && vec_in->get_link() && vec_in->get_link()->get_parent()) { | ||||
| ShaderNode *vec_src = vec_in->link->parent; | ShaderNode *vec_src = vec_in->get_link()->get_parent(); | ||||
| if ((vec_src->type != TextureCoordinateNode::node_type) || | if ((vec_src->get_type() != TextureCoordinateNode::node_type) || | ||||
| (vec_in->link != vec_src->output("Generated"))) { | (vec_in->get_link() != vec_src->output("Generated"))) { | ||||
| environment_res.x = max(environment_res.x, 4096); | environment_res.x = max(environment_res.x, 4096); | ||||
| environment_res.y = max(environment_res.y, 2048); | environment_res.y = max(environment_res.y, 2048); | ||||
| continue; | continue; | ||||
| } | } | ||||
| } | } | ||||
| /* Determine sun direction from lat/long and texture mapping. */ | /* Determine sun direction from lat/long and texture mapping. */ | ||||
| float latitude = sky->get_sun_elevation(); | float latitude = sky->get_sun_elevation(); | ||||
| ▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | void LightManager::device_update_background(Device *device, | ||||
| /* update device */ | /* update device */ | ||||
| dscene->light_background_marginal_cdf.copy_to_device(); | dscene->light_background_marginal_cdf.copy_to_device(); | ||||
| dscene->light_background_conditional_cdf.copy_to_device(); | dscene->light_background_conditional_cdf.copy_to_device(); | ||||
| } | } | ||||
| void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *scene) | void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *scene) | ||||
| { | { | ||||
| int num_scene_lights = scene->lights.size(); | int num_scene_lights = scene->get_lights().size(); | ||||
| int num_lights = 0; | int num_lights = 0; | ||||
| foreach (Light *light, scene->lights) { | foreach (Light *light, scene->get_lights()) { | ||||
| if (light->is_enabled || light->is_portal) { | if (light->is_enabled || light->is_portal) { | ||||
| num_lights++; | num_lights++; | ||||
| } | } | ||||
| } | } | ||||
| KernelLight *klights = dscene->lights.alloc(num_lights); | KernelLight *klights = dscene->lights.alloc(num_lights); | ||||
| if (num_lights == 0) { | if (num_lights == 0) { | ||||
| VLOG(1) << "No effective light, ignoring points update."; | VLOG(1) << "No effective light, ignoring points update."; | ||||
| return; | return; | ||||
| } | } | ||||
| int light_index = 0; | int light_index = 0; | ||||
| foreach (Light *light, scene->lights) { | foreach (Light *light, scene->get_lights()) { | ||||
| if (!light->is_enabled) { | if (!light->is_enabled) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| float3 co = light->co; | float3 co = light->co; | ||||
| Shader *shader = (light->shader) ? light->shader : scene->default_light; | Shader *shader = (light->shader) ? light->shader : scene->get_default_light(); | ||||
| int shader_id = scene->shader_manager->get_shader_id(shader); | int shader_id = scene->get_shader_manager()->get_shader_id(shader); | ||||
| int max_bounces = light->max_bounces; | int max_bounces = light->max_bounces; | ||||
| float random = (float)light->random_id * (1.0f / (float)0xFFFFFFFF); | float random = (float)light->random_id * (1.0f / (float)0xFFFFFFFF); | ||||
| if (!light->cast_shadow) | if (!light->cast_shadow) | ||||
| shader_id &= ~SHADER_CAST_SHADOW; | shader_id &= ~SHADER_CAST_SHADOW; | ||||
| if (!light->use_diffuse) { | if (!light->use_diffuse) { | ||||
| shader_id |= SHADER_EXCLUDE_DIFFUSE; | shader_id |= SHADER_EXCLUDE_DIFFUSE; | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | else if (light->light_type == LIGHT_DISTANT) { | ||||
| klights[light_index].co[1] = dir.y; | klights[light_index].co[1] = dir.y; | ||||
| klights[light_index].co[2] = dir.z; | klights[light_index].co[2] = dir.z; | ||||
| klights[light_index].distant.invarea = invarea; | klights[light_index].distant.invarea = invarea; | ||||
| klights[light_index].distant.radius = radius; | klights[light_index].distant.radius = radius; | ||||
| klights[light_index].distant.cosangle = cosangle; | klights[light_index].distant.cosangle = cosangle; | ||||
| } | } | ||||
| else if (light->light_type == LIGHT_BACKGROUND) { | else if (light->light_type == LIGHT_BACKGROUND) { | ||||
| uint visibility = scene->background->get_visibility(); | uint visibility = scene->get_background()->get_visibility(); | ||||
| shader_id &= ~SHADER_AREA_LIGHT; | shader_id &= ~SHADER_AREA_LIGHT; | ||||
| shader_id |= SHADER_USE_MIS; | shader_id |= SHADER_USE_MIS; | ||||
| if (!(visibility & PATH_RAY_DIFFUSE)) { | if (!(visibility & PATH_RAY_DIFFUSE)) { | ||||
| shader_id |= SHADER_EXCLUDE_DIFFUSE; | shader_id |= SHADER_EXCLUDE_DIFFUSE; | ||||
| use_light_visibility = true; | use_light_visibility = true; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | foreach (Light *light, scene->get_lights()) { | ||||
| klights[light_index].itfm = transform_inverse(light->tfm); | klights[light_index].itfm = transform_inverse(light->tfm); | ||||
| light_index++; | light_index++; | ||||
| } | } | ||||
| /* TODO(sergey): Consider moving portals update to their own function | /* TODO(sergey): Consider moving portals update to their own function | ||||
| * keeping this one more manageable. | * keeping this one more manageable. | ||||
| */ | */ | ||||
| foreach (Light *light, scene->lights) { | foreach (Light *light, scene->get_lights()) { | ||||
| if (!light->is_portal) | if (!light->is_portal) | ||||
| continue; | continue; | ||||
| assert(light->light_type == LIGHT_AREA); | assert(light->light_type == LIGHT_AREA); | ||||
| float3 co = light->co; | float3 co = light->co; | ||||
| float3 axisu = light->axisu * (light->sizeu * light->size); | float3 axisu = light->axisu * (light->sizeu * light->size); | ||||
| float3 axisv = light->axisv * (light->sizev * light->size); | float3 axisv = light->axisv * (light->sizev * light->size); | ||||
| float area = len(axisu) * len(axisv); | float area = len(axisu) * len(axisv); | ||||
| Show All 36 Lines | void LightManager::device_update(Device *device, | ||||
| DeviceScene *dscene, | DeviceScene *dscene, | ||||
| Scene *scene, | Scene *scene, | ||||
| Progress &progress) | Progress &progress) | ||||
| { | { | ||||
| if (!need_update) | if (!need_update) | ||||
| return; | return; | ||||
| scoped_callback_timer timer([scene](double time) { | scoped_callback_timer timer([scene](double time) { | ||||
| if (scene->update_stats) { | if (scene->get_update_stats()) { | ||||
| scene->update_stats->light.times.add_entry({"device_update", time}); | scene->get_update_stats()->light.times.add_entry({"device_update", time}); | ||||
| } | } | ||||
| }); | }); | ||||
| VLOG(1) << "Total " << scene->lights.size() << " lights."; | VLOG(1) << "Total " << scene->get_lights().size() << " lights."; | ||||
| /* Detect which lights are enabled, also determins if we need to update the background. */ | /* Detect which lights are enabled, also determins if we need to update the background. */ | ||||
| test_enabled_lights(scene); | test_enabled_lights(scene); | ||||
| device_free(device, dscene, need_update_background); | device_free(device, dscene, need_update_background); | ||||
| use_light_visibility = false; | use_light_visibility = false; | ||||
| Show All 10 Lines | if (need_update_background) { | ||||
| if (progress.get_cancel()) | if (progress.get_cancel()) | ||||
| return; | return; | ||||
| } | } | ||||
| device_update_ies(dscene); | device_update_ies(dscene); | ||||
| if (progress.get_cancel()) | if (progress.get_cancel()) | ||||
| return; | return; | ||||
| scene->film->set_use_light_visibility(use_light_visibility); | scene->get_film()->set_use_light_visibility(use_light_visibility); | ||||
| need_update = false; | need_update = false; | ||||
| need_update_background = false; | need_update_background = false; | ||||
| } | } | ||||
| void LightManager::device_free(Device *, DeviceScene *dscene, const bool free_background) | void LightManager::device_free(Device *, DeviceScene *dscene, const bool free_background) | ||||
| { | { | ||||
| dscene->light_distribution.free(); | dscene->light_distribution.free(); | ||||
| ▲ Show 20 Lines • Show All 132 Lines • Show Last 20 Lines | |||||