Динамическая тесселяция ландшафта (комментарии)
Это сообщение сгенерировано автоматически.
У меня толькодна просьба к оформлению - дать в начале статьи ссылку на термин Tessellation (Тесселяция)
Skyblade
Дал ссылку на предыдущую статью, думаю так будет лучше.
Прям душа радуется от нового материала, большое спасибо! :)
Ещё tessLevel от N.V есть
и Безье патчи
Ого! Красота! А то я вручную делаю патчи... получается хуже. :(
/A\
последний писк моды, можно делать опрос результата запроса в самом шейдере http://www.opengl.org/registry/specs/AMD/query_buffer_object.txt
innuendo
> Ещё tessLevel от N.V есть
Как расшифровывается? В зависимости от нормали?
> и Безье патчи
Это способ сглаживания, будет в следующей статье.
> последний писк моды, можно делать опрос результата запроса в самом шейдере
А зачем он мне, тем более у меня NV.
/A\
> > Ещё tessLevel от N.V есть
> Как расшифровывается? В зависимости от нормали?
от направления к камере - то, что перпендикулярно, то можно не сильно тесселировать, что под углом - больше
> > и Безье патчи
> Это способ сглаживания, будет в следующей статье.
это способ представления поверхности
Исправил баг для AMD карт (странно что никто не сказал, у всех NVidia?), изменен алгоритм вывода уровня тесселяции для шейдера из 6й части и поменял движение вверх/вниз на space/shift.
upd: счетчик вершин на AMD почему-то не работает...
innuendo
> от направления к камере - то, что перпендикулярно, то можно не сильно
> тесселировать, что под углом - больше
..., а что обратной стороной - отсекать. :)
Это интересно, попробую сделать.
Что-то как-то медленно работает. Первый режим даёт всего 9 кадров в секунду. Шестой - 80, но при переключении на цифру 2 детализация на расстоянии падает, и FPS тоже уменьшается до 62. Так и должно быть? У меня мой ландшафт 128x128 даёт FPS около 150.
gammaker
> Первый режим даёт всего 9 кадров в секунду. Шестой - 80
В первой части нет никакой оптимизации и выводится около 4млн вершин, в шестой все заоптимизированно и выводится где-то 200 тыщ вершин, отсюда такая разница в производительности.
> но при переключении на цифру 2 детализация на расстоянии падает, и FPS тоже уменьшается до 62.
Детализация при разном способе расчета уровня детализации отличается, я регулирую (клавиши <>) по количеству выводимых вершин.
> У меня мой ландшафт 128x128 даёт FPS около 150.
Карта высот имеет разрешение 1024х1024, сетка 128х128 используется как минимальный ЛОД.
Можешь заменить PCF сглаживание на одно чтение текстуры, производительность возростет где-то на 5-10%.
/A\
> > от направления к камере - то, что перпендикулярно, то можно не сильно
> > тесселировать, что под углом - больше
> ..., а что обратной стороной - отсекать. :)
> Это интересно, попробую сделать
и ?
Безье сплайн поверхности в студию :)
innuendo
> и ?
> Безье сплайн поверхности в студию :)
Я на прошлой неделе занят был, так что сделано мало...
Шейдеры PN и Bezier готовы, но там еще много работы, для этой статьи я использовал свои наработки вот и получилось быстро.
А пример с нормалями выложу в ближайшие 2 часа...
Еще я сделал демку с линеным буфером глубины.
Обновил примеры: Скачать
Изменения:
- карта высот 2048x2048
- изменение скорости стрелками вверх/вниз
- уровень детализации примерно одинаковый для разных техник
- добавлен шейдер тумана, включается клавишей F
- добавлена часть 7 - изменение детализации в зависимости от направления к камере. Способ этот оказался не очень: нет увеличения детализации вблизи и уменьшение вдали, отсечение по направлению плохо стыкуется с существующим отсечением. Но в примере я объединил эту технику с детализацией по расстоянию от камеры. Расчет детализации:
float Level(float dist, in vec3 norm) { float norm_to_cam = ( abs( dot( vec3( 1.0,0.0,0.0), norm ) ) + abs( dot( vec3( -1.0,0.0,0.0), norm ) ) ) * 1.25; return clamp( unDetailLevel*unGridScale*0.05/dist * ( norm_to_cam+0.35), 0.1, unMaxTessLevel ); }
Не знаю насколько это правильно, но результат получился хороший - детализация на наклонных поверхностях увеличивается, на больших дистанциях дает лучшее качество при одинаковой производительности на низком общем уровне детализации (параметр unDetailLevel).
Второй пример - эксперименты с буфером глубины.
Клавиши 1 и 2 переключает между отображением цвета и глубины.
Переключение между частями примера клавишами F1..F5...на клавише F5 мне пришлось набирать все заново ((
Далее описание частей:
1. используется обычный буфер глубины формата float32
2. используется линейный буфер глубины формата float32, получается он так:
gl_Position.z = (gl_Position.z / unFarPlane - 1.0) * gl_Position.w;
3. используется рендеринг в texture2d array, ближний буфер глубины нелинейный, дальний линейный, оба формата float32. В геометрическом шейдере идет отсечение полигонов (увеличивает производительность на 5%).
4. используется свой буфер глубины и тест в фрагментном шейдере:
layout(r32ui) coherent uniform uimage2D unDepthBuffer; ... uint new_depth = uint( gl_FragCoord.z * 0xFFFFFFFF + 0.5 ); ivec2 coord = ivec2( gl_FragCoord.xy - 0.5 ); uint last_depth = imageAtomicMin( unDepthBuffer, coord, new_depth ); if ( new_depth > last_depth ) discard;
5. с помощью функции packDouble2x32 создается double depth buffer:
layout(rg32ui) coherent uniform uimage2D unDepthBuffer; ivec2 coord = ivec2( gl_FragCoord.xy - 0.5 ); double depth = packDouble2x32( imageLoad( unDepthBuffer, coord ).rg ); if ( Input.dDepth > depth ) discard; imageStore( unDepthBuffer, coord, uvec4( unpackDouble2x32( Input.dDepth ), 0, 0) );
4 и 5 части могут не работать на AMD, но там смотреть не на что - появляются артефакты, причем в 4-ом в буфере глубины они не видны, только на цвете, а в 5-ом все плохо.
3-я часть дает лучший результат, но сильно снижается производительность, где-то в 2-3 раза.
А линейный буфер достаточно хорош, только вблизи дает искажения.
Тема в архиве.