ılǝ*_*ılǝ 2 android blending opengl-es opengl-es-2.0
如果在片段着色器中混合两个不同大小的纹理,是否可以将纹理映射到不同的坐标?
例如,如果混合以下两个图像中的纹理:

使用以下着色器:
// Vertex shader
uniform mat4 uMVPMatrix;
attribute vec4 vPosition;
attribute vec2 aTexcoord;
varying vec2 vTexcoord;
void main() {
gl_Position = uMVPMatrix * vPosition;
vTexcoord = aTexcoord;
}
// Fragment shader
uniform sampler2D uContTexSampler;
uniform sampler2D uMaskTextSampler;
varying vec2 vTexcoord;
void main() {
vec4 mask = texture2D(uMaskTextSampler, vTexcoord);
vec4 text = texture2D(uContTexSampler, vTexcoord);
gl_FragColor = vec4(text.r * mask.r), text.g * mask.r, text.b * mask.r, text.a * mask.r);
}
Run Code Online (Sandbox Code Playgroud)
(片段着色器用第二个纹理替换黑色和白色蒙版的白色空格).
由于两个纹理都使用相同的gl_Position和坐标(1.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f),因此两个纹理都映射到视图中的相同坐标:

但是,我的目标是保持原始纹理比例:

我想着色器内实现这一目标,而不是glBlendFunc和glBlendFuncSeparate,以我自己的值混合.
有没有办法在GLSL中实现这一目标?我有一种感觉,我将不同位置坐标的纹理顶点混合的方法被设计破坏了......
这确实是可能的,但您需要获得掩模纹理坐标的2D比例矢量.我建议你在CPU上计算它们并通过统一将它们发送到着色器,替代方法是按顶点甚至每个片段计算它们,但是你仍然需要将图像尺寸传递到着色器中,所以只需在CPU上进行并添加制服.
要获得该比例矢量,您需要一些简单的数学运算.你想要做的是尊重掩模比例,但要缩放它,所以2个刻度坐标中的一个是,1.0而另一个是<=1.0.这意味着您将看到整个蒙版的宽度或高度,而相反的尺寸将缩小.例如,如果您的图像大小为1.0x1.0且掩码大小为2.0x1.0,则您的缩放矢量将为(.5,1.0).
要使用它,scaleVector您只需要乘以纹理坐标:
vec4 mask = texture2D(uMaskTextSampler, vTexcoord* scaleVector);
Run Code Online (Sandbox Code Playgroud)
要计算比例矢量,请尝试以下方法:
float imageWidth;
float imageHeight;
float maskWidth;
float maskHeight;
float imageRatio = imageWidth/imageHeight;
float maskRatio = maskWidth/maskHeight;
float scaleX, scaleY;
if(imageRatio/maskRatio > 1.0f) {
//x will be 1.0
scaleX = 1.0f;
scaleY = 1.0f/(imageRatio/maskRatio);
}
else {
//y will be 1.0
scaleX = imageRatio/maskRatio;
scaleY = 1.0f;
}
Run Code Online (Sandbox Code Playgroud)
注意我没有尝试这个代码,所以你可能需要玩一下.
编辑:缩放纹理坐标修复
上面的纹理坐标比例使得蒙版纹理使用左上部分而不是中心部分.坐标必须围绕中心缩放.这意味着从中心获取原始矢量,vTexcoord-vec2(.5,.5)然后缩放此矢量并将其从中心添加回来:
vec2 fromCentre = vTexcoord-vec2(.5,.5);
vec2 scaledFromCenter = fromCenter*scaleVector;
vec2 resultCoordinate = vec2(.5,.5) + scaledFromCenter;
Run Code Online (Sandbox Code Playgroud)
你可以将它放在一行中,甚至尝试缩短它(首先在纸上做).
| 归档时间: |
|
| 查看次数: |
2238 次 |
| 最近记录: |