1 #ifndef VOLUMERENDERING_HXX
2 #define VOLUMERENDERING_HXX
3
4 #include "Primitive.hxx"
5 #include "PerlinNoise.hxx"
6
7 class VolumeRendering : public Primitive
8 {
9 private:
10 Scene* scene;
11 TransparencyShader* shader;
12 Primitive* primitive;
13 PerlinNoise* noise;
14 Vec3f color;
15 float ka;
16 float kd;
17 float ks;
18 float ke;
19 float stepsize;
20 float trans;
21
22 Box CalcBounds()
23 {
24 return primitive->GetBounds();
25 }
26
27 public:
28 VolumeRendering( Scene* scene, Primitive* primitive, Vec3f color, float ka, float kd, float ks, float ke, float trans )
29 : scene(scene), primitive(primitive), trans(trans)
30 {
31 noise = new PerlinNoise();
32 stepsize = 0.3;
33 // create a new shader for the given primitive
34 shader = new TransparencyShader(scene, color, ka, kd, ks, ke, 1.0, 0.0, 1.0, 1.0);
35 this->setShader(shader);
36 };
37
38 ~VolumeRendering()
39 {
40 delete noise;
41 };
42
43 bool Intersect(Ray &ray)
44 {
45 // does the ray hit the primitive?
46 if (!primitive->Intersect(ray))
47 return false;
48
49 ray.hit = this;
50
51 float transparency = 0.0;
52
53 // copy ray and compute next hitpoint
54 Ray clone = ray;
55 clone.org = ray.org + ray.t * ray.dir;
56
57 primitive->Intersect(clone);
58
59 // compute transparency:
60 // which variegates through the whole object, since the transparency is dependent of the hitpoint
61 // thereby the VolumeRendering effect is produced
62 for (float t = clone.t; t > 0; t -= stepsize)
63 {
64 Vec3f hit = clone.org + clone.t * clone.dir;
65 transparency += 0.2 * fabs(noise->PerlinNoise3D( hit, 0.5, 8 ));
66 }
67
68 // change transparency
69 transparency = trans * min(transparency,1.0);
70
71 // compute shaded colour
72 shader->setTransparency(transparency);
73
74 return true;
75 }
76
77 /**
78 * normal is the same as for the given primitive
79 */
80 Vec3f GetNormal(Ray &ray)
81 {
82 return primitive->GetNormal(ray);
83 }
84 };
85
86 #endif
87
syntax highlighted by Code2HTML, v. 0.9.1