Mikle » 01.09.2010 (Ср) 16:26
Итак, по порядку:
Общие переменные:
NZ() - шум Перлина. Сначала планировал несколько раз менять его размер, поэтому массив динамический, но отказался от изменений, можно сделать массив статическим.
WB(1024, 384 To 768) - таблица высот волн на воде, до 1024 и 768, а не до 1023 и 767 потому, что таблица для углов пикселов.
WX(1023, 384 To 767) - таблица норамалей в направлении X, уже для самих пикселов.
WY(1023, 384 To 767) - то же для Y.
Col(1023, 767) - сюда рисуем.
CC(128, 8 ) - уменьшенный массив для образа неба для отражений.
FC - цвет нижней части неба.
SX, SY - позиция солнца.
Функции:
Lerp - линейная интерполяция между двумя RGB значениями по коэффициенту. Очень сомневаюсь, что таблицей получится сделать лучше.
Gen - генерация шума Перлина.
BN - выборка из массива шума по дробным координатам (с интерполяцией).
BC - такая же выборка из массива CC.
fCC - масштабирование картинки из массива Col в массив CC до седьмой строки. Восьмая строка повторяет седьмую. Это нужно, чтобы в отражениях не появлялась полоса цвета с противоположной стороны.
Sky - рисуем небо. Плотность облаков берём как разность двух выборок из Перлина:
BN(sx1, sy1) - BN(sx1 * 0.14 + sy1 * 0.21, sy1 * 0.14 - sx1 * 0.21)
sx1 и sy1 для первой выборки рассчитываются с учётом перспективы (плотность sx1 зависит от sy1). Для второй выборки координаты поворачиваются и масштабируются по формуле:
x2=k*x1*cos(a)+k*y1*sin(a)
y2=k*y1*cos(a)-k*x1*sin(a)
k - масштаб.
a - угол.Далее вычисляем цвет нижней части неба FC, верхней части неба c1 и облаков c2. Интерполируем c1 с цветом солнца:
c1 = Lerp(&HFFFFFF, c1, s)
и интерполируем далее с цветом облаков по плотности облаков:
Col(x, y) = Lerp(c2, c1, k)
Water - берём высоту волн из разности двух выборок шума, как брали плотность облаков, только уже обе выборки идут с масштабированием и поворотом.
Вычисляем WX и WY как разность соседних высот, только WX домножаем на поправку, имитирую уменьшение отклонения отражённого луча вдоль оси X, что превращает отражение у горизонта в вытянутые дорожки.
По полученной карте нормалей берём выборку из массива отражений и интерполируем с цветом воды &H352520, имитируя формулу Френеля.
Air - проход по полученному изображению с наложением тумана, зависящего от дальности. Коэффициент зависимости:
k1 = (1 - Abs(383.5 - y) / 384) ^ 5
В зависимости от угла относительно центра солнца вычисляем k2:
k2 = Atn((x - SX) / (y - SY)) / 6.283186 + 0.25
Вычисляем цвет тумана, интерполируя по k2 цвет FC с белым (имитация лучей от солнца), s - вспомогательный коэффициент, делающий лучи белыми близко к центру солнца (фактически на фона солнца).
Далее по k1 интерполируем полученный цвет с нашей картинкой и отображаем на форму.