diff options
author | Lukas Stockner <lukas.stockner@freenet.de> | 2016-09-03 23:40:07 +0300 |
---|---|---|
committer | Lukas Stockner <lukas.stockner@freenet.de> | 2016-09-09 02:39:09 +0300 |
commit | 1558f5b6602ebe8ba31455b1837b2594d5c7f264 (patch) | |
tree | 7cc89f0098577099d916e4f3e27d2e2885444252 /intern/cycles/render/light.cpp | |
parent | 6de08f6cd1cb9e50736a0a43bf37d621c6eb2b87 (diff) |
Cycles: Don't run full shader evaluation for constant emission lamps
Most of the time, Lamps in Cycles are just a constant emission closure, no texturing etc. Therefore, running a full shader evaluation is wasteful.
To avoid that, Cycles now detects these constant emission shaders and stores their value in the lamp data along with a flag in the shader.
Then, at runtime, if this flag is set, the lamp code just uses this value and only runs the full shader evaluation if it is neccessary.
In scenes with a lot of lamps and with "Sample all direct/indirect" enabled, this saves up to 20% of rendering time in my tests.
Reviewers: #cycles
Differential Revision: https://developer.blender.org/D2193
Diffstat (limited to 'intern/cycles/render/light.cpp')
-rw-r--r-- | intern/cycles/render/light.cpp | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 787e5cf07b2..c833a8b1c46 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -664,6 +664,11 @@ void LightManager::device_update_points(Device *device, use_light_visibility = true; } + float3 fixed_emission = make_float3(0.0f, 0.0f, 0.0f); + if(shader->is_constant_emission(&fixed_emission)) { + shader_id |= SHADER_FIXED_EMISSION; + } + if(light->type == LIGHT_POINT) { shader_id &= ~SHADER_AREA_LIGHT; @@ -677,7 +682,6 @@ void LightManager::device_update_points(Device *device, light_data[light_index*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, 0.0f); light_data[light_index*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); light_data[light_index*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f); - light_data[light_index*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f); } else if(light->type == LIGHT_DISTANT) { shader_id &= ~SHADER_AREA_LIGHT; @@ -698,7 +702,6 @@ void LightManager::device_update_points(Device *device, light_data[light_index*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, cosangle, invarea); light_data[light_index*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); light_data[light_index*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f); - light_data[light_index*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f); } else if(light->type == LIGHT_BACKGROUND) { uint visibility = scene->background->visibility; @@ -727,7 +730,6 @@ void LightManager::device_update_points(Device *device, light_data[light_index*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), 0.0f, 0.0f, 0.0f); light_data[light_index*LIGHT_SIZE + 2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); light_data[light_index*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f); - light_data[light_index*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f); } else if(light->type == LIGHT_AREA) { float3 axisu = light->axisu*(light->sizeu*light->size); @@ -745,7 +747,6 @@ void LightManager::device_update_points(Device *device, light_data[light_index*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), axisu.x, axisu.y, axisu.z); light_data[light_index*LIGHT_SIZE + 2] = make_float4(invarea, axisv.x, axisv.y, axisv.z); light_data[light_index*LIGHT_SIZE + 3] = make_float4(samples, dir.x, dir.y, dir.z); - light_data[light_index*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f); } else if(light->type == LIGHT_SPOT) { shader_id &= ~SHADER_AREA_LIGHT; @@ -765,9 +766,10 @@ void LightManager::device_update_points(Device *device, light_data[light_index*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), radius, invarea, spot_angle); light_data[light_index*LIGHT_SIZE + 2] = make_float4(spot_smooth, dir.x, dir.y, dir.z); light_data[light_index*LIGHT_SIZE + 3] = make_float4(samples, 0.0f, 0.0f, 0.0f); - light_data[light_index*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f); } + light_data[light_index*LIGHT_SIZE + 4] = make_float4(max_bounces, fixed_emission.x, fixed_emission.y, fixed_emission.z); + light_index++; } |