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:
-rw-r--r--intern/cycles/kernel/kernel_emission.h6
-rw-r--r--intern/cycles/kernel/kernel_types.h3
-rw-r--r--intern/cycles/render/light.cpp12
-rw-r--r--intern/cycles/render/shader.cpp22
-rw-r--r--intern/cycles/render/shader.h4
5 files changed, 41 insertions, 6 deletions
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index 149ac3ed4f9..9fbcd9b371b 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -49,6 +49,12 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg,
}
else
#endif
+ if(ls->lamp != LAMP_NONE && (ls->shader & SHADER_FIXED_EMISSION))
+ {
+ float4 L = kernel_tex_fetch(__light_data, ls->lamp*LIGHT_SIZE + 4);
+ eval = make_float3(L.y, L.z, L.w);
+ }
+ else
{
shader_setup_from_sample(kg, emission_sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time);
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 0646148f6a0..5e2b0d6cc38 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -454,8 +454,9 @@ typedef enum ShaderFlag {
SHADER_EXCLUDE_CAMERA = (1 << 24),
SHADER_EXCLUDE_SCATTER = (1 << 23),
SHADER_EXCLUDE_ANY = (SHADER_EXCLUDE_DIFFUSE|SHADER_EXCLUDE_GLOSSY|SHADER_EXCLUDE_TRANSMIT|SHADER_EXCLUDE_CAMERA|SHADER_EXCLUDE_SCATTER),
+ SHADER_FIXED_EMISSION = (1 << 22),
- SHADER_MASK = ~(SHADER_SMOOTH_NORMAL|SHADER_CAST_SHADOW|SHADER_AREA_LIGHT|SHADER_USE_MIS|SHADER_EXCLUDE_ANY)
+ SHADER_MASK = ~(SHADER_SMOOTH_NORMAL|SHADER_CAST_SHADOW|SHADER_AREA_LIGHT|SHADER_USE_MIS|SHADER_EXCLUDE_ANY|SHADER_FIXED_EMISSION)
} ShaderFlag;
/* Light Type */
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++;
}
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 70e1443be2c..1849161ead9 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -194,6 +194,28 @@ Shader::~Shader()
delete graph_bump;
}
+bool Shader::is_constant_emission(float3 *emission)
+{
+ ShaderInput *surf = graph->output()->input("Surface");
+
+ if(!surf->link || surf->link->parent->type != EmissionNode::node_type) {
+ return false;
+ }
+
+ EmissionNode *node = (EmissionNode*) surf->link->parent;
+
+ assert(node->input("Color"));
+ assert(node->input("Strength"));
+
+ if(node->input("Color")->link || node->input("Strength")->link) {
+ return false;
+ }
+
+ *emission = node->color*node->strength;
+
+ return true;
+}
+
void Shader::set_graph(ShaderGraph *graph_)
{
/* do this here already so that we can detect if mesh or object attributes
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index 696e22bc3c9..7d896652196 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -139,6 +139,10 @@ public:
Shader();
~Shader();
+ /* Checks whether the shader consists of just a emission node with fixed inputs that's connected directly to the output.
+ * If yes, it sets the content of emission to the constant value (color * strength), which is then used for speeding up light evaluation. */
+ bool is_constant_emission(float3* emission);
+
void set_graph(ShaderGraph *graph);
void tag_update(Scene *scene);
void tag_used(Scene *scene);