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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2013-01-30 19:57:15 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2013-01-30 19:57:15 +0400
commitdc0f4b56183cd81b6ba4653d281f6b8ec236a574 (patch)
tree96bb9e62d6e78e224d3de22a5ef18a7f72c67853 /intern/cycles/render/light.cpp
parent4c971d572785c63a4c715210308664941c5c8f26 (diff)
Cycles: make multiple importance sampling for lamps an option per lamp now,
disabled by default for backwards compatibility. http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Integrator
Diffstat (limited to 'intern/cycles/render/light.cpp')
-rw-r--r--intern/cycles/render/light.cpp28
1 files changed, 26 insertions, 2 deletions
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 04fea1953e7..e7fb9514371 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -115,6 +115,8 @@ Light::Light()
spot_smooth = 0.0f;
cast_shadow = true;
+ use_mis = false;
+
shader = 0;
samples = 1;
}
@@ -291,13 +293,19 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
/* point lights */
float lightarea = (totarea > 0.0f)? totarea/scene->lights.size(): 1.0f;
+ bool use_lamp_mis = false;
for(int i = 0; i < scene->lights.size(); i++, offset++) {
+ Light *light = scene->lights[i];
+
distribution[offset].x = totarea;
distribution[offset].y = __int_as_float(~(int)i);
distribution[offset].z = 1.0f;
- distribution[offset].w = scene->lights[i]->size;
+ distribution[offset].w = light->size;
totarea += lightarea;
+
+ if(light->size > 0.0f && light->use_mis)
+ use_lamp_mis = true;
}
/* normalize cumulative distribution functions */
@@ -344,6 +352,8 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
kintegrator->inv_pdf_lights = 1.0f/kintegrator->pdf_lights;
}
+ kintegrator->use_lamp_mis = use_lamp_mis;
+
/* CDF */
device->tex_alloc("__light_distribution", dscene->light_distribution);
}
@@ -355,6 +365,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
kintegrator->pdf_triangles = 0.0f;
kintegrator->pdf_lights = 0.0f;
kintegrator->inv_pdf_lights = 0.0f;
+ kintegrator->use_lamp_mis = false;
}
}
@@ -484,6 +495,9 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
float radius = light->size;
float invarea = (radius > 0.0f)? 1.0f/(M_PI_F*radius*radius): 1.0f;
+ if(light->use_mis && radius > 0.0f)
+ shader_id |= SHADER_USE_MIS;
+
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), radius, invarea, 0.0f);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
@@ -498,6 +512,9 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
float area = M_PI_F*radius*radius;
float invarea = (area > 0.0f)? 1.0f/area: 1.0f;
+ if(light->use_mis && area > 0.0f)
+ shader_id |= SHADER_USE_MIS;
+
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), radius, cosangle, invarea);
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
@@ -505,6 +522,7 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
}
else if(light->type == LIGHT_BACKGROUND) {
shader_id &= ~SHADER_AREA_LIGHT;
+ shader_id |= SHADER_USE_MIS;
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);
@@ -515,7 +533,10 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
float3 axisu = light->axisu*(light->sizeu*light->size);
float3 axisv = light->axisv*(light->sizev*light->size);
float area = len(axisu)*len(axisv);
- float invarea = (area > 0.0f)? 1.0f/area: 0.0f;
+ float invarea = (area > 0.0f)? 1.0f/area: 1.0f;
+
+ if(light->use_mis && area > 0.0f)
+ shader_id |= SHADER_USE_MIS;
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);
@@ -530,6 +551,9 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
float spot_angle = cosf(light->spot_angle*0.5f);
float spot_smooth = (1.0f - spot_angle)*light->spot_smooth;
+ if(light->use_mis && radius > 0.0f)
+ shader_id |= SHADER_USE_MIS;
+
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), radius, invarea, spot_angle);
light_data[i*LIGHT_SIZE + 2] = make_float4(spot_smooth, dir.x, dir.y, dir.z);