diff options
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/graph.cpp | 23 | ||||
-rw-r--r-- | intern/cycles/render/light.cpp | 10 | ||||
-rw-r--r-- | intern/cycles/render/light.h | 3 | ||||
-rw-r--r-- | intern/cycles/render/mesh.cpp | 37 | ||||
-rw-r--r-- | intern/cycles/render/mesh.h | 1 | ||||
-rw-r--r-- | intern/cycles/render/nodes.h | 1 | ||||
-rw-r--r-- | intern/cycles/render/object.cpp | 63 | ||||
-rw-r--r-- | intern/cycles/render/object.h | 1 | ||||
-rw-r--r-- | intern/cycles/render/osl.cpp | 22 | ||||
-rw-r--r-- | intern/cycles/render/shader.cpp | 37 | ||||
-rw-r--r-- | intern/cycles/render/shader.h | 2 | ||||
-rw-r--r-- | intern/cycles/render/svm.cpp | 60 | ||||
-rw-r--r-- | intern/cycles/render/svm.h | 1 |
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); |