Opengl es 在一个着色器过程中渲染多个纹理

Opengl es 在一个着色器过程中渲染多个纹理,opengl-es,branch,webgl,Opengl Es,Branch,Webgl,在WebGL中,一次渲染多个纹理是否会更快,如: varying float materialIndex; varying vec2 textureCoord; uniform sampler2D textureSampler1; uniform sampler2D textureSampler2; uniform sampler2D textureSampler3; uniform sampler2D textureSampler4; vec4 getMaterial(float mat

在WebGL中,一次渲染多个纹理是否会更快,如:

varying float materialIndex;
varying vec2 textureCoord; 

uniform sampler2D textureSampler1;
uniform sampler2D textureSampler2;
uniform sampler2D textureSampler3;
uniform sampler2D textureSampler4;

vec4 getMaterial(float materialId, textureCoord) {
    vec4 color;

    if (materialId == 1.0)
    {
        color = texture2D( textureSampler1, textureCoord );
    }
    else if (materialId == 2.0)
    {
        color = texture2D( textureSampler2, textureCoord );
    }
    else if (materialId == 3.0)
    {
        color = texture2D( textureSampler3, textureCoord );
    }
    else
    {
        color = texture2D( textureSampler4, textureCoord );
    }

    return color;
}

void main()               
{                  
    vec4 color = getMaterial(materialIndex, textureCoord);
    gl_FragColor = color;        
}
因为这将节省CPU必须发送到GPU的指令的四分之一,除了顶点着色器必须传递的额外信息之外,在大多数情况下,它不是比执行4倍的程序调用更快吗?我已经读到,即使在opengl中,到目前为止最大的性能影响是CPU,我打赌Webgl的情况更是如此。或者这可能会更快

uniform float materialIndex;
varying vec2 textureCoord; 

uniform sampler2D textureSampler1;
uniform sampler2D textureSampler2;
uniform sampler2D textureSampler3;
uniform sampler2D textureSampler4;


void main()               
{                  
    vec4 color = getMaterial(materialIndex, textureCoord);
    gl_FragColor = color;        
}

或者,就CPU必须执行的调用数量而言,更改功能统一是否与加载新着色器一样糟糕?

批处理很重要,是的。但这并不重要。特别是当遇到某个硬件可以从所有四种纹理中采样的可能性时,不管是什么

在变化的情况下,编译器不知道值如何变化。因此,它将假定任何片段都可以获得任何值。因此,它必须为所有内容执行运行时分支。由于条件分支的代价,编译器通常会尝试通过简单地执行所有可用路径并使用非分支逻辑计算最终结果来避免执行4个连续的条件分支

您的统一案例也不能避免此类“优化”,因为某些旧硬件在功能上根本无法对重要指令执行条件分支。因此,他们别无选择,只能在每次更改一致性时重新编译着色器(这并不夸张;旧硬件上的NVIDIA编译器确实做到了这一点),或者执行所有4种纹理访问

哦,还有一件事:
texture2D
函数在非统一控制流中(如在有条件执行的块中)变得未定义。现在,它可能不会因为你如何使用它而伤害你。但一般来说,您需要使用显式渐变或从条件块中删除纹理访问函数。我记得WebGL没有渐变纹理函数

简而言之,只需更改纹理并再次渲染。即使在JavaScript中,这也不会像潜在地进行4次纹理访问那样影响性能。只要您只在渲染之间绑定纹理(即:您没有更改程序或其他状态),并且您遵守良好的实践(在状态更改之间尽可能渲染),您就应该相对正常