Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlie Jolly <charlie>2021-10-18 12:12:22 +0300
committerCharlie Jolly <mistajolly@gmail.com>2021-10-18 16:24:14 +0300
commit729b2d026d1379de92908b16e7492a509721c796 (patch)
tree7cd9396e59006f9bbd5135e6c4556df25040bae5 /source/blender/nodes/shader
parentde6bf5d4d2f1f832f8305c519fc88d8896ea9a0b (diff)
Geometry Nodes: Add shader Musgrave texture node
Port shader node musgrave texture Differential Revision: https://developer.blender.org/D12701
Diffstat (limited to 'source/blender/nodes/shader')
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc410
1 files changed, 408 insertions, 2 deletions
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc
index 23f150d8135..61c26d07e2f 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc
@@ -19,12 +19,14 @@
#include "../node_shader_util.h"
+#include "BLI_noise.hh"
+
namespace blender::nodes {
static void sh_node_tex_musgrave_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
- b.add_input<decl::Vector>("Vector").hide_value();
+ b.add_input<decl::Vector>("Vector").hide_value().implicit_field();
b.add_input<decl::Float>("W").min(-1000.0f).max(1000.0f);
b.add_input<decl::Float>("Scale").min(-1000.0f).max(1000.0f).default_value(5.0f);
b.add_input<decl::Float>("Detail").min(0.0f).max(16.0f).default_value(2.0f);
@@ -124,11 +126,414 @@ static void node_shader_update_tex_musgrave(bNodeTree *UNUSED(ntree), bNode *nod
node_sock_label(outFacSock, "Height");
}
+namespace blender::nodes {
+
+class MusgraveFunction : public fn::MultiFunction {
+ private:
+ const int dimensions_;
+ const int musgrave_type_;
+
+ public:
+ MusgraveFunction(const int dimensions, const int musgrave_type)
+ : dimensions_(dimensions), musgrave_type_(musgrave_type)
+ {
+ BLI_assert(dimensions >= 1 && dimensions <= 4);
+ BLI_assert(musgrave_type >= 0 && musgrave_type <= 4);
+ static std::array<fn::MFSignature, 20> signatures{
+ create_signature(1, SHD_MUSGRAVE_MULTIFRACTAL),
+ create_signature(2, SHD_MUSGRAVE_MULTIFRACTAL),
+ create_signature(3, SHD_MUSGRAVE_MULTIFRACTAL),
+ create_signature(4, SHD_MUSGRAVE_MULTIFRACTAL),
+
+ create_signature(1, SHD_MUSGRAVE_FBM),
+ create_signature(2, SHD_MUSGRAVE_FBM),
+ create_signature(3, SHD_MUSGRAVE_FBM),
+ create_signature(4, SHD_MUSGRAVE_FBM),
+
+ create_signature(1, SHD_MUSGRAVE_HYBRID_MULTIFRACTAL),
+ create_signature(2, SHD_MUSGRAVE_HYBRID_MULTIFRACTAL),
+ create_signature(3, SHD_MUSGRAVE_HYBRID_MULTIFRACTAL),
+ create_signature(4, SHD_MUSGRAVE_HYBRID_MULTIFRACTAL),
+
+ create_signature(1, SHD_MUSGRAVE_RIDGED_MULTIFRACTAL),
+ create_signature(2, SHD_MUSGRAVE_RIDGED_MULTIFRACTAL),
+ create_signature(3, SHD_MUSGRAVE_RIDGED_MULTIFRACTAL),
+ create_signature(4, SHD_MUSGRAVE_RIDGED_MULTIFRACTAL),
+
+ create_signature(1, SHD_MUSGRAVE_HETERO_TERRAIN),
+ create_signature(2, SHD_MUSGRAVE_HETERO_TERRAIN),
+ create_signature(3, SHD_MUSGRAVE_HETERO_TERRAIN),
+ create_signature(4, SHD_MUSGRAVE_HETERO_TERRAIN),
+ };
+ this->set_signature(&signatures[dimensions + musgrave_type * 4 - 1]);
+ }
+
+ static fn::MFSignature create_signature(const int dimensions, const int musgrave_type)
+ {
+ fn::MFSignatureBuilder signature{"Musgrave"};
+
+ if (ELEM(dimensions, 2, 3, 4)) {
+ signature.single_input<float3>("Vector");
+ }
+ if (ELEM(dimensions, 1, 4)) {
+ signature.single_input<float>("W");
+ }
+ signature.single_input<float>("Scale");
+ signature.single_input<float>("Detail");
+ signature.single_input<float>("Dimension");
+ signature.single_input<float>("Lacunarity");
+ if (ELEM(musgrave_type,
+ SHD_MUSGRAVE_RIDGED_MULTIFRACTAL,
+ SHD_MUSGRAVE_HYBRID_MULTIFRACTAL,
+ SHD_MUSGRAVE_HETERO_TERRAIN)) {
+ signature.single_input<float>("Offset");
+ }
+ if (ELEM(musgrave_type, SHD_MUSGRAVE_RIDGED_MULTIFRACTAL, SHD_MUSGRAVE_HYBRID_MULTIFRACTAL)) {
+ signature.single_input<float>("Gain");
+ }
+
+ signature.single_output<float>("Fac");
+
+ return signature.build();
+ }
+
+ void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+ {
+ auto get_vector = [&](int param_index) -> const VArray<float3> & {
+ return params.readonly_single_input<float3>(param_index, "Vector");
+ };
+ auto get_w = [&](int param_index) -> const VArray<float> & {
+ return params.readonly_single_input<float>(param_index, "W");
+ };
+ auto get_scale = [&](int param_index) -> const VArray<float> & {
+ return params.readonly_single_input<float>(param_index, "Scale");
+ };
+ auto get_detail = [&](int param_index) -> const VArray<float> & {
+ return params.readonly_single_input<float>(param_index, "Detail");
+ };
+ auto get_dimension = [&](int param_index) -> const VArray<float> & {
+ return params.readonly_single_input<float>(param_index, "Dimension");
+ };
+ auto get_lacunarity = [&](int param_index) -> const VArray<float> & {
+ return params.readonly_single_input<float>(param_index, "Lacunarity");
+ };
+ auto get_offset = [&](int param_index) -> const VArray<float> & {
+ return params.readonly_single_input<float>(param_index, "Offset");
+ };
+ auto get_gain = [&](int param_index) -> const VArray<float> & {
+ return params.readonly_single_input<float>(param_index, "Gain");
+ };
+
+ auto get_r_factor = [&](int param_index) -> MutableSpan<float> {
+ return params.uninitialized_single_output_if_required<float>(param_index, "Fac");
+ };
+
+ int param = ELEM(dimensions_, 2, 3, 4) + ELEM(dimensions_, 1, 4);
+ const VArray<float> &scale = get_scale(param++);
+ const VArray<float> &detail = get_detail(param++);
+ const VArray<float> &dimension = get_dimension(param++);
+ const VArray<float> &lacunarity = get_lacunarity(param++);
+
+ switch (musgrave_type_) {
+ case SHD_MUSGRAVE_MULTIFRACTAL: {
+ MutableSpan<float> r_factor = get_r_factor(param++);
+ const bool compute_factor = !r_factor.is_empty();
+ switch (dimensions_) {
+ case 1: {
+ const VArray<float> &w = get_w(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float position = w[i] * scale[i];
+ r_factor[i] = noise::musgrave_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ case 2: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float2 position = float2(pxyz[0], pxyz[1]);
+ r_factor[i] = noise::musgrave_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ case 3: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 position = vector[i] * scale[i];
+ r_factor[i] = noise::musgrave_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ case 4: {
+ const VArray<float3> &vector = get_vector(0);
+ const VArray<float> &w = get_w(1);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float pw = w[i] * scale[i];
+ const float4 position{pxyz[0], pxyz[1], pxyz[2], pw};
+ r_factor[i] = noise::musgrave_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case SHD_MUSGRAVE_RIDGED_MULTIFRACTAL: {
+ const VArray<float> &offset = get_offset(param++);
+ const VArray<float> &gain = get_gain(param++);
+ MutableSpan<float> r_factor = get_r_factor(param++);
+ const bool compute_factor = !r_factor.is_empty();
+ switch (dimensions_) {
+ case 1: {
+ const VArray<float> &w = get_w(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float position = w[i] * scale[i];
+ r_factor[i] = noise::musgrave_ridged_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ case 2: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float2 position = float2(pxyz[0], pxyz[1]);
+ r_factor[i] = noise::musgrave_ridged_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ case 3: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 position = vector[i] * scale[i];
+ r_factor[i] = noise::musgrave_ridged_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ case 4: {
+ const VArray<float3> &vector = get_vector(0);
+ const VArray<float> &w = get_w(1);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float pw = w[i] * scale[i];
+ const float4 position{pxyz[0], pxyz[1], pxyz[2], pw};
+ r_factor[i] = noise::musgrave_ridged_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case SHD_MUSGRAVE_HYBRID_MULTIFRACTAL: {
+ const VArray<float> &offset = get_offset(param++);
+ const VArray<float> &gain = get_gain(param++);
+ MutableSpan<float> r_factor = get_r_factor(param++);
+ const bool compute_factor = !r_factor.is_empty();
+ switch (dimensions_) {
+ case 1: {
+ const VArray<float> &w = get_w(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float position = w[i] * scale[i];
+ r_factor[i] = noise::musgrave_hybrid_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ case 2: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float2 position = float2(pxyz[0], pxyz[1]);
+ r_factor[i] = noise::musgrave_hybrid_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ case 3: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 position = vector[i] * scale[i];
+ r_factor[i] = noise::musgrave_hybrid_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ case 4: {
+ const VArray<float3> &vector = get_vector(0);
+ const VArray<float> &w = get_w(1);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float pw = w[i] * scale[i];
+ const float4 position{pxyz[0], pxyz[1], pxyz[2], pw};
+ r_factor[i] = noise::musgrave_hybrid_multi_fractal(
+ position, dimension[i], lacunarity[i], detail[i], offset[i], gain[i]);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case SHD_MUSGRAVE_FBM: {
+ MutableSpan<float> r_factor = get_r_factor(param++);
+ const bool compute_factor = !r_factor.is_empty();
+ switch (dimensions_) {
+ case 1: {
+ const VArray<float> &w = get_w(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float position = w[i] * scale[i];
+ r_factor[i] = noise::musgrave_fBm(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ case 2: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float2 position = float2(pxyz[0], pxyz[1]);
+ r_factor[i] = noise::musgrave_fBm(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ case 3: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 position = vector[i] * scale[i];
+ r_factor[i] = noise::musgrave_fBm(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ case 4: {
+ const VArray<float3> &vector = get_vector(0);
+ const VArray<float> &w = get_w(1);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float pw = w[i] * scale[i];
+ const float4 position{pxyz[0], pxyz[1], pxyz[2], pw};
+ r_factor[i] = noise::musgrave_fBm(
+ position, dimension[i], lacunarity[i], detail[i]);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case SHD_MUSGRAVE_HETERO_TERRAIN: {
+ const VArray<float> &offset = get_offset(param++);
+ MutableSpan<float> r_factor = get_r_factor(param++);
+ const bool compute_factor = !r_factor.is_empty();
+ switch (dimensions_) {
+ case 1: {
+ const VArray<float> &w = get_w(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float position = w[i] * scale[i];
+ r_factor[i] = noise::musgrave_hetero_terrain(
+ position, dimension[i], lacunarity[i], detail[i], offset[i]);
+ }
+ }
+ break;
+ }
+ case 2: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float2 position = float2(pxyz[0], pxyz[1]);
+ r_factor[i] = noise::musgrave_hetero_terrain(
+ position, dimension[i], lacunarity[i], detail[i], offset[i]);
+ }
+ }
+ break;
+ }
+ case 3: {
+ const VArray<float3> &vector = get_vector(0);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 position = vector[i] * scale[i];
+ r_factor[i] = noise::musgrave_hetero_terrain(
+ position, dimension[i], lacunarity[i], detail[i], offset[i]);
+ }
+ }
+ break;
+ }
+ case 4: {
+ const VArray<float3> &vector = get_vector(0);
+ const VArray<float> &w = get_w(1);
+ if (compute_factor) {
+ for (int64_t i : mask) {
+ const float3 pxyz = vector[i] * scale[i];
+ const float pw = w[i] * scale[i];
+ const float4 position{pxyz[0], pxyz[1], pxyz[2], pw};
+ r_factor[i] = noise::musgrave_hetero_terrain(
+ position, dimension[i], lacunarity[i], detail[i], offset[i]);
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+}; // namespace blender::nodes
+
+static void sh_node_musgrave_build_multi_function(
+ blender::nodes::NodeMultiFunctionBuilder &builder)
+{
+ bNode &node = builder.node();
+ NodeTexMusgrave *tex = (NodeTexMusgrave *)node.storage;
+ builder.construct_and_set_matching_fn<MusgraveFunction>(tex->dimensions, tex->musgrave_type);
+}
+
+} // namespace blender::nodes
+
void register_node_type_sh_tex_musgrave(void)
{
static bNodeType ntype;
- sh_node_type_base(&ntype, SH_NODE_TEX_MUSGRAVE, "Musgrave Texture", NODE_CLASS_TEXTURE, 0);
+ sh_fn_node_type_base(&ntype, SH_NODE_TEX_MUSGRAVE, "Musgrave Texture", NODE_CLASS_TEXTURE, 0);
ntype.declare = blender::nodes::sh_node_tex_musgrave_declare;
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
node_type_init(&ntype, node_shader_init_tex_musgrave);
@@ -136,6 +541,7 @@ void register_node_type_sh_tex_musgrave(void)
&ntype, "NodeTexMusgrave", node_free_standard_storage, node_copy_standard_storage);
node_type_gpu(&ntype, node_shader_gpu_tex_musgrave);
node_type_update(&ntype, node_shader_update_tex_musgrave);
+ ntype.build_multi_function = blender::nodes::sh_node_musgrave_build_multi_function;
nodeRegisterType(&ntype);
}