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