miScalar worleynoise3d_val(miState *state,texture_worleynoise3d_t *param) {
  miScalar f1, f2, f3;
  miVector p1, p2, p3;
  
  // ways to get the current point:
  // state->tex_list[0]; // yields good results only in the x and y coordinate
  // state->point // usable for 3D, but problematic for getting a smooth 2D texture as x,y and z all have to be somehow incorporated in the 2D vector to use
  // state->tex // does not yield usable results / seems to be constant
	// 
	// instead, we just take an u and v value explicitly; they would usually be provided by a 2D placement node.
	
	// note: getting current values must always be wrapped in mi_eval... calls!
	miVector pt;
	miScalar *m = mi_eval_transform(&param->matrix);
	mi_point_transform(&pt,&state->point,m);
	
  point_distances3(state,param,&pt,&f1,&p1,&f2,&p2,&f3,&p3);
  
  miInteger dist_measure = *mi_eval_integer(&param->distance_measure);
  
  miScalar scale = dist_scale(dist_measure) * (*mi_eval_scalar(&param->scale)) * (*mi_eval_scalar(&param->scaleX));
	miBoolean jagged = *mi_eval_boolean(&param->jagged_gap);
  
  miScalar s = 1.0;
  {
    miScalar gap_size = *mi_eval_scalar(&param->gap_size);
    
    miVector ptX = pt;
		
		// jagged edges. useful for broken earth crusts
		if(jagged) {
			miVector seed = pt;	 mi_vector_mul(&seed,3 / scale);
			miScalar jaggingX = (mi_unoise_3d(&seed) - 0.5) * scale * 0.2;
			ptX.x += jaggingX; seed.x += 1000;
			miScalar jaggingY = (mi_unoise_3d(&seed) - 0.5) * scale * 0.2;
			ptX.y += jaggingY; seed.y += 1000;
			miScalar jaggingZ = (mi_unoise_3d(&seed) - 0.5) * scale * 0.2;
			ptX.z += jaggingZ;
		}
		
    miScalar f1X, f2X, f3X;
    miVector p1X, p2X, p3X;
    
    point_distances3(state,param,&ptX,&f1X,&p1X,&f2X,&p2X,&f3X,&p3X);
     
    // based on code from "Advanced Renderman"
    // this leads to gaps of equal width, in contrast to just simple thresholding of f2 - f1.
    miScalar scaleFactor = (distance3(dist_measure, &p1X, &p2X) * scale) / (f1X + f2X);
    
    // FIXME: there may be some adjustment needed for distance measures that are not just dist_linear
    if(gap_size * scaleFactor > f2X - f1X) //  on left side
      s = -1.0;
  }
  
  {
    f1 /= scale;
    f2 /= scale;
    f3 /= scale;
  }
  
  miScalar dist = 0.0;
  {
    miInteger dist_mode = *mi_eval_integer(&param->distance_mode);
    switch(dist_mode) {
      case DIST_F1: dist = f1; break;
      case DIST_F2_M_F1: dist = f2 - f1; break;
      case DIST_F1_P_F2: dist = (2 * f1 + f2) / 3; break;
      case DIST_F3_M_F2_M_F1: dist = (2 * f3 - f2 - f1) / 2; break;
      case DIST_F1_P_F2_P_F3: dist = (0.5 * f1 + 0.33 * f2 + (1 - 0.5 - 0.33) * f3); break;
      default: ;
    }
  }
  
   return s * scaling_function(dist);
}
Beispiel #2
0
extern "C" DLLEXPORT miBoolean mib_bent_normal_env(
	miColor     *result,
	miState     *state,
	struct mib_bent_normal_env_p *paras)
{
	miTag  original_env = state->environment;
	miTag  environment  = *mi_eval_tag(&paras->environment);
	miColor   normal    = *mi_eval_color(&paras->bent_normals);
	miColor   occlus    = *mi_eval_color(&paras->occlusion);
	miScalar  strength  = *mi_eval_scalar(&paras->strength);
	miColor   color;      /* Work color */
	miVector  bent;       /* Bent normals */
	miVector  bent_i;     /* Bent normals in internal space */
	miUint	  samples;    /* # of samples */

	/* Displace or light - makes no sense */
	if (state->type == miRAY_DISPLACE || state->type == miRAY_LIGHT)
	    return miFALSE;

	if (strength == 0.0) {
	    result->r = result->g = result->b = 0.0;
	    result->a = 1.0;
	    return miTRUE;
	}

	color.r = color.b = color.g = 0.0;

	/* Does occlusion live in "alpha" component of bn data? */
	if (*mi_eval_boolean(&paras->occlusion_in_alpha))
	    strength *= normal.a;
    
	bent.x = (normal.r * 2.0) - 1.0;
	bent.y = (normal.g * 2.0) - 1.0;
	bent.z = (normal.b * 2.0) - 1.0;

	mi_vector_normalize(&bent);

	/* The different coordinate spaces */
	switch(*mi_eval_integer(&paras->coordinate_space)) {
		case 0: /* No change */
			bent_i = bent;
			break;
		case 1: /* By matrix */
			mi_vector_transform(&bent_i,
				&bent,
				mi_eval_transform(&paras->matrix));
			break;
		case 2: /* World */
			mi_normal_from_world(state, &bent_i, &bent);
			break;
		case 3: /* Camera */
			mi_normal_from_camera(state, &bent_i, &bent);
			break;
		case 4: /* Object */
			mi_normal_from_object(state, &bent_i, &bent);
			break;
	}
    
	samples = *mi_eval_integer(&paras->env_samples);

	/* Temporarily override the environment */
	if (environment)
	    state->environment = environment;

	if (samples <= 1) {
		/* Single sampling */		      
		mi_trace_environment(&color, state, &bent_i);
	} else {
		/* Multisampling */
		double	 sample[3];
		int	 counter = 0;
		miScalar spread  = *mi_eval_scalar(&paras->samples_spread);
		miColor  work_color;

		/* Clear color */
		color.r = color.g = color.b = 0.0;
			
		while (mi_sample(sample, &counter, state, 3, &samples)) {
			miVector trace_dir;
			trace_dir.x = bent_i.x + (sample[0] - 0.5) * spread;
			trace_dir.y = bent_i.y + (sample[1] - 0.5) * spread;
			trace_dir.z = bent_i.z + (sample[2] - 0.5) * spread;
			
			mi_vector_normalize(&trace_dir);

			mi_trace_environment(&work_color, state, &trace_dir);
			color.r += work_color.r;
			color.g += work_color.g;
			color.b += work_color.b;
		}

		color.r /= samples;
		color.g /= samples;
		color.b /= samples;
	}

	/* Reset original environment */
	state->environment = original_env;

	result->r = color.r * occlus.r * strength;
	result->g = color.g * occlus.g * strength;
	result->b = color.b * occlus.b * strength;
	result->a = 1.0;

	return miTRUE;
}