GLSL停止渲染

时间:2016-10-29 06:48:49

标签: c++ opengl glsl

我想写一个签名的距离解释。为此,我正在创建一个体素网100 * 100 * 100(如果它工作,大小会增加)。 现在我的计划是将点云加载到1d纹理中:

glEnable(GL_TEXTURE_1D);
glGenTextures(1, &_texture);
glBindTexture(GL_TEXTURE_1D, _texture);

glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, pc->pc.size(), 0, GL_RGBA, GL_FLOAT, &pc->pc.front());

glBindTexture(GL_TEXTURE_1D, 0);

' PC'只是一个包含结构Vector的向量的类,它只有浮点数x,y,z,w。

比我想要渲染洞100x100x100网格,所以每个体素并迭代通过该纹理的所有点,计算到我当前体素的距离并将该距离存储在新纹理中(1000x1000)。目前我正在创建的这个纹理只保留颜色贵重物品,它存储红色和绿色组件中的距离,蓝色设置为1.0。 所以我可以在屏幕上看到结果。

现在我的问题是,当我的点云中有大约50万个点时,似乎在几个体素(小于50 000)之后停止渲染。我的猜测是,如果它需要很长时间,它会停止并只是将它所拥有的缓冲区拉出来。 我不知道是否会出现这种情况,但是如果是这样的话,我是否可以做些什么来对付它,或者我可以做些什么来使这个程序更好/更快。

我的第二个猜测是,我不会考虑使用1D纹理。但是有更好的方法来传递大量数据吗?因为我肯定需要几十万点数据。

我不知道如果我显示完整的片段着色器是否有帮助,所以我只会显示一些部分,我认为这对于该问题很重要:

通过所有点的距离计算和迭代:

for(int i = 0; i < points; ++i){
        vec4 texInfo = texture(textureImg, getTextCoord(i));
        vec4 pos = position;
        pos.z /= rows*rows;
        vec4 distVector = texInfo-pos;
        float dist = sqrt(distVector.x*distVector.x + distVector.y*distVector.y + distVector.z*distVector.z);
        if(dist < minDist){
            minDist = dist;
        }
    }

函数getTexCoord:

float getTextCoord(float a)
{
    return (a * 2.0f + 1.0f) / (2.0f * points);
}

*编辑:

vec4 newPos = vec4(makeCoord(position.x+Col())-1,
                   makeCoord(position.y+Row())-1,
                   0,
                   1.0);

float makeCoord(float a){
return (a/rows)*2;
}

int Col(){
float a = mod(position.z,rows);
return int(a);
}

int Row()
{
    float a = position.z/rows;
    return int(a);
}

1 个答案:

答案 0 :(得分:1)

  1. 你绝对不应该循环遍历片段着色器中的所有点,因为它每帧计算N次(其中N等于像素数),这实际上给你O(N 2 < / sup>)计算复杂性。
  2. 所有纹理都限制了每个维度可容纳的数据量。这里有两个最重要的值是GL_MAX_TEXTURE_SIZE和GL_MAX_3D_TEXTURE_SIZE。如official docs中所述,

      

    纹理大小基于GL实现有限制。对于1D和2D纹理(以及使用类似维度的任何纹理类型,如立方体贴图),任一维度的最大大小为GL_MAX_TEXTURE_SIZE。对于数组纹理,最大数组长度为GL_MAX_ARRAY_TEXTURE_LAYERS。对于3D纹理,尺寸不能大于GL_MAX_3D_TEXTURE_SIZE。

         

    在这些限制范围内,纹理的大小可以是任何值。但是,建议您坚持使用纹理大小的2的幂,除非您非常需要使用任意大小。

    列出了最典型的值herehere

  3. 如果您真的必须在frag着色器中使用大量数据,请考虑具有已知2维度和GL_NEAREST / GL_REPEAT坐标的2D或3D纹理。这将使您能够计算2D纹理坐标,只需将源偏移乘以预先计算的1 /宽度值(Y坐标;其余的定义小于1个纹素,并且可以在GL_NEAREST存在时安全地忽略)并将其用作-is for X coord(GL_REPEAT保证只使用其余部分)。我个人在需要将128 MB数据传递给GLSL 1.20着色器时实现了这种方法。

  4. 如果您定位的是最近足够的OpenGL(≥3.0),您也可以使用buffer textures

  5. 最后,但并非最不重要。您不能通过标准IEEE浮点数传递大于2 24 的整数精度值。