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

Glsl WebGL:将纹理从顶点着色器传递到片段着色器,glsl,webgl,Glsl,Webgl,是否可以将纹理从顶点传递到WebGL中的片段着色器?如果是这样的话,如何才能实现这种行为 我试图将Sampler2D传递给frag着色器,但出现错误: 取样器必须是均匀的 我非常感谢其他人在这个问题上提供的任何帮助 为什么要将纹理从顶点着色器传递到片段着色器?只是在两个着色器中声明相同的采样器 顶点着色器 ... uniform sampler2D foo; .... varying float textureSelector; ... textureSelector = ??? 片段着色器

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

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

取样器必须是均匀的


我非常感谢其他人在这个问题上提供的任何帮助

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

顶点着色器

...
uniform sampler2D foo;
....
varying float textureSelector;
...
textureSelector = ???
片段着色器

...
uniform sampler2D foo;
...
vec4 color1 = texture2D(foo, ...);
vec4 color2 = texture2D(bar, ...);
vec4 color = mix(color1, color2, textureSelector);
否则答案是否定的,不能在着色器之间传递纹理。您可以传递一些值以选择采样器结果

顶点着色器

...
uniform sampler2D foo;
....
varying float textureSelector;
...
textureSelector = ???
片段着色器

...
uniform sampler2D foo;
...
vec4 color1 = texture2D(foo, ...);
vec4 color2 = texture2D(bar, ...);
vec4 color = mix(color1, color2, textureSelector);
注:根据Nicol的注释更新,如果在内部条件代码中使用,则根据规范纹理中断。从

纹理访问 访问非均匀条件块体中的mip贴图纹理会给出一个未定义的值。非统一条件块是编译时无法确定其执行情况的块

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

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

...

if (textureSelector > ???) {
  ... use foo ...
} else {
  ... use bar ...
}
因此,我想最好在着色器的非条件部分中对所有纹理进行采样,然后使用上面的“混合”之类的数学,或者在从纹理中获取值后使用条件。访问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 ...
}

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

请尽可能多地显示vs和fs源代码以帮助我们you@DacreDenny你是说可以将纹理从顶点着色器传递到碎片着色器?我没有发布代码,因为错误似乎断言sampler2D必须是统一的,而不是可变的。不管怎样,我会更新这个问题…请看下面的答案。我认为是这样的。您知道是否存在所有可能的不同数据类型的列表吗?用例是避免在片段着色器中使用大型纹理查找树,我有多个纹理,如果我可以在顶点着色器中为片段找到合适的纹理,我认为这将是最佳选择。当你说你可以传递一些值来选择着色器时,你能更详细地说明你的意思吗?我能为每个纹理定义一个frag着色器,然后只改变用于给定点的片段着色器吗?如果textureSelector>的话???这样做会带来很多警告。WebGL是否支持dFdx/y功能和textureGrad?如果没有,那么这样的选择器将带来问题。至少,如果实际纹理提取是在该条件下完成的。如果您在之前进行两次回迁并忽略条件中的一次回迁,这将起作用。中有一个可能的变量列表,当然,参考表显示了规范中每个主题的部分。谢谢@gman。我将我的纹理索引强制转换为int,然后用它来执行查找-这解决了你提到的问题吗,Nicolas?我知道基于变量选择纹理没有不明显的问题。当然,它们是不同的,所以它们是不同的。将其转换为int不会阻止它们的变化。为三角形的每个顶点传递相同的值将导致错误。我真的取决于你想用它们做什么。当然你也可以混合。GLSL只是一种编程语言。根据输入,由您来编写正确的数学。