diff --git a/scripts/startup/nodeitems_builtins.py b/scripts/startup/nodeitems_builtins.py index b60fd8521e2..9d55396f028 100644 --- a/scripts/startup/nodeitems_builtins.py +++ b/scripts/startup/nodeitems_builtins.py @@ -225,6 +225,7 @@ shader_node_categories = [ NodeItem("ShaderNodeSdfPrimitive"), NodeItem("ShaderNodeSdfOp"), NodeItem("ShaderNodeSdfVectorOp"), + NodeItem("ShaderNodeSdfNoise"), ]), ShaderNodeCategory("SH_NEW_OP_COLOR", "Color", items=[ NodeItem("ShaderNodeMix", label="Mix Color", settings={"data_type": "'RGBA'"}), diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 697fc2fb878..b95321cceba 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -976,6 +976,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i #define SH_NODE_SDF_PRIMITIVE 802 #define SH_NODE_SDF_OP 803 #define SH_NODE_SDF_VECTOR_OP 804 +#define SH_NODE_SDF_NOISE 805 #define SH_NODE_SET_DEPTH 806 #define SH_NODE_CURVATURE 807 diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 71756787c5c..b4b0ddec3ee 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -515,6 +515,7 @@ set(GLSL_SRC shaders/material/gpu_shader_material_rgb_to_bw.glsl shaders/material/gpu_shader_material_screenspace_info.glsl shaders/material/gpu_shader_material_set_depth.glsl + shaders/material/gpu_shader_material_sdf_noise.glsl shaders/material/gpu_shader_material_sdf_util.glsl shaders/material/gpu_shader_material_sdf_primitive.glsl shaders/material/gpu_shader_material_sdf_op.glsl diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_sdf_noise.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_sdf_noise.glsl new file mode 100644 index 00000000000..5e32dbb0867 --- /dev/null +++ b/source/blender/gpu/shaders/material/gpu_shader_material_sdf_noise.glsl @@ -0,0 +1,79 @@ + +// http://iquilezles.org/www/articles/smin/smin.htm +float smin( float a, float b, float k ) +{ + float h = max(k-abs(a-b),0.0); + return min(a, b) - h*h*0.25/k; +} + +// http://iquilezles.org/www/articles/smin/smin.htm +float smax( float a, float b, float k ) +{ + float h = max(k-abs(a-b),0.0); + return max(a, b) + h*h*0.25/k; +} + +// https://iquilezles.org/www/articles/fbmsdf/fbmsdf.htm +float sph( vec3 i, vec3 f, vec3 c ) +{ + // random radius at grid vertex i+c (please replace this hash by + // something better if you plan to use this for a real application) + vec3 p = 17.0*fract( (i+c)*0.3183099+vec3(0.11,0.17,0.13) ); + float w = fract( p.x*p.y*p.z*(p.x+p.y+p.z) ); + float r = 0.7*w*w; + // distance to sphere at grid vertex i+c + return length(f-c) - r; +} + +// https://iquilezles.org/www/articles/fbmsdf/fbmsdf.htm +float sdBase( in vec3 p ) +{ + vec3 i = floor(p); + vec3 f = fract(p); + return min(min(min(sph(i,f,vec3(0,0,0)), + sph(i,f,vec3(0,0,1))), + min(sph(i,f,vec3(0,1,0)), + sph(i,f,vec3(0,1,1)))), + min(min(sph(i,f,vec3(1,0,0)), + sph(i,f,vec3(1,0,1))), + min(sph(i,f,vec3(1,1,0)), + sph(i,f,vec3(1,1,1))))); +} + +float sdFbm( + in vec3 p, + in float detail, + in float rough, + in float inflate, + in float smooth_fac, + in float d ) +{ + float s = 1.0; + for( int i=0; i < min(int(detail), 12); i++ ) + { + // evaluate new octave + float n = s*sdBase(p); + + // add + n = smax(n,d - inflate*s, smooth_fac*s ); + d = smin(n,d , smooth_fac*s ); + + // prepare next octave + p = mat3( 0.00, 1.60, 1.20, + -1.60, 0.72,-0.96, + -1.20,-0.96, 1.28 )*p; + s = rough*s; + } + return d; +} + +void node_sdf_noise(in vec3 pos, + in float dist_in, + in float detail, + in float rough, + in float inflate_fac, + in float smooth_fac, + out float dist_out) +{ + dist_out = sdFbm(pos, detail, rough, inflate_fac, smooth_fac, dist_in); +} diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 946a378e4d0..3b582156f13 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -130,6 +130,7 @@ DefNode(ShaderNode, SH_NODE_SHADER_INFO, def_sh_shader_info, "SHA DefNode(ShaderNode, SH_NODE_SCREENSPACE_INFO, 0, "SCREENSPACEINFO", ScreenspaceInfo, "Screenspace Info", "Sample internal colour and depth buffers") DefNode(ShaderNode, SH_NODE_SET_DEPTH, 0, "SET_DEPTH", SetDepth, "Set Depth", "Pixel depth offset") DefNode(ShaderNode, SH_NODE_CURVATURE, 0, "CURVATURE", Curvature, "Curvature", "" ) +DefNode(ShaderNode, SH_NODE_SDF_NOISE, 0, "SDF_NOISE", SdfNoise, "Sdf Noise", "" ) DefNode(CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" ) diff --git a/source/blender/nodes/shader/CMakeLists.txt b/source/blender/nodes/shader/CMakeLists.txt index e77148d9f56..1b539033a32 100644 --- a/source/blender/nodes/shader/CMakeLists.txt +++ b/source/blender/nodes/shader/CMakeLists.txt @@ -85,6 +85,7 @@ set(SRC nodes/node_shader_rgb_to_bw.cc nodes/node_shader_screenspace_info.cc nodes/node_shader_script.cc + nodes/node_shader_sdf_noise.cc nodes/node_shader_sdf_op.cc nodes/node_shader_sdf_primitive.cc nodes/node_shader_sdf_vector_op.cc diff --git a/source/blender/nodes/shader/node_shader_register.cc b/source/blender/nodes/shader/node_shader_register.cc index 3210ef93d8c..d44e7c42fed 100644 --- a/source/blender/nodes/shader/node_shader_register.cc +++ b/source/blender/nodes/shader/node_shader_register.cc @@ -116,4 +116,5 @@ void register_shader_nodes() register_node_type_sh_sdf_primitive(); register_node_type_sh_sdf_op(); register_node_type_sh_sdf_vector_op(); + register_node_type_sh_sdf_noise(); } diff --git a/source/blender/nodes/shader/node_shader_register.hh b/source/blender/nodes/shader/node_shader_register.hh index 9008478d501..c6349459a32 100644 --- a/source/blender/nodes/shader/node_shader_register.hh +++ b/source/blender/nodes/shader/node_shader_register.hh @@ -115,3 +115,4 @@ void register_node_type_sh_wireframe(); void register_node_type_sh_sdf_primitive(); void register_node_type_sh_sdf_op(); void register_node_type_sh_sdf_vector_op(); +void register_node_type_sh_sdf_noise(); diff --git a/source/blender/nodes/shader/nodes/node_shader_sdf_noise.cc b/source/blender/nodes/shader/nodes/node_shader_sdf_noise.cc new file mode 100644 index 00000000000..d58ae60917f --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_sdf_noise.cc @@ -0,0 +1,62 @@ +/* +* 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.hh" + +namespace blender::nodes::node_shader_sdf_noise_cc { +static void node_declare(NodeDeclarationBuilder &b) +{ + b.add_input(N_("Position")).hide_value(); + b.add_input(N_("Distance")); + b.add_input(N_("Detail")).default_value(4.f).max(12.f); + b.add_input(N_("Roughness")).default_value(0.5f) + .max(1.f).subtype(PROP_FACTOR); + b.add_input(N_("Detail Inflation")).default_value(0.1f) + .max(1.f).subtype(PROP_FACTOR); + b.add_input(N_("Detail Blend")).default_value(0.3f) + .max(1.f).subtype(PROP_FACTOR); + + b.add_output(N_("Distance")); +} +} + +static int node_shader_gpu_sdf_noise(GPUMaterial *mat, + bNode *node, + bNodeExecData* /* execdata */, + GPUNodeStack *in, + GPUNodeStack *out) +{ + node_shader_gpu_default_tex_coord(mat, node, &in[0].link); + + return GPU_stack_link(mat, node, "node_sdf_noise", in, out); +} + +/* node type definition */ +void register_node_type_sh_sdf_noise(void) +{ + namespace file_ns = blender::nodes::node_shader_sdf_noise_cc; + + static bNodeType ntype; + + sh_node_type_base(&ntype, SH_NODE_SDF_NOISE, "SDF Noise", NODE_CLASS_TEXTURE); + ntype.declare = file_ns::node_declare; + ntype.gpu_fn = node_shader_gpu_sdf_noise; + + nodeRegisterType(&ntype); +}