WebGL:将纹理从顶点着色器传递到片段着色器

时间:2018-07-24 20:04:29

标签: glsl webgl

是否可以将纹理从顶点传递到WebGL中的片段着色器?如果是这样,一个人怎么能实现这种行为?

我试图将Sampler2D传递给碎片着色器,但出现错误:

  

sampler2D必须一致

对于其他人可以在此问题上提供的帮助,我将不胜感激!

1 个答案:

答案 0 :(得分:2)

为什么要将纹理从顶点着色器传递到片段着色器?只需在两个着色器中声明相同的采样器?

顶点着色器

...
uniform sampler2D foo;
....

片段着色器

...
uniform sampler2D foo;
...

否则,答案是否定的,您不能在着色器之间传递纹理。您可以传递一些值来选择采样器结果

顶点着色器

varying float textureSelector;
...
textureSelector = ???

片段着色器

vec4 color1 = texture2D(foo, ...);
vec4 color2 = texture2D(bar, ...);
vec4 color = mix(color1, color2, textureSelector);

注意:根据Nicol的评论进行了更新,如果在内部条件代码中使用纹理,则根据规范纹理会中断。来自the spec, Appendix A.6

  

纹理访问

     

在非均匀条件块的主体内访问mip映射的纹理会给出不确定的值。非均匀条件块是在编译时无法确定执行的块

换句话说,这样的代码可能不起作用

varying float textureSelector;
uniform sampler2D foo;
uniform sampler2D bar;

...

if (textureSelector > ???) {
  ... use foo ...
} else {
  ... use bar ...
}

因此,我认为最好在着色器的非条件部分中对所有纹理进行采样,然后使用上面的mix之类的数学方法,或者在从纹理中获取值之后使用条件条件。一个访问N个纹理但仅选择1.的示例。

#define NUM_TEXTURES 6
uniform sampler2D u_textures[NUM_TEXTURES];
varying float textureSelector;  // 0 to NUM_TEXTURES - 1
void main() {
  vec4 color = vec4(0);
  for (int i = 0; i < NUM_TEXTURES; ++i) {
    float id = float(i);
    float mult = step(id - .5, textureSelector) * step(textureSelector, id + .5);
    vec4 texColor = texture2D(u_textures[i], someTexCoord);
    color = mix(color, texColor, mult); 
  }
  ... use color ...
}

当然,在大多数情况下,您可能应该使用纹理图集,并使用纹理坐标来选择其中的一部分。使用多个纹理的正常原因是诸如法线贴图,不透明度贴图,反射率贴图,环境光遮挡,光照和/或诸如泥土/草/雪的平滑混合之类的东西,在这种情况下,您不需要条件。要重新迭代,在着色器中从多个纹理中进行选择并不常见。

相关问题