Режим наложения Photoshop на OpenGL ES без шейдеров
Вопрос
Мне нужно имитировать режимы наложения Photoshop ("умножение", "экран" и т.д.) В моем коде OpenGL ES 1.1 (без шейдеры).
Есть несколько документов о том, как это сделать с HLSL:
- http://www.nathanm.com/photoshop-blending-math / (архив)
- http://mouaif.wordpress.com/2009/01/05/photoshop-math-with-glsl-shaders/
Мне нужен хотя бы рабочий экранный режим.
Есть ли какие-либо реализации в фиксированном конвейере, на которые я мог бы обратить внимание?
Решение
Большинство режимов наложения photoshop основаны на режимах смешивания Портера-Даффа.
Для этого требуется, чтобы все ваши изображения (текстуры, renderbuffer) находились в предварительно умноженном цветовом пространстве.Обычно это делается путем умножения всех значений пикселей на альфа-значение перед сохранением их в текстуре.Например.полностью прозрачный пиксель будет выглядеть как черный в предварительно не умноженном цветовом пространстве.Если вы не знакомы с этим цветовым пространством, потратьте час или два на чтение о нем в Интернете.Это аккуратная и хорошая концепция, необходимая для композиций, похожих на photoshop.
В любом случае - как только у вас будут ваши изображения в этом формате, вы можете включить ЭКРАН с помощью:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR)
Полный режим УМНОЖЕНИЯ невозможен с конвейером OpenGL | ES.Если вы работаете только с полностью непрозрачными пикселями, вы можете подделать это с помощью:
glBlendFunc(GL_ZERO, GL_SRC_COLOR)
Однако результаты для прозрачных пикселей либо в вашей текстуре, либо в вашем фреймбуфере будут неверными.
Другие советы
вы должны попробовать это:
glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA)
Для меня это похоже на умножение на iPhone / OpenGL ES
Ваше лучшее место для начала - это взять копию Красная книга и прочтите главы о материалах и режимах наложения.В нем содержится очень всеобъемлющее и четкое объяснение того, как работают "классические" функции смешивания OpenGL.
Я обнаружил, что с помощью этого:
glDepthFun( GL_LEQUAL);
все это было необходимо для получения экранного эффекта, по крайней мере, это хорошо сработало в моем проекте.
Я не уверен, почему это работает, но если кто-то знает, пожалуйста, поделитесь.