Cycles volume: detect homogeneous volume automatically in common cases.
In practice this means that if you don't connect a texture to your volume nodes it will figure that out and render the node faster, rather than you having to specify it manually. Main weakness is custom OSL nodes where we have to assume it is heterogeneous because we don't know what kind of data the node accesses.
This commit is contained in:
@@ -193,6 +193,7 @@ public:
|
|||||||
virtual bool has_surface_bssrdf() { return false; }
|
virtual bool has_surface_bssrdf() { return false; }
|
||||||
virtual bool has_converter_blackbody() { return false; }
|
virtual bool has_converter_blackbody() { return false; }
|
||||||
virtual bool has_bssrdf_bump() { return false; }
|
virtual bool has_bssrdf_bump() { return false; }
|
||||||
|
virtual bool has_spatial_varying() { return false; }
|
||||||
|
|
||||||
vector<ShaderInput*> inputs;
|
vector<ShaderInput*> inputs;
|
||||||
vector<ShaderOutput*> outputs;
|
vector<ShaderOutput*> outputs;
|
||||||
|
@@ -209,6 +209,7 @@ public:
|
|||||||
BsdfNode(bool scattering = false);
|
BsdfNode(bool scattering = false);
|
||||||
SHADER_NODE_BASE_CLASS(BsdfNode);
|
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);
|
void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3 = NULL, ShaderInput *param4 = NULL);
|
||||||
|
|
||||||
ClosureType closure;
|
ClosureType closure;
|
||||||
@@ -280,6 +281,7 @@ public:
|
|||||||
SHADER_NODE_CLASS(SubsurfaceScatteringNode)
|
SHADER_NODE_CLASS(SubsurfaceScatteringNode)
|
||||||
bool has_surface_bssrdf() { return true; }
|
bool has_surface_bssrdf() { return true; }
|
||||||
bool has_bssrdf_bump();
|
bool has_bssrdf_bump();
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
|
|
||||||
static ShaderEnum falloff_enum;
|
static ShaderEnum falloff_enum;
|
||||||
};
|
};
|
||||||
@@ -289,6 +291,7 @@ public:
|
|||||||
SHADER_NODE_CLASS(EmissionNode)
|
SHADER_NODE_CLASS(EmissionNode)
|
||||||
|
|
||||||
bool has_surface_emission() { return true; }
|
bool has_surface_emission() { return true; }
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
|
|
||||||
bool total_power;
|
bool total_power;
|
||||||
};
|
};
|
||||||
@@ -306,6 +309,8 @@ public:
|
|||||||
class AmbientOcclusionNode : public ShaderNode {
|
class AmbientOcclusionNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(AmbientOcclusionNode)
|
SHADER_NODE_CLASS(AmbientOcclusionNode)
|
||||||
|
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class VolumeNode : public ShaderNode {
|
class VolumeNode : public ShaderNode {
|
||||||
@@ -340,12 +345,14 @@ class GeometryNode : public ShaderNode {
|
|||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(GeometryNode)
|
SHADER_NODE_CLASS(GeometryNode)
|
||||||
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class TextureCoordinateNode : public ShaderNode {
|
class TextureCoordinateNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(TextureCoordinateNode)
|
SHADER_NODE_CLASS(TextureCoordinateNode)
|
||||||
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
|
|
||||||
bool from_dupli;
|
bool from_dupli;
|
||||||
};
|
};
|
||||||
@@ -354,6 +361,7 @@ class UVMapNode : public ShaderNode {
|
|||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(UVMapNode)
|
SHADER_NODE_CLASS(UVMapNode)
|
||||||
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
|
|
||||||
ustring attribute;
|
ustring attribute;
|
||||||
bool from_dupli;
|
bool from_dupli;
|
||||||
@@ -367,6 +375,7 @@ public:
|
|||||||
class LightFalloffNode : public ShaderNode {
|
class LightFalloffNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(LightFalloffNode)
|
SHADER_NODE_CLASS(LightFalloffNode)
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ObjectInfoNode : public ShaderNode {
|
class ObjectInfoNode : public ShaderNode {
|
||||||
@@ -385,6 +394,7 @@ public:
|
|||||||
SHADER_NODE_CLASS(HairInfoNode)
|
SHADER_NODE_CLASS(HairInfoNode)
|
||||||
|
|
||||||
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class ValueNode : public ShaderNode {
|
class ValueNode : public ShaderNode {
|
||||||
@@ -470,6 +480,7 @@ class AttributeNode : public ShaderNode {
|
|||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(AttributeNode)
|
SHADER_NODE_CLASS(AttributeNode)
|
||||||
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
|
|
||||||
ustring attribute;
|
ustring attribute;
|
||||||
};
|
};
|
||||||
@@ -477,21 +488,25 @@ public:
|
|||||||
class CameraNode : public ShaderNode {
|
class CameraNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(CameraNode)
|
SHADER_NODE_CLASS(CameraNode)
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class FresnelNode : public ShaderNode {
|
class FresnelNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(FresnelNode)
|
SHADER_NODE_CLASS(FresnelNode)
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class LayerWeightNode : public ShaderNode {
|
class LayerWeightNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(LayerWeightNode)
|
SHADER_NODE_CLASS(LayerWeightNode)
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class WireframeNode : public ShaderNode {
|
class WireframeNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(WireframeNode)
|
SHADER_NODE_CLASS(WireframeNode)
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
|
|
||||||
bool use_pixel_size;
|
bool use_pixel_size;
|
||||||
};
|
};
|
||||||
@@ -548,6 +563,8 @@ public:
|
|||||||
class BumpNode : public ShaderNode {
|
class BumpNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(BumpNode)
|
SHADER_NODE_CLASS(BumpNode)
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
|
|
||||||
bool invert;
|
bool invert;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -578,6 +595,10 @@ public:
|
|||||||
class OSLScriptNode : public ShaderNode {
|
class OSLScriptNode : public ShaderNode {
|
||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(OSLScriptNode)
|
SHADER_NODE_CLASS(OSLScriptNode)
|
||||||
|
|
||||||
|
/* ideally we could beter detect this, but we can't query this now */
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
|
|
||||||
string filepath;
|
string filepath;
|
||||||
string bytecode_hash;
|
string bytecode_hash;
|
||||||
|
|
||||||
@@ -591,6 +612,7 @@ class NormalMapNode : public ShaderNode {
|
|||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(NormalMapNode)
|
SHADER_NODE_CLASS(NormalMapNode)
|
||||||
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
|
|
||||||
ustring space;
|
ustring space;
|
||||||
static ShaderEnum space_enum;
|
static ShaderEnum space_enum;
|
||||||
@@ -602,6 +624,7 @@ class TangentNode : public ShaderNode {
|
|||||||
public:
|
public:
|
||||||
SHADER_NODE_CLASS(TangentNode)
|
SHADER_NODE_CLASS(TangentNode)
|
||||||
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
||||||
|
bool has_spatial_varying() { return true; }
|
||||||
|
|
||||||
ustring direction_type;
|
ustring direction_type;
|
||||||
static ShaderEnum direction_type_enum;
|
static ShaderEnum direction_type_enum;
|
||||||
|
@@ -53,6 +53,7 @@ Shader::Shader()
|
|||||||
has_volume = false;
|
has_volume = false;
|
||||||
has_displacement = false;
|
has_displacement = false;
|
||||||
has_bssrdf_bump = false;
|
has_bssrdf_bump = false;
|
||||||
|
has_heterogeneous_volume = false;
|
||||||
|
|
||||||
used = false;
|
used = false;
|
||||||
|
|
||||||
@@ -249,7 +250,7 @@ void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Sc
|
|||||||
* the case with camera inside volumes too */
|
* the case with camera inside volumes too */
|
||||||
flag |= SD_HAS_TRANSPARENT_SHADOW;
|
flag |= SD_HAS_TRANSPARENT_SHADOW;
|
||||||
}
|
}
|
||||||
if(shader->heterogeneous_volume)
|
if(shader->heterogeneous_volume && shader->has_heterogeneous_volume)
|
||||||
flag |= SD_HETEROGENEOUS_VOLUME;
|
flag |= SD_HETEROGENEOUS_VOLUME;
|
||||||
if(shader->has_bssrdf_bump)
|
if(shader->has_bssrdf_bump)
|
||||||
flag |= SD_HAS_BSSRDF_BUMP;
|
flag |= SD_HAS_BSSRDF_BUMP;
|
||||||
|
@@ -77,6 +77,7 @@ public:
|
|||||||
bool has_surface_bssrdf;
|
bool has_surface_bssrdf;
|
||||||
bool has_converter_blackbody;
|
bool has_converter_blackbody;
|
||||||
bool has_bssrdf_bump;
|
bool has_bssrdf_bump;
|
||||||
|
bool has_heterogeneous_volume;
|
||||||
|
|
||||||
/* requested mesh attributes */
|
/* requested mesh attributes */
|
||||||
AttributeRequestSet attributes;
|
AttributeRequestSet attributes;
|
||||||
|
@@ -379,6 +379,18 @@ void SVMCompiler::find_dependencies(set<ShaderNode*>& dependencies, const set<Sh
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SVMCompiler::generate_node(ShaderNode *node, set<ShaderNode*>& done)
|
||||||
|
{
|
||||||
|
node->compile(*this);
|
||||||
|
stack_clear_users(node, done);
|
||||||
|
stack_clear_temporary(node);
|
||||||
|
|
||||||
|
if(current_type == SHADER_TYPE_VOLUME) {
|
||||||
|
if(node->has_spatial_varying())
|
||||||
|
current_shader->has_heterogeneous_volume = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SVMCompiler::generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNode*>& done)
|
void SVMCompiler::generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNode*>& done)
|
||||||
{
|
{
|
||||||
bool nodes_done;
|
bool nodes_done;
|
||||||
@@ -400,9 +412,7 @@ void SVMCompiler::generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNo
|
|||||||
if(node->has_converter_blackbody())
|
if(node->has_converter_blackbody())
|
||||||
current_shader->has_converter_blackbody = true;
|
current_shader->has_converter_blackbody = true;
|
||||||
|
|
||||||
node->compile(*this);
|
generate_node(node, done);
|
||||||
stack_clear_users(node, done);
|
|
||||||
stack_clear_temporary(node);
|
|
||||||
done.insert(node);
|
done.insert(node);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -485,9 +495,7 @@ void SVMCompiler::generate_closure(ShaderNode *node, set<ShaderNode*>& done)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* compile closure itself */
|
/* compile closure itself */
|
||||||
node->compile(*this);
|
generate_node(node, done);
|
||||||
stack_clear_users(node, done);
|
|
||||||
stack_clear_temporary(node);
|
|
||||||
|
|
||||||
if(current_type == SHADER_TYPE_SURFACE) {
|
if(current_type == SHADER_TYPE_SURFACE) {
|
||||||
if(node->has_surface_emission())
|
if(node->has_surface_emission())
|
||||||
@@ -550,9 +558,7 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& don
|
|||||||
mix_weight_offset = SVM_STACK_INVALID;
|
mix_weight_offset = SVM_STACK_INVALID;
|
||||||
|
|
||||||
/* compile closure itself */
|
/* compile closure itself */
|
||||||
node->compile(*this);
|
generate_node(node, done);
|
||||||
stack_clear_users(node, done);
|
|
||||||
stack_clear_temporary(node);
|
|
||||||
|
|
||||||
mix_weight_offset = SVM_STACK_INVALID;
|
mix_weight_offset = SVM_STACK_INVALID;
|
||||||
|
|
||||||
@@ -694,6 +700,7 @@ void SVMCompiler::compile(Shader *shader, vector<int4>& global_svm_nodes, int in
|
|||||||
shader->has_converter_blackbody = false;
|
shader->has_converter_blackbody = false;
|
||||||
shader->has_volume = false;
|
shader->has_volume = false;
|
||||||
shader->has_displacement = false;
|
shader->has_displacement = false;
|
||||||
|
shader->has_heterogeneous_volume = false;
|
||||||
|
|
||||||
/* generate surface shader */
|
/* generate surface shader */
|
||||||
compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
|
compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
|
||||||
|
@@ -124,6 +124,7 @@ protected:
|
|||||||
|
|
||||||
/* single closure */
|
/* single closure */
|
||||||
void find_dependencies(set<ShaderNode*>& dependencies, const set<ShaderNode*>& done, ShaderInput *input);
|
void find_dependencies(set<ShaderNode*>& dependencies, const set<ShaderNode*>& done, ShaderInput *input);
|
||||||
|
void generate_node(ShaderNode *node, set<ShaderNode*>& done);
|
||||||
void generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNode*>& done);
|
void generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNode*>& done);
|
||||||
void generate_closure(ShaderNode *node, set<ShaderNode*>& done);
|
void generate_closure(ShaderNode *node, set<ShaderNode*>& done);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user