Shading: Add Volume Info node.

The Volume Info node provides the Color, Desnity, Flame, and Temperature
of smoke domains.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D5551
This commit is contained in:
OmarSquircleArt 2019-08-21 20:22:24 +02:00
parent 133dfdd704
commit e83f092201
11 changed files with 193 additions and 0 deletions

View File

@ -607,6 +607,9 @@ static ShaderNode *add_node(Scene *scene,
else if (b_node.is_a(&RNA_ShaderNodeHairInfo)) {
node = new HairInfoNode();
}
else if (b_node.is_a(&RNA_ShaderNodeVolumeInfo)) {
node = new VolumeInfoNode();
}
else if (b_node.is_a(&RNA_ShaderNodeBump)) {
BL::ShaderNodeBump b_bump_node(b_node);
BumpNode *bump = new BumpNode();

View File

@ -4168,6 +4168,90 @@ void HairInfoNode::compile(OSLCompiler &compiler)
compiler.add(this, "node_hair_info");
}
/* Volume Info */
NODE_DEFINE(VolumeInfoNode)
{
NodeType *type = NodeType::add("volume_info", create, NodeType::SHADER);
SOCKET_OUT_COLOR(color, "Color");
SOCKET_OUT_FLOAT(density, "Density");
SOCKET_OUT_FLOAT(flame, "Flame");
SOCKET_OUT_FLOAT(temperature, "Temperature");
return type;
}
VolumeInfoNode::VolumeInfoNode() : ShaderNode(node_type)
{
}
/* The requested attributes are not updated after node expansion.
* So we explicitly request the required attributes.
*/
void VolumeInfoNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
if (shader->has_volume) {
if (!output("Color")->links.empty()) {
attributes->add(ATTR_STD_VOLUME_COLOR);
}
if (!output("Density")->links.empty()) {
attributes->add(ATTR_STD_VOLUME_DENSITY);
}
if (!output("Flame")->links.empty()) {
attributes->add(ATTR_STD_VOLUME_FLAME);
}
if (!output("Temperature")->links.empty()) {
attributes->add(ATTR_STD_VOLUME_TEMPERATURE);
}
attributes->add(ATTR_STD_GENERATED_TRANSFORM);
}
ShaderNode::attributes(shader, attributes);
}
void VolumeInfoNode::expand(ShaderGraph *graph)
{
ShaderOutput *color_out = output("Color");
if (!color_out->links.empty()) {
AttributeNode *attr = new AttributeNode();
attr->attribute = "color";
graph->add(attr);
graph->relink(color_out, attr->output("Color"));
}
ShaderOutput *density_out = output("Density");
if (!density_out->links.empty()) {
AttributeNode *attr = new AttributeNode();
attr->attribute = "density";
graph->add(attr);
graph->relink(density_out, attr->output("Fac"));
}
ShaderOutput *flame_out = output("Flame");
if (!flame_out->links.empty()) {
AttributeNode *attr = new AttributeNode();
attr->attribute = "flame";
graph->add(attr);
graph->relink(flame_out, attr->output("Fac"));
}
ShaderOutput *temperature_out = output("Temperature");
if (!temperature_out->links.empty()) {
AttributeNode *attr = new AttributeNode();
attr->attribute = "temperature";
graph->add(attr);
graph->relink(temperature_out, attr->output("Fac"));
}
}
void VolumeInfoNode::compile(SVMCompiler &)
{
}
void VolumeInfoNode::compile(OSLCompiler &)
{
}
/* Value */
NODE_DEFINE(ValueNode)

View File

@ -961,6 +961,21 @@ class HairInfoNode : public ShaderNode {
}
};
class VolumeInfoNode : public ShaderNode {
public:
SHADER_NODE_CLASS(VolumeInfoNode)
void attributes(Shader *shader, AttributeRequestSet *attributes);
bool has_attribute_dependency()
{
return true;
}
bool has_spatial_varying()
{
return true;
}
void expand(ShaderGraph *graph);
};
class ValueNode : public ShaderNode {
public:
SHADER_NODE_CLASS(ValueNode)

View File

@ -186,6 +186,7 @@ shader_node_categories = [
NodeItem("ShaderNodeAmbientOcclusion"),
NodeItem("ShaderNodeObjectInfo"),
NodeItem("ShaderNodeHairInfo"),
NodeItem("ShaderNodeVolumeInfo"),
NodeItem("ShaderNodeParticleInfo"),
NodeItem("ShaderNodeCameraData"),
NodeItem("ShaderNodeUVMap"),

View File

@ -979,6 +979,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree,
#define SH_NODE_MAP_RANGE 702
#define SH_NODE_CLAMP 703
#define SH_NODE_TEX_WHITE_NOISE 704
#define SH_NODE_VOLUME_INFO 705
/* custom defines options for Material node */
#define SH_NODE_MAT_DIFF 1

View File

@ -3960,6 +3960,7 @@ static void registerTextureNodes(void)
register_node_type_sh_tangent();
register_node_type_sh_normal_map();
register_node_type_sh_hair_info();
register_node_type_sh_volume_info();
register_node_type_tex_checker();
register_node_type_tex_texture();

View File

@ -2322,6 +2322,35 @@ void node_attribute_volume_temperature(
outcol = vec4(outf, outf, outf, 1.0);
}
void node_volume_info(sampler3D densitySampler,
sampler3D flameSampler,
vec2 temperature,
out vec4 outColor,
out float outDensity,
out float outFlame,
out float outTemprature)
{
#if defined(MESH_SHADER) && defined(VOLUMETRICS)
vec3 p = volumeObjectLocalCoord;
#else
vec3 p = vec3(0.0);
#endif
vec4 density = texture(densitySampler, p);
outDensity = density.a;
/* Density is premultiplied for interpolation, divide it out here. */
if (density.a > 1e-8) {
density.rgb /= density.a;
}
outColor = vec4(density.rgb * volumeColor, 1.0);
float flame = texture(flameSampler, p).r;
outFlame = flame;
outTemprature = (flame > 0.01) ? temperature.x + flame * (temperature.y - temperature.x) : 0.0;
}
void node_attribute(vec3 attr, out vec4 outcol, out vec3 outvec, out float outf)
{
outcol = vec4(attr, 1.0);

View File

@ -209,6 +209,7 @@ set(SRC
shader/nodes/node_shader_vectTransform.c
shader/nodes/node_shader_vector_displacement.c
shader/nodes/node_shader_volume_absorption.c
shader/nodes/node_shader_volume_info.c
shader/nodes/node_shader_volume_principled.c
shader/nodes/node_shader_volume_scatter.c
shader/nodes/node_shader_wavelength.c

View File

@ -81,6 +81,7 @@ void register_node_type_sh_layer_weight(void);
void register_node_type_sh_tex_coord(void);
void register_node_type_sh_particle_info(void);
void register_node_type_sh_hair_info(void);
void register_node_type_sh_volume_info(void);
void register_node_type_sh_script(void);
void register_node_type_sh_normal_map(void);
void register_node_type_sh_tangent(void);

View File

@ -96,6 +96,7 @@ DefNode(ShaderNode, SH_NODE_LIGHT_FALLOFF, 0, "LIG
DefNode(ShaderNode, SH_NODE_OBJECT_INFO, 0, "OBJECT_INFO", ObjectInfo, "Object Info", "" )
DefNode(ShaderNode, SH_NODE_PARTICLE_INFO, 0, "PARTICLE_INFO", ParticleInfo, "Particle Info", "" )
DefNode(ShaderNode, SH_NODE_HAIR_INFO, 0, "HAIR_INFO", HairInfo, "Hair Info", "" )
DefNode(ShaderNode, SH_NODE_VOLUME_INFO, 0, "VOLUME_INFO", VolumeInfo, "Volume Info", "" )
DefNode(ShaderNode, SH_NODE_WIREFRAME, def_sh_tex_wireframe, "WIREFRAME", Wireframe, "Wireframe", "" )
DefNode(ShaderNode, SH_NODE_WAVELENGTH, 0, "WAVELENGTH", Wavelength, "Wavelength", "" )
DefNode(ShaderNode, SH_NODE_BLACKBODY, 0, "BLACKBODY", Blackbody, "Blackbody", "" )

View File

@ -0,0 +1,56 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2005 Blender Foundation.
* All rights reserved.
*/
#include "../node_shader_util.h"
static bNodeSocketTemplate sh_node_volume_info_out[] = {
{SOCK_RGBA, 0, N_("Color")},
{SOCK_FLOAT, 0, N_("Density")},
{SOCK_FLOAT, 0, N_("Flame")},
{SOCK_FLOAT, 0, N_("Temperature")},
{-1, 0, ""},
};
static int node_shader_gpu_volume_info(GPUMaterial *mat,
bNode *node,
bNodeExecData *UNUSED(execdata),
GPUNodeStack *in,
GPUNodeStack *out)
{
return GPU_stack_link(mat,
node,
"node_volume_info",
in,
out,
GPU_builtin(GPU_VOLUME_DENSITY),
GPU_builtin(GPU_VOLUME_FLAME),
GPU_builtin(GPU_VOLUME_TEMPERATURE));
}
void register_node_type_sh_volume_info(void)
{
static bNodeType ntype;
sh_node_type_base(&ntype, SH_NODE_VOLUME_INFO, "Volume Info", NODE_CLASS_INPUT, 0);
node_type_socket_templates(&ntype, NULL, sh_node_volume_info_out);
node_type_gpu(&ntype, node_shader_gpu_volume_info);
nodeRegisterType(&ntype);
}