source: GTP/trunk/App/Demos/Illum/pathmap/Material.hpp @ 2197

Revision 2197, 6.2 KB checked in by szirmay, 17 years ago (diff)
Line 
1#pragma once
2#include "Vector.hpp"
3/*!
4\brief Material class for ray tracing.
5A material that can be assigned to Intersectables.
6Implements [lambert + phong + ideal reflection + refraction + emission] model.
7Descendants may override this by texturing (TexturedMaterial) or procedural texturing.
8*/
9class Material
10{
11protected:
12        char name[64];
13
14        //! diffuse coefficient
15        Vector kd;     
16        //! specular energy reflected for perpendicular light
17        Vector ks;     
18        //! specularity
19        float ns;       
20
21        //! ideal
22        Vector ki;     
23        //! refractive
24        Vector kr;     
25        //! refraction ratio
26        float rf;       
27
28        //! diffuse albedo
29        float ad;
30        //! specular albedo
31        float as;
32        //! ideal albedo
33        float ai;
34        //! refraction albedo
35        float ar;
36
37        //! diffuse emission
38        Vector ed;
39        //! directional (near surface normal) emission
40        Vector es;
41        //! directional (near surface normal) emission exponent
42        float ens;
43        //! diffuse emission albedo
44        float aed;
45        //! directional emission albedo
46        float aes;
47
48public:
49        static const Material DIFFUSEWHITE;
50        static const Material DIFFUSEGRAY;
51        static const Material SHINYBLACK;
52        static const Material STEEL;
53        static const Material DIFFUSERED;
54        static const Material DIFFUSEBLUE;
55        static const Material DIFFUSELIGHTBLUE;
56        static const Material DIFFUSEGREEN;
57        static const Material DIFFUSEYELLOW;
58        static const Material DIFFUSEORANGE;
59        static const Material YELLOWPLASTIC;
60        static const Material LAMP;
61
62        Material(std::istream& isc)
63        {
64                name[0] = '\0';
65                kd = ks = ki = kr = ed = es = Vector::RGBBLACK;
66                ns = rf = ens = 0.0f;
67                char key[200];
68                do
69                {
70                        isc >> key;
71                        if(strcmp(key,"name") == 0) isc >> name;
72                        else if(strcmp(key,"diffuse") == 0)     isc >> kd;
73                        else if(strcmp(key,"specular") == 0)    { isc >> ks; isc >> ns; }
74                        else if(strcmp(key,"emissive") == 0)    isc >> ed;
75                        else if(strcmp(key,"specularemissive") == 0)    { isc >> es; isc >> ens; }
76                        else if(strcmp(key,"ideal") == 0)       isc >> ki;
77                        else if(strcmp(key,"refactive") == 0)   { isc >> kd; isc >> rf; }
78                }while(strcmp(key,"end") != 0);
79
80                ad = kd.sum() / 3.0f;
81                as = ks.sum() / 3.0f;
82                ai = ki.sum() / 3.0f;
83                ar = kr.sum() / 3.0f;
84                aed = ed.sum() / 3.0f;
85                aes = es.sum() / 3.0f;
86        }
87
88        Material(const Vector& kd, const Vector& ks, float ns)
89        {
90                this->kd = kd;
91                this->ks = ks;
92                this->ns = ns;
93                this->ki = Vector::RGBBLACK;
94                this->kr = Vector::RGBBLACK;
95                this->rf = 1.0f;
96
97                this->ed = Vector::RGBBLACK;
98                this->es = Vector::RGBBLACK;
99                this->ens = 2.0f;
100
101                ad = kd.sum() / 3.0f;
102                as = ks.sum() / 3.0f;
103                ai = ki.sum() / 3.0f;
104                ar = kr.sum() / 3.0f;
105                aed = ed.sum() / 3.0f;
106                aes = es.sum() / 3.0f;
107        }
108
109        Material(const Vector& kd, const Vector& ks, float ns,
110                        const Vector& ed, const Vector& es, float ens)
111        {
112                this->kd = kd;
113                this->ks = ks;
114                this->ns = ns;
115                this->ki = Vector::RGBBLACK;
116                this->kr = Vector::RGBBLACK;
117                this->rf = 1.0f;
118
119                this->ed = ed;
120                this->es = es;
121                this->ens = ens;
122
123                ad = kd.sum() / 3.0f;
124                as = ks.sum() / 3.0f;
125                ai = ki.sum() / 3.0f;
126                ar = kr.sum() / 3.0f;
127                aed = ed.sum() / 3.0f;
128                aes = es.sum() / 3.0f;
129        }
130
131        void makeDiffuseAndIdeal(const Vector& kd, const Vector& ki)
132        {
133                this->kd = kd;
134                this->ks = Vector::RGBBLACK;
135                this->ns = 0.0f;
136                this->ki = ki;
137                this->kr = Vector::RGBBLACK;
138                this->rf = 1.0f;
139
140                ad = kd.sum() / 3.0f;
141                as = ks.sum() / 3.0f;
142                ai = ki.sum() / 3.0f;
143                ar = kr.sum() / 3.0f;
144        }
145
146        void makeRefractiveAndIdeal(float rf, const Vector& kr, const Vector& ki)
147        {
148                this->kd = Vector::RGBBLACK;
149                this->ks = Vector::RGBBLACK;
150                this->ns = 0.0f;
151                this->ki = ki;
152                this->kr = kr;
153                this->rf = rf;
154
155                ad = kd.sum() / 3.0f;
156                as = ks.sum() / 3.0f;
157                ai = ki.sum() / 3.0f;
158                ar = kr.sum() / 3.0f;
159        }
160
161        bool isEmissive() const
162        {
163                if(isHDRI())
164                        return true;
165                return aes + aed > 0.0f;
166        }
167
168        bool isMirror() const
169        {
170                return ai > 0.0f;
171        }
172
173        bool isGlass() const
174        {
175                return ar > 0.0f;
176        }
177
178        void getReflectivity(Vector& result) const
179        {
180                result = ki;
181        }
182
183        void getRefractivity(Vector& result) const
184        {
185                result = kr;
186        }
187
188        const Vector& getDiffuseEmission() const
189        {
190                return ed;
191        }
192
193        const Vector& getDiffuseBrdf() const
194        {
195                return kd;
196        }
197
198        virtual Vector getProceduralDiffuseBrdf(const Vector& atPoint) const
199        {
200                return kd;
201        }
202
203        virtual Vector getTextureDiffuseBrdf(const Vector& atPoint) const
204        {
205                return kd;
206        }
207
208        const Vector& getIdealBrdf() const
209        {
210                return ki;
211        }
212
213        float getDiffuseAlbedo() const
214        {
215                return ad;
216        }
217
218        float getTextureDiffuseAlbedo(const Vector& uv) const
219        {
220                return ad;
221        }
222
223        float getSpecularAlbedo() const
224        {
225                return as;
226        }
227
228        float getIdealAlbedo() const
229        {
230                return ai;
231        }
232
233        float getTextureIdealAlbedo(const Vector& uv) const
234        {
235                return ad;
236        }
237
238        float getRefractiveAlbedo() const
239        {
240                return ar;
241        }
242
243        float getRefractionDensity() const
244        {
245                return rf;
246        }
247
248        Vector getSurfaceRadiance() const
249        {
250                return ed;
251        }
252
253        void scatteringProbability (const Vector& in, Vector& out, const Vector& normal, Vector& result) const
254        {
255                float nDotOut = normal * out;
256                float nDotIn = - (normal * in);
257                if ( nDotOut < 0) {
258                        result = Vector::RGBBLACK;
259                        return;
260                }
261                // add diffuse part
262                result  = kd;
263                // add specular using max Phong shading
264                Vector idealReflected;
265                idealReflected.setIdealReflectedDirection (in, normal);
266                float dotProduct = idealReflected* out;
267            if(dotProduct > 0)
268                {
269                        float scale = (float)pow (dotProduct, ns) * (ns + 2.0f) * 0.5f / 3.14159265358979323846f ;
270                        if(nDotOut > nDotIn)
271                                scale /= nDotOut;
272                        else
273                                scale /= nDotIn;
274                        result += ks * scale;
275                }
276                result *= nDotOut;
277        }
278
279        virtual void proceduralScatteringProbability (const Vector& atPoint, const Vector& in, Vector& out, const Vector& normal, Vector& result) const
280        {
281                float nDotOut = normal * out;
282                float nDotIn = - (normal * in);
283                if ( nDotOut < 0) {
284                        result = Vector::RGBBLACK;
285                        return;
286                }
287                // add diffuse part
288                result  = kd;
289                // add specular using max Phong shading
290                Vector idealReflected;
291                idealReflected.setIdealReflectedDirection (in, normal);
292                float dotProduct = idealReflected* out;
293            if(dotProduct > 0)
294                {
295                        float scale = (float)pow (dotProduct, ns) * (ns + 2.0f) * 0.5f / 3.14159265358979323846f ;
296                        if(nDotOut > nDotIn)
297                                scale /= nDotOut;
298                        else
299                                scale /= nDotIn;
300                        result += ks * scale;
301                }
302                result *= nDotOut;
303        }
304
305        const char* getName() const
306        {
307                return name;
308        }
309
310        virtual bool isHDRI() const
311        {
312                return false;
313        }
314
315        virtual ~Material(){}
316};
Note: See TracBrowser for help on using the repository browser.