Трепанация триангуляции

Привет. Раз глобус не идет в сову, возьмемся за более плоские штуки.

RNtqcYV

Когда шейдерами хотят рисовать плоские фигуры или вообще всё остальное, то в первую очередь пытаются избавиться от конвееееера видеокарты. Тут все просто: если у нас два дэ платформер и на экране всего-лишь куча спрайтов, то, как бы это обидно не звучало, логично понакидать на экран всякие билборды или понарисовать много квадов (четырехугольников) из двух треугольников, а затем текстурировать их спрайтами из атласа. Но можно вообще без треугольников.

glDrawArrays( GL_TRIANGLES, 0, 3 );

Эта абракадабра в глубинах вашего платформера означает, что вы повелеваете нарисовать много треугольников (GL_TRIANGLES), начиная с вершины номер 0, всего 3 вершины, итого один треугольник. В туториалах перед этой строчкой обычно идут загрузки массивов координат и прочие сяськи-масяськи, ахалай-махалай. Мы обойдемся без этого. Будем рисовать единственный несуществующий треугольник. Во весь экран.

Получив команду свыше, ГПУ делает вид что у нас действительно есть треугольник, у которого есть три вершины с номерами 0, 1 и 2. Это произойдет в геометрическом шейдере. Нас это не интересует, пусть как-нибудь обходится без нас, а результат нас устраивает.

Конвейер крутится и дальше по ходу нас ждет вертексный шейдер. Здесь мы можем сделать что-нибудь с координатами вершин нашего несуществующего треугольника. Например, их можно скорректировать. В нашем же случае, для начала их нужно посчитать. Ведь до сих пор их даже не существовало.

Как настоящий художник я стащил картинку:

8QgUGfH

Там где Clip Space — это ваш экран, а на все остальные части треугольника нам всё равно (их все равно не видно). В этом месте олдскульщики и творцы софтрендеров крякнут или даже квакнут: что нельзя же так впустую расходовать производительность ГПУ, ведь там тратится время, чтобы проверить границы экрана и отрезать лишнее, а затем полученный квадрат все равно автоматически разобьется на два или больше треугольников. Дудки! Это было давно, а сейчас все нормально. ГПУ умный и ленивый там, где нада. И лишнего ничего не произойдет. Там вообще ничего не произойдет: нарисуются только те пиксели, которые попадают в экран, а на остальные никто даже не посмотрит. Смотрим в шейдер:

void main()
{
    float x = -1.0 + float((gl_VertexID & 1) << 2);
    float y = -1.0 + float((gl_VertexID & 2) << 1);

    vec2 texCoord = vec2(
      (x + 1.0) * 0.5,
(y + 1.0) * 0.5 ); gl_Position = vec4(x, y, 0, 1);
}

Что здесь происходит: по номеру вершин треугольника (gl_VertexID), наш шейдер определяет их координаты (x, y). Всё. Ну, почти все...

Кроме этого мы тут же создаем текстурные координаты (texCoord) для прямоугольной текстуры размером во весь экран. В нее мы будем рисовать... что нам нада, то и будем рисовать. Там по ходу конвейера как раз пикселявый и фрагментный шейдер идет. Можно понарисовать два дэ спрайтов, а можно три дэ рейтрейсингом сделать или даже SDF с 3д фракталами.

  • nw2
  • 03 июля 2018, 00:09
  • 0
Blank