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

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

int noiseSDTexSize - 128: GLuint noise3DTexName - 0; GLubyte *noise3DTexPtr:
void make3DNoiseTexture(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 * noise3DTexSize * 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[03 = ni[l] = 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: ni[l] += incj)
{
inck = 1.0 / (noise3DTexSize / frequency);

for (k = 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]).


⇐ Предыдущая| |Следующая ⇒