#android #opengl-es #camera #fragment-shader
Вопрос:
Я хочу реализовать размытие заднего плана для селфи-камеры.
У меня есть шейдер фрагментов размытия
precision mediump float;
uniform sampler2D uSampler;
uniform float uBlur;
uniform float uRadius;
varying vec2 vTextureCoord;
void main() {
vec3 sum = vec3(0);
if (uBlur > 0.0) {
for (float i = -uBlur; i < uBlur; i ) {
for (float j = -uBlur; j < uBlur; j ) {
sum = texture2D(uSampler, vTextureCoord vec2(i, j) * (uRadius / uBlur)).rgb / pow(uBlur * 2.0, 2.0);
}
}
} else {
sum = texture2D(uSampler, vTextureCoord).rgb;
}
gl_FragColor = vec4(sum, 1.0);
}
Также у меня есть массив, который указывает, где мне нужно поместить эффект размытия.
Моя идея состоит в том, чтобы каким-то образом передать массив шейдеру фрагментов и пропустить координаты, которые не должны быть размыты.
Есть ли какой-нибудь способ сделать это или есть какой-то другой способ, которому я должен следовать?
UPD0: Маска генерируется динамически несколько раз в секунду. Данные маски, содержащиеся в com.google.mlkit.vision.segmentation.SegmentationMask
классе, — у него есть ByteBuffer
с width
и heigh
внутри. Я попытался создать растровое изображение с Bitmap.createBitmap(maskColorsFromByteBuffer(mask), maskWidth, maskHeight, Config.ARGB_8888)
помощью и
private int[] maskColorsFromByteBuffer(ByteBuffer byteBuffer) {
@ColorInt int[] colors = new int[maskWidth * maskHeight];
for (int i = 0; i < maskWidth * maskHeight; i ) {
float backgroundLikelihood = 1 - byteBuffer.getFloat();
if (backgroundLikelihood > 0.9) {
colors[i] = Color.argb(128, 51, 112, 69);
} else if (backgroundLikelihood > 0.2) {
// Linear interpolation to make sure when backgroundLikelihood is 0.2, the alpha is 0 and
// when backgroundLikelihood is 0.9, the alpha is 128.
// 0.5 to round the float value to the nearest int.
int alpha = (int) (182.9 * backgroundLikelihood - 36.6 0.5);
colors[i] = Color.argb(alpha, 51, 112, 69);
}
}
return colors;
}
После создания растрового изображения я попытался нарисовать его с помощью ImageObjectFilterRender — насколько я вижу, этот класс генерирует текстуру из растрового изображения.
Комментарии:
1. Почему бы не сохранить маску в текстуре?
2. Как это должно работать? Маска-это динамическая вещь, которая меняется примерно 4 раза в течение секунды. Я попытался построить из него растровое изображение и использовать
ImageObjectFilterRender
класс отсюда github.com/pedroSG94/rtmp-rtsp-stream-client-java , но он слишком сильно отстает3. «Маска-это динамичная вещь, которая меняется примерно 4 раза» — это новая информация. Однако это ничего не меняет. Обычный способ сделать это-с помощью текстуры, UB или SSBO. Как вы генерируете данные маски? Можете ли вы отобразить его в текстуру.
4. Пожалуйста, смотрите обновление 0 в описании.
5. Я понимаю. Поэтому загрузите данные маски (
color
) в текстуру. Создайте текстуру сglTexImage2D
помощью (один раз) и обновите данные изображения сglTexSubImage2D
помощью (после изменения маски).