在 glsl 着色器中将矩阵作为纹理访问

Posted

技术标签:

【中文标题】在 glsl 着色器中将矩阵作为纹理访问【英文标题】:Accessing matrix as texture in glsl shader 【发布时间】:2017-05-26 14:51:11 【问题描述】:

我有一个矩阵,它有 149 行和 210 列。我想将它发送到着色器进行一些计算。矩阵的值在 9-128 之间。我使用以下方法将其绑定到纹理:

m_GLTextureNNZ = new QOpenGLTexture(QOpenGLTexture::Target::Target2DArray);
m_GLTextureNNZ->create();
m_GLTextureNNZ->bind(indx);
m_GLTextureNNZ->setMinificationFilter(QOpenGLTexture::Nearest); 
m_GLTextureNNZ->setMagnificationFilter(QOpenGLTexture::Nearest);
m_GLTextureNNZ->setLayers(1);
m_GLTextureNNZ->setFormat(QOpenGLTexture::R8U);
m_GLTextureNNZ->setSize(m_sizeNZ2DCoeff_r,m_sizeNZ2DCoeff_c,1);
m_GLTextureNNZ->setWrapMode(QOpenGLTexture::ClampToEdge);
m_GLTextureNNZ->allocateStorage(QOpenGLTexture::Red, QOpenGLTexture::UInt8);

m_GLTextureNNZ->setData(0, 0, QOpenGLTexture::Red, QOpenGLTexture::UInt8, m_NNZ.data());

在着色器中,我想访问此纹理的特定行和列:

uniform usampler2DArray NNZ;
vec3 getTexCoord(ivec2 indx, ivec3 tsize )
 
  // ivec3 size = textureSize()
  return vec3( (indx.x+0.5)/tsize.x , (indx.y+0.5)/tsize.y , tsize.z);
 
 .
 .
 .
 ivec3 patchedTexSize = textureSize(NNZ,0);
 vec3 texCoord = getTexCoord( ivec2(0,0),  ivec3(patchedTexSize.xy,0));

 uint iNNZ =  texture(NNZ, texCoord).r;

所以基于我的矩阵 (0,0) 应该有一个值 1。但是我没有得到这个值。有什么我遗漏的吗?

编辑:所以我测试了全零矩阵和从纹理查找中获得的值,无论 texcoords 是什么,都是 2^8-1。

【问题讨论】:

为什么你的 2D 矩阵用 3D 寻址? @BDL 为了测试,我现在只使用一个矩阵,但我可以将这个矩阵的 128 个作为数组。 您的texcoord.z 似乎是错误的,因为textureSize.z 将是最大层索引加一。除此之外,我不明白你为什么还要走规范化的texcoords路线,而不是直接使用texelFetch @derhass 我更正了 texcoord.z 并将其替换为 0。我仍然得到奇怪的值。我在我的问题中添加了一个关于值的外观的编辑。我试过 texelFetch,结果是一样的。 【参考方案1】:

问题是我的数据是int,我试图创建一个无符号位纹理。所以我将我的数据转换为uint8_t 并且它可以工作。另外,我需要添加glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 以确保像素对齐正确。

【讨论】:

以上是关于在 glsl 着色器中将矩阵作为纹理访问的主要内容,如果未能解决你的问题,请参考以下文章

在GLSL ES中的片段着色器上旋转纹理

OpenGL、GLSL 片段着色器无法读取 Sampler2D 纹理

为啥我的着色器中的 GLSL 纹理坐标不是线性的?

WebGL-Shader入门(2.着色器语言GLSL ES矢量和矩阵的访问与运算)

如何在着色器之后读取像素?

GLSL将颜色数据从片段着色器发送到顶点着色器似乎总是等于0