Shader chrome_ramp

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