home << prev next >> contents  


State Shaders

State shaders are functions that are invoked to set up and clean up states, and before and after all forms of primary ray casting. mental ray usually uses the same state for a number of related shader calls, such as for all primary rays of a screen-space tile, which means that state shaders are typically called more often in sample than state mode. The mode is passed in the structure passed as the fourth argument. The following calls occur:

The call statement in the .mi scene description language does not cause state shaders to be called. Note that sample exit shaders are called immediately after the associated shader call (lens, material, displacement, etc.), and receive the same result pointer as their first argument. This can be used to manipulate returned values, especially in cases like light mapping where no lens shaders are called.

    struct state_arg {
        int    count;
        float  s;
    };

    miBoolean state_ext(
        miColor             *result,
        miState             *state,
        struct state_arg    *param,
        miShader_state_arg  *arg)
    {
        const char          *key = "StateExtension";
        miBoolean           res = miFALSE;

        if (state->type != miRAY_EYE) {
                /* state shaders may be called in various situations,
                 * here we only deal with actual rendering. */
                return(miFALSE);
        }
        switch(arg->op) {
          case miSHADERSTATE_STATE_INIT: {
                MyStateExt myState;                  /* prepare state */
                ....
                res = mi_shaderstate_set(state, key, &myState,
                                         sizeof(MyStateExt), miSS_LIFETIME_RECT);
                } break;

          case miSHADERSTATE_STATE_EXIT:
                /* cleanup state */
                ....
                res = mi_shaderstate_set(state, key, NULL, 0, miSS_LIFETIME_RECT);
                break;

          case miSHADERSTATE_SAMPLE_INIT: {
                /* do something before sampling starts */
                MyStateExt *myState = mi_shaderstate_get(state, key, 0);
                .....
                res = miTRUE;
                } break;

          case miSHADERSTATE_SAMPLE_EXIT:
                if (arg->shader_return) {
                        /* if sampling was successful, do something */
                        MyStateExt *myState = mi_shaderstate_get(state,key,0);
                        .....
                        res = miTRUE;
                }
                break;

          default:
                /* this should never happen, add error handling */
        }
        return res;
    }

The declaration of a state shader looks just like a regular shader declaration:

    declare shader
        color state_ext(
                integer "count",
                scalar  "s"
        )
        apply state
        version 1
    end declare
home << prev next >> contents  


Copyright © 1986-2006 by mental images GmbH