From 4a04d7ae8930502037cd23dc94ed1bc9bc0043ac Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Fri, 19 May 2017 04:59:35 +0200 Subject: Fix T51553: Cycles Volume Emission turns black when strength is 0 or color is black The problem was that Cycles implicitly uses a transparent surface shader when only volume nodes are used, but since the black emission shader gets optimized away, it was no longer detected and therefore no transparent surface was used. Therefore, the shader now stores whether volume nodes were connected before optimizing. --- intern/cycles/render/shader.cpp | 11 +++++++---- intern/cycles/render/shader.h | 9 +++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index ef89288f167..a64f227a38c 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -241,6 +241,10 @@ void Shader::set_graph(ShaderGraph *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. */ + has_volume_connected = (graph->output()->input("Volume")->link != NULL); } void Shader::tag_update(Scene *scene) @@ -432,15 +436,14 @@ void ShaderManager::device_update_common(Device *device, flag |= SD_HAS_VOLUME; has_volumes = true; - /* in this case we can assume transparent surface */ - if(!shader->has_surface) - flag |= SD_HAS_ONLY_VOLUME; - /* todo: this could check more fine grained, to skip useless volumes * enclosed inside an opaque bsdf. */ flag |= SD_HAS_TRANSPARENT_SHADOW; } + /* in this case we can assume transparent surface */ + if(shader->has_volume_connected && !shader->has_surface) + flag |= SD_HAS_ONLY_VOLUME; if(shader->heterogeneous_volume && shader->has_volume_spatial_varying) flag |= SD_HETEROGENEOUS_VOLUME; if(shader->has_bssrdf_bump) diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index a8018231f1a..b6714b13247 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -105,6 +105,15 @@ public: bool need_update; bool need_update_attributes; + /* If the shader has only volume components, the surface is assumed to + * be transparent. + * However, graph optimization might remove the volume subgraph, but + * since the user connected something to the volume output the surface + * should still be transparent. + * Therefore, has_volume_connected stores whether some volume subtree + * was connected before optimization. */ + bool has_volume_connected; + /* information about shader after compiling */ bool has_surface; bool has_surface_emission; -- cgit v1.2.3