diff options
Diffstat (limited to 'intern/cycles')
24 files changed, 202 insertions, 157 deletions
diff --git a/intern/cycles/blender/addon/presets.py b/intern/cycles/blender/addon/presets.py index dd4e8e60a42..17efb00abdb 100644 --- a/intern/cycles/blender/addon/presets.py +++ b/intern/cycles/blender/addon/presets.py @@ -67,6 +67,7 @@ class AddPresetSampling(AddPresetBase, Operator): "cycles.mesh_light_samples", "cycles.subsurface_samples", "cycles.volume_samples", + "cycles.use_square_samples", "cycles.progressive", "cycles.seed", "cycles.sample_clamp_direct", diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index cd71183acb6..a50da3634f3 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -172,6 +172,12 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): default='PATH', ) + cls.use_square_samples = BoolProperty( + name="Square Samples", + description="Square sampling values for easier artist control", + default=False, + ) + cls.samples = IntProperty( name="Samples", description="Number of samples to render for each pixel", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 5ae9466b40c..459d0d7d05e 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -101,6 +101,8 @@ def draw_samples_info(layout, context): # Calculate sample values if integrator == 'PATH': aa = cscene.samples + if cscene.use_square_samples: + aa = aa * aa else: aa = cscene.aa_samples d = cscene.diffuse_samples @@ -111,9 +113,19 @@ def draw_samples_info(layout, context): sss = cscene.subsurface_samples vol = cscene.volume_samples + if cscene.use_square_samples: + aa = aa * aa + d = d * d + g = g * g + t = t * t + ao = ao * ao + ml = ml * ml + sss = sss * sss + vol = vol * vol + # Draw interface # Do not draw for progressive, when Square Samples are disabled - if use_branched_path(context): + if use_branched_path(context) or (cscene.use_square_samples and integrator == 'PATH'): col = layout.column(align=True) col.scale_y = 0.6 col.label("Total Samples:") @@ -146,7 +158,7 @@ class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel): row = layout.row() sub = row.row() sub.prop(cscene, "progressive", text="") - sub.label() + row.prop(cscene, "use_square_samples") split = layout.split() diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py index a37ac38c101..efd794461d6 100644 --- a/intern/cycles/blender/addon/version_update.py +++ b/intern/cycles/blender/addon/version_update.py @@ -315,23 +315,3 @@ def do_versions(self): cscene.blur_glossy = 0.0 if not cscene.is_property_set("sample_clamp_indirect"): cscene.sample_clamp_indirect = 0.0 - - # Remove and apply square samples - use_square_samples = cscene.get("use_square_samples", False) - if use_square_samples: - del cscene["use_square_samples"] - - cscene.samples *= cscene.samples - cscene.preview_samples *= cscene.preview_samples - cscene.aa_samples *= cscene.aa_samples - cscene.preview_aa_samples *= cscene.preview_aa_samples - cscene.diffuse_samples *= cscene.diffuse_samples - cscene.glossy_samples *= cscene.glossy_samples - cscene.transmission_samples *= cscene.transmission_samples - cscene.ao_samples *= cscene.ao_samples - cscene.mesh_light_samples *= cscene.mesh_light_samples - cscene.subsurface_samples *= cscene.subsurface_samples - cscene.volume_samples *= cscene.volume_samples - - for layer in scene.render.layers: - layer.samples *= layer.samples diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 6b46402730e..991b834dcfa 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -163,11 +163,16 @@ void BlenderSync::sync_light(BL::Object& b_parent, light->shader = used_shaders[0]; /* shadow */ + PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); PointerRNA clamp = RNA_pointer_get(&b_lamp.ptr, "cycles"); light->cast_shadow = get_boolean(clamp, "cast_shadow"); light->use_mis = get_boolean(clamp, "use_multiple_importance_sampling"); - light->samples = get_int(clamp, "samples"); + int samples = get_int(clamp, "samples"); + if(get_boolean(cscene, "use_square_samples")) + light->samples = samples * samples; + else + light->samples = samples; light->max_bounces = get_int(clamp, "max_bounces"); @@ -195,6 +200,7 @@ void BlenderSync::sync_background_light(bool use_portal) BL::World b_world = b_scene.world(); if(b_world) { + PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles"); bool sample_as_light = get_boolean(cworld, "sample_as_light"); @@ -213,7 +219,11 @@ void BlenderSync::sync_background_light(bool use_portal) light->use_mis = sample_as_light; light->max_bounces = get_int(cworld, "max_bounces"); - light->samples = get_int(cworld, "samples"); + int samples = get_int(cworld, "samples"); + if(get_boolean(cscene, "use_square_samples")) + light->samples = samples * samples; + else + light->samples = samples; light->tag_update(scene); light_map.set_recalc(b_world); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 423f781dc17..19d8044cd4a 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -294,13 +294,32 @@ void BlenderSync::sync_integrator() integrator->sample_all_lights_indirect = get_boolean(cscene, "sample_all_lights_indirect"); integrator->light_sampling_threshold = get_float(cscene, "light_sampling_threshold"); - integrator->diffuse_samples = get_int(cscene, "diffuse_samples"); - integrator->glossy_samples = get_int(cscene, "glossy_samples"); - integrator->transmission_samples = get_int(cscene, "transmission_samples"); - integrator->ao_samples = get_int(cscene, "ao_samples"); - integrator->mesh_light_samples = get_int(cscene, "mesh_light_samples"); - integrator->subsurface_samples = get_int(cscene, "subsurface_samples"); - integrator->volume_samples = get_int(cscene, "volume_samples"); + int diffuse_samples = get_int(cscene, "diffuse_samples"); + int glossy_samples = get_int(cscene, "glossy_samples"); + int transmission_samples = get_int(cscene, "transmission_samples"); + int ao_samples = get_int(cscene, "ao_samples"); + int mesh_light_samples = get_int(cscene, "mesh_light_samples"); + int subsurface_samples = get_int(cscene, "subsurface_samples"); + int volume_samples = get_int(cscene, "volume_samples"); + + if(get_boolean(cscene, "use_square_samples")) { + integrator->diffuse_samples = diffuse_samples * diffuse_samples; + integrator->glossy_samples = glossy_samples * glossy_samples; + integrator->transmission_samples = transmission_samples * transmission_samples; + integrator->ao_samples = ao_samples * ao_samples; + integrator->mesh_light_samples = mesh_light_samples * mesh_light_samples; + integrator->subsurface_samples = subsurface_samples * subsurface_samples; + integrator->volume_samples = volume_samples * volume_samples; + } + else { + integrator->diffuse_samples = diffuse_samples; + integrator->glossy_samples = glossy_samples; + integrator->transmission_samples = transmission_samples; + integrator->ao_samples = ao_samples; + integrator->mesh_light_samples = mesh_light_samples; + integrator->subsurface_samples = subsurface_samples; + integrator->volume_samples = volume_samples; + } if(b_scene.render().use_simplify()) { if(preview) { @@ -400,7 +419,11 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D& b_v3d, const char *layer) render_layer.bound_samples = (use_layer_samples == 1); if(use_layer_samples != 2) { - render_layer.samples = b_rlay->samples(); + int samples = b_rlay->samples(); + if(get_boolean(cscene, "use_square_samples")) + render_layer.samples = samples * samples; + else + render_layer.samples = samples; } } @@ -715,6 +738,14 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine, int preview_samples = get_int(cscene, "preview_samples"); int preview_aa_samples = get_int(cscene, "preview_aa_samples"); + if(get_boolean(cscene, "use_square_samples")) { + aa_samples = aa_samples * aa_samples; + preview_aa_samples = preview_aa_samples * preview_aa_samples; + + samples = samples * samples; + preview_samples = preview_samples * preview_samples; + } + if(get_enum(cscene, "progressive") == 0) { if(background) { params.samples = aa_samples; diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index c68eba7bef6..f295f7e227c 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -2144,18 +2144,34 @@ Device *device_cuda_create(DeviceInfo& info, Stats &stats, bool background) return new CUDADevice(info, stats, background); } -void device_cuda_info(vector<DeviceInfo>& devices) +static CUresult device_cuda_safe_init() { - CUresult result; - int count = 0; +#ifdef _WIN32 + __try { + return cuInit(0); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + /* Ignore crashes inside the CUDA driver and hope we can + * survive even with corrupted CUDA installs. */ + fprintf(stderr, "Cycles CUDA: driver crashed, continuing without CUDA.\n"); + } + + return CUDA_ERROR_NO_DEVICE; +#else + return cuInit(0); +#endif +} - result = cuInit(0); +void device_cuda_info(vector<DeviceInfo>& devices) +{ + CUresult result = device_cuda_safe_init(); if(result != CUDA_SUCCESS) { if(result != CUDA_ERROR_NO_DEVICE) fprintf(stderr, "CUDA cuInit: %s\n", cuewErrorString(result)); return; } + int count = 0; result = cuDeviceGetCount(&count); if(result != CUDA_SUCCESS) { fprintf(stderr, "CUDA cuDeviceGetCount: %s\n", cuewErrorString(result)); @@ -2212,7 +2228,7 @@ void device_cuda_info(vector<DeviceInfo>& devices) string device_cuda_capabilities(void) { - CUresult result = cuInit(0); + CUresult result = device_cuda_safe_init(); if(result != CUDA_SUCCESS) { if(result != CUDA_ERROR_NO_DEVICE) { return string("Error initializing CUDA: ") + cuewErrorString(result); diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index aa380ec4b94..9d89decaaaf 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -73,8 +73,34 @@ bool device_opencl_init(void) return result; } + +static cl_int device_opencl_get_num_platforms_safe(cl_uint *num_platforms) +{ +#ifdef _WIN32 + __try { + return clGetPlatformIDs(0, NULL, num_platforms); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + /* Ignore crashes inside the OpenCL driver and hope we can + * survive even with corrupted OpenCL installs. */ + fprintf(stderr, "Cycles OpenCL: driver crashed, continuing without OpenCL.\n"); + } + + *num_platforms = 0; + return CL_DEVICE_NOT_FOUND; +#else + return clGetPlatformIDs(0, NULL, num_platforms); +#endif +} + void device_opencl_info(vector<DeviceInfo>& devices) { + cl_uint num_platforms = 0; + device_opencl_get_num_platforms_safe(&num_platforms); + if(num_platforms == 0) { + return; + } + vector<OpenCLPlatformDevice> usable_devices; OpenCLInfo::get_usable_devices(&usable_devices); /* Devices are numbered consecutively across platforms. */ @@ -113,7 +139,7 @@ string device_opencl_capabilities(void) * it could also be nicely reported to the console. */ cl_uint num_platforms = 0; - opencl_assert(clGetPlatformIDs(0, NULL, &num_platforms)); + opencl_assert(device_opencl_get_num_platforms_safe(&num_platforms)); if(num_platforms == 0) { return "No OpenCL platforms found\n"; } diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h index ea30ee9c139..d9b803cf692 100644 --- a/intern/cycles/kernel/kernel_bake.h +++ b/intern/cycles/kernel/kernel_bake.h @@ -342,8 +342,8 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, shader_eval_surface(kg, &sd, &state, 0.f, 0, SHADER_CONTEXT_MAIN); } - /* compression: normal = (2 * color) - 1 */ - out = sd.N * 0.5f + make_float3(0.5f, 0.5f, 0.5f); + /* encoding: normal = (2 * color) - 1 */ + out = shader_bsdf_average_normal(kg, &sd) * 0.5f + make_float3(0.5f, 0.5f, 0.5f); break; } case SHADER_EVAL_UV: diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h index de65e8ef27b..d454cce6e30 100644 --- a/intern/cycles/kernel/kernel_passes.h +++ b/intern/cycles/kernel/kernel_passes.h @@ -260,7 +260,7 @@ ccl_device_inline void kernel_write_data_passes(KernelGlobals *kg, ccl_global fl } if(flag & PASS_NORMAL) { - float3 normal = sd->N; + float3 normal = shader_bsdf_average_normal(kg, sd); kernel_write_pass_float3(buffer + kernel_data.film.pass_normal, sample, normal); } if(flag & PASS_UV) { diff --git a/intern/cycles/kernel/kernel_path_subsurface.h b/intern/cycles/kernel/kernel_path_subsurface.h index 5fce5ed59d2..9bccc9201e0 100644 --- a/intern/cycles/kernel/kernel_path_subsurface.h +++ b/intern/cycles/kernel/kernel_path_subsurface.h @@ -46,7 +46,7 @@ bool kernel_path_subsurface_scatter( */ kernel_assert(!ss_indirect->tracing); - uint lcg_state = lcg_state_init(state, 0x68bc21eb); + uint lcg_state = lcg_state_init_addrspace(state, 0x68bc21eb); SubsurfaceIntersection ss_isect; float bssrdf_u, bssrdf_v; diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h index 459333f9807..221d92f5de1 100644 --- a/intern/cycles/kernel/kernel_random.h +++ b/intern/cycles/kernel/kernel_random.h @@ -307,12 +307,19 @@ ccl_device_inline void path_state_branch(ccl_addr_space PathState *state, state->num_samples = state->num_samples*num_branches; } -ccl_device_inline uint lcg_state_init(ccl_addr_space PathState *state, +ccl_device_inline uint lcg_state_init(PathState *state, uint scramble) { return lcg_init(state->rng_hash + state->rng_offset + state->sample*scramble); } +ccl_device_inline uint lcg_state_init_addrspace(ccl_addr_space PathState *state, + uint scramble) +{ + return lcg_init(state->rng_hash + state->rng_offset + state->sample*scramble); +} + + ccl_device float lcg_step_float_addrspace(ccl_addr_space uint *rng) { /* Implicit mod 2^32 */ diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 01ba6d86f0b..a47766565a8 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -764,6 +764,19 @@ ccl_device float3 shader_bsdf_subsurface(KernelGlobals *kg, ShaderData *sd) return eval; } +ccl_device float3 shader_bsdf_average_normal(KernelGlobals *kg, ShaderData *sd) +{ + float3 N = make_float3(0.0f, 0.0f, 0.0f); + + for(int i = 0; i < sd->num_closure; i++) { + ShaderClosure *sc = &sd->closure[i]; + if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) + N += sc->N*average(sc->weight); + } + + return (is_zero(N))? sd->N : normalize(N); +} + ccl_device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_factor, float3 *N_) { float3 eval = make_float3(0.0f, 0.0f, 0.0f); @@ -783,12 +796,7 @@ ccl_device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_fac } } - if(is_zero(N)) - N = sd->N; - else - N = normalize(N); - - *N_ = N; + *N_ = (is_zero(N))? sd->N : normalize(N); return eval; } @@ -888,7 +896,7 @@ ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd, } if(sd->flag & SD_BSDF_NEEDS_LCG) { - sd->lcg_state = lcg_state_init(state, 0xb4bc3953); + sd->lcg_state = lcg_state_init_addrspace(state, 0xb4bc3953); } } diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 58371c56267..ce52ed4191c 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -878,7 +878,7 @@ enum ShaderDataFlag { SD_VOLUME_MIS = (1 << 23), /* Use cubic interpolation for voxels. */ SD_VOLUME_CUBIC = (1 << 24), - /* Has data connected to the displacement input. */ + /* Has data connected to the displacement input or uses bump map. */ SD_HAS_BUMP = (1 << 25), /* Has true displacement. */ SD_HAS_DISPLACEMENT = (1 << 26), diff --git a/intern/cycles/kernel/split/kernel_subsurface_scatter.h b/intern/cycles/kernel/split/kernel_subsurface_scatter.h index 76d198abc8a..a487e53df5c 100644 --- a/intern/cycles/kernel/split/kernel_subsurface_scatter.h +++ b/intern/cycles/kernel/split/kernel_subsurface_scatter.h @@ -51,8 +51,8 @@ ccl_device_noinline bool kernel_split_branched_path_subsurface_indirect_light_it if(branched_state->ss_next_sample == 0 && branched_state->next_hit == 0 && branched_state->next_closure == 0 && branched_state->next_sample == 0) { - branched_state->lcg_state = lcg_state_init(&branched_state->path_state, - 0x68bc21eb); + branched_state->lcg_state = lcg_state_init_addrspace(&branched_state->path_state, + 0x68bc21eb); } int num_samples = kernel_data.integrator.subsurface_samples; float num_samples_inv = 1.0f/num_samples; @@ -258,7 +258,7 @@ ccl_device void kernel_subsurface_scatter(KernelGlobals *kg) /* do bssrdf scatter step if we picked a bssrdf closure */ if(sc) { - uint lcg_state = lcg_state_init(state, 0x68bc21eb); + uint lcg_state = lcg_state_init_addrspace(state, 0x68bc21eb); float bssrdf_u, bssrdf_v; path_state_rng_2D(kg, state, diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 2d810ff664f..41e7e0205b0 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -221,28 +221,6 @@ OutputNode *ShaderGraph::output() return (OutputNode*)nodes.front(); } -ShaderGraph *ShaderGraph::copy() -{ - ShaderGraph *newgraph = new ShaderGraph(); - - /* copy nodes */ - ShaderNodeSet nodes_all; - foreach(ShaderNode *node, nodes) - nodes_all.insert(node); - - ShaderNodeMap nodes_copy; - copy_nodes(nodes_all, nodes_copy); - - /* add nodes (in same order, so output is still first) */ - newgraph->clear_nodes(); - foreach(ShaderNode *node, nodes) - newgraph->add(nodes_copy[node]); - - newgraph->simplified = simplified; - - return newgraph; -} - void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to) { assert(!finalized); diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h index 72e391991a7..f0fd789c6bd 100644 --- a/intern/cycles/render/graph.h +++ b/intern/cycles/render/graph.h @@ -151,6 +151,7 @@ public: virtual bool has_surface_emission() { return false; } virtual bool has_surface_transparent() { return false; } virtual bool has_surface_bssrdf() { return false; } + virtual bool has_bump() { return false; } virtual bool has_bssrdf_bump() { return false; } virtual bool has_spatial_varying() { return false; } virtual bool has_object_dependency() { return false; } @@ -245,8 +246,6 @@ public: ShaderGraph(); ~ShaderGraph(); - ShaderGraph *copy(); - ShaderNode *add(ShaderNode *node); OutputNode *output(); diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 90a68a06cb5..2b682756c6a 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1801,6 +1801,14 @@ BsdfBaseNode::BsdfBaseNode(const NodeType *node_type) special_type = SHADER_SPECIAL_TYPE_CLOSURE; } +bool BsdfBaseNode::has_bump() +{ + /* detect if anything is plugged into the normal input besides the default */ + ShaderInput *normal_in = input("Normal"); + return (normal_in && normal_in->link && + normal_in->link->parent->special_type != SHADER_SPECIAL_TYPE_GEOMETRY); +} + /* BSDF Closure */ BsdfNode::BsdfNode(const NodeType *node_type) @@ -2439,9 +2447,7 @@ void PrincipledBsdfNode::compile(OSLCompiler& compiler) bool PrincipledBsdfNode::has_bssrdf_bump() { - /* detect if anything is plugged into the normal input besides the default */ - ShaderInput *normal_in = input("Normal"); - return (normal_in->link && normal_in->link->parent->special_type != SHADER_SPECIAL_TYPE_GEOMETRY); + return has_surface_bssrdf() && has_bump(); } /* Translucent BSDF Closure */ diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index c0271a3c8eb..ec4c7c7c50d 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -326,6 +326,16 @@ class BsdfBaseNode : public ShaderNode { public: BsdfBaseNode(const NodeType *node_type); + bool has_spatial_varying() { return true; } + virtual ClosureType get_closure_type() { return closure; } + virtual bool has_bump(); + + virtual bool equals(const ShaderNode& /*other*/) + { + /* TODO(sergey): With some care BSDF nodes can be de-duplicated. */ + return false; + } + ClosureType closure; }; @@ -334,19 +344,11 @@ public: explicit BsdfNode(const NodeType *node_type); SHADER_NODE_BASE_CLASS(BsdfNode) - bool has_spatial_varying() { return true; } void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3 = NULL, ShaderInput *param4 = NULL); - virtual ClosureType get_closure_type() { return closure; } float3 color; float3 normal; float surface_mix_weight; - - virtual bool equals(const ShaderNode& /*other*/) - { - /* TODO(sergey): With some care BSDF nodes can be de-duplicated. */ - return false; - } }; class AnisotropicBsdfNode : public BsdfNode { @@ -373,7 +375,6 @@ class PrincipledBsdfNode : public BsdfBaseNode { public: SHADER_NODE_CLASS(PrincipledBsdfNode) - bool has_spatial_varying() { return true; } bool has_surface_bssrdf(); bool has_bssrdf_bump(); void compile(SVMCompiler& compiler, ShaderInput *metallic, ShaderInput *subsurface, ShaderInput *subsurface_radius, @@ -390,13 +391,6 @@ public: float surface_mix_weight; ClosureType distribution, distribution_orig; - virtual bool equals(const ShaderNode * /*other*/) - { - /* TODO(sergey): With some care BSDF nodes can be de-duplicated. */ - return false; - } - - ClosureType get_closure_type() { return closure; } bool has_integrator_dependency(); void attributes(Shader *shader, AttributeRequestSet *attributes); }; diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index c337079b09f..5c5ac6e2be9 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -721,6 +721,7 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath) current_shader->has_surface_bssrdf = true; current_shader->has_bssrdf_bump = true; /* can't detect yet */ } + current_shader->has_bump = true; /* can't detect yet */ } if(node->has_spatial_varying()) { @@ -1029,6 +1030,9 @@ void OSLCompiler::generate_nodes(const ShaderNodeSet& nodes) if(node->has_bssrdf_bump()) current_shader->has_bssrdf_bump = true; } + if(node->has_bump()) { + current_shader->has_bump = true; + } } else if(current_type == SHADER_TYPE_VOLUME) { if(node->has_spatial_varying()) @@ -1091,21 +1095,14 @@ void OSLCompiler::compile(Scene *scene, OSLGlobals *og, Shader *shader) ShaderGraph *graph = shader->graph; ShaderNode *output = (graph)? graph->output(): NULL; - /* copy graph for shader with bump mapping */ - if(output->input("Surface")->link && output->input("Displacement")->link) - if(!shader->graph_bump) - shader->graph_bump = shader->graph->copy(); + bool has_bump = (shader->displacement_method != DISPLACE_TRUE) && + output->input("Surface")->link && output->input("Displacement")->link; /* finalize */ shader->graph->finalize(scene, - false, - shader->has_integrator_dependency); - if(shader->graph_bump) { - shader->graph_bump->finalize(scene, - true, - shader->has_integrator_dependency, - shader->displacement_method == DISPLACE_BOTH); - } + has_bump, + shader->has_integrator_dependency, + shader->displacement_method == DISPLACE_BOTH); current_shader = shader; @@ -1113,7 +1110,8 @@ void OSLCompiler::compile(Scene *scene, OSLGlobals *og, Shader *shader) shader->has_surface_emission = false; shader->has_surface_transparent = false; shader->has_surface_bssrdf = false; - shader->has_bssrdf_bump = false; + shader->has_bump = has_bump; + shader->has_bssrdf_bump = has_bump; shader->has_volume = false; shader->has_displacement = false; shader->has_surface_spatial_varying = false; @@ -1125,8 +1123,8 @@ 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->displacement_method != DISPLACE_TRUE) - shader->osl_surface_bump_ref = compile_type(shader, shader->graph_bump, SHADER_TYPE_BUMP); + if(has_bump) + shader->osl_surface_bump_ref = compile_type(shader, shader->graph, SHADER_TYPE_BUMP); else shader->osl_surface_bump_ref = OSL::ShaderGroupRef(); diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 493e01de363..86378dfb495 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -177,7 +177,6 @@ Shader::Shader() pass_id = 0; graph = NULL; - graph_bump = NULL; has_surface = false; has_surface_transparent = false; @@ -185,6 +184,7 @@ Shader::Shader() has_surface_bssrdf = false; has_volume = false; has_displacement = false; + has_bump = false; has_bssrdf_bump = false; has_surface_spatial_varying = false; has_volume_spatial_varying = false; @@ -204,7 +204,6 @@ Shader::Shader() Shader::~Shader() { delete graph; - delete graph_bump; } bool Shader::is_constant_emission(float3 *emission) @@ -239,9 +238,7 @@ void Shader::set_graph(ShaderGraph *graph_) /* assign graph */ delete graph; - delete graph_bump; graph = graph_; - graph_bump = NULL; /* Store info here before graph optimization to make sure that * nodes that get optimized away still count. */ @@ -458,15 +455,11 @@ void ShaderManager::device_update_common(Device *device, flag |= SD_VOLUME_MIS; if(shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC) flag |= SD_VOLUME_CUBIC; - if(shader->graph_bump) + if(shader->has_bump) flag |= SD_HAS_BUMP; if(shader->displacement_method != DISPLACE_BUMP) flag |= SD_HAS_DISPLACEMENT; - /* shader with bump mapping */ - if(shader->displacement_method != DISPLACE_TRUE && shader->graph_bump) - flag |= SD_HAS_BSSRDF_BUMP; - /* constant emission check */ float3 constant_emission = make_float3(0.0f, 0.0f, 0.0f); if(shader->is_constant_emission(&constant_emission)) @@ -608,11 +601,6 @@ void ShaderManager::get_requested_features(Scene *scene, Shader *shader = scene->shaders[i]; /* Gather requested features from all the nodes from the graph nodes. */ get_requested_graph_features(shader->graph, requested_features); - /* Gather requested features from the graph itself. */ - if(shader->graph_bump) { - get_requested_graph_features(shader->graph_bump, - requested_features); - } ShaderNode *output_node = shader->graph->output(); if(output_node->input("Displacement")->link != NULL) { requested_features->nodes_features |= NODE_FEATURE_BUMP; diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index b6714b13247..79a67d6756a 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -89,11 +89,6 @@ public: /* shader graph */ ShaderGraph *graph; - /* shader graph with auto bump mapping included, we compile two shaders, - * with and without bump, because the displacement method is a mesh - * level setting, so we need to handle both */ - ShaderGraph *graph_bump; - /* sampling */ bool use_mis; bool use_transparent_shadow; @@ -121,6 +116,7 @@ public: bool has_volume; bool has_displacement; bool has_surface_bssrdf; + bool has_bump; bool has_bssrdf_bump; bool has_surface_spatial_varying; bool has_volume_spatial_varying; diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index 48287d872d4..32f89897970 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -521,6 +521,9 @@ void SVMCompiler::generate_closure_node(ShaderNode *node, if(node->has_bssrdf_bump()) current_shader->has_bssrdf_bump = true; } + if(node->has_bump()) { + current_shader->has_bump = true; + } } } @@ -799,29 +802,21 @@ void SVMCompiler::compile(Scene *scene, Summary *summary) { /* copy graph for shader with bump mapping */ - ShaderNode *node = shader->graph->output(); + ShaderNode *output = shader->graph->output(); int start_num_svm_nodes = svm_nodes.size(); const double time_start = time_dt(); - if(node->input("Surface")->link && node->input("Displacement")->link) - if(!shader->graph_bump) - shader->graph_bump = shader->graph->copy(); + bool has_bump = (shader->displacement_method != DISPLACE_TRUE) && + output->input("Surface")->link && output->input("Displacement")->link; /* finalize */ { scoped_timer timer((summary != NULL)? &summary->time_finalize: NULL); shader->graph->finalize(scene, - false, - shader->has_integrator_dependency); - } - - if(shader->graph_bump) { - scoped_timer timer((summary != NULL)? &summary->time_finalize_bump: NULL); - shader->graph_bump->finalize(scene, - true, - shader->has_integrator_dependency, - shader->displacement_method == DISPLACE_BOTH); + has_bump, + shader->has_integrator_dependency, + shader->displacement_method == DISPLACE_BOTH); } current_shader = shader; @@ -830,7 +825,8 @@ void SVMCompiler::compile(Scene *scene, shader->has_surface_emission = false; shader->has_surface_transparent = false; shader->has_surface_bssrdf = false; - shader->has_bssrdf_bump = false; + shader->has_bump = has_bump; + shader->has_bssrdf_bump = has_bump; shader->has_volume = false; shader->has_displacement = false; shader->has_surface_spatial_varying = false; @@ -839,9 +835,9 @@ void SVMCompiler::compile(Scene *scene, shader->has_integrator_dependency = false; /* generate bump shader */ - if(shader->displacement_method != DISPLACE_TRUE && shader->graph_bump) { + if(has_bump) { scoped_timer timer((summary != NULL)? &summary->time_generate_bump: NULL); - compile_type(shader, shader->graph_bump, SHADER_TYPE_BUMP); + compile_type(shader, shader->graph, SHADER_TYPE_BUMP); svm_nodes[index].y = svm_nodes.size(); svm_nodes.insert(svm_nodes.end(), current_svm_nodes.begin(), @@ -853,7 +849,7 @@ void SVMCompiler::compile(Scene *scene, scoped_timer timer((summary != NULL)? &summary->time_generate_surface: NULL); compile_type(shader, shader->graph, SHADER_TYPE_SURFACE); /* 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) { + if(!has_bump) { svm_nodes[index].y = svm_nodes.size(); } svm_nodes.insert(svm_nodes.end(), @@ -895,7 +891,6 @@ SVMCompiler::Summary::Summary() : num_svm_nodes(0), peak_stack_usage(0), time_finalize(0.0), - time_finalize_bump(0.0), time_generate_surface(0.0), time_generate_bump(0.0), time_generate_volume(0.0), @@ -911,10 +906,7 @@ string SVMCompiler::Summary::full_report() const report += string_printf("Peak stack usage: %d\n", peak_stack_usage); report += string_printf("Time (in seconds):\n"); - report += string_printf(" Finalize: %f\n", time_finalize); - report += string_printf(" Bump finalize: %f\n", time_finalize_bump); - report += string_printf("Finalize: %f\n", time_finalize + - time_finalize_bump); + report += string_printf("Finalize: %f\n", time_finalize); report += string_printf(" Surface: %f\n", time_generate_surface); report += string_printf(" Bump: %f\n", time_generate_bump); report += string_printf(" Volume: %f\n", time_generate_volume); diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h index abbd9e50610..98ef5fa05d8 100644 --- a/intern/cycles/render/svm.h +++ b/intern/cycles/render/svm.h @@ -74,9 +74,6 @@ public: /* Time spent on surface graph finalization. */ double time_finalize; - /* Time spent on bump graph finalization. */ - double time_finalize_bump; - /* Time spent on generating SVM nodes for surface shader. */ double time_generate_surface; |