#include "shader.h" #include "miaux.h" struct ground_fog_layers { miColor fog_color; miColor fog_density; miScalar fade_start; miScalar fade_end; miScalar unit_density; miScalar march_increment; miBoolean show_layers; miColor full_fog_marker; miColor partial_fog_marker; }; DLLEXPORT int ground_fog_layers_version(void) { return 1; } DLLEXPORT miBoolean ground_fog_layers ( miColor *result, miState *state, struct ground_fog_layers *params ) { miScalar fade_start = *mi_eval_scalar(¶ms->fade_start); miScalar fade_end = *mi_eval_scalar(¶ms->fade_end); miVector world_point, march_point; if (state->dist == 0.0) return miTRUE; else if (*mi_eval_boolean(¶ms->show_layers)) { miColor* full_fog_marker = mi_eval_color(¶ms->full_fog_marker); miColor* partial_fog_marker = mi_eval_color(¶ms->partial_fog_marker); mi_point_to_world(state, &world_point, &state->point); if (world_point.y < fade_start) miaux_multiply_colors(result, result, full_fog_marker); else if (world_point.y < fade_end) miaux_multiply_colors(result, result, partial_fog_marker); } else { miScalar fog_density = *mi_eval_scalar(¶ms->fog_density); miScalar march_increment = *mi_eval_scalar(¶ms->march_increment); miScalar unit_density = *mi_eval_scalar(¶ms->unit_density); miScalar accumulated_density = 0.0, distance, density_factor; for (distance = 0; distance < state->dist; distance += march_increment) { miaux_world_space_march_point(&march_point, state, distance); density_factor = miaux_fit_clamp( march_point.y, fade_start, fade_end, fog_density, 0.0); accumulated_density += density_factor * march_increment * unit_density; if (accumulated_density > 1.0) { *result = *mi_eval_color(¶ms->fog_color); return miTRUE; } } if (accumulated_density > 0.0) { miaux_blend_colors(result, result, mi_eval_color(¶ms->fog_color), 1.0 - accumulated_density); } } return miTRUE; }