Help: ray trace in material shader in mental ray


#1

Hi, I have only learned Mental Ray for one month, and now I find a big problem. I have spent one day to conquer it, but found it impossible for me.

My shader needs to ray trace several times in different positions to different directions to make Monte Carlo integration. But now I find trouble in the ray trace.
I cut some part of my shader below to do the debug. If it works, then so will my shader.

Tag is a flag which I defined. When tag is 0, I use ray trace, from the point below the current intersect point, to the direction same as the surface’s normal.
When tag is 2, the ray hit the back side of the surface, I calculate the light radiance, and send it back in result.

I create a sphere in Maya and add my shader and a point light(decay rate: linear) to it, and render it in 640*480. Set the sample number to 30 or bigger, then bugs will occur different times in different area, which drives me crazy.

I need help. Please, HELP ME!!!

Thanks to everyone who have spent time reading my question and sorry for my poor English.

//subscatter.c
#include <stdio.h>
#include <stdlib.h> /* for abs /
#include <float.h> /
for FLT_MAX */
#include <math.h>
#include <string.h>
#include <assert.h>
#include “shader.h”

struct subscatter {
int sample_num;
int mode; /* light mode: 0…2 /
int i_light; /
index of first light /
int n_light; /
number of lights /
miTag light[1]; /
list of lights */
};

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

static int tag = 0;
static miTag light_tag; /* tag of light instance */

DLLEXPORT miBoolean subscatter(
miColor *result,
miState *state,
struct subscatter *paras)
{
miVector old_state_dir;
miVector old_state_point;
void * old_state_pri;

int         m;              /* light mode: 0=all, 1=incl, 2=excl */
miTag       *light;         /* tag of light instance */
int         n_l;            /* number of light sources */
int         i_l;            /* offset of light sources */
int	sam_num;

int         light_samples;        /* # of samples taken */
miColor     color;          /* color from light source */
miColor     light_sum;            /* summed sample colors */
miVector    dir;            /* direction towards light */
miScalar    dot_nl;         /* dot prod of normal and dir */
int         n;              /* light counter */

miVector	p_x0;
miVector	normal;
miVector	watch_dir;
int		i;
miVector	p_intersect;
miColor		Li;

sam_num = *mi_eval_integer(&paras-&gt;sample_num);

if (tag == 2)	//hit the back side of the material: tag = 2
					//I still have a tag=1, but I don't leave it here
{  	      
	light_sum.r = light_sum.g = light_sum.b = 0;
	light_samples = 0;
		
	old_state_pri = state-&gt;pri;
	state-&gt;pri = 0;

	while (mi_sample_light(&color, &dir, &dot_nl, state,
                                     light_tag, &light_samples)) {
		light_sum.r += color.r;
		light_sum.g += color.g;
		light_sum.b += color.b;
	}
	if (light_samples) {
		light_sum.r /= light_samples;
		light_sum.g /= light_samples;
		light_sum.b /= light_samples;
	}

	result-&gt;r = light_sum.r;
	result-&gt;g = light_sum.g;
	result-&gt;b = light_sum.b;

	state-&gt;pri = old_state_pri;
	return(miTRUE);
}

// hit the front side of the material:  tag = 0
result-&gt;r = 0.0;
result-&gt;g = 0.0;
result-&gt;b = 0.0;

    m		= *mi_eval_integer(&paras-&gt;mode);
    n_l		= *mi_eval_integer(&paras-&gt;n_light);
    i_l		= *mi_eval_integer(&paras-&gt;i_light);
    light		=  mi_eval_tag(paras-&gt;light) + i_l;

    if (m == 1)             /* modify light list (inclusive mode) */
            mi_inclusive_lightlist(&n_l, &light, state);
    else if (m == 2)        /* modify light list (exclusive mode) */
            mi_exclusive_lightlist(&n_l, &light, state);

	normal = state-&gt;normal;
	watch_dir = state-&gt;dir;
	p_x0 = state-&gt;point;

    //Loop over all light sources 
    for (n=0; n &lt; n_l; n++, light++) 
{
	light_tag = *light;

	for (i=0; i&lt;sam_num; i++)
	{// In my shader, there is a while loop use mi_sample() 
	//		to make Monte Carlo integration.
			
	//But in debug, this for loop is enough.
	//My trouble is that the more times I trace (it means the bigger sam_num),
	//			the larger broken partition I'll have after rendering.
		state-&gt;cache = 0 ;

		old_state_dir = state-&gt;dir;
		old_state_point = state-&gt;point;

		state-&gt;dir = normal;

		p_intersect.x = p_x0.x - normal.x * 0.01;
		p_intersect.y = p_x0.y - normal.y * 0.01;
		p_intersect.z = p_x0.z - normal.z * 0.01;
		state-&gt;point = p_intersect;

		tag = 2;
		mi_trace_transparent(&Li, state);

		state-&gt;dir = old_state_dir;	
		state-&gt;point = old_state_point;
	}
	*result = Li;
}
		
tag =0;
return miTRUE;

}

//subscatter.mi
declare shader
color “subscatter” (
integer “sample_num”,
integer “mode”, # light selection mode 0…2
array light “lights”
)
version 1
apply material
end declare


#2

This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.