我有一个带有两个纹理的全屏四边形。
我想根据用户选择混合任意形状的两个纹理。
例如,四边形首先是100%texture0而texture1是透明的。
如果用户通过在四边形上拖动鼠标来选择一个区域,例如一个圆圈,那么 circle region应该将texture0和texture1都显示为半透明。
未被圆圈包围的区域仍应为texture0。
请参见示例图片,纹理简化为颜色。
目前,我已经在四边形上混合了两个纹理,但是混合区域只能是垂直切片,因为我使用了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大小相同的alpha蒙版纹理?
然后我将该纹理传递给frag着色器以检查值,如果value为0则为texture0,如果value为1则再混合texture0和texture1。
我的方法是否正确?你能指点我的样品吗?
我希望效果如OpenGL - mask with multiple textures
但我想在我的程序中动态创建蒙版纹理,我想在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中动态创建掩码纹理
答案 0 :(得分:1)
这是一种方法和样本。
为是否要混合创建布尔测试。 在我的示例中,我使用了一个以屏幕为中心的圆的方程式。
然后混合(我通过加权添加2种颜色混合)。
(注意:我在此示例中没有使用纹理坐标,因此我使用屏幕分辨率来确定圆位置。)
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;
}