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

时间:2017-10-22 08:09:28

标签: glsl webgl

尝试将顶点/碎片着色器从glsl 330转换为glsl es1.0
(自从原始应用程序是为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 个答案:

答案 0 :(得分:3)

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

当然,您可以传入浮点数(并作为无符号字节提供)。在调用false

时,将gl.vertexAttribPointer传递给normalize标志

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

来自spec

  

12.30动态索引

     

...

     

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

     

RESOLUTION:No。采样器数组只能通过常量整数表达式进行索引。

“GLSL ES 3.00中是否应包含此功能?”表示GLES ES 3.00中应包含采样器的动态索引

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

所以,你必须编写代码,以便你的indies是常量索引表达式。

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安排到二进制搜索中可能会更快。