В целом ожидается, что приложения будут использовать либо встроенную, либо определенную функцию шума, чтобы шум не повторялся (как это может произойти при использовании текстуры), значения шума были более точными, а ресурсы текстур могли применяться для других целей. А если приложению нужно полностью контролировать работу функции шума и разработчиков устраивают ограничения в диапазоне входных значений текстурной функции шума, то используется текстурный метод создания шума. На данном этапе развития аппаратного обеспечения текстуры шума также работают быстрее и требуют меньше команд в шейдере.

12.4. Простой шейдер шума

Теперь посмотрим, как можно использовать разные способы создания шума в шейдерах OpenGL, которые создают интересные эффекты. Первый шейдер использует шум очень простым способом и рисует облака.

12.4.1. Настройка приложения

Шейдеры, описанные здесь и в разделах 12.5 и 12.6, требуют не очень много входных параметров. Как и всегда, нужно передавать координаты вершин, а нормаль поверхности нужна для вычислений освещения. Различные цвета и коэффициенты масштабирования передаются как uniform-переменные в различные шейдеры.

Первая строка кода шейдера выполняет поиск по трехмерной текстуре шума и получает результат, состоящий из четырех компонентов. Значение i ntensi ty вычисляется сложением четырех компонентов текстуры шума. Результат затем умножается на коэффициент масштабирования 1,5 и используется для плавного линейного перехода от белого цвета к небесно-голубому. Четыре канала текстуры шума имеют определенные значения: 0,25, 0,125, 0,0625 и 0,03125. Дополнительное значение 0,03125 добавляется к каждому среднему значению всех октав с более высокой частотой. Можно считать это «обесцвечиванием» средних значений на всех октавах с более высокой частотой, которые не включаются в вычисления (см. раздел 12.1). Умножение на коэффициент масштабирования 1,5 дает возможность «растянуть» полученное значение, чтобы выйти за рамки диапазона [0,1].

Затем на вычисленный цвет накладывается значение Light Intensity, чтобы сымитировать диффузно отражающую поверхность, освещенную одним источником. Каждый компонент цвета затем приводится к диапазону [0, 1], результат заносится во встроенную переменную gl _FragCol or со значением прозрачности 1,0 и передается для окончательной обработки. Объект, рендеринг которого выполнен данным шейдером, показан на цветном рис. 20, причем текстура на чайничке очень напоминает окончательное изображение рис. 12.6.

Листинг 12.4. Фрагментный шейдер для создания эффекта облачного неба

varying float Lightlntensity: varying vec3 MCposition:

uniform sampler30 Noise:

uniform vec3 SkyColor: // (0.0. 0,0. 0.8)

uniform vec3 CloudColor: // (0.8, 0.8. 0.8)

void main (void)

{

vec4 noisevec = texture3D(Noise. MCposition):

float intensity = ( noisevec[0] + noisevec[l] +

noisevec[2] + noisevec[3] + 0.03125) * 1.5:

vec3 color = mix(SkyColor, CloudColor. intensity) * Lightlntensity:


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