GPUMaterial: Add volume shader flags
This allows for some optimization when we know some effects are not present. Also this is needed to detect the case when world contains absorption in order to disable distant lighting. Related #114062
This commit is contained in:
@@ -80,8 +80,11 @@ typedef enum eGPUMaterialFlag {
|
||||
GPU_MATFLAG_AO = (1 << 8),
|
||||
GPU_MATFLAG_COAT = (1 << 9),
|
||||
|
||||
GPU_MATFLAG_OBJECT_INFO = (1 << 10),
|
||||
GPU_MATFLAG_AOV = (1 << 11),
|
||||
GPU_MATFLAG_VOLUME_SCATTER = (1 << 10),
|
||||
GPU_MATFLAG_VOLUME_ABSORPTION = (1 << 11),
|
||||
|
||||
GPU_MATFLAG_OBJECT_INFO = (1 << 12),
|
||||
GPU_MATFLAG_AOV = (1 << 13),
|
||||
|
||||
GPU_MATFLAG_BARYCENTRIC = (1 << 20),
|
||||
|
||||
|
||||
@@ -9,20 +9,34 @@ namespace blender::nodes::node_shader_volume_absorption_cc {
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Color>("Color").default_value({0.8f, 0.8f, 0.8f, 1.0f});
|
||||
#define SOCK_COLOR_ID 0
|
||||
b.add_input<decl::Float>("Density").default_value(1.0f).min(0.0f).max(1000.0f);
|
||||
#define SOCK_DENSITY_ID 1
|
||||
b.add_input<decl::Float>("Weight").unavailable();
|
||||
b.add_output<decl::Shader>("Volume").translation_context(BLT_I18NCONTEXT_ID_ID);
|
||||
}
|
||||
|
||||
#define socket_not_zero(sock) (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) > 1e-5f))
|
||||
#define socket_not_white(sock) \
|
||||
(in[sock].link || \
|
||||
(clamp_f(in[sock].vec[0], 0.0f, 1.0f) < 1.0f && clamp_f(in[sock].vec[1], 0.0f, 1.0f) < 1.0f && \
|
||||
clamp_f(in[sock].vec[2], 0.0f, 1.0f) < 1.0f))
|
||||
|
||||
static int node_shader_gpu_volume_absorption(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
if (socket_not_zero(SOCK_DENSITY_ID) && socket_not_white(SOCK_COLOR_ID)) {
|
||||
GPU_material_flag_set(mat, GPU_MATFLAG_VOLUME_ABSORPTION);
|
||||
}
|
||||
return GPU_stack_link(mat, node, "node_volume_absorption", in, out);
|
||||
}
|
||||
|
||||
#undef SOCK_COLOR_ID
|
||||
#undef SOCK_DENSITY_ID
|
||||
|
||||
} // namespace blender::nodes::node_shader_volume_absorption_cc
|
||||
|
||||
/* node type definition */
|
||||
|
||||
@@ -11,23 +11,33 @@ namespace blender::nodes::node_shader_volume_principled_cc {
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Color>("Color").default_value({0.5f, 0.5f, 0.5f, 1.0f});
|
||||
#define SOCK_COLOR_ID 0
|
||||
b.add_input<decl::String>("Color Attribute");
|
||||
#define SOCK_COLOR_ATTR_ID 1
|
||||
b.add_input<decl::Float>("Density").default_value(1.0f).min(0.0f).max(1000.0f);
|
||||
#define SOCK_DENSITY_ID 2
|
||||
b.add_input<decl::String>("Density Attribute").default_value("density");
|
||||
#define SOCK_DENSITY_ATTR_ID 3
|
||||
b.add_input<decl::Float>("Anisotropy")
|
||||
.default_value(0.0f)
|
||||
.min(-1.0f)
|
||||
.max(1.0f)
|
||||
.subtype(PROP_FACTOR);
|
||||
#define SOCK_ANISOTROPY_ID 4
|
||||
b.add_input<decl::Color>("Absorption Color").default_value({0.0f, 0.0f, 0.0f, 1.0f});
|
||||
#define SOCK_ABSORPTION_COLOR_ID 5
|
||||
b.add_input<decl::Float>("Emission Strength").default_value(0.0f).min(0.0f).max(1000.0f);
|
||||
#define SOCK_EMISSION_ID 6
|
||||
b.add_input<decl::Color>("Emission Color").default_value({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
#define SOCK_EMISSION_COLOR_ID 7
|
||||
b.add_input<decl::Float>("Blackbody Intensity")
|
||||
.default_value(0.0f)
|
||||
.min(0.0f)
|
||||
.max(1.0f)
|
||||
.subtype(PROP_FACTOR);
|
||||
#define SOCK_BLACKBODY_INTENSITY_ID 8
|
||||
b.add_input<decl::Color>("Blackbody Tint").default_value({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
#define SOCK_BLACKBODY_TINT_ID 8
|
||||
b.add_input<decl::Float>("Temperature").default_value(1000.0f).min(0.0f).max(6500.0f);
|
||||
b.add_input<decl::String>("Temperature Attribute").default_value("temperature");
|
||||
b.add_input<decl::Float>("Weight").unavailable();
|
||||
@@ -46,6 +56,16 @@ static void attribute_post_process(GPUMaterial *mat,
|
||||
}
|
||||
}
|
||||
|
||||
#define socket_not_zero(sock) (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) > 1e-5f))
|
||||
#define socket_not_black(sock) \
|
||||
(in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) > 1e-5f && \
|
||||
clamp_f(in[sock].vec[1], 0.0f, 1.0f) > 1e-5f && \
|
||||
clamp_f(in[sock].vec[2], 0.0f, 1.0f) > 1e-5f))
|
||||
#define socket_not_white(sock) \
|
||||
(in[sock].link || \
|
||||
(clamp_f(in[sock].vec[0], 0.0f, 1.0f) < 1.0f && clamp_f(in[sock].vec[1], 0.0f, 1.0f) < 1.0f && \
|
||||
clamp_f(in[sock].vec[2], 0.0f, 1.0f) < 1.0f))
|
||||
|
||||
static int node_shader_gpu_volume_principled(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
@@ -53,7 +73,16 @@ static int node_shader_gpu_volume_principled(GPUMaterial *mat,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
/* Test if blackbody intensity is enabled. */
|
||||
bool use_blackbody = (in[8].link || in[8].vec[0] != 0.0f);
|
||||
bool use_blackbody = socket_not_zero(SOCK_BLACKBODY_INTENSITY_ID);
|
||||
|
||||
if (socket_not_zero(SOCK_DENSITY_ID) && socket_not_black(SOCK_COLOR_ID)) {
|
||||
/* Consider there is absorption phenomenon when there is scattering since
|
||||
* `extinction = scattering + absorption`. */
|
||||
GPU_material_flag_set(mat, GPU_MATFLAG_VOLUME_SCATTER | GPU_MATFLAG_VOLUME_ABSORPTION);
|
||||
}
|
||||
if (socket_not_zero(SOCK_DENSITY_ID) && socket_not_white(SOCK_ABSORPTION_COLOR_ID)) {
|
||||
GPU_material_flag_set(mat, GPU_MATFLAG_VOLUME_ABSORPTION);
|
||||
}
|
||||
|
||||
/* Get volume attributes. */
|
||||
GPUNodeLink *density = nullptr, *color = nullptr, *temperature = nullptr;
|
||||
@@ -119,6 +148,17 @@ static int node_shader_gpu_volume_principled(GPUMaterial *mat,
|
||||
GPU_constant(&layer));
|
||||
}
|
||||
|
||||
#undef SOCK_COLOR_ID
|
||||
#undef SOCK_COLOR_ATTR_ID
|
||||
#undef SOCK_DENSITY_ID
|
||||
#undef SOCK_DENSITY_ATTR_ID
|
||||
#undef SOCK_ANISOTROPY_ID
|
||||
#undef SOCK_ABSORPTION_COLOR_ID
|
||||
#undef SOCK_EMISSION_ID
|
||||
#undef SOCK_EMISSION_COLOR_ID
|
||||
#undef SOCK_BLACKBODY_INTENSITY_ID
|
||||
#undef SOCK_BLACKBODY_TINT_ID
|
||||
|
||||
} // namespace blender::nodes::node_shader_volume_principled_cc
|
||||
|
||||
/* node type definition */
|
||||
|
||||
@@ -9,7 +9,9 @@ namespace blender::nodes::node_shader_volume_scatter_cc {
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Color>("Color").default_value({0.8f, 0.8f, 0.8f, 1.0f});
|
||||
#define SOCK_COLOR_ID 0
|
||||
b.add_input<decl::Float>("Density").default_value(1.0f).min(0.0f).max(1000.0f);
|
||||
#define SOCK_DENSITY_ID 1
|
||||
b.add_input<decl::Float>("Anisotropy")
|
||||
.default_value(0.0f)
|
||||
.min(-1.0f)
|
||||
@@ -19,15 +21,29 @@ static void node_declare(NodeDeclarationBuilder &b)
|
||||
b.add_output<decl::Shader>("Volume").translation_context(BLT_I18NCONTEXT_ID_ID);
|
||||
}
|
||||
|
||||
#define socket_not_zero(sock) (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) > 1e-5f))
|
||||
#define socket_not_black(sock) \
|
||||
(in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) > 1e-5f && \
|
||||
clamp_f(in[sock].vec[1], 0.0f, 1.0f) > 1e-5f && \
|
||||
clamp_f(in[sock].vec[2], 0.0f, 1.0f) > 1e-5f))
|
||||
|
||||
static int node_shader_gpu_volume_scatter(GPUMaterial *mat,
|
||||
bNode *node,
|
||||
bNodeExecData * /*execdata*/,
|
||||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
if (socket_not_zero(SOCK_DENSITY_ID) && socket_not_black(SOCK_COLOR_ID)) {
|
||||
/* Consider there is absorption phenomenon when there is scattering since
|
||||
* `extinction = scattering + absorption`. */
|
||||
GPU_material_flag_set(mat, GPU_MATFLAG_VOLUME_SCATTER | GPU_MATFLAG_VOLUME_ABSORPTION);
|
||||
}
|
||||
return GPU_stack_link(mat, node, "node_volume_scatter", in, out);
|
||||
}
|
||||
|
||||
#undef SOCK_COLOR_ID
|
||||
#undef SOCK_DENSITY_ID
|
||||
|
||||
} // namespace blender::nodes::node_shader_volume_scatter_cc
|
||||
|
||||
/* node type definition */
|
||||
|
||||
Reference in New Issue
Block a user