Click on the filename to display or download the file.
chrome_ramp.mi
declare shader
color "chrome_ramp" ()
version 1
apply environment, texture
end declare
chrome_ramp.c
#include "shader.h"
#include "miaux.h"
#define RAMPSIZE 1024
typedef struct {
int r_size, g_size, b_size;
miScalar r[RAMPSIZE];
miScalar g[RAMPSIZE];
miScalar b[RAMPSIZE];
} channel_ramp_table;
static channel_ramp_table *ramp;
DLLEXPORT
miBoolean chrome_ramp_init(
miState *state, void *params, miBoolean *instance_init_required)
{
int key_count = 4;
miScalar key_positions[] = {0, 0.49, 0.51, 1.0};
miScalar red[] = {0.95, 0.68, 0.95, 0.5};
miScalar green[] = {0.85, 0.6, 0.95, 0.4};
miScalar blue[] = {0.75, 0.48, 1.0, 0.9};
ramp = (channel_ramp_table*)mi_mem_allocate(sizeof(channel_ramp_table));
miaux_piecewise_sinusoid(ramp->r, RAMPSIZE, key_count, key_positions, red);
miaux_piecewise_sinusoid(ramp->g, RAMPSIZE, key_count, key_positions, green);
miaux_piecewise_sinusoid(ramp->b, RAMPSIZE, key_count, key_positions, blue);
return miTRUE;
}
DLLEXPORT
miBoolean chrome_ramp_exit(miState *state, void *params)
{
mi_mem_release(ramp);
return miTRUE;
}
DLLEXPORT
int chrome_ramp_version(void) { return 1; }
DLLEXPORT
miBoolean chrome_ramp (
miColor *result, miState *state, void *params )
{
miScalar altitude = miaux_altitude(state);
result->r = miaux_interpolated_lookup(ramp->r, RAMPSIZE, altitude);
result->g = miaux_interpolated_lookup(ramp->g, RAMPSIZE, altitude);
result->b = miaux_interpolated_lookup(ramp->b, RAMPSIZE, altitude);
return miTRUE;
}
chrome_ramp_util.c
void miaux_piecewise_sinusoid(
miScalar result[], int result_count,
int key_count, miScalar key_positions[], miScalar key_values[])
{
int key, i;
for (key = 1; key < key_count; key++) {
int start = (int)(key_positions[key-1] * result_count);
int end = (int)(key_positions[key] * result_count) - 1;
for (i = start; i <= end; i++) {
result[i] = miaux_sinusoid_fit(
i, start, end, key_values[key-1], key_values[key]);
}
}
}
double miaux_sinusoid_fit(
double v, double oldmin, double oldmax, double newmin, double newmax)
{
return miaux_fit(sin(miaux_fit(v, oldmin, oldmax, -M_PI_2, M_PI_2)),
-1, 1,
newmin, newmax);
}
double miaux_fit(
double v, double oldmin, double oldmax, double newmin, double newmax)
{
return newmin + ((v - oldmin) / (oldmax - oldmin)) * (newmax - newmin);
}
float miaux_altitude(miState *state)
{
miVector ray;
mi_vector_to_world(state, &ray, &state->dir);
mi_vector_normalize(&ray);
return miaux_fit(asin(ray.y), -M_PI_2, M_PI_2, 0.0, 1.0);
}
miScalar miaux_interpolated_lookup(miScalar lookup_table[], int table_size,
miScalar t)
{
int lower_index = (int)(t * (table_size - 1));
miScalar lower_value = lookup_table[lower_index];
int upper_index = lower_index + 1;
miScalar upper_value = lookup_table[upper_index];
return miaux_fit(
t * table_size, lower_index, upper_index, lower_value, upper_value);
}
22 April 2008 23:40:47