Примечание: Если ваш шейдер должен возвращать не miCotor, то просто пишем тут нужный тип возвращаемого значения, например miScalar *result, или тот тип, какой вам нужен, можно использовать даже структуру.
Вторым параметром передается miState *state, это указатель на структуру, в которой хранится вся информация о точке пересечения, которая может понадобиться для просчета шейдера, например normal, point, direction, options и тд. И третьим параметром в функцию передается указатель на структуру, в которой хранятся параметры шейдера my_constant_t *paras. Имя данной функции - это и есть имя шейдера.
Помимо этих функций, в шейдере могут быть еще две другие не обязательные функции - shadername_ init() и shadername_exit().
Функция _init() выполняется всего однажды, когда шейдер вызывается первый раз. В ней можно вычислять, например, данные, которые не меняются в процессе рендера. Например, в _init функции можно создать и вычислить какие-нибудь статичные данные, которые потом использовать во всех вызовах шейдера.
Функция _exit() выполняется один раз, после того как шейдер вызывается в последний раз. В данной функции можно, например, удалять данные, созданные в _init() функции.
Итак, рассмотрим сам код функциональной части шейдера. Как видно, он очень простои.
*result = *mi_eval_color (¶s->color) ; Функция mi_eval_color() просто зачитывает параметр шейдера, в данном случае ^lor , и возвращает указатель на его значение. В зависимости от типа параметра, нужно использовать разные функции: mi_ eval_color(), mi_eval_scalar() и mi_eval_boolean(). Как видно из кода, в качестве результата используется значение, взятое из параметра шейдера, то есть как бы из GUI. Можно, например не считывать значение, а просто указать его явно, например, так:
result->r = 0.7; result->g = 0.8; result->b = 0.3; result->a = 1.0; При удачном выполнении шейдера функция должна возвращать miTRUE.
Освещение Далее мы рассмотрим, как сделать так, чтобы шейдер реагировал на свет, то есть имел диффузную составляющую. Для этого создадим в проекте новый фаил my_lambert. срр, в который впишем следующий код.
#pragma once #include <math.h>
#include "shader.h"
typedef struct {
miColor diffuse; int mode;
int i_light;
int n_light ;
miTag light[1] ;
}my_lambert_t;
extern "С"
{
DLLEXPORT int my_lambert_version (void) {return (1);}
DLLEXPORT miBoolean my_lambert (miColor *result, miState *state, my_lambert_t *paras)
{
miTag *light;
int n_l, i_l, mode, n, samples;
miColor color, sum;
miColor*diff;
miVector dir ;
miScalar dot_nl;
result->r = result->g = resulfc->b = result->a = 0; diff = mi_eval color(*paras->di£fuse); mode = *mi_eval_integer (¶s->mode) ;
n_l = *mi_eval_integer (¶s->n_light);