forked from bartvdbraak/blender
Cycles: add voronoi features and distance settings from Blender.
Features to get the 2nd, 3rd, 4th closest point instead of the closest, and various distance metrics. No viewport/Eevee support yet. Patch by Michel Anders, Charlie Jolly and Brecht Van Lommel. Differential Revision: https://developer.blender.org/D3503
This commit is contained in:
parent
4697604331
commit
83a4e1aaf9
@ -748,6 +748,8 @@ static ShaderNode *add_node(Scene *scene,
|
||||
BL::ShaderNodeTexVoronoi b_voronoi_node(b_node);
|
||||
VoronoiTextureNode *voronoi = new VoronoiTextureNode();
|
||||
voronoi->coloring = (NodeVoronoiColoring)b_voronoi_node.coloring();
|
||||
voronoi->metric = (NodeVoronoiDistanceMetric)b_voronoi_node.distance();
|
||||
voronoi->feature = (NodeVoronoiFeature)b_voronoi_node.feature();
|
||||
BL::TexMapping b_texture_mapping(b_voronoi_node.texture_mapping());
|
||||
get_tex_mapping(&voronoi->tex_mapping, b_texture_mapping);
|
||||
node = voronoi;
|
||||
|
@ -17,12 +17,93 @@
|
||||
#include "stdosl.h"
|
||||
#include "node_texture.h"
|
||||
|
||||
void voronoi_m(point p, string metric, float e, float da[4], point pa[4])
|
||||
{
|
||||
/* Compute the distance to and the position of the four closest neighbors to p.
|
||||
*
|
||||
* The neighbors are randomly placed, 1 each in a 3x3x3 grid (Worley pattern).
|
||||
* The distances and points are returned in ascending order, i.e. da[0] and pa[0] will
|
||||
* contain the distance to the closest point and its coordinates respectively.
|
||||
*/
|
||||
int xx, yy, zz, xi, yi, zi;
|
||||
|
||||
xi = (int)floor(p[0]);
|
||||
yi = (int)floor(p[1]);
|
||||
zi = (int)floor(p[2]);
|
||||
|
||||
da[0] = 1e10;
|
||||
da[1] = 1e10;
|
||||
da[2] = 1e10;
|
||||
da[3] = 1e10;
|
||||
|
||||
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);
|
||||
|
||||
float d = 0.0;
|
||||
if (metric == "distance") {
|
||||
d = dot(pd, pd);
|
||||
}
|
||||
else if (metric == "manhattan") {
|
||||
d = fabs(pd[0]) + fabs(pd[1]) + fabs(pd[2]);
|
||||
}
|
||||
else if (metric == "chebychev") {
|
||||
d = max(fabs(pd[0]), max(fabs(pd[1]), fabs(pd[2])));
|
||||
}
|
||||
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);
|
||||
|
||||
if (d < da[0]) {
|
||||
da[3] = da[2];
|
||||
da[2] = da[1];
|
||||
da[1] = da[0];
|
||||
da[0] = d;
|
||||
|
||||
pa[3] = pa[2];
|
||||
pa[2] = pa[1];
|
||||
pa[1] = pa[0];
|
||||
pa[0] = vp;
|
||||
}
|
||||
else if (d < da[1]) {
|
||||
da[3] = da[2];
|
||||
da[2] = da[1];
|
||||
da[1] = d;
|
||||
|
||||
pa[3] = pa[2];
|
||||
pa[2] = pa[1];
|
||||
pa[1] = vp;
|
||||
}
|
||||
else if (d < da[2]) {
|
||||
da[3] = da[2];
|
||||
da[2] = d;
|
||||
|
||||
pa[3] = pa[2];
|
||||
pa[2] = vp;
|
||||
}
|
||||
else if (d < da[3]) {
|
||||
da[3] = d;
|
||||
pa[3] = vp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Voronoi */
|
||||
|
||||
shader node_voronoi_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 coloring = "intensity",
|
||||
string metric = "distance",
|
||||
string feature = "F1",
|
||||
float Exponent = 1.0,
|
||||
float Scale = 5.0,
|
||||
point Vector = P,
|
||||
output float Fac = 0.0,
|
||||
@ -37,17 +118,48 @@ shader node_voronoi_texture(
|
||||
float da[4];
|
||||
point pa[4];
|
||||
|
||||
voronoi(p * Scale, 1.0, da, pa);
|
||||
/* compute distance and point coordinate of 4 nearest neighbours */
|
||||
voronoi_m(p * Scale, metric, Exponent, da, pa);
|
||||
|
||||
/* Colored output */
|
||||
if (coloring == "intensity") {
|
||||
Fac = fabs(da[0]);
|
||||
/* Intensity output */
|
||||
if (feature == "F1") {
|
||||
Fac = fabs(da[0]);
|
||||
}
|
||||
else if (feature == "F2") {
|
||||
Fac = fabs(da[1]);
|
||||
}
|
||||
else if (feature == "F3") {
|
||||
Fac = fabs(da[2]);
|
||||
}
|
||||
else if (feature == "F4") {
|
||||
Fac = fabs(da[3]);
|
||||
}
|
||||
else if (feature == "F2F1") {
|
||||
Fac = fabs(da[1] - da[0]);
|
||||
}
|
||||
Color = color(Fac);
|
||||
}
|
||||
else {
|
||||
Color = cellnoise_color(pa[0]);
|
||||
Fac = (Color[0] + Color[1] + Color[2]) * (1.0 / 3.0);
|
||||
/* Color output */
|
||||
if (feature == "F1") {
|
||||
Color = pa[0];
|
||||
}
|
||||
else if (feature == "F2") {
|
||||
Color = pa[1];
|
||||
}
|
||||
else if (feature == "F3") {
|
||||
Color = pa[2];
|
||||
}
|
||||
else if (feature == "F4") {
|
||||
Color = pa[3];
|
||||
}
|
||||
else if (feature == "F2F1") {
|
||||
Color = fabs(pa[1] - pa[0]);
|
||||
}
|
||||
|
||||
Color = cellnoise_color(Color);
|
||||
Fac = (Color[0] + Color[1] + Color[2]) * (1.0 / 3.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -338,6 +338,21 @@ typedef enum NodeVoronoiColoring {
|
||||
NODE_VORONOI_CELLS
|
||||
} NodeVoronoiColoring;
|
||||
|
||||
typedef enum NodeVoronoiDistanceMetric {
|
||||
NODE_VORONOI_DISTANCE,
|
||||
NODE_VORONOI_MANHATTAN,
|
||||
NODE_VORONOI_CHEBYCHEV,
|
||||
NODE_VORONOI_MINKOWSKI
|
||||
} NodeVoronoiDistanceMetric;
|
||||
|
||||
typedef enum NodeVoronoiFeature {
|
||||
NODE_VORONOI_F1,
|
||||
NODE_VORONOI_F2,
|
||||
NODE_VORONOI_F3,
|
||||
NODE_VORONOI_F4,
|
||||
NODE_VORONOI_F2F1
|
||||
} NodeVoronoiFeature;
|
||||
|
||||
typedef enum NodeBlendWeightType {
|
||||
NODE_LAYER_WEIGHT_FRESNEL,
|
||||
NODE_LAYER_WEIGHT_FACING
|
||||
|
@ -18,10 +18,19 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Voronoi */
|
||||
|
||||
ccl_device float voronoi_F1_distance(float3 p)
|
||||
ccl_device void voronoi_neighbors(float3 p, NodeVoronoiDistanceMetric distance, float e, float da[4], float3 pa[4])
|
||||
{
|
||||
/* returns squared distance in da */
|
||||
float da = 1e10f;
|
||||
/* Compute the distance to and the position of the closest neighbors to p.
|
||||
*
|
||||
* The neighbors are randomly placed, 1 each in a 3x3x3 grid (Worley pattern).
|
||||
* The distances and points are returned in ascending order, i.e. da[0] and pa[0] will
|
||||
* contain the distance to the closest point and its coordinates respectively.
|
||||
*/
|
||||
|
||||
da[0] = 1e10f;
|
||||
da[1] = 1e10f;
|
||||
da[2] = 1e10f;
|
||||
da[3] = 1e10f;
|
||||
|
||||
int3 xyzi = quick_floor_to_int3(p);
|
||||
|
||||
@ -31,71 +40,114 @@ ccl_device float voronoi_F1_distance(float3 p)
|
||||
int3 ip = xyzi + make_int3(xx, yy, zz);
|
||||
float3 fp = make_float3(ip.x, ip.y, ip.z);
|
||||
float3 vp = fp + cellnoise3(fp);
|
||||
float d = len_squared(p - vp);
|
||||
da = min(d, da);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return da;
|
||||
}
|
||||
float d;
|
||||
switch(distance) {
|
||||
case NODE_VORONOI_DISTANCE:
|
||||
d = len_squared(p - vp);
|
||||
break;
|
||||
case NODE_VORONOI_MANHATTAN:
|
||||
d = reduce_add(fabs(vp - p));
|
||||
break;
|
||||
case NODE_VORONOI_CHEBYCHEV:
|
||||
d = max3(fabs(vp - p));
|
||||
break;
|
||||
case NODE_VORONOI_MINKOWSKI:
|
||||
float3 n = fabs(vp - p);
|
||||
if(e == 0.5f) {
|
||||
d = sqr(reduce_add(sqrt(n)));
|
||||
}
|
||||
else {
|
||||
d = powf(reduce_add(pow3(n, e)), 1.0f/e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ccl_device float3 voronoi_F1_color(float3 p)
|
||||
{
|
||||
/* returns color of the nearest point */
|
||||
float da = 1e10f;
|
||||
float3 pa;
|
||||
/* To keep the shortest four distances and associated points we have to keep them in sorted order. */
|
||||
if (d < da[0]) {
|
||||
da[3] = da[2];
|
||||
da[2] = da[1];
|
||||
da[1] = da[0];
|
||||
da[0] = d;
|
||||
|
||||
int3 xyzi = quick_floor_to_int3(p);
|
||||
pa[3] = pa[2];
|
||||
pa[2] = pa[1];
|
||||
pa[1] = pa[0];
|
||||
pa[0] = vp;
|
||||
}
|
||||
else if (d < da[1]) {
|
||||
da[3] = da[2];
|
||||
da[2] = da[1];
|
||||
da[1] = d;
|
||||
|
||||
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);
|
||||
float d = len_squared(p - vp);
|
||||
pa[3] = pa[2];
|
||||
pa[2] = pa[1];
|
||||
pa[1] = vp;
|
||||
}
|
||||
else if (d < da[2]) {
|
||||
da[3] = da[2];
|
||||
da[2] = d;
|
||||
|
||||
if(d < da) {
|
||||
da = d;
|
||||
pa = vp;
|
||||
pa[3] = pa[2];
|
||||
pa[2] = vp;
|
||||
}
|
||||
else if (d < da[3]) {
|
||||
da[3] = d;
|
||||
pa[3] = vp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cellnoise3(pa);
|
||||
}
|
||||
|
||||
ccl_device_noinline float4 svm_voronoi(NodeVoronoiColoring coloring, float3 p)
|
||||
{
|
||||
if(coloring == NODE_VORONOI_INTENSITY) {
|
||||
/* compute squared distance to the nearest neighbour */
|
||||
float fac = voronoi_F1_distance(p);
|
||||
return make_float4(fac, fac, fac, fac);
|
||||
}
|
||||
else {
|
||||
/* compute color of the nearest neighbour */
|
||||
float3 color = voronoi_F1_color(p);
|
||||
return make_float4(color.x, color.y, color.z, average(color));
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device void svm_node_tex_voronoi(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int *offset)
|
||||
{
|
||||
uint coloring = node.y;
|
||||
uint scale_offset, co_offset, fac_offset, color_offset;
|
||||
uint4 node2 = read_node(kg, offset);
|
||||
|
||||
decode_node_uchar4(node.z, &scale_offset, &co_offset, &fac_offset, &color_offset);
|
||||
uint co_offset, coloring, distance, feature;
|
||||
uint scale_offset, e_offset, fac_offset, color_offset;
|
||||
|
||||
decode_node_uchar4(node.y, &co_offset, &coloring, &distance, &feature);
|
||||
decode_node_uchar4(node.z, &scale_offset, &e_offset, &fac_offset, &color_offset);
|
||||
|
||||
float3 co = stack_load_float3(stack, co_offset);
|
||||
float scale = stack_load_float_default(stack, scale_offset, node.w);
|
||||
float scale = stack_load_float_default(stack, scale_offset, node2.x);
|
||||
float exponent = stack_load_float_default(stack, e_offset, node2.y);
|
||||
|
||||
float4 result = svm_voronoi((NodeVoronoiColoring)coloring, co*scale);
|
||||
float3 color = make_float3(result.x, result.y, result.z);
|
||||
float f = result.w;
|
||||
float dist[4];
|
||||
float3 neighbor[4];
|
||||
voronoi_neighbors(co*scale, (NodeVoronoiDistanceMetric)distance, exponent, dist, neighbor);
|
||||
|
||||
if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, f);
|
||||
float3 color;
|
||||
float fac;
|
||||
if(coloring == NODE_VORONOI_INTENSITY) {
|
||||
switch(feature) {
|
||||
case NODE_VORONOI_F1: fac = dist[0]; break;
|
||||
case NODE_VORONOI_F2: fac = dist[1]; break;
|
||||
case NODE_VORONOI_F3: fac = dist[2]; break;
|
||||
case NODE_VORONOI_F4: fac = dist[3]; break;
|
||||
case NODE_VORONOI_F2F1: fac = dist[1] - dist[0]; break;
|
||||
}
|
||||
|
||||
color = make_float3(fac, fac, fac);
|
||||
}
|
||||
else {
|
||||
/* NODE_VORONOI_CELLS */
|
||||
switch(feature) {
|
||||
case NODE_VORONOI_F1: color = neighbor[0]; break;
|
||||
case NODE_VORONOI_F2: color = neighbor[1]; break;
|
||||
case NODE_VORONOI_F3: color = neighbor[2]; break;
|
||||
case NODE_VORONOI_F4: color = neighbor[3]; break;
|
||||
/* Usefulness of this vector is questionable. Note F2 >= F1 but the
|
||||
* individual vector components might not be. */
|
||||
case NODE_VORONOI_F2F1: color = fabs(neighbor[1] - neighbor[0]); break;
|
||||
}
|
||||
|
||||
color = cellnoise3(color);
|
||||
fac = average(color);
|
||||
}
|
||||
|
||||
if(stack_valid(fac_offset)) stack_store_float(stack, fac_offset, fac);
|
||||
if(stack_valid(color_offset)) stack_store_float3(stack, color_offset, color);
|
||||
}
|
||||
|
||||
|
@ -913,7 +913,23 @@ NODE_DEFINE(VoronoiTextureNode)
|
||||
coloring_enum.insert("cells", NODE_VORONOI_CELLS);
|
||||
SOCKET_ENUM(coloring, "Coloring", coloring_enum, NODE_VORONOI_INTENSITY);
|
||||
|
||||
static NodeEnum metric;
|
||||
metric.insert("distance", NODE_VORONOI_DISTANCE);
|
||||
metric.insert("manhattan", NODE_VORONOI_MANHATTAN);
|
||||
metric.insert("chebychev", NODE_VORONOI_CHEBYCHEV);
|
||||
metric.insert("minkowski", NODE_VORONOI_MINKOWSKI);
|
||||
SOCKET_ENUM(metric, "Distance Metric", metric, NODE_VORONOI_INTENSITY);
|
||||
|
||||
static NodeEnum feature_enum;
|
||||
feature_enum.insert("F1", NODE_VORONOI_F1);
|
||||
feature_enum.insert("F2", NODE_VORONOI_F2);
|
||||
feature_enum.insert("F3", NODE_VORONOI_F3);
|
||||
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_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_OUT_COLOR(color, "Color");
|
||||
@ -931,19 +947,32 @@ void VoronoiTextureNode::compile(SVMCompiler& compiler)
|
||||
{
|
||||
ShaderInput *scale_in = input("Scale");
|
||||
ShaderInput *vector_in = input("Vector");
|
||||
ShaderInput *exponent_in = input("Exponent");
|
||||
ShaderOutput *color_out = output("Color");
|
||||
ShaderOutput *fac_out = output("Fac");
|
||||
|
||||
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);
|
||||
|
||||
int vector_offset = tex_mapping.compile_begin(compiler, vector_in);
|
||||
|
||||
compiler.add_node(NODE_TEX_VORONOI,
|
||||
coloring,
|
||||
compiler.encode_uchar4(
|
||||
vector_offset,
|
||||
coloring,
|
||||
metric,
|
||||
feature
|
||||
),
|
||||
compiler.encode_uchar4(
|
||||
compiler.stack_assign_if_linked(scale_in),
|
||||
vector_offset,
|
||||
compiler.stack_assign_if_linked(exponent_in),
|
||||
compiler.stack_assign(fac_out),
|
||||
compiler.stack_assign(color_out)),
|
||||
__float_as_int(scale));
|
||||
compiler.stack_assign(color_out)
|
||||
));
|
||||
compiler.add_node(
|
||||
__float_as_int(scale),
|
||||
__float_as_int(exponent));
|
||||
|
||||
tex_mapping.compile_end(compiler, vector_in, vector_offset);
|
||||
}
|
||||
@ -953,6 +982,8 @@ void VoronoiTextureNode::compile(OSLCompiler& compiler)
|
||||
tex_mapping.compile(compiler);
|
||||
|
||||
compiler.parameter(this, "coloring");
|
||||
compiler.parameter(this, "metric");
|
||||
compiler.parameter(this, "feature");
|
||||
compiler.add(this, "node_voronoi_texture");
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,9 @@ public:
|
||||
virtual int get_group() { return NODE_GROUP_LEVEL_2; }
|
||||
|
||||
NodeVoronoiColoring coloring;
|
||||
float scale;
|
||||
NodeVoronoiDistanceMetric metric;
|
||||
NodeVoronoiFeature feature;
|
||||
float scale, exponent;
|
||||
float3 vector;
|
||||
};
|
||||
|
||||
|
@ -280,6 +280,11 @@ ccl_device_inline float3 sqrt(const float3& a)
|
||||
#endif
|
||||
}
|
||||
|
||||
ccl_device_inline float3 pow3(const float3& a, float e)
|
||||
{
|
||||
return make_float3(powf(a.x, e), powf(a.y, e), powf(a.z, e));
|
||||
}
|
||||
|
||||
ccl_device_inline float3 mix(const float3& a, const float3& b, float t)
|
||||
{
|
||||
return a + t*(b - a);
|
||||
|
@ -961,6 +961,8 @@ static void node_shader_buts_tex_musgrave(uiLayout *layout, bContext *UNUSED(C),
|
||||
static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||
{
|
||||
uiItemR(layout, ptr, "coloring", 0, "", ICON_NONE);
|
||||
uiItemR(layout, ptr, "distance", 0, "", ICON_NONE);
|
||||
uiItemR(layout, ptr, "feature", 0, "", ICON_NONE);
|
||||
}
|
||||
|
||||
static void node_shader_buts_tex_pointdensity(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||
|
@ -3660,7 +3660,7 @@ void node_tex_sky(vec3 co, out vec4 color)
|
||||
color = vec4(1.0);
|
||||
}
|
||||
|
||||
void node_tex_voronoi(vec3 co, float scale, float coloring, out vec4 color, out float fac)
|
||||
void node_tex_voronoi(vec3 co, float scale, float exponent, float coloring, out vec4 color, out float fac)
|
||||
{
|
||||
#ifdef BIT_OPERATIONS
|
||||
vec3 p = co * scale;
|
||||
|
@ -778,6 +778,8 @@ typedef struct NodeTexNoise {
|
||||
typedef struct NodeTexVoronoi {
|
||||
NodeTexBase base;
|
||||
int coloring;
|
||||
int distance;
|
||||
int feature;
|
||||
int pad;
|
||||
} NodeTexVoronoi;
|
||||
|
||||
@ -976,17 +978,20 @@ typedef struct NodeSunBeams {
|
||||
#define SHD_NOISE_HARD 1
|
||||
|
||||
/* voronoi texture */
|
||||
#define SHD_VORONOI_DISTANCE_SQUARED 0
|
||||
#define SHD_VORONOI_ACTUAL_DISTANCE 1
|
||||
#define SHD_VORONOI_MANHATTAN 2
|
||||
#define SHD_VORONOI_CHEBYCHEV 3
|
||||
#define SHD_VORONOI_MINKOVSKY_H 4
|
||||
#define SHD_VORONOI_MINKOVSKY_4 5
|
||||
#define SHD_VORONOI_MINKOVSKY 6
|
||||
#define SHD_VORONOI_DISTANCE 0
|
||||
#define SHD_VORONOI_MANHATTAN 1
|
||||
#define SHD_VORONOI_CHEBYCHEV 2
|
||||
#define SHD_VORONOI_MINKOWSKI 3
|
||||
|
||||
#define SHD_VORONOI_INTENSITY 0
|
||||
#define SHD_VORONOI_CELLS 1
|
||||
|
||||
#define SHD_VORONOI_F1 0
|
||||
#define SHD_VORONOI_F2 1
|
||||
#define SHD_VORONOI_F3 2
|
||||
#define SHD_VORONOI_F4 3
|
||||
#define SHD_VORONOI_F2F1 4
|
||||
|
||||
/* musgrave texture */
|
||||
#define SHD_MUSGRAVE_MULTIFRACTAL 0
|
||||
#define SHD_MUSGRAVE_FBM 1
|
||||
|
@ -3055,16 +3055,7 @@ static void rna_ShaderNodeScript_update(Main *bmain, Scene *scene, PointerRNA *p
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node);
|
||||
}
|
||||
|
||||
static void rna_ShaderNodePrincipled_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
|
||||
bNode *node = (bNode *)ptr->data;
|
||||
|
||||
nodeUpdate(ntree, node);
|
||||
rna_Node_update(bmain, scene, ptr);
|
||||
}
|
||||
|
||||
static void rna_ShaderNodeSubsurface_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
static void rna_ShaderNode_socket_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
|
||||
bNode *node = (bNode *)ptr->data;
|
||||
@ -4003,6 +3994,23 @@ static void def_sh_tex_voronoi(StructRNA *srna)
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem prop_distance_items[] = {
|
||||
{ SHD_VORONOI_DISTANCE, "DISTANCE", 0, "Distance", "Distance" },
|
||||
{ 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" },
|
||||
{ 0, NULL, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static EnumPropertyItem prop_feature_items[] = {
|
||||
{ SHD_VORONOI_F1, "F1", 0, "Closest", "Closest point" },
|
||||
{ SHD_VORONOI_F2, "F2", 0, "2nd Closest", "2nd closest point" },
|
||||
{ SHD_VORONOI_F3, "F3", 0, "3rd Closest", "3rd closest point" },
|
||||
{ SHD_VORONOI_F4, "F4", 0, "4th Closest", "4th closest point" },
|
||||
{ SHD_VORONOI_F2F1, "F2F1", 0, "Crackle", "Difference between 2nd and 1st closest point" },
|
||||
{ 0, NULL, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
PropertyRNA *prop;
|
||||
|
||||
RNA_def_struct_sdna_from(srna, "NodeTexVoronoi", "storage");
|
||||
@ -4013,6 +4021,18 @@ static void def_sh_tex_voronoi(StructRNA *srna)
|
||||
RNA_def_property_enum_items(prop, prop_coloring_items);
|
||||
RNA_def_property_ui_text(prop, "Coloring", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "distance", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "distance");
|
||||
RNA_def_property_enum_items(prop, prop_distance_items);
|
||||
RNA_def_property_ui_text(prop, "Distance metric", "");
|
||||
RNA_def_property_update(prop, 0, "rna_ShaderNode_socket_update");
|
||||
|
||||
prop = RNA_def_property(srna, "feature", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "feature");
|
||||
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");
|
||||
}
|
||||
|
||||
static void def_sh_tex_wave(StructRNA *srna)
|
||||
@ -4284,13 +4304,13 @@ static void def_principled(StructRNA *srna)
|
||||
RNA_def_property_enum_sdna(prop, NULL, "custom1");
|
||||
RNA_def_property_enum_items(prop, node_principled_distribution_items);
|
||||
RNA_def_property_ui_text(prop, "Distribution", "");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodePrincipled_update");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update");
|
||||
|
||||
prop = RNA_def_property(srna, "subsurface_method", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "custom2");
|
||||
RNA_def_property_enum_items(prop, node_subsurface_method_items);
|
||||
RNA_def_property_ui_text(prop, "Subsurface Method", "Method for rendering subsurface scattering");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodePrincipled_update");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update");
|
||||
}
|
||||
|
||||
static void def_refraction(StructRNA *srna)
|
||||
@ -4525,7 +4545,7 @@ static void def_sh_subsurface(StructRNA *srna)
|
||||
RNA_def_property_enum_sdna(prop, NULL, "custom1");
|
||||
RNA_def_property_enum_items(prop, prop_subsurface_falloff_items);
|
||||
RNA_def_property_ui_text(prop, "Falloff", "Function to determine how much light nearby points contribute based on their distance to the shading point");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodeSubsurface_update");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update");
|
||||
}
|
||||
|
||||
static void def_sh_tex_ies(StructRNA *srna)
|
||||
|
@ -32,6 +32,7 @@
|
||||
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},
|
||||
{ -1, 0, "" }
|
||||
};
|
||||
|
||||
@ -47,6 +48,8 @@ static void node_shader_init_tex_voronoi(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->coloring = SHD_VORONOI_INTENSITY;
|
||||
tex->distance = SHD_VORONOI_DISTANCE;
|
||||
tex->feature = SHD_VORONOI_F1;
|
||||
|
||||
node->storage = tex;
|
||||
}
|
||||
@ -66,6 +69,23 @@ static int node_shader_gpu_tex_voronoi(GPUMaterial *mat, bNode *node, bNodeExecD
|
||||
return GPU_stack_link(mat, "node_tex_voronoi", in, out, GPU_uniform(&coloring));
|
||||
}
|
||||
|
||||
static void node_shader_update_tex_voronoi(bNodeTree *UNUSED(ntree), bNode *node)
|
||||
{
|
||||
NodeTexVoronoi *tex = (NodeTexVoronoi *)node->storage;
|
||||
bNodeSocket *sock;
|
||||
|
||||
for (sock = node->inputs.first; sock; sock = sock->next) {
|
||||
if (STREQ(sock->name, "Exponent")) {
|
||||
if (tex->distance == SHD_VORONOI_MINKOWSKI) {
|
||||
sock->flag &= ~SOCK_UNAVAIL;
|
||||
}
|
||||
else {
|
||||
sock->flag |= SOCK_UNAVAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* node type definition */
|
||||
void register_node_type_sh_tex_voronoi(void)
|
||||
{
|
||||
@ -77,6 +97,7 @@ void register_node_type_sh_tex_voronoi(void)
|
||||
node_type_init(&ntype, node_shader_init_tex_voronoi);
|
||||
node_type_storage(&ntype, "NodeTexVoronoi", node_free_standard_storage, node_copy_standard_storage);
|
||||
node_type_gpu(&ntype, node_shader_gpu_tex_voronoi);
|
||||
node_type_update(&ntype, node_shader_update_tex_voronoi, NULL);
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user