У меня полноэкранный квад с двумя текстурами.
Я хочу смешать две текстуры в произвольной форме в соответствии с выбором пользователя.
Например, сначала квад имеет 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
Вот один подход и пример.
Создайте логический тест на то, хотите ли вы смешать.
В моем примере я использую уравнение для круга с центром на экране.
Затем смешайте (я смешал путем взвешенного сложения двух цветов).
(ПРИМЕЧАНИЕ: у меня не было текстурных координат для работы в этом примере, поэтому я использовал разрешение экрана, чтобы определить положение круга).
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;
}