OpenGL ES Shader для создания 2D-изображений - PullRequest
6 голосов
/ 25 января 2012

Я работаю над 2D-игрой для iOS, использующей OpenGL 2.0, и мне интересно, можно ли написать шейдер, который будет выделять изображения светящимися. Все изображения являются 2D спрайтами. Примеры шейдеров, которые я видел для обрисовки, относятся к 3D-объектам, поэтому я не уверен, возможно ли это для 2D-изображений.

1 Ответ

7 голосов
/ 25 января 2012

Примете ли вы фильтр обнаружения краев (такой как Собел), производящий изображение, подобное показанному в статье Википедии , с последующим гауссовым размытием по результатам этого, чтобы смягчить края и придать емубольше свечения, а затем скомпоновать это изображение в вашей сцене?

На практике вы, вероятно, могли бы просто повторно использовать 3d-шейдеры, которые вы видели, хотя в теории вы могли бы проверять величины глубины (с некоторыми расширенными усилиями в ES), каждый, что я когда-либо видел, был просто 2-мерным эффектом на визуализированном изображении.

РЕДАКТИРОВАТЬ: при дальнейшем рассмотрении, Лапласиан может быть немного легче применить, чем Собель, потому что это можно сделать какпростые сверточные шейдеры (как описано в местах , как это ).Хотя для безопасности на мобильных устройствах вы, возможно, захотите придерживаться максимум 3х3 ядра и писать разные шейдеры для каждого эффекта, а не делать это с данными.Так, например, грубое размытие по Гауссу, записанное в длину:

void main()
{
    mediump vec4 total = vec4(0.0);
    mediump vec4 grabPixel;

    total +=        texture2D(tex2D, texCoordVarying + vec2(-1.0 / width, -1.0 / height));
    total +=        texture2D(tex2D, texCoordVarying + vec2(1.0 / width, -1.0 / height));
    total +=        texture2D(tex2D, texCoordVarying + vec2(1.0 / width, 1.0 / height));
    total +=        texture2D(tex2D, texCoordVarying + vec2(-1.0 / width, 1.0 / height));

    grabPixel =     texture2D(tex2D, texCoordVarying + vec2(0.0, -1.0 / height));
    total += grabPixel * 2.0;

    grabPixel =     texture2D(tex2D, texCoordVarying + vec2(0.0, 1.0 / height));
    total += grabPixel * 2.0;

    grabPixel =     texture2D(tex2D, texCoordVarying + vec2(-1.0 / width, 0.0));
    total += grabPixel * 2.0;

    grabPixel =     texture2D(tex2D, texCoordVarying + vec2(1.0 / width, 0.0));
    total += grabPixel * 2.0;

    grabPixel = texture2D(tex2D, texCoordVarying);
    total += grabPixel * 4.0;

    total *= 1.0 / 16.0;

    gl_FragColor = total;
}

И обнаружение края Лапласа в конечном итоге выглядит похожим, но с разными константами.

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

...