diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 44ff29d4bf8..1c53ca4c2aa 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -755,6 +755,7 @@ static ShaderNode *add_node(Scene *scene, voronoi->coloring = (NodeVoronoiColoring)b_voronoi_node.coloring(); voronoi->metric = (NodeVoronoiDistanceMetric)b_voronoi_node.distance(); voronoi->feature = (NodeVoronoiFeature)b_voronoi_node.feature(); + voronoi->periodic = b_voronoi_node.periodic(); BL::TexMapping b_texture_mapping(b_voronoi_node.texture_mapping()); get_tex_mapping(&voronoi->tex_mapping, b_texture_mapping); node = voronoi; diff --git a/intern/cycles/kernel/shaders/node_voronoi_texture.osl b/intern/cycles/kernel/shaders/node_voronoi_texture.osl index 2e47d74a414..29abeeb9d80 100644 --- a/intern/cycles/kernel/shaders/node_voronoi_texture.osl +++ b/intern/cycles/kernel/shaders/node_voronoi_texture.osl @@ -17,7 +17,7 @@ #include "stdosl.h" #include "node_texture.h" -void voronoi_m(point p, string metric, float e, float da[4], point pa[4]) +void voronoi_m(point co, float scale, int periodic, string metric, float e, point Jitter, float da[4], point pa[4], point coords[4], point cell[4]) { /* Compute the distance to and the position of the four closest neighbors to p. * @@ -26,6 +26,10 @@ void voronoi_m(point p, string metric, float e, float da[4], point pa[4]) * contain the distance to the closest point and its coordinates respectively. */ int xx, yy, zz, xi, yi, zi; + point ip, vp, pd, tp, pf; + float tscale; + + point p = co * scale; xi = (int)floor(p[0]); yi = (int)floor(p[1]); @@ -35,13 +39,29 @@ void voronoi_m(point p, string metric, float e, float da[4], point pa[4]) da[1] = 1e10; da[2] = 1e10; da[3] = 1e10; + + point jitter_in = clamp(Jitter, 0.0, 1.0); + + if(periodic){ + tscale = scale * 2.0; + pf = floor(p); + } for (xx = xi - 1; xx <= xi + 1; xx++) { for (yy = yi - 1; yy <= yi + 1; yy++) { for (zz = zi - 1; zz <= zi + 1; zz++) { - point ip = point(xx, yy, zz); - point vp = (point)cellnoise_color(ip); - point pd = p - (vp + ip); + if(periodic){ + ip = point(xx-xi, yy-yi, zz-zi); + tp = pf + ip; + point hash = (point)cellnoise_color(mod(tp, scale)) ; + pd = p - (tp + hash * jitter_in); + vp = hash * tscale; + } + else { + ip = point(xx, yy, zz); + vp = ip + (point)cellnoise_color(ip) * jitter_in; + pd = p - vp; + } float d = 0.0; if (metric == "distance") { @@ -56,8 +76,16 @@ void voronoi_m(point p, string metric, float e, float da[4], point pa[4]) else if (metric == "minkowski") { d = pow(pow(fabs(pd[0]), e) + pow(fabs(pd[1]), e) + pow(fabs(pd[2]), e), 1.0/e); } - - vp += point(xx, yy, zz); + else if (metric == "length") { + d = length(pd); + } + else if (metric == "sine") { + float len = length(pd); + d = len + (1.0 + sin(e * len))/2.0; + } + else if (metric == "triangular") { + d = max(fabs(pd[0])*0.866025+pd[1]*0.5,-pd[1]) + fabs(pd[2]*0.5); + } if (d < da[0]) { da[3] = da[2]; @@ -69,6 +97,16 @@ void voronoi_m(point p, string metric, float e, float da[4], point pa[4]) pa[2] = pa[1]; pa[1] = pa[0]; pa[0] = vp; + + coords[3] = coords[2]; + coords[2] = coords[1]; + coords[1] = coords[0]; + coords[0] = pd; + + cell[3] = cell[2]; + cell[2] = cell[1]; + cell[1] = cell[0]; + cell[0] = ip; } else if (d < da[1]) { da[3] = da[2]; @@ -78,6 +116,14 @@ void voronoi_m(point p, string metric, float e, float da[4], point pa[4]) pa[3] = pa[2]; pa[2] = pa[1]; pa[1] = vp; + + coords[3] = coords[2]; + coords[2] = coords[1]; + coords[1] = pd; + + cell[3] = cell[2]; + cell[2] = cell[1]; + cell[1] = ip; } else if (d < da[2]) { da[3] = da[2]; @@ -85,10 +131,18 @@ void voronoi_m(point p, string metric, float e, float da[4], point pa[4]) pa[3] = pa[2]; pa[2] = vp; + + coords[3] = coords[2]; + coords[2] = pd; + + cell[3] = cell[2]; + cell[2] = ip; } else if (d < da[3]) { da[3] = d; pa[3] = vp; + coords[3] = pd; + cell[3] = ip; } } } @@ -103,11 +157,15 @@ shader node_voronoi_texture( string coloring = "intensity", string metric = "distance", string feature = "F1", - float Exponent = 1.0, float Scale = 5.0, + float Exponent = 1.0, point Vector = P, + point Jitter = point(1.0,1.0,1.0), + int periodic = 0, output float Fac = 0.0, - output color Color = 0.0) + output color Color = 0.0, + output point Cell = 0.0, + output point Coords = 0.0) { point p = Vector; @@ -117,9 +175,36 @@ shader node_voronoi_texture( /* compute distance and point coordinate of 4 nearest neighbours */ float da[4]; point pa[4]; + point coords_out[4]; + point cell_out[4]; /* compute distance and point coordinate of 4 nearest neighbours */ - voronoi_m(p * Scale, metric, Exponent, da, pa); + voronoi_m(p, Scale, periodic, metric, Exponent, Jitter, da, pa, coords_out, cell_out); + + if (feature == "F1") { + Coords = coords_out[0]; + Cell = cell_out[0]; + } + else if (feature == "F2") { + Coords = coords_out[1]; + Cell = cell_out[1]; + } + else if (feature == "F3") { + Coords = coords_out[2]; + Cell = cell_out[2]; + } + else if (feature == "F4") { + Coords = coords_out[3]; + Cell = cell_out[3]; + } + else if (feature == "F2F1") { + Coords = coords_out[1] - coords_out[0]; + Cell = cell_out[1] - cell_out[0]; + } + + if(Scale != 0.0){ + Cell /= Scale; + } if (coloring == "intensity") { /* Intensity output */ diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 8b15d7bf9f4..065e529fac1 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -343,7 +343,10 @@ typedef enum NodeVoronoiDistanceMetric { NODE_VORONOI_DISTANCE, NODE_VORONOI_MANHATTAN, NODE_VORONOI_CHEBYCHEV, - NODE_VORONOI_MINKOWSKI + NODE_VORONOI_MINKOWSKI, + NODE_VORONOI_LENGTH, + NODE_VORONOI_SINE, + NODE_VORONOI_TRIANGULAR } NodeVoronoiDistanceMetric; typedef enum NodeVoronoiFeature { diff --git a/intern/cycles/kernel/svm/svm_voronoi.h b/intern/cycles/kernel/svm/svm_voronoi.h index d661df54ead..511c1c67a18 100644 --- a/intern/cycles/kernel/svm/svm_voronoi.h +++ b/intern/cycles/kernel/svm/svm_voronoi.h @@ -18,7 +18,7 @@ CCL_NAMESPACE_BEGIN /* Voronoi */ -ccl_device void voronoi_neighbors(float3 p, NodeVoronoiDistanceMetric distance, float e, float da[4], float3 pa[4]) +ccl_device void voronoi_neighbors(float3 co, float scale, int tiled, NodeVoronoiDistanceMetric distance, float e, float3 jitter, float da[4], float3 pa[4], float3 coords[4], float3 cell[4]) { /* Compute the distance to and the position of the closest neighbors to p. * @@ -27,6 +27,8 @@ ccl_device void voronoi_neighbors(float3 p, NodeVoronoiDistanceMetric distance, * contain the distance to the closest point and its coordinates respectively. */ + float3 p = co * scale; + da[0] = 1e10f; da[1] = 1e10f; da[2] = 1e10f; @@ -38,27 +40,51 @@ ccl_device void voronoi_neighbors(float3 p, NodeVoronoiDistanceMetric distance, pa[3] = make_float3(0.0f, 0.0f, 0.0f); int3 xyzi = quick_floor_to_int3(p); + + int3 ip; + float3 fp, vp, pd, pf; + float tscale; + + jitter = clamp(jitter, make_float3(0.0, 0.0, 0.0), make_float3(1.0, 1.0, 1.0)); + + if (tiled) { + tscale = scale * 2.0f; + pf = make_float3(floorf(p.x), floorf(p.y), floorf(p.z)); + } for(int xx = -1; xx <= 1; xx++) { for(int yy = -1; yy <= 1; yy++) { - for(int zz = -1; zz <= 1; zz++) { - int3 ip = xyzi + make_int3(xx, yy, zz); - float3 fp = make_float3(ip.x, ip.y, ip.z); - float3 vp = fp + cellnoise3(fp); + for(int zz = -1; zz <= 1; zz++) { + if (tiled) { + ip = xyzi + make_int3(xx - xyzi.x, yy - xyzi.y, zz - xyzi.z); + fp = make_float3(ip.x, ip.y, ip.z); + float3 tp = pf + fp; + float3 mtp = make_float3(fmodf(tp.x, scale), fmodf(tp.y, scale), fmodf(tp.z, scale)); + float3 hash = cellnoise3(mtp); + pd = p - (tp + hash * jitter); + vp = hash * tscale; + } + else { + ip = xyzi + make_int3(xx, yy, zz); + fp = make_float3(ip.x, ip.y, ip.z); + vp = fp + cellnoise3(fp) * jitter; + pd = p - vp; + } float d; switch(distance) { - case NODE_VORONOI_DISTANCE: - d = len_squared(p - vp); + default: + case NODE_VORONOI_DISTANCE: + d = len_squared(pd); break; case NODE_VORONOI_MANHATTAN: - d = reduce_add(fabs(vp - p)); + d = reduce_add(fabs(pd)); break; case NODE_VORONOI_CHEBYCHEV: - d = max3(fabs(vp - p)); + d = max3(fabs(pd)); break; case NODE_VORONOI_MINKOWSKI: { - float3 n = fabs(vp - p); + float3 n = fabs(pd); if(e == 0.5f) { d = sqr(reduce_add(sqrt(n))); } @@ -66,6 +92,19 @@ ccl_device void voronoi_neighbors(float3 p, NodeVoronoiDistanceMetric distance, d = powf(reduce_add(pow3(n, e)), 1.0f/e); } break; + } + case NODE_VORONOI_LENGTH: { + d = len(pd); + break; + } + case NODE_VORONOI_SINE: { + float dl = len(pd); + d = dl + (1.0f + sinf(e * dl)) / 2.0f; + break; + } + case NODE_VORONOI_TRIANGULAR: { + d = max(fabsf(pd[0])*0.866025f + pd[1] * 0.5f, -pd[1]) + fabsf(pd[2] * 0.5f); + break; } } @@ -80,6 +119,16 @@ ccl_device void voronoi_neighbors(float3 p, NodeVoronoiDistanceMetric distance, pa[2] = pa[1]; pa[1] = pa[0]; pa[0] = vp; + + coords[3] = coords[2]; + coords[2] = coords[1]; + coords[1] = coords[0]; + coords[0] = pd; + + cell[3] = cell[2]; + cell[2] = cell[1]; + cell[1] = cell[0]; + cell[0] = fp; } else if(d < da[1]) { da[3] = da[2]; @@ -89,6 +138,14 @@ ccl_device void voronoi_neighbors(float3 p, NodeVoronoiDistanceMetric distance, pa[3] = pa[2]; pa[2] = pa[1]; pa[1] = vp; + + coords[3] = coords[2]; + coords[2] = coords[1]; + coords[1] = pd; + + cell[3] = cell[2]; + cell[2] = cell[1]; + cell[1] = fp; } else if(d < da[2]) { da[3] = da[2]; @@ -96,10 +153,18 @@ ccl_device void voronoi_neighbors(float3 p, NodeVoronoiDistanceMetric distance, pa[3] = pa[2]; pa[2] = vp; + + coords[3] = coords[2]; + coords[2] = pd; + + cell[3] = cell[2]; + cell[2] = fp; } else if(d < da[3]) { da[3] = d; pa[3] = vp; + coords[3] = pd; + cell[3] = fp; } } } @@ -112,20 +177,41 @@ ccl_device void svm_node_tex_voronoi(KernelGlobals *kg, ShaderData *sd, float *s uint co_offset, coloring, distance, feature; uint scale_offset, e_offset, fac_offset, color_offset; + uint jitter_offset, coords_offset, cell_offset, use_tiles; decode_node_uchar4(node.y, &co_offset, &coloring, &distance, &feature); decode_node_uchar4(node.z, &scale_offset, &e_offset, &fac_offset, &color_offset); + decode_node_uchar4(node.w, &jitter_offset, &coords_offset, &cell_offset, &use_tiles); float3 co = stack_load_float3(stack, co_offset); float scale = stack_load_float_default(stack, scale_offset, node2.x); float exponent = stack_load_float_default(stack, e_offset, node2.y); + float3 jitter = stack_load_float3(stack, jitter_offset); float dist[4]; float3 neighbor[4]; - voronoi_neighbors(co*scale, (NodeVoronoiDistanceMetric)distance, exponent, dist, neighbor); + float3 coords_out[4]; + float3 cell_out[4]; + + voronoi_neighbors(co, scale, (int)use_tiles, (NodeVoronoiDistanceMetric)distance, exponent, jitter, dist, neighbor, coords_out, cell_out); float3 color; float fac; + float3 coords; + float3 cell; + + switch (feature) { + case NODE_VORONOI_F1: coords = coords_out[0]; cell = cell_out[0]; break; + case NODE_VORONOI_F2: coords = coords_out[1]; cell = cell_out[1]; break; + case NODE_VORONOI_F3: coords = coords_out[2]; cell = cell_out[2]; break; + case NODE_VORONOI_F4: coords = coords_out[3]; cell = cell_out[3]; break; + case NODE_VORONOI_F2F1: coords = (coords_out[1] - coords_out[0]); cell = (cell_out[1] - cell_out[0]); break; + } + + if (scale != 0.0f) { + cell /= scale; + } + if(coloring == NODE_VORONOI_INTENSITY) { switch(feature) { case NODE_VORONOI_F1: fac = dist[0]; break; @@ -155,6 +241,8 @@ ccl_device void svm_node_tex_voronoi(KernelGlobals *kg, ShaderData *sd, float *s if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, fac); if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, color); + if(stack_valid(coords_offset)) stack_store_float3(stack, coords_offset, coords); + if(stack_valid(cell_offset)) stack_store_float3(stack, cell_offset, cell); } CCL_NAMESPACE_END diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index cc9dd8f2679..1748cc3e3db 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -918,6 +918,9 @@ NODE_DEFINE(VoronoiTextureNode) metric.insert("manhattan", NODE_VORONOI_MANHATTAN); metric.insert("chebychev", NODE_VORONOI_CHEBYCHEV); metric.insert("minkowski", NODE_VORONOI_MINKOWSKI); + metric.insert("length", NODE_VORONOI_LENGTH); + metric.insert("sine", NODE_VORONOI_SINE); + metric.insert("triangular", NODE_VORONOI_TRIANGULAR); SOCKET_ENUM(metric, "Distance Metric", metric, NODE_VORONOI_INTENSITY); static NodeEnum feature_enum; @@ -927,10 +930,13 @@ NODE_DEFINE(VoronoiTextureNode) feature_enum.insert("F4", NODE_VORONOI_F4); feature_enum.insert("F2F1", NODE_VORONOI_F2F1); SOCKET_ENUM(feature, "Feature", feature_enum, NODE_VORONOI_INTENSITY); - + + SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); SOCKET_IN_FLOAT(scale, "Scale", 1.0f); SOCKET_IN_FLOAT(exponent, "Exponent", 0.5f); - SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); + SOCKET_IN_POINT(jitter, "Jitter", make_float3(1.0f, 1.0f, 1.0f)); + + SOCKET_BOOLEAN(periodic, "Tileable", false); SOCKET_OUT_COLOR(color, "Color"); SOCKET_OUT_FLOAT(fac, "Fac"); @@ -945,15 +951,20 @@ VoronoiTextureNode::VoronoiTextureNode() void VoronoiTextureNode::compile(SVMCompiler& compiler) { - ShaderInput *scale_in = input("Scale"); ShaderInput *vector_in = input("Vector"); + ShaderInput *scale_in = input("Scale"); + ShaderInput *exponent_in = input("Exponent"); + ShaderInput *jitter_in = input("Jitter"); ShaderOutput *color_out = output("Color"); ShaderOutput *fac_out = output("Fac"); + ShaderOutput *coords_out = output("Coords"); + ShaderOutput *cell_out = output("Cell"); if(vector_in->link) compiler.stack_assign(vector_in); if(scale_in->link) compiler.stack_assign(scale_in); if(exponent_in->link) compiler.stack_assign(exponent_in); + if(jitter_in->link) compiler.stack_assign(jitter_in); int vector_offset = tex_mapping.compile_begin(compiler, vector_in); @@ -969,10 +980,18 @@ void VoronoiTextureNode::compile(SVMCompiler& compiler) compiler.stack_assign_if_linked(exponent_in), compiler.stack_assign(fac_out), compiler.stack_assign(color_out) - )); + ), + compiler.encode_uchar4( + compiler.stack_assign(jitter_in), + compiler.stack_assign(coords_out), + compiler.stack_assign(cell_out), + periodic + ) + ); compiler.add_node( __float_as_int(scale), - __float_as_int(exponent)); + __float_as_int(exponent) + ); tex_mapping.compile_end(compiler, vector_in, vector_offset); } @@ -984,6 +1003,7 @@ void VoronoiTextureNode::compile(OSLCompiler& compiler) compiler.parameter(this, "coloring"); compiler.parameter(this, "metric"); compiler.parameter(this, "feature"); + compiler.parameter(this, "periodic"); compiler.add(this, "node_voronoi_texture"); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 5571c525e9a..6de16e8532d 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -193,7 +193,8 @@ public: NodeVoronoiDistanceMetric metric; NodeVoronoiFeature feature; float scale, exponent; - float3 vector; + float3 vector, jitter; + bool periodic; }; class MusgraveTextureNode : public TextureNode { diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c index fe8c2f1e107..8abbaa64fd2 100644 --- a/source/blender/draw/engines/eevee/eevee_subsurface.c +++ b/source/blender/draw/engines/eevee/eevee_subsurface.c @@ -253,14 +253,11 @@ void EEVEE_subsurface_add_pass( DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src); DRW_shgroup_uniform_texture_ref(grp, "sssData", &effects->sss_blur); + DRW_shgroup_uniform_texture_ref(grp, "sssAlbedo", &effects->sss_albedo); DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); DRW_shgroup_stencil_mask(grp, sss_id); DRW_shgroup_call_add(grp, quad, NULL); - - if (effects->sss_separate_albedo) { - DRW_shgroup_uniform_texture_ref(grp, "sssAlbedo", &effects->sss_albedo); - } } } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index be26f67b936..bd43db3cd20 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -892,6 +892,7 @@ static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext *UNUSED(C), uiItemR(layout, ptr, "coloring", 0, "", ICON_NONE); uiItemR(layout, ptr, "distance", 0, "", ICON_NONE); uiItemR(layout, ptr, "feature", 0, "", ICON_NONE); + uiItemR(layout, ptr, "periodic", 0, IFACE_("Periodic"), 0); } static void node_shader_buts_tex_pointdensity(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 034f93cc273..a73438a0f75 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -2794,23 +2794,43 @@ void node_tex_sky(vec3 co, out vec4 color) color = vec4(1.0); } -void node_tex_voronoi(vec3 co, float scale, float exponent, float coloring, float metric, float feature, out vec4 color, out float fac) +void node_tex_voronoi(vec3 co, float scale, float exponent, vec3 jitter, float coloring, float metric, float feature, float periodic, out vec4 color, out float fac, out vec3 coords_out, out vec3 cell_out) { vec3 p = co * scale; int xx, yy, zz, xi, yi, zi; vec4 da = vec4(1e10); vec3 pa[4] = vec3[4](vec3(0.0), vec3(0.0), vec3(0.0), vec3(0.0)); - + float tscale; + vec3 coords[4]; + vec3 cell[4]; + vec3 ip, vp, pd, tp, pf; + xi = floor_to_int(p[0]); yi = floor_to_int(p[1]); zi = floor_to_int(p[2]); + + jitter = clamp(jitter,0.0,1.0); + + if(periodic == 1){ + tscale = scale * 2.0; + pf = floor(p); + } for (xx = xi - 1; xx <= xi + 1; xx++) { for (yy = yi - 1; yy <= yi + 1; yy++) { for (zz = zi - 1; zz <= zi + 1; zz++) { - vec3 ip = vec3(xx, yy, zz); - vec3 vp = cellnoise_color(ip); - vec3 pd = p - (vp + ip); + if(periodic == 1){ + ip = vec3(xx-xi, yy-yi, zz-zi); + tp = pf + ip; + vec3 hash = cellnoise_color(mod(tp, scale)); + pd = p - (tp + hash * jitter); + vp = hash * tscale; + } + else { + ip = vec3(xx, yy, zz); + vp = ip + cellnoise_color(ip) * jitter; + pd = p - vp; + } float d = 0.0; if (metric == 0.0) { /* SHD_VORONOI_DISTANCE 0 */ @@ -2825,8 +2845,17 @@ void node_tex_voronoi(vec3 co, float scale, float exponent, float coloring, floa else if (metric == 3.0) { /* SHD_VORONOI_MINKOWSKI 3 */ d = pow(pow(abs(pd[0]), exponent) + pow(abs(pd[1]), exponent) + pow(abs(pd[2]), exponent), 1.0/exponent); } - - vp += vec3(xx, yy, zz); + else if (metric == 4) { /* SHD_VORONOI_LENGTH 4 */ + d = length(pd); + } + else if (metric == 5) { /* SHD_VORONOI_SINE 5 */ + float len = length(pd); + d = len + (1.0 + sin(exponent * len))/2.0; + } + else if (metric == 6) { /* SHD_VORONOI_TRIANGULAR 6 */ + d = max(abs(pd[0])*0.866025+(pd[1])*0.5,-(pd[1])) + abs(pd[2]*0.5); + } + if (d < da[0]) { da.yzw = da.xyz; da[0] = d; @@ -2835,6 +2864,16 @@ void node_tex_voronoi(vec3 co, float scale, float exponent, float coloring, floa pa[2] = pa[1]; pa[1] = pa[0]; pa[0] = vp; + + coords[3] = coords[2]; + coords[2] = coords[1]; + coords[1] = coords[0]; + coords[0] = pd; + + cell[3] = cell[2]; + cell[2] = cell[1]; + cell[1] = cell[0]; + cell[0] = ip; } else if (d < da[1]) { da.zw = da.yz; @@ -2843,6 +2882,14 @@ void node_tex_voronoi(vec3 co, float scale, float exponent, float coloring, floa pa[3] = pa[2]; pa[2] = pa[1]; pa[1] = vp; + + coords[3] = coords[2]; + coords[2] = coords[1]; + coords[1] = pd; + + cell[3] = cell[2]; + cell[2] = cell[1]; + cell[1] = ip; } else if (d < da[2]) { da[3] = da[2]; @@ -2850,15 +2897,48 @@ void node_tex_voronoi(vec3 co, float scale, float exponent, float coloring, floa pa[3] = pa[2]; pa[2] = vp; + + coords[3] = coords[2]; + coords[2] = pd; + + cell[3] = cell[2]; + cell[2] = ip; } else if (d < da[3]) { da[3] = d; pa[3] = vp; + coords[3] = pd; + cell[3] = ip; } } } } - + + if (feature == 0) { /* F1 */ + coords_out = coords[0]; + cell_out = cell[0]; + } + else if (feature == 1) { /* F2 */ + coords_out = coords[1]; + cell_out = cell[1]; + } + else if (feature == 2) { /* F3 */ + coords_out = coords[2]; + cell_out = cell[2]; + } + else if (feature == 3) { /* F4 */ + coords_out = coords[3]; + cell_out = cell[3]; + } + else if (feature == 4) { /* F2F1 */ + coords_out = abs(coords[1] - coords[0]); + cell_out = abs(cell[1] - cell[0]); + } + + if(scale != 0.0) { + cell_out /= scale; + } + if (coloring == 0.0) { /* Intensity output */ if (feature == 0.0) { /* F1 */ diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 0f06aed8bca..5e9cad1054a 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -891,7 +891,7 @@ typedef struct NodeTexVoronoi { int coloring; int distance; int feature; - char _pad[4]; + int periodic; } NodeTexVoronoi; typedef struct NodeTexMusgrave { @@ -1110,6 +1110,9 @@ typedef struct NodeCryptomatte { #define SHD_VORONOI_MANHATTAN 1 #define SHD_VORONOI_CHEBYCHEV 2 #define SHD_VORONOI_MINKOWSKI 3 +#define SHD_VORONOI_LENGTH 4 +#define SHD_VORONOI_SINE 5 +#define SHD_VORONOI_TRIANGULAR 6 #define SHD_VORONOI_INTENSITY 0 #define SHD_VORONOI_CELLS 1 diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 44cf15995f9..27d0fdd32ab 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -4036,10 +4036,13 @@ static void def_sh_tex_voronoi(StructRNA *srna) }; static EnumPropertyItem prop_distance_items[] = { - { SHD_VORONOI_DISTANCE, "DISTANCE", 0, "Distance", "Distance" }, + { SHD_VORONOI_DISTANCE, "DISTANCE", 0, "Distance", "Distance sqaured" }, { SHD_VORONOI_MANHATTAN, "MANHATTAN", 0, "Manhattan", "Manhattan (city block) distance" }, { SHD_VORONOI_CHEBYCHEV, "CHEBYCHEV", 0, "Chebychev", "Chebychev distance" }, { SHD_VORONOI_MINKOWSKI, "MINKOWSKI", 0, "Minkowski", "Minkowski distance" }, + { SHD_VORONOI_LENGTH, "LENGTH", 0, "Actual Distance", "Actual distance" }, + { SHD_VORONOI_SINE, "SINE", 0, "Sine", "Sine distance" }, + { SHD_VORONOI_TRIANGULAR, "TRIANGULAR", 0, "Triangular", "Triangular distance" }, { 0, NULL, 0, NULL, NULL } }; @@ -4074,6 +4077,11 @@ static void def_sh_tex_voronoi(StructRNA *srna) RNA_def_property_enum_items(prop, prop_feature_items); RNA_def_property_ui_text(prop, "Feature Output", ""); RNA_def_property_update(prop, 0, "rna_Node_update"); + + prop = RNA_def_property(srna, "periodic", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "periodic", 0); + RNA_def_property_ui_text(prop, "Periodic", "Make texture periodic"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } static void def_sh_tex_wave(StructRNA *srna) diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c index bd3dc0d2c79..7d5ed70d639 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.c @@ -25,12 +25,15 @@ static bNodeSocketTemplate sh_node_tex_voronoi_in[] = { { SOCK_VECTOR, 1, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { SOCK_FLOAT, 1, N_("Scale"), 5.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f}, { SOCK_FLOAT, 1, N_("Exponent"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 32.0f}, + { SOCK_VECTOR, 1, N_("Jitter"), 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f}, { -1, 0, "" }, }; static bNodeSocketTemplate sh_node_tex_voronoi_out[] = { { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK}, { SOCK_FLOAT, 0, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR, SOCK_NO_INTERNAL_LINK}, + { SOCK_VECTOR, 0, N_("Coords"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK }, + { SOCK_VECTOR, 0, N_("Cell"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_NO_INTERNAL_LINK }, { -1, 0, "" }, }; @@ -59,8 +62,9 @@ static int node_shader_gpu_tex_voronoi(GPUMaterial *mat, bNode *node, bNodeExecD float coloring = tex->coloring; float metric = tex->distance; float feature = tex->feature; - - return GPU_stack_link(mat, node, "node_tex_voronoi", in, out, GPU_constant(&coloring), GPU_constant(&metric), GPU_constant(&feature)); + float periodic = tex->periodic; + + return GPU_stack_link(mat, node, "node_tex_voronoi", in, out, GPU_constant(&coloring), GPU_constant(&metric), GPU_constant(&feature), GPU_constant(&periodic)); } static void node_shader_update_tex_voronoi(bNodeTree *UNUSED(ntree), bNode *node) @@ -70,7 +74,7 @@ static void node_shader_update_tex_voronoi(bNodeTree *UNUSED(ntree), bNode *node for (sock = node->inputs.first; sock; sock = sock->next) { if (STREQ(sock->name, "Exponent")) { - if (tex->distance == SHD_VORONOI_MINKOWSKI) { + if (tex->distance == SHD_VORONOI_MINKOWSKI || tex->distance == SHD_VORONOI_SINE) { sock->flag &= ~SOCK_UNAVAIL; } else {