123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- /*
- * 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.
- */
- #include "stdosl.h"
- #include "node_texture.h"
- void voronoi_m(point p, string metric, float e, float da[4], point pa[4])
- {
- /* Compute the distance to and the position of the four closest neighbors to p.
- *
- * The neighbors are randomly placed, 1 each in a 3x3x3 grid (Worley pattern).
- * The distances and points are returned in ascending order, i.e. da[0] and pa[0] will
- * contain the distance to the closest point and its coordinates respectively.
- */
- int xx, yy, zz, xi, yi, zi;
- xi = (int)floor(p[0]);
- yi = (int)floor(p[1]);
- zi = (int)floor(p[2]);
- da[0] = 1e10;
- da[1] = 1e10;
- da[2] = 1e10;
- da[3] = 1e10;
- for (xx = xi - 1; xx <= xi + 1; xx++) {
- for (yy = yi - 1; yy <= yi + 1; yy++) {
- for (zz = zi - 1; zz <= zi + 1; zz++) {
- point ip = point(xx, yy, zz);
- point vp = (point)cellnoise_color(ip);
- point pd = p - (vp + ip);
- float d = 0.0;
- if (metric == "distance") {
- d = dot(pd, pd);
- }
- else if (metric == "manhattan") {
- d = fabs(pd[0]) + fabs(pd[1]) + fabs(pd[2]);
- }
- else if (metric == "chebychev") {
- d = max(fabs(pd[0]), max(fabs(pd[1]), fabs(pd[2])));
- }
- else if (metric == "minkowski") {
- d = pow(pow(fabs(pd[0]), e) + pow(fabs(pd[1]), e) + pow(fabs(pd[2]), e), 1.0 / e);
- }
- vp += point(xx, yy, zz);
- if (d < da[0]) {
- da[3] = da[2];
- da[2] = da[1];
- da[1] = da[0];
- da[0] = d;
- pa[3] = pa[2];
- pa[2] = pa[1];
- pa[1] = pa[0];
- pa[0] = vp;
- }
- else if (d < da[1]) {
- da[3] = da[2];
- da[2] = da[1];
- da[1] = d;
- pa[3] = pa[2];
- pa[2] = pa[1];
- pa[1] = vp;
- }
- else if (d < da[2]) {
- da[3] = da[2];
- da[2] = d;
- pa[3] = pa[2];
- pa[2] = vp;
- }
- else if (d < da[3]) {
- da[3] = d;
- pa[3] = vp;
- }
- }
- }
- }
- }
- /* Voronoi */
- shader node_voronoi_texture(
- int use_mapping = 0,
- matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- string coloring = "intensity",
- string metric = "distance",
- string feature = "F1",
- float Exponent = 1.0,
- float Scale = 5.0,
- point Vector = P,
- output float Fac = 0.0,
- output color Color = 0.0)
- {
- point p = Vector;
- if (use_mapping)
- p = transform(mapping, p);
- /* compute distance and point coordinate of 4 nearest neighbours */
- float da[4];
- point pa[4];
- /* compute distance and point coordinate of 4 nearest neighbours */
- voronoi_m(p * Scale, metric, Exponent, da, pa);
- if (coloring == "intensity") {
- /* Intensity output */
- if (feature == "F1") {
- Fac = fabs(da[0]);
- }
- else if (feature == "F2") {
- Fac = fabs(da[1]);
- }
- else if (feature == "F3") {
- Fac = fabs(da[2]);
- }
- else if (feature == "F4") {
- Fac = fabs(da[3]);
- }
- else if (feature == "F2F1") {
- Fac = fabs(da[1] - da[0]);
- }
- Color = color(Fac);
- }
- else {
- /* Color output */
- if (feature == "F1") {
- Color = pa[0];
- }
- else if (feature == "F2") {
- Color = pa[1];
- }
- else if (feature == "F3") {
- Color = pa[2];
- }
- else if (feature == "F4") {
- Color = pa[3];
- }
- else if (feature == "F2F1") {
- Color = fabs(pa[1] - pa[0]);
- }
- Color = cellnoise_color(Color);
- Fac = (Color[0] + Color[1] + Color[2]) * (1.0 / 3.0);
- }
- }
|