Add Fractal Voronoi Noise V.2 #106827

Merged
Jacques Lucke merged 77 commits from Hoshinova/blender:add-fractal-voronoi into main 2023-06-13 09:18:18 +02:00
4 changed files with 647 additions and 247 deletions
Showing only changes of commit 326fb1c28e - Show all commits

View File

@ -1,6 +1,9 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#pragma once
#define NODE_FRACTAL_VORONOI_H
#include "node_voronoi.h"
#include "stdcycles.h"
#include "vector2.h"
@ -8,106 +11,286 @@
#define vector3 point
/* **** 1D Fractal Voronoi **** */
/* **** 1D Fractal Voronoi **** */
/* **** 2D Fractal Voronoi **** */
void fractal_voronoi_f1(float w,
float detail,
float roughness,
float lacunarity,
float exponent,
float randomness,
string metric,
output float max_amplitude,
output float outDistance,
output color outColor,
output float outW)
{
voronoi_f1(w, exponent, randomness, metric, outDistance, outColor, outW);
max_amplitude = 1.0;
}
void fractal_voronoi_smooth_f1(float w,
float detail,
float roughness,
float lacunarity,
float smoothness,
float exponent,
float randomness,
string metric,
output float max_amplitude,
output float outDistance,
output color outColor,
output float outW)
{
voronoi_smooth_f1(w, smoothness, exponent, randomness, metric, outDistance, outColor, outW);
max_amplitude = 1.0;
}
void fractal_voronoi_f2(float w,
float detail,
float roughness,
float lacunarity,
float exponent,
float randomness,
string metric,
output float max_amplitude,
output float outDistance,
output color outColor,
output float outW)
{
voronoi_f2(w, exponent, randomness, metric, outDistance, outColor, outW);
max_amplitude = 1.0;
}
void fractal_voronoi_distance_to_edge(float w,
float detail,
float lacunarity,
float randomness,
float normalize,
output float outDistance)
{
voronoi_distance_to_edge(w, randomness, outDistance);
}
/* **** 2D Fractal Voronoi **** */
void fractal_voronoi_f1(vector2 coord,
float detail,
float roughness,
float lacunarity,
float exponent,
float randomness,
string metric,
float max_distance,
output float max_amplitude,
output float outDistance,
output color outColor,
output vector2 outPosition)
float detail,
float roughness,
float lacunarity,
float exponent,
float randomness,
string metric,
float max_distance,
output float max_amplitude,
output float outDistance,
output color outColor,
output vector2 outPosition)
{
voronoi_f1(coord, exponent, randomness, metric, outDistance, outColor, outPosition);
max_amplitude = max_distance;
}
/* **** 3D Fractal Voronoi **** */
void fractal_voronoi_smooth_f1(vector2 coord,
float detail,
float roughness,
float lacunarity,
float smoothness,
float exponent,
float randomness,
string metric,
float max_distance,
output float max_amplitude,
output float outDistance,
output color outColor,
output vector2 outPosition)
{
voronoi_smooth_f1(
coord, smoothness, exponent, randomness, metric, outDistance, outColor, outPosition);
max_amplitude = max_distance;
}
void fractal_voronoi_f2(vector2 coord,
float detail,
float roughness,
float lacunarity,
float exponent,
float randomness,
string metric,
float max_distance,
output float max_amplitude,
output float outDistance,
output color outColor,
output vector2 outPosition)
{
voronoi_f2(coord, exponent, randomness, metric, outDistance, outColor, outPosition);
max_amplitude = max_distance;
}
void fractal_voronoi_distance_to_edge(vector2 coord,
float detail,
float lacunarity,
float randomness,
float normalize,
output float outDistance)
{
voronoi_distance_to_edge(coord, randomness, outDistance);
}
/* **** 3D Fractal Voronoi **** */
void fractal_voronoi_f1(vector3 coord,
float detail,
float roughness,
float lacunarity,
float exponent,
float randomness,
string metric,
float max_distance,
output float max_amplitude,
output float outDistance,
output color outColor,
output vector3 outPosition)
float detail,
float roughness,
float lacunarity,
float exponent,
float randomness,
string metric,
float max_distance,
output float max_amplitude,
output float outDistance,
output color outColor,
output vector3 outPosition)
{
voronoi_f1(coord, exponent, randomness, metric, outDistance, outColor, outPosition);
max_amplitude = max_distance;
float octave_scale = 1.0;
float octave_amplitude = 1.0;
float octave_distance = 0.0;
max_amplitude = 0.0;
outDistance = 0.0;
for (float i = 0; i <= ceil(detail); ++i) {
voronoi_f1(coord, exponent, randomness, metric, outDistance, outColor, outPosition);
if (detail == 0.0 || roughness == 0.0 || lacunarity == 0.0) {
max_amplitude = max_distance;
outDistance = octave_distance;
return;
}
else if (i <= detail) {
max_amplitude += max_distance * octave_amplitude;
outDistance += octave_distance * octave_amplitude;
outPosition /= octave_scale;
octave_scale *= lacunarity;
octave_amplitude *= roughness;
}
else {
float remainder = detail - floor(detail);
if (remainder != 0.0) {
max_amplitude += max_distance * octave_amplitude;
float lerp_distance = outDistance + octave_distance * octave_amplitude;
outDistance = (1.0 - remainder) * outDistance + remainder * lerp_distance;
outPosition /= octave_scale;
}
}
}
}
void fractal_voronoi_smooth_f1(vector3 coord,
float detail,
float roughness,
float lacunarity,
float smoothness,
float exponent,
float randomness,
string metric,
float max_distance,
output float max_amplitude,
output float outDistance,
output color outColor,
output vector3 outPosition)
float detail,
float roughness,
float lacunarity,
float smoothness,
float exponent,
float randomness,
string metric,
float max_distance,
output float max_amplitude,
output float outDistance,
output color outColor,
output vector3 outPosition)
{
voronoi_smooth_f1(coord, smoothness, exponent, randomness, metric, outDistance, outColor, outPosition);
voronoi_smooth_f1(
coord, smoothness, exponent, randomness, metric, outDistance, outColor, outPosition);
max_amplitude = max_distance;
}
void fractal_voronoi_f2(vector3 coord,
float detail,
float roughness,
float lacunarity,
float exponent,
float randomness,
string metric,
float max_distance,
output float max_amplitude,
output float outDistance,
output color outColor,
output vector3 outPosition)
float detail,
float roughness,
float lacunarity,
float exponent,
float randomness,
string metric,
float max_distance,
output float max_amplitude,
output float outDistance,
output color outColor,
output vector3 outPosition)
{
voronoi_f2(coord, exponent, randomness, metric, outDistance, outColor, outPosition);
max_amplitude = max_distance;
}
void fractal_voronoi_distance_to_edge(vector3 coord,
float detail,
float lacunarity,
float randomness,
float normalize,
output float outDistance)
float detail,
float lacunarity,
float randomness,
float normalize,
output float outDistance)
{
voronoi_distance_to_edge(coord, randomness, outDistance);
}
/* **** 4D Fractal Voronoi **** */
/* **** 4D Fractal Voronoi **** */
void fractal_voronoi_f1(vector4 coord,
float detail,
float roughness,
float lacunarity,
float exponent,
float randomness,
string metric,
float max_distance,
output float max_amplitude,
output float outDistance,
output color outColor,
output vector4 outPosition)
float detail,
float roughness,
float lacunarity,
float exponent,
float randomness,
string metric,
float max_distance,
output float max_amplitude,
output float outDistance,
output color outColor,
output vector4 outPosition)
{
voronoi_f1(coord, exponent, randomness, metric, outDistance, outColor, outPosition);
max_amplitude = max_distance;
}
void fractal_voronoi_smooth_f1(vector4 coord,
float detail,
float roughness,
float lacunarity,
float smoothness,
float exponent,
float randomness,
string metric,
float max_distance,
output float max_amplitude,
output float outDistance,
output color outColor,
output vector4 outPosition)
{
voronoi_smooth_f1(
coord, smoothness, exponent, randomness, metric, outDistance, outColor, outPosition);
max_amplitude = max_distance;
}
void fractal_voronoi_f2(vector4 coord,
float detail,
float roughness,
float lacunarity,
float exponent,
float randomness,
string metric,
float max_distance,
output float max_amplitude,
output float outDistance,
output color outColor,
output vector4 outPosition)
{
voronoi_f2(coord, exponent, randomness, metric, outDistance, outColor, outPosition);
max_amplitude = max_distance;
}
void fractal_voronoi_distance_to_edge(vector4 coord,
float detail,
float lacunarity,
float randomness,
float normalize,
output float outDistance)
{
voronoi_distance_to_edge(coord, randomness, outDistance);
}

View File

@ -1,6 +1,9 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#pragma once
#define NODE_VORONOI_H
#include "node_hash.h"
#include "stdcycles.h"
#include "vector2.h"
@ -8,7 +11,7 @@
#define vector3 point
/* **** Distance Functions **** */
/* **** Distance Functions **** */
float distance(float a, float b)
{
@ -35,9 +38,9 @@ vector2 safe_divide(vector2 a, float b)
vector4 safe_divide(vector4 a, float b)
{
return vector4((b != 0.0) ? a.x / b : 0.0,
(b != 0.0) ? a.y / b : 0.0,
(b != 0.0) ? a.z / b : 0.0,
(b != 0.0) ? a.w / b : 0.0);
(b != 0.0) ? a.y / b : 0.0,
(b != 0.0) ? a.z / b : 0.0,
(b != 0.0) ? a.w / b : 0.0);
}
/*
@ -56,7 +59,7 @@ vector4 safe_divide(vector4 a, float b)
* as explained in https://www.shadertoy.com/view/llG3zy.
*/
/* **** 1D Voronoi **** */
/* **** 1D Voronoi **** */
float voronoi_distance(float a, float b, string metric, float exponent)
{
@ -64,12 +67,12 @@ float voronoi_distance(float a, float b, string metric, float exponent)
}
void voronoi_f1(float w,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output float outW)
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output float outW)
{
float cellPosition = floor(w);
float localPosition = w - cellPosition;
@ -92,13 +95,13 @@ void voronoi_f1(float w,
}
void voronoi_smooth_f1(float w,
float smoothness,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output float outW)
float smoothness,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output float outW)
{
float cellPosition = floor(w);
float localPosition = w - cellPosition;
@ -124,12 +127,12 @@ void voronoi_smooth_f1(float w,
}
void voronoi_f2(float w,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output float outW)
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output float outW)
{
float cellPosition = floor(w);
float localPosition = w - cellPosition;
@ -172,7 +175,7 @@ void voronoi_distance_to_edge(float w, float randomness, output float outDistanc
float rightPointPosition = 1.0 + hash_float_to_float(cellPosition + 1.0) * randomness;
float distanceToMidLeft = distance((midPointPosition + leftPointPosition) / 2.0, localPosition);
float distanceToMidRight = distance((midPointPosition + rightPointPosition) / 2.0,
localPosition);
localPosition);
outDistance = min(distanceToMidLeft, distanceToMidRight);
}
@ -235,12 +238,12 @@ float voronoi_distance(vector2 a, vector2 b, string metric, float exponent)
}
void voronoi_f1(vector2 coord,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector2 outPosition)
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector2 outPosition)
{
vector2 cellPosition = floor(coord);
vector2 localPosition = coord - cellPosition;
@ -251,7 +254,7 @@ void voronoi_f1(vector2 coord,
for (int i = -1; i <= 1; i++) {
vector2 cellOffset = vector2(i, j);
vector2 pointPosition = cellOffset +
hash_vector2_to_vector2(cellPosition + cellOffset) * randomness;
hash_vector2_to_vector2(cellPosition + cellOffset) * randomness;
float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
if (distanceToPoint < minDistance) {
targetOffset = cellOffset;
@ -266,13 +269,13 @@ void voronoi_f1(vector2 coord,
}
void voronoi_smooth_f1(vector2 coord,
float smoothness,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector2 outPosition)
float smoothness,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector2 outPosition)
{
vector2 cellPosition = floor(coord);
vector2 localPosition = coord - cellPosition;
@ -284,7 +287,7 @@ void voronoi_smooth_f1(vector2 coord,
for (int i = -2; i <= 2; i++) {
vector2 cellOffset = vector2(i, j);
vector2 pointPosition = cellOffset +
hash_vector2_to_vector2(cellPosition + cellOffset) * randomness;
hash_vector2_to_vector2(cellPosition + cellOffset) * randomness;
float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
float h = smoothstep(0.0, 1.0, 0.5 + 0.5 * (smoothDistance - distanceToPoint) / smoothness);
float correctionFactor = smoothness * h * (1.0 - h);
@ -301,12 +304,12 @@ void voronoi_smooth_f1(vector2 coord,
}
void voronoi_f2(vector2 coord,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector2 outPosition)
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector2 outPosition)
{
vector2 cellPosition = floor(coord);
vector2 localPosition = coord - cellPosition;
@ -320,7 +323,7 @@ void voronoi_f2(vector2 coord,
for (int i = -1; i <= 1; i++) {
vector2 cellOffset = vector2(i, j);
vector2 pointPosition = cellOffset +
hash_vector2_to_vector2(cellPosition + cellOffset) * randomness;
hash_vector2_to_vector2(cellPosition + cellOffset) * randomness;
float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
if (distanceToPoint < distanceF1) {
distanceF2 = distanceF1;
@ -353,8 +356,8 @@ void voronoi_distance_to_edge(vector2 coord, float randomness, output float outD
for (int i = -1; i <= 1; i++) {
vector2 cellOffset = vector2(i, j);
vector2 vectorToPoint = cellOffset +
hash_vector2_to_vector2(cellPosition + cellOffset) * randomness -
localPosition;
hash_vector2_to_vector2(cellPosition + cellOffset) * randomness -
localPosition;
float distanceToPoint = dot(vectorToPoint, vectorToPoint);
if (distanceToPoint < minDistance) {
minDistance = distanceToPoint;
@ -368,12 +371,12 @@ void voronoi_distance_to_edge(vector2 coord, float randomness, output float outD
for (int i = -1; i <= 1; i++) {
vector2 cellOffset = vector2(i, j);
vector2 vectorToPoint = cellOffset +
hash_vector2_to_vector2(cellPosition + cellOffset) * randomness -
localPosition;
hash_vector2_to_vector2(cellPosition + cellOffset) * randomness -
localPosition;
vector2 perpendicularToEdge = vectorToPoint - vectorToClosest;
if (dot(perpendicularToEdge, perpendicularToEdge) > 0.0001) {
float distanceToEdge = dot((vectorToClosest + vectorToPoint) / 2.0,
normalize(perpendicularToEdge));
normalize(perpendicularToEdge));
minDistance = min(minDistance, distanceToEdge);
}
}
@ -393,7 +396,7 @@ void voronoi_n_sphere_radius(vector2 coord, float randomness, output float outRa
for (int i = -1; i <= 1; i++) {
vector2 cellOffset = vector2(i, j);
vector2 pointPosition = cellOffset +
hash_vector2_to_vector2(cellPosition + cellOffset) * randomness;
hash_vector2_to_vector2(cellPosition + cellOffset) * randomness;
float distanceToPoint = distance(pointPosition, localPosition);
if (distanceToPoint < minDistance) {
minDistance = distanceToPoint;
@ -412,7 +415,7 @@ void voronoi_n_sphere_radius(vector2 coord, float randomness, output float outRa
}
vector2 cellOffset = vector2(i, j) + closestPointOffset;
vector2 pointPosition = cellOffset +
hash_vector2_to_vector2(cellPosition + cellOffset) * randomness;
hash_vector2_to_vector2(cellPosition + cellOffset) * randomness;
float distanceToPoint = distance(closestPoint, pointPosition);
if (distanceToPoint < minDistance) {
minDistance = distanceToPoint;
@ -438,8 +441,8 @@ float voronoi_distance(vector3 a, vector3 b, string metric, float exponent)
}
else if (metric == "minkowski") {
return pow(pow(abs(a[0] - b[0]), exponent) + pow(abs(a[1] - b[1]), exponent) +
pow(abs(a[2] - b[2]), exponent),
1.0 / exponent);
pow(abs(a[2] - b[2]), exponent),
1.0 / exponent);
}
else {
return 0.0;
@ -447,12 +450,12 @@ float voronoi_distance(vector3 a, vector3 b, string metric, float exponent)
}
void voronoi_f1(vector3 coord,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector3 outPosition)
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector3 outPosition)
{
vector3 cellPosition = floor(coord);
vector3 localPosition = coord - cellPosition;
@ -464,7 +467,7 @@ void voronoi_f1(vector3 coord,
for (int i = -1; i <= 1; i++) {
vector3 cellOffset = vector3(i, j, k);
vector3 pointPosition = cellOffset +
hash_vector3_to_vector3(cellPosition + cellOffset) * randomness;
hash_vector3_to_vector3(cellPosition + cellOffset) * randomness;
float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
if (distanceToPoint < minDistance) {
targetOffset = cellOffset;
@ -480,13 +483,13 @@ void voronoi_f1(vector3 coord,
}
void voronoi_smooth_f1(vector3 coord,
float smoothness,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector3 outPosition)
float smoothness,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector3 outPosition)
{
vector3 cellPosition = floor(coord);
vector3 localPosition = coord - cellPosition;
@ -499,10 +502,10 @@ void voronoi_smooth_f1(vector3 coord,
for (int i = -2; i <= 2; i++) {
vector3 cellOffset = vector3(i, j, k);
vector3 pointPosition = cellOffset +
hash_vector3_to_vector3(cellPosition + cellOffset) * randomness;
hash_vector3_to_vector3(cellPosition + cellOffset) * randomness;
float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
float h = smoothstep(
0.0, 1.0, 0.5 + 0.5 * (smoothDistance - distanceToPoint) / smoothness);
0.0, 1.0, 0.5 + 0.5 * (smoothDistance - distanceToPoint) / smoothness);
float correctionFactor = smoothness * h * (1.0 - h);
smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
correctionFactor /= 1.0 + 3.0 * smoothness;
@ -518,12 +521,12 @@ void voronoi_smooth_f1(vector3 coord,
}
void voronoi_f2(vector3 coord,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector3 outPosition)
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector3 outPosition)
{
vector3 cellPosition = floor(coord);
vector3 localPosition = coord - cellPosition;
@ -538,7 +541,7 @@ void voronoi_f2(vector3 coord,
for (int i = -1; i <= 1; i++) {
vector3 cellOffset = vector3(i, j, k);
vector3 pointPosition = cellOffset +
hash_vector3_to_vector3(cellPosition + cellOffset) * randomness;
hash_vector3_to_vector3(cellPosition + cellOffset) * randomness;
float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
if (distanceToPoint < distanceF1) {
distanceF2 = distanceF1;
@ -573,8 +576,8 @@ void voronoi_distance_to_edge(vector3 coord, float randomness, output float outD
for (int i = -1; i <= 1; i++) {
vector3 cellOffset = vector3(i, j, k);
vector3 vectorToPoint = cellOffset +
hash_vector3_to_vector3(cellPosition + cellOffset) * randomness -
localPosition;
hash_vector3_to_vector3(cellPosition + cellOffset) * randomness -
localPosition;
float distanceToPoint = dot(vectorToPoint, vectorToPoint);
if (distanceToPoint < minDistance) {
minDistance = distanceToPoint;
@ -590,12 +593,12 @@ void voronoi_distance_to_edge(vector3 coord, float randomness, output float outD
for (int i = -1; i <= 1; i++) {
vector3 cellOffset = vector3(i, j, k);
vector3 vectorToPoint = cellOffset +
hash_vector3_to_vector3(cellPosition + cellOffset) * randomness -
localPosition;
hash_vector3_to_vector3(cellPosition + cellOffset) * randomness -
localPosition;
vector3 perpendicularToEdge = vectorToPoint - vectorToClosest;
if (dot(perpendicularToEdge, perpendicularToEdge) > 0.0001) {
float distanceToEdge = dot((vectorToClosest + vectorToPoint) / 2.0,
normalize((vector)perpendicularToEdge));
normalize((vector)perpendicularToEdge));
minDistance = min(minDistance, distanceToEdge);
}
}
@ -617,7 +620,7 @@ void voronoi_n_sphere_radius(vector3 coord, float randomness, output float outRa
for (int i = -1; i <= 1; i++) {
vector3 cellOffset = vector3(i, j, k);
vector3 pointPosition = cellOffset +
hash_vector3_to_vector3(cellPosition + cellOffset) * randomness;
hash_vector3_to_vector3(cellPosition + cellOffset) * randomness;
float distanceToPoint = distance(pointPosition, localPosition);
if (distanceToPoint < minDistance) {
minDistance = distanceToPoint;
@ -638,7 +641,7 @@ void voronoi_n_sphere_radius(vector3 coord, float randomness, output float outRa
}
vector3 cellOffset = vector3(i, j, k) + closestPointOffset;
vector3 pointPosition = cellOffset +
hash_vector3_to_vector3(cellPosition + cellOffset) * randomness;
hash_vector3_to_vector3(cellPosition + cellOffset) * randomness;
float distanceToPoint = distance(closestPoint, pointPosition);
if (distanceToPoint < minDistance) {
minDistance = distanceToPoint;
@ -665,8 +668,8 @@ float voronoi_distance(vector4 a, vector4 b, string metric, float exponent)
}
else if (metric == "minkowski") {
return pow(pow(abs(a.x - b.x), exponent) + pow(abs(a.y - b.y), exponent) +
pow(abs(a.z - b.z), exponent) + pow(abs(a.w - b.w), exponent),
1.0 / exponent);
pow(abs(a.z - b.z), exponent) + pow(abs(a.w - b.w), exponent),
1.0 / exponent);
}
else {
return 0.0;
@ -674,12 +677,12 @@ float voronoi_distance(vector4 a, vector4 b, string metric, float exponent)
}
void voronoi_f1(vector4 coord,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector4 outPosition)
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector4 outPosition)
{
vector4 cellPosition = floor(coord);
vector4 localPosition = coord - cellPosition;
@ -692,7 +695,7 @@ void voronoi_f1(vector4 coord,
for (int i = -1; i <= 1; i++) {
vector4 cellOffset = vector4(i, j, k, u);
vector4 pointPosition = cellOffset +
hash_vector4_to_vector4(cellPosition + cellOffset) * randomness;
hash_vector4_to_vector4(cellPosition + cellOffset) * randomness;
float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
if (distanceToPoint < minDistance) {
targetOffset = cellOffset;
@ -709,13 +712,13 @@ void voronoi_f1(vector4 coord,
}
void voronoi_smooth_f1(vector4 coord,
float smoothness,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector4 outPosition)
float smoothness,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector4 outPosition)
{
vector4 cellPosition = floor(coord);
vector4 localPosition = coord - cellPosition;
@ -729,10 +732,10 @@ void voronoi_smooth_f1(vector4 coord,
for (int i = -2; i <= 2; i++) {
vector4 cellOffset = vector4(i, j, k, u);
vector4 pointPosition = cellOffset +
hash_vector4_to_vector4(cellPosition + cellOffset) * randomness;
hash_vector4_to_vector4(cellPosition + cellOffset) * randomness;
float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
float h = smoothstep(
0.0, 1.0, 0.5 + 0.5 * (smoothDistance - distanceToPoint) / smoothness);
0.0, 1.0, 0.5 + 0.5 * (smoothDistance - distanceToPoint) / smoothness);
float correctionFactor = smoothness * h * (1.0 - h);
smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
correctionFactor /= 1.0 + 3.0 * smoothness;
@ -749,12 +752,12 @@ void voronoi_smooth_f1(vector4 coord,
}
void voronoi_f2(vector4 coord,
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector4 outPosition)
float exponent,
float randomness,
string metric,
output float outDistance,
output color outColor,
output vector4 outPosition)
{
vector4 cellPosition = floor(coord);
vector4 localPosition = coord - cellPosition;
@ -770,7 +773,7 @@ void voronoi_f2(vector4 coord,
for (int i = -1; i <= 1; i++) {
vector4 cellOffset = vector4(i, j, k, u);
vector4 pointPosition = cellOffset +
hash_vector4_to_vector4(cellPosition + cellOffset) * randomness;
hash_vector4_to_vector4(cellPosition + cellOffset) * randomness;
float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
if (distanceToPoint < distanceF1) {
distanceF2 = distanceF1;
@ -807,8 +810,8 @@ void voronoi_distance_to_edge(vector4 coord, float randomness, output float outD
for (int i = -1; i <= 1; i++) {
vector4 cellOffset = vector4(i, j, k, u);
vector4 vectorToPoint = cellOffset +
hash_vector4_to_vector4(cellPosition + cellOffset) * randomness -
localPosition;
hash_vector4_to_vector4(cellPosition + cellOffset) * randomness -
localPosition;
float distanceToPoint = dot(vectorToPoint, vectorToPoint);
if (distanceToPoint < minDistance) {
minDistance = distanceToPoint;
@ -826,12 +829,12 @@ void voronoi_distance_to_edge(vector4 coord, float randomness, output float outD
for (int i = -1; i <= 1; i++) {
vector4 cellOffset = vector4(i, j, k, u);
vector4 vectorToPoint = cellOffset +
hash_vector4_to_vector4(cellPosition + cellOffset) * randomness -
localPosition;
hash_vector4_to_vector4(cellPosition + cellOffset) * randomness -
localPosition;
vector4 perpendicularToEdge = vectorToPoint - vectorToClosest;
if (dot(perpendicularToEdge, perpendicularToEdge) > 0.0001) {
float distanceToEdge = dot((vectorToClosest + vectorToPoint) / 2.0,
normalize(perpendicularToEdge));
normalize(perpendicularToEdge));
minDistance = min(minDistance, distanceToEdge);
}
}
@ -855,7 +858,7 @@ void voronoi_n_sphere_radius(vector4 coord, float randomness, output float outRa
for (int i = -1; i <= 1; i++) {
vector4 cellOffset = vector4(i, j, k, u);
vector4 pointPosition = cellOffset +
hash_vector4_to_vector4(cellPosition + cellOffset) * randomness;
hash_vector4_to_vector4(cellPosition + cellOffset) * randomness;
float distanceToPoint = distance(pointPosition, localPosition);
if (distanceToPoint < minDistance) {
minDistance = distanceToPoint;
@ -878,7 +881,7 @@ void voronoi_n_sphere_radius(vector4 coord, float randomness, output float outRa
}
vector4 cellOffset = vector4(i, j, k, u) + closestPointOffset;
vector4 pointPosition = cellOffset +
hash_vector4_to_vector4(cellPosition + cellOffset) * randomness;
hash_vector4_to_vector4(cellPosition + cellOffset) * randomness;
float distanceToPoint = distance(closestPoint, pointPosition);
if (distanceToPoint < minDistance) {
minDistance = distanceToPoint;

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#include "node_voronoi.h"
#include "node_fractal_voronoi.h"
#include "stdcycles.h"
#include "vector2.h"
@ -44,12 +45,72 @@ shader node_voronoi_texture(
if (dimensions == "1D") {
if (feature == "f1") {
float max_amplitude = 1.0;
fractal_voronoi_f1(WIn,
detail,
roughness,
Lacunarity,
Exponent,
randomness,
metric,
max_amplitude,
Distance,
Color,
WOut);
if (normalize != 0.0) {
/* Optimized lerp(max_amplitude*0.5, max_amplitude, randomness) */
Distance /= (0.5 + 0.5 * randomness) * max_amplitude;
}
}
else if (feature == "smooth_f1") {
float max_amplitude = 1.0;
fractal_voronoi_smooth_f1(WIn,
detail,
roughness,
Lacunarity,
smoothness,
Exponent,
randomness,
metric,
max_amplitude,
Distance,
Color,
WOut);
if (normalize != 0.0) {
/* Optimized lerp(max_amplitude*0.5, max_amplitude, randomness) */
Distance /= (0.5 + 0.5 * randomness) * max_amplitude;
}
}
else if (feature == "f2") {
float max_amplitude = 1.0;
fractal_voronoi_f2(WIn,
detail,
roughness,
Lacunarity,
Exponent,
randomness,
metric,
max_amplitude,
Distance,
Color,
WOut);
if (normalize != 0.0) {
if (detail == 0.0 || roughness == 0.0 || Lacunarity == 0.0) {
Distance /= (1.0 - randomness) + randomness * max_amplitude;
}
else {
Distance /= (1.0 - randomness) * ceil(detail + 1.0) + randomness * max_amplitude;
}
}
}
else if (feature == "distance_to_edge") {
fractal_voronoi_distance_to_edge(WIn, detail, Lacunarity, randomness, normalize, Distance);
}
else if (feature == "n_sphere_radius") {
voronoi_n_sphere_radius(w, randomness, Radius);
@ -63,12 +124,81 @@ shader node_voronoi_texture(
vector2 coord2D = vector2(coord[0], coord[1]);
vector2 outPosition2D;
if (feature == "f1") {
float max_distance = voronoi_distance(
vector2(1.0, 1.0), vector2(0.0, 0.0), metric, Exponent);
float max_amplitude = max_distance;
fractal_voronoi_f1(coord2D,
detail,
roughness,
Lacunarity,
Exponent,
randomness,
metric,
max_distance,
max_amplitude,
Distance,
Color,
outPosition2D);
if (normalize != 0.0) {
/* Optimized lerp(max_amplitude*0.5, max_amplitude, randomness) */
Distance /= (0.5 + 0.5 * randomness) * max_amplitude;
}
}
else if (feature == "smooth_f1") {
float max_distance = voronoi_distance(
vector2(1.0, 1.0), vector2(0.0, 0.0), metric, Exponent);
float max_amplitude = max_distance;
fractal_voronoi_smooth_f1(coord2D,
detail,
roughness,
Lacunarity,
smoothness,
Exponent,
randomness,
metric,
max_distance,
max_amplitude,
Distance,
Color,
outPosition2D);
if (normalize != 0.0) {
/* Optimized lerp(max_amplitude*0.5, max_amplitude, randomness) */
Distance /= (0.5 + 0.5 * randomness) * max_amplitude;
}
}
else if (feature == "f2") {
float max_distance = voronoi_distance(
vector2(1.0, 1.0), vector2(0.0, 0.0), metric, Exponent);
float max_amplitude = max_distance;
fractal_voronoi_f2(coord2D,
detail,
roughness,
Lacunarity,
Exponent,
randomness,
metric,
max_distance,
max_amplitude,
Distance,
Color,
outPosition2D);
if (normalize != 0.0) {
if (detail == 0.0 || roughness == 0.0 || Lacunarity == 0.0) {
Distance /= (1.0 - randomness) + randomness * max_amplitude;
}
else {
Distance /= (1.0 - randomness) * ceil(detail + 1.0) + randomness * max_amplitude;
}
}
}
else if (feature == "distance_to_edge") {
fractal_voronoi_distance_to_edge(coord2D, detail, Lacunarity, randomness, normalize, Distance);
}
else if (feature == "n_sphere_radius") {
voronoi_n_sphere_radius(coord2D, randomness, Radius);
@ -82,80 +212,80 @@ shader node_voronoi_texture(
else if (dimensions == "3D") {
if (feature == "f1") {
float max_distance = voronoi_distance(
vector3(1.0, 1.0, 1.0), vector3(0.0, 0.0, 0.0), metric, Exponent);
float max_amplitude = max_distance;
vector3(1.0, 1.0, 1.0), vector3(0.0, 0.0, 0.0), metric, Exponent);
float max_amplitude = max_distance;
fractal_voronoi_f1(coord,
detail,
roughness,
Lacunarity,
Exponent,
randomness,
metric,
max_distance,
max_amplitude,
Distance,
Color,
Position);
fractal_voronoi_f1(coord,
detail,
roughness,
Lacunarity,
Exponent,
randomness,
metric,
max_distance,
max_amplitude,
Distance,
Color,
Position);
if (normalize != 0.0) {
/* Optimized lerp(max_amplitude*0.5, max_amplitude, randomness) */
Distance /= (0.5 + 0.5 * randomness) * max_amplitude;
}
if (normalize != 0.0) {
/* Optimized lerp(max_amplitude*0.5, max_amplitude, randomness) */
Distance /= (0.5 + 0.5 * randomness) * max_amplitude;
}
}
else if (feature == "smooth_f1") {
float max_distance = voronoi_distance(
vector3(1.0, 1.0, 1.0), vector3(0.0, 0.0, 0.0), metric, Exponent);
float max_amplitude = max_distance;
float max_distance = voronoi_distance(
vector3(1.0, 1.0, 1.0), vector3(0.0, 0.0, 0.0), metric, Exponent);
float max_amplitude = max_distance;
fractal_voronoi_smooth_f1(coord,
detail,
roughness,
Lacunarity,
smoothness,
Exponent,
randomness,
metric,
max_distance,
max_amplitude,
Distance,
Color,
Position);
fractal_voronoi_smooth_f1(coord,
detail,
roughness,
Lacunarity,
smoothness,
Exponent,
randomness,
metric,
max_distance,
max_amplitude,
Distance,
Color,
Position);
if (normalize != 0.0) {
/* Optimized lerp(max_amplitude*0.5, max_amplitude, randomness) */
Distance /= (0.5 + 0.5 * randomness) * max_amplitude;
}
if (normalize != 0.0) {
/* Optimized lerp(max_amplitude*0.5, max_amplitude, randomness) */
Distance /= (0.5 + 0.5 * randomness) * max_amplitude;
}
}
else if (feature == "f2") {
float max_distance = voronoi_distance(
vector3(1.0, 1.0, 1.0), vector3(0.0, 0.0, 0.0), metric, Exponent);
float max_amplitude = max_distance;
float max_distance = voronoi_distance(
vector3(1.0, 1.0, 1.0), vector3(0.0, 0.0, 0.0), metric, Exponent);
float max_amplitude = max_distance;
fractal_voronoi_f2(coord,
detail,
roughness,
Lacunarity,
Exponent,
randomness,
metric,
max_distance,
max_amplitude,
Distance,
Color,
Position);
fractal_voronoi_f2(coord,
detail,
roughness,
Lacunarity,
Exponent,
randomness,
metric,
max_distance,
max_amplitude,
Distance,
Color,
Position);
if (normalize != 0.0) {
if (normalize != 0.0) {
if (detail == 0.0 || roughness == 0.0 || Lacunarity == 0.0) {
Distance /= (1.0 - randomness) + randomness * max_amplitude;
}
else {
Distance /= (1.0 - randomness) * ceil(detail + 1.0) + randomness * max_amplitude;
}
}
Distance /= (1.0 - randomness) + randomness * max_amplitude;
}
else {
Distance /= (1.0 - randomness) * ceil(detail + 1.0) + randomness * max_amplitude;
}
}
}
else if (feature == "distance_to_edge") {
fractal_voronoi_distance_to_edge(coord, detail, Lacunarity,randomness,normalize,Distance);
fractal_voronoi_distance_to_edge(coord, detail, Lacunarity, randomness, normalize, Distance);
}
else if (feature == "n_sphere_radius") {
voronoi_n_sphere_radius(coord, randomness, Radius);
@ -169,12 +299,81 @@ shader node_voronoi_texture(
vector4 coord4D = vector4(coord[0], coord[1], coord[2], w);
vector4 outPosition4D;
if (feature == "f1") {
float max_distance = voronoi_distance(
vector4(1.0, 1.0, 1.0, 1.0), vector4(0.0, 0.0, 0.0, 0.0), metric, Exponent);
float max_amplitude = max_distance;
fractal_voronoi_f1(coord4D,
detail,
roughness,
Lacunarity,
Exponent,
randomness,
metric,
max_distance,
max_amplitude,
Distance,
Color,
outPosition4D);
if (normalize != 0.0) {
/* Optimized lerp(max_amplitude*0.5, max_amplitude, randomness) */
Distance /= (0.5 + 0.5 * randomness) * max_amplitude;
}
}
else if (feature == "smooth_f1") {
float max_distance = voronoi_distance(
vector4(1.0, 1.0, 1.0, 1.0), vector4(0.0, 0.0, 0.0, 0.0), metric, Exponent);
float max_amplitude = max_distance;
fractal_voronoi_smooth_f1(coord4D,
detail,
roughness,
Lacunarity,
smoothness,
Exponent,
randomness,
metric,
max_distance,
max_amplitude,
Distance,
Color,
outPosition4D);
if (normalize != 0.0) {
/* Optimized lerp(max_amplitude*0.5, max_amplitude, randomness) */
Distance /= (0.5 + 0.5 * randomness) * max_amplitude;
}
}
else if (feature == "f2") {
float max_distance = voronoi_distance(
vector4(1.0, 1.0, 1.0, 1.0), vector4(0.0, 0.0, 0.0, 0.0), metric, Exponent);
float max_amplitude = max_distance;
fractal_voronoi_f2(coord4D,
detail,
roughness,
Lacunarity,
Exponent,
randomness,
metric,
max_distance,
max_amplitude,
Distance,
Color,
outPosition4D);
if (normalize != 0.0) {
if (detail == 0.0 || roughness == 0.0 || Lacunarity == 0.0) {
Distance /= (1.0 - randomness) + randomness * max_amplitude;
}
else {
Distance /= (1.0 - randomness) * ceil(detail + 1.0) + randomness * max_amplitude;
}
}
}
else if (feature == "distance_to_edge") {
fractal_voronoi_distance_to_edge(coord4D, detail, Lacunarity, randomness, normalize, Distance);
}
else if (feature == "n_sphere_radius") {
voronoi_n_sphere_radius(coord4D, randomness, Radius);

View File

@ -2,7 +2,22 @@
* Copyright 2011-2022 Blender Foundation */
#pragma once
#include "device/device.h"
#include "scene/background.h"
#include "scene/light.h"
#include "scene/mesh.h"
#include "scene/scene.h"
#include "scene/shader.h"
#include "scene/shader_graph.h"
#include "scene/shader_nodes.h"
#include "scene/stats.h"
#include "scene/svm.h"
#include "util/foreach.h"
#include "util/log.h"
#include "util/progress.h"
#include "util/task.h"
CCL_NAMESPACE_BEGIN
/*