IronPeter
>Гм... не знаю, какой именно процессор у тебя, но на моих 2.3 гигагерцах та
>самая демка дает 750 fps (если откомпилировать IntelC, вариант от VC в полтора
128 -> 512 замедление в 16 раз (30 - 50 фпс).
Сложение гармоник можно попробовать. Думаю стоит расчитывать на 4 текстурных блока - 3 гармоники и текстура отражения.
Федор
>Может быть проще изобразить только вид блещущигося на солнце (или в свете луны,
>тоже неплохо) моря?
Сделал одну текстуру 128х128 - на тайл 16х16 метров, смотрится неплохо, вдали рябь сглаживается дальними мипами.
>Да, это так. Но таким путем, каплями сложно (в смысле: затратно) достижение
>настоящего хаоса. И все равно это будет псевдохаос.
Одна капелька на кадр (25 капель в секунду) - совсем не затратно, результат как на последнем скриншоте.
> Одна капелька на кадр (25 капель в секунду) - совсем не затратно, результат как на последнем скриншоте.
Я проверял, естессно. С каплями нужно долго ждать пока прорцесс установится. Я поэтому и написал, что затратно.
На ниленейном уравнение процесс установления распределения энергии по гармоникам происходит значительно быстрее.
Я это обясняю тем, что хотя капля конечно генерирует все гармоники (это в сущности локальный импульс), но ждать пока "вымрут" гармоники с большой энергией (а они ее теряют быстрее из-за вязкости - тоже нелинейный фактор) слишком долго.
В нелинейном же уравнении гармоники обмениваются энергией напрямую, без "отбора" вязкостью.
Федор
>Может быть проще изобразить только вид блещущигося на солнце (или в свете луны,
>тоже неплохо) моря?
>Сделал одну текстуру 128х128 - на тайл 16х16 метров, смотрится неплохо, вдали рябь сглаживается дальними мипами.
Было бы интересно посмотреть, но программа наверное тяжелая (в смысле Мб) ?
Федор
>Я имею в виду конечно случайно, по определенному закону естественно, меняющиеся
> нормали поверхности.
В таком случае, можно сделать очень быстро на GPU. См. пример Reflections Refractions from RM или ocean from FX Composer.
Извиняйте, что влезаю, речь то была про ФИЗИЧЕСКОЕ моделирование...
Просто лет 10 назад в Крыму мне прибило написать скринсэвер - лунную дорожку... Ясное дело, на машинках того времени ни про какой OpenGL для подобной задачи речи идти не могла - если память не изменяет, самое крутое, на что я мог в тот момент рассчитывать - это 486 DX2/66 - да-да, и такое было 8). Пришлось выкручиваться - основная идея отрисовки была содрана с Mars3D, а для анимации моря использовался эффект вроде огня с искорками. Получилось вполне красиво и довольно похоже на натуральное море - правда подбирать цвета и параметры этого самого огня было (мне) довольно сложно. Что до скорости - на текстуре 512х512 и на разрешении 800х600х256 цветов все это работало примерно на 25-30 фпс - правда под досом и на довольно жестоком ассемблере. Так что для имитации плещущегося моря вполне может подойти...
Artemka
Все хотел спросить у тебя одну вещь [не возражаешь, если на "ты"? :)]... В обсуждении темы о физическом моделировании воды, ты привел следующее уравнение и назвал его уравнением для мелкой воды (хотя это скорее линейная апроксимация такого):
(U/k)^2 * d2U / dt2 = d2U / dx2 + d2U / dy2
Но разве скорость волн не должна быть обратно пропорциональна глубине? Т.е., везде, где я видел это уравнение, оно представлено в другом виде (сохраняя обозначения):
d2U / dt2 = (U/k) * (d2U / dx2 + d2U / dy2)
Замечу, что нигде не видел квадрата...
В общем, очень хочется знать прав я или нет, и если нет, то может какие-нибудь интересные ссылочки подкинешь? :-)
Ты прав. Посмотрел точно у
М. А. ЛАВРЕНТЬЕВ, Б. В. ШАБАТ
ПРОБЛЕМЫ ГИДРОДИНАМИКИ и их МАТЕМАТИЧЕСКИЕ МОДЕЛИ, стр. 309
Действительно, если это уравнение упростить (с медленно меняющимся уровнем дна), то получится твое уравнение.
Когда я делал реплику в статью меня интересовала только возможность сделать уравнение нелинейным, формул перед глазами я не имел, поэтому и получился квадрат от амплитуды u.
Впрочем дальше я работал уже с уравнением
((U0+U)/k)^2 * d2U / dt2 = d2U / dx2 + d2U / dy2
Кстати величена (U/k) должна была конечно стоять в правой части, перед лапласианом. Это ведь квадрат скорости распространения волн и соответственно для цунами он пропорционален локальной глубине.
Спасибо за интересную статью. А не подскажите ли, насколько сложно моделирование волны от идущего корабля, и в каком направлении тут нужно копать?
PaulSh
> Подскажите, как в решение добавить шаг времени dT, чтобы симуляция не зависела
> от частоты кадров.
вот тут:
n->U[i+i1+3][j+j1+3]-=v*0.004f;
вместо 0.004f домножь на свой dt. где-то ещё должно быть, но я почему-то не могу найти.
Upd:
вообще IronPeter использовал достаточно странный интегратор, в который вклинить шаг по времени вообще не так-то просто. попробуй вместо этого:
p->U[i][j]=(( 2.0f-vis)*n->U[i][j]-p->U[i][j]*( 1.0f-vis)+laplas);
сделай как-то так:
v->U[i][j] += laplas * viscosity * dt; p->U[i][j] += n->U[i][j] * dt;
здесь смысл поля p меняется на "позиция узла", поле n(ранее означавшее новую позицию) заменяется на v, означающее скорость.
Короче результирующий код должен быть примерно таким:
for(i=1;i<127;i++) { for( j=1;j<127;j++) { /*2*/ vertices[i][j].coo[2]=n->U[i][j]; vertices[i][j].nor[0]=n->U[i-1][j]-n->U[i+1][j]; vertices[i][j].nor[1]=n->U[i][j-1]-n->U[i][j+1]; /*3*/ #define vis 0.005f float laplas=( n->U[i-1][j]+ n->U[i+1][j]+ n->U[i][j+1]+ n->U[i][j-1])*0.25f-n->U[i][j]; /*4*/ v->U[i][j] += laplas * viscosity * dt; //тут может быть минус, лень думать p->U[i][j] = n->U[i][j] + v->U[i][j] * dt; } } field *sw=p;p=n;n=sw;
писал в браузере, разумеется, ничего не тестировал, но должно рабтать корректно.
PaulSh
> Теперь пропал параметр вязкость, viscosity её больше не задаёт.
не задаёт, вязкозть нужно заводить отдельно:
v->U[i][j] *= exp(-dt * viscosity);
тот параметр, что я написал в этом уравнении:
v->U[i][j] += laplas * viscosity * dt;
это не вязкозть, а параметр, отвечающий за скорость распространения волн. не знаю, как его назвать, но он некоторым образом пропорционален гравитации. можешь его назвать по-другому, чтобы избежать путаницы.
> " viscosity * dt " по сути тот же dt.
очевидно, это неверно, так как в другом месте встречается просто dt без параметра(при интегрировании позиции).
ничёсе
Спасибо огромное за статью. Очень хорошая, но есть один вопрос. Здесь, насколько я понимаю для показа текстуры используется автоматическая генерация текстурных координат. Причем сферическая.
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glEnable( GL_TEXTURE_GEN_S); glEnable( GL_TEXTURE_GEN_T);
Из-за этого загружая картинку в качестве текстуры получаем какую-то ее немного выпуклую центральную часть. Если убрать эти строчки и генерировать текстурные координаты вручную, не получается такого красивого эффекта. Высота считается правильно но таких преломлений красивых нету. Как можно добиться того чтобы этот эффект работал на всей картинке, которую загружаю, в качестве текстуры. И я не совсем понимаю, почему получается так красиво именно из-за такой генерации текстурных координат. Может кто-то объяснит или что-то дельное посоветует.
Тема в архиве.