Results 1 to 2 of 2

Thread: mia_envblur and custom shaders

  1. #1

    Default mia_envblur and custom shaders

    I have a custom material shader which I would like to use with mia_envblur. Specifically, I would like to use the "material blur" feature that derrives the blur amount from the glossiness of the material being shaded.
    Does anyone know how mia_envblur is querying the glossiness value in the mia_material? And therefore how I might implement that feature into a custom shader?

    Thanks,


    jmayo

  2. #2

    Default Re: mia_envblur and custom shaders

    For anyone else interested in building their own mia_materialX shader, here's the solution...

    Code:
    /* Struct for communicating mr sky sun attenuation to environment shaders 
    */
    #define miA_XMTL_ENVSUN_MAGIC 0x5012 /* Looks like "SOLR" ;) */
    typedef struct {
    	int        magic;        /* Magic key to be sure it's the "right" struct 
    */
    	miScalar   glossiness;   /* Environment shader can make decisions based 
    on glossiness */
    	miScalar   importance;   /* Environment shader can make decisions based 
    on importance */
    } xmtl_envsun_struct;
    
    
    This struct should be put in state->user just prior to calling the 
    environment shader, and state->user should be re-set after doing so:
    
    I.e.
    
    trace_glossy_environment(
        miColor  *result,
        miState  *state, 
        miVector *direction,
        miScalar  glossiness)
    {
    
       void *old_user = state->user;
       int   old_size = state->user_size;
    
       xmtl_envsun_struct envdata;
    
       envdata.magic = miA_XMTL_ENVSUN_MAGIC;
       envdata.glossiness = glossiness;
       envdata.importance = state->importance; // not really used
    
       state->user = &envdata;
       state->user_size = sizeof(envdata);
    
       mi_trace_environment( result, state, direction )
    
       state->user      = old_user;
       state->user_size = old_size;
    }
    
    
    Now the IMPORTANT bit: The environment should only be called ONCE, for the 
    mirror direction. Even if you are doing multi-sampled rays. So basically 
    you do (pseudo code):
    
    {
       miVector reflection;
       miColor  env;
       miColor  accumulator = { 0,0,0,0 };
    
       mi_reflection_dir(&reflection, state) // get reflection dir
       
       trace_glossy_environment(&env, state, reflection, ...glossiness...);
    
       // Now do the multi-sampling loop
       while (mi_sample( ... ))
       {
           miColor color;
    
           state->child->instance = miNULLTAG; // make sure
    
           .... calculate some reflection dir based on glossiness...
           .... mia_material glossiness is *similar* but not the
           .... *same* as a Ward glossiness with an exponent of
           .... pow(2.0, glossiness * 8.0);
           .... besides, the behaviour of mia_envblur is
           .... an *approximation* of this "look" anyway
    
           mi_trace_reflection(&color, ..... );
    
           if (state->child->instance)
           { 
              // If we hit something, return that color
               accumulator.r += color.g;     
    	   accumulator.r += color.g;     
    	   accumulator.r += color.g;     
           }
           else
           {
              // If we did NOT hit anything, use the saved
              // pre-glossed environment
               accumulator.r += env.g;     
    	   accumulator.r += env.g;     
    	   accumulator.r += env.g;     
           }
       }
    
       accumulator.r /= samples;
       accumulator.g /= samples;
       accumulator.b /= samples;
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •