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:
Diffstat (limited to 'intern/cycles/render')
-rw-r--r--intern/cycles/render/graph.cpp23
-rw-r--r--intern/cycles/render/light.cpp10
-rw-r--r--intern/cycles/render/light.h3
-rw-r--r--intern/cycles/render/mesh.cpp37
-rw-r--r--intern/cycles/render/mesh.h1
-rw-r--r--intern/cycles/render/nodes.h1
-rw-r--r--intern/cycles/render/object.cpp63
-rw-r--r--intern/cycles/render/object.h1
-rw-r--r--intern/cycles/render/osl.cpp22
-rw-r--r--intern/cycles/render/shader.cpp37
-rw-r--r--intern/cycles/render/shader.h2
-rw-r--r--intern/cycles/render/svm.cpp60
-rw-r--r--intern/cycles/render/svm.h1
13 files changed, 171 insertions, 90 deletions
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 6e795ef896a..57256ceecd3 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -856,27 +856,8 @@ void ShaderGraph::bump_from_displacement()
/* connect the bump out to the set normal in: */
connect(bump->output("Normal"), set_normal->input("Direction"));
- /* connect bump output to normal input nodes that aren't set yet. actually
- * this will only set the normal input to the geometry node that we created
- * and connected to all other normal inputs already. */
- foreach(ShaderNode *node, nodes) {
- /* Don't connect normal to the bump node we're coming from,
- * otherwise it'll be a cycle in graph.
- */
- if(node == bump) {
- continue;
- }
- foreach(ShaderInput *input, node->inputs) {
- if(!input->link && (input->flags() & SocketType::LINK_NORMAL))
- connect(set_normal->output("Normal"), input);
- }
- }
-
- /* for displacement bump, clear the normal input in case the above loop
- * connected the setnormal out to the bump normalin */
- ShaderInput *bump_normal_in = bump->input("Normal");
- if(bump_normal_in)
- bump_normal_in->link = NULL;
+ /* connect to output node */
+ connect(set_normal->output("Normal"), output()->input("Normal"));
/* finally, add the copied nodes to the graph. we can't do this earlier
* because we would create dependency cycles in the above loop */
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 4cd77f8c6e1..787e5cf07b2 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -177,6 +177,16 @@ LightManager::~LightManager()
{
}
+bool LightManager::has_background_light(Scene *scene)
+{
+ foreach(Light *light, scene->lights) {
+ if(light->type == LIGHT_BACKGROUND) {
+ return true;
+ }
+ }
+ return false;
+}
+
void LightManager::disable_ineffective_light(Device *device, Scene *scene)
{
/* Make all lights enabled by default, and perform some preliminary checks
diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h
index 745caa96159..040a672937d 100644
--- a/intern/cycles/render/light.h
+++ b/intern/cycles/render/light.h
@@ -91,6 +91,9 @@ public:
void tag_update(Scene *scene);
+ /* Check whether there is a background light. */
+ bool has_background_light(Scene *scene);
+
protected:
/* Optimization: disable light which is either unsupported or
* which doesn't contribute to the scene or which is only used for MIS
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 35d1a441975..2d297c33446 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -567,10 +567,11 @@ void Mesh::add_vertex_normals()
for(size_t i = 0; i < subd_faces.size(); i++) {
SubdFace& face = subd_faces[i];
+ float3 fN = face.normal(this);
for(size_t j = 0; j < face.num_corners; j++) {
size_t corner = subd_face_corners[face.start_corner+j];
- vN[corner] += verts[corner];
+ vN[corner] += fN;
}
}
@@ -583,6 +584,28 @@ void Mesh::add_vertex_normals()
}
}
+void Mesh::add_undisplaced()
+{
+ AttributeSet& attrs = (subdivision_type == SUBDIVISION_NONE) ? attributes : subd_attributes;
+
+ /* don't compute if already there */
+ if(attrs.find(ATTR_STD_POSITION_UNDISPLACED)) {
+ return;
+ }
+
+ /* get attribute */
+ Attribute *attr = attrs.add(ATTR_STD_POSITION_UNDISPLACED);
+ attr->flags |= ATTR_SUBDIVIDED;
+
+ float3 *data = attr->data_float3();
+
+ /* copy verts */
+ size_t size = attr->buffer_size(this, (subdivision_type == SUBDIVISION_NONE) ? ATTR_PRIM_TRIANGLE : ATTR_PRIM_SUBD);
+ if(size) {
+ memcpy(data, verts.data(), size);
+ }
+}
+
void Mesh::pack_normals(Scene *scene, uint *tri_shader, float4 *vnormal)
{
Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
@@ -609,7 +632,7 @@ void Mesh::pack_normals(Scene *scene, uint *tri_shader, float4 *vnormal)
last_smooth = smooth[i];
Shader *shader = (last_shader < used_shaders.size()) ?
used_shaders[last_shader] : scene->default_surface;
- shader_id = scene->shader_manager->get_shader_id(shader, this, last_smooth);
+ shader_id = scene->shader_manager->get_shader_id(shader, last_smooth);
}
tri_shader[i] = shader_id;
@@ -678,7 +701,7 @@ void Mesh::pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, s
int shader_id = curve_shader[i];
Shader *shader = (shader_id < used_shaders.size()) ?
used_shaders[shader_id] : scene->default_surface;
- shader_id = scene->shader_manager->get_shader_id(shader, this, false);
+ shader_id = scene->shader_manager->get_shader_id(shader, false);
curve_data[i] = make_float4(
__int_as_float(curve.first_key + curvekey_offset),
@@ -1627,10 +1650,10 @@ void MeshManager::device_update_displacement_images(Device *device,
foreach(Mesh *mesh, scene->meshes) {
if(mesh->need_update) {
foreach(Shader *shader, mesh->used_shaders) {
- if(shader->graph_bump == NULL) {
+ if(!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) {
continue;
}
- foreach(ShaderNode* node, shader->graph_bump->nodes) {
+ foreach(ShaderNode* node, shader->graph->nodes) {
if(node->special_type != SHADER_SPECIAL_TYPE_IMAGE_SLOT) {
continue;
}
@@ -1681,6 +1704,10 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
mesh->add_face_normals();
mesh->add_vertex_normals();
+ if(mesh->need_attribute(scene, ATTR_STD_POSITION_UNDISPLACED)) {
+ mesh->add_undisplaced();
+ }
+
if(progress.get_cancel()) return;
}
}
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index a77e296ea4a..c0310f45840 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -215,6 +215,7 @@ public:
void compute_bounds();
void add_face_normals();
void add_vertex_normals();
+ void add_undisplaced();
void pack_normals(Scene *scene, uint *shader, float4 *vnormal);
void pack_verts(const vector<uint>& tri_prim_index,
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index b0eb2395adf..fd349f4b7e8 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -770,6 +770,7 @@ class CameraNode : public ShaderNode {
public:
SHADER_NODE_CLASS(CameraNode)
bool has_spatial_varying() { return true; }
+ virtual int get_group() { return NODE_GROUP_LEVEL_2; }
};
class FresnelNode : public ShaderNode {
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index db44327e24c..d8f3ce58505 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -45,6 +45,7 @@ NODE_DEFINE(Object)
SOCKET_UINT(random_id, "Random ID", 0);
SOCKET_INT(pass_id, "Pass ID", 0);
SOCKET_BOOLEAN(use_holdout, "Use Holdout", false);
+ SOCKET_BOOLEAN(hide_on_missing_motion, "Hide on Missing Motion", false);
SOCKET_POINT(dupli_generated, "Dupli Generated", make_float3(0.0f, 0.0f, 0.0f));
SOCKET_POINT2(dupli_uv, "Dupli UV", make_float2(0.0f, 0.0f));
@@ -72,28 +73,41 @@ void Object::compute_bounds(bool motion_blur)
BoundBox mbounds = mesh->bounds;
if(motion_blur && use_motion) {
- if(motion.pre == transform_empty() ||
- motion.post == transform_empty()) {
+ MotionTransform mtfm = motion;
+
+ if(hide_on_missing_motion) {
/* Hide objects that have no valid previous or next transform, for
* example particle that stop existing. TODO: add support for this
* case in the kernel so we don't get render artifacts. */
- bounds = BoundBox::empty;
+ if(mtfm.pre == transform_empty() ||
+ mtfm.post == transform_empty()) {
+ bounds = BoundBox::empty;
+ return;
+ }
+ }
+
+ /* In case of missing motion information for previous/next frame,
+ * assume there is no motion. */
+ if(mtfm.pre == transform_empty()) {
+ mtfm.pre = tfm;
+ }
+ if(mtfm.post == transform_empty()) {
+ mtfm.post = tfm;
}
- else {
- DecompMotionTransform decomp;
- transform_motion_decompose(&decomp, &motion, &tfm);
- bounds = BoundBox::empty;
+ DecompMotionTransform decomp;
+ transform_motion_decompose(&decomp, &mtfm, &tfm);
- /* todo: this is really terrible. according to pbrt there is a better
- * way to find this iteratively, but did not find implementation yet
- * or try to implement myself */
- for(float t = 0.0f; t < 1.0f; t += (1.0f/128.0f)) {
- Transform ttfm;
+ bounds = BoundBox::empty;
- transform_motion_interpolate(&ttfm, &decomp, t);
- bounds.grow(mbounds.transformed(&ttfm));
- }
+ /* todo: this is really terrible. according to pbrt there is a better
+ * way to find this iteratively, but did not find implementation yet
+ * or try to implement myself */
+ for(float t = 0.0f; t < 1.0f; t += (1.0f/128.0f)) {
+ Transform ttfm;
+
+ transform_motion_interpolate(&ttfm, &decomp, t);
+ bounds.grow(mbounds.transformed(&ttfm));
}
}
else {
@@ -345,28 +359,27 @@ void ObjectManager::device_update_object_transform(UpdateObejctTransformState *s
* comes with deformed position in object space, or if we transform
* the shading point in world space.
*/
- Transform mtfm_pre = ob->motion.pre;
- Transform mtfm_post = ob->motion.post;
+ MotionTransform mtfm = ob->motion;
/* In case of missing motion information for previous/next frame,
* assume there is no motion. */
- if(!ob->use_motion || mtfm_pre == transform_empty()) {
- mtfm_pre = ob->tfm;
+ if(!ob->use_motion || mtfm.pre == transform_empty()) {
+ mtfm.pre = ob->tfm;
}
- if(!ob->use_motion || mtfm_post == transform_empty()) {
- mtfm_post = ob->tfm;
+ if(!ob->use_motion || mtfm.post == transform_empty()) {
+ mtfm.post = ob->tfm;
}
if(!mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) {
- mtfm_pre = mtfm_pre * itfm;
- mtfm_post = mtfm_post * itfm;
+ mtfm.pre = mtfm.pre * itfm;
+ mtfm.post = mtfm.post * itfm;
}
else {
flag |= SD_OBJECT_HAS_VERTEX_MOTION;
}
- memcpy(&objects_vector[object_index*OBJECT_VECTOR_SIZE+0], &mtfm_pre, sizeof(float4)*3);
- memcpy(&objects_vector[object_index*OBJECT_VECTOR_SIZE+3], &mtfm_post, sizeof(float4)*3);
+ memcpy(&objects_vector[object_index*OBJECT_VECTOR_SIZE+0], &mtfm.pre, sizeof(float4)*3);
+ memcpy(&objects_vector[object_index*OBJECT_VECTOR_SIZE+3], &mtfm.post, sizeof(float4)*3);
}
#ifdef __OBJECT_MOTION__
else if(state->need_motion == Scene::MOTION_BLUR) {
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index 2e5837f672f..7e306fab2a8 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -51,6 +51,7 @@ public:
uint visibility;
MotionTransform motion;
bool use_motion;
+ bool hide_on_missing_motion;
bool use_holdout;
float3 dupli_generated;
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index 1a6ae5f9277..f83aab47e84 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -609,7 +609,7 @@ bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input)
return true;
if(input->name() == "Displacement" && current_type != SHADER_TYPE_DISPLACEMENT)
return true;
- if(input->name() == "Normal")
+ if(input->name() == "Normal" && current_type != SHADER_TYPE_BUMP)
return true;
}
else if(node->special_type == SHADER_SPECIAL_TYPE_BUMP) {
@@ -684,6 +684,8 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
ss->Shader("surface", name, id(node).c_str());
else if(current_type == SHADER_TYPE_DISPLACEMENT)
ss->Shader("displacement", name, id(node).c_str());
+ else if(current_type == SHADER_TYPE_BUMP)
+ ss->Shader("displacement", name, id(node).c_str());
else
assert(0);
@@ -1055,6 +1057,12 @@ OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph
generate_nodes(dependencies);
output->compile(*this);
}
+ else if(type == SHADER_TYPE_BUMP) {
+ /* generate bump shader */
+ find_dependencies(dependencies, output->input("Normal"));
+ generate_nodes(dependencies);
+ output->compile(*this);
+ }
else if(type == SHADER_TYPE_VOLUME) {
/* generate volume shader */
find_dependencies(dependencies, output->input("Volume"));
@@ -1116,10 +1124,10 @@ void OSLCompiler::compile(Scene *scene, OSLGlobals *og, Shader *shader)
if(shader->used && graph && output->input("Surface")->link) {
shader->osl_surface_ref = compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
- if(shader->graph_bump)
- shader->osl_surface_bump_ref = compile_type(shader, shader->graph_bump, SHADER_TYPE_SURFACE);
+ if(shader->graph_bump && shader->displacement_method != DISPLACE_TRUE)
+ shader->osl_surface_bump_ref = compile_type(shader, shader->graph_bump, SHADER_TYPE_BUMP);
else
- shader->osl_surface_bump_ref = shader->osl_surface_ref;
+ shader->osl_surface_bump_ref = OSL::ShaderGroupRef();
shader->has_surface = true;
}
@@ -1147,13 +1155,9 @@ void OSLCompiler::compile(Scene *scene, OSLGlobals *og, Shader *shader)
/* push state to array for lookup */
og->surface_state.push_back(shader->osl_surface_ref);
- og->surface_state.push_back(shader->osl_surface_bump_ref);
-
- og->volume_state.push_back(shader->osl_volume_ref);
og->volume_state.push_back(shader->osl_volume_ref);
-
- og->displacement_state.push_back(shader->osl_displacement_ref);
og->displacement_state.push_back(shader->osl_displacement_ref);
+ og->bump_state.push_back(shader->osl_surface_bump_ref);
}
#else
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index d000cca5a45..70e1443be2c 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -221,6 +221,16 @@ void Shader::tag_update(Scene *scene)
if(use_mis && has_surface_emission)
scene->light_manager->need_update = true;
+ /* Special handle of background MIS light for now: for some reason it
+ * has use_mis set to false. We are quite close to release now, so
+ * better to be safe.
+ */
+ if(this == scene->default_background &&
+ scene->light_manager->has_background_light(scene))
+ {
+ scene->light_manager->need_update = true;
+ }
+
/* quick detection of which kind of shaders we have to avoid loading
* e.g. surface attributes when there is only a volume shader. this could
* be more fine grained but it's better than nothing */
@@ -240,6 +250,10 @@ void Shader::tag_update(Scene *scene)
attributes.clear();
foreach(ShaderNode *node, graph->nodes)
node->attributes(this, &attributes);
+
+ if(has_displacement && displacement_method == DISPLACE_BOTH) {
+ attributes.add(ATTR_STD_POSITION_UNDISPLACED);
+ }
/* compare if the attributes changed, mesh manager will check
* need_update_attributes, update the relevant meshes and clear it. */
@@ -312,14 +326,11 @@ uint ShaderManager::get_attribute_id(AttributeStandard std)
return (uint)std;
}
-int ShaderManager::get_shader_id(Shader *shader, Mesh *mesh, bool smooth)
+int ShaderManager::get_shader_id(Shader *shader, bool smooth)
{
/* get a shader id to pass to the kernel */
- int id = shader->id*2;
-
- /* index depends bump since this setting is not in the shader */
- if(mesh && shader->displacement_method != DISPLACE_TRUE)
- id += 1;
+ int id = shader->id;
+
/* smooth flag */
if(smooth)
id |= SHADER_SMOOTH_NORMAL;
@@ -368,7 +379,7 @@ void ShaderManager::device_update_common(Device *device,
if(scene->shaders.size() == 0)
return;
- uint shader_flag_size = scene->shaders.size()*4;
+ uint shader_flag_size = scene->shaders.size()*2;
uint *shader_flag = dscene->shader_flag.resize(shader_flag_size);
uint i = 0;
bool has_volumes = false;
@@ -406,15 +417,14 @@ void ShaderManager::device_update_common(Device *device,
flag |= SD_VOLUME_CUBIC;
if(shader->graph_bump)
flag |= SD_HAS_BUMP;
-
- /* regular shader */
- shader_flag[i++] = flag;
- shader_flag[i++] = shader->pass_id;
+ if(shader->displacement_method != DISPLACE_BUMP)
+ flag |= SD_HAS_DISPLACEMENT;
/* shader with bump mapping */
- if(shader->graph_bump)
+ if(shader->displacement_method != DISPLACE_TRUE && shader->graph_bump)
flag |= SD_HAS_BSSRDF_BUMP;
+ /* regular shader */
shader_flag[i++] = flag;
shader_flag[i++] = shader->pass_id;
@@ -551,6 +561,9 @@ void ShaderManager::get_requested_features(Scene *scene,
ShaderNode *output_node = shader->graph->output();
if(output_node->input("Displacement")->link != NULL) {
requested_features->nodes_features |= NODE_FEATURE_BUMP;
+ if(shader->displacement_method == DISPLACE_BOTH && requested_features->experimental) {
+ requested_features->nodes_features |= NODE_FEATURE_BUMP_STATE;
+ }
}
/* On top of volume nodes, also check if we need volume sampling because
* e.g. an Emission node would slip through the NODE_FEATURE_VOLUME check */
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index 060ad7056bc..696e22bc3c9 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -173,7 +173,7 @@ public:
uint get_attribute_id(AttributeStandard std);
/* get shader id for mesh faces */
- int get_shader_id(Shader *shader, Mesh *mesh = NULL, bool smooth = false);
+ int get_shader_id(Shader *shader, bool smooth = false);
/* add default shaders to scene, to use as default for things that don't
* have any shader assigned explicitly */
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index 1a166885e2b..352bed8f0f2 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -63,7 +63,6 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
for(i = 0; i < scene->shaders.size(); i++) {
svm_nodes.push_back(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
- svm_nodes.push_back(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
}
foreach(Shader *shader, scene->shaders) {
@@ -147,9 +146,8 @@ int SVMCompiler::stack_size(SocketType::Type type)
return size;
}
-int SVMCompiler::stack_find_offset(SocketType::Type type)
+int SVMCompiler::stack_find_offset(int size)
{
- int size = stack_size(type);
int offset = -1;
/* find free space in stack & mark as used */
@@ -176,6 +174,11 @@ int SVMCompiler::stack_find_offset(SocketType::Type type)
return 0;
}
+int SVMCompiler::stack_find_offset(SocketType::Type type)
+{
+ return stack_find_offset(stack_size(type));
+}
+
void SVMCompiler::stack_clear_offset(SocketType::Type type, int offset)
{
int size = stack_size(type);
@@ -648,6 +651,9 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
case SHADER_TYPE_DISPLACEMENT:
clin = node->input("Displacement");
break;
+ case SHADER_TYPE_BUMP:
+ clin = node->input("Normal");
+ break;
default:
assert(0);
break;
@@ -664,6 +670,14 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
output->stack_offset = SVM_STACK_INVALID;
}
+ /* for the bump shader we need add a node to store the shader state */
+ bool need_bump_state = (type == SHADER_TYPE_BUMP) && (shader->displacement_method == DISPLACE_BOTH);
+ int bump_state_offset = SVM_STACK_INVALID;
+ if(need_bump_state) {
+ bump_state_offset = stack_find_offset(SVM_BUMP_EVAL_STATE_SIZE);
+ add_node(NODE_ENTER_BUMP_EVAL, bump_state_offset);
+ }
+
if(shader->used) {
if(clin->link) {
bool generate = false;
@@ -681,6 +695,9 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
generate = true;
shader->has_displacement = true;
break;
+ case SHADER_TYPE_BUMP: /* generate bump shader */
+ generate = true;
+ break;
default:
break;
}
@@ -697,13 +714,21 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
node->compile(*this);
}
+ /* add node to restore state after bump shader has finished */
+ if(need_bump_state) {
+ add_node(NODE_LEAVE_BUMP_EVAL, bump_state_offset);
+ }
+
/* if compile failed, generate empty shader */
if(compile_failed) {
svm_nodes.clear();
compile_failed = false;
}
- add_node(NODE_END, 0, 0, 0);
+ /* for bump shaders we fall thru to the surface shader, but if this is any other kind of shader it ends here */
+ if(type != SHADER_TYPE_BUMP) {
+ add_node(NODE_END, 0, 0, 0);
+ }
}
void SVMCompiler::compile(Scene *scene,
@@ -753,19 +778,22 @@ void SVMCompiler::compile(Scene *scene,
shader->has_object_dependency = false;
shader->has_integrator_dependency = false;
+ /* generate bump shader */
+ if(shader->displacement_method != DISPLACE_TRUE && shader->graph_bump) {
+ scoped_timer timer((summary != NULL)? &summary->time_generate_bump: NULL);
+ compile_type(shader, shader->graph_bump, SHADER_TYPE_BUMP);
+ global_svm_nodes[index].y = global_svm_nodes.size();
+ global_svm_nodes.insert(global_svm_nodes.end(), svm_nodes.begin(), svm_nodes.end());
+ }
+
/* generate surface shader */
{
scoped_timer timer((summary != NULL)? &summary->time_generate_surface: NULL);
compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
- global_svm_nodes[index*2 + 0].y = global_svm_nodes.size();
- global_svm_nodes[index*2 + 1].y = global_svm_nodes.size();
- global_svm_nodes.insert(global_svm_nodes.end(), svm_nodes.begin(), svm_nodes.end());
- }
-
- if(shader->graph_bump) {
- scoped_timer timer((summary != NULL)? &summary->time_generate_bump: NULL);
- compile_type(shader, shader->graph_bump, SHADER_TYPE_SURFACE);
- global_svm_nodes[index*2 + 1].y = global_svm_nodes.size();
+ /* only set jump offset if there's no bump shader, as the bump shader will fall thru to this one if it exists */
+ if(shader->displacement_method == DISPLACE_TRUE || !shader->graph_bump) {
+ global_svm_nodes[index].y = global_svm_nodes.size();
+ }
global_svm_nodes.insert(global_svm_nodes.end(), svm_nodes.begin(), svm_nodes.end());
}
@@ -773,8 +801,7 @@ void SVMCompiler::compile(Scene *scene,
{
scoped_timer timer((summary != NULL)? &summary->time_generate_volume: NULL);
compile_type(shader, shader->graph, SHADER_TYPE_VOLUME);
- global_svm_nodes[index*2 + 0].z = global_svm_nodes.size();
- global_svm_nodes[index*2 + 1].z = global_svm_nodes.size();
+ global_svm_nodes[index].z = global_svm_nodes.size();
global_svm_nodes.insert(global_svm_nodes.end(), svm_nodes.begin(), svm_nodes.end());
}
@@ -782,8 +809,7 @@ void SVMCompiler::compile(Scene *scene,
{
scoped_timer timer((summary != NULL)? &summary->time_generate_displacement: NULL);
compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT);
- global_svm_nodes[index*2 + 0].w = global_svm_nodes.size();
- global_svm_nodes[index*2 + 1].w = global_svm_nodes.size();
+ global_svm_nodes[index].w = global_svm_nodes.size();
global_svm_nodes.insert(global_svm_nodes.end(), svm_nodes.begin(), svm_nodes.end());
}
diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h
index e14d57d7601..99e91ca0c3e 100644
--- a/intern/cycles/render/svm.h
+++ b/intern/cycles/render/svm.h
@@ -99,6 +99,7 @@ public:
int stack_assign(ShaderInput *input);
int stack_assign_if_linked(ShaderInput *input);
int stack_assign_if_linked(ShaderOutput *output);
+ int stack_find_offset(int size);
int stack_find_offset(SocketType::Type type);
void stack_clear_offset(SocketType::Type type, int offset);
void stack_link(ShaderInput *input, ShaderOutput *output);