diff options
-rw-r--r-- | intern/cycles/blender/addon/properties.py | 13 | ||||
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 13 | ||||
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 9 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/bsdf.h | 13 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_accumulate.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_passes.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 6 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path_state.h | 16 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 14 | ||||
-rw-r--r-- | intern/cycles/render/background.cpp | 12 | ||||
-rw-r--r-- | intern/cycles/render/background.h | 3 |
11 files changed, 79 insertions, 24 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 263d90d6712..7410cc32342 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -413,9 +413,20 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): ) cls.film_transparent = BoolProperty( name="Transparent", - description="World background is transparent with premultiplied alpha", + description="World background is transparent, for compositing the render over another background", default=False, ) + cls.film_transparent_glass = BoolProperty( + name="Transparent Glass", + description="Render transmissive surfaces as transparent, for compositing glass over another background", + default=False, + ) + cls.film_transparent_roughness = FloatProperty( + name="Transparent Roughness Threshold", + description="For transparent transmission, keep surfaces with roughness above the threshold opaque", + min=0.0, max=1.0, + default=0.1, + ) # Really annoyingly, we have to keep it around for a few releases, # otherwise forward compatibility breaks in really bad manner: CRASH! diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 5bb0ea1c2dd..5d58ecc99eb 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -367,14 +367,21 @@ class CYCLES_RENDER_PT_film(CyclesButtonsPanel, Panel): col = split.column() col.prop(cscene, "film_exposure") - col.prop(cscene, "film_transparent") - - col = split.column() + col.separator() sub = col.column(align=True) sub.prop(cscene, "pixel_filter_type", text="") if cscene.pixel_filter_type != 'BOX': sub.prop(cscene, "filter_width", text="Width") + col = split.column() + col.prop(cscene, "film_transparent") + sub = col.row() + sub.prop(cscene, "film_transparent_glass", text="Transparent Glass") + sub.active = cscene.film_transparent + sub = col.row() + sub.prop(cscene, "film_transparent_roughness", text="Roughness Threshold") + sub.active = cscene.film_transparent and cscene.film_transparent_glass + class CYCLES_RENDER_PT_performance(CyclesButtonsPanel, Panel): bl_label = "Performance" diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index a90e0d3ddc4..67845bb5561 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -1333,6 +1333,15 @@ void BlenderSync::sync_world(bool update_all) else background->transparent = b_scene.render().alpha_mode() == BL::RenderSettings::alpha_mode_TRANSPARENT; + if(background->transparent) { + background->transparent_glass = get_boolean(cscene, "film_transparent_glass"); + background->transparent_roughness_threshold = get_float(cscene, "film_transparent_roughness"); + } + else { + background->transparent_glass = false; + background->transparent_roughness_threshold = 0.0f; + } + background->use_shader = render_layer.use_background_shader; background->use_ao = background->use_ao && render_layer.use_background_ao; diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index e4573024e85..6f0bdb3fa38 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -38,7 +38,7 @@ CCL_NAMESPACE_BEGIN /* Returns the square of the roughness of the closure if it has roughness, * 0 for singular closures and 1 otherwise. */ -ccl_device_inline float bsdf_get_roughness_sqr(const ShaderClosure *sc) +ccl_device_inline float bsdf_get_roughness_squared(const ShaderClosure *sc) { if(CLOSURE_IS_BSDF_SINGULAR(sc->type)) { return 0.0f; @@ -173,6 +173,17 @@ ccl_device_forceinline int bsdf_sample(KernelGlobals *kg, break; } + /* Test if BSDF sample should be treated as transparent for background. */ + if(label & LABEL_TRANSMIT) { + float threshold_squared = kernel_data.background.transparent_roughness_squared_threshold; + + if(threshold_squared >= 0.0f) { + if(bsdf_get_roughness_squared(sc) <= threshold_squared) { + label |= LABEL_TRANSMIT_TRANSPARENT; + } + } + } + return label; } diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h index 7c1b2a015e1..c0f281cae97 100644 --- a/intern/cycles/kernel/kernel_accumulate.h +++ b/intern/cycles/kernel/kernel_accumulate.h @@ -455,7 +455,7 @@ ccl_device_inline void path_radiance_accum_background( #ifdef __PASSES__ if(L->use_light_pass) { - if(state->bounce == 0) + if(state->flag & PATH_RAY_TRANSPARENT_BACKGROUND) L->background += throughput*value; else if(state->bounce == 1) L->direct_emission += throughput*value; diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h index 29451b6b8b6..1933d695f92 100644 --- a/intern/cycles/kernel/kernel_passes.h +++ b/intern/cycles/kernel/kernel_passes.h @@ -140,7 +140,7 @@ ccl_device_inline void kernel_update_denoising_features(KernelGlobals *kg, /* All closures contribute to the normal feature, but only diffuse-like ones to the albedo. */ normal += sc->N * sc->sample_weight; sum_weight += sc->sample_weight; - if(bsdf_get_roughness_sqr(sc) > sqr(0.075f)) { + if(bsdf_get_roughness_squared(sc) > sqr(0.075f)) { albedo += sc->weight; sum_nonspecular_weight += sc->sample_weight; } diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h index c2421c1ec18..1e98bca66ad 100644 --- a/intern/cycles/kernel/kernel_path.h +++ b/intern/cycles/kernel/kernel_path.h @@ -136,7 +136,7 @@ ccl_device_forceinline void kernel_path_background( PathRadiance *L) { /* eval background shader if nothing hit */ - if(kernel_data.background.transparent && (state->flag & PATH_RAY_CAMERA)) { + if(kernel_data.background.transparent && (state->flag & PATH_RAY_TRANSPARENT_BACKGROUND)) { L->transparent += average(throughput); #ifdef __PASSES__ @@ -280,7 +280,7 @@ ccl_device_forceinline bool kernel_path_shader_apply( { #ifdef __SHADOW_TRICKS__ if((sd->object_flag & SD_OBJECT_SHADOW_CATCHER)) { - if(state->flag & PATH_RAY_CAMERA) { + if(state->flag & PATH_RAY_TRANSPARENT_BACKGROUND) { state->flag |= (PATH_RAY_SHADOW_CATCHER | PATH_RAY_STORE_SHADOW_INFO); @@ -302,7 +302,7 @@ ccl_device_forceinline bool kernel_path_shader_apply( #ifdef __HOLDOUT__ if(((sd->flag & SD_HOLDOUT) || (sd->object_flag & SD_OBJECT_HOLDOUT_MASK)) && - (state->flag & PATH_RAY_CAMERA)) + (state->flag & PATH_RAY_TRANSPARENT_BACKGROUND)) { if(kernel_data.background.transparent) { float3 holdout_weight; diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h index eccee54c0e3..505eed117e0 100644 --- a/intern/cycles/kernel/kernel_path_state.h +++ b/intern/cycles/kernel/kernel_path_state.h @@ -23,7 +23,7 @@ ccl_device_inline void path_state_init(KernelGlobals *kg, int sample, ccl_addr_space Ray *ray) { - state->flag = PATH_RAY_CAMERA|PATH_RAY_MIS_SKIP; + state->flag = PATH_RAY_CAMERA|PATH_RAY_MIS_SKIP|PATH_RAY_TRANSPARENT_BACKGROUND; state->rng_hash = rng_hash; state->rng_offset = PRNG_BASE_NUM; @@ -86,12 +86,13 @@ ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathSta } state->bounce++; + state->flag &= ~(PATH_RAY_ALL_VISIBILITY|PATH_RAY_MIS_SKIP); #ifdef __VOLUME__ if(label & LABEL_VOLUME_SCATTER) { /* volume scatter */ state->flag |= PATH_RAY_VOLUME_SCATTER; - state->flag &= ~(PATH_RAY_REFLECT|PATH_RAY_TRANSMIT|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT|PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP); + state->flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND; state->volume_bounce++; } @@ -101,7 +102,7 @@ ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathSta /* surface reflection/transmission */ if(label & LABEL_REFLECT) { state->flag |= PATH_RAY_REFLECT; - state->flag &= ~(PATH_RAY_TRANSMIT|PATH_RAY_VOLUME_SCATTER|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT); + state->flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND; if(label & LABEL_DIFFUSE) state->diffuse_bounce++; @@ -112,7 +113,10 @@ ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathSta kernel_assert(label & LABEL_TRANSMIT); state->flag |= PATH_RAY_TRANSMIT; - state->flag &= ~(PATH_RAY_REFLECT|PATH_RAY_VOLUME_SCATTER|PATH_RAY_CAMERA|PATH_RAY_TRANSPARENT); + + if(!(label & LABEL_TRANSMIT_TRANSPARENT)) { + state->flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND; + } state->transmission_bounce++; } @@ -120,17 +124,13 @@ ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathSta /* diffuse/glossy/singular */ if(label & LABEL_DIFFUSE) { state->flag |= PATH_RAY_DIFFUSE|PATH_RAY_DIFFUSE_ANCESTOR; - state->flag &= ~(PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP); } else if(label & LABEL_GLOSSY) { state->flag |= PATH_RAY_GLOSSY; - state->flag &= ~(PATH_RAY_DIFFUSE|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP); } else { kernel_assert(label & LABEL_SINGULAR); - state->flag |= PATH_RAY_GLOSSY|PATH_RAY_SINGULAR|PATH_RAY_MIS_SKIP; - state->flag &= ~PATH_RAY_DIFFUSE; } } diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index b052d668b7d..4f655784044 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -346,11 +346,12 @@ enum PathRayFlag { PATH_RAY_ALL_VISIBILITY = ((1 << 14)-1), - PATH_RAY_MIS_SKIP = (1 << 15), - PATH_RAY_DIFFUSE_ANCESTOR = (1 << 16), - PATH_RAY_SINGLE_PASS_DONE = (1 << 17), - PATH_RAY_SHADOW_CATCHER = (1 << 18), - PATH_RAY_STORE_SHADOW_INFO = (1 << 19), + PATH_RAY_MIS_SKIP = (1 << 15), + PATH_RAY_DIFFUSE_ANCESTOR = (1 << 16), + PATH_RAY_SINGLE_PASS_DONE = (1 << 17), + PATH_RAY_SHADOW_CATCHER = (1 << 18), + PATH_RAY_STORE_SHADOW_INFO = (1 << 19), + PATH_RAY_TRANSPARENT_BACKGROUND = (1 << 20), }; /* Closure Label */ @@ -364,6 +365,7 @@ typedef enum ClosureLabel { LABEL_SINGULAR = 16, LABEL_TRANSPARENT = 32, LABEL_VOLUME_SCATTER = 64, + LABEL_TRANSMIT_TRANSPARENT = 128, } ClosureLabel; /* Render Passes */ @@ -1259,7 +1261,7 @@ typedef struct KernelBackground { int surface_shader; int volume_shader; int transparent; - int pad; + float transparent_roughness_squared_threshold; /* ambient occlusion */ float ao_factor; diff --git a/intern/cycles/render/background.cpp b/intern/cycles/render/background.cpp index 3ed96732b14..df3b65be110 100644 --- a/intern/cycles/render/background.cpp +++ b/intern/cycles/render/background.cpp @@ -38,7 +38,10 @@ NODE_DEFINE(Background) SOCKET_BOOLEAN(use_shader, "Use Shader", true); SOCKET_BOOLEAN(use_ao, "Use AO", false); SOCKET_UINT(visibility, "Visibility", PATH_RAY_ALL_VISIBILITY); + SOCKET_BOOLEAN(transparent, "Transparent", false); + SOCKET_BOOLEAN(transparent_glass, "Transparent Glass", false); + SOCKET_FLOAT(transparent_roughness_threshold, "Transparent Roughness Threshold", 0.0f); SOCKET_NODE(shader, "Shader", &Shader::node_type); @@ -81,6 +84,15 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene kbackground->transparent = transparent; kbackground->surface_shader = scene->shader_manager->get_shader_id(bg_shader); + if(transparent && transparent_glass) { + /* Square twice, once for principled BSDF convention, and once for + * faster comparison in kernel with anisotropic roughness. */ + kbackground->transparent_roughness_squared_threshold = sqr(sqr(transparent_roughness_threshold)); + } + else { + kbackground->transparent_roughness_squared_threshold = -1.0f; + } + if(bg_shader->has_volume) kbackground->volume_shader = kbackground->surface_shader; else diff --git a/intern/cycles/render/background.h b/intern/cycles/render/background.h index db20b6ebf87..145c05f1c18 100644 --- a/intern/cycles/render/background.h +++ b/intern/cycles/render/background.h @@ -42,6 +42,9 @@ public: Shader *shader; bool transparent; + bool transparent_glass; + float transparent_roughness_threshold; + bool need_update; Background(); |