Render Pass Merge Shaders

Pass merge shaders combine multiple pass files to a single pass file or image. They have access to all pass files, but only a single sample location at a time. One of the input file may be the currently rendered scene instead of a pass file on disk; in this case the merge shader is called every time the renderer has completed one sample, such as when a lens shader or primary material shader returns.

Here is an example of a simple merge shader that loops over all samples and selects the frontmost, based on its Z depth:

    DLLEXPORT int passmerge_version(void) {return(1);}

    DLLEXPORT miBoolean passmerge(
        miColor         *dummy,
        miState         *state,
        void            *paras)
    {
        int             best_p = -1, p;
        miScalar        best_z = 1e10, *zp;
        miColor         *src, *tar;

        for (p=0;; p++) {
            zp = mi_renderpass_access(state, p, miRC_IMAGE_Z);
            if (!zp) break;
            if (*zp > 0 && *zp < best_z) {
                best_z = *zp;
                best_p = p;
            }
        }
        if (best_p >= 0) {
            tar = mi_renderpass_access(state, -1,     miRC_IMAGE_RGBA);
            src = mi_renderpass_access(state, best_p, miRC_IMAGE_RGBA);
            *tar = *src;
            if ((int)state->raster_x/3%5 == (int)state->raster_y/3%5)
                switch(best_p) {
                  case 0:  tar->a = tar->r = 1; break;
                  case 1:  tar->a = tar->g = 1; break;
                  case 2:  tar->a = tar->b = 1; break;
                  default: tar->a = tar->r = tar->g = tar->b = 1;
                }
        }
        return(miTRUE);
    }

The shader first loops over all passes, reading the Z distance from the depth frame buffer ( miRC_IMAGE_RGBA). In pass rendering mode, the color and depth frame buffers always exist. When the lookup fails, the end of the pass list was reached and the loop terminates. Otherwise, for non-infinite depths (*zp = 0), the one closest to the camera is saved in the best_ variables.

When the closest sample was found, assuming one non-infinite distance was found, its color value is copied to the output ( tar), and diagonal white stripes are painted on top. Only the color frame buffer is written to. A better merge shader would write the entire sample, and perform a correct depth-sorted alpha blending loop. This is what the built-in default merge function does. It is very rarely necessary to override the built-in merge function with a custom one like this.

Copyright © 1986-2010 by mental images GmbH