diff options
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/integrator.cpp | 38 | ||||
-rw-r--r-- | intern/cycles/render/integrator.h | 10 | ||||
-rw-r--r-- | intern/cycles/render/light.cpp | 69 | ||||
-rw-r--r-- | intern/cycles/render/light.h | 1 | ||||
-rw-r--r-- | intern/cycles/render/scene.cpp | 2 |
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; |