Add Fractal Voronoi Noise V.2 #106827
|
@ -938,7 +938,6 @@ ccl_device void fractal_voronoi_f1(T coord,
|
||||||
float exponent,
|
float exponent,
|
||||||
float randomness,
|
float randomness,
|
||||||
NodeVoronoiDistanceMetric metric,
|
NodeVoronoiDistanceMetric metric,
|
||||||
float max_distance,
|
|
||||||
ccl_private float *max_amplitude,
|
ccl_private float *max_amplitude,
|
||||||
ccl_private float *outDistance,
|
ccl_private float *outDistance,
|
||||||
ccl_private float3 *outColor,
|
ccl_private float3 *outColor,
|
||||||
|
@ -947,6 +946,8 @@ ccl_device void fractal_voronoi_f1(T coord,
|
||||||
float octave_scale = 1.0f;
|
float octave_scale = 1.0f;
|
||||||
float octave_amplitude = 1.0f;
|
float octave_amplitude = 1.0f;
|
||||||
float octave_distance = 0.0f;
|
float octave_distance = 0.0f;
|
||||||
|
float3 octave_color{};
|
||||||
|
T octave_postion{};
|
||||||
|
|
||||||
*max_amplitude = 0.0f;
|
*max_amplitude = 0.0f;
|
||||||
*outDistance = 0.0f;
|
*outDistance = 0.0f;
|
||||||
|
@ -956,27 +957,34 @@ ccl_device void fractal_voronoi_f1(T coord,
|
||||||
randomness,
|
randomness,
|
||||||
metric,
|
metric,
|
||||||
&octave_distance,
|
&octave_distance,
|
||||||
outColor,
|
&octave_color,
|
||||||
outPosition);
|
&octave_postion);
|
||||||
if (detail == 0.0f || roughness == 0.0f || lacunarity == 0.0f) {
|
if (detail == 0.0f || roughness == 0.0f || lacunarity == 0.0f) {
|
||||||
*max_amplitude = max_distance;
|
*max_amplitude = 1.0f;
|
||||||
*outDistance = octave_distance;
|
*outDistance = octave_distance;
|
||||||
|
*outColor = octave_color;
|
||||||
|
*outPosition = octave_postion;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (i <= detail) {
|
else if (i <= detail) {
|
||||||
*max_amplitude += max_distance * octave_amplitude;
|
*max_amplitude += octave_amplitude;
|
||||||
*outDistance += octave_distance * octave_amplitude;
|
*outDistance += octave_distance * octave_amplitude;
|
||||||
*outPosition /= octave_scale;
|
*outColor += octave_color * octave_amplitude;
|
||||||
|
*outPosition = lerp(*outPosition, octave_postion / octave_scale, octave_amplitude);
|
||||||
octave_scale *= lacunarity;
|
octave_scale *= lacunarity;
|
||||||
octave_amplitude *= roughness;
|
octave_amplitude *= roughness;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float remainder = detail - floorf(detail);
|
float remainder = detail - floorf(detail);
|
||||||
if (remainder != 0.0f) {
|
if (remainder != 0.0f) {
|
||||||
*max_amplitude += max_distance * octave_amplitude;
|
float lerp_amplitude = *max_amplitude + octave_amplitude;
|
||||||
float lerp_distance = *outDistance + octave_distance * octave_amplitude;
|
float lerp_distance = *outDistance + octave_distance * octave_amplitude;
|
||||||
*outDistance = (1.0f - remainder) * (*outDistance) + remainder * lerp_distance;
|
float3 lerp_color = *outColor + octave_color * octave_amplitude;
|
||||||
*outPosition /= octave_scale;
|
T lerp_position = lerp(*outPosition, octave_postion / octave_scale, octave_amplitude);
|
||||||
|
*max_amplitude = lerp(*max_amplitude, lerp_amplitude, remainder);
|
||||||
|
*outDistance = lerp(*outDistance, lerp_distance, remainder);
|
||||||
|
*outColor = lerp(*outColor, lerp_color, remainder);
|
||||||
|
*outPosition = lerp(*outPosition, lerp_position, remainder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -991,7 +999,6 @@ ccl_device void fractal_voronoi_smooth_f1(T coord,
|
||||||
float exponent,
|
float exponent,
|
||||||
float randomness,
|
float randomness,
|
||||||
NodeVoronoiDistanceMetric metric,
|
NodeVoronoiDistanceMetric metric,
|
||||||
float max_distance,
|
|
||||||
ccl_private float *max_amplitude,
|
ccl_private float *max_amplitude,
|
||||||
ccl_private float *outDistance,
|
ccl_private float *outDistance,
|
||||||
ccl_private float3 *outColor,
|
ccl_private float3 *outColor,
|
||||||
|
@ -1000,6 +1007,8 @@ ccl_device void fractal_voronoi_smooth_f1(T coord,
|
||||||
float octave_scale = 1.0f;
|
float octave_scale = 1.0f;
|
||||||
float octave_amplitude = 1.0f;
|
float octave_amplitude = 1.0f;
|
||||||
float octave_distance = 0.0f;
|
float octave_distance = 0.0f;
|
||||||
|
float3 octave_color{};
|
||||||
|
T octave_postion{};
|
||||||
|
|
||||||
*max_amplitude = 0.0f;
|
*max_amplitude = 0.0f;
|
||||||
*outDistance = 0.0f;
|
*outDistance = 0.0f;
|
||||||
|
@ -1010,27 +1019,34 @@ ccl_device void fractal_voronoi_smooth_f1(T coord,
|
||||||
randomness,
|
randomness,
|
||||||
metric,
|
metric,
|
||||||
&octave_distance,
|
&octave_distance,
|
||||||
outColor,
|
&octave_color,
|
||||||
outPosition);
|
&octave_postion);
|
||||||
if (detail == 0.0f || roughness == 0.0f || lacunarity == 0.0f) {
|
if (detail == 0.0f || roughness == 0.0f || lacunarity == 0.0f) {
|
||||||
*max_amplitude = max_distance;
|
*max_amplitude = 1.0f;
|
||||||
*outDistance = octave_distance;
|
*outDistance = octave_distance;
|
||||||
|
*outColor = octave_color;
|
||||||
|
*outPosition = octave_postion;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (i <= detail) {
|
else if (i <= detail) {
|
||||||
*max_amplitude += max_distance * octave_amplitude;
|
*max_amplitude += octave_amplitude;
|
||||||
*outDistance += octave_distance * octave_amplitude;
|
*outDistance += octave_distance * octave_amplitude;
|
||||||
*outPosition /= octave_scale;
|
*outColor += octave_color * octave_amplitude;
|
||||||
|
*outPosition = lerp(*outPosition, octave_postion / octave_scale, octave_amplitude);
|
||||||
octave_scale *= lacunarity;
|
octave_scale *= lacunarity;
|
||||||
octave_amplitude *= roughness;
|
octave_amplitude *= roughness;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float remainder = detail - floorf(detail);
|
float remainder = detail - floorf(detail);
|
||||||
if (remainder != 0.0f) {
|
if (remainder != 0.0f) {
|
||||||
*max_amplitude += max_distance * octave_amplitude;
|
float lerp_amplitude = *max_amplitude + octave_amplitude;
|
||||||
float lerp_distance = *outDistance + octave_distance * octave_amplitude;
|
float lerp_distance = *outDistance + octave_distance * octave_amplitude;
|
||||||
*outDistance = (1.0f - remainder) * (*outDistance) + remainder * lerp_distance;
|
float3 lerp_color = *outColor + octave_color * octave_amplitude;
|
||||||
*outPosition /= octave_scale;
|
T lerp_position = lerp(*outPosition, octave_postion / octave_scale, octave_amplitude);
|
||||||
|
*max_amplitude = lerp(*max_amplitude, lerp_amplitude, remainder);
|
||||||
|
*outDistance = lerp(*outDistance, lerp_distance, remainder);
|
||||||
|
*outColor = lerp(*outColor, lerp_color, remainder);
|
||||||
|
*outPosition = lerp(*outPosition, lerp_position, remainder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1044,7 +1060,6 @@ ccl_device void fractal_voronoi_f2(T coord,
|
||||||
float exponent,
|
float exponent,
|
||||||
float randomness,
|
float randomness,
|
||||||
NodeVoronoiDistanceMetric metric,
|
NodeVoronoiDistanceMetric metric,
|
||||||
float max_distance,
|
|
||||||
ccl_private float *max_amplitude,
|
ccl_private float *max_amplitude,
|
||||||
ccl_private float *outDistance,
|
ccl_private float *outDistance,
|
||||||
ccl_private float3 *outColor,
|
ccl_private float3 *outColor,
|
||||||
|
@ -1053,6 +1068,8 @@ ccl_device void fractal_voronoi_f2(T coord,
|
||||||
float octave_scale = 1.0f;
|
float octave_scale = 1.0f;
|
||||||
float octave_amplitude = 1.0f;
|
float octave_amplitude = 1.0f;
|
||||||
float octave_distance = 0.0f;
|
float octave_distance = 0.0f;
|
||||||
|
float3 octave_color{};
|
||||||
|
T octave_postion{};
|
||||||
|
|
||||||
*max_amplitude = 0.0f;
|
*max_amplitude = 0.0f;
|
||||||
*outDistance = 0.0f;
|
*outDistance = 0.0f;
|
||||||
|
@ -1062,27 +1079,34 @@ ccl_device void fractal_voronoi_f2(T coord,
|
||||||
randomness,
|
randomness,
|
||||||
metric,
|
metric,
|
||||||
&octave_distance,
|
&octave_distance,
|
||||||
outColor,
|
&octave_color,
|
||||||
outPosition);
|
&octave_postion);
|
||||||
if (detail == 0.0f || roughness == 0.0f || lacunarity == 0.0f) {
|
if (detail == 0.0f || roughness == 0.0f || lacunarity == 0.0f) {
|
||||||
*max_amplitude = max_distance;
|
*max_amplitude = 1.0f;
|
||||||
*outDistance = octave_distance;
|
*outDistance = octave_distance;
|
||||||
|
*outColor = octave_color;
|
||||||
|
*outPosition = octave_postion;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (i <= detail) {
|
else if (i <= detail) {
|
||||||
*max_amplitude += max_distance * octave_amplitude;
|
*max_amplitude += octave_amplitude;
|
||||||
*outDistance += octave_distance * octave_amplitude;
|
*outDistance += octave_distance * octave_amplitude;
|
||||||
*outPosition /= octave_scale;
|
*outColor += octave_color * octave_amplitude;
|
||||||
|
*outPosition = lerp(*outPosition, octave_postion / octave_scale, octave_amplitude);
|
||||||
octave_scale *= lacunarity;
|
octave_scale *= lacunarity;
|
||||||
octave_amplitude *= roughness;
|
octave_amplitude *= roughness;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float remainder = detail - floorf(detail);
|
float remainder = detail - floorf(detail);
|
||||||
if (remainder != 0.0f) {
|
if (remainder != 0.0f) {
|
||||||
*max_amplitude += max_distance * octave_amplitude;
|
float lerp_amplitude = *max_amplitude + octave_amplitude;
|
||||||
float lerp_distance = *outDistance + octave_distance * octave_amplitude;
|
float lerp_distance = *outDistance + octave_distance * octave_amplitude;
|
||||||
*outDistance = (1.0f - remainder) * (*outDistance) + remainder * lerp_distance;
|
float3 lerp_color = *outColor + octave_color * octave_amplitude;
|
||||||
*outPosition /= octave_scale;
|
T lerp_position = lerp(*outPosition, octave_postion / octave_scale, octave_amplitude);
|
||||||
|
*max_amplitude = lerp(*max_amplitude, lerp_amplitude, remainder);
|
||||||
|
*outDistance = lerp(*outDistance, lerp_distance, remainder);
|
||||||
|
*outColor = lerp(*outColor, lerp_color, remainder);
|
||||||
|
*outPosition = lerp(*outPosition, lerp_position, remainder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1091,22 +1115,42 @@ ccl_device void fractal_voronoi_f2(T coord,
|
||||||
template<typename T>
|
template<typename T>
|
||||||
ccl_device void fractal_voronoi_distance_to_edge(T coord,
|
ccl_device void fractal_voronoi_distance_to_edge(T coord,
|
||||||
float detail,
|
float detail,
|
||||||
|
float roughness,
|
||||||
float lacunarity,
|
float lacunarity,
|
||||||
float randomness,
|
float randomness,
|
||||||
bool normalize,
|
ccl_private float *max_amplitude,
|
||||||
ccl_private float *outDistance)
|
ccl_private float *outDistance)
|
||||||
{
|
{
|
||||||
float octave_scale = 1.0f;
|
float octave_scale = 1.0f;
|
||||||
|
float octave_amplitude = 1.0f;
|
||||||
float octave_distance = 0.0f;
|
float octave_distance = 0.0f;
|
||||||
|
|
||||||
|
*max_amplitude = 2.0f - randomness;
|
||||||
*outDistance = 8.0f;
|
*outDistance = 8.0f;
|
||||||
for (int i = 0; i <= ceilf(detail); ++i) {
|
for (int i = 0; i <= ceilf(detail); ++i) {
|
||||||
voronoi_distance_to_edge(coord * octave_scale, randomness, &octave_distance);
|
voronoi_distance_to_edge(coord * octave_scale, randomness, &octave_distance);
|
||||||
*outDistance = min(*outDistance, octave_distance / octave_scale);
|
if (detail == 0.0f || roughness == 0.0f || lacunarity == 0.0f) {
|
||||||
octave_scale *= lacunarity;
|
*outDistance = octave_distance;
|
||||||
}
|
return;
|
||||||
if (normalize) {
|
}
|
||||||
*outDistance *= (2.0f - randomness) * octave_scale / lacunarity;
|
else if (i <= detail) {
|
||||||
|
*max_amplitude = lerp(*max_amplitude, (2.0f - randomness) * octave_scale, octave_amplitude);
|
||||||
|
*outDistance = lerp(
|
||||||
|
*outDistance, min(*outDistance, octave_distance / octave_scale), octave_amplitude);
|
||||||
|
octave_scale *= lacunarity;
|
||||||
|
octave_amplitude *= roughness;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float remainder = detail - floorf(detail);
|
||||||
|
if (remainder != 0.0f) {
|
||||||
|
float lerp_amplitude = lerp(
|
||||||
|
*max_amplitude, (2.0f - randomness) * octave_scale, octave_amplitude);
|
||||||
|
float lerp_distance = lerp(
|
||||||
|
*outDistance, min(*outDistance, octave_distance / octave_scale), octave_amplitude);
|
||||||
|
*max_amplitude = lerp(*max_amplitude, lerp_amplitude, remainder);
|
||||||
|
*outDistance = lerp(*outDistance, min(*outDistance, lerp_distance), remainder);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1186,14 +1230,14 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
||||||
exponent,
|
exponent,
|
||||||
randomness,
|
randomness,
|
||||||
voronoi_metric,
|
voronoi_metric,
|
||||||
1.0f,
|
|
||||||
&max_amplitude,
|
&max_amplitude,
|
||||||
&distance_out,
|
&distance_out,
|
||||||
&color_out,
|
&color_out,
|
||||||
&w_out);
|
&w_out);
|
||||||
if (normalize) {
|
if (normalize) {
|
||||||
/* Optimized std::lerp(max_amplitude*0.5, max_amplitude, randomness) */
|
/* Optimized std::lerp(max_amplitude * 0.5, max_amplitude, randomness) */
|
||||||
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude;
|
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude;
|
||||||
|
color_out /= max_amplitude;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1206,14 +1250,14 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
||||||
exponent,
|
exponent,
|
||||||
randomness,
|
randomness,
|
||||||
voronoi_metric,
|
voronoi_metric,
|
||||||
1.0f,
|
|
||||||
&max_amplitude,
|
&max_amplitude,
|
||||||
&distance_out,
|
&distance_out,
|
||||||
&color_out,
|
&color_out,
|
||||||
&w_out);
|
&w_out);
|
||||||
if (normalize) {
|
if (normalize) {
|
||||||
/* Optimized std::lerp(max_amplitude*0.5, max_amplitude, randomness) */
|
/* Optimized std::lerp(max_amplitude * 0.5, max_amplitude, randomness) */
|
||||||
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude;
|
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude;
|
||||||
|
color_out /= max_amplitude;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1225,7 +1269,6 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
||||||
exponent,
|
exponent,
|
||||||
randomness,
|
randomness,
|
||||||
voronoi_metric,
|
voronoi_metric,
|
||||||
1.0f,
|
|
||||||
&max_amplitude,
|
&max_amplitude,
|
||||||
&distance_out,
|
&distance_out,
|
||||||
&color_out,
|
&color_out,
|
||||||
|
@ -1238,12 +1281,20 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
||||||
distance_out /= (1.0f - randomness) * ceilf(detail + 1.0f) +
|
distance_out /= (1.0f - randomness) * ceilf(detail + 1.0f) +
|
||||||
randomness * max_amplitude;
|
randomness * max_amplitude;
|
||||||
}
|
}
|
||||||
|
color_out /= max_amplitude;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_VORONOI_DISTANCE_TO_EDGE: {
|
case NODE_VORONOI_DISTANCE_TO_EDGE: {
|
||||||
fractal_voronoi_distance_to_edge<float>(
|
fractal_voronoi_distance_to_edge<float>(
|
||||||
w, detail, lacunarity, randomness, normalize, &distance_out);
|
w, detail, roughness, lacunarity, randomness, &max_amplitude, &distance_out);
|
||||||
|
if (normalize) {
|
||||||
|
/* max_amplitude is used here to keep the code consistent, however it has a different
|
||||||
|
* meaning than in F1, Smooth F1 and F2. Instead of the highest possible amplitude, it
|
||||||
|
* represents an abstract factor needed to cancel out the amplitude attenuation caused
|
||||||
|
* by the higher layers. */
|
||||||
|
distance_out *= max_amplitude;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_VORONOI_N_SPHERE_RADIUS:
|
case NODE_VORONOI_N_SPHERE_RADIUS:
|
||||||
|
@ -1271,14 +1322,15 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
||||||
exponent,
|
exponent,
|
||||||
randomness,
|
randomness,
|
||||||
voronoi_metric,
|
voronoi_metric,
|
||||||
max_distance,
|
|
||||||
&max_amplitude,
|
&max_amplitude,
|
||||||
&distance_out,
|
&distance_out,
|
||||||
&color_out,
|
&color_out,
|
||||||
&position_out_2d);
|
&position_out_2d);
|
||||||
if (normalize) {
|
if (normalize) {
|
||||||
/* Optimized std::lerp(max_amplitude*0.5, max_amplitude, randomness) */
|
/* Optimized lerp(max_amplitude * max_distance * 0.5, max_amplitude * max_distance,
|
||||||
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude;
|
* randomness) */
|
||||||
|
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude * max_distance;
|
||||||
|
color_out /= max_amplitude;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1293,14 +1345,15 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
||||||
exponent,
|
exponent,
|
||||||
randomness,
|
randomness,
|
||||||
voronoi_metric,
|
voronoi_metric,
|
||||||
max_distance,
|
|
||||||
&max_amplitude,
|
&max_amplitude,
|
||||||
&distance_out,
|
&distance_out,
|
||||||
&color_out,
|
&color_out,
|
||||||
&position_out_2d);
|
&position_out_2d);
|
||||||
if (normalize) {
|
if (normalize) {
|
||||||
/* Optimized std::lerp(max_amplitude*0.5, max_amplitude, randomness) */
|
/* Optimized lerp(max_amplitude * max_distance * 0.5, max_amplitude * max_distance,
|
||||||
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude;
|
* randomness) */
|
||||||
|
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude * max_distance;
|
||||||
|
color_out /= max_amplitude;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1313,25 +1366,32 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
||||||
exponent,
|
exponent,
|
||||||
randomness,
|
randomness,
|
||||||
voronoi_metric,
|
voronoi_metric,
|
||||||
max_distance,
|
|
||||||
&max_amplitude,
|
&max_amplitude,
|
||||||
&distance_out,
|
&distance_out,
|
||||||
&color_out,
|
&color_out,
|
||||||
&position_out_2d);
|
&position_out_2d);
|
||||||
if (normalize) {
|
if (normalize) {
|
||||||
if (detail == 0.0f || roughness == 0.0f || lacunarity == 0.0f) {
|
if (detail == 0.0f || roughness == 0.0f || lacunarity == 0.0f) {
|
||||||
distance_out /= (1.0f - randomness) + randomness * max_amplitude;
|
distance_out /= (1.0f - randomness) + randomness * max_amplitude * max_distance;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
distance_out /= (1.0f - randomness) * ceilf(detail + 1.0f) +
|
distance_out /= (1.0f - randomness) * ceilf(detail + 1.0f) +
|
||||||
randomness * max_amplitude;
|
randomness * max_amplitude * max_distance;
|
||||||
}
|
}
|
||||||
|
color_out /= max_amplitude;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_VORONOI_DISTANCE_TO_EDGE: {
|
case NODE_VORONOI_DISTANCE_TO_EDGE: {
|
||||||
fractal_voronoi_distance_to_edge<float2>(
|
fractal_voronoi_distance_to_edge<float2>(
|
||||||
coord_2d, detail, lacunarity, randomness, normalize, &distance_out);
|
coord_2d, detail, roughness, lacunarity, randomness, &max_amplitude, &distance_out);
|
||||||
|
if (normalize) {
|
||||||
|
/* max_amplitude is used here to keep the code consistent, however it has a different
|
||||||
|
* meaning than in F1, Smooth F1 and F2. Instead of the highest possible amplitude, it
|
||||||
|
* represents an abstract factor needed to cancel out the amplitude attenuation caused
|
||||||
|
* by the higher layers. */
|
||||||
|
distance_out *= max_amplitude;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_VORONOI_N_SPHERE_RADIUS:
|
case NODE_VORONOI_N_SPHERE_RADIUS:
|
||||||
|
@ -1358,14 +1418,15 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
||||||
exponent,
|
exponent,
|
||||||
randomness,
|
randomness,
|
||||||
voronoi_metric,
|
voronoi_metric,
|
||||||
max_distance,
|
|
||||||
&max_amplitude,
|
&max_amplitude,
|
||||||
&distance_out,
|
&distance_out,
|
||||||
&color_out,
|
&color_out,
|
||||||
&position_out);
|
&position_out);
|
||||||
if (normalize) {
|
if (normalize) {
|
||||||
/* Optimized std::lerp(max_amplitude*0.5, max_amplitude, randomness) */
|
/* Optimized lerp(max_amplitude * max_distance * 0.5, max_amplitude * max_distance,
|
||||||
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude;
|
* randomness) */
|
||||||
|
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude * max_distance;
|
||||||
|
color_out /= max_amplitude;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1380,14 +1441,15 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
||||||
exponent,
|
exponent,
|
||||||
randomness,
|
randomness,
|
||||||
voronoi_metric,
|
voronoi_metric,
|
||||||
max_distance,
|
|
||||||
&max_amplitude,
|
&max_amplitude,
|
||||||
&distance_out,
|
&distance_out,
|
||||||
&color_out,
|
&color_out,
|
||||||
&position_out);
|
&position_out);
|
||||||
if (normalize) {
|
if (normalize) {
|
||||||
/* Optimized std::lerp(max_amplitude*0.5, max_amplitude, randomness) */
|
/* Optimized lerp(max_amplitude * max_distance * 0.5, max_amplitude * max_distance,
|
||||||
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude;
|
* randomness) */
|
||||||
|
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude * max_distance;
|
||||||
|
color_out /= max_amplitude;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1400,25 +1462,32 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
||||||
exponent,
|
exponent,
|
||||||
randomness,
|
randomness,
|
||||||
voronoi_metric,
|
voronoi_metric,
|
||||||
max_distance,
|
|
||||||
&max_amplitude,
|
&max_amplitude,
|
||||||
&distance_out,
|
&distance_out,
|
||||||
&color_out,
|
&color_out,
|
||||||
&position_out);
|
&position_out);
|
||||||
if (normalize) {
|
if (normalize) {
|
||||||
if (detail == 0.0f || roughness == 0.0f || lacunarity == 0.0f) {
|
if (detail == 0.0f || roughness == 0.0f || lacunarity == 0.0f) {
|
||||||
distance_out /= (1.0f - randomness) + randomness * max_amplitude;
|
distance_out /= (1.0f - randomness) + randomness * max_amplitude * max_distance;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
distance_out /= (1.0f - randomness) * ceilf(detail + 1.0f) +
|
distance_out /= (1.0f - randomness) * ceilf(detail + 1.0f) +
|
||||||
randomness * max_amplitude;
|
randomness * max_amplitude * max_distance;
|
||||||
}
|
}
|
||||||
|
color_out /= max_amplitude;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_VORONOI_DISTANCE_TO_EDGE: {
|
case NODE_VORONOI_DISTANCE_TO_EDGE: {
|
||||||
fractal_voronoi_distance_to_edge<float3>(
|
fractal_voronoi_distance_to_edge<float3>(
|
||||||
coord, detail, lacunarity, randomness, normalize, &distance_out);
|
coord, detail, roughness, lacunarity, randomness, &max_amplitude, &distance_out);
|
||||||
|
if (normalize) {
|
||||||
|
/* max_amplitude is used here to keep the code consistent, however it has a different
|
||||||
|
* meaning than in F1, Smooth F1 and F2. Instead of the highest possible amplitude, it
|
||||||
|
* represents an abstract factor needed to cancel out the amplitude attenuation caused
|
||||||
|
* by the higher layers. */
|
||||||
|
distance_out *= max_amplitude;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_VORONOI_N_SPHERE_RADIUS:
|
case NODE_VORONOI_N_SPHERE_RADIUS:
|
||||||
|
@ -1451,14 +1520,15 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
||||||
exponent,
|
exponent,
|
||||||
randomness,
|
randomness,
|
||||||
voronoi_metric,
|
voronoi_metric,
|
||||||
max_distance,
|
|
||||||
&max_amplitude,
|
&max_amplitude,
|
||||||
&distance_out,
|
&distance_out,
|
||||||
&color_out,
|
&color_out,
|
||||||
&position_out_4d);
|
&position_out_4d);
|
||||||
if (normalize) {
|
if (normalize) {
|
||||||
/* Optimized std::lerp(max_amplitude*0.5, max_amplitude, randomness) */
|
/* Optimized lerp(max_amplitude * max_distance * 0.5, max_amplitude * max_distance,
|
||||||
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude;
|
* randomness) */
|
||||||
|
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude * max_distance;
|
||||||
|
color_out /= max_amplitude;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1471,14 +1541,15 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
||||||
exponent,
|
exponent,
|
||||||
randomness,
|
randomness,
|
||||||
voronoi_metric,
|
voronoi_metric,
|
||||||
max_distance,
|
|
||||||
&max_amplitude,
|
&max_amplitude,
|
||||||
&distance_out,
|
&distance_out,
|
||||||
&color_out,
|
&color_out,
|
||||||
&position_out_4d);
|
&position_out_4d);
|
||||||
if (normalize) {
|
if (normalize) {
|
||||||
/* Optimized std::lerp(max_amplitude*0.5, max_amplitude, randomness) */
|
/* Optimized lerp(max_amplitude * max_distance * 0.5, max_amplitude * max_distance,
|
||||||
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude;
|
* randomness) */
|
||||||
|
distance_out /= (0.5f + 0.5f * randomness) * max_amplitude * max_distance;
|
||||||
|
color_out /= max_amplitude;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1490,25 +1561,37 @@ ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
|
||||||
exponent,
|
exponent,
|
||||||
randomness,
|
randomness,
|
||||||
voronoi_metric,
|
voronoi_metric,
|
||||||
max_distance,
|
|
||||||
&max_amplitude,
|
&max_amplitude,
|
||||||
&distance_out,
|
&distance_out,
|
||||||
&color_out,
|
&color_out,
|
||||||
&position_out_4d);
|
&position_out_4d);
|
||||||
if (normalize) {
|
if (normalize) {
|
||||||
if (detail == 0.0f || roughness == 0.0f || lacunarity == 0.0f) {
|
if (detail == 0.0f || roughness == 0.0f || lacunarity == 0.0f) {
|
||||||
distance_out /= (1.0f - randomness) + randomness * max_amplitude;
|
distance_out /= (1.0f - randomness) + randomness * max_amplitude * max_distance;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
distance_out /= (1.0f - randomness) * ceilf(detail + 1.0f) +
|
distance_out /= (1.0f - randomness) * ceilf(detail + 1.0f) +
|
||||||
randomness * max_amplitude;
|
randomness * max_amplitude * max_distance;
|
||||||
}
|
}
|
||||||
|
color_out /= max_amplitude;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_VORONOI_DISTANCE_TO_EDGE: {
|
case NODE_VORONOI_DISTANCE_TO_EDGE: {
|
||||||
fractal_voronoi_distance_to_edge<float4>(
|
fractal_voronoi_distance_to_edge<float4>(coord_4d,
|
||||||
coord_4d, detail, lacunarity, randomness, normalize, &distance_out);
|
detail,
|
||||||
|
roughness,
|
||||||
|
lacunarity,
|
||||||
|
randomness,
|
||||||
|
&max_amplitude,
|
||||||
|
&distance_out);
|
||||||
|
if (normalize) {
|
||||||
|
/* max_amplitude is used here to keep the code consistent, however it has a different
|
||||||
|
* meaning than in F1, Smooth F1 and F2. Instead of the highest possible amplitude,
|
||||||
|
* it represents an abstract factor needed to cancel out the amplitude attenuation
|
||||||
|
* caused by the higher layers. */
|
||||||
|
distance_out *= max_amplitude;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_VORONOI_N_SPHERE_RADIUS:
|
case NODE_VORONOI_N_SPHERE_RADIUS:
|
||||||
|
|
|
@ -553,7 +553,7 @@ CCL_NAMESPACE_BEGIN
|
||||||
#if !defined(__KERNEL_METAL__)
|
#if !defined(__KERNEL_METAL__)
|
||||||
/* Interpolation */
|
/* Interpolation */
|
||||||
|
|
||||||
template<class A, class B> A lerp(const A &a, const A &b, const B &t)
|
template<class A, class B> ccl_device_inline A lerp(const A &a, const A &b, const B &t)
|
||||||
{
|
{
|
||||||
return (A)(a * ((B)1 - t) + b * t);
|
return (A)(a * ((B)1 - t) + b * t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,10 +186,8 @@ static void node_shader_update_tex_voronoi(bNodeTree *ntree, bNode *node)
|
||||||
storage.distance == SHD_VORONOI_MINKOWSKI && storage.dimensions != 1 &&
|
storage.distance == SHD_VORONOI_MINKOWSKI && storage.dimensions != 1 &&
|
||||||
!ELEM(storage.feature, SHD_VORONOI_DISTANCE_TO_EDGE, SHD_VORONOI_N_SPHERE_RADIUS));
|
!ELEM(storage.feature, SHD_VORONOI_DISTANCE_TO_EDGE, SHD_VORONOI_N_SPHERE_RADIUS));
|
||||||
nodeSetSocketAvailability(ntree, inDetailSock, storage.feature != SHD_VORONOI_N_SPHERE_RADIUS);
|
nodeSetSocketAvailability(ntree, inDetailSock, storage.feature != SHD_VORONOI_N_SPHERE_RADIUS);
|
||||||
nodeSetSocketAvailability(ntree,
|
nodeSetSocketAvailability(
|
||||||
inRoughnessSock,
|
ntree, inRoughnessSock, storage.feature != SHD_VORONOI_N_SPHERE_RADIUS);
|
||||||
storage.feature != SHD_VORONOI_N_SPHERE_RADIUS &&
|
|
||||||
storage.feature != SHD_VORONOI_DISTANCE_TO_EDGE);
|
|
||||||
nodeSetSocketAvailability(
|
nodeSetSocketAvailability(
|
||||||
ntree, inLacunaritySock, storage.feature != SHD_VORONOI_N_SPHERE_RADIUS);
|
ntree, inLacunaritySock, storage.feature != SHD_VORONOI_N_SPHERE_RADIUS);
|
||||||
nodeSetSocketAvailability(ntree, inSmoothnessSock, storage.feature == SHD_VORONOI_SMOOTH_F1);
|
nodeSetSocketAvailability(ntree, inSmoothnessSock, storage.feature == SHD_VORONOI_SMOOTH_F1);
|
||||||
|
@ -1180,6 +1178,7 @@ class VoronoiEdgeFunction : public mf::MultiFunction {
|
||||||
builder.single_input<float>("Scale");
|
builder.single_input<float>("Scale");
|
||||||
if (feature == SHD_VORONOI_DISTANCE_TO_EDGE) {
|
if (feature == SHD_VORONOI_DISTANCE_TO_EDGE) {
|
||||||
builder.single_input<float>("Detail");
|
builder.single_input<float>("Detail");
|
||||||
|
builder.single_input<float>("Roughness");
|
||||||
builder.single_input<float>("Lacunarity");
|
builder.single_input<float>("Lacunarity");
|
||||||
}
|
}
|
||||||
builder.single_input<float>("Randomness");
|
builder.single_input<float>("Randomness");
|
||||||
|
@ -1207,6 +1206,9 @@ class VoronoiEdgeFunction : public mf::MultiFunction {
|
||||||
auto get_detail = [&](int param_index) -> VArray<float> {
|
auto get_detail = [&](int param_index) -> VArray<float> {
|
||||||
return params.readonly_single_input<float>(param_index, "Detail");
|
return params.readonly_single_input<float>(param_index, "Detail");
|
||||||
};
|
};
|
||||||
|
auto get_roughness = [&](int param_index) -> VArray<float> {
|
||||||
|
return params.readonly_single_input<float>(param_index, "Roughness");
|
||||||
|
};
|
||||||
auto get_lacunarity = [&](int param_index) -> VArray<float> {
|
auto get_lacunarity = [&](int param_index) -> VArray<float> {
|
||||||
return params.readonly_single_input<float>(param_index, "Lacunarity");
|
return params.readonly_single_input<float>(param_index, "Lacunarity");
|
||||||
};
|
};
|
||||||
|
@ -1228,6 +1230,7 @@ class VoronoiEdgeFunction : public mf::MultiFunction {
|
||||||
switch (feature_) {
|
switch (feature_) {
|
||||||
case SHD_VORONOI_DISTANCE_TO_EDGE: {
|
case SHD_VORONOI_DISTANCE_TO_EDGE: {
|
||||||
const VArray<float> &detail = get_detail(param++);
|
const VArray<float> &detail = get_detail(param++);
|
||||||
|
const VArray<float> &roughness = get_roughness(param++);
|
||||||
const VArray<float> &lacunarity = get_lacunarity(param++);
|
const VArray<float> &lacunarity = get_lacunarity(param++);
|
||||||
const VArray<float> &randomness = get_randomness(param++);
|
const VArray<float> &randomness = get_randomness(param++);
|
||||||
MutableSpan<float> r_distance = get_r_distance(param++);
|
MutableSpan<float> r_distance = get_r_distance(param++);
|
||||||
|
|
Loading…
Reference in New Issue