PDA

View Full Version : working with mia_env_blur



Saturn
May 26th, 2009, 11:42
Hi everyone.

Is there a way to comunicate with mia_env_blur shader like the mia_architectural is doing with a custom shader ?
I would like to take advantage of the multiple pre filter envmap done by the mia_env_blur shader.

I can't find any documentation about it.

Cheers,

H.

jmayo
May 29th, 2009, 13:23
Its not officially supported or documented but I do have this useful snippet of code that explains how its done.

/* 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;
}