/* tonemapping.h: tone mapping */ #ifndef _RPK_TONE_MAPPING_ #define _RPK_TONE_MAPPING_ #include #include "color.h" #include "adaptation.h" /* struct describing a tone map. Most of the functions have similar meaning * as for a radiance or ray-tracing method */ typedef struct TONEMAP { char *name, /* full name */ *shortName, /* short name useable as option argument */ *buttonName; /* UI button name, determines button resources */ int abbrev; /* minimal abbreviation of short name in option arg. */ void (*Defaults)(void); /* sets defaults */ void (*ParseOptions)(int *argc, char **argv); /* optional */ void (*PrintOptions)(FILE *fp); /* optional */ void (*Init)(void); /* initialises */ void (*Terminate)(void); /* terminates */ /* --------------------------------------------------------------------------- `TonemapReverseScaleForComputations' Knowing the display luminance "dl" this function determines the correct scaling value that transforms display luminance back into the real world luminance. ------------------------------------------------------------------------- */ COLOR (*ScaleForComputations)(COLOR radiance); /* --------------------------------------------------------------------------- `TonemapScaleForDisplay' Full tonemapping to display values. Transforms real world luminance of colour specified by "radiance" into corresponding display input values. The result has to be clipped to <0,1> afterwards. ------------------------------------------------------------------------- */ COLOR (*ScaleForDisplay)(COLOR radiance); /* --------------------------------------------------------------------------- `TonemapReverseScaleForComputations' Knowing the display luminance "dl" this function determines the correct scaling value that transforms display luminance back into the real world luminance. ------------------------------------------------------------------------- */ float (*ReverseScaleForComputations)(float dl); /* the GUI routines below are currently unused */ void (*CreateControlPanel)(void *parent_widget); /* optional */ void (*UpdateControlPanel)(void *parent_widget); /* optional */ void (*ShowControlPanel)(void); /* optional */ void (*HideControlPanel)(void); /* optional */ } TONEMAP; /* available tone mapping operators (NULL terminated array) */ extern TONEMAP *AvailableToneMaps[]; /* iterates over all available tone maps */ #define ForAllAvailableToneMaps(map) {{ \ TONEMAP **mapp; \ for (mapp=AvailableToneMaps; *mapp; mapp++) { \ TONEMAP *map = *mapp; #ifndef EndForAll #define EndForAll }}} #endif /* makes 'map' the current tone map and initialises. */ extern void SetToneMap(TONEMAP *map); /* gamma correction table */ #define GAMMATAB_BITS 12 /* 12-bit gamma table */ #define GAMMATAB_SIZE ((1<ScaleForComputations(radiance)) #define TonemapScaleForDisplay(radiance) (tmopts.ToneMap->ScaleForDisplay(radiance)) #define TonemapReverseScaleForComputations(dl) (tmopts.ToneMap->ReverseScaleForComputations(dl)) /* --------------------------------------------------------------------------- `ContrastSensitivity' Returns the normalised sensitivity to contrast changes along the line from "p1" to "p2" in case that the points are viewed from the eye point for the current camera. ------------------------------------------------------------------------- */ extern float ContrastSensitivity(POINT *p1, POINT *p2); /* --------------------------------------------------------------------------- `ContrastSensitivityEye' Eyepoint for contrast sensitivity computations. ------------------------------------------------------------------------- */ extern void ContrastSensitivityEye(POINT *p); /* --------------------------------------------------------------------------- `TMO_COLOR_COMP' Scales the given radiance "_c" so that the luminance of the result corresponds to the luminance that would be emitted by the display device displaying this color. ------------------------------------------------------------------------- */ #define TMO_COLOR_COMP(_c) \ _c = TonemapScaleForComputations(_c) /* --------------------------------------------------------------------------- `TMO_COLOR_DISP' Scales the given radiance "_c" so that the result lays in [0,1] range. ------------------------------------------------------------------------- */ #define TMO_COLOR_DISP(_c) \ _c = TonemapScaleForDisplay(_c) /* --------------------------------------------------------------------------- `TMO_COLOR_COMP_CLIPPED' This is something that I am again not sure about: We need clipped luminance value in cd/m^2 of display output - this has to be clipped by "ldmax" as the display device can not produce higher luminance. I am clipping the Y value and scaling the X and Z so that the correspoding x,y stays the same. But: * shall we not simply set it to maximum white? * what about gamut clipping in this case? * is gamma correction necessary? (probably no, as it is just a means to account for nonlinear response of the given display device; luminances reproduced shall be OK. Moreover, the effectivity of this piece of code is not very high. Blah. ------------------------------------------------------------------------- */ #define TMO_COLOR_COMP_CLIPPED(_c, _gamma) \ do { \ float _b, _ldmax; \ TMO_COLOR_COMP(_c); /* result is in cd/m2 */ \ _b = ColorGray(_c); /* achromatic luminance */ \ _ldmax = TonemapLdmax(); \ if (_b > _ldmax) { COLORSCALE(_ldmax/_b, _c, _c); } \ } while(0) /* --------------------------------------------------------------------------- `TMO_CANDELA_LAMBERT' Transforms luminance from cd/m^2 to lamberts. Luminance in lamberts is needed for example by algorithms that are based on experiments of Stevens and Stevens (original Tumblin-Rushmeier tone operator). The transformation rule comes from Glassner's book, table 13.3, seems to be OK. ------------------------------------------------------------------------- */ #define TMO_CANDELA_LAMBERT(_a) ((_a) * M_PI * 1e-4) /* --------------------------------------------------------------------------- `TMO_LAMBERT_CANDELA' Transforms luminance from lamberts to cd/m^2 to lamberts. ------------------------------------------------------------------------- */ #define TMO_LAMBERT_CANDELA(_a) ((_a) / (M_PI * 1e-4)) #endif /*_RPK_TONE_MAPPING_*/