extern "C" DLLEXPORT miBoolean mib_color_spread( register miColor *result, miState *state, struct mib_color_spread *paras) { register int i, n = *mi_eval_integer(¶s->num); register miScalar r, g, b, a; register miScalar weight; miColor *input; input = mi_eval_color(¶s->input); r = input->r; g = input->g; b = input->b; a = input->a; if (n > 8) n = 8; for (i=0; i < n; i++, result++) { weight = *mi_eval_scalar(¶s->weight[i]); switch(*mi_eval_integer(¶s->mode[i])) { default: case 0: result->r = r * weight; result->g = g * weight; result->b = b * weight; result->a = a * weight; break; case 1: result->r = result->g = result->b = result->a = a * weight; break; case 2: result->r = result->g = result->b = result->a = (a + r + g)/3 * weight; break; case 3: result->r = result->g = result->b = result->a = (.299 * r + .587 * g + .114 * b) * weight; break; case 4: result->r = result->g = result->b = result->a = r * weight; break; } } return(miTRUE); }
extern "C" DLLEXPORT miBoolean MYMR_AmbientOcclusion( miColor *result , miState *state, struct MYMR_AmbientOcclusion_p *paras) { miUint samples = * mi_eval_integer(¶s->samples); miVector trace_direction; miUshort dimension = 2; int instance = 0, found=0; double amb_exp; double sample[dimension]; //Try to get samples to random places monte carlo style while (mi_sample(sample,&instance,state,dimension,&samples)){ // get the direction of the ray given the sample mi_reflection_dir_diffuse_x(&trace_direction,state,sample); if (mi_trace_probe(state, &trace_direction, &state->point)){ found++; } } printf("%d %d\n",found,samples); amb_exp = 1.0 - ((double)found/(double)samples); printf("%f\n",amb_exp); result->r = result->g = result->b = amb_exp; return miTRUE; }
DLLEXPORT void domeAFL_FOV_Stereo_init( miState *state, struct dsDomeAFL_FOV_Stereo *params, miBoolean *inst_init_req) { if (!params) { // version output mi_info(_VER_); *inst_init_req = miTRUE; } else { fov_angle = *mi_eval_scalar(¶ms->FOV_Angle); viewport_offset = *mi_eval_vector(¶ms->View_Offset); camera = *mi_eval_integer(¶ms->Camera); dome_radius = *mi_eval_scalar(¶ms->Dome_Radius); dome_tilt = *mi_eval_scalar(¶ms->Dome_Tilt); cameras_separation = *mi_eval_scalar(¶ms->Cameras_Separation); dome_tilt_compensation = *mi_eval_boolean(¶ms->Dome_Tilt_Compensation); vertical_mode = *mi_eval_boolean(¶ms->Vertical_Mode); //mi_info("II-> fov=%f,cam=%i,rad=%f,tilt=%f,sep=%f,comp=%i,vert=%i",fov_angle,camera,dome_radius,dome_tilt,cameras_separation,dome_tilt_compensation,vertical_mode); // Convert input angles from degrees to radians... fov_angle = (miScalar)(fov_angle*M_PI/180.0); dome_tilt = (miScalar)(dome_tilt*M_PI/180.0); } }
DLLEXPORT miBoolean nkPass( miColor *result, miState *state, nkPass_t *param) { /* * get parameter values. It is inefficient to do this all at the beginning of * the code. Move the assignments here to where the values are first used. * You may want to use pointers for colors and vectors. */ miInteger layerNumber = *mi_eval_integer(¶m->layerNumber); miColor color = *mi_eval_color(¶m->color); if( !mi_fb_put( state, layerNumber, &color )) printf( "Could not save framebuffer %d.\n", layerNumber ); /* * set shader results. ``+='' etc. is useful for shaders in shader * lists but other shaders may need to simply assign result variables. */ result->r += color.r; result->g += color.g; result->b += color.b; result->a += color.a; return(miTRUE); }
miBoolean contour_shader_framefade( miContour_endpoint *result, miStdInfo *info_near, miStdInfo *info_far, miState *state, Framefade_Parameters *paras) { int frame = state->camera->frame; double w1, w2; int frame1, frame2; miASSERT(frame >= 0); frame1 = *mi_eval_integer(¶s->frame1); frame2 = *mi_eval_integer(¶s->frame2); miASSERT(frame1 >= 0 && frame2 >= 0); if (frame <= frame1) { /* before frame1 */ result->color = *mi_eval_color(¶s->color1); result->width = *mi_eval_scalar(¶s->width1); } else if (frame2 <= frame) { /* after frame2 */ result->color = *mi_eval_color(¶s->color2); result->width = *mi_eval_scalar(¶s->width2); } else { /* between frame1 and frame2 */ /* Weights w1 and w2 depend on frame number */ miColor color1 = *mi_eval_color(¶s->color1); miColor color2 = *mi_eval_color(¶s->color2); miASSERT(frame1 < frame2); w1 = ((double)frame2 - frame) / (frame2 - frame1); miASSERT(0.0 <= w1 && w1 <= 1.0); w2 = 1.0 - w1; /* Mix of color1 and color2 according to weights */ result->color.r = w1 * color1.r + w2 * color2.r; result->color.g = w1 * color1.g + w2 * color2.g; result->color.b = w1 * color1.b + w2 * color2.b; result->color.a = w1 * color1.a + w2 * color2.a; /* Width depending on weights */ result->width = w1 * *mi_eval_scalar(¶s->width1) + w2 * *mi_eval_scalar(¶s->width2); } return(miTRUE); }
bool checkScreenSpace(miState *state, mrParticleGeoShader_paras *paras, miVector pos, miVector& bottomLeft, miVector& topRight) { miScalar minPixelSize = *mi_eval_scalar(¶s->minPixelSize); miScalar maxPixelSize = *mi_eval_scalar(¶s->maxPixelSize); int minSizeBehaviour = *mi_eval_integer(¶s->minSizeBehaviour); // 0 = delete, 1 = resize if(maxPixelSize <= 0.0f ) maxPixelSize = 100000000.0f; miVector screenBottomLeft = bottomLeft; miVector screenTopRight = topRight; mi_point_from_camera(state, &screenBottomLeft, &screenBottomLeft); mi_point_from_camera(state, &screenTopRight, &screenTopRight); mi_point_to_raster(state, &screenBottomLeft, &screenBottomLeft); mi_point_to_raster(state, &screenTopRight, &screenTopRight); miScalar screenDist = mi_vector_dist(&screenBottomLeft, &screenTopRight); miScalar dist = mi_vector_dist(&bottomLeft, &topRight); //mi_info("screenDist %f minPixelSize %f", screenDist, minPixelSize); // nonsense no check will be done if(minPixelSize > maxPixelSize) return true; float minClip = 0.001f; if( screenDist < minPixelSize ) { if( minSizeBehaviour == 0) return false; //mi_info("screenDist %f < minPixelSize %f", screenDist, minPixelSize); float resizeFactor = minPixelSize/screenDist; float resizeDist = dist * resizeFactor/2.0f; topRight = pos; bottomLeft = pos; topRight.x += resizeDist; topRight.y += resizeDist; bottomLeft.x -= resizeDist; bottomLeft.y -= resizeDist; return true; } if( screenDist > maxPixelSize ) { float resizeFactor = maxPixelSize/screenDist; float resizeDist = dist * resizeFactor/2.0f; topRight = pos; bottomLeft = pos; topRight.x += resizeDist; topRight.y += resizeDist; bottomLeft.x -= resizeDist; bottomLeft.y -= resizeDist; return true; } return true; }
extern "C" DLLEXPORT miBoolean mib_color_interpolate( miColor *result, miState *state, struct mib_color_interpolate *paras) { miInteger num = *mi_eval_integer(¶s->num); miScalar input; miScalar ominput; miScalar prev = 0; miScalar next = 1; int i; if (num < 1) { result->r = result->g = result->b = result->a = 0; return(miTRUE); } if (num == 1) { *result = *mi_eval_color(¶s->color[0]); return(miTRUE); } if (num > 8) num = 8; input = *mi_eval_scalar(¶s->input); if (input <= 0) { *result = *mi_eval_color(¶s->color[0]); return(miTRUE); } if (input >= 1) { *result = *mi_eval_color(¶s->color[num-1]); return(miTRUE); } for (i=0; i < num-2; i++) { next = *mi_eval_scalar(¶s->weight[i]); if (input <= next) break; prev = next; next = 1; } input = (input - prev) / (next - prev); ominput = 1 - input; if (input == 0) *result = *mi_eval_color(¶s->color[i]); else if (input == 1) *result = *mi_eval_color(¶s->color[i+1]); else { miColor *pcol = mi_eval_color(¶s->color[i]); miColor *ncol = mi_eval_color(¶s->color[i+1]); result->r = ominput * pcol->r + input * ncol->r; result->g = ominput * pcol->g + input * ncol->g; result->b = ominput * pcol->b + input * ncol->b; result->a = ominput * pcol->a + input * ncol->a; } return(miTRUE); }
extern "C" DLLEXPORT miBoolean mib_texture_filter_lookup( miColor *result, miState *state, struct mib_texture_filter_lookup *paras) { miTag tex = *mi_eval_tag(¶s->tex); miVector *coord; miUint space; miTag remap; miVector p[3], t[3]; miMatrix ST; miTexfilter ell_opt; miScalar disc_r; if (!tex) { result->r = result->g = result->b = result->a = 0; return(miFALSE); } coord = mi_eval_vector(¶s->coord); space = *mi_eval_integer(¶s->space); disc_r = *mi_eval_scalar(¶s->disc_r); if (disc_r <= 0) disc_r = DISC_R; if (state->reflection_level == 0 && mi_texture_filter_project(p, t, state, disc_r, space) && (remap = *mi_eval_tag(¶s->remap))) { mi_call_shader_x((miColor*)&t[0], miSHADER_TEXTURE, state, remap, &t[0]); mi_call_shader_x((miColor*)&t[1], miSHADER_TEXTURE, state, remap, &t[1]); mi_call_shader_x((miColor*)&t[2], miSHADER_TEXTURE, state, remap, &t[2]); if (mi_texture_filter_transform(ST, p, t)) { ell_opt.eccmax = *mi_eval_scalar(¶s->eccmax); ell_opt.max_minor = *mi_eval_scalar(¶s->maxminor); ell_opt.bilinear = *mi_eval_boolean(¶s->bilinear); ell_opt.circle_radius = CIRCLE_R; /* * when no bump-mapping is used, coord and ST[..] * are identical. for bump mapping, the projection * matrix is calculated for the current raster * position, the ellipse is translated to the * bump position */ ST[2*4+0] = coord->x; ST[2*4+1] = coord->y; if (mi_lookup_filter_color_texture(result, state, tex, &ell_opt, ST)) return(miTRUE); } } /* fallback to standard pyramid or nonfiltered texture lookup */ return(mi_lookup_color_texture(result, state, tex, coord)); }
extern "C" DLLEXPORT miBoolean mib_ray_marcher( miColor *result, miState *state, struct mrm *p) { struct mrm pe; miScalar scale; result->r = result->g = result->b = result->a = 0.0; /* * copy all parameters to a static structure to * avoid all the mi_eval_* calls in the code */ pe.s = *mi_eval_tag(&p->s); pe.distance = *mi_eval_scalar(&p->distance); pe.num = *mi_eval_integer(&p->num); pe.subdiv = *mi_eval_integer(&p->subdiv); pe.contrast = *mi_eval_color(&p->contrast); if (pe.num == 0.0) if (pe.distance > 0.0) pe.num = state->dist / pe.distance; else pe.num = 4; /* default #samples */ if (pe.num < 2) pe.num = 2; /* go! */ raymarch(result, state, &pe); /* normalize result */ scale = 1.0 / (miScalar)pe.num; result->r *= scale; result->g *= scale; result->b *= scale; result->a *= scale; return(miTRUE); }
extern "C" DLLEXPORT miBoolean mrParticleGeoShader( miTag *result, miState *state, mrParticleGeoShader_paras *paras) { mi_info("mrParticleGeoShader: Version %s", VERSION); int geometryType = *mi_eval_integer(¶s->geometryType); miScalar minPixelSize = *mi_eval_scalar(¶s->minPixelSize); miScalar maxPixelSize = *mi_eval_scalar(¶s->maxPixelSize); int i_m = *mi_eval_integer(¶s->i_particleFiles); int n_m = *mi_eval_integer(¶s->n_particleFiles); miTag *particleFiles = mi_eval_tag(paras->particleFiles) + i_m; for(int i = 0; i < n_m; i++) { if (particleFiles[i]) { std::string fileName = tag_to_string(particleFiles[i]); std::string correctedFileName = getCorrectFileName(state, paras, fileName); mi_info("reading cacheFile %s", correctedFileName.c_str()); PartioContainer pc(correctedFileName); if( geometryType == 0) { miTag particleTag = createMeshParticles(state, paras, pc); if( particleTag != miNULLTAG) miBoolean done = mi_geoshader_add_result( result, particleTag); }else{ miTag particleTag = createNativeParticles(state, paras, pc); if( particleTag != miNULLTAG) miBoolean done = mi_geoshader_add_result( result, particleTag); } } } return miTRUE; }
void point_distances3(miState *state,texture_worleynoise3d_t *param, miVector *pt, miScalar *f1, miVector *p1, miScalar *f2, miVector *p2, miScalar *f3, miVector *p3) { miScalar cube_dist = CUBE_DIST * (*mi_eval_scalar(¶m->scale)); miVector cube = point_cube3(pt,cube_dist); worley_context3 *context; mi_query(miQ_FUNC_TLS_GET, state, miNULLTAG, &context); miInteger dist_measure = *mi_eval_integer(¶m->distance_measure); *f3 = FLT_MAX; *f2 = *f3 - 1; *f1 = *f2 - 1; update_cache3(context, &cube, cube_dist); miVector *cache = context->cacheVals; for(int i=0; i < CACHE_SIZE; ++i) { miVector p = cache[i]; miScalar d = distance3(dist_measure, pt, &p); if(d < *f3) { if(d < *f2) { *f3 = *f2; *p3 = *p2; if(d < *f1) { *f2 = *f1; *p2 = *p1; *f1 = d; *p1 = p; } else { *f2 = d; *p2 = p; } } else { *f3 = d; *p3 = p; } } } }
DLLEXPORT void LatLong_Stereo_init( miState *state, struct dsLatLong_Stereo *params, miBoolean *inst_init_req) { if (!params) { // Version output mi_info(_VER_); *inst_init_req = miTRUE; } else { fov_vert_angle = *mi_eval_scalar(¶ms->FOV_Vert_Angle); fov_horiz_angle = *mi_eval_scalar(¶ms->FOV_Horiz_Angle); camera = *mi_eval_integer(¶ms->Camera); parallax_distance = *mi_eval_scalar(¶ms->Parallax_Distance); cameras_separation = *mi_eval_scalar(¶ms->Cameras_Separation); //mi_info("II-> fovV=%f,fovH=%f,cam=%i,rad=%f,sep=%f",fov_vert_angle,fov_horiz_angle,camera,parallax_distance,cameras_separation); // Convert input angles from degrees to radians... fov_vert_angle = (miScalar)(fov_vert_angle*M_PI/180.0); fov_horiz_angle = (miScalar)(fov_horiz_angle*M_PI/180.0); } }
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(¶m->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(¶m->distance_measure); miScalar scale = dist_scale(dist_measure) * (*mi_eval_scalar(¶m->scale)) * (*mi_eval_scalar(¶m->scaleX)); miBoolean jagged = *mi_eval_boolean(¶m->jagged_gap); miScalar s = 1.0; { miScalar gap_size = *mi_eval_scalar(¶m->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(¶m->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); }
extern "C" DLLEXPORT miBoolean mib_amb_occlusion( miColor *result, miState *state, struct mib_amb_occlusion_p *paras) { double sample[3], near_clip, far_clip; int counter = 0; miUint samples = *mi_eval_integer(¶s->samples); miScalar clipdist = *mi_eval_scalar(¶s->max_distance); miBoolean reflecto = *mi_eval_boolean(¶s->reflective); miBoolean ret_type = *mi_eval_integer(¶s->return_type); miTag org_env = state->environment; /* Original environ. */ miVector orig_normal, trace_dir; miScalar output = 0.0, samplesdone = 0.0; miScalar spread = *mi_eval_scalar(¶s->spread); miScalar o_m_spread = 1.0f - spread; miColor env_total; /* environment Total */ miVector norm_total; /* Used for adding up normals */ miBoolean occ_alpha = *mi_eval_boolean(¶s->occlusion_in_alpha); miScalar falloff = 1.0; miao_trace_info ti; int version = 1; /* If called as user area light source, return "no more samples" for any call beyond the first */ if (state->type == miRAY_LIGHT && state->count > 0) return (miBoolean)2; /* Figure out the call version */ mi_query(miQ_DECL_VERSION, 0, state->shader->function_decl, &version); if (version >= 2) { falloff = *mi_eval_scalar(¶s->falloff); if (falloff <= 0.0) falloff = 1.0; ti.id_inclexcl = *mi_eval_integer(¶s->id_includeexclude); ti.id_nonself = *mi_eval_integer(¶s->id_nonself); /* None of these options used, go into compatible mode */ ti.compatible = (ti.id_inclexcl == 0 && ti.id_nonself == 0 ); } else { ti.compatible = miTRUE; } /* Used for adding up environment */ env_total.r = env_total.g = env_total.b = env_total.a = 0; far_clip = near_clip = clipdist; orig_normal = state->normal; norm_total = state->normal; /* Begin by standard normal */ /* Displacement? Shadow? Makes no sense */ if (state->type == miRAY_DISPLACE || state->type == miRAY_SHADOW) { result->r = result->g = result->b = result->a = 0.0; return (miTRUE); } if (clipdist > 0.0) mi_ray_falloff(state, &near_clip, &far_clip); /* Avoid recursion: If we are designated as environment shader, we will be called with rays of type miRAY_ENVIRON, and if so we switch the environment to the global environment */ if (state->type == miRAY_ENVIRONMENT) state->environment = state->camera->environment; while (mi_sample(sample, &counter, state, 2, &samples)) { mi_reflection_dir_diffuse_x(&trace_dir, state, sample); trace_dir.x = orig_normal.x*o_m_spread + trace_dir.x*spread; trace_dir.y = orig_normal.y*o_m_spread + trace_dir.y*spread; trace_dir.z = orig_normal.z*o_m_spread + trace_dir.z*spread; mi_vector_normalize(&trace_dir); if (reflecto) { miVector ref; miScalar nd = state->dot_nd; /* Calculate the reflection direction */ state->normal = trace_dir; state->dot_nd = mi_vector_dot( &state->dir, &state->normal); /* Bugfix: mi_reflection_dir(&ref, state); for some reason gives me the wrong result, doing it "manually" works better */ ref = state->dir; ref.x -= state->normal.x*state->dot_nd*2.0f; ref.y -= state->normal.y*state->dot_nd*2.0f; ref.z -= state->normal.z*state->dot_nd*2.0f; state->normal = orig_normal; state->dot_nd = nd; trace_dir = ref; } if (mi_vector_dot(&trace_dir, &state->normal_geom) < 0.0) continue; output += 1.0; /* Add one */ samplesdone += 1.0; if (state->options->shadow && miao_trace_the_ray(state, &trace_dir, &state->point, &ti)) { /* we hit something */ if (clipdist == 0.0) output -= 1.0; else if (state->child->dist < clipdist) { miScalar f = pow(state->child->dist / clipdist, (double) falloff); output -= (1.0 - f); norm_total.x += trace_dir.x * f; norm_total.y += trace_dir.y * f; norm_total.z += trace_dir.z * f; switch (ret_type) { case 1: { /* Environment sampling */ miColor envsample; mi_trace_environment(&envsample, state, &trace_dir); env_total.r += envsample.r * f; env_total.g += envsample.g * f; env_total.b += envsample.b * f; } break; default: /* Most return types need no special stuff */ break; } } } else { /* We hit nothing */ norm_total.x += trace_dir.x; norm_total.y += trace_dir.y; norm_total.z += trace_dir.z; switch (ret_type) { case 1: /* Environment sampling */ { miColor envsample; mi_trace_environment(&envsample, state, &trace_dir); env_total.r += envsample.r; env_total.g += envsample.g; env_total.b += envsample.b; } break; default: /* Most return types need no special treatment */ break; } } } if (clipdist > 0.0) mi_ray_falloff(state, &near_clip, &far_clip); if (samplesdone <= 0.0) /* No samples? */ samplesdone = 1.0; /* 1.0 to not to break divisons below */ switch (ret_type) { case -1: /* Plain old occlusion with untouched normal*/ case 0: /* Plain old occlusion */ default: /* (also the default for out-of-bounds values) */ { miVector old_dir = state->dir; output /= (miScalar) samplesdone; if (ret_type == -1) norm_total = state->normal; else { mi_vector_normalize(&norm_total); /* If the color shaders use the normal.... give them the bent one... */ state->normal = norm_total; state->dir = norm_total; } if (output == 0.0) *result = *mi_eval_color(¶s->dark); else if (output >= 1.0) *result = *mi_eval_color(¶s->bright); else { miColor bright, dark; bright = *mi_eval_color(¶s->bright); dark = *mi_eval_color(¶s->dark); result->r = bright.r * output + dark.r * (1.0 - output); result->g = bright.g * output + dark.g * (1.0 - output); result->b = bright.b * output + dark.b * (1.0 - output); if (occ_alpha) result->a = output; else result->a = bright.a * output + dark.a * (1.0 - output); } state->normal = orig_normal; state->dir = old_dir; } break; case 1: /* Sampled environment */ { miColor br = *mi_eval_color(¶s->bright), drk = *mi_eval_color(¶s->dark); result->r = drk.r + (br.r * env_total.r / samplesdone); result->g = drk.g + (br.g * env_total.g / samplesdone); result->b = drk.b + (br.b * env_total.b / samplesdone); if (occ_alpha) result->a = output/ samplesdone; else result->a = 1.0; } break; case 2: /* Bent normals, world */ case 3: /* Bent normals, camera */ case 4: /* Bent normals, object */ { miVector retn; /* returned Normal */ mi_vector_normalize(&norm_total); if (ret_type == 2) mi_normal_to_world(state, &retn, &norm_total); if (ret_type == 3) mi_normal_to_camera(state, &retn, &norm_total); if (ret_type == 4) mi_normal_to_object(state, &retn, &norm_total); result->r = (retn.x + 1.0) / 2.0; result->g = (retn.y + 1.0) / 2.0; result->b = (retn.z + 1.0) / 2.0; if (occ_alpha) result->a = output/ samplesdone; else result->a = 1.0; } break; } if (state->type == miRAY_LIGHT) { /* Are we a light shader? */ int type; mi_query(miQ_FUNC_CALLTYPE, state, 0, &type); /* Make sure we are called as light shader */ if (type == miSHADER_LIGHT) { /* If so, move ourselves to above the point... */ state->org.x = state->point.x + state->normal.x; state->org.y = state->point.y + state->normal.y; state->org.z = state->point.z + state->normal.z; /* ...and set dot_nd to 1.0 to illuminate fully */ state->dot_nd = 1.0; } } /* Reset environment, if we changed it */ state->environment = org_env; return miTRUE; }
miBoolean contour_contrast_function_levels( miStdInfo *info1, miStdInfo *info2, int level, miState *state, Contour_Contrast_Parameters_Levels *paras) { /* * No contour if level too near or too deep */ if (level < *mi_eval_integer(¶s->min_level) || *mi_eval_integer(¶s->max_level) < level) return(miFALSE); /* * Contour if one ray intersected an object and one ray hit background */ miASSERT(info1 || info2); if ((info1 == NULL) != (info2 == NULL)) return(miTRUE); miASSERT(info1 && info2); /* * Contour if sufficiently large difference in depth */ if (fabs(info1->point.z - info2->point.z) > *mi_eval_scalar(¶s->zdelta)) return(miTRUE); /* * Contour if sufficiently large change in normal */ if (mi_vector_dot(&info1->normal, &info2->normal) < cos(*mi_eval_scalar(¶s->ndelta) * M_PI/180.0)) return(miTRUE); /* * Contour if different materials (if specified) */ if (*mi_eval_boolean(¶s->diff_mat) && info1->material != info2->material) return(miTRUE); /* * Contour if different object labels (if specified) */ if (*mi_eval_boolean(¶s->diff_label) && info1->label != info2->label) return(miTRUE); /* * Contour if different triangle indices (if specified) */ if (*mi_eval_boolean(¶s->diff_index) && (info1->index != info2->index || mi_vector_dot(&info1->normal_geom, &info2->normal_geom) < 0.9999)) return(miTRUE); /* * Contour if color contrast (if specified) --- doesn't work properly * on objects behind semitransparent objects since there can be a * contrast on the semistransparent object caused by the color * difference behind it (as a result, it looks like the contrast * shader of the semitransparent object is used on the object behind * even though it isn't). */ if (*mi_eval_boolean(¶s->contrast) && (fabs(info1->color.r-info2->color.r) > state->options->contrast.r || fabs(info1->color.g-info2->color.g) > state->options->contrast.g || fabs(info1->color.b-info2->color.b) > state->options->contrast.b)) return(miTRUE); /* * No contour otherwise */ return(miFALSE); }
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(¶s->environment); miColor normal = *mi_eval_color(¶s->bent_normals); miColor occlus = *mi_eval_color(¶s->occlusion); miScalar strength = *mi_eval_scalar(¶s->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(¶s->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(¶s->coordinate_space)) { case 0: /* No change */ bent_i = bent; break; case 1: /* By matrix */ mi_vector_transform(&bent_i, &bent, mi_eval_transform(¶s->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(¶s->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(¶s->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; }
extern "C" DLLEXPORT miBoolean mib_color_mix( miColor *result, miState *state, struct mib_color_mix *paras) { register int i, n = *mi_eval_integer(¶s->num), mode; register miScalar r, g, b, a; register miScalar w, weight; register miColor *color; miColor *base = mi_eval_color(¶s->base); r = base->r; g = base->g; b = base->b; a = base->a; if (n > 8) n = 8; for (i=0; i < n; i++) { mode = *mi_eval_integer(¶s->mode [i]); color = mi_eval_color (¶s->color [i]); weight = *mi_eval_scalar (¶s->weight[i]); switch(mode) { default: case 0: w = ( 1 - color->a ) * weight; r = r * w + color->r * weight; g = g * w + color->g * weight; b = b * w + color->b * weight; a = a * w + color->a * weight; break; case 1: w = 1 - weight; r = r * w + color->r * weight; g = g * w + color->g * weight; b = b * w + color->b * weight; a = a * w + color->a * weight; break; case 2: case 3: r += color->r * weight; g += color->g * weight; b += color->b * weight; a += color->a * weight; break; case 4: case 5: r *= color->r * weight; g *= color->g * weight; b *= color->b * weight; a *= color->a * weight; break; case 6: r *= weight; g *= weight; b *= weight; a = color->a; break; } if (mode == 3 || mode == 5) { if (r < 0) r = 0; else if (r > 1) r = 1; if (g < 0) g = 0; else if (g > 1) g = 1; if (b < 0) b = 0; else if (b > 1) b = 1; if (a < 0) a = 0; else if (a > 1) a = 1; } } result->r = r; result->g = g; result->b = b; result->a = a; return(miTRUE); }
miTag createNativeParticles(miState *state, mrParticleGeoShader_paras *paras, PartioContainer& pc) { miBoolean useAllAttributes = *mi_eval_boolean(¶s->useAllAttributes); int i_a = *mi_eval_integer(¶s->i_attributeNames); int n_a = *mi_eval_integer(¶s->n_attributeNames); miTag *attributeNames = mi_eval_tag(paras->attributeNames) + i_a; if( !pc.good()) { mi_info("createNativeParticles: Invalid patioContainer"); return miNULLTAG; } Partio::ParticleAttribute posAttr; if(!pc.assertAttribute("position", posAttr)) { mi_info("createNativeParticles: partioContainer: no position."); return miNULLTAG; } Partio::ParticleAttribute idAttr; bool hasId = true; if(!pc.assertAttribute("id", idAttr)) hasId = false; Partio::ParticleAttribute radiusPPAttr; bool hasRadiusPP = true; if(!pc.assertAttribute("radiusPP", radiusPPAttr)) hasRadiusPP = false; Partio::ParticleAttribute radiusRGBPPAttr; bool hasRgbPP = true; if(!pc.assertAttribute("rgbPP", radiusRGBPPAttr)) hasRgbPP = false; mi_info("Creating native particles for cache file: %s", pc.cacheFileName.c_str()); // declare the map as a 3-dimensional map mi_api_map_decl_dim ( 3 ); // the 'mi_api_map_field_decl' function takes four arguments: // // miParam_type type: basic type of the field (miTYPE_SCALAR or miTYPE_INTEGER) // char *name : field name // int dimension : dimension of the field, 0 for single values, > 0 for arrays // miBoolean global : miTRUE if it's a global field, miFALSE otherwise // add the "extension" field as a single float miParameter *extension_field = mi_api_map_field_decl ( miTYPE_SCALAR , mi_mem_strdup("extension") , 0 , miFALSE ); // add the "color" field as an array of 1 color miParameter *color_field = mi_api_map_field_decl ( miTYPE_SCALAR , mi_mem_strdup("color") , 3 , miFALSE ); // append the color to the extension for the declaration // (this also frees the 'color_field' miParameter) miParameter *fields_list = mi_api_map_field_append ( extension_field , color_field ); // create a declaration called "particles" with the given fields list // (this also frees the 'fields_list' miParameter) miMap_decl *decl = mi_api_map_decl_begin ( mi_mem_strdup("particles") , fields_list ); // ends the declaration mi_api_map_decl_end (); // Then you begin the object definition, by calling 'mi_api_object_begin' and possibly setting the object flags as needed, then you begin the definition of the particle object as a set of spheres: miObject *obj = mi_api_object_begin(mi_mem_strdup("TestParticleObject")); obj->visible = miTRUE; // begin the definition of the particle object as spheres mi_api_map_obj_type ( mi_mem_strdup("spheres") ); // the 'mi_api_map_obj_field' function takes 2 arguments: // // char *field_name : name of the field to map ("radius" in this case) // char *mapped_name : name of the mapped field ("extension" in this case) // maps the "radius" field to the "extension" field of this map mi_api_map_obj_field( mi_mem_strdup("radius") , mi_mem_strdup("extension") ); // begins the definition of the map, taking "particles" as the declaration name mi_api_map_begin ( mi_mem_strdup("particles") ); int num_elements = pc.data->numParticles(); for ( int i = 0 ; i < num_elements ; ++i ) { float pos[3]; pc.getPosition(i, pos); // define the position of this element mi_api_map_value ( miTYPE_SCALAR , &pos[0] ); mi_api_map_value ( miTYPE_SCALAR , &pos[1] ); mi_api_map_value ( miTYPE_SCALAR , &pos[2] ); mi_api_map_field_end (); float radiusPP = 1.0f; if( hasRadiusPP ) radiusPP = *pc.data->data<float>(radiusPPAttr, i); radiusPP = rnd() * 0.3; // define the radius of this element mi_api_map_value ( miTYPE_SCALAR , &radiusPP ); mi_api_map_field_end (); // // compute the color in r, g and b // miScalar r = rnd(); miScalar g = rnd(); miScalar b = rnd(); miColor col; col.r = r; col.g = g; col.b = b; // define the color of this element //mi_api_map_value ( miTYPE_COLOR , &col ); mi_api_map_value ( miTYPE_SCALAR , &r ); mi_api_map_value ( miTYPE_SCALAR , &g ); mi_api_map_value ( miTYPE_SCALAR , &b ); mi_api_map_field_end(); // end the definition of this element mi_api_map_element_end (); } // terminates the map definition and stores it in the DB miTag map_tag = mi_api_map_end ( 0 ); miTag particleObjTag = mi_api_object_end(); miEchoOptions options; memset(&options, 0, sizeof(options)); options.ascii_output = true; options.compressed_output = false; options.dont_echo = false; mi_info("Writing to geodump.mi file."); const char *mode = "w"; FILE *fh = fopen("C:/daten/3dprojects/Maya2013/scenes/geodump.mi", mode); //mi_geoshader_echo_tag(fh, particleObjTag, &options); fclose(fh); mi::shader::Access_map map(map_tag); mi::shader::Map_status status; mi::shader::Map_declaration map_declaration(map, &status); mi::shader::Map_field_id field_id = map_declaration->get_field_id(mi_mem_strdup("color"), &status); if (!status.is_ok()) { mi_error("problems getting field_id for color"); return particleObjTag; } mi_info("Field id %d", field_id); mi::shader::Map_field_type f_type; miUint f_dimension; bool f_is_global; status = map_declaration->get_field_info(field_id, f_type, f_dimension, f_is_global); if (!status.is_ok()) { mi_error("problems get_field_info"); return particleObjTag; } mi_info("Field type %d is global %d", f_type.type(), f_is_global); return particleObjTag; }
extern "C" DLLEXPORT miBoolean mib_illum_cooktorr( miColor *result, miState *state, struct mib_illum_cooktorr *paras) { miColor *ambi, *diff, *spec; miScalar roughness; /* average microfacet slope */ miColor *ior; /* index of refraction */ miTag *light; /* tag of light instance */ int n_l; /* number of light sources */ int i_l; /* offset of light sources */ int mode; /* light mode: 0=all, 1=incl, 2=excl */ int samples; /* # of samples taken */ miColor color; /* color from light source */ miColor sum; /* summed sample colors */ miVector dir; /* direction towards light */ miScalar dot_nl; /* dot prod of normal and dir */ miColor refl; /* specular reflection color */ /* check for illegal calls */ if (state->type == miRAY_SHADOW || state->type == miRAY_DISPLACE ) { return(miFALSE); } ambi = mi_eval_color(¶s->ambient); diff = mi_eval_color(¶s->diffuse); spec = mi_eval_color(¶s->specular); roughness = *mi_eval_scalar(¶s->roughness); ior = mi_eval_color(¶s->ior); *result = *mi_eval_color(¶s->ambience); /* ambient term */ result->r *= ambi->r; result->g *= ambi->g; result->b *= ambi->b; mode = *mi_eval_integer(¶s->mode); n_l = *mi_eval_integer(¶s->n_light); i_l = *mi_eval_integer(¶s->i_light); light = mi_eval_tag(paras->light) + i_l; if (mode == 1) /* modify light list (inclusive mode) */ mi_inclusive_lightlist(&n_l, &light, state); else if (mode == 2) /* modify light list (exclusive mode) */ mi_exclusive_lightlist(&n_l, &light, state); else if (mode == 4) { n_l = 0; light = 0; } /* Loop over all light sources */ if (mode == 4 || n_l) { for (mi::shader::LightIterator iter(state, light, n_l); !iter.at_end(); ++iter) { sum.r = sum.g = sum.b = 0; samples = 0; while (iter->sample()) { iter->get_contribution(&color); dot_nl = iter->get_dot_nl(); /* Diffuse reflection: Lambert's cosine law */ sum.r += dot_nl * diff->r * color.r; sum.g += dot_nl * diff->g * color.g; sum.b += dot_nl * diff->b * color.b; /* Specular reflection: Cook-Torrance reflection */ dir = iter->get_direction(); if (mi_cooktorr_specular(&refl, &state->dir, &dir, &state->normal, roughness, ior)) { sum.r += refl.r * spec->r * color.r; sum.g += refl.g * spec->g * color.g; sum.b += refl.b * spec->b * color.b; } } samples = iter->get_number_of_samples(); if (samples) { result->r += sum.r / samples; result->g += sum.g / samples; result->b += sum.b / samples; } } } /* add contribution from indirect illumination (caustics) */ mi_compute_irradiance(&color, state); result->r += color.r * diff->r; result->g += color.g * diff->g; result->b += color.b * diff->b; result->a = 1; return(miTRUE); }
extern "C" DLLEXPORT miBoolean mib_illum_lambert( miColor *result, miState *state, struct mib_illum_lambert *paras) { miColor *ambi, *diff; miTag *light; /* tag of light instance */ int n_l; /* number of light sources */ int i_l; /* offset of light sources */ int m; /* light mode: 0=all, 1=incl, 2=excl */ int samples; /* # of samples taken */ miColor color; /* color from light source */ miColor sum; /* summed sample colors */ miScalar dot_nl; /* dot prod of normal and dir*/ /* check for illegal calls */ if (state->type == miRAY_SHADOW || state->type == miRAY_DISPLACE ) { return(miFALSE); } ambi = mi_eval_color(¶s->ambient); diff = mi_eval_color(¶s->diffuse); m = *mi_eval_integer(¶s->mode); *result = *mi_eval_color(¶s->ambience); /* ambient term */ result->r *= ambi->r; result->g *= ambi->g; result->b *= ambi->b; n_l = *mi_eval_integer(¶s->n_light); i_l = *mi_eval_integer(¶s->i_light); light = mi_eval_tag(paras->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); else if (m == 4) { n_l = 0; light = 0; } /* Loop over all light sources */ if (m==4 || n_l) { for (mi::shader::LightIterator iter(state, light, n_l); !iter.at_end(); ++iter) { sum.r = sum.g = sum.b = 0; while (iter->sample()) { dot_nl = iter->get_dot_nl(); iter->get_contribution(&color); sum.r += dot_nl * diff->r * color.r; sum.g += dot_nl * diff->g * color.g; sum.b += dot_nl * diff->b * color.b; } samples = iter->get_number_of_samples(); if (samples) { result->r += sum.r / samples; result->g += sum.g / samples; result->b += sum.b / samples; } } } /* add contribution from indirect illumination (caustics) */ mi_compute_irradiance(&color, state); result->r += color.r * diff->r; result->g += color.g * diff->g; result->b += color.b * diff->b; result->a = 1; return(miTRUE); }