Android:屏幕外纹理的负值被限制为0

时间:2016-04-26 07:19:17

标签: opengl-es-2.0 fragment-shader texture-mapping texture2d off-screen

我正在使用离线渲染到2D纹理。 我的第一个着色器将输出YUV值,第二个片段着色器将从屏幕外纹理中读取YUV。 在第二个着色器中,我操纵U和V并使其在-0.5到0.5范围之间。但是一旦我尝试渲染它,这些就会被钳制到0到1(正)。我所有的负值都变为0。

发现问题在这里:

GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA,
                width, height, 0, GLES20.GL_RGBA,
                GLES20.GL_UNSIGNED_BYTE, null)

如果我使用GL_FLOAT而不是GL_UNSIGNED_BYTE,它会给我错误,因为颜色格式不匹配。 从链接中,https://www.khronos.org/opengles/sdk/docs/man/xhtml/glTexImage2D.xml看起来所有支持的格式都会限制在0-1范围内。 如何在下一个纹理中获得负值。

发现我可以使用其他图像格式,例如GL_R16F,但GLES20中的链接/中都不支持它们。

2 个答案:

答案 0 :(得分:1)

最好继续使用GL_UNSIGNED_BYTE,但只需将UV值从-1重新范围重新映射到0到1范围,然后再将其写入第一个着色器。然后在第二个着色器中读取它们之后,将从0到1范围映射到-1到1范围。

每个着色器中只有一个额外的乘法加法,可以节省大量的纹理内存/带宽。

e.g。着色器1的结尾

vShader1Output = vUVBetweenNeg1And1 * vec2(0.5, 0.5) + vec2(0.5, 0.5);

e.g。着色器2的开始

vShader2Input = vUVFromShader1Texture * vec2(2.0, 2.0) - vec2(1.0, 1.0)

答案 1 :(得分:0)

我可以通过以下更改来解决问题:

final int GL_HALF_FLOAT_OES = 0x8D61;

GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D,0,GLES20.GL_RGBA,                     宽度,高度,0,GLES20.GL_RGBA,                     GL_HALF_FLOAT_OES,null);