--- ray/src/rt/noise3.c 2003/02/22 02:07:29 2.6
+++ ray/src/rt/noise3.c 2013/10/08 18:59:44 2.13
@@ -1,112 +1,40 @@
#ifndef lint
-static const char RCSid[] = "$Id: noise3.c,v 2.6 2003/02/22 02:07:29 greg Exp $";
+static const char RCSid[] = "$Id: noise3.c,v 2.13 2013/10/08 18:59:44 greg Exp $";
#endif
/*
* noise3.c - noise functions for random textures.
*
- * Credit for the smooth algorithm goes to Ken Perlin.
- * (ref. SIGGRAPH Vol 19, No 3, pp 287-96)
+ * Credit for the smooth algorithm goes to Ken Perlin, and code
+ * translation/implementation to Rahul Narain.
+ * (ref. Improving Noise, Computer Graphics; Vol. 35 No. 3., 2002)
*/
-/* ====================================================================
- * The Radiance Software License, Version 1.0
- *
- * Copyright (c) 1990 - 2002 The Regents of the University of California,
- * through Lawrence Berkeley National Laboratory. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes Radiance software
- * (http://radsite.lbl.gov/)
- * developed by the Lawrence Berkeley National Laboratory
- * (http://www.lbl.gov/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Radiance," "Lawrence Berkeley National Laboratory"
- * and "The Regents of the University of California" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact radiance@radsite.lbl.gov.
- *
- * 5. Products derived from this software may not be called "Radiance",
- * nor may "Radiance" appear in their name, without prior written
- * permission of Lawrence Berkeley National Laboratory.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of Lawrence Berkeley National Laboratory. For more
- * information on Lawrence Berkeley National Laboratory, please see
- * .
- */
+#include "copyright.h"
-#include
+#include "ray.h"
+#include "func.h"
-#define A 0
-#define B 1
-#define C 2
-#define D 3
-
-#define rand3a(x,y,z) frand(67*(x)+59*(y)+71*(z))
-#define rand3b(x,y,z) frand(73*(x)+79*(y)+83*(z))
-#define rand3c(x,y,z) frand(89*(x)+97*(y)+101*(z))
-#define rand3d(x,y,z) frand(103*(x)+107*(y)+109*(z))
-
-#define hpoly1(t) ((2.0*t-3.0)*t*t+1.0)
-#define hpoly2(t) (-2.0*t+3.0)*t*t
-#define hpoly3(t) ((t-2.0)*t+1.0)*t
-#define hpoly4(t) (t-1.0)*t*t
-
-#define hermite(p0,p1,r0,r1,t) ( p0*hpoly1(t) + \
- p1*hpoly2(t) + \
- r0*hpoly3(t) + \
- r1*hpoly4(t) )
-
static char noise_name[4][8] = {"noise3x", "noise3y", "noise3z", "noise3"};
static char fnoise_name[] = "fnoise3";
-static char hermite_name[] = "hermite";
-double *noise3(), fnoise3(), argument(), frand();
-static interpolate();
+#define EPSILON .0005 /* error allowed in fractal */
-static long xlim[3][2];
-static double xarg[3];
-
-#define EPSILON .001 /* error allowed in fractal */
-
#define frand3(x,y,z) frand(17*(x)+23*(y)+29*(z))
+static double l_noise3(char *nam);
+static double noise3(double xnew[3], int i);
+static double noise3partial(double f3, double x[3], int i);
+static double perlin_noise (double x, double y, double z);
+static double frand(long s);
+static double fnoise3(double x[3]);
+
static double
-l_noise3(nam) /* compute a noise function */
-register char *nam;
+l_noise3( /* compute a noise function */
+ char *nam
+)
{
- register int i;
+ int i;
double x[3];
/* get point */
x[0] = argument(1);
@@ -118,29 +46,19 @@ register char *nam;
i = 4;
while (i--)
if (nam == noise_name[i])
- return(noise3(x)[i]);
+ return(noise3(x,i));
eputs(nam);
eputs(": called l_noise3!\n");
quit(1);
+ return 1; /* pro forma return */
}
-double
-l_hermite() /* library call for hermite interpolation */
+void
+setnoisefuncs(void) /* add noise functions to library */
{
- double t;
-
- t = argument(5);
- return( hermite(argument(1), argument(2),
- argument(3), argument(4), t) );
-}
+ int i;
-
-setnoisefuncs() /* add noise functions to library */
-{
- register int i;
-
- funset(hermite_name, 5, ':', l_hermite);
funset(fnoise_name, 3, ':', l_noise3);
i = 4;
while (i--)
@@ -148,76 +66,31 @@ setnoisefuncs() /* add noise functions to library */
}
-double *
-noise3(xnew) /* compute the noise function */
-register double xnew[3];
+static double
+frand( /* get random number from seed */
+ long s
+)
{
- static double x[3] = {-100000.0, -100000.0, -100000.0};
- static double f[4];
-
- if (x[0]==xnew[0] && x[1]==xnew[1] && x[2]==xnew[2])
- return(f);
- x[0] = xnew[0]; x[1] = xnew[1]; x[2] = xnew[2];
- xlim[0][0] = floor(x[0]); xlim[0][1] = xlim[0][0] + 1;
- xlim[1][0] = floor(x[1]); xlim[1][1] = xlim[1][0] + 1;
- xlim[2][0] = floor(x[2]); xlim[2][1] = xlim[2][0] + 1;
- xarg[0] = x[0] - xlim[0][0];
- xarg[1] = x[1] - xlim[1][0];
- xarg[2] = x[2] - xlim[2][0];
- interpolate(f, 0, 3);
- return(f);
-}
-
-
-static
-interpolate(f, i, n)
-double f[4];
-register int i, n;
-{
- double f0[4], f1[4], hp1, hp2;
-
- if (n == 0) {
- f[A] = rand3a(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
- f[B] = rand3b(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
- f[C] = rand3c(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
- f[D] = rand3d(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
- } else {
- n--;
- interpolate(f0, i, n);
- interpolate(f1, i | 1<>i & 1)) {
+ f[i] = noise3partial(f[3], x, i);
+ gotV |= 1<