Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2016-02-06 22:43:44 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-02-06 22:43:44 +0300
commitc502114ee11dcd2e737452944b652205517b5682 (patch)
tree4b59a9066954bc8851297c7ce38f647088b8e02c /intern/cycles/render
parentf25f7c803020b9341e49e898abe94917c3235515 (diff)
Cycles: Solve issues with auto-disabled MIS
There were two issues: 1. Memory leak: std:;erase does not call delete on the pointer (which is actually a good idea), 2. After MIS was disabled in viewport render there was no way to bring MIS back. Now instead of removing light from the scene data we kind of tagging it for an ignore. Possible cleanup would be to add Light::is_enabled and use that instead of passing weird and wonderful function arguments.
Diffstat (limited to 'intern/cycles/render')
-rw-r--r--intern/cycles/render/light.cpp99
-rw-r--r--intern/cycles/render/light.h13
2 files changed, 68 insertions, 44 deletions
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 4212cc5fb5f..fafc66ade06 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -161,6 +161,34 @@ LightManager::~LightManager()
{
}
+bool LightManager::skip_background_light(Device *device, Scene *scene)
+{
+ /* Check whether we've got portals. */
+ bool has_portal = false;
+ foreach(Light *light, scene->lights) {
+ if(light->is_portal) {
+ has_portal = true;
+ break;
+ }
+ }
+ /* Ignore background light if:
+ * - If unsupported on a device
+ * - If we don't need it (no HDRs etc.)
+ */
+ foreach(Light *light, scene->lights) {
+ if(light->type == LIGHT_BACKGROUND) {
+ Shader *shader = scene->shaders[scene->background->shader];
+ bool auto_disable_mis = (!has_portal && !shader->has_surface_spatial_varying);
+ if(!(device->info.advanced_shading) || auto_disable_mis) {
+ VLOG(1) << "Background MIS has been disabled.\n";
+ return true;
+ }
+ break;
+ }
+ }
+ return false;
+}
+
void LightManager::device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
progress.set_status("Updating Lights", "Computing distribution");
@@ -460,16 +488,22 @@ static void background_cdf(int start,
}
}
-void LightManager::device_update_background(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+void LightManager::device_update_background(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress& progress,
+ bool skip_background)
{
KernelIntegrator *kintegrator = &dscene->data.integrator;
Light *background_light = NULL;
/* find background light */
- foreach(Light *light, scene->lights) {
- if(light->type == LIGHT_BACKGROUND) {
- background_light = light;
- break;
+ if(!skip_background) {
+ foreach(Light *light, scene->lights) {
+ if(light->type == LIGHT_BACKGROUND) {
+ background_light = light;
+ break;
+ }
}
}
@@ -551,37 +585,16 @@ void LightManager::device_update_background(Device *device, DeviceScene *dscene,
device->tex_alloc("__light_background_conditional_cdf", dscene->light_background_conditional_cdf);
}
-void LightManager::device_update_points(Device *device, DeviceScene *dscene, Scene *scene)
+void LightManager::device_update_points(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ bool skip_background)
{
- if(scene->lights.size() == 0)
+ int num_scene_lights = scene->lights.size();
+ if(num_scene_lights == 0)
return;
- /* Do we have a portal? */
- bool has_portal = false;
- foreach(Light *light, scene->lights) {
- if(light->is_portal) {
- has_portal = true;
- break;
- }
- }
-
- /* Remove background light:
- * - If unsupported on a device
- * - If we don't need it (no HDRs etc.)
- */
- foreach(Light *light, scene->lights) {
- if(light->type == LIGHT_BACKGROUND) {
- Shader *shader = scene->shaders[scene->background->shader];
- bool auto_disable_mis = (!has_portal && !shader->has_surface_spatial_varying);
- if(!(device->info.advanced_shading) || auto_disable_mis) {
- VLOG(1) << "Background MIS has been disabled. \n";
- scene->lights.erase(std::remove(scene->lights.begin(), scene->lights.end(), light), scene->lights.end());
- }
- break;
- }
- }
-
- float4 *light_data = dscene->light_data.resize(scene->lights.size()*LIGHT_SIZE);
+ float4 *light_data = dscene->light_data.resize(num_scene_lights*LIGHT_SIZE);
int light_index = 0;
foreach(Light *light, scene->lights) {
@@ -651,6 +664,10 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[light_index*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_BACKGROUND) {
+ if(skip_background) {
+ continue;
+ }
+
uint visibility = scene->background->visibility;
shader_id &= ~SHADER_AREA_LIGHT;
@@ -747,15 +764,17 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_index++;
}
+ VLOG(1) << "Number of lights sent to the device: " << light_index;
+
VLOG(1) << "Number of lights without contribution: "
- << scene->lights.size() - light_index;
+ << num_scene_lights - light_index;
device->tex_alloc("__light_data", dscene->light_data);
}
void LightManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
- int lights_size = scene->lights.size();
+ VLOG(1) << "Total " << scene->lights.size() << " lights.";
if(!need_update)
return;
@@ -763,14 +782,15 @@ void LightManager::device_update(Device *device, DeviceScene *dscene, Scene *sce
device_free(device, dscene);
use_light_visibility = false;
+ bool skip_background = skip_background_light(device, scene);
- device_update_points(device, dscene, scene);
+ device_update_points(device, dscene, scene, skip_background);
if(progress.get_cancel()) return;
device_update_distribution(device, dscene, scene, progress);
if(progress.get_cancel()) return;
- device_update_background(device, dscene, scene, progress);
+ device_update_background(device, dscene, scene, progress, skip_background);
if(progress.get_cancel()) return;
if(use_light_visibility != scene->film->use_light_visibility) {
@@ -779,11 +799,6 @@ void LightManager::device_update(Device *device, DeviceScene *dscene, Scene *sce
}
need_update = false;
-
- if(lights_size != scene->lights.size())
- VLOG(1) << "Total " << scene->lights.size() << " lights (" << lights_size << " before optimization).";
- else
- VLOG(1) << "Total " << scene->lights.size() << " lights.";
}
void LightManager::device_free(Device *device, DeviceScene *dscene)
diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h
index afec3628dda..bba03e33a86 100644
--- a/intern/cycles/render/light.h
+++ b/intern/cycles/render/light.h
@@ -82,9 +82,18 @@ public:
void tag_update(Scene *scene);
protected:
- void device_update_points(Device *device, DeviceScene *dscene, Scene *scene);
+ bool skip_background_light(Device *device, Scene *scene);
+
+ void device_update_points(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ bool skip_background);
void device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
- void device_update_background(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
+ void device_update_background(Device *device,
+ DeviceScene *dscene,
+ Scene *scene,
+ Progress& progress,
+ bool skip_background);
};
CCL_NAMESPACE_END