DLLEXPORT miBoolean Facade(miColor *result, miState *state, struct Facade_param *paras) { miVector tex_point; miBoolean h; h = Facade_tex_coord(state, paras->size, paras->rotation_cylindrical_on, &tex_point); /* scale for aspect ratio */ { int xres, yres; mi_texture_info(paras->si_default.texture, &xres, &yres, NULL); tex_point.x = (tex_point.x -0.5) * (miScalar) yres / (miScalar) xres + 0.5; } if ((h) && (tex_point.x >= 0) && (tex_point.x <= 1) && (tex_point.y >= 0) && (tex_point.y <= 1)) { return mi_lookup_color_texture(result, state, paras->si_default.texture, &tex_point); } else return miFALSE; }
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)); }
void lume_lookup_color_texture(miColor *fog_color, miState *state, miTag color_map_filename, miVector *map_point) { if (color_map_filename) mi_lookup_color_texture(fog_color, state, color_map_filename, map_point); else fog_color->r = fog_color->g = fog_color->b = 1; }
extern "C" DLLEXPORT miBoolean mib_texture_lookup( miColor *result, miState *state, struct mib_texture_lookup *paras) { miTag tex = *mi_eval_tag(¶s->tex); miVector *coord = mi_eval_vector(¶s->coord); if (tex && coord->x >= 0 && coord->x < 1 && coord->y >= 0 && coord->y < 1 && mi_lookup_color_texture(result, state, tex, coord)) return(miTRUE); result->r = result->g = result->b = result->a = 0; return(miFALSE); }
extern "C" DLLEXPORT miBoolean mib_texture_lookup2( miColor *result, miState *state, struct mib_texture_lookup2 *paras) { miTag tex = *mi_eval_tag(¶s->tex); miVector coord; miScalar factor = *mi_eval_scalar(¶s->factor); if (tex ) { coord.x = state->tex_list[0].x * factor; coord.y = state->tex_list[0].y * factor; mi_lookup_color_texture(result, state, tex, &coord); return(miTRUE); } result->r = result->g = result->b = result->a = 0; return(miFALSE); }
DLLEXPORT miBoolean Glare(miOutstate *state, struct Glare_param *paras) { miColor *image_in; miColor *image_out; float *glare_box; int box_size; /* size of the effect box */ double min; /* threshold for affecting distant pixels */ double threshold; /* limit at which a pixel contributes */ double scaling; /* make glare resolution independent */ lic(NULL, NAME, PROD); if ((paras->rays_on) && (paras->rays_image == NULL)) mi_fatal("[Glare] Streaks image invalid.\n"); /* set quality */ if (paras->quality_fastest_on) { min = 0.00031; threshold = 3.0; } if (paras->quality_faster_on) { min = 0.0001; threshold = 2.0; } if (paras->quality_average_on) { min = 0.000031; threshold = 1.1; } if (paras->quality_better_on) { min = 0.00001; threshold = 0.9; } if (paras->quality_best_on) { min = 0.00001; threshold = 0.5; } /* Determine scaling for resolution independence */ /* scaling = sqrt(state->xres * state->xres + state->yres * state->yres) / 720.0; */ scaling = 1; /* allocate out frame buffers */ if (paras->verbose_on) mi_info("[Glare] Allocating image buffers.\n"); image_in = mi_mem_allocate(sizeof(miColor) * state->xres * state->yres); image_out = mi_mem_allocate(sizeof(miColor) * state->xres * state->yres); { /* copy the image into our buffer, also, set the copy the alpha channel directly to the outgoing image */ int x,y; miColor color; for (x=0; x<state->xres; x++) for (y=0; y<state->yres; y++) { mi_img_get_color(state->frame_rgba, &color, x,y); image_in[x+y*state->xres] = color; image_out[x+y*state->xres].a = color.a; } } { /* Determine the size of the glare-box */ int x,y; float M,m; miColor color; M = threshold; for (x=0; x<state->xres; x++) for (y=0; y<state->yres; y++) { color = image_in[x+y*state->xres]; m = max3(color.r, color.g, color.b); if (m != m) /* is NaN */ { mi_warning(NAN_WARN,x,y); m = 0; } if ((m + 1) == m) /* is Infinity */ { mi_warning(INF_WARN,x,y); m = 0; } if (m > M) { if ((m > threshold) && (glare_object(state, paras, x,y))) { M = m; box_size = (int)(paras->spread * scaling * pow(autogamma_inverse_scalar(min) /m/K_B,1/FALL_POW)); } } } if (box_size > state->xres) box_size = state->xres; if (box_size > state->yres) box_size = state->yres; if (box_size == 0) { mi_info("[Glare] Nothing to glare.\n"); mi_mem_release(image_in); mi_mem_release(image_out); return miTRUE; } } if (paras->verbose_on) mi_info("[Glare] Allocating glare buffer (%dx%d).\n", box_size, box_size); glare_box = mi_mem_allocate(sizeof(float) * box_size * box_size * 4); { /* compute the glare_box */ int x,y; for (x = -box_size; x < box_size; x++) for (y = -box_size; y < box_size; y ++) { double f,d; miColor p; d = sqrt(x*x + y*y); if (( 0 == x )&&( 0 == y)) { if (paras->overlay_on) f = 0; else f = 1; } else { f = autogamma_scalar(K_B * pow(d/paras->spread/scaling, FALL_POW)); if (paras->rays_on) { miColor c; miVector p; p.x = 0.5 + (double) x / state->xres; p.y = 0.5 + (double) y / state->yres; mi_lookup_color_texture(&c, NULL, paras->rays_image, &p); f *= ((c.r + c.g + c.b)/3 * paras->rays_contrast + 1.0 - paras->rays_contrast); } } glare_box[(x+box_size) + (y+box_size)*box_size*2] = f; } } { /* Do glare */ int x,y; int maxb = 0; int verbose_count; miColor color; verbose_count = 10; for (x=0; x < state->xres; x++) for (y=0; y < state->yres; y++) { int bx, by; int b; miScalar c; if ((x%verbose_count == 0) && (y == 0) && (paras->verbose_on)) { mi_info("[Glare] %.1f%% complete.\n", (float) x/state->xres * 100.0); } color = image_in[x+y*state->xres]; c = max3(color.r, color.g, color.b); if (c <= threshold) b = 0; else if ((c != c) || (c == c +1)) b = 0; else if (!glare_object(state, paras, x, y)) b = 0; else { b = (int)(paras->spread * scaling * pow(autogamma_inverse_scalar(min)/c/K_B,1/FALL_POW)); if (b > box_size - 1) b = box_size -1; } for (by = -b ; by < b+1; by++) { float *gp; miColor *iop; gp = &glare_box[(-b+box_size) + (by+box_size)*box_size*2]; iop = &image_out[(x-b)+(y+by)*state->xres]; for (bx = -b ; bx < b+1; bx++, gp++, iop++) { int px, py; px = x + bx; py = y + by; if ((px >= 0) && (px < state->xres) && (py >= 0 ) && (py < state->yres)) { float f; f = *gp; iop->r += f * color.r; iop->g += f * color.g; iop->b += f * color.b; } } } } } { /* copy the image out to mi */ int x,y; miColor color; for (x=0; x<state->xres; x++) for (y=0; y<state->yres; y++) { miColor color; miScalar new_alpha; color = image_out[x+y*state->xres]; new_alpha = max3(color.r, color.b, color.g); if (new_alpha > color.a) color.a = new_alpha; mi_img_put_color(state->frame_rgba, &color, x,y); } } mi_mem_release(image_in); mi_mem_release(image_out); mi_mem_release(glare_box); lic_end(PROD); return miTRUE; }