顶点纹理获取(在顶点着色器中读取纹理)

Posted

技术标签:

【中文标题】顶点纹理获取(在顶点着色器中读取纹理)【英文标题】:Vertex texture Fetch (Texture read in vertex shader) 【发布时间】:2016-05-26 11:13:10 【问题描述】:

Opengl 和 GLSL 的新手。

我正在使用 OpenGL es 3.0我的 GLSL 版本 #version 300 es

我想在我的顶点着色器(顶点纹理获取)中的每个位置获取像素(ARGB 数据)。我已验证我的 android 平板电脑支持顶点纹理提取。

现在我将纹理(图像)和纹理坐标传递给顶点着色器 并执行

GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);

这是正确的方法还是我应该使用 GL_POINTS 。 如果我使用 GL_POINTS 如何传递纹理坐标?

您能否提供在顶点着色器中进行全像素读取 (ARGB) 的任何示例/示例代码。

附加我的顶点着色器

uniform sampler2D sTexture; 
in vec4 aTextureCoord;
out vec3 colorFactor;
vec2 vTextureCoord;
vec4 tex;
void main() 

   vTextureCoord = aTextureCoord.xy;
   tex =  texture(sTexture,vTextureCoord);
   float luminance = 0.299 * tex.r + 0.587 * tex.g + 0.114 * tex.b;
   colorFactor = vec3(1.0, 1.0, 1.0);
   gl_Position = vec4(-1.0 + (luminance * 0.00784313725), 0.0, 0.0,      1.0); 
   gl_PointSize = 1.0;
;

我传递的纹理坐标是 0.f,1.f 1.f,1.f 0.f,0.f 1.f,0.f

着色器由

触发
GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);

【问题讨论】:

【参考方案1】:

只需声明一个采样器并像往常一样对其进行采样。例如

"#version 150\n"

in vec4 position;
in vec2 texCoordinate;

uniform sampler2D texID;
uniform mat4 modelViewProjection;

void main()

    gl_Position = modelViewProjection * (position + texture(texID, texCoordinate));

这将从纹理单元texID 的位置texCoordinate 中采样一个4d 矢量,在应用模型-视图-投影矩阵之前使用它来扰动position。您绘制的几何图形类型没有区别。

【讨论】:

我已经使用 glGet 进行了验证,GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 得到了 16 “实现可以声明零顶点纹理单元”,Table 6.31 (page 274) 表示GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 的最小值是 16,而不是零。您可能会想到 ES 2.0,其中最小值为零 (Table 6.20, page 154)。 感谢您的回复 :) 我的目的是根据顶点着色器中的颜色信息计算发光直方图值,因此 color = texture(texID,texcoordinate) 会返回顶点着色器中的每个像素吗?要获得每个像素,我应该使用 GL_POINTS 吗?我对这些东西不熟悉@Tommy @genpfault 在这种情况下,我可以确认一些表面上的 ES 3 实现不符合标准。虽然你是对的,但我会编辑答案,我错了。 @vishnudinakaran 是的,我想你可以使用 GL_POINTS,源中的每个像素一个,然后将位置作为一个函数来存储它们,然后使用加法混合模式输出?也就是说,假设限制输出不会毁了你。【参考方案2】:

gl_Position = vec4(-1.0 + (亮度 * 0.00784313725), 0.0, 0.0, 1.0);

这很聪明。它不会工作,但这很聪明。

让每个人都感到困惑的是你没有告诉我们的事情。您正在使用混合计算直方图。您根据亮度计算每个片段的位置,因此您会得到很多重叠。混合只是将所有内容相加,从而生成直方图。

仅供参考:最好在你的问题中解释你实际上想要完成什么,而不是希望有人能推断出你想要做什么。

这是行不通的,因为在这种情况下您只有四个顶点。您有很多片段,但它们将根据您的 4 个顶点的插值生成。而且您不能在片段着色器中更改片段的位置。

如果你想做你想做的事,你仍然需要为你获取的每个纹素渲染一个顶点。您仍然需要使用GL_POINTS

【讨论】:

我实际上使用了来自开源项目的直方图计算,并且完全不知道它是如何工作的。无论如何,当我使用 glreadpixel 并将像素数据传递给着色器时,我得到了直方图属性并使用 GLES30.glDrawArrays(GLES30.GL_POINT, 0, #no of pixel) 触发;现在我想在顶点着色器中进行纹理读取以避免 glreadpixel ,因为你指定我需要使用 GL_POINT 。在这种情况下,我如何传递我的纹理坐标来读取顶点着色器中的整个像素。你能提供任何样本/建议。 两者之间有没有更好的方法来计算GPU中的发光直方图。

以上是关于顶点纹理获取(在顶点着色器中读取纹理)的主要内容,如果未能解决你的问题,请参考以下文章

顶点着色器 glsl qt 中的纹理映射

如何在片段着色器中找到 4 个顶点之间的插值位置?

通过顶点属性指针将颜色坐标传递到顶点着色器

将顶点保存到纹理并传递给着色器

OpenGL:只模糊纹理的一部分;可以使用顶点着色器加速吗?

一个支持纹理渲染和逐顶点颜色的着色器,还是两个专用着色器?