1 /*
2 * cloud.c
3 *
4 * Copyright (C) 1989, 1991, Craig E. Kolb
5 * All rights reserved.
6 *
7 * This software may be freely copied, modified, and redistributed
8 * provided that this copyright notice is preserved on all copies.
9 *
10 * You may not distribute this software, in whole or in part, as part of
11 * any commercial product without the express consent of the authors.
12 *
13 * There is no warranty or other guarantee of fitness of this software
14 * for any purpose. It is provided solely "as is".
15 *
16 * $Id: cloud.c,v 4.0 91/07/17 14:41:57 kolb Exp Locker: kolb $
17 *
18 * $Log: cloud.c,v $
19 * Revision 4.0 91/07/17 14:41:57 kolb
20 * Initial version.
21 *
22 */
23 #include "texture.h"
24 #include "cloud.h"
25
26 /*
27 * Gardner-style textured ellipsoid. Designed to be used on unit spheres
28 * centered at the origin. (Of course, the spheres may be transformed
29 * into ellipsoids, translated, etc.)
30 */
31 CloudText *
CloudTextCreate(scale,h,lambda,octaves,cthresh,lthresh,transcale)32 CloudTextCreate(scale, h, lambda, octaves, cthresh, lthresh, transcale)
33 Float scale, h, lambda, cthresh, lthresh, transcale;
34 int octaves;
35 {
36 CloudText *cloud;
37
38 cloud = (CloudText *)Malloc(sizeof(CloudText));
39 cloud->beta = 1. + 2 * h;
40 cloud->omega = pow(lambda, -0.5 * cloud->beta);
41 cloud->lambda = lambda;
42 cloud->scale = scale;
43 cloud->cthresh = cthresh;
44 cloud->range = lthresh - cthresh;
45 cloud->transcale = transcale;
46 cloud->maxval = 1. / (1. - cloud->beta);
47 cloud->octaves = octaves;
48 return cloud;
49 }
50
51 void
CloudTextApply(cloud,prim,ray,pos,norm,gnorm,surf)52 CloudTextApply(cloud, prim, ray, pos, norm, gnorm, surf)
53 CloudText *cloud;
54 Geom *prim;
55 Ray *ray;
56 Vector *pos, *norm, *gnorm;
57 Surface *surf;
58 {
59 Ray pray;
60 Float alpha, beta, It, dsquared, d, limb;
61
62 /*
63 * Transform ray to prim. space.
64 */
65 pray = *ray;
66 (void)TextRayToPrim(&pray);
67 dsquared = dotp(&pray.pos, &pray.pos);
68 if (fabs(dsquared) < 1. + EPSILON) {
69 surf->transp = 1.;
70 surf->amb.r = surf->amb.g = surf->amb.b = 0.;
71 surf->diff.r = surf->diff.g = surf->diff.b = 0.;
72 return;
73 }
74 It = fBm(pos,cloud->omega,cloud->lambda,cloud->octaves);
75 It = (cloud->maxval + It) * 0.5/cloud->maxval;
76 if (It < 0.)
77 It = 0;
78 else if (It > 1.)
79 It = 1;
80 d = sqrt(dsquared);
81 beta = sqrt(dsquared - 1) / d;
82 alpha = -dotp(&pray.pos, &pray.dir) / d;
83 limb = (alpha - beta) / (1 - beta);
84 /*
85 * limb is 0 on the limb, 1 at the center, < 1 outside.
86 */
87 surf->transp = 1. - (It-cloud->cthresh-cloud->range*(1.-limb))/
88 cloud->transcale;
89
90 if (surf->transp > 1)
91 surf->transp = 1.;
92 if (surf->transp < 0)
93 surf->transp = 0.;
94
95 ColorScale((1. - surf->transp) *
96 (1. - cloud->scale + cloud->scale*It),
97 surf->diff, &surf->diff);
98 ColorScale(1. - surf->transp, surf->amb, &surf->amb);
99 }
100