Как фрагментный шейдер может использовать значения цвета ранее визуализированного кадра?
Я учусь использовать шейдеры в OpenGL ES.
В качестве примера: вот мой фрагментный шейдер игровой площадки, который берет текущий видеокадр и делает его в градациях серого:
varying highp vec2 textureCoordinate;
uniform sampler2D videoFrame;
void main() {
highp vec4 theColor = texture2D(videoFrame, textureCoordinate);
highp float avrg = (theColor[0] + theColor[1] + theColor[2]) / 3.0;
theColor[0] = avrg; // r
theColor[1] = avrg; // g
theColor[2] = avrg; // b
gl_FragColor = theColor;
}
theColor
представляет текущий пиксель. Было бы здорово также получить доступ к предыдущему пикселю по этой же координате.
Ради любопытства я хотел бы добавить или умножить цвет текущего пикселя на цвет пикселя в предыдущем кадре рендеринга.
Как я могу сохранить предыдущие пиксели и передать их фрагментному шейдеру, чтобы что-то с ними сделать?
Примечание: это OpenGL ES 2.0 на iPhone.
2 ответа
Вам нужно визуализировать предыдущий кадр в текстуру, используя объект Framebuffer (FBO), затем вы можете прочитать эту текстуру в своем фрагментном шейдере.
Точечная внутренняя функция, на которую ссылается Дэймон, является реализацией кода математического точечного произведения. Я не очень хорошо знаком с OpenGL, поэтому я не уверен, каков точный вызов функции, но математически точечный продукт выглядит так:
Учитывая vector a
и vector b
, 'dot' product a 'dot' b
дает скалярный результат c
:
c = a.x * b.x + a.y * b.y + a.z * b.z
Большинство современных графических устройств (и, в этом отношении, процессоры) способны выполнять операции такого рода за один проход. В вашем конкретном случае вы можете легко вычислить среднее значение с помощью точечного произведения, например, так:
highp vec4 = (1/3, 1/3, 1/3, 0) //or zero
Я всегда получаю 4-й компонент в однородных векторах и матрицах по какой-то причине.
highp float avg = theColor DOT vec4
Это умножит каждый компонент цвета на 1/3
(и 4-й компонент на 0), а затем сложите их вместе.