From 9131adca9f748f794c18c71d36f830a961c218b4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 18 Jun 2013 09:36:00 +0000 Subject: Cycles: add "Transparent Shadow" option for materials, to disable them per material. --- intern/cycles/blender/addon/properties.py | 6 ++++++ intern/cycles/blender/addon/ui.py | 1 + intern/cycles/blender/blender_shader.cpp | 3 ++- intern/cycles/kernel/kernel_emission.h | 4 ++-- intern/cycles/kernel/kernel_shader.h | 2 +- intern/cycles/kernel/kernel_types.h | 4 ++-- intern/cycles/render/light.cpp | 12 ++++++------ intern/cycles/render/object.cpp | 2 +- intern/cycles/render/osl.cpp | 2 +- intern/cycles/render/shader.cpp | 13 +++++++------ intern/cycles/render/shader.h | 3 ++- intern/cycles/render/svm.cpp | 2 +- 12 files changed, 32 insertions(+), 22 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 0c6cf9f513a..b94dd32fad0 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -504,6 +504,12 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup): "objects that emit little light compared to other light sources", default=True, ) + cls.use_transparent_shadow = BoolProperty( + name="Transparent Shadows", + description="Use transparent shadows for this material if it contains a Transparent BSDF" + "disabling will render faster but not give accurate shadows", + default=True, + ) cls.homogeneous_volume = BoolProperty( name="Homogeneous Volume", description="When using volume rendering, assume volume has the same density everywhere, " diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index a30622a36ac..e9f8a4f0a8d 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -919,6 +919,7 @@ class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel): col = split.column() col.prop(mat, "pass_index") + col.prop(cmat, "use_transparent_shadow") layout.prop(cmat, "sample_as_light") diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index a9db10b21d7..923f9b1e726 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -860,7 +860,8 @@ void BlenderSync::sync_materials(bool update_all) /* settings */ PointerRNA cmat = RNA_pointer_get(&b_mat->ptr, "cycles"); - shader->sample_as_light = get_boolean(cmat, "sample_as_light"); + shader->use_mis = get_boolean(cmat, "sample_as_light"); + shader->use_transparent_shadow = get_boolean(cmat, "use_transparent_shadow"); shader->homogeneous_volume = get_boolean(cmat, "homogeneous_volume"); shader->set_graph(graph); diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index c430a40d814..77dc59d2691 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -168,9 +168,9 @@ __device_noinline float3 indirect_primitive_emission(KernelGlobals *kg, ShaderDa float3 L = shader_emissive_eval(kg, sd); #ifdef __HAIR__ - if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT) && (sd->segment == ~0)) { + if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) && (sd->segment == ~0)) { #else - if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_SAMPLE_AS_LIGHT)) { + if(!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS)) { #endif /* multiple importance sampling, get triangle light pdf, * and compute weight with respect to BSDF pdf */ diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 347c066962a..7e41ee35ae0 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -891,7 +891,7 @@ __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect) #endif int flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2); - return (flag & SD_HAS_SURFACE_TRANSPARENT) != 0; + return (flag & SD_HAS_TRANSPARENT_SHADOW) != 0; } #endif diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 6ae3b10595c..a9f1831fc7d 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -492,8 +492,8 @@ enum ShaderDataFlag { SD_CLOSURE_FLAGS = (SD_EMISSION|SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY|SD_BSSRDF|SD_HOLDOUT|SD_VOLUME|SD_AO), /* shader flags */ - SD_SAMPLE_AS_LIGHT = 512, /* direct light sample */ - SD_HAS_SURFACE_TRANSPARENT = 1024, /* has surface transparency */ + SD_USE_MIS = 512, /* direct light sample */ + SD_HAS_TRANSPARENT_SHADOW = 1024, /* has transparent shadow */ SD_HAS_VOLUME = 2048, /* has volume shader */ SD_HOMOGENEOUS_VOLUME = 4096, /* has homogeneous volume */ diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 1d48ae8f87d..2f92b957929 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -164,7 +164,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen foreach(uint sindex, mesh->used_shaders) { Shader *shader = scene->shaders[sindex]; - if(shader->sample_as_light && shader->has_surface_emission) { + if(shader->use_mis && shader->has_surface_emission) { have_emission = true; break; } @@ -175,7 +175,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen for(size_t i = 0; i < mesh->triangles.size(); i++) { Shader *shader = scene->shaders[mesh->shader[i]]; - if(shader->sample_as_light && shader->has_surface_emission) + if(shader->use_mis && shader->has_surface_emission) num_triangles++; } @@ -184,7 +184,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen foreach(Mesh::Curve& curve, mesh->curves) { Shader *shader = scene->shaders[curve.shader]; - if(shader->sample_as_light && shader->has_surface_emission) + if(shader->use_mis && shader->has_surface_emission) num_curve_segments += curve.num_segments(); #endif } @@ -215,7 +215,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen foreach(uint sindex, mesh->used_shaders) { Shader *shader = scene->shaders[sindex]; - if(shader->sample_as_light && shader->has_surface_emission) { + if(shader->use_mis && shader->has_surface_emission) { have_emission = true; break; } @@ -247,7 +247,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen for(size_t i = 0; i < mesh->triangles.size(); i++) { Shader *shader = scene->shaders[mesh->shader[i]]; - if(shader->sample_as_light && shader->has_surface_emission) { + if(shader->use_mis && shader->has_surface_emission) { distribution[offset].x = totarea; distribution[offset].y = __int_as_float(i + mesh->tri_offset); distribution[offset].z = __int_as_float(shader_id); @@ -277,7 +277,7 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen Shader *shader = scene->shaders[curve.shader]; int first_key = curve.first_key; - if(shader->sample_as_light && shader->has_surface_emission) { + if(shader->use_mis && shader->has_surface_emission) { for(int j = 0; j < curve.num_segments(); j++) { distribution[offset].x = totarea; distribution[offset].y = __int_as_float(i + mesh->curve_offset); // XXX fix kernel code diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 1a2780995e3..7931a51b99d 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -127,7 +127,7 @@ void Object::tag_update(Scene *scene) foreach(uint sindex, mesh->used_shaders) { Shader *shader = scene->shaders[sindex]; - if(shader->sample_as_light && shader->has_surface_emission) + if(shader->use_mis && shader->has_surface_emission) scene->light_manager->need_update = true; } } diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index 8efc6b553e0..52e4c697ba8 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -100,7 +100,7 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene compiler.background = (shader == scene->shaders[scene->default_background]); compiler.compile(og, shader); - if(shader->sample_as_light && shader->has_surface_emission) + if(shader->use_mis && shader->has_surface_emission) scene->light_manager->need_update = true; } diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index b061e869e2f..da6c3566f69 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -42,7 +42,8 @@ Shader::Shader() graph = NULL; graph_bump = NULL; - sample_as_light = true; + use_mis = true; + use_transparent_shadow = true; homogeneous_volume = false; has_surface = false; @@ -88,7 +89,7 @@ void Shader::tag_update(Scene *scene) /* if the shader previously was emissive, update light distribution, * if the new shader is emissive, a light manager update tag will be * done in the shader manager device update. */ - if(sample_as_light && has_surface_emission) + if(use_mis && has_surface_emission) scene->light_manager->need_update = true; /* get requested attributes. this could be optimized by pruning unused @@ -220,10 +221,10 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc foreach(Shader *shader, scene->shaders) { uint flag = 0; - if(shader->sample_as_light) - flag |= SD_SAMPLE_AS_LIGHT; - if(shader->has_surface_transparent) - flag |= SD_HAS_SURFACE_TRANSPARENT; + if(shader->use_mis) + flag |= SD_USE_MIS; + if(shader->has_surface_transparent && shader->use_transparent_shadow) + flag |= SD_HAS_TRANSPARENT_SHADOW; if(shader->has_volume) flag |= SD_HAS_VOLUME; if(shader->homogeneous_volume) diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index 2a9f1198467..8810017068b 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -62,7 +62,8 @@ public: ShaderGraph *graph_bump; /* sampling */ - bool sample_as_light; + bool use_mis; + bool use_transparent_shadow; bool homogeneous_volume; /* synchronization */ diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index f61f9ca0fe3..3e211a3ee24 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -74,7 +74,7 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene assert(shader->graph); - if(shader->sample_as_light && shader->has_surface_emission) + if(shader->use_mis && shader->has_surface_emission) scene->light_manager->need_update = true; SVMCompiler compiler(scene->shader_manager, scene->image_manager, -- cgit v1.2.3