代码之家  ›  专栏  ›  技术社区  ›  Thomas An

GLSL ES1.0并将纹理单元索引传递给片段着色器?

  •  2
  • Thomas An  · 技术社区  · 7 年前


    (基本上是倒退了一步,因为最初的应用程序是为OpenGL3.0的桌面版本编写的,但据我所知,webGL2.0仍然没有得到某些浏览器的完全支持,如IE或Safari)。

    我知道1.0正在使用 属性/变化 输入/输出 ,但我有一个问题,我不能使用带变量的整数。有一个逐顶点整数值数组,表示该顶点的纹理单位索引。我没有看到将该信息传递给片段着色器的方法。如果我以浮点形式发送值,它将开始插值。正当

    #version 330 //for openGL 3.3
    //VERTEX shader
    //---------------------------------------------------------------------------------
    //uniform variables stay constant for the whole glDraw call
    uniform mat4   ProjViewModelMatrix; 
    uniform mat4   NormalsMatrix;       
    uniform vec4   DefaultColor;        
    uniform vec4   LightColor;          
    uniform vec3   LightPosition;       
    uniform float  LightIntensity;      
    uniform bool   ExcludeFromLight;    
    //---------------------------------------------------------------------------------
    //non-uniform variables get fed per vertex from the buffers
    layout (location=0) in vec3 VertexCoord;  
    layout (location=1) in vec4 VertexColor;  
    layout (location=2) in vec3 VertexNormal; 
    layout (location=3) in vec2 VertexUVcoord;
    layout (location=4) in int  vertexTexUnit;
    //---------------------------------------------------------------------------------
    //Output variables to fragment shader
         out vec4  thisColor;          
         out vec2  vertexUVcoord;
    flat out int   TexUnitIdx;         // <------ PROBLEM
         out float VertLightIntensity; 
    //---------------------------------------------------------------------------------
    
    void main ()
    { /* ... blah ... */ }
    

    需要平移的伴随片段着色器如下所示

    #version 330 //for openGL 3.3
    //FRAGMENT shader
    //---------------------------------------------------------------------------------
    //uniform variables
    uniform bool      useTextures;     //If no textures, don't bother reading the TextureUnit array
    uniform vec4      AmbientColor;    //Background illumination
    uniform sampler2D TextureUnit[6];  //Allow up to 6 texture units per draw call
    //---------------------------------------------------------------------------------
    //non-uniform variables
         in  vec2  vertexUVcoord;      
         in  vec4  thisColor;          
    flat in  int   TexUnitIdx;         // <------ PROBLEM
         in  float VertLightIntensity;
    //---------------------------------------------------------------------------------
    //Output color to graphics card
    out vec4 pixelColor;
    //---------------------------------------------------------------------------------
    
    void main ()
    { /* ... blah ... */ }
    
    1 回复  |  直到 7 年前
        1
  •  4
  •   gman    7 年前

    GLSL ES 1.0中没有基于整数的属性

    当然,您可以传入浮点(并以无符号字节的形式提供)。传入 false 用于调用时规范化标志 gl.vertexAttribPointer

    另一方面,GLSL ES 1.0和GLSL ES 3.00都不允许索引采样器阵列。

    spec

    12.30动态索引

    GLSL ES 1.00支持通过常数索引表达式对采样器阵列进行索引。常数索引表达式 是由常量表达式和某些循环索引组成的表达式,定义为 循环构造的子集。GLSL ES 3.00中是否应包含此功能?

    分辨率:否。取样器阵列只能由常数积分表达式索引。

    “GLSL ES 3.00中是否应包含此功能?” 手段应该 动态索引 GLES ES 3.00中包括的采样器数量

    我引用了GLSL ES 3.00规范,因为它也引用了GLSL ES 1.0规范。

    所以,你必须编写代码,使你的独立变量是常数索引表达式。

    attribute float TexUnitNdx;  
    
    ...
    
    uniform sampler2D TextureUnit[6];
    
    vec4 getValueFromSamplerArray(float ndx, vec2 uv) {
      if (ndx < .5) {
       return texture2D(TextureUnit[0], uv);
      } else if (ndx < 1.5) {
       return texture2D(TextureUnit[1], uv);
      } else if (ndx < 2.5) {
       return texture2D(TextureUnit[2], uv);
      } else if (ndx < 3.5) {
       return texture2D(TextureUnit[3], uv);
      } else if (ndx < 4.5) {
       return texture2D(TextureUnit[4], uv);
      } else {
       return texture2D(TextureUnit[5], uv);
      }
    }
    
    vec4 color = getValueFromSamplerArray(TexUnitNdx, someTexCoord);
    

    或者类似的。将ifs整理成二进制搜索可能会更快。