gl_FragColor = vec4 (color. 1.0):
}
12.5. Завихрения
Интересные эффекты получаются при использовании абсолютного значения функции шума. Производная функции в этом случае будет разрывной, так как функция имеет излом в точке 0 (см. рис. 5.2). Если выполнить такую операцию над функциями шума на разных частотах и сложить результаты, результат функции будет иметь перегибы и изломы. Перлин называет этот вид шума завихрение (турбулентность), так как он напоминает турбулентный поток. В природе такие потоки встречаются довольно часто, и с помощью завихрения можно имитировать, например, огонь или лаву. Двухмерный вариант такого шума показан нарис. 12.7.
![Абсолютное значение шума, или турбулентность](/images/openglorg06/openglorg06-38.png)
Рис. 12.7. Абсолютное значение шума, или турбулентность
2.5.1. Шейдер поверхности солнца
Описываемый далее эффект похож на впадины в расплавленной лаве или на поверхности солнца, и его можно получить с помощью все того же вершинного шейдера и немного измененного фрагментного шейдера. Основное его отличие в том, что каждое из значений шума масштабируется и сдвигается симметрично относительно 0, а потом вычисляется абсолютное значение. После сложения всех значений результат опять масштабируется, чтобы приблизительно помещаться в диапазон [0, 1]. В дальнейшем это значение используется для смешивания желтого и красного цветов, а результат такого смешивания показан на цветном рис. 20 (листинг 12.5). (В главе 13 будут рассмотрены некоторые способы анимации таких текстур, для того чтобы поверхность выглядела более интересно и реалистично.)
Листинг 12.5. Фрагментный шейдер поверхности солнца
varying float Lightlntensity: varying vec3 MCposition:
uniform sampler3D Noise: uniform vec3 Colorl: // (0.8. 0,7, 0.0)
uniform vec3 Color2; // (0.6. 0,1. 0.0)
uniform float NoiseScale: //1.2
void main (void)
{
vec4 noisevec = texture3D(Noise. MCposition * NoiseScale):
float intensity = abs(noisevec[0] - 0.25) + abs(noisevec[l] - 0.125) + abs(noisevec[2] - 0.0625) + abs(noisevec[3] - 0.03125):
intensity = clamp(intensity * 6.0, 0.0. 1.0): vec3 color = mix(Colorl, Color2, intensity) * Lightlntensity: gl_FragColor = vec4 (color, 1.0):
12.5.2. Мрамор
Еще одна разновидность функции шума - часть периодической функции, например синуса. Добавив значение шума к аргументу функции синуса, получим функцию колебаний с шумом. Получается нечто вроде прожилок на некоторых видах мрамора. В листинге 12.6 приведен фрагментный шейдер для создания этого эффекта. Вершинный шейдер остается все тем же, а результаты работы шейдеров показаны на цветном рис. 20.
Листинг 12.6. Фрагментный шейдер для создания эффекта мрамора
varying float Lightlntensity; varying vec3 MCposition;
uniform samp1er3D Noise; uniform vec3 MarbleColor; uniform vec3 VeinColor;
void main (void)
{
vec4 noisevec = texture3D(Noise. MCposition):
float intensity = abs(noisevec[0] - 0.25) + abs(noisevec[l] - 0.125) + abs(noisevec[2] - 0.0625) + abs(noisevec[3] - 0.03125):
float sineval = sin(MCposition.y * 6.0 + intensity * 12.0) * 0.5 + 0.5: vec3 color = mix(VeinColor. MarbleColor. sineval) * Lightlntensity; gl_FragColor = vec4 (color. 1.0):