Контурные эффекты в OpenGL

В OpenGL я могу очертить объекты, обычно рисуя объект, а затем снова рисуя его в качестве каркаса, используя буфер трафарета, чтобы исходный объект не был нарисован. Однако это приводит к очертаниям с одним сплошным цветом.

введите описание изображения здесь

На этом изображении пиксели контура существа кажутся более прозрачными, чем дальше от существа, которое они описывают. Как я могу добиться аналогичного эффекта с OpenGL?

Ответы

Ответ 1

Они не использовали каркас для этого. Я предполагаю, что это сильно связано с шейдером и требует этого:

  • Рендеринг объекта в буфер трафарета
  • Предоставление буфера трафарета с выбранным цветом при использовании размытия
  • Модель рендеринга поверх нее

Ответ 2

Я опоздал на ответ, но я пытался добиться того же и подумал, что я поделюсь решением, которое я использую.

Аналогичный эффект может быть достигнут в однократной операции с не очень сложным шейдером.

В шейдере фрагмента вы вычисляете цвет фрагмента на основе молнии и текстуры, давая вам не выделенный цвет "colorA".

Второй цвет - это цвет контура, colorB.

Вы должны получить фрагмент для вектора камеры, нормализовать его, а затем получить точечный продукт этого вектора с нормальным фрагментом.

Фрагмент к вектору камеры просто является инверсией положения фрагмента в пространстве глаза.

Цвет фрагмента:

float CameraFacingPercentage = dot(v_fragmentToCamera, v_Normal);
gl_FragColor = ColorA * CameraFacingPercentage + ColorB * (1 - FacingCameraPercentage);

Это основная идея, но вам придется поиграть, чтобы иметь более или менее цвет контура. Кроме того, вогнутые части вашей модели также будут выделены, но это также имеет место в изображении, опубликованном в вопросе.

Ответ 4

Насколько я вижу, эффект на экране короткий, и многие эффекты "края" - это не чистые края, как в комической схеме. Что в основном сделано, у вас есть один проход, вы обычно визуализируете объект, а затем проход с только геометрией (без текстур) и шейдером GLSL. В флеш-шейдере выполняется нормальная норма, а нормаль перпендикулярна вектору камеры, который вы окрашиваете объект. Затем эффект сглаживается путем включения области, близкой к идеальной перпендикуляру.

Мне нужно было бы искать точную математику, но я думаю, что если вы возьмете точечный продукт вектора камеры и нормальный, вы получите количество "перпендикулярности". Затем вы можете выполнить функцию типа exp, чтобы получить смещение в сторону 1.

Итак (без гарантии, что это правильно):

exp(dot(vec3(0, 0, 1), normal));

(Примечание: все в пространстве экрана.)