OpenGL GLSL смешивает две текстуры произвольной формы

У меня полноэкранный квад с двумя текстурами.

Я хочу смешать две текстуры в произвольной форме в соответствии с выбором пользователя.

Например, сначала квад имеет 100% текстуры0, а текстура1 прозрачна.

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

Область, не окруженная кружком, должна быть текстурой0.

Пожалуйста, смотрите пример изображения, текстуры упрощены как цвета.

образ

На данный момент я добился наложения двух текстур на квад, но область наложения может быть только вертикальными срезами, потому что я использую функцию step ().

Мой фрагментный шейдер:

uniform sampler2D Texture0;
uniform sampler2D Texture1;
uniform float alpha;
uniform float leftBlend;
uniform float rightBlend;
varying vec4 oColor;
varying vec2 oTexCoord;
void main()
{
vec4 first_sample = texture2D(Texture0, oTexCoord);
vec4 second_sample = texture2D(Texture1, oTexCoord);

float stepLeft = step(leftBlend, oTexCoord.x);
float stepRight = step(rightBlend, 1.0 - oTexCoord.x);
if(stepLeft == 1.0 && stepRight == 1.0)
gl_FragColor = oColor * first_sample;
else
gl_FragColor = oColor * (first_sample * alpha + second_sample * (1.0-alpha));

if (gl_FragColor.a < 0.4)
discard;
}

Для достижения произвольной формы, я предполагаю, что мне нужно создать текстуру альфа-маски, которая имеет тот же размер, что и texture0 и texture 1?

Затем я передаю эту текстуру фрагментирующему шейдеру, чтобы проверить значения, если значение равно 0, то текстура 0, если значение равно 1, то смешать текстуры 0 и текстуры 1.

Мой подход правильный? Можете ли вы указать мне какие-либо образцы?

Я хочу эффект, такой как OpenGL — маска с несколькими текстурами

но я хочу динамически создавать текстуру маски в своей программе и реализовать смешивание в GLSL

У меня есть смешивание работы с маской текстуры черного и белого

uniform sampler2D TextureMask;
vec4 mask_sample = texture2D(TextureMask, oTexCoord);
if(mask_sample.r == 0)
gl_FragColor = first_sample;
else
gl_FragColor =  (first_sample * alpha + second_sample * (1.0-alpha));

теперь текстура маски загружается статически с изображения на диске, теперь мне просто нужно динамически создать текстуру маски в opengl

1

Решение

Вот один подход и пример.

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

Затем смешайте (я смешал путем взвешенного сложения двух цветов).

(ПРИМЕЧАНИЕ: у меня не было текстурных координат для работы в этом примере, поэтому я использовал разрешение экрана, чтобы определить положение круга).

uniform vec2 resolution;

void main( void ) {

vec2 position = gl_FragCoord.xy / resolution;

// test if we're "in" or "out" of the blended region
// lets use a circle of radius 0.5, but you can make this mroe complex and/or pass this value in from the user
bool isBlended = (position.x - 0.5) * (position.x - 0.5) +
(position.y - 0.5) * (position.y - 0.5) > 0.25;

vec4 color1 = vec4(1,0,0,1); // this could come from texture 1
vec4 color2 = vec4(0,1,0,1); // this could come from texture 2
vec4 finalColor;

if (isBlended)
{
// blend
finalColor = color1 * 0.5 + color2 * 0.5;
}
else
{
// don't blend
finalColor = color1;
}
gl_FragColor = finalColor;
}

Смотрите пример работы здесь: http://glsl.heroku.com/e#18231.0

(попытался опубликовать мой образец изображения, но мне не хватает представителя) извините: /

Обновить:

Вот еще один пример с использованием положения мыши для определения положения смешанной области.
Чтобы запустить, вставьте код в этот сайт с песочницей: https://www.shadertoy.com/new
Это должно работать с объектами любой формы, если вы правильно настроили данные мыши.

void main(void)
{
vec2 position = gl_FragCoord.xy;

// test if we're "in" or "out" of the blended region
// lets use a circle of radius 10px, but you can make this mroe complex and/or pass this value in from the user
float diffX = position.x - iMouse.x;
float diffY = position.y - iMouse.y;
bool isBlended = (diffX * diffX) + (diffY * diffY) < 100.0;

vec4 color1 = vec4(1,0,0,1); // this could come from texture 1
vec4 color2 = vec4(0,1,0,1); // this could come from texture 2
vec4 finalColor;

if (isBlended)
{
// blend
finalColor = color1 * 0.5 + color2 * 0.5;
}
else
{
// don't blend
finalColor = color1;
}
gl_FragColor = finalColor;
}
1

Другие решения