【发布时间】:2017-04-24 18:15:45
【问题描述】:
我的片段着色器中有两个具有不同坐标 和 尺寸的纹理:
varying highp vec2 v_currentTextureCoords;
varying highp vec2 v_backgroundTextureCoords;
uniform sampler2D u_currentTexture;
uniform sampler2D u_backgroundTexture;
void main()
{
vec4 currentColor = texture2D(u_currentTexture, v_currentTextureCoords);
vec4 backgroundColor = texture2D(u_backgroundTexture, v_backgroundTextureCoords);
gl_FragColor = backgroundColor;
}
下面是对应的顶点着色器:
attribute vec4 a_position;
attribute vec2 a_currentTextureCoords;
attribute vec2 a_backgroundTextureCoords;
varying vec2 v_currentTextureCoords;
varying vec2 v_backgroundTextureCoords;
void main()
{
gl_Position = a_position;
v_currentTextureCoords = a_currentTextureCoords;
v_backgroundTextureCoords = a_backgroundTextureCoords;
}
那些着色器负责渲染u_currentTexture。
编辑:用我的真实应用程序(Android 应用程序)和问题更新了帖子。
正如您在上面看到的,这两个纹理是:
-
u_backgroundTexture:是视频流,全屏,大小为1080x1920 -
u_currentTexture:可以是任意图片,尺寸为469x833(较小但相同比例)。
为了简单起见,目前,我不想混合任何东西,只是在u_currentTexture的着色器程序中显示u_backgroundTexture的像素 >.
如您所见,上面带有着色器的渲染图像(左上角,不是整个图像)与背景图像相同,但按比例缩小以适应较小的矩形。 这不是我想要的。
我想显示u_currentTexture“后面”的像素(u_backgroundTexture 的像素),所以到最后,你甚至不会注意到有两个纹理。 p>
但由于纹理有不同的大小和坐标,它根本不会给出这个结果(现在,就是你在上面看到的)。
然后,在我的片段着色器中,我设法“缩放”纹理,使左上角的图像具有与背景图像相同的“缩放”:
为此,我修改了片段着色器:
varying highp vec2 v_currentTextureCoords;
varying highp vec2 v_backgroundTextureCoords;
uniform sampler2D u_currentTexture;
uniform sampler2D u_backgroundTexture;
uniform vec2 u_scaleRatio; // Notice here
void main()
{
vec4 currentColor = texture2D(u_currentTexture, v_currentTextureCoords);
vec4 backgroundColor = texture2D(u_backgroundTexture, v_backgroundTextureCoords * u_scaleRatio); // And here
gl_FragColor = backgroundColor;
}
我在我的程序中将u_scaleRatio 设置为glUniform2fv()。这些值基本上是(伪代码):
u_scaleRatio = vec2(currentTextureWidth / backgroundTextureWidth, currentTextureHeight / backgroundTextureHeight);
如您所见,它几乎可以工作了,但看起来 X 轴上有一个 偏移:在顶部 left 角的渲染图像实际上是我们在右上角看到...我找不到纠正它的方法。
如果知道纹理具有不同的大小和坐标,如何修改我的着色器以便更正此偏移?
编辑 2:
要回答下面的评论,这是一个截图
vec4 backgroundColor = texture2D(u_backgroundTexture, v_currentTextureCoords);
并与:
vec4 backgroundColor = texture2D(u_backgroundTexture, v_currentTextureCoords * u_scaleRatio);
编辑 3: 回复this answer,这里是截图:
uniform vec2 texelSize; // (1.0/windowResolution.x, 1.0/windowResolution.y)
vec2 uv = gl_FragCoord.xy * texelSize;
vec4 backgroundColor = texture2D(u_backgroundTexture, uv);
我了解您要做什么,我认为如果两个纹理的顶点位置和纹理坐标相同,那么它会起作用,但是......它们不是。你知道如何解决它吗?
【问题讨论】:
-
您可以使用不同大小的纹理发布您的结果。
-
我不认为你的片段着色器给你正确的颜色。红色和蓝色相乘的结果是黑色。
vec4(1, 0, 0, 1) * vec4(0, 0, 1, 1) = vec4(0, 0, 0, 1)您应该使用另一种混合方法,例如mix函数。 -
@eldo 我在原始帖子中添加了更多解释和屏幕截图。
-
能否提供计算
a_currentTextureCoords的代码?这可能就是失真的来源。 -
纹理实际上并没有你认为的大小。这些纹理查找函数采用标准化坐标(如果纹理为 256x256 或 16x16,则 0-1 相同)。您始终可以将坐标限制在某个范围内,然后如果坐标超出所述范围,则将纹理视为半透明。这实际上就是边界纹素(已弃用)。
标签: android opengl-es glsl fragment-shader vertex-shader