
В начале декабря этого года мы с Лялей посетили конференцию CG Event в Holiday Inn в Сокольниках, посвящённую компьютерной графике.
http://www.cgevent.ru/Очевидно, что нацелены мы были на Blender Block, но постарались попасть и на другие выступления и в первую очередь на Pixar. Выступление Константина Промохова было посвящено созданию анимационного фильма «Храбрая сердцем». По ходу выступления он затронул множество технологических тонкостей и в частности тему использования процедурных текстур.

Суть проблемы в том, что сцены очень большие. Желание сделать окружение еще более живим и детальным требует многократного увеличения ресурсов. И в этом случае процедурные текстуры дают возможность не хранить геометрию и другие данные на жестоком диске, а производить вычисления на лету.
Собственно Константин дал ссылку на такой ресурс
http://iquilezles.org/live/index.htm , и часть материала с этого ресурса вошла в его презентацию.
formulanimations :: creating simple cloverНо теперь, в связи с выходом версии Blender 2.65 мы тоже имеем возможность писать собственные шейдеры. Вот пример создания клевера, о котором рассказывал в своем выступлении Константин Промохов, но переработанный под Blender/Cycles с помощью Open Shading Language для Cycles.
Во вложении лежит blend файл с этим примером.
Вот короткое описание, что и как получилось. Итак создадим текстовый блок, внесем туда код шейдера, создадим в редакторе нодов узел Scripts и укажем наш текстовый блок в качестве источника кода.

Далее будут показаны изменения в коде шейдера и как они повлияли на результат визуализации.
#include <stdosl.h>
shader simple_clover(
output float Factor = 0.5
)
{
point p = P;
float r = sqrt(dot(p,p));
float f = r;
Factor = f;
}
float dot (vector A, vector B) - встроенная функция OSL, возвращает скалятное произведение двух весторов (или нормалей), то есть AB=AxBx+AyBy+AzCz.

#include <stdosl.h>
shader simple_clover(
output color Factor = 0.5
)
{
point p = P;
float r = sqrt(dot(p,p));
float f = 0.0;
if(r<0.5) f = 1.0;
Factor = mix(color(1,1,1),color(0,1,0),f);
}
type mix (type x, type y, type alpha) или
type mix (type x, type y, float alpha) - функция линейного смешивая: x*(1-a)+y*(a)

#include <stdosl.h>
shader simple_clover(
output color Factor = 0.5
)
{
point p = P;
float r = sqrt(dot(p,p));
float a = atan2(p[1],p[0]);
float s = 0.5 + 0.5*sin(3*a);
float t = 0.15+ 0.35*pow(s,0.3);
float f = 0.0;
if(r<t) f = 1.0;
Factor = mix(color(1,1,1),color(0,1,0),f);
}
type atan2 (type y, type x) - жуткое дело, арктангенс, расчитывает угол.
type pow (type x, type y) или
type pow (type x, float y) - функция возведения в степень

#include <stdosl.h>
shader simple_clover(
output color Factor = 0.5
)
{
point p = P;
float r = sqrt(dot(p,p));
float a = atan2(p[1],p[0]);
float s = 0.5 + 0.5*sin(3*a);
float t = 0.15 + 0.35*pow(s,0.3);
t += 0.1*pow(0.5+0.5*cos(6*a),0.5);
float f = 0.0;
if(r<t) f = 1.0;
Factor = mix(color(1,1,1),color(0,1,0),f);
}

#include <stdosl.h>
shader simple_clover(
output color Factor = 0.5
)
{
point p = P;
float r = sqrt(dot(p,p));
float a = atan2(p[1],p[0]);
float s = 0.5 + 0.5*sin(3*a);
float t = 0.15 + 0.35*pow(s,0.3);
t += 0.1*pow(0.5+0.5*cos(6*a),0.5);
float f = 0.0;
float h = r/t;
if(h<1.0) f = 1.0;
Factor = mix(color(1,1,1),(0.1+0.9*h)*color(0,1,0),f);
}

А вот тест заполения. Для создания ланшафта задействавано 64 фейса.

... или так ...

... во вложении есть файл с примером заполнения клеверного поля ...
