/* General-purpose geometric models. */ /* Last edited on 2020-10-03 20:23:36 by jstolfi */ #ifndef gmo_opto_H #define gmo_opto_H #include #include #include #include typedef enum { gmo_opto_kind_EMIT = 0, gmo_opto_kind_ABSORB = 1, gmo_opto_kind_REFLECT = 2, gmo_opto_kind_TRANSMIT = 3 } gmo_opto_kind_t; typedef struct gmo_opto_t { frgb_t color; /* Fraction of coverage per band. */ gmo_opto_kind_t kind; /* Kind of optical effect. */ float sigma; /* Additional parameter, e.g. roughness. */ int next; /* Underlying opto, or -1 if none. */ } gmo_opto_t; /* An `opto' (short for `optical operator') specifies how a surface interacts with light at a point. It is assumed to be a linear combination of standard bi-directional radiation functions (BDRFs): * An EMIT function emits wite light (intensity 1) on all bands. If {sigma=0} the light is emitted perpendicularly to the surface; if {sigma=1} it is emitted like the Lambertian distribution (so that the apparent color is independent of viewing angle). * A REFLECT function reflects or diffuses light coming from the same side as the observer. If {sigma=0} the surface is a smooth mirror; if {sigma=1} it is an opaque Lambertian diffuser. * A TRANSMIT function transmits or scatters light coming from the side of the surface opposite to the observer. If {sigma=0} the surface is clear glass, if {sigma=1} it is a translucent Lambertian diffuser. * An ABSORB function emits nothing. An {opto} is actually a sequence of zero or more `stages', each described by an {gmo_opto_t} record. For each band {k}, the parameter {color.c[k]} specifies the percentage of the incident view rays that hit this stage of the opto. The remaining rays are assumed to interact with the {next} stage and following stages. An ABSORB stage with {color.c[k]=1} (i.e. a coal black layer) is assumed at the end of every stack, to catch any rays that are not caught by preceding stages. Note that rays that hit a TRANSMIT stage go through the surface unchanged, while those that miss it may interact with its subsequent stages. This behavior is not intuitive but simplifies the math. Intermediate values of {sigma} give a BDRF that is intermediate between the cases {sigma=0} and {sigma=1}. Thus, for example, highlights are obtained by adding a REFLECT stage with small but nonzero {sigma}. */ /* INPUT/OUTPUT */ gmo_opto_kind_t gmo_opto_kind_from_char(char c); char gmo_opto_kind_to_char(gmo_opto_kind_t oknd); #endif