通过opengl中的纹理传递数组数据

Posted

技术标签:

【中文标题】通过opengl中的纹理传递数组数据【英文标题】:Passing array data through textures in opengl 【发布时间】:2020-11-08 20:03:56 【问题描述】:

所以我试图将一堆向量传递给片段着色器,显然我应该使用一维纹理来完成。但是,如果我尝试访问传递的向量,则这些值不是我所期望的。

我应该如何索引 texture() 函数?

传递纹理:

std::vector<vec3> triangles;
//triangles is already filled by this point
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_1D, texture);        
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB16F, Object::triangles.size(), 0, GL_RGB, GL_FLOAT, &Object::triangles[0]);

GLint textureLoc =  glGetUniformLocation( getId(), "triangles" );
glUniform1f(textureLoc, 0);

setUniform((int)Object::triangles.size(), "triCount");

glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//draw a rectangle from -1,-1 to 1,1

片段着色器代码:

uniform sampler1D triangles;
uniform int triCount;

struct Triangle
            vec3 a,b,c;
            vec3 normal;
;

void main()
  for(int i = 0;i < triCount;i++)//for each triangle
    Triangle triangle;
    //set the points of the triangle
    triangle.a = vec3(texture(triangles,i));
    triangle.b = vec3(texture(triangles,i++));
    triangle.c = vec3(texture(triangles,i++));
    //set the normal vector of the triangle
    triangle.normal = vec3(texture(triangles,i++));

    //then i do stuff with the current triangle and return a color 
  

该数组包含 3 个点和一组三角形的法线向量,这就是我以这种方式从纹理中读取的原因。

编辑: glGetTexImage 确认传递的纹理是正确的。

【问题讨论】:

【参考方案1】:

使用texture时,纹理坐标为[0.0, 1.0]范围内的浮点值。使用texelFetch 从具有[0, 宽度) 范围内的整体纹理坐标的纹理中查找单个Texel:

triangle.a      = texelFetch(triangles, i*4,   0).xyz;
triangle.b      = texelFetch(triangles, i*4+1, 0).xyz;
triangle.c      = texelFetch(triangles, i*4+2, 0).xyz;
triangle.normal = texelFetch(triangles, i*4+3, 0).xyz;

请注意,着色器代码中 Texel 索引的计算不正确。


或者,您可以通过将索引除以纹理的宽度来计算纹理坐标。纹理的大小可以通过textureSize获取:

float width = float(textureSize(triangles, 0));
triangle.a      = texture(triangles, (float(i*4)+0.5) / width).xyz;
triangle.b      = texture(triangles, (float(i*4)+1.5) / width).xyz;
triangle.c      = texture(triangles, (float(i*4)+2.5) / width).xyz;
triangle.normal = texture(triangles, (float(i*4)+3.5) / width).xyz;

【讨论】:

以上是关于通过opengl中的纹理传递数组数据的主要内容,如果未能解决你的问题,请参考以下文章

纹理顶点数组中的每个多边形 - OpenGL

通过 Glut 为 OpenGL 自定义纹理映射

OpenGL:将图像加载到纹理数组中

通过表面写入 CUDA 中的浮点 OpenGL 纹理

OpenGL着色器没有传递正确的纹理坐标

使用 VBO 和元素数组索引的 OpenGL 纹理