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')
-rw-r--r--intern/cycles/render/integrator.cpp38
-rw-r--r--intern/cycles/render/integrator.h10
-rw-r--r--intern/cycles/render/light.cpp69
-rw-r--r--intern/cycles/render/light.h1
-rw-r--r--intern/cycles/render/scene.cpp2
5 files changed, 74 insertions, 46 deletions
diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp
index b26ebfd91e1..da563c9c4ec 100644
--- a/intern/cycles/render/integrator.cpp
+++ b/intern/cycles/render/integrator.cpp
@@ -18,9 +18,11 @@
#include "device.h"
#include "integrator.h"
+#include "light.h"
#include "scene.h"
#include "sobol.h"
+#include "util_foreach.h"
#include "util_hash.h"
CCL_NAMESPACE_BEGIN
@@ -47,6 +49,13 @@ Integrator::Integrator()
sample_clamp = 0.0f;
motion_blur = false;
+ diffuse_samples = 1;
+ glossy_samples = 1;
+ transmission_samples = 1;
+ ao_samples = 1;
+ mesh_light_samples = 1;
+ progressive = true;
+
need_update = true;
}
@@ -54,7 +63,7 @@ Integrator::~Integrator()
{
}
-void Integrator::device_update(Device *device, DeviceScene *dscene)
+void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene)
{
if(!need_update)
return;
@@ -93,8 +102,27 @@ void Integrator::device_update(Device *device, DeviceScene *dscene)
kintegrator->sample_clamp = (sample_clamp == 0.0f)? FLT_MAX: sample_clamp*3.0f;
+ kintegrator->progressive = progressive;
+ kintegrator->diffuse_samples = diffuse_samples;
+ kintegrator->glossy_samples = glossy_samples;
+ kintegrator->transmission_samples = transmission_samples;
+ kintegrator->ao_samples = ao_samples;
+ kintegrator->mesh_light_samples = mesh_light_samples;
+
/* sobol directions table */
- int dimensions = PRNG_BASE_NUM + (max_bounce + transparent_max_bounce + 2)*PRNG_BOUNCE_NUM;
+ int max_samples = 1;
+
+ if(!progressive) {
+ foreach(Light *light, scene->lights)
+ max_samples = max(max_samples, light->samples);
+
+ max_samples = max(max_samples, max(diffuse_samples, max(glossy_samples, transmission_samples)));
+ max_samples = max(max_samples, max(ao_samples, mesh_light_samples));
+ }
+
+ max_samples *= (max_bounce + transparent_max_bounce + 2);
+
+ int dimensions = PRNG_BASE_NUM + max_samples*PRNG_BOUNCE_NUM;
uint *directions = dscene->sobol_directions.resize(SOBOL_BITS*dimensions);
sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions);
@@ -127,6 +155,12 @@ bool Integrator::modified(const Integrator& integrator)
layer_flag == integrator.layer_flag &&
seed == integrator.seed &&
sample_clamp == integrator.sample_clamp &&
+ progressive == integrator.progressive &&
+ diffuse_samples == integrator.diffuse_samples &&
+ glossy_samples == integrator.glossy_samples &&
+ transmission_samples == integrator.transmission_samples &&
+ ao_samples == integrator.ao_samples &&
+ mesh_light_samples == integrator.mesh_light_samples &&
motion_blur == integrator.motion_blur);
}
diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h
index afda41a857d..8fb341182b7 100644
--- a/intern/cycles/render/integrator.h
+++ b/intern/cycles/render/integrator.h
@@ -49,12 +49,20 @@ public:
float sample_clamp;
bool motion_blur;
+ int diffuse_samples;
+ int glossy_samples;
+ int transmission_samples;
+ int ao_samples;
+ int mesh_light_samples;
+
+ bool progressive;
+
bool need_update;
Integrator();
~Integrator();
- void device_update(Device *device, DeviceScene *dscene);
+ void device_update(Device *device, DeviceScene *dscene, Scene *scene);
void device_free(Device *device, DeviceScene *dscene);
bool modified(const Integrator& integrator);
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index e918de990c2..6c03d0859a7 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -17,6 +17,7 @@
*/
#include "device.h"
+#include "integrator.h"
#include "light.h"
#include "mesh.h"
#include "object.h"
@@ -114,6 +115,7 @@ Light::Light()
cast_shadow = true;
shader = 0;
+ samples = 1;
}
void Light::tag_update(Scene *scene)
@@ -136,9 +138,6 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
{
progress.set_status("Updating Lights", "Computing distribution");
- /* option to always sample all point lights */
- bool multi_light = false;
-
/* count */
size_t num_lights = scene->lights.size();
size_t num_triangles = 0;
@@ -169,9 +168,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
}
size_t num_distribution = num_triangles;
-
- if(!multi_light)
- num_distribution += num_lights;
+ num_distribution += num_lights;
/* emission area */
float4 *distribution = dscene->light_distribution.resize(num_distribution + 1);
@@ -231,16 +228,14 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
float trianglearea = totarea;
/* point lights */
- if(!multi_light) {
- float lightarea = (totarea > 0.0f)? totarea/scene->lights.size(): 1.0f;
-
- for(int i = 0; i < scene->lights.size(); i++, offset++) {
- distribution[offset].x = totarea;
- distribution[offset].y = __int_as_float(~(int)i);
- distribution[offset].z = 1.0f;
- distribution[offset].w = scene->lights[i]->size;
- totarea += lightarea;
- }
+ float lightarea = (totarea > 0.0f)? totarea/scene->lights.size(): 1.0f;
+
+ for(int i = 0; i < scene->lights.size(); i++, offset++) {
+ distribution[offset].x = totarea;
+ distribution[offset].y = __int_as_float(~(int)i);
+ distribution[offset].z = 1.0f;
+ distribution[offset].w = scene->lights[i]->size;
+ totarea += lightarea;
}
/* normalize cumulative distribution functions */
@@ -259,7 +254,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* update device */
KernelIntegrator *kintegrator = &dscene->data.integrator;
- kintegrator->use_direct_light = (totarea > 0.0f) || (multi_light && num_lights);
+ kintegrator->use_direct_light = (totarea > 0.0f);
if(kintegrator->use_direct_light) {
/* number of emissives */
@@ -269,30 +264,19 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
kintegrator->pdf_triangles = 0.0f;
kintegrator->pdf_lights = 0.0f;
- if(multi_light) {
- /* sample one of all triangles and all lights */
- kintegrator->num_all_lights = num_lights;
+ /* sample one, with 0.5 probability of light or triangle */
+ kintegrator->num_all_lights = num_lights;
- if(trianglearea > 0.0f)
- kintegrator->pdf_triangles = 1.0f/trianglearea;
+ if(trianglearea > 0.0f) {
+ kintegrator->pdf_triangles = 1.0f/trianglearea;
if(num_lights)
- kintegrator->pdf_lights = 1.0f;
+ kintegrator->pdf_triangles *= 0.5f;
}
- else {
- /* sample one, with 0.5 probability of light or triangle */
- kintegrator->num_all_lights = 0;
-
- if(trianglearea > 0.0f) {
- kintegrator->pdf_triangles = 1.0f/trianglearea;
- if(num_lights)
- kintegrator->pdf_triangles *= 0.5f;
- }
- if(num_lights) {
- kintegrator->pdf_lights = 1.0f/num_lights;
- if(trianglearea > 0.0f)
- kintegrator->pdf_lights *= 0.5f;
- }
+ if(num_lights) {
+ kintegrator->pdf_lights = 1.0f/num_lights;
+ if(trianglearea > 0.0f)
+ kintegrator->pdf_lights *= 0.5f;
}
/* CDF */
@@ -417,6 +401,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
float3 co = light->co;
float3 dir = normalize(light->dir);
int shader_id = scene->shader_manager->get_shader_id(scene->lights[i]->shader);
+ float samples = __int_as_float(light->samples);
if(!light->cast_shadow)
shader_id &= ~SHADER_CAST_SHADOW;
@@ -427,7 +412,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_DISTANT) {
shader_id &= ~SHADER_AREA_LIGHT;
@@ -435,7 +420,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), dir.x, dir.y, dir.z);
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_BACKGROUND) {
shader_id &= ~SHADER_AREA_LIGHT;
@@ -443,7 +428,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), 0.0f, 0.0f, 0.0f);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
else if(light->type == LIGHT_AREA) {
float3 axisu = light->axisu*(light->sizeu*light->size);
@@ -452,7 +437,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), axisu.x, axisu.y, axisu.z);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, axisv.x, axisv.y, axisv.z);
- light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, dir.x, dir.y, dir.z);
+ light_data[i*LIGHT_SIZE + 3] = make_float4(samples, dir.x, dir.y, dir.z);
}
else if(light->type == LIGHT_SPOT) {
shader_id &= ~SHADER_AREA_LIGHT;
@@ -463,7 +448,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, dir.x, dir.y);
light_data[i*LIGHT_SIZE + 2] = make_float4(dir.z, spot_angle, spot_smooth, 0.0f);
- light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
+ light_data[i*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f);
}
}
diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h
index fb8684fa59b..3cedde2596e 100644
--- a/intern/cycles/render/light.h
+++ b/intern/cycles/render/light.h
@@ -54,6 +54,7 @@ public:
bool cast_shadow;
int shader;
+ int samples;
void tag_update(Scene *scene);
};
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index a5f90bfe34b..45c8a05c27d 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -160,7 +160,7 @@ void Scene::device_update(Device *device_, Progress& progress)
if(progress.get_cancel()) return;
progress.set_status("Updating Integrator");
- integrator->device_update(device, &dscene);
+ integrator->device_update(device, &dscene, this);
if(progress.get_cancel()) return;