[comp.graphics] Texturing Functions

jonb@vector.Dallas.TX.US (Jon Buller) (02/17/90)

Last April, when there were many raging requests for the RenderMan
Noise function.  I posted the one that I got from Gary Herron (one of
my Profs at the time).  After I had fixed the hashing it used, so that
there would not be rows upon rows of blobs of the same shape, I posted
it to comp.graphics.  I didn't have it documented in the best form,
since I posted it quickly to hopefully stem the tide of requests.
There was a bug in it (that I knew about, but forgot to tell everyone
about, and it needed several followups to explain how it worked and
how to initialize it, etc.)

Well, I would like to get some various texture routines from the net
at large, just to see what others are doing, and for a bit of fun...
Of course, I don't just want take things without some sort of return,
so to get your collections of 'new & unusual(tm)' textures started,
I have included one of my favorites, The Planet Texture.  It does not
need watering, food, or specular reflection, just take a dot-product
of the surface normal and the light source direction to add shadows,
and have fun...  It is written in Pascal.  (No, I do not yet have a
C compiler for my Mac, but that WILL change in a couple of months.)  So
you must translate it to your language of choice, but I belive it is
a bit better documented than the first.

Anyway, I would like to see your favorite textures (call or write
today!) and if there is a tremendous response, I may (or may not)
compile them into a list, summarize, and post.  Two textures I would
REALLY like to see are 1) a good Marble texture (like the one in
[Perlin85], (guess what this paper is.), and 2) something like the
Wood_Burl texture I saw applied to your favorite teapot and mine in
a book by (or maybe edited by) Andrew Glassner.  I don't remember the
title (Computer Graphics for Artists, maybe?)

If you dont have a Noise function of your own, mine was translated
and should be around... or you can link it to whatever function
you like if it returns a Real (er.. float) 8-).

Get Noise From UUNET (Is it still there?  I can't find out anymore.)
or a friend.  Change it to initialize the random array pts[] to fill
with  (-1.0 to 1.0) instead of (0.0 to 1.0) like it says.  My Thanks
to Bill Dirks for doing that translation, BTW.  (You may also notice
that I am no longer a student at Colorado State University...)

I included my Turb function with this, because last time I checked
UUNET (April '89) the noise file there said that Bill had not
translated the Turb function yet, and in the interest of completeness
(and reducing mail volume 8-), it is here, but you must translate it
yourself...

[Perlin85] An Image Systhesizer, Ken Perlin,
     Proceedings of SIGGRAPH '85

If you haven't guessed (after reading the code, of course 8-):
Add([x1,y1,z1], [x2,y2,z2]) = [x1+x2, y1+y2, z1+z2]
Subtract([x1,y1,z1], [x2,y2,z2]) = [x1-x2, y1-y2, z1-z2]
Scale(s, [x,y,z]) = [s*x, s*y, s*z]
Color and Vector coerce the given type of a 3-vector into the
      other kind of 3-vector

(* ------- cut here ------- Planet&Turb.p ------- cur here ------- *)

function Turb (Size: Integer; ScaleFactor: Real; Loc: Vector): Real;
(* Size = Size of largest feature: Smallest feature size = 1,
   ScaleFactor is related to the fractal dimension of the turbulence,
   Loc = point of turbulence to compute *)
var CurScale, Result: Real;
	Cur: Integer;
begin
   Result := Noise(Loc);
   CurScale := 1.0;

   Cur := 1;
   while Cur < Size do Begin
      Cur := BSL(Cur, 1);
           (* Shift Left is MUCH quicker than a multiply *)
      CurScale := CurScale * ScaleFactor;
      Loc := Scale(2.0, Loc);
      Result := Result + Noise(Loc) * CurScale;
   end;
   Turb := Result;
end;

(* This was designed to work with a unit sphere.  I think it works well, you
   may (should) form your own opinions... *)
Function Planet (Loc: Vector): Color;
Const Land  := [0.28125, 0.1875, 0.09375];
               (* A reasonably nice brown color *)
      Sea   := [0.0    , 0.0   , 1.0];
               (* Oceans are usually blue *)
      Cloud := [1.0    , 1.0   , 1.0];
               (* And Clouds are white *)
      (* OK, this part isn't Pascal, (I wish it was though...)
         but it beats the way it's done in the real code... *)
Var C: Color;
    Amt: Real;
Begin
   If Turb(430, 0.7, Loc) > 0.25
        (* The sphere I use is 430 pixels across *)
   Then C := Land
   Else C := Sea;

   Amt := Turb(18, 0.6, Scale(24.0, Loc));
           (* Clouds I like are 18 pixels across *)
   If Amt > -0.25 Then
   C := Color(Add(Vector(C), Scale(Amt + 0.25,
          Subtract(Vector(Cloud), Vector(C)))));
   
   (* I Wish I could do it like this...
          C := C + (Amt + 0.25) * (Cloud - C)    *)
End;

-- 
----------------------------------------------------------------------
Jon Buller       jonb@vector.dallas.tx.us       ..!texbell!vector!jonb
FROM Fortune IMPORT Quote;             FROM Lawyers IMPORT Disclaimer;

bernie@julimar2.ecr.mu.oz (Bernard Kirby) (02/23/90)

	We can do all the "standard" textures (marble, wood etc),
	we can even do what looks like granite, but I was wondering
	if anyone had a physically based algorithm for the synthesis
	of granite. Any pointers would be welcome.

	Bernie (bernie@munnari.OZ.AU, bernie@murtoa.cs.mu.OZ.AU)