diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-06-13 15:44:48 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-06-13 15:44:48 +0400 |
commit | 4ba456d1754c29b488b8304c8546af45078e8536 (patch) | |
tree | 49649b7442d58aa835a7428043130f158613521d /intern/cycles/render/light.cpp | |
parent | dcda234a3d93ed44189fac3716a694f4f75f366e (diff) |
Cycles: first step for implementation of non-progressive sampler that handles
direct and indirect lighting differently. Rather than picking one light for each
point on the path, it now loops over all lights for direct lighting. For indirect
lighting it still picks a random light each time.
It gives control over the number of AA samples, and the number of Diffuse, Glossy,
Transmission, AO, Mesh Light, Background and Lamp samples for each AA sample.
This helps tuning render performance/noise and tends to give less noise for renders
dominated by direct lighting.
This sampling mode only works on the CPU, and still needs proper tile rendering
to show progress (will follow tommorrow or so), because each AA sample can be quite
slow now and so the delay between each update wil be too long.
Diffstat (limited to 'intern/cycles/render/light.cpp')
-rw-r--r-- | intern/cycles/render/light.cpp | 69 |
1 files changed, 27 insertions, 42 deletions
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); } } |