【问题标题】:GLSL ES1.0 and passing texture-unit indices to the fragment shader?GLSL ES1.0 并将纹理单元索引传递给片段着色器?
【发布时间】:2017-10-22 20:28:16
【问题描述】:

尝试将顶点/片段着色器从 glsl 330 转换为 glsl es1.0
(基本上退一步,因为最初的应用程序是为 OpenGL3.0 的桌面版本编写的,但 webGL2.0 仍然没有被某些浏览器完全支持,如 IE 或 Safari;据我所知)。

我了解 1.0 使用 attribute/variingin/out,但我遇到了一个问题,即我不能使用带变量的整数。有一个每顶点整数值数组,表示该顶点的纹理单元索引。我看不到将这些信息传达给片段着色器的方法。如果我将值作为浮点数发送,它将开始插值。对吧?

#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 ... */ }

【问题讨论】:

    标签: glsl webgl


    【解决方案1】:

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

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

    另一方面,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 排列成二分搜索可能会更快。

    【讨论】:

    • 肯定会的!感谢您提出这个建议。
    • 如果它在两个不相邻的纹理之间进行插值则不起作用。
    • 上面没有“相邻”纹理。如果要在纹理之间进行插值,则必须添加 GLSL。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-20
    • 1970-01-01
    • 2019-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    相关资源
    最近更新 更多