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:
Diffstat (limited to 'intern/cycles/render/light.cpp')
-rw-r--r--intern/cycles/render/light.cpp204
1 files changed, 106 insertions, 98 deletions
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 9ef35820254..4cd77f8c6e1 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -209,57 +209,73 @@ void LightManager::disable_ineffective_light(Device *device, Scene *scene)
}
}
+bool LightManager::object_usable_as_light(Object *object) {
+ Mesh *mesh = object->mesh;
+ /* Skip if we are not visible for BSDFs. */
+ if(!(object->visibility & (PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY|PATH_RAY_TRANSMIT))) {
+ return false;
+ }
+ /* Skip motion blurred deforming meshes, not supported yet. */
+ if(mesh->has_motion_blur()) {
+ return false;
+ }
+ /* Skip if we have no emission shaders. */
+ /* TODO(sergey): Ideally we want to avoid such duplicated loop, since it'll
+ * iterate all mesh shaders twice (when counting and when calculating
+ * triangle area.
+ */
+ foreach(const Shader *shader, mesh->used_shaders) {
+ if(shader->use_mis && shader->has_surface_emission) {
+ return true;
+ }
+ }
+ return false;
+}
+
void LightManager::device_update_distribution(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
progress.set_status("Updating Lights", "Computing distribution");
/* count */
size_t num_lights = 0;
+ size_t num_portals = 0;
size_t num_background_lights = 0;
size_t num_triangles = 0;
bool background_mis = false;
foreach(Light *light, scene->lights) {
- if(light->is_enabled)
+ if(light->is_enabled) {
num_lights++;
+ }
+ if(light->is_portal) {
+ num_portals++;
+ }
}
foreach(Object *object, scene->objects) {
- Mesh *mesh = object->mesh;
- bool have_emission = false;
-
- /* skip if we are not visible for BSDFs */
- if(!(object->visibility & (PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY|PATH_RAY_TRANSMIT)))
- continue;
+ if(progress.get_cancel()) return;
- /* skip motion blurred deforming meshes, not supported yet */
- if(mesh->has_motion_blur())
+ if(!object_usable_as_light(object)) {
continue;
-
- /* skip if we have no emission shaders */
- foreach(Shader *shader, mesh->used_shaders) {
- if(shader->use_mis && shader->has_surface_emission) {
- have_emission = true;
- break;
- }
}
+ /* Count triangles. */
+ Mesh *mesh = object->mesh;
+ size_t mesh_num_triangles = mesh->num_triangles();
+ for(size_t i = 0; i < mesh_num_triangles; i++) {
+ int shader_index = mesh->shader[i];
+ Shader *shader = (shader_index < mesh->used_shaders.size())
+ ? mesh->used_shaders[shader_index]
+ : scene->default_surface;
- /* count triangles */
- if(have_emission) {
- size_t mesh_num_triangles = mesh->num_triangles();
- for(size_t i = 0; i < mesh_num_triangles; i++) {
- int shader_index = mesh->shader[i];
- Shader *shader = (shader_index < mesh->used_shaders.size()) ?
- mesh->used_shaders[shader_index] : scene->default_surface;
-
- if(shader->use_mis && shader->has_surface_emission)
- num_triangles++;
+ if(shader->use_mis && shader->has_surface_emission) {
+ num_triangles++;
}
}
}
size_t num_distribution = num_triangles + num_lights;
+ VLOG(1) << "Total " << num_distribution << " of light distribution primitives.";
/* emission area */
float4 *distribution = dscene->light_distribution.resize(num_distribution + 1);
@@ -270,87 +286,68 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
int j = 0;
foreach(Object *object, scene->objects) {
- Mesh *mesh = object->mesh;
- bool have_emission = false;
+ if(progress.get_cancel()) return;
- /* skip if we are not visible for BSDFs */
- if(!(object->visibility & (PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY|PATH_RAY_TRANSMIT))) {
+ if(!object_usable_as_light(object)) {
j++;
continue;
}
+ /* Sum area. */
+ Mesh *mesh = object->mesh;
+ bool transform_applied = mesh->transform_applied;
+ Transform tfm = object->tfm;
+ int object_id = j;
+ int shader_flag = 0;
- /* skip motion blurred deforming meshes, not supported yet */
- if(mesh->has_motion_blur()) {
- j++;
- continue;
- }
+ if(transform_applied)
+ object_id = ~object_id;
- /* skip if we have no emission shaders */
- foreach(Shader *shader, mesh->used_shaders) {
- if(shader->use_mis && shader->has_surface_emission) {
- have_emission = true;
- break;
- }
+ if(!(object->visibility & PATH_RAY_DIFFUSE)) {
+ shader_flag |= SHADER_EXCLUDE_DIFFUSE;
+ use_light_visibility = true;
+ }
+ if(!(object->visibility & PATH_RAY_GLOSSY)) {
+ shader_flag |= SHADER_EXCLUDE_GLOSSY;
+ use_light_visibility = true;
+ }
+ if(!(object->visibility & PATH_RAY_TRANSMIT)) {
+ shader_flag |= SHADER_EXCLUDE_TRANSMIT;
+ use_light_visibility = true;
+ }
+ if(!(object->visibility & PATH_RAY_VOLUME_SCATTER)) {
+ shader_flag |= SHADER_EXCLUDE_SCATTER;
+ use_light_visibility = true;
}
- /* sum area */
- if(have_emission) {
- bool transform_applied = mesh->transform_applied;
- Transform tfm = object->tfm;
- int object_id = j;
- int shader_flag = 0;
-
- if(transform_applied)
- object_id = ~object_id;
+ size_t mesh_num_triangles = mesh->num_triangles();
+ for(size_t i = 0; i < mesh_num_triangles; i++) {
+ int shader_index = mesh->shader[i];
+ Shader *shader = (shader_index < mesh->used_shaders.size())
+ ? mesh->used_shaders[shader_index]
+ : scene->default_surface;
- if(!(object->visibility & PATH_RAY_DIFFUSE)) {
- shader_flag |= SHADER_EXCLUDE_DIFFUSE;
- use_light_visibility = true;
- }
- if(!(object->visibility & PATH_RAY_GLOSSY)) {
- shader_flag |= SHADER_EXCLUDE_GLOSSY;
- use_light_visibility = true;
- }
- if(!(object->visibility & PATH_RAY_TRANSMIT)) {
- shader_flag |= SHADER_EXCLUDE_TRANSMIT;
- use_light_visibility = true;
- }
- if(!(object->visibility & PATH_RAY_VOLUME_SCATTER)) {
- shader_flag |= SHADER_EXCLUDE_SCATTER;
- use_light_visibility = true;
- }
-
- size_t mesh_num_triangles = mesh->num_triangles();
- for(size_t i = 0; i < mesh_num_triangles; i++) {
- int shader_index = mesh->shader[i];
- Shader *shader = (shader_index < mesh->used_shaders.size()) ?
- mesh->used_shaders[shader_index] : scene->default_surface;
-
- if(shader->use_mis && shader->has_surface_emission) {
- distribution[offset].x = totarea;
- distribution[offset].y = __int_as_float(i + mesh->tri_offset);
- distribution[offset].z = __int_as_float(shader_flag);
- distribution[offset].w = __int_as_float(object_id);
- offset++;
-
- Mesh::Triangle t = mesh->get_triangle(i);
- float3 p1 = mesh->verts[t.v[0]];
- float3 p2 = mesh->verts[t.v[1]];
- float3 p3 = mesh->verts[t.v[2]];
-
- if(!transform_applied) {
- p1 = transform_point(&tfm, p1);
- p2 = transform_point(&tfm, p2);
- p3 = transform_point(&tfm, p3);
- }
-
- totarea += triangle_area(p1, p2, p3);
+ if(shader->use_mis && shader->has_surface_emission) {
+ distribution[offset].x = totarea;
+ distribution[offset].y = __int_as_float(i + mesh->tri_offset);
+ distribution[offset].z = __int_as_float(shader_flag);
+ distribution[offset].w = __int_as_float(object_id);
+ offset++;
+
+ Mesh::Triangle t = mesh->get_triangle(i);
+ float3 p1 = mesh->verts[t.v[0]];
+ float3 p2 = mesh->verts[t.v[1]];
+ float3 p3 = mesh->verts[t.v[2]];
+
+ if(!transform_applied) {
+ p1 = transform_point(&tfm, p1);
+ p2 = transform_point(&tfm, p2);
+ p3 = transform_point(&tfm, p3);
}
+
+ totarea += triangle_area(p1, p2, p3);
}
}
- if(progress.get_cancel()) return;
-
j++;
}
@@ -443,9 +440,9 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
device->tex_alloc("__light_distribution", dscene->light_distribution);
/* Portals */
- if(num_background_lights > 0 && light_index != scene->lights.size()) {
+ if(num_portals > 0) {
kintegrator->portal_offset = light_index;
- kintegrator->num_portals = scene->lights.size() - light_index;
+ kintegrator->num_portals = num_portals;
kintegrator->portal_pdf = background_mis? 0.5f: 1.0f;
}
else {
@@ -609,10 +606,21 @@ void LightManager::device_update_points(Device *device,
Scene *scene)
{
int num_scene_lights = scene->lights.size();
- if(num_scene_lights == 0)
+
+ int num_lights = 0;
+ foreach(Light *light, scene->lights) {
+ if(light->is_enabled || light->is_portal) {
+ num_lights++;
+ }
+ }
+
+ float4 *light_data = dscene->light_data.resize(num_lights*LIGHT_SIZE);
+
+ if(num_lights == 0) {
+ VLOG(1) << "No effective light, ignoring points update.";
return;
+ }
- float4 *light_data = dscene->light_data.resize(num_scene_lights*LIGHT_SIZE);
int light_index = 0;
foreach(Light *light, scene->lights) {