Cycles: add "Transparent Shadow" option for materials, to disable them per material.

This commit is contained in:
Brecht Van Lommel 2013-06-18 09:36:00 +00:00
parent 943388183d
commit 9131adca9f
12 changed files with 32 additions and 22 deletions

@ -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, "

@ -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")

@ -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);

@ -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 */

@ -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

@ -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 */

@ -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

@ -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;
}
}

@ -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;
}

@ -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)

@ -62,7 +62,8 @@ public:
ShaderGraph *graph_bump;
/* sampling */
bool sample_as_light;
bool use_mis;
bool use_transparent_shadow;
bool homogeneous_volume;
/* synchronization */

@ -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,