/****************************************************************************** * Copyright 1986-2004 by mental images GmbH, Fasanenstr. 81, D-10623 Berlin, * Germany. All rights reserved. ****************************************************************************** * Created: 7.4.99 * Module: physics * Purpose: lens depth of field shader * * Exports: * physical_lens_dof_version * physical_lens_dof * * History: * 10.06.99: use mi_eval * * Description: *****************************************************************************/ #include #include #include static miColor black = {0.0, 0.0, 0.0, 0.0}; /* * New depth of field shader using low discrepancy sampling for the * simulation of depth of field. It does supersampling of the lens before * the ordinary oversampling. A fixed number of four samples is used. This * shader is now also in softimage.so, as soft_dof, where it replaces the * original Softimage depth of field shaders. */ struct dof { miScalar plane; /* distance to focused plane */ miScalar radius; /* size of the lens */ }; #define NO_SAMPLES 4 DLLEXPORT int physical_lens_dof_version(void) {return(1);} DLLEXPORT miBoolean physical_lens_dof( register miColor *result, register miState *state, register struct dof *paras) { miScalar plane = *mi_eval_scalar(¶s->plane); miScalar rads = *mi_eval_scalar(¶s->radius); miVector org, dir; /* original state->org, state->dir */ miVector rayorg, raydir; /* ray origin and direction */ miVector dest; double t, radius, angle; miColor average; int i; double pad[2]; miUint n; average = black; mi_point_to_camera (state, &org, &state->org); mi_vector_to_camera(state, &dir, &state->dir); t = (plane - org.z) / dir.z; dest.x = org.x + t * dir.x; dest.y = org.y + t * dir.y; dest.z = plane; i = 0; n = NO_SAMPLES; while(mi_sample(pad, &i, state, 2, &n)) { radius = rads * sqrt(pad[0]); angle = 2.0 * M_PI * pad[1]; rayorg.x = org.x + radius * cos(angle); rayorg.y = org.y + radius * sin(angle); rayorg.z = org.z; raydir.x = dest.x - rayorg.x; raydir.y = dest.y - rayorg.y; raydir.z = dest.z - rayorg.z; mi_point_from_camera (state, &rayorg, &rayorg); mi_vector_from_camera(state, &raydir, &raydir); (void)mi_trace_eye(result, state, &rayorg, &raydir); average.r += result->r; average.g += result->g; average.b += result->b; average.a += result->a; } result->r = average.r / NO_SAMPLES; result->g = average.g / NO_SAMPLES; result->b = average.b / NO_SAMPLES; result->a = average.a / NO_SAMPLES; return(miTRUE); }