Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/svm/svm_voronoi.h')
-rw-r--r--intern/cycles/kernel/svm/svm_voronoi.h1162
1 files changed, 0 insertions, 1162 deletions
diff --git a/intern/cycles/kernel/svm/svm_voronoi.h b/intern/cycles/kernel/svm/svm_voronoi.h
deleted file mode 100644
index b8067520770..00000000000
--- a/intern/cycles/kernel/svm/svm_voronoi.h
+++ /dev/null
@@ -1,1162 +0,0 @@
-/*
- * Copyright 2011-2013 Blender Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-CCL_NAMESPACE_BEGIN
-
-/*
- * Original code is under the MIT License, Copyright (c) 2013 Inigo Quilez.
- *
- * Smooth Voronoi:
- *
- * - https://wiki.blender.org/wiki/User:OmarSquircleArt/GSoC2019/Documentation/Smooth_Voronoi
- *
- * Distance To Edge based on:
- *
- * - https://www.iquilezles.org/www/articles/voronoilines/voronoilines.htm
- * - https://www.shadertoy.com/view/ldl3W8
- *
- * With optimization to change -2..2 scan window to -1..1 for better performance,
- * as explained in https://www.shadertoy.com/view/llG3zy.
- */
-
-/* **** 1D Voronoi **** */
-
-ccl_device float voronoi_distance_1d(float a,
- float b,
- NodeVoronoiDistanceMetric metric,
- float exponent)
-{
- return fabsf(b - a);
-}
-
-ccl_device void voronoi_f1_1d(float w,
- float exponent,
- float randomness,
- NodeVoronoiDistanceMetric metric,
- ccl_private float *outDistance,
- ccl_private float3 *outColor,
- ccl_private float *outW)
-{
- float cellPosition = floorf(w);
- float localPosition = w - cellPosition;
-
- float minDistance = 8.0f;
- float targetOffset = 0.0f;
- float targetPosition = 0.0f;
- for (int i = -1; i <= 1; i++) {
- float cellOffset = i;
- float pointPosition = cellOffset + hash_float_to_float(cellPosition + cellOffset) * randomness;
- float distanceToPoint = voronoi_distance_1d(pointPosition, localPosition, metric, exponent);
- if (distanceToPoint < minDistance) {
- targetOffset = cellOffset;
- minDistance = distanceToPoint;
- targetPosition = pointPosition;
- }
- }
- *outDistance = minDistance;
- *outColor = hash_float_to_float3(cellPosition + targetOffset);
- *outW = targetPosition + cellPosition;
-}
-
-ccl_device void voronoi_smooth_f1_1d(float w,
- float smoothness,
- float exponent,
- float randomness,
- NodeVoronoiDistanceMetric metric,
- ccl_private float *outDistance,
- ccl_private float3 *outColor,
- ccl_private float *outW)
-{
- float cellPosition = floorf(w);
- float localPosition = w - cellPosition;
-
- float smoothDistance = 8.0f;
- float smoothPosition = 0.0f;
- float3 smoothColor = make_float3(0.0f, 0.0f, 0.0f);
- for (int i = -2; i <= 2; i++) {
- float cellOffset = i;
- float pointPosition = cellOffset + hash_float_to_float(cellPosition + cellOffset) * randomness;
- float distanceToPoint = voronoi_distance_1d(pointPosition, localPosition, metric, exponent);
- float h = smoothstep(
- 0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness);
- float correctionFactor = smoothness * h * (1.0f - h);
- smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
- correctionFactor /= 1.0f + 3.0f * smoothness;
- float3 cellColor = hash_float_to_float3(cellPosition + cellOffset);
- smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
- smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
- }
- *outDistance = smoothDistance;
- *outColor = smoothColor;
- *outW = cellPosition + smoothPosition;
-}
-
-ccl_device void voronoi_f2_1d(float w,
- float exponent,
- float randomness,
- NodeVoronoiDistanceMetric metric,
- ccl_private float *outDistance,
- ccl_private float3 *outColor,
- ccl_private float *outW)
-{
- float cellPosition = floorf(w);
- float localPosition = w - cellPosition;
-
- float distanceF1 = 8.0f;
- float distanceF2 = 8.0f;
- float offsetF1 = 0.0f;
- float positionF1 = 0.0f;
- float offsetF2 = 0.0f;
- float positionF2 = 0.0f;
- for (int i = -1; i <= 1; i++) {
- float cellOffset = i;
- float pointPosition = cellOffset + hash_float_to_float(cellPosition + cellOffset) * randomness;
- float distanceToPoint = voronoi_distance_1d(pointPosition, localPosition, metric, exponent);
- if (distanceToPoint < distanceF1) {
- distanceF2 = distanceF1;
- distanceF1 = distanceToPoint;
- offsetF2 = offsetF1;
- offsetF1 = cellOffset;
- positionF2 = positionF1;
- positionF1 = pointPosition;
- }
- else if (distanceToPoint < distanceF2) {
- distanceF2 = distanceToPoint;
- offsetF2 = cellOffset;
- positionF2 = pointPosition;
- }
- }
- *outDistance = distanceF2;
- *outColor = hash_float_to_float3(cellPosition + offsetF2);
- *outW = positionF2 + cellPosition;
-}
-
-ccl_device void voronoi_distance_to_edge_1d(float w,
- float randomness,
- ccl_private float *outDistance)
-{
- float cellPosition = floorf(w);
- float localPosition = w - cellPosition;
-
- float midPointPosition = hash_float_to_float(cellPosition) * randomness;
- float leftPointPosition = -1.0f + hash_float_to_float(cellPosition - 1.0f) * randomness;
- float rightPointPosition = 1.0f + hash_float_to_float(cellPosition + 1.0f) * randomness;
- float distanceToMidLeft = fabsf((midPointPosition + leftPointPosition) / 2.0f - localPosition);
- float distanceToMidRight = fabsf((midPointPosition + rightPointPosition) / 2.0f - localPosition);
-
- *outDistance = min(distanceToMidLeft, distanceToMidRight);
-}
-
-ccl_device void voronoi_n_sphere_radius_1d(float w, float randomness, ccl_private float *outRadius)
-{
- float cellPosition = floorf(w);
- float localPosition = w - cellPosition;
-
- float closestPoint = 0.0f;
- float closestPointOffset = 0.0f;
- float minDistance = 8.0f;
- for (int i = -1; i <= 1; i++) {
- float cellOffset = i;
- float pointPosition = cellOffset + hash_float_to_float(cellPosition + cellOffset) * randomness;
- float distanceToPoint = fabsf(pointPosition - localPosition);
- if (distanceToPoint < minDistance) {
- minDistance = distanceToPoint;
- closestPoint = pointPosition;
- closestPointOffset = cellOffset;
- }
- }
-
- minDistance = 8.0f;
- float closestPointToClosestPoint = 0.0f;
- for (int i = -1; i <= 1; i++) {
- if (i == 0) {
- continue;
- }
- float cellOffset = i + closestPointOffset;
- float pointPosition = cellOffset + hash_float_to_float(cellPosition + cellOffset) * randomness;
- float distanceToPoint = fabsf(closestPoint - pointPosition);
- if (distanceToPoint < minDistance) {
- minDistance = distanceToPoint;
- closestPointToClosestPoint = pointPosition;
- }
- }
- *outRadius = fabsf(closestPointToClosestPoint - closestPoint) / 2.0f;
-}
-
-/* **** 2D Voronoi **** */
-
-ccl_device float voronoi_distance_2d(float2 a,
- float2 b,
- NodeVoronoiDistanceMetric metric,
- float exponent)
-{
- if (metric == NODE_VORONOI_EUCLIDEAN) {
- return distance(a, b);
- }
- else if (metric == NODE_VORONOI_MANHATTAN) {
- return fabsf(a.x - b.x) + fabsf(a.y - b.y);
- }
- else if (metric == NODE_VORONOI_CHEBYCHEV) {
- return max(fabsf(a.x - b.x), fabsf(a.y - b.y));
- }
- else if (metric == NODE_VORONOI_MINKOWSKI) {
- return powf(powf(fabsf(a.x - b.x), exponent) + powf(fabsf(a.y - b.y), exponent),
- 1.0f / exponent);
- }
- else {
- return 0.0f;
- }
-}
-
-ccl_device void voronoi_f1_2d(float2 coord,
- float exponent,
- float randomness,
- NodeVoronoiDistanceMetric metric,
- ccl_private float *outDistance,
- ccl_private float3 *outColor,
- ccl_private float2 *outPosition)
-{
- float2 cellPosition = floor(coord);
- float2 localPosition = coord - cellPosition;
-
- float minDistance = 8.0f;
- float2 targetOffset = make_float2(0.0f, 0.0f);
- float2 targetPosition = make_float2(0.0f, 0.0f);
- for (int j = -1; j <= 1; j++) {
- for (int i = -1; i <= 1; i++) {
- float2 cellOffset = make_float2(i, j);
- float2 pointPosition = cellOffset +
- hash_float2_to_float2(cellPosition + cellOffset) * randomness;
- float distanceToPoint = voronoi_distance_2d(pointPosition, localPosition, metric, exponent);
- if (distanceToPoint < minDistance) {
- targetOffset = cellOffset;
- minDistance = distanceToPoint;
- targetPosition = pointPosition;
- }
- }
- }
- *outDistance = minDistance;
- *outColor = hash_float2_to_float3(cellPosition + targetOffset);
- *outPosition = targetPosition + cellPosition;
-}
-
-ccl_device void voronoi_smooth_f1_2d(float2 coord,
- float smoothness,
- float exponent,
- float randomness,
- NodeVoronoiDistanceMetric metric,
- ccl_private float *outDistance,
- ccl_private float3 *outColor,
- ccl_private float2 *outPosition)
-{
- float2 cellPosition = floor(coord);
- float2 localPosition = coord - cellPosition;
-
- float smoothDistance = 8.0f;
- float3 smoothColor = make_float3(0.0f, 0.0f, 0.0f);
- float2 smoothPosition = make_float2(0.0f, 0.0f);
- for (int j = -2; j <= 2; j++) {
- for (int i = -2; i <= 2; i++) {
- float2 cellOffset = make_float2(i, j);
- float2 pointPosition = cellOffset +
- hash_float2_to_float2(cellPosition + cellOffset) * randomness;
- float distanceToPoint = voronoi_distance_2d(pointPosition, localPosition, metric, exponent);
- float h = smoothstep(
- 0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness);
- float correctionFactor = smoothness * h * (1.0f - h);
- smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
- correctionFactor /= 1.0f + 3.0f * smoothness;
- float3 cellColor = hash_float2_to_float3(cellPosition + cellOffset);
- smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
- smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
- }
- }
- *outDistance = smoothDistance;
- *outColor = smoothColor;
- *outPosition = cellPosition + smoothPosition;
-}
-
-ccl_device void voronoi_f2_2d(float2 coord,
- float exponent,
- float randomness,
- NodeVoronoiDistanceMetric metric,
- ccl_private float *outDistance,
- ccl_private float3 *outColor,
- ccl_private float2 *outPosition)
-{
- float2 cellPosition = floor(coord);
- float2 localPosition = coord - cellPosition;
-
- float distanceF1 = 8.0f;
- float distanceF2 = 8.0f;
- float2 offsetF1 = make_float2(0.0f, 0.0f);
- float2 positionF1 = make_float2(0.0f, 0.0f);
- float2 offsetF2 = make_float2(0.0f, 0.0f);
- float2 positionF2 = make_float2(0.0f, 0.0f);
- for (int j = -1; j <= 1; j++) {
- for (int i = -1; i <= 1; i++) {
- float2 cellOffset = make_float2(i, j);
- float2 pointPosition = cellOffset +
- hash_float2_to_float2(cellPosition + cellOffset) * randomness;
- float distanceToPoint = voronoi_distance_2d(pointPosition, localPosition, metric, exponent);
- if (distanceToPoint < distanceF1) {
- distanceF2 = distanceF1;
- distanceF1 = distanceToPoint;
- offsetF2 = offsetF1;
- offsetF1 = cellOffset;
- positionF2 = positionF1;
- positionF1 = pointPosition;
- }
- else if (distanceToPoint < distanceF2) {
- distanceF2 = distanceToPoint;
- offsetF2 = cellOffset;
- positionF2 = pointPosition;
- }
- }
- }
- *outDistance = distanceF2;
- *outColor = hash_float2_to_float3(cellPosition + offsetF2);
- *outPosition = positionF2 + cellPosition;
-}
-
-ccl_device void voronoi_distance_to_edge_2d(float2 coord,
- float randomness,
- ccl_private float *outDistance)
-{
- float2 cellPosition = floor(coord);
- float2 localPosition = coord - cellPosition;
-
- float2 vectorToClosest = make_float2(0.0f, 0.0f);
- float minDistance = 8.0f;
- for (int j = -1; j <= 1; j++) {
- for (int i = -1; i <= 1; i++) {
- float2 cellOffset = make_float2(i, j);
- float2 vectorToPoint = cellOffset +
- hash_float2_to_float2(cellPosition + cellOffset) * randomness -
- localPosition;
- float distanceToPoint = dot(vectorToPoint, vectorToPoint);
- if (distanceToPoint < minDistance) {
- minDistance = distanceToPoint;
- vectorToClosest = vectorToPoint;
- }
- }
- }
-
- minDistance = 8.0f;
- for (int j = -1; j <= 1; j++) {
- for (int i = -1; i <= 1; i++) {
- float2 cellOffset = make_float2(i, j);
- float2 vectorToPoint = cellOffset +
- hash_float2_to_float2(cellPosition + cellOffset) * randomness -
- localPosition;
- float2 perpendicularToEdge = vectorToPoint - vectorToClosest;
- if (dot(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
- float distanceToEdge = dot((vectorToClosest + vectorToPoint) / 2.0f,
- normalize(perpendicularToEdge));
- minDistance = min(minDistance, distanceToEdge);
- }
- }
- }
- *outDistance = minDistance;
-}
-
-ccl_device void voronoi_n_sphere_radius_2d(float2 coord,
- float randomness,
- ccl_private float *outRadius)
-{
- float2 cellPosition = floor(coord);
- float2 localPosition = coord - cellPosition;
-
- float2 closestPoint = make_float2(0.0f, 0.0f);
- float2 closestPointOffset = make_float2(0.0f, 0.0f);
- float minDistance = 8.0f;
- for (int j = -1; j <= 1; j++) {
- for (int i = -1; i <= 1; i++) {
- float2 cellOffset = make_float2(i, j);
- float2 pointPosition = cellOffset +
- hash_float2_to_float2(cellPosition + cellOffset) * randomness;
- float distanceToPoint = distance(pointPosition, localPosition);
- if (distanceToPoint < minDistance) {
- minDistance = distanceToPoint;
- closestPoint = pointPosition;
- closestPointOffset = cellOffset;
- }
- }
- }
-
- minDistance = 8.0f;
- float2 closestPointToClosestPoint = make_float2(0.0f, 0.0f);
- for (int j = -1; j <= 1; j++) {
- for (int i = -1; i <= 1; i++) {
- if (i == 0 && j == 0) {
- continue;
- }
- float2 cellOffset = make_float2(i, j) + closestPointOffset;
- float2 pointPosition = cellOffset +
- hash_float2_to_float2(cellPosition + cellOffset) * randomness;
- float distanceToPoint = distance(closestPoint, pointPosition);
- if (distanceToPoint < minDistance) {
- minDistance = distanceToPoint;
- closestPointToClosestPoint = pointPosition;
- }
- }
- }
- *outRadius = distance(closestPointToClosestPoint, closestPoint) / 2.0f;
-}
-
-/* **** 3D Voronoi **** */
-
-ccl_device float voronoi_distance_3d(float3 a,
- float3 b,
- NodeVoronoiDistanceMetric metric,
- float exponent)
-{
- if (metric == NODE_VORONOI_EUCLIDEAN) {
- return distance(a, b);
- }
- else if (metric == NODE_VORONOI_MANHATTAN) {
- return fabsf(a.x - b.x) + fabsf(a.y - b.y) + fabsf(a.z - b.z);
- }
- else if (metric == NODE_VORONOI_CHEBYCHEV) {
- return max(fabsf(a.x - b.x), max(fabsf(a.y - b.y), fabsf(a.z - b.z)));
- }
- else if (metric == NODE_VORONOI_MINKOWSKI) {
- return powf(powf(fabsf(a.x - b.x), exponent) + powf(fabsf(a.y - b.y), exponent) +
- powf(fabsf(a.z - b.z), exponent),
- 1.0f / exponent);
- }
- else {
- return 0.0f;
- }
-}
-
-ccl_device void voronoi_f1_3d(float3 coord,
- float exponent,
- float randomness,
- NodeVoronoiDistanceMetric metric,
- ccl_private float *outDistance,
- ccl_private float3 *outColor,
- ccl_private float3 *outPosition)
-{
- float3 cellPosition = floor(coord);
- float3 localPosition = coord - cellPosition;
-
- float minDistance = 8.0f;
- float3 targetOffset = make_float3(0.0f, 0.0f, 0.0f);
- float3 targetPosition = make_float3(0.0f, 0.0f, 0.0f);
- for (int k = -1; k <= 1; k++) {
- for (int j = -1; j <= 1; j++) {
- for (int i = -1; i <= 1; i++) {
- float3 cellOffset = make_float3(i, j, k);
- float3 pointPosition = cellOffset +
- hash_float3_to_float3(cellPosition + cellOffset) * randomness;
- float distanceToPoint = voronoi_distance_3d(
- pointPosition, localPosition, metric, exponent);
- if (distanceToPoint < minDistance) {
- targetOffset = cellOffset;
- minDistance = distanceToPoint;
- targetPosition = pointPosition;
- }
- }
- }
- }
- *outDistance = minDistance;
- *outColor = hash_float3_to_float3(cellPosition + targetOffset);
- *outPosition = targetPosition + cellPosition;
-}
-
-ccl_device void voronoi_smooth_f1_3d(float3 coord,
- float smoothness,
- float exponent,
- float randomness,
- NodeVoronoiDistanceMetric metric,
- ccl_private float *outDistance,
- ccl_private float3 *outColor,
- ccl_private float3 *outPosition)
-{
- float3 cellPosition = floor(coord);
- float3 localPosition = coord - cellPosition;
-
- float smoothDistance = 8.0f;
- float3 smoothColor = make_float3(0.0f, 0.0f, 0.0f);
- float3 smoothPosition = make_float3(0.0f, 0.0f, 0.0f);
- for (int k = -2; k <= 2; k++) {
- for (int j = -2; j <= 2; j++) {
- for (int i = -2; i <= 2; i++) {
- float3 cellOffset = make_float3(i, j, k);
- float3 pointPosition = cellOffset +
- hash_float3_to_float3(cellPosition + cellOffset) * randomness;
- float distanceToPoint = voronoi_distance_3d(
- pointPosition, localPosition, metric, exponent);
- float h = smoothstep(
- 0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness);
- float correctionFactor = smoothness * h * (1.0f - h);
- smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
- correctionFactor /= 1.0f + 3.0f * smoothness;
- float3 cellColor = hash_float3_to_float3(cellPosition + cellOffset);
- smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
- smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
- }
- }
- }
- *outDistance = smoothDistance;
- *outColor = smoothColor;
- *outPosition = cellPosition + smoothPosition;
-}
-
-ccl_device void voronoi_f2_3d(float3 coord,
- float exponent,
- float randomness,
- NodeVoronoiDistanceMetric metric,
- ccl_private float *outDistance,
- ccl_private float3 *outColor,
- ccl_private float3 *outPosition)
-{
- float3 cellPosition = floor(coord);
- float3 localPosition = coord - cellPosition;
-
- float distanceF1 = 8.0f;
- float distanceF2 = 8.0f;
- float3 offsetF1 = make_float3(0.0f, 0.0f, 0.0f);
- float3 positionF1 = make_float3(0.0f, 0.0f, 0.0f);
- float3 offsetF2 = make_float3(0.0f, 0.0f, 0.0f);
- float3 positionF2 = make_float3(0.0f, 0.0f, 0.0f);
- for (int k = -1; k <= 1; k++) {
- for (int j = -1; j <= 1; j++) {
- for (int i = -1; i <= 1; i++) {
- float3 cellOffset = make_float3(i, j, k);
- float3 pointPosition = cellOffset +
- hash_float3_to_float3(cellPosition + cellOffset) * randomness;
- float distanceToPoint = voronoi_distance_3d(
- pointPosition, localPosition, metric, exponent);
- if (distanceToPoint < distanceF1) {
- distanceF2 = distanceF1;
- distanceF1 = distanceToPoint;
- offsetF2 = offsetF1;
- offsetF1 = cellOffset;
- positionF2 = positionF1;
- positionF1 = pointPosition;
- }
- else if (distanceToPoint < distanceF2) {
- distanceF2 = distanceToPoint;
- offsetF2 = cellOffset;
- positionF2 = pointPosition;
- }
- }
- }
- }
- *outDistance = distanceF2;
- *outColor = hash_float3_to_float3(cellPosition + offsetF2);
- *outPosition = positionF2 + cellPosition;
-}
-
-ccl_device void voronoi_distance_to_edge_3d(float3 coord,
- float randomness,
- ccl_private float *outDistance)
-{
- float3 cellPosition = floor(coord);
- float3 localPosition = coord - cellPosition;
-
- float3 vectorToClosest = make_float3(0.0f, 0.0f, 0.0f);
- float minDistance = 8.0f;
- for (int k = -1; k <= 1; k++) {
- for (int j = -1; j <= 1; j++) {
- for (int i = -1; i <= 1; i++) {
- float3 cellOffset = make_float3(i, j, k);
- float3 vectorToPoint = cellOffset +
- hash_float3_to_float3(cellPosition + cellOffset) * randomness -
- localPosition;
- float distanceToPoint = dot(vectorToPoint, vectorToPoint);
- if (distanceToPoint < minDistance) {
- minDistance = distanceToPoint;
- vectorToClosest = vectorToPoint;
- }
- }
- }
- }
-
- minDistance = 8.0f;
- for (int k = -1; k <= 1; k++) {
- for (int j = -1; j <= 1; j++) {
- for (int i = -1; i <= 1; i++) {
- float3 cellOffset = make_float3(i, j, k);
- float3 vectorToPoint = cellOffset +
- hash_float3_to_float3(cellPosition + cellOffset) * randomness -
- localPosition;
- float3 perpendicularToEdge = vectorToPoint - vectorToClosest;
- if (dot(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
- float distanceToEdge = dot((vectorToClosest + vectorToPoint) / 2.0f,
- normalize(perpendicularToEdge));
- minDistance = min(minDistance, distanceToEdge);
- }
- }
- }
- }
- *outDistance = minDistance;
-}
-
-ccl_device void voronoi_n_sphere_radius_3d(float3 coord,
- float randomness,
- ccl_private float *outRadius)
-{
- float3 cellPosition = floor(coord);
- float3 localPosition = coord - cellPosition;
-
- float3 closestPoint = make_float3(0.0f, 0.0f, 0.0f);
- float3 closestPointOffset = make_float3(0.0f, 0.0f, 0.0f);
- float minDistance = 8.0f;
- for (int k = -1; k <= 1; k++) {
- for (int j = -1; j <= 1; j++) {
- for (int i = -1; i <= 1; i++) {
- float3 cellOffset = make_float3(i, j, k);
- float3 pointPosition = cellOffset +
- hash_float3_to_float3(cellPosition + cellOffset) * randomness;
- float distanceToPoint = distance(pointPosition, localPosition);
- if (distanceToPoint < minDistance) {
- minDistance = distanceToPoint;
- closestPoint = pointPosition;
- closestPointOffset = cellOffset;
- }
- }
- }
- }
-
- minDistance = 8.0f;
- float3 closestPointToClosestPoint = make_float3(0.0f, 0.0f, 0.0f);
- for (int k = -1; k <= 1; k++) {
- for (int j = -1; j <= 1; j++) {
- for (int i = -1; i <= 1; i++) {
- if (i == 0 && j == 0 && k == 0) {
- continue;
- }
- float3 cellOffset = make_float3(i, j, k) + closestPointOffset;
- float3 pointPosition = cellOffset +
- hash_float3_to_float3(cellPosition + cellOffset) * randomness;
- float distanceToPoint = distance(closestPoint, pointPosition);
- if (distanceToPoint < minDistance) {
- minDistance = distanceToPoint;
- closestPointToClosestPoint = pointPosition;
- }
- }
- }
- }
- *outRadius = distance(closestPointToClosestPoint, closestPoint) / 2.0f;
-}
-
-/* **** 4D Voronoi **** */
-
-ccl_device float voronoi_distance_4d(float4 a,
- float4 b,
- NodeVoronoiDistanceMetric metric,
- float exponent)
-{
- if (metric == NODE_VORONOI_EUCLIDEAN) {
- return distance(a, b);
- }
- else if (metric == NODE_VORONOI_MANHATTAN) {
- return fabsf(a.x - b.x) + fabsf(a.y - b.y) + fabsf(a.z - b.z) + fabsf(a.w - b.w);
- }
- else if (metric == NODE_VORONOI_CHEBYCHEV) {
- return max(fabsf(a.x - b.x), max(fabsf(a.y - b.y), max(fabsf(a.z - b.z), fabsf(a.w - b.w))));
- }
- else if (metric == NODE_VORONOI_MINKOWSKI) {
- return powf(powf(fabsf(a.x - b.x), exponent) + powf(fabsf(a.y - b.y), exponent) +
- powf(fabsf(a.z - b.z), exponent) + powf(fabsf(a.w - b.w), exponent),
- 1.0f / exponent);
- }
- else {
- return 0.0f;
- }
-}
-
-ccl_device void voronoi_f1_4d(float4 coord,
- float exponent,
- float randomness,
- NodeVoronoiDistanceMetric metric,
- ccl_private float *outDistance,
- ccl_private float3 *outColor,
- ccl_private float4 *outPosition)
-{
- float4 cellPosition = floor(coord);
- float4 localPosition = coord - cellPosition;
-
- float minDistance = 8.0f;
- float4 targetOffset = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- float4 targetPosition = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- for (int u = -1; u <= 1; u++) {
- for (int k = -1; k <= 1; k++) {
- ccl_loop_no_unroll for (int j = -1; j <= 1; j++)
- {
- for (int i = -1; i <= 1; i++) {
- float4 cellOffset = make_float4(i, j, k, u);
- float4 pointPosition = cellOffset +
- hash_float4_to_float4(cellPosition + cellOffset) * randomness;
- float distanceToPoint = voronoi_distance_4d(
- pointPosition, localPosition, metric, exponent);
- if (distanceToPoint < minDistance) {
- targetOffset = cellOffset;
- minDistance = distanceToPoint;
- targetPosition = pointPosition;
- }
- }
- }
- }
- }
- *outDistance = minDistance;
- *outColor = hash_float4_to_float3(cellPosition + targetOffset);
- *outPosition = targetPosition + cellPosition;
-}
-
-ccl_device void voronoi_smooth_f1_4d(float4 coord,
- float smoothness,
- float exponent,
- float randomness,
- NodeVoronoiDistanceMetric metric,
- ccl_private float *outDistance,
- ccl_private float3 *outColor,
- ccl_private float4 *outPosition)
-{
- float4 cellPosition = floor(coord);
- float4 localPosition = coord - cellPosition;
-
- float smoothDistance = 8.0f;
- float3 smoothColor = make_float3(0.0f, 0.0f, 0.0f);
- float4 smoothPosition = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- for (int u = -2; u <= 2; u++) {
- for (int k = -2; k <= 2; k++) {
- ccl_loop_no_unroll for (int j = -2; j <= 2; j++)
- {
- for (int i = -2; i <= 2; i++) {
- float4 cellOffset = make_float4(i, j, k, u);
- float4 pointPosition = cellOffset +
- hash_float4_to_float4(cellPosition + cellOffset) * randomness;
- float distanceToPoint = voronoi_distance_4d(
- pointPosition, localPosition, metric, exponent);
- float h = smoothstep(
- 0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness);
- float correctionFactor = smoothness * h * (1.0f - h);
- smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
- correctionFactor /= 1.0f + 3.0f * smoothness;
- float3 cellColor = hash_float4_to_float3(cellPosition + cellOffset);
- smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
- smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
- }
- }
- }
- }
- *outDistance = smoothDistance;
- *outColor = smoothColor;
- *outPosition = cellPosition + smoothPosition;
-}
-
-ccl_device void voronoi_f2_4d(float4 coord,
- float exponent,
- float randomness,
- NodeVoronoiDistanceMetric metric,
- ccl_private float *outDistance,
- ccl_private float3 *outColor,
- ccl_private float4 *outPosition)
-{
- float4 cellPosition = floor(coord);
- float4 localPosition = coord - cellPosition;
-
- float distanceF1 = 8.0f;
- float distanceF2 = 8.0f;
- float4 offsetF1 = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- float4 positionF1 = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- float4 offsetF2 = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- float4 positionF2 = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- for (int u = -1; u <= 1; u++) {
- for (int k = -1; k <= 1; k++) {
- ccl_loop_no_unroll for (int j = -1; j <= 1; j++)
- {
- for (int i = -1; i <= 1; i++) {
- float4 cellOffset = make_float4(i, j, k, u);
- float4 pointPosition = cellOffset +
- hash_float4_to_float4(cellPosition + cellOffset) * randomness;
- float distanceToPoint = voronoi_distance_4d(
- pointPosition, localPosition, metric, exponent);
- if (distanceToPoint < distanceF1) {
- distanceF2 = distanceF1;
- distanceF1 = distanceToPoint;
- offsetF2 = offsetF1;
- offsetF1 = cellOffset;
- positionF2 = positionF1;
- positionF1 = pointPosition;
- }
- else if (distanceToPoint < distanceF2) {
- distanceF2 = distanceToPoint;
- offsetF2 = cellOffset;
- positionF2 = pointPosition;
- }
- }
- }
- }
- }
- *outDistance = distanceF2;
- *outColor = hash_float4_to_float3(cellPosition + offsetF2);
- *outPosition = positionF2 + cellPosition;
-}
-
-ccl_device void voronoi_distance_to_edge_4d(float4 coord,
- float randomness,
- ccl_private float *outDistance)
-{
- float4 cellPosition = floor(coord);
- float4 localPosition = coord - cellPosition;
-
- float4 vectorToClosest = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- float minDistance = 8.0f;
- for (int u = -1; u <= 1; u++) {
- for (int k = -1; k <= 1; k++) {
- ccl_loop_no_unroll for (int j = -1; j <= 1; j++)
- {
- for (int i = -1; i <= 1; i++) {
- float4 cellOffset = make_float4(i, j, k, u);
- float4 vectorToPoint = cellOffset +
- hash_float4_to_float4(cellPosition + cellOffset) * randomness -
- localPosition;
- float distanceToPoint = dot(vectorToPoint, vectorToPoint);
- if (distanceToPoint < minDistance) {
- minDistance = distanceToPoint;
- vectorToClosest = vectorToPoint;
- }
- }
- }
- }
- }
-
- minDistance = 8.0f;
- for (int u = -1; u <= 1; u++) {
- for (int k = -1; k <= 1; k++) {
- ccl_loop_no_unroll for (int j = -1; j <= 1; j++)
- {
- for (int i = -1; i <= 1; i++) {
- float4 cellOffset = make_float4(i, j, k, u);
- float4 vectorToPoint = cellOffset +
- hash_float4_to_float4(cellPosition + cellOffset) * randomness -
- localPosition;
- float4 perpendicularToEdge = vectorToPoint - vectorToClosest;
- if (dot(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
- float distanceToEdge = dot((vectorToClosest + vectorToPoint) / 2.0f,
- normalize(perpendicularToEdge));
- minDistance = min(minDistance, distanceToEdge);
- }
- }
- }
- }
- }
- *outDistance = minDistance;
-}
-
-ccl_device void voronoi_n_sphere_radius_4d(float4 coord,
- float randomness,
- ccl_private float *outRadius)
-{
- float4 cellPosition = floor(coord);
- float4 localPosition = coord - cellPosition;
-
- float4 closestPoint = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- float4 closestPointOffset = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- float minDistance = 8.0f;
- for (int u = -1; u <= 1; u++) {
- for (int k = -1; k <= 1; k++) {
- ccl_loop_no_unroll for (int j = -1; j <= 1; j++)
- {
- for (int i = -1; i <= 1; i++) {
- float4 cellOffset = make_float4(i, j, k, u);
- float4 pointPosition = cellOffset +
- hash_float4_to_float4(cellPosition + cellOffset) * randomness;
- float distanceToPoint = distance(pointPosition, localPosition);
- if (distanceToPoint < minDistance) {
- minDistance = distanceToPoint;
- closestPoint = pointPosition;
- closestPointOffset = cellOffset;
- }
- }
- }
- }
- }
-
- minDistance = 8.0f;
- float4 closestPointToClosestPoint = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
- for (int u = -1; u <= 1; u++) {
- for (int k = -1; k <= 1; k++) {
- ccl_loop_no_unroll for (int j = -1; j <= 1; j++)
- {
- for (int i = -1; i <= 1; i++) {
- if (i == 0 && j == 0 && k == 0 && u == 0) {
- continue;
- }
- float4 cellOffset = make_float4(i, j, k, u) + closestPointOffset;
- float4 pointPosition = cellOffset +
- hash_float4_to_float4(cellPosition + cellOffset) * randomness;
- float distanceToPoint = distance(closestPoint, pointPosition);
- if (distanceToPoint < minDistance) {
- minDistance = distanceToPoint;
- closestPointToClosestPoint = pointPosition;
- }
- }
- }
- }
- }
- *outRadius = distance(closestPointToClosestPoint, closestPoint) / 2.0f;
-}
-
-template<uint node_feature_mask>
-ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg,
- ccl_private ShaderData *sd,
- ccl_private float *stack,
- uint dimensions,
- uint feature,
- uint metric,
- int offset)
-{
- uint4 stack_offsets = read_node(kg, &offset);
- uint4 defaults = read_node(kg, &offset);
-
- uint coord_stack_offset, w_stack_offset, scale_stack_offset, smoothness_stack_offset;
- uint exponent_stack_offset, randomness_stack_offset, distance_out_stack_offset,
- color_out_stack_offset;
- uint position_out_stack_offset, w_out_stack_offset, radius_out_stack_offset;
-
- svm_unpack_node_uchar4(stack_offsets.x,
- &coord_stack_offset,
- &w_stack_offset,
- &scale_stack_offset,
- &smoothness_stack_offset);
- svm_unpack_node_uchar4(stack_offsets.y,
- &exponent_stack_offset,
- &randomness_stack_offset,
- &distance_out_stack_offset,
- &color_out_stack_offset);
- svm_unpack_node_uchar3(
- stack_offsets.z, &position_out_stack_offset, &w_out_stack_offset, &radius_out_stack_offset);
-
- float3 coord = stack_load_float3(stack, coord_stack_offset);
- float w = stack_load_float_default(stack, w_stack_offset, stack_offsets.w);
- float scale = stack_load_float_default(stack, scale_stack_offset, defaults.x);
- float smoothness = stack_load_float_default(stack, smoothness_stack_offset, defaults.y);
- float exponent = stack_load_float_default(stack, exponent_stack_offset, defaults.z);
- float randomness = stack_load_float_default(stack, randomness_stack_offset, defaults.w);
-
- NodeVoronoiFeature voronoi_feature = (NodeVoronoiFeature)feature;
- NodeVoronoiDistanceMetric voronoi_metric = (NodeVoronoiDistanceMetric)metric;
-
- float distance_out = 0.0f, w_out = 0.0f, radius_out = 0.0f;
- float3 color_out = make_float3(0.0f, 0.0f, 0.0f);
- float3 position_out = make_float3(0.0f, 0.0f, 0.0f);
-
- randomness = clamp(randomness, 0.0f, 1.0f);
- smoothness = clamp(smoothness / 2.0f, 0.0f, 0.5f);
-
- w *= scale;
- coord *= scale;
-
- switch (dimensions) {
- case 1: {
- switch (voronoi_feature) {
- case NODE_VORONOI_F1:
- voronoi_f1_1d(
- w, exponent, randomness, voronoi_metric, &distance_out, &color_out, &w_out);
- break;
- case NODE_VORONOI_SMOOTH_F1:
- voronoi_smooth_f1_1d(w,
- smoothness,
- exponent,
- randomness,
- voronoi_metric,
- &distance_out,
- &color_out,
- &w_out);
- break;
- case NODE_VORONOI_F2:
- voronoi_f2_1d(
- w, exponent, randomness, voronoi_metric, &distance_out, &color_out, &w_out);
- break;
- case NODE_VORONOI_DISTANCE_TO_EDGE:
- voronoi_distance_to_edge_1d(w, randomness, &distance_out);
- break;
- case NODE_VORONOI_N_SPHERE_RADIUS:
- voronoi_n_sphere_radius_1d(w, randomness, &radius_out);
- break;
- default:
- kernel_assert(0);
- }
- w_out = safe_divide(w_out, scale);
- break;
- }
- case 2: {
- float2 coord_2d = make_float2(coord.x, coord.y);
- float2 position_out_2d = zero_float2();
- switch (voronoi_feature) {
- case NODE_VORONOI_F1:
- voronoi_f1_2d(coord_2d,
- exponent,
- randomness,
- voronoi_metric,
- &distance_out,
- &color_out,
- &position_out_2d);
- break;
- case NODE_VORONOI_SMOOTH_F1:
- IF_KERNEL_NODES_FEATURE(VORONOI_EXTRA)
- {
- voronoi_smooth_f1_2d(coord_2d,
- smoothness,
- exponent,
- randomness,
- voronoi_metric,
- &distance_out,
- &color_out,
- &position_out_2d);
- }
- break;
- case NODE_VORONOI_F2:
- voronoi_f2_2d(coord_2d,
- exponent,
- randomness,
- voronoi_metric,
- &distance_out,
- &color_out,
- &position_out_2d);
- break;
- case NODE_VORONOI_DISTANCE_TO_EDGE:
- voronoi_distance_to_edge_2d(coord_2d, randomness, &distance_out);
- break;
- case NODE_VORONOI_N_SPHERE_RADIUS:
- voronoi_n_sphere_radius_2d(coord_2d, randomness, &radius_out);
- break;
- default:
- kernel_assert(0);
- }
- position_out_2d = safe_divide_float2_float(position_out_2d, scale);
- position_out = make_float3(position_out_2d.x, position_out_2d.y, 0.0f);
- break;
- }
- case 3: {
- switch (voronoi_feature) {
- case NODE_VORONOI_F1:
- voronoi_f1_3d(coord,
- exponent,
- randomness,
- voronoi_metric,
- &distance_out,
- &color_out,
- &position_out);
- break;
- case NODE_VORONOI_SMOOTH_F1:
- IF_KERNEL_NODES_FEATURE(VORONOI_EXTRA)
- {
- voronoi_smooth_f1_3d(coord,
- smoothness,
- exponent,
- randomness,
- voronoi_metric,
- &distance_out,
- &color_out,
- &position_out);
- }
- break;
- case NODE_VORONOI_F2:
- voronoi_f2_3d(coord,
- exponent,
- randomness,
- voronoi_metric,
- &distance_out,
- &color_out,
- &position_out);
- break;
- case NODE_VORONOI_DISTANCE_TO_EDGE:
- voronoi_distance_to_edge_3d(coord, randomness, &distance_out);
- break;
- case NODE_VORONOI_N_SPHERE_RADIUS:
- voronoi_n_sphere_radius_3d(coord, randomness, &radius_out);
- break;
- default:
- kernel_assert(0);
- }
- position_out = safe_divide_float3_float(position_out, scale);
- break;
- }
-
- case 4: {
- IF_KERNEL_NODES_FEATURE(VORONOI_EXTRA)
- {
- float4 coord_4d = make_float4(coord.x, coord.y, coord.z, w);
- float4 position_out_4d;
- switch (voronoi_feature) {
- case NODE_VORONOI_F1:
- voronoi_f1_4d(coord_4d,
- exponent,
- randomness,
- voronoi_metric,
- &distance_out,
- &color_out,
- &position_out_4d);
- break;
- case NODE_VORONOI_SMOOTH_F1:
- voronoi_smooth_f1_4d(coord_4d,
- smoothness,
- exponent,
- randomness,
- voronoi_metric,
- &distance_out,
- &color_out,
- &position_out_4d);
- break;
- case NODE_VORONOI_F2:
- voronoi_f2_4d(coord_4d,
- exponent,
- randomness,
- voronoi_metric,
- &distance_out,
- &color_out,
- &position_out_4d);
- break;
- case NODE_VORONOI_DISTANCE_TO_EDGE:
- voronoi_distance_to_edge_4d(coord_4d, randomness, &distance_out);
- break;
- case NODE_VORONOI_N_SPHERE_RADIUS:
- voronoi_n_sphere_radius_4d(coord_4d, randomness, &radius_out);
- break;
- default:
- kernel_assert(0);
- }
- position_out_4d = safe_divide_float4_float(position_out_4d, scale);
- position_out = make_float3(position_out_4d.x, position_out_4d.y, position_out_4d.z);
- w_out = position_out_4d.w;
- }
- break;
- }
- default:
- kernel_assert(0);
- }
-
- if (stack_valid(distance_out_stack_offset))
- stack_store_float(stack, distance_out_stack_offset, distance_out);
- if (stack_valid(color_out_stack_offset))
- stack_store_float3(stack, color_out_stack_offset, color_out);
- if (stack_valid(position_out_stack_offset))
- stack_store_float3(stack, position_out_stack_offset, position_out);
- if (stack_valid(w_out_stack_offset))
- stack_store_float(stack, w_out_stack_offset, w_out);
- if (stack_valid(radius_out_stack_offset))
- stack_store_float(stack, radius_out_stack_offset, radius_out);
- return offset;
-}
-
-CCL_NAMESPACE_END