Эта функция предполагает существование функции noi se3, которая выдает трехмерные значения шума в диапазоне [-1, 1]. Можно попробовать использовать в своей программе реализацию этой функции на языке С от Перлина (http:// www,texturingandmodeling.com/CODE/PERLIN/PERLIN.С). Джон Кессеиич сделал в этом коде несколько изменений (добавил функцию setNoiseFrequency), обеспечивающих плавное изменение значений шума на краях массива. В этом случае при повторении тех же фрагментов (режим GL_REPEAT) переход на краях фрагментов плавный, а не резкий. Измененную версию кода можно найти на веб-сайте этой книги, ;http://3dshaders.com.

Листинг 12.1. Функция на языке С для создания трехмерной текстуры шума

int roise3DTexSize - 128:

GLuint noise3DTexName “ 0;

GLubyte *noise3DTexPtr:

void make3QNoiseTexture(void)

{

i nt f, i, j , k, i nc;

int startFrequency = 4:

int numOctaves = 4;

double ni[3]:

double inci. incj. inck:

int frequency = startFrequency:

GLubyte *ptr: double amp - 0.5;

if ({noise3DTexPtr = (GLubyte *) malloc( noise3DTexSize *

noise3DTexSize * noise30TexSize * 4)) = NULL)

{

fprintf(stderr. "Ошибка: невозможно выделить память\п"); exit(l):

}

for (f = 0. inc = 0: f < numOctaves:

++f. frequency *= 2, ++inc, amp *- 0.5)

{

setNoiseFrequency(frequency): ptr = noise3DTexPtr: ni[0] = ni[1] - ni[2] = 0;

inci = 1.0 / (noise3DTexSize / frequency); for (i - 0: i < noise3DTexSize; ++i. ni[0] += inci)

Листинг 12.1 (продолжение)

{

incj = 1.0 / (noise3DTexSize / frequency):

for (j = 0; j < noise3DTexSize: ++j, ni[ID += incj)

{

inck = 1.0 / (noise3DTexSize / frequency);

for (к = 0; к < noise3DTexSize: ++k. ni[2] += inck, ptr+= 4)

{

*(ptr+inc) = (GLubyte)(((noise3(ni)+1.0) * amp)*128.0):

}

}

}

}

}

Эта функция вычисляет значения шума для четырех октав и сохраняет их в трехмерной текстуре RGBA размером 128 х 128 х 128. Данный код также предполагает, что каждый компонент текстуры сохраняется как 8-битное целое значение. В первой октаве частота равна 4, а амплитуда - 0,5. В самом внутреннем цикле вызывается функция noise3 для получения значения шума, основанного на текущем значении ni. Функция noi se3 всегда возвращает значение в диапазоне [-1, 1]; добавив единицу, получим значение шума в диапазоне [0,2]. Умножив результат на значение амплитуды 0,5, получим значение в диапазоне [0, 1]. И наконец, умножив последнее значение на 128, получим целое число в диапазоне [0, 128], которое'сохраняется в красном компоненте текстуры (при доступе из шейдера это значение будет числом с плавающей запятой в диапазоне [0, 0,5]).

При каждом следующем прохождении цикла частота увеличивается вдвое, а амплитуда вдвое уменьшается. В зеленом компоненте текстуры шума будут сохраняться целые значения из диапазона [0, 64], в синем компоненте - целые значения из диапазона [0, 32], а в компоненте прозрачности - целые значения из диапазона [0, 16]. Изображения, приведенные на рис. 12.5, сформированы отдельно из каждого из этих каналов, после того как значения были приведены к нужному диапазону интенсивности (целые числа в диапазоне [0, 255] или числа с плавающей запятой в диапазоне [0, 1]).


⇐ вернуться назад | | далее ⇒