serpinf
> у меня несколько другая проблема:) Приложение типа Google Earth скорее, корабли
> пока не нужны, а вот 3D модели зданий, деревьев, машин... всё это будет.
> соответственно оно будет многократно перекрываться, а шейдер атмосферы, как я
> понимаю, достаточно дорогой. Единственное, что смущает - как подружить
> атмосферу с прозрачностью. В статье говорят, что они как раз применяют
> атмосферу ДО блендинга, а это означает, что при рисовании геометрии...
>
> Правка: Наверное, буду делать как в статье - сначала depth-only pass, а потом
> рендерить всё с атмосферой, потом поверх прозрачные.
Я тоже боролся с этим, когда делал облака. Решилось всё просто - берётся исходная статья, листок бумаги и ручка. Как считается скаттеринг? У нас есть функция texture4D, она даёт интенсивность света в одной точке. Она вызывется дважды - один раз для точки поверхности, второй раз для точки, в которой находится камера (если камера в космосе, берётся точка пересечения луча зрения с верхней границей атмосферы). Полная интенсивность вычисляется как конечная (eyeInScatter) минус начальная (fragInScatter), умноженная на поглощение по пути от начальной точки до конечной. Потом эта величина умножается на фазовые функции Рэлея и Ми:
vec3 inscatterGround(vec3 lightVec, vec3 Attenuation) { .... fragInScatter = texture4D( FragR, FragMu, FragMuS, nu); // поверхность eyeInScatter = texture4D( EyeR, EyeMu, EyeMuS, nu); // камера inScatter = max( eyeInScatter - Attenuation.rgbr * fragInScatter, 0.0); return inScatter.rgb * phaseR + getMie( inScatter) * phaseM; }
Цвет поверхности с учётом атмосферы получается так:
// получаем цвет поверхности из текстуры (прямой рендер) или цветового буффера (постэффект) vec3 groundColor = ... // вычисляем поглощение по пути от точки поверхности до камеры vec3 Attenuation = transmittanceAnalytic(EyeR, EyeMu, eyeVecLength); // вычисляем скаттеринг по пути от точки поверхности до камеры vec3 Inscatter = inscatterGround( light0Vec, Attenuation) * LightColor.rgb; // вычисляем финальный цвет: начальный умножить на поглощение + скаттеринг groundColor = groundColor * Attenuation + Inscatter;
После непрозрачной поверхности рисуем облака. Функция блендинга glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA), в альфа канале текстуры облаков записана прозрачность. Атмосфера учитывается таким же кодом, но появляется проблема - облака слишком яркие. Это происхоит из-за того, что скаттеринг как бы дважды учитывается - один раз при рисовании поверхности, второй раз при рисовании облаков. Чтобы исправить это, надо в шейдере облаков вычесть скаттеринг от облака до камеры, умноженный на (1 - альфа облака). Это как раз равно скаттерингу от облака до камеры, уже посчитанному при рендере поверхности. Я сейчас не помню выкладки, но они достаточно простые, используются две формулы, приведённые в коде выше.
// вычисляем финальный цвет: начальный умножить на поглощение + скаттеринг cloudColor = cloudColor * Attenuation + Inscatter; // вычитаем вклад поверхности в скаттеринг от облака до камеры groundColor -= Inscatter * (1.0 - diffColor.a);
Таким образом второй лишний вклад скаттеринга устраняется, и облака корректно блендятся с поверхностью. После всего этого нужно применить глобальный tone mapping (если применять его сразу в конце шейдера поверхности или облака, получится некорректный блендинг).
Вот обещання переделанная демка Брунетона: BrunetonAtmoFixed_Neptune.rar
Там включены все либы для работы (но кажись для компиляции нади хедеры в папку студии кинуть), так что tiff грузится нормально. Сделана загрузка/сохранение в бинарник текстур атмосферы, все параметры атмосферы вынесены в main.cpp (в его начале, там есть попытки сделать атмофсеры для других планет), переделано убогое управление - пробел сразу центрирует камеру на горе, которая торчит из полюса, так что можно заценить артефакты на закате. Если надо, вышлю текстуры для других планет (пути к которым прописаны в начале main.cpp).
UPD: Странно, но демка работает только из-под студии...
innuendo
> Neptune
> > Забил, ибо ATI не знает, что такое Cg
> знает, с ограничениями правда :)
Ну не знаю, у меня ниче не работало на ATI. Вспомни первую выложенную версию движка, 0.74. Зато в Cg есть классная вещь - сохранение и загрузка бинарников шейдеров. Хотя он и так компилит значитаельно быстрее чем glsl, но всё же загрузка бинарника быстрее компиляции. В с glsl это доступно только в GL4. Обидно, ведь glsl очень тормозно компилит, особенно на NVidia.
innuendo
> Neptune
> > Кстати, у меня Cg шейдеры на NVidia работали ощутимо быстрее,
> а это интересно, однако - что-то тут не так
Особенно это касается атмосфер. Раньше (с Cg) у меня планеты с атмофсерами раза в 1.5 быстрее рендерились, чем теперь (с glsl).
Neptune
> Раньше (с Cg) у меня планеты с атмофсерами раза в 1.5 быстрее рендерились, чем
> теперь (с glsl).
однако, странно :)
Ранее всё работало, теперь валится на precomputations. GeForce 8300, драйвер 270.61.
Neptune
> В с glsl это доступно только в GL4
С версии OpenGL 3.x.
Алмаз
> Ранее всё работало, теперь валится на precomputations. GeForce 8300, драйвер
> 270.61.
та же фигня.
Видеодрайвер был восстановлен блаблаблаблабла........
Падает демка которую я прислал? У меня нормально работет, код шейдеров не менял... У меня Mobility Radeon HD 5730
Алмаз
> Neptune
> > В с glsl это доступно только в GL4
> С версии OpenGL 3.x.
О, спасибо!
Neptune
> Падает демка которую я прислал? У меня нормально работет, код шейдеров не
> менял... У меня Mobility Radeon HD 5730
а у меня вообще всё вешается при втором запуске (Vista 64, HD5450, Catalist 10.6). Второй запуск после перезагрузки компа имеется в виду. В связи с этим вопрос: у тебя не сохранился код построения текстур, для CPU?
П.С. Однако уже спасибо, сумел посмотреть как офигительно смотрится закат с множественным скаттерингом:)
Neptune
черный экран... radeon5770
ready - что делать ?
Neptune
Падают демки с атмосферой, что твоя, что Брюнетоновские, конкретно в функции precompute() после/в цикла(е) "loop for each scattering order (line 6 in algorithm 4.1)". А вот уже демка Ocean без всяких проблем фурычит.
Алмаз
>А вот уже демка Ocean без всяких проблем фурычит
ага, потому, что там текстуры заранее посчитанные лежат:)
serpinf
> В связи с этим вопрос: у тебя не сохранился код построения текстур, для CPU?
Такового и не было. Весь расчёт на GPU.
Вот новая демка, перекомпилил - стала запускаться. Там две версии ехе-шника, atmo_precompute.exe рассчитывает текстуры атмосфер и сохраняет их в бинарник Earth.atm, atmo_load.exe не рассчитывет их, а просто загружает из этого бинарника. Запускайте сначала второй. Перед запуском первого на всякий случай сохраните бинарник куда-нибудь:) Пробел центрирует камеру на единственную "гору" на глобусе.
В начале main.cpp есть дефайн, он и задаёт поведение экзешника - рассчитывать или загружать текстуры.
#define LOAD_ATMO_MODEL 1
Бинарник *.atm вроде совместим с таковым от SpaceEngine:) Кстати, вот ещё один способ потестить брунетоновские шейдеры - сгенерить бинарники атмосферы с помощью SpaceEngine. Для этого надо удалить их из папки cache, запустить движок, и посмотреть, сгенерируются ли они. Если шейдеры не скомпилятся логе напишутся ошибки об этом. Второй способ - выбрать планету, войти в режим edit (два раза нажав *), и нажать F5 - пересоздастся модель атмосферы этой планеты.
Кстати, а стоит ли написать нвидиа об этой проблеме? Ведь раньше всё работало.
Спасибо за архив. ;)
Так это только на нвидиа проблема? У меня на ноуте ати, и всё прекрасно работает, текстуры рассчитываются. Вернусь в Питер - проверю на десктопе с GF 9800.
Так версия с загрузкой текстур из файла работает?
Neptune
> Так это только на нвидиа проблема?
п143
Тема в архиве.