#ifndef rdo_synthesis_H #define rdo_synthesis_H /* Top-level image synthesis functions. */ #define rdo_synthesis_H_COPYRIGHT "Copyright © 2008 Danillo Pereira and J. Stolfi, UNICAMP" /* Last edited on 2024-12-21 11:51:08 by stolfi */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* !!! Add an explicit option for signed-value vs. unsigned-value image scaling. !!! */ #define MAX_HIGHLIGHTS 10 /* Max number of pixels and/or basis element that are to be highlighted during image sythesis. */ #define LINSOL_MAX_ITER 20 /* Maximum number of Gauss-Seidel iterations when solving radiance linear equations. */ #define LINSOL_OMEGA (0.25) /* Relaxation factor for iterative radiance equation solving. */ #define LINSOL_REL_TOL (1.0e-3) /* Stop iterative radiance equation solving when the relative change in the result is less than this. */ #define LINSOL_ABS_TOL (1.0e-4) /* Stop iterative radiance equation solving when the absolute change in the result is less than this. */ typedef enum { /* Image types that DO NOT require an approximation basis: */ image_type_Diffusion, /* The radiance will be the surface's diffusion coefficient. */ image_type_Emission, /* The radiance will be the emission coefficient. */ image_type_Normal, /* The radiance is a continuos function of the surface normal. */ image_type_Quadrants, /* The radiance is a piecewise constant function of the surface normal. */ image_type_Depth, /* The radiance depends only on the distance from the camera. */ image_type_SiteDist, /* The radiance is a function of distance from some site. */ /* Image types that DO require an approximation basis: */ image_type_BasisElems, /* Shows the values of selected basis elements. */ image_type_QuadrantsApprox, /* Shows the interpolation of the {Quadrants} image with the basis. */ image_type_Interpolators, /* Shows the values of some basis interpolators. */ image_type_ElemTransfer, /* Shows the effect or turning on a single element. */ image_type_Realistic /* Radiance computed with radiosity method. */ } image_type_t; /* A code that identifies the type of image to be generated. Setting {Realistic} with {maxBounces == 1} gives the result of ordinary ray tracing; {Realistic} with {maxBounces > 1} uses radiosity. */ /* Other parameters that control scene rendering: */ typedef struct synthesis_options_t { image_type_t imageType; /* Type of image to be generated. */ int maxBounces; /* Max number of bounces per photon. */ bool_t showSamplingSites; /* If {TRUE} shows the sampling sites. */ bool_t signedValues; /* If {TRUE}, assumes that radiance values may be negative. */ double crossSize; /* Radius (in pixels) of crosses */ int highlight_n; /* Count of selected pixels. */ r2_t highlight_hv[MAX_HIGHLIGHTS]; /* {H,V} indices of selected pixels. */ frgb_t highlight_color[MAX_HIGHLIGHTS]; /* Colors to use for the selected pixels. */ /* Fields computed by the program: */ int highlight_pix[MAX_HIGHLIGHTS]; /* Indices of the selected image-pixel sites. */ int highlight_smp[MAX_HIGHLIGHTS]; /* Indices of the selected sampling sites. */ } synthesis_options_t; void rdo_synthesis_compute_image ( scene_t *scn, camera_t *cam, dist_type_t tpDist, basis_elem_type_t tpElem, sampling_options_t *opSmp, approx_basis_options_t *opBas, synthesis_options_t *opSyn, image_t *img ); /* Fills the image {img} with the image of scene {scn} as viewed from camera {cam}, computed as described by the parameters {tpDist,tpElem,opSmp,opBas,opSyn}. If any fields of {scn} (sampling sites, approximation basis, matrices) are missing but are required by the image type, computes those fields from the given parameters. */ /* OBTAINING THE INGREDIENTS */ void rdo_synthesis_require_sampling_sites ( solid_vec_t *sds, point3_t *eye, dist_type_t tpDist, sampling_options_t *opSmp, site_vec_t *smp ); /* If the sampling site list {*smp} is empty, selects the sampling sites on the solid objects {sds} using the parameters {eye}, {tpDist}, and {opSmp}. */ void rdo_synthesis_require_approx_basis ( solid_vec_t *sds, site_vec_t *smp, dist_type_t tpDist, basis_elem_type_t tpElem, approx_basis_options_t *opBas, approx_basis_t *bas ); /* If the approx basis {*bas} is empty, constructs a basis of elements centered at the sampling sites listed in {smp}, with the parameters {tpDist}, {tpElem}, and {opBas}. */ void rdo_synthesis_require_basis_matrix ( site_vec_t *smp, approx_basis_t *bas, int avgCover, dspmat_t *M ); /* If the matrix {*M} is empty (all zeros), replaces it by the sample-basis value matrix (that maps basis coefficients to the radiances at the sampling sites {smp->e[0..smp->ne]}), computed with {rdo_approx_basis_build_matrix}. !!! Should take a {tpElem} parameter, and just return the identity for Shepard-like bases !!! */ void rdo_synthesis_require_site_transfer_matrix ( solid_vec_t *sds, site_vec_t *smp, dspmat_t *T ); /* If the matrix {*T} is empty (all zeros), replaces it by the (albedo-independent) radiance transfer matrix between the sampling sites {smp}, taking into account possible obstruction by the opaque solid objects {sds}. Estimates the nominal radii of the sites, then calls {rdo_lighting_compute_site_transfer_matrix}. */ void rdo_synthesis_require_basis_transfer_matrix ( solid_vec_t *sds, finish_vec_t *fns, site_vec_t *smp, int channel, dspmat_t *T, dspmat_t *M, dspmat_t *R ); /* If the matrix {*R} is empty (all zeros), replaces it by the radiance transfer matrix between the approx basis elements for the specified channel. Element {R[i,j]} of this matrix tells the coefficient of basis element {i} that is needed to approximate the radiance of the scene due to photons that were emitted by basis element {j} and suffered a single Lambertian scattering event at the scene's surface, assuming that only element {j} is turned on with coefficient 1.0. The matrix {R} is computed as the product {M^{-1}*S*T*M} where {M} is the matrix that maps basis coeffs to radiances at the sampling sites, {T} is the radiance transfer matrix between the sampling sites, and {S} is the diagonal matrix of the Lambertian diffusion coefficients at the sampling sites for the specified [channel}. */ void rdo_synthesis_require_rendering_matrix ( site_vec_t *pix, approx_basis_t *bas, int avgElemsPerColumn, dspmat_t *Q ); /* If the matrix {*Q} is empty (all zeros), replaces it by the pixel-basis value matrix (that maps basis coefficients to radiances of the pixels {pix->e[0..pix->ne]}), computed with {rdo_approx_basis_build_matrix}. */ /* OBTAINING THE IMAGE PIXEL SITES */ site_vec_t rdo_synthesis_compute_pixel_sites ( solid_vec_t *sds, camera_t *cam, int nh, int nv ); /* Generates the sites on the scene's surface that correspond to the {nh*nv} pixels of the image to be produced. The resulting site list has one site for each pixel; the site may be at infinity. Pixels are stored by row, bottom to top !!!check!!!, and left to right within each row. */ /* IMAGE PAINTING */ void rdo_synthesis_compute_pixel_radiances_from_coeffs ( double L[], int nL, dspmat_t *Q, double F[], int nF ); /* Computes the image pixel radiances {F[0..nF-1]} given the basis coefficient vector {L[0..nL-1]} and the basis rendering matrix {Q}. */ void rdo_synthesis_paint_pixel_radiances ( image_t *img, int channel, double F[], int nF ); /* Stores into color band {channel} of {img} the pixel radiances {F[0..nF-1]}. Requires {nF} to be equal to the number of image pixels. */ /* SITE HIGHLIGHTING */ void rdo_synthesis_identify_highlighted_sites ( synthesis_options_t *opSyn, solid_vec_t *sds, site_vec_t *smp, camera_t *cam, image_t *img, site_vec_t *pix ); /* Identifies the imag epixels sites and the sampling sites that correspond to the image coordinates {opSyn->higlight_hv[0..n-1]} where {n == opSyn->higlight_n}. More precisely, traces a ray from camera {cam} through each of the specified points of the image domain; finds the site {s} where the ray hits the scene; and then looks for the visible site that is closest to {s} in the lists {smp} (sampling sites) and {pix} (image pixel sites). The results are stored into {opSyn->higlight_bas[0..n-1]} and {opSyn->higlight_image[0..n-1]}, respectively. If the ray does not meet the scene, or there is no site in the list that meets the requirements, stores {NULL} into those variables. */ void rdo_synthesis_show_site ( site_t *s, solid_vec_t *sds, camera_t *cam, image_t *img, int channel, bool_t vis_only, float value0, float value1, double rad, double hwd, bool_t diagonal ); /* Projects the site {s} onto {img} by the camera {cam}, then paints a cross at that point with {float_image_paint_cross}. The cross will have radius {rad} and arms with half-width {hwd} (in pixels). If {diagonal} is TRUE, it will be turned 45 degrees. The image is painted into the selected {channel} only, with a sample value that varies depending on the site's visibility from the camera's {eye}, given the solid objects {sds}: from {value0} (invisible) to {value1} (fully visible). If {vis_only} is TRUE, paints the site only if the visibility is greater than zero. */ void rdo_synthesis_show_site_vec ( site_vec_t sts[], solid_vec_t *sds, camera_t *cam, image_t *img, bool_t vis_only, frgb_t *color0, frgb_t *color1, double rad, double hwd, bool_t diagonal ); /* Executes {rdo_synthesis_show_site(sts->e[i],cam,img,vis_only,color0,color1,rad,hwd,diagonal)} for {i} in {0..sts->ne-1]}. */ void rdo_synthesis_show_selected_sites ( site_vec_t *sts, int index[], frgb_t color[], int n, solid_vec_t *sds, camera_t *cam, image_t *img, double rad, double hwd, bool_t diagonal ); /* Paints into {img} a cross at the position of site {sts->e[index[j]]} for each {j} in {0..n-1}. Uses {rdo_synthesis_show_site} with the given {rad}, {hwd} and {diagonal} parameters. The color of the cross is {color[j]}, lightened or darkened to ensure contrats against a background of that same color. Ignores entries {index[j]} that are not in the range {0..sts->ne-1}. */ /* COMMAND LINE PARSING */ synthesis_options_t *rdo_synthesis_options_parse(argparser_t *pp); /* Parses the command line options that specify image to be produced, as described in {synthesis_options_HELP} and {synthesis_options_INFO}. */ #define synthesis_options_HELP \ " -imageType {IMAGE_TYPE} \\\n" \ " -maxBounces {MAX_BOUNCES} \\\n" \ " [ -highlight {H_PIX} {V_PIX} [ -color " frgb_parse_color_HELP " ] ].. \\\n" \ " [ -showSamplingSites ] \\\n" \ " [ -crossSize {CROSS_SIZE} ]" #define synthesis_options_INFO \ " -imageType {IMAGE_TYPE}\n" \ " This parameter specifies the kind of image to produce. The choices for {IMAGE_TYPE} are:\n" \ "\n" \ " Diffusion The radiance will be the surface's diffusion coefficient.\n" \ " Emission The radiance will be the emission coefficient.\n" \ " Normal The radiance is a continuos function of the surface normal.\n" \ " Quadrants The radiance is a piecewise constant function of the surface normal.\n" \ " Depth The radiance depends only on the distance from the camera.\n" \ " SiteDist The radiance is a function of distance from some site.\n" \ " BasisElems Shows the values of selected basis elements.\n" \ " Interpolators Shows the values of some basis interpolators.\n" \ " QuadrantsApprox Shows the interpolation of the {Quadrants} image with the basis.\n" \ " ElemTransfer Shows the effect or turning on a single element.\n" \ " Realistic Radiance computed with radiosity method.\n" \ "\n" \ " -maxBounces {MAX_BOUNCES}\n" \ " This parameter specifies something !!!.\n" \ "\n" \ " -highlight {H_PIX} {V_PIX} [ -color " frgb_parse_color_HELP " ]\n" \ " This parameter specifies something !!!.\n" \ "\n" \ " -showSamplingSites\n" \ " This option, if present, causes the sampling sites" \ " to be marked with small crosses on the output image.\n" \ "\n" \ " -signedValues\n" \ " This option, if present, signals to the program that the" \ " computed pixel radiance values may be negative. In" \ " that case, the program will scale the computed radiances to" \ " fit the range {[-0.5 _ +0.5]}, rather" \ " than {[0 _ 1]}; and then add 0.5 to all radiance values," \ " so that zero radiance becomes RGB {(0.5,0.5,0.5)}" \ " (middle gray), rather than {(0,0,0)} (black). Note" \ " that the resulting RGB values may be gamma-encoded" \ " when written to an image file.\n" \ "\n" \ " -crossSize {CROSS_SIZE}\n" \ " This optional parameter specifies the radius of the crosses used" \ " to show the sampling sites. It is doubled for the sites" \ " seleced through the \"-highlight\" option. The default is \"-crossSize 1\"." image_type_t rdo_synthesis_options_image_type_parse(argparser_t *pp); /* Parses the next command line argument into an {image_type_t} value. The argument must be one of the words "Diffusion", "Emission", etc. */ #endif