在WebGL中使用GLSL着色器中的数组

3
我正在尝试发送一个值的数组到我的片元着色器- 该着色器从纹理中读取值,并根据当前被纹理读取的值,我想从数组中检索一个值-
我能够使用int(u.r)将值(u.r)转换为整数,但是当我实际将其放入数组索引中以查找该值时,它会说该整数不是常量,因此我无法使用它...
错误:0:75:'[]':索引表达式必须是常量-
有没有更好的方法将值的数组发送到着色器?
以下是一些代码-正如您所看到的,“tab”数组是我主要关注的内容。
    <script id="shader-fs" type="x-shader/x-fragment">


#ifdef GL_ES

precision highp float;

#endif

  uniform sampler2D uTexSamp;

uniform sampler2D uTabSamp;
  uniform float dt;
  uniform float dte;
  uniform float dth2;
  uniform float a;
  uniform float nb;
  uniform float m;
  uniform float eps;
    uniform float weee;

 uniform float tab[100];


    //uniform float temp;

  uniform int fframes;
  uniform vec2 vStimCoord;
  varying vec2 vTexCoord;

  const float d = 0.001953125; // 1./512.

void main(void) {

   vec4 t = texture2D(uTexSamp, vTexCoord);
   float u = t.r,  v = t.g,  u2 = t.b,  v2 = t.a;


    //const mediump int arrindex = floor(u*10 + u2);
    //float sigvaluetab = tab[arrindex];

    u += u2/255.;   v += v2/255.;

   //u += u2 * 0.003921568627451;
   v += v2 * 0.003921568627451;

   //Scaling factors
   v = v*1.2;
   u = u*4.;


   float temp =  (1.0 / (exp(2.0 * (u-3.0)) + 1.0)); // (1-tanh(u-3)) * 0.5



    //const mediump int utoint;
    //utoint = int(u);
    //for(int index = 0; index< 50; index++)

    int u2toint;
    u2toint = int(u2);

  //  int arrindex = utoint*10 + u2toint;
    float sigmoid = tab[u2toint];//(tab[5] + 1.);
    //float sigmoid= temp;//tab[arrindex];

   float hfunc   = sigmoid * u * u;
   float ffunc   = -u +(a - pow(v*nb,m))*hfunc ;

   float gfunc = -v;
   if (u  > 1.0) {   //u-1.0 > 0.0
       gfunc += 1.4990;
   } 

... MORE STUFF UNDER, BUT THIS IS THE IDEA


1
我觉得有必要指出,OpenGL ES 2.0规范并不要求在片段着色器中使用highp。为了符合规范,在使用片段着色器中的highp之前,您需要测试预处理器定义GL_FRAGMENT_PRECISION_HIGH;如果实现支持它,则该值将为1,否则为未定义 - Andon M. Coleman
1个回答

2
片段着色器很棘手,不像顶点着色器可以使用任何整数表达式索引一个统一变量,在片段着色器中,表达式必须限定为const-index。这甚至可能排除在片段着色器的循环中索引统一变量的情况 :-\

GLSL ES规范(版本100) - 附录A:ES 2.0的限制 - 第110页

                       Specification Excerpt

许多实现超出了这些要求,但请注意片段着色器比顶点着色器更加严格。如果您能编辑您的问题以包括完整的片段着色器,我可能能够为您提供替代解决方案。
一个解决方案可能是使用一维纹理查找而不是数组。从技术上讲,使用非常量坐标的纹理查找是依赖性查找,速度可能会显著降低。然而,纹理查找可以克服 GLSL ES 中数组索引的限制。

@Skorpius:最终在看到你的着色器后,我认为将这个数组存储为一维纹理,并使用纹理查找而不是数组索引将是你最好的选择。如果这是一个顶点着色器,实现你想要做的事情会简单得多... - Andon M. Coleman
这个答案确实非常有用,但作为一个WebGL(和OpenGL)的初学者,我想知道如何实际实现解决方案...... - birgersp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接