ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/translat.txt
Revision: 1.2
Committed: Thu Sep 8 12:10:10 1994 UTC (29 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.1: +15 -12 lines
Log Message:
minor wording changes

File Contents

# User Rev Content
1 greg 1.1 TRANSLATING TO MGF FROM OTHER FORMATS
2     SCCSid "$SunId$ LBL"
3    
4     The description of the parser and the MGF specification should provide
5     enough information to get you started using MGF scene files, but we
6     thought it would be helpful to also provide some hints and
7     suggestions for translating to MGF from other formats.
8     Specifically, we will discuss several issues that come up repeatedly
9     when converting from more usual computer graphics scene formats to
10     MGF, most of them having to do with materials. First, let's look at
11     some geometry-related issues.
12    
13     Vertex Naming
14     =============
15     Many scene formats do not name vertices; many do not even share
16     vertices. Does it matter what names are given to vertices in MGF?
17     Not a lot, but it can affect memory and file size. In a way, vertex
18     sharing is nothing more than a form of file compression, and the
19     better you are at sharing vertex information, the smaller your file
20     will be. (Vertex sharing is also important for some rendering
21     algorithms, which depend on it for computing surface adjacency.)
22    
23     If you are translating from a format that shares unnamed vertices,
24     such as Wavefront's .OBJ format, you will want to name your MGF
25     vertices according to some simple pattern. In most cases, a name
26     such as "v%d" will do, where %d is replaced by an incremented
27     integer.
28    
29     If, on the other hand, you are translating from a format that does
30     not share vertices, you should do one of two things. You should
31     either select your MGF vertex names from a small, recycled pool of
32     names, or figure out some way to share vertices that were not shared
33     before. In the first case, you will just allocate as many vertex
34     names as you need for any given object, then reuse these names and
35 greg 1.2 therefore the parser's memory for other objects. In the second case,
36 greg 1.1 you will cache vertex names and values in some LRU table of
37     predetermined size, and use this table to merge vertices in the
38     file. (See rad2mgf.c as an example of how this can be done.)
39    
40     For some objects, there may be little point in merging vertices, and
41     you may want to treat these surfaces separately. For example,
42     putting out an MGF ring means putting out a central vertex, which
43     must have both a position point and a normal direction. It is somewhat
44     unlikely that any other MGF entity will share this point, and quite
45     unlikely that it will share the normal direction, so there is little
46     sense in trying to merge or otherwise reuse it.
47    
48     Points and Lines
49     ================
50     Although points and lines are really 3-d surfaces, many CAD
51     systems include them in their models. The question then is,
52     what do we do with these in MGF? If the idea is to produce a point
53     or line on the final display that is one or two pixels wide, there
54     is little one can do to guarantee such a thing will happen because
55     the pixel size is dependent on view and display parameters as well
56 greg 1.2 as object location.
57 greg 1.1
58     There are two ways of dealing with points and lines in MGF. The
59     first is to say, "Hey, these are 0 and 1 dimensional entities, so
60     they won't appear in 3 dimensions," and get rid of them. The second
61     approach is to assign some user-specified dimension for the "width"
62     of points and lines, and turn them into spheres and cylinders. It
63     might be best to instead create minimal polyhedron analogs, such as
64     tetrahedra for points and triangular prisms for lines. That way, an
65     itty-bitty point won't be converted into 200 polygons because the
66     translator reading in the MGF file can't handle curved surfaces.
67    
68     Polygons with Holes
69     ===================
70     There is no explicit representation of holes in MGF. A hole must be
71     represented implicitly by connecting vertices to form "seams." For
72     example, a wall with a window in it might look like this:
73    
74     v1.-----------------------------------------------.v4
75     | |
76     | v8.---------------.v5 |
77     | | | |
78     | | | |
79     | v7.---------------.v6 |
80     | |
81     | |
82     v2.-----------------------------------------------.v3
83    
84     In many systems, the wall itself would be represented with the first
85     list of vertices, (v1,v2,v3,v4) and the hole associated with that
86     wall as a second set of vertices (v5,v6,v7,v8). In MGF, we must
87     give the whole thing as a single polygon, connecting the vertices so
88     as to create a "seam," thus:
89    
90     v1.----------------------<------------------------.v4
91     | _____--><---'|
92     | v8.------->-------.v5 |
93     | | v |
94     v ^ | ^
95     | v7.-------<-------.v6 |
96     | |
97     | |
98     v2.---------------------->------------------------.v3
99    
100     which could be written in MGF as "f v1 v2 v3 v4 v5 v6 v7 v8 v5 v4".
101    
102     It is very important that the order of the hole be opposite to the
103     order of the outer perimeter, otherwise the polygon will be
104     "twisted" on top of itself. Note also that the seam was traversed
105     in both directions, once going from v4 to v5, and again returning
106     from v5 to v4. This is a necessary condition for a proper seam.
107     (The final edge from v4 back to v1 is implied in MGF.)
108    
109     The choice of vertices to make into a seam is somewhat arbitrary, but
110     some rendering systems may not give sane results if you cross over a
111     hole with part of your seam. If we had chosen to create the seam
112     between v2 and v5 in the above example instead of v4 and v5, the seam
113     would cross our hole and may not render correctly. (For systems that
114 greg 1.2 are sensitive to this, it is probably safest for their MGF
115 greg 1.1 loader/translator re-expresses seams in terms of holes again, which can
116     be done easily so long as vertices are shared in the above fashion.)
117    
118     Non-planar Polygons
119     ===================
120     Polygons in MGF should be planar. There is nothing about the format
121     that enforces this, but the rendering or modeling software on the other
122     end may have real problems if this requirement is violated. The parser
123     itself does not test for non-planar polygons, so when in doubt about a
124 greg 1.2 model, it is safest to test for planarity and break a polygon into triangles
125 greg 1.1 if it is even slightly non-planar.
126    
127     NURBS, CSG, Blobbies, Etc.
128     ==========================
129     Sorry, folks, this is just plain hard. If and until MGF supports these
130     higher-order entities, it will be necessary for you to convert them to
131     smoothed triangle meshes. Fortunately, a lot of modeling software
132     already knows how to do this, so if you wrote the modeler, you probably
133     have access to the necessary code. (By the way, if you ever want to see
134     these primitives in MGF, you might just think about sharing the wealth,
135     because the MGF parser needs to mesh every primitive it supports.)
136    
137     Materials
138     =========
139     The MGF material model was designed to accommodate most common
140     physical surfaces. Included are reasonable models for plastic
141     and metal, thin glass and translucent surfaces. Not included at
142     this time are surfaces with anisotropic reflection, refraction and/or
143     surface textures. These were deemed either unnecessary or too
144     difficult to standardize for the initial format. Also, light
145     sources are known only by the emissive nature of their surface(s),
146     and MGF itself only provides for diffuse emission. (As MGF is
147     destined to be part of the IES luminaire data standard, it was
148     assumed that this combined format would be used for such purposes as
149     describing light source output and geometry.)
150    
151     The "sides" entity is used to control the number of sides a surface
152     should have. In the real world, a surface can have only one side,
153     defining the interface between one volume and another. Many
154     object-space rendering packages (e.g. z-buffer algorithms) take
155     advantage of this fact by culling back-facing polygons and thus saving
156     roughly 50% of the calculation time. However, many models rely on an
157     approximation whereby a single surface is used to represent a very thin
158     volume, such as a pane of glass, and this also can provide significant
159     calculational savings in an image-space algorithm (such as
160     ray-tracing). Since both types of surfaces are useful and both types
161     of rendering algorithms may ultimately be applied, MGF provides a way
162 greg 1.2 to specify sidedness rather than picking one interpretation or the other.
163 greg 1.1
164     So-called specular reflection and transmission are modeled using a
165     Gaussian distribution of surface normals. The "alpha_r" and
166     "alpha_t" parameters to the respective "rs" and "ts" entities specify
167     the root-mean-squared (RMS) surface facet slope, which varies from 0
168     for a perfectly smooth surface to around .2 for a fairly rough one.
169     The effect this will have on the reflected component distribution is
170     well-defined, but predicting the behavior of the transmitted
171     component requires further assumptions. We assume that the surface
172     scatters light passing through it just as much as it scatters
173     reflected light. This assumption is approximately correct for a
174     two-sided transparent material with an index of refraction of 1.5
175     (about that of glass) and both sides having the given RMS facet
176     slope.
177    
178     Oftentimes, one is translating from a Phong exponent on the cosine
179     of the half-vector-to-normal angle to the more physical but less
180     familiar Gaussian model of MGF. The hardest part is translating
181     the specular power to a roughness value. For this, we recommend
182     the following approximation:
183    
184     roughness = 0.6/sqrt(specular_power)
185    
186     It's not a perfect correlation, but it's about as good as you can get.
187    
188     Colors
189     ======
190     Unlike most graphics languages, MGF does not use an RGB color model,
191     simply because there is no recognized definition for this model.
192     It is based on computer monitor phosphors, which vary from one
193     CRT to the next. (There is an RGB standard defined in the TV
194 greg 1.2 industry, but this has a rather poor correlation to most computer
195     monitors.)
196 greg 1.1
197     MGF uses two alternative, well-defined standards. The first is the CIE
198 greg 1.2 standard xy chromaticity coordinates. With this standard, any viewable
199 greg 1.1 color may be exactly reproduced. Unfortunately, the interaction between
200     colors (i.e. colored light sources and interreflections) cannot be
201     specified exactly with any finite coordinate set, including CIE
202     chromaticities. So, MGF offers the ability to give reflectance,
203     transmittance or emittance as a function of wavelength over the visible
204     spectrum. This function is still discretized, but at a user-selectable
205     resolution. Furthermore, spectral colors may be mixed, providing (nearly)
206     arbitrary basis functions, which can produce more accurate results in
207 greg 1.2 some cases and are merely a convenience for translation in others.
208 greg 1.1
209     Conversion back and forth between CIE chromaticity coordinates and spectral
210     samples is provided within the MGF parser. Unfortunately, conversion
211     to and from RGB values depends on a particular RGB definition, and as we
212     have said, there is no recognized standard. We therefore recommend that
213     you decide yourself what chromaticity values to use for each RGB primary,
214     and adopt the following code to convert between CIE and RGB coordinates.
215    
216     #ifdef NTSC
217     #define CIE_x_r 0.670 /* standard NTSC primaries */
218     #define CIE_y_r 0.330
219     #define CIE_x_g 0.210
220     #define CIE_y_g 0.710
221     #define CIE_x_b 0.140
222     #define CIE_y_b 0.080
223     #define CIE_x_w 0.3333 /* monitor white point */
224     #define CIE_y_w 0.3333
225     #else
226     #define CIE_x_r 0.640 /* nominal CRT primaries */
227     #define CIE_y_r 0.330
228     #define CIE_x_g 0.290
229     #define CIE_y_g 0.600
230     #define CIE_x_b 0.150
231     #define CIE_y_b 0.060
232     #define CIE_x_w 0.3333 /* monitor white point */
233     #define CIE_y_w 0.3333
234     #endif
235    
236     #define CIE_D ( CIE_x_r*(CIE_y_g - CIE_y_b) + \
237     CIE_x_g*(CIE_y_b - CIE_y_r) + \
238     CIE_x_b*(CIE_y_r - CIE_y_g) )
239     #define CIE_C_rD ( (1./CIE_y_w) * \
240     ( CIE_x_w*(CIE_y_g - CIE_y_b) - \
241     CIE_y_w*(CIE_x_g - CIE_x_b) + \
242     CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g ) )
243     #define CIE_C_gD ( (1./CIE_y_w) * \
244     ( CIE_x_w*(CIE_y_b - CIE_y_r) - \
245     CIE_y_w*(CIE_x_b - CIE_x_r) - \
246     CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r ) )
247     #define CIE_C_bD ( (1./CIE_y_w) * \
248     ( CIE_x_w*(CIE_y_r - CIE_y_g) - \
249     CIE_y_w*(CIE_x_r - CIE_x_g) + \
250     CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r ) )
251    
252     #define CIE_rf (CIE_y_r*CIE_C_rD/CIE_D)
253     #define CIE_gf (CIE_y_g*CIE_C_gD/CIE_D)
254     #define CIE_bf (CIE_y_b*CIE_C_bD/CIE_D)
255    
256     float xyz2rgbmat[3][3] = { /* XYZ to RGB */
257     {(CIE_y_g - CIE_y_b - CIE_x_b*CIE_y_g + CIE_y_b*CIE_x_g)/CIE_C_rD,
258     (CIE_x_b - CIE_x_g - CIE_x_b*CIE_y_g + CIE_x_g*CIE_y_b)/CIE_C_rD,
259     (CIE_x_g*CIE_y_b - CIE_x_b*CIE_y_g)/CIE_C_rD},
260     {(CIE_y_b - CIE_y_r - CIE_y_b*CIE_x_r + CIE_y_r*CIE_x_b)/CIE_C_gD,
261     (CIE_x_r - CIE_x_b - CIE_x_r*CIE_y_b + CIE_x_b*CIE_y_r)/CIE_C_gD,
262     (CIE_x_b*CIE_y_r - CIE_x_r*CIE_y_b)/CIE_C_gD},
263     {(CIE_y_r - CIE_y_g - CIE_y_r*CIE_x_g + CIE_y_g*CIE_x_r)/CIE_C_bD,
264     (CIE_x_g - CIE_x_r - CIE_x_g*CIE_y_r + CIE_x_r*CIE_y_g)/CIE_C_bD,
265     (CIE_x_r*CIE_y_g - CIE_x_g*CIE_y_r)/CIE_C_bD}
266     };
267    
268     float rgb2xyzmat[3][3] = { /* RGB to XYZ */
269     {CIE_x_r*CIE_C_rD/CIE_D,CIE_x_g*CIE_C_gD/CIE_D,CIE_x_b*CIE_C_bD/CIE_D},
270     {CIE_y_r*CIE_C_rD/CIE_D,CIE_y_g*CIE_C_gD/CIE_D,CIE_y_b*CIE_C_bD/CIE_D},
271     {(1.-CIE_x_r-CIE_y_r)*CIE_C_rD/CIE_D,
272     (1.-CIE_x_g-CIE_y_g)*CIE_C_gD/CIE_D,
273     (1.-CIE_x_b-CIE_y_b)*CIE_C_bD/CIE_D}
274     };
275    
276    
277     cie_rgb(rgbcolor, ciecolor) /* convert CIE to RGB */
278     register float *rgbcolor, *ciecolor;
279     {
280     register int i;
281    
282     for (i = 0; i < 3; i++) {
283     rgbcolor[i] = xyz2rgbmat[i][0]*ciecolor[0] +
284     xyz2rgbmat[i][1]*ciecolor[1] +
285     xyz2rgbmat[i][2]*ciecolor[2] ;
286     if (rgbcolor[i] < 0.0)
287     rgbcolor[i] = 0.0;
288     }
289     }
290    
291    
292     rgb_cie(ciecolor, rgbcolor) /* convert RGB to CIE */
293     register float *ciecolor, *rgbcolor;
294     {
295     register int i;
296    
297     for (i = 0; i < 3; i++)
298     ciecolor[i] = rgb2xyzmat[i][0]*rgbcolor[0] +
299     rgb2xyzmat[i][1]*rgbcolor[1] +
300     rgb2xyzmat[i][2]*rgbcolor[2] ;
301     }
302    
303 greg 1.2 An alternative to adopting the above code is to use the MGF "cmix"
304     entity to convert from RGB directly by naming the three primaries in
305     terms of their chromaticities, e.g:
306 greg 1.1
307     c r =
308     cxy 0.640 0.330
309     c g =
310     cxy 0.290 0.600
311     c b =
312     cxy 0.150 0.060
313    
314     Then, converting from RGB to MGF colors is as simple as multiplying each
315     component by its relative luminance in a cmix statement, for instance:
316    
317     c white =
318     cmix 0.265 r 0.670 g 0.065 b
319    
320     For the chosen RGB standard, the above specification would result a pure
321     white. The reason the coefficients are not all 1 as you might expect is
322     that cmix uses relative luminance as the standard for its weights. Since
323     blue is less luminous for the same energy than red, which is in turn
324     less luminous than green, the weights cannot be the same to achieve an
325     even spectral balance. Unfortunately, computing these relative weights
326 greg 1.2 is not straightforward, though it is given in the above macros as CIE_rf,
327     CIE_gf and CIE_bf. (The common factors in these macros may of course
328     be removed for simplification purposes.)