diff options
author | Bartosz Moniewski <monio> | 2020-02-17 14:31:38 +0300 |
---|---|---|
committer | Brecht Van Lommel <brecht@blender.org> | 2020-02-17 15:24:07 +0300 |
commit | 67d12bb5192d04a596e216f63cff2875fdd8cfbf (patch) | |
tree | c4d866f343ec9b87f713ebd004a8f343ab6f5307 | |
parent | ae9bbb4d0360aea694b46ee698d24dbc1476ebf3 (diff) |
Shading: add direction modes and phase offset to wave texture node
* Direction mode X, Y and Z to align with axes rather than diagonal or
spherical as previously. X is the new default, existing files will
use diagonal or spherical for compatibility.
* Phase offset to offset the wave along its direction, for purposes like
animation and distortion.
https://developer.blender.org/D6382
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_wave_texture.osl | 67 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_types.h | 17 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_wave.h | 91 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 44 | ||||
-rw-r--r-- | intern/cycles/render/nodes.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_blender_version.h | 2 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_cycles.c | 34 | ||||
-rw-r--r-- | source/blender/editors/space_node/drawnode.c | 8 | ||||
-rw-r--r-- | source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl | 69 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_node_types.h | 23 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 33 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_tex_wave.c | 18 |
13 files changed, 354 insertions, 58 deletions
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 635405e42c7..12009d6160c 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -770,6 +770,8 @@ static ShaderNode *add_node(Scene *scene, BL::ShaderNodeTexWave b_wave_node(b_node); WaveTextureNode *wave = new WaveTextureNode(); wave->type = (NodeWaveType)b_wave_node.wave_type(); + wave->bands_direction = (NodeWaveBandsDirection)b_wave_node.bands_direction(); + wave->rings_direction = (NodeWaveRingsDirection)b_wave_node.rings_direction(); wave->profile = (NodeWaveProfile)b_wave_node.wave_profile(); BL::TexMapping b_texture_mapping(b_wave_node.texture_mapping()); get_tex_mapping(&wave->tex_mapping, b_texture_mapping); diff --git a/intern/cycles/kernel/shaders/node_wave_texture.osl b/intern/cycles/kernel/shaders/node_wave_texture.osl index 5b27c570e42..5f97976e582 100644 --- a/intern/cycles/kernel/shaders/node_wave_texture.osl +++ b/intern/cycles/kernel/shaders/node_wave_texture.osl @@ -19,40 +19,81 @@ /* Wave */ -float wave(point p, string type, string profile, float detail, float distortion, float dscale) +float wave(point p, + string type, + string bands_direction, + string rings_direction, + string profile, + float detail, + float distortion, + float dscale, + float phase) { + /* Prevent precision issues on unit coordinates. */ + p = (p + 0.000001) * 0.999999; + float n = 0.0; if (type == "bands") { - n = (p[0] + p[1] + p[2]) * 10.0; + if (bands_direction == "x") { + n = p[0] * 20.0; + } + else if (bands_direction == "y") { + n = p[1] * 20.0; + } + else if (bands_direction == "z") { + n = p[2] * 20.0; + } + else { /* diagonal */ + n = (p[0] + p[1] + p[2]) * 10.0; + } } else if (type == "rings") { - n = length(p) * 20.0; + point rp = p; + if (rings_direction == "x") { + rp *= point(0.0, 1.0, 1.0); + } + else if (rings_direction == "y") { + rp *= point(1.0, 0.0, 1.0); + } + else if (rings_direction == "z") { + rp *= point(1.0, 1.0, 0.0); + } + /* else: "spherical" */ + + n = length(rp) * 20.0; } + n += phase; + if (distortion != 0.0) { n = n + (distortion * (fractal_noise(p * dscale, detail) * 2.0 - 1.0)); } if (profile == "sine") { - return 0.5 + 0.5 * sin(n); + return 0.5 + 0.5 * sin(n - M_PI_2); + } + else if (profile == "saw") { + n /= M_2PI; + return n - floor(n); } - else { - /* Saw profile */ + else { /* profile tri */ n /= M_2PI; - n -= (int)n; - return (n < 0.0) ? n + 1.0 : n; + return abs(n - floor(n + 0.5)) * 2.0; } } shader node_wave_texture(int use_mapping = 0, matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), string type = "bands", + string bands_direction = "x", + string rings_direction = "x", string profile = "sine", float Scale = 5.0, float Distortion = 0.0, float Detail = 2.0, float DetailScale = 1.0, + float PhaseOffset = 0.0, point Vector = P, output float Fac = 0.0, output color Color = 0.0) @@ -62,6 +103,14 @@ shader node_wave_texture(int use_mapping = 0, if (use_mapping) p = transform(mapping, p); - Fac = wave(p * Scale, type, profile, Detail, Distortion, DetailScale); + Fac = wave(p * Scale, + type, + bands_direction, + rings_direction, + profile, + Detail, + Distortion, + DetailScale, + PhaseOffset); Color = Fac; } diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 828b43eb8e4..45c299e0acb 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -384,9 +384,24 @@ typedef enum NodeMusgraveType { typedef enum NodeWaveType { NODE_WAVE_BANDS, NODE_WAVE_RINGS } NodeWaveType; -typedef enum NodeWaveProfiles { +typedef enum NodeWaveBandsDirection { + NODE_WAVE_BANDS_DIRECTION_X, + NODE_WAVE_BANDS_DIRECTION_Y, + NODE_WAVE_BANDS_DIRECTION_Z, + NODE_WAVE_BANDS_DIRECTION_DIAGONAL +} NodeWaveBandsDirection; + +typedef enum NodeWaveRingsDirection { + NODE_WAVE_RINGS_DIRECTION_X, + NODE_WAVE_RINGS_DIRECTION_Y, + NODE_WAVE_RINGS_DIRECTION_Z, + NODE_WAVE_RINGS_DIRECTION_SPHERICAL +} NodeWaveRingsDirection; + +typedef enum NodeWaveProfile { NODE_WAVE_PROFILE_SIN, NODE_WAVE_PROFILE_SAW, + NODE_WAVE_PROFILE_TRI, } NodeWaveProfile; typedef enum NodeSkyType { NODE_SKY_OLD, NODE_SKY_NEW } NodeSkyType; diff --git a/intern/cycles/kernel/svm/svm_wave.h b/intern/cycles/kernel/svm/svm_wave.h index 50c868c0f82..64102535f7d 100644 --- a/intern/cycles/kernel/svm/svm_wave.h +++ b/intern/cycles/kernel/svm/svm_wave.h @@ -19,52 +19,101 @@ CCL_NAMESPACE_BEGIN /* Wave */ ccl_device_noinline_cpu float svm_wave(NodeWaveType type, + NodeWaveBandsDirection bands_dir, + NodeWaveRingsDirection rings_dir, NodeWaveProfile profile, float3 p, float detail, float distortion, - float dscale) + float dscale, + float phase) { + /* Prevent precision issues on unit coordinates. */ + p = (p + 0.000001f) * 0.999999f; + float n; - if (type == NODE_WAVE_BANDS) - n = (p.x + p.y + p.z) * 10.0f; - else /* NODE_WAVE_RINGS */ - n = len(p) * 20.0f; + if (type == NODE_WAVE_BANDS) { + if (bands_dir == NODE_WAVE_BANDS_DIRECTION_X) { + n = p.x * 20.0f; + } + else if (bands_dir == NODE_WAVE_BANDS_DIRECTION_Y) { + n = p.y * 20.0f; + } + else if (bands_dir == NODE_WAVE_BANDS_DIRECTION_Z) { + n = p.z * 20.0f; + } + else { /* NODE_WAVE_BANDS_DIRECTION_DIAGONAL */ + n = (p.x + p.y + p.z) * 10.0f; + } + } + else { /* NODE_WAVE_RINGS */ + float3 rp = p; + if (rings_dir == NODE_WAVE_RINGS_DIRECTION_X) { + rp *= make_float3(0.0f, 1.0f, 1.0f); + } + else if (rings_dir == NODE_WAVE_RINGS_DIRECTION_Y) { + rp *= make_float3(1.0f, 0.0f, 1.0f); + } + else if (rings_dir == NODE_WAVE_RINGS_DIRECTION_Z) { + rp *= make_float3(1.0f, 1.0f, 0.0f); + } + /* else: NODE_WAVE_RINGS_DIRECTION_SPHERICAL */ + + n = len(rp) * 20.0f; + } + + n += phase; if (distortion != 0.0f) n += distortion * (fractal_noise_3d(p * dscale, detail) * 2.0f - 1.0f); if (profile == NODE_WAVE_PROFILE_SIN) { - return 0.5f + 0.5f * sinf(n); + return 0.5f + 0.5f * sinf(n - M_PI_2_F); + } + else if (profile == NODE_WAVE_PROFILE_SAW) { + n /= M_2PI_F; + return n - floorf(n); } - else { /* NODE_WAVE_PROFILE_SAW */ + else { /* NODE_WAVE_PROFILE_TRI */ n /= M_2PI_F; - n -= (int)n; - return (n < 0.0f) ? n + 1.0f : n; + return fabsf(n - floorf(n + 0.5f)) * 2.0f; } } ccl_device void svm_node_tex_wave( KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset) { - uint4 node2 = read_node(kg, offset); + uint4 defaults1 = read_node(kg, offset); + uint4 defaults2 = read_node(kg, offset); - uint type; - uint co_offset, scale_offset, detail_offset, dscale_offset, distortion_offset, color_offset, - fac_offset; + /* RNA properties */ + uint type_offset, bands_dir_offset, rings_dir_offset, profile_offset; + /* Inputs, Outputs */ + uint co_offset, scale_offset, distortion_offset, detail_offset, dscale_offset, phase_offset; + uint color_offset, fac_offset; - svm_unpack_node_uchar4(node.y, &type, &color_offset, &fac_offset, &dscale_offset); - svm_unpack_node_uchar4(node.z, &co_offset, &scale_offset, &detail_offset, &distortion_offset); + svm_unpack_node_uchar4( + node.y, &type_offset, &bands_dir_offset, &rings_dir_offset, &profile_offset); + svm_unpack_node_uchar4(node.z, &co_offset, &scale_offset, &distortion_offset, &detail_offset); + svm_unpack_node_uchar4(node.w, &dscale_offset, &phase_offset, &color_offset, &fac_offset); float3 co = stack_load_float3(stack, co_offset); - float scale = stack_load_float_default(stack, scale_offset, node2.x); - float detail = stack_load_float_default(stack, detail_offset, node2.y); - float distortion = stack_load_float_default(stack, distortion_offset, node2.z); - float dscale = stack_load_float_default(stack, dscale_offset, node2.w); + float scale = stack_load_float_default(stack, scale_offset, defaults1.x); + float detail = stack_load_float_default(stack, detail_offset, defaults1.y); + float distortion = stack_load_float_default(stack, distortion_offset, defaults1.z); + float dscale = stack_load_float_default(stack, dscale_offset, defaults1.w); + float phase = stack_load_float_default(stack, phase_offset, defaults2.x); - float f = svm_wave( - (NodeWaveType)type, (NodeWaveProfile)node.w, co * scale, detail, distortion, dscale); + float f = svm_wave((NodeWaveType)type_offset, + (NodeWaveBandsDirection)bands_dir_offset, + (NodeWaveRingsDirection)rings_dir_offset, + (NodeWaveProfile)profile_offset, + co * scale, + detail, + distortion, + dscale, + phase); if (stack_valid(fac_offset)) stack_store_float(stack, fac_offset, f); diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 3f5c2aacc98..83b973011a1 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1422,15 +1422,33 @@ NODE_DEFINE(WaveTextureNode) type_enum.insert("rings", NODE_WAVE_RINGS); SOCKET_ENUM(type, "Type", type_enum, NODE_WAVE_BANDS); + static NodeEnum bands_direction_enum; + bands_direction_enum.insert("x", NODE_WAVE_BANDS_DIRECTION_X); + bands_direction_enum.insert("y", NODE_WAVE_BANDS_DIRECTION_Y); + bands_direction_enum.insert("z", NODE_WAVE_BANDS_DIRECTION_Z); + bands_direction_enum.insert("diagonal", NODE_WAVE_BANDS_DIRECTION_DIAGONAL); + SOCKET_ENUM( + bands_direction, "Bands Direction", bands_direction_enum, NODE_WAVE_BANDS_DIRECTION_X); + + static NodeEnum rings_direction_enum; + rings_direction_enum.insert("x", NODE_WAVE_RINGS_DIRECTION_X); + rings_direction_enum.insert("y", NODE_WAVE_RINGS_DIRECTION_Y); + rings_direction_enum.insert("z", NODE_WAVE_RINGS_DIRECTION_Z); + rings_direction_enum.insert("spherical", NODE_WAVE_RINGS_DIRECTION_SPHERICAL); + SOCKET_ENUM( + rings_direction, "Rings Direction", rings_direction_enum, NODE_WAVE_BANDS_DIRECTION_X); + static NodeEnum profile_enum; profile_enum.insert("sine", NODE_WAVE_PROFILE_SIN); profile_enum.insert("saw", NODE_WAVE_PROFILE_SAW); + profile_enum.insert("tri", NODE_WAVE_PROFILE_TRI); SOCKET_ENUM(profile, "Profile", profile_enum, NODE_WAVE_PROFILE_SIN); SOCKET_IN_FLOAT(scale, "Scale", 1.0f); SOCKET_IN_FLOAT(distortion, "Distortion", 0.0f); SOCKET_IN_FLOAT(detail, "Detail", 2.0f); SOCKET_IN_FLOAT(detail_scale, "Detail Scale", 0.0f); + SOCKET_IN_FLOAT(phase, "Phase Offset", 0.0f); SOCKET_IN_POINT( vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); @@ -1446,32 +1464,36 @@ WaveTextureNode::WaveTextureNode() : TextureNode(node_type) void WaveTextureNode::compile(SVMCompiler &compiler) { + ShaderInput *vector_in = input("Vector"); ShaderInput *scale_in = input("Scale"); ShaderInput *distortion_in = input("Distortion"); - ShaderInput *dscale_in = input("Detail Scale"); ShaderInput *detail_in = input("Detail"); - ShaderInput *vector_in = input("Vector"); - ShaderOutput *fac_out = output("Fac"); + ShaderInput *dscale_in = input("Detail Scale"); + ShaderInput *phase_in = input("Phase Offset"); ShaderOutput *color_out = output("Color"); + ShaderOutput *fac_out = output("Fac"); int vector_offset = tex_mapping.compile_begin(compiler, vector_in); compiler.add_node(NODE_TEX_WAVE, - compiler.encode_uchar4(type, - compiler.stack_assign_if_linked(color_out), - compiler.stack_assign_if_linked(fac_out), - compiler.stack_assign_if_linked(dscale_in)), + compiler.encode_uchar4(type, bands_direction, rings_direction, profile), compiler.encode_uchar4(vector_offset, compiler.stack_assign_if_linked(scale_in), - compiler.stack_assign_if_linked(detail_in), - compiler.stack_assign_if_linked(distortion_in)), - profile); + compiler.stack_assign_if_linked(distortion_in), + compiler.stack_assign_if_linked(detail_in)), + compiler.encode_uchar4(compiler.stack_assign_if_linked(dscale_in), + compiler.stack_assign_if_linked(phase_in), + compiler.stack_assign_if_linked(color_out), + compiler.stack_assign_if_linked(fac_out))); compiler.add_node(__float_as_int(scale), __float_as_int(detail), __float_as_int(distortion), __float_as_int(detail_scale)); + compiler.add_node( + __float_as_int(phase), SVM_STACK_INVALID, SVM_STACK_INVALID, SVM_STACK_INVALID); + tex_mapping.compile_end(compiler, vector_in, vector_offset); } @@ -1480,6 +1502,8 @@ void WaveTextureNode::compile(OSLCompiler &compiler) tex_mapping.compile(compiler); compiler.parameter(this, "type"); + compiler.parameter(this, "bands_direction"); + compiler.parameter(this, "rings_direction"); compiler.parameter(this, "profile"); compiler.add(this, "node_wave_texture"); diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 56f709c8a79..8346ac77ae6 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -288,9 +288,11 @@ class WaveTextureNode : public TextureNode { } NodeWaveType type; + NodeWaveBandsDirection bands_direction; + NodeWaveRingsDirection rings_direction; NodeWaveProfile profile; - float scale, distortion, detail, detail_scale; + float scale, distortion, detail, detail_scale, phase; float3 vector; }; diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 24a114dbe83..09aa4ca7a6b 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -27,7 +27,7 @@ * \note Use #STRINGIFY() rather than defining with quotes. */ #define BLENDER_VERSION 283 -#define BLENDER_SUBVERSION 3 +#define BLENDER_SUBVERSION 4 /** Several breakages with 280, e.g. collections vs layers. */ #define BLENDER_MINVERSION 280 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenloader/intern/versioning_cycles.c b/source/blender/blenloader/intern/versioning_cycles.c index 466dd02b3b3..77167d887cf 100644 --- a/source/blender/blenloader/intern/versioning_cycles.c +++ b/source/blender/blenloader/intern/versioning_cycles.c @@ -1250,6 +1250,31 @@ static void update_noise_and_wave_distortion(bNodeTree *ntree) } } +/* Wave Texture node: Restore previous texture directions and offset. + * 1. In 2.81, Wave texture had fixed diagonal direction (Bands) or + * mapping along distance (Rings). Now, directions are customizable + * properties, with X axis being new default. To fix this we set new + * direction options to Diagonal and Spherical. + * 2. Sine profile is now negatively offseted by PI/2 to better match + * other profiles. To fix this we set new Phase Offset input to PI/2 + * in nodes with Sine profile. + */ +static void update_wave_node_directions_and_offset(bNodeTree *ntree) +{ + for (bNode *node = ntree->nodes.first; node; node = node->next) { + if (node->type == SH_NODE_TEX_WAVE) { + NodeTexWave *tex = (NodeTexWave *)node->storage; + tex->bands_direction = SHD_WAVE_BANDS_DIRECTION_DIAGONAL; + tex->rings_direction = SHD_WAVE_RINGS_DIRECTION_SPHERICAL; + + if (tex->wave_profile == SHD_WAVE_PROFILE_SIN) { + bNodeSocket *sockPhaseOffset = nodeFindSocket(node, SOCK_IN, "Phase Offset"); + *cycles_node_socket_float_value(sockPhaseOffset) = M_PI_2; + } + } + } +} + void blo_do_versions_cycles(FileData *UNUSED(fd), Library *UNUSED(lib), Main *bmain) { /* Particle shape shared with Eevee. */ @@ -1489,4 +1514,13 @@ void do_versions_after_linking_cycles(Main *bmain) } FOREACH_NODETREE_END; } + + if (!MAIN_VERSION_ATLEAST(bmain, 283, 4)) { + FOREACH_NODETREE_BEGIN (bmain, ntree, id) { + if (ntree->type == NTREE_SHADER) { + update_wave_node_directions_and_offset(ntree); + } + } + FOREACH_NODETREE_END; + } } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 121c597c1bb..a00006f7025 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -873,6 +873,14 @@ static void node_shader_buts_tex_brick(uiLayout *layout, bContext *UNUSED(C), Po static void node_shader_buts_tex_wave(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "wave_type", 0, "", ICON_NONE); + int type = RNA_enum_get(ptr, "wave_type"); + if (type == SHD_WAVE_BANDS) { + uiItemR(layout, ptr, "bands_direction", 0, "", ICON_NONE); + } + else { /* SHD_WAVE_RINGS */ + uiItemR(layout, ptr, "rings_direction", 0, "", ICON_NONE); + } + uiItemR(layout, ptr, "wave_profile", 0, "", ICON_NONE); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl index 957aa606a79..c72f9717af3 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_wave.glsl @@ -1,26 +1,64 @@ -float calc_wave( - vec3 p, float distortion, float detail, float detail_scale, int wave_type, int wave_profile) +float calc_wave(vec3 p, + float distortion, + float detail, + float detail_scale, + float phase, + int wave_type, + int bands_dir, + int rings_dir, + int wave_profile) { + /* Prevent precision issues on unit coordinates. */ + p = (p + 0.000001) * 0.999999; + float n; - if (wave_type == 0) { /* type bands */ - n = (p.x + p.y + p.z) * 10.0; + if (wave_type == 0) { /* type bands */ + if (bands_dir == 0) { /* X axis */ + n = p.x * 20.0; + } + else if (bands_dir == 1) { /* Y axis */ + n = p.y * 20.0; + } + else if (bands_dir == 2) { /* Z axis */ + n = p.z * 20.0; + } + else { /* Diagonal axis */ + n = (p.x + p.y + p.z) * 10.0; + } } else { /* type rings */ - n = length(p) * 20.0; + vec3 rp = p; + if (rings_dir == 0) { /* X axis */ + rp *= vec3(0.0, 1.0, 1.0); + } + else if (rings_dir == 1) { /* Y axis */ + rp *= vec3(1.0, 0.0, 1.0); + } + else if (rings_dir == 2) { /* Z axis */ + rp *= vec3(1.0, 1.0, 0.0); + } + /* else: Spherical */ + + n = length(rp) * 20.0; } + n += phase; + if (distortion != 0.0) { n += distortion * (fractal_noise(p * detail_scale, detail) * 2.0 - 1.0); } if (wave_profile == 0) { /* profile sin */ - return 0.5 + 0.5 * sin(n); + return 0.5 + 0.5 * sin(n - M_PI_2); + } + else if (wave_profile == 1) { /* profile saw */ + n /= 2.0 * M_PI; + return n - floor(n); } - else { /* profile saw */ + else { /* profile tri */ n /= 2.0 * M_PI; - n -= int(n); - return (n < 0.0) ? n + 1.0 : n; + return abs(n - floor(n + 0.5)) * 2.0; } } @@ -29,13 +67,24 @@ void node_tex_wave(vec3 co, float distortion, float detail, float detail_scale, + float phase, float wave_type, + float bands_dir, + float rings_dir, float wave_profile, out vec4 color, out float fac) { float f; - f = calc_wave(co * scale, distortion, detail, detail_scale, int(wave_type), int(wave_profile)); + f = calc_wave(co * scale, + distortion, + detail, + detail_scale, + phase, + int(wave_type), + int(bands_dir), + int(rings_dir), + int(wave_profile)); color = vec4(f, f, f, 1.0); fac = f; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index b7bb267db11..a8f33072915 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -896,6 +896,8 @@ typedef struct NodeTexMusgrave { typedef struct NodeTexWave { NodeTexBase base; int wave_type; + int bands_direction; + int rings_direction; int wave_profile; } NodeTexWave; @@ -1139,8 +1141,25 @@ enum { #define SHD_WAVE_BANDS 0 #define SHD_WAVE_RINGS 1 -#define SHD_WAVE_PROFILE_SIN 0 -#define SHD_WAVE_PROFILE_SAW 1 +enum { + SHD_WAVE_BANDS_DIRECTION_X = 0, + SHD_WAVE_BANDS_DIRECTION_Y = 1, + SHD_WAVE_BANDS_DIRECTION_Z = 2, + SHD_WAVE_BANDS_DIRECTION_DIAGONAL = 3, +}; + +enum { + SHD_WAVE_RINGS_DIRECTION_X = 0, + SHD_WAVE_RINGS_DIRECTION_Y = 1, + SHD_WAVE_RINGS_DIRECTION_Z = 2, + SHD_WAVE_RINGS_DIRECTION_SPHERICAL = 3, +}; + +enum { + SHD_WAVE_PROFILE_SIN = 0, + SHD_WAVE_PROFILE_SAW = 1, + SHD_WAVE_PROFILE_TRI = 2, +}; /* sky texture */ #define SHD_SKY_OLD 0 diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index cc833287aa7..e17fdb5359d 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -4556,9 +4556,30 @@ static void def_sh_tex_wave(StructRNA *srna) {0, NULL, 0, NULL, NULL}, }; + static EnumPropertyItem prop_wave_bands_direction_items[] = { + {SHD_WAVE_BANDS_DIRECTION_X, "X", 0, "X", "Bands across X axis"}, + {SHD_WAVE_BANDS_DIRECTION_Y, "Y", 0, "Y", "Bands across Y axis"}, + {SHD_WAVE_BANDS_DIRECTION_Z, "Z", 0, "Z", "Bands across Z axis"}, + {SHD_WAVE_BANDS_DIRECTION_DIAGONAL, "DIAGONAL", 0, "Diagonal", "Bands across diagonal axis"}, + {0, NULL, 0, NULL, NULL}, + }; + + static EnumPropertyItem prop_wave_rings_direction_items[] = { + {SHD_WAVE_RINGS_DIRECTION_X, "X", 0, "X", "Rings along X axis"}, + {SHD_WAVE_RINGS_DIRECTION_Y, "Y", 0, "Y", "Rings along Y axis"}, + {SHD_WAVE_RINGS_DIRECTION_Z, "Z", 0, "Z", "Rings along Z axis"}, + {SHD_WAVE_RINGS_DIRECTION_SPHERICAL, + "SPHERICAL", + 0, + "Spherical", + "Rings along spherical distance"}, + {0, NULL, 0, NULL, NULL}, + }; + static const EnumPropertyItem prop_wave_profile_items[] = { {SHD_WAVE_PROFILE_SIN, "SIN", 0, "Sine", "Use a standard sine profile"}, {SHD_WAVE_PROFILE_SAW, "SAW", 0, "Saw", "Use a sawtooth profile"}, + {SHD_WAVE_PROFILE_TRI, "TRI", 0, "Triangle", "Use a triangle profile"}, {0, NULL, 0, NULL, NULL}, }; @@ -4573,6 +4594,18 @@ static void def_sh_tex_wave(StructRNA *srna) RNA_def_property_ui_text(prop, "Wave Type", ""); RNA_def_property_update(prop, 0, "rna_Node_update"); + prop = RNA_def_property(srna, "bands_direction", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "bands_direction"); + RNA_def_property_enum_items(prop, prop_wave_bands_direction_items); + RNA_def_property_ui_text(prop, "Bands Direction", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); + + prop = RNA_def_property(srna, "rings_direction", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "rings_direction"); + RNA_def_property_enum_items(prop, prop_wave_rings_direction_items); + RNA_def_property_ui_text(prop, "Rings Direction", ""); + RNA_def_property_update(prop, 0, "rna_Node_update"); + prop = RNA_def_property(srna, "wave_profile", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "wave_profile"); RNA_def_property_enum_items(prop, prop_wave_profile_items); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.c b/source/blender/nodes/shader/nodes/node_shader_tex_wave.c index b525f4897a9..457e85519b2 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.c @@ -27,6 +27,7 @@ static bNodeSocketTemplate sh_node_tex_wave_in[] = { {SOCK_FLOAT, 1, N_("Distortion"), 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f}, {SOCK_FLOAT, 1, N_("Detail"), 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 16.0f}, {SOCK_FLOAT, 1, N_("Detail Scale"), 1.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f}, + {SOCK_FLOAT, 1, N_("Phase Offset"), 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f}, {-1, 0, ""}, }; @@ -62,7 +63,9 @@ static void node_shader_init_tex_wave(bNodeTree *UNUSED(ntree), bNode *node) BKE_texture_mapping_default(&tex->base.tex_mapping, TEXMAP_TYPE_POINT); BKE_texture_colormapping_default(&tex->base.color_mapping); tex->wave_type = SHD_WAVE_BANDS; - + tex->bands_direction = SHD_WAVE_BANDS_DIRECTION_X; + tex->rings_direction = SHD_WAVE_RINGS_DIRECTION_X; + tex->wave_profile = SHD_WAVE_PROFILE_SIN; node->storage = tex; } @@ -77,10 +80,19 @@ static int node_shader_gpu_tex_wave(GPUMaterial *mat, NodeTexWave *tex = (NodeTexWave *)node->storage; float wave_type = tex->wave_type; + float bands_direction = tex->bands_direction; + float rings_direction = tex->rings_direction; float wave_profile = tex->wave_profile; - return GPU_stack_link( - mat, node, "node_tex_wave", in, out, GPU_constant(&wave_type), GPU_constant(&wave_profile)); + return GPU_stack_link(mat, + node, + "node_tex_wave", + in, + out, + GPU_constant(&wave_type), + GPU_constant(&bands_direction), + GPU_constant(&rings_direction), + GPU_constant(&wave_profile)); } /* node type definition */ |