使用多个sampler2D一次发送一个纹理吗?

时间:2019-04-21 18:42:29

标签: c++ opengl glsl

因此,我在Maya中制作了一个网格,编写了一些代码以将其导入到顶点缓冲区中,到目前为止,效果很好,但是网格中有多个组件分配了不同的纹理,因此我认为很容易在vertbuffer中放一个键,运行switch语句(从this post中收集的信息并不是什么坏事),并通过制服发送整个网格所需的纹理,并通过键选择它们,但是当我实现它时,我注意到了它将需要多个sampler2D,并且想知道这是否需要在每个像素上加载多个几乎未使用的纹理,这会浪费吗?

GLchar* MeshFragmentShader =    //also known as pixel shader
    "#version 330 core\n"   //version 3, not 440 >> 450
    "\n"                    //GLSL 3, core = non-depricated
    "layout(location = 0) out vec4 color;\n"
    "\n"
    "in vec2 v_TexCoord;\n"
    "in vec4 v_color;\n"
    "in float v_lightval;\n"
    "\n"
    "uniform sampler2D u_Texture;\n"//<<multiple samplers?
    "\n"
    "void main()\n"
    "{\n"
    "   int i = 0;\n"//<<texture/color key (location = 4) Vertbuffer
    "   vec4 texColor;  \n"
    "   switch (i) {\n"
    "       case 0:\n"
    "           texColor = texture(u_Texture, v_TexCoord);\n"
    "           break;\n"
    "       case 20:\n"
    "           texColor = v_color;\n"//<<override
    "           break;\n"
    "   }   \n"
    //" texColor = texture(u_Texture, v_TexCoord);  \n"
    "   \n"//simple code certainly somthing i would like to improve
    "   vec3 Kolor = texColor.rgb * (v_lightval + 0.4f);\n"//change 0.4f to gamma
    "   color = vec4(Kolor, 1.0f);\n"
    //WORKING
    //" vec4 texColor = texture(u_Texture, v_TexCoord);\n"
    //"   texColor.rgb *= v_lightval;\n"
    //" color = texColor;\n"
    "}\n";

更新:
对于遇到此问题并可能要详细说明的任何人,我从上面的着色器转到了这一点,并添加了顶点着色器(和图像)以供参考;

GLchar* MeshVertexShader =
        "#version 400 core\n"   //version 3, not 440 >> 450 
        "\n"                    //GLSL 3, core = non-depricated
        "layout(location = 0) in vec4 position;\n"
        "layout(location = 1) in vec2 texCoord;\n"
        "layout(location = 2) in vec3 normal;\n"
        "layout(location = 3) in vec4 color;\n"
        "layout(location = 4) in float matid;\n"
        "\n"
        "out vec2 v_TexCoord;\n"
        "out vec4 v_color;\n"
        "out float v_matid;\n"
        "out vec3 norm;\n"
        "\n"
        "uniform mat4 u_MVP;\n"//model matrix projection matrix
        "uniform mat3 u_normalmatrix;\n"
        //"uniform bool u_LightingFlag;\n"  //had problems passing this

        "void main()\n"
        "{\n"
        "   vec4 postposition = u_MVP * position;\n"//3 line down
        "   norm = normalize( u_normalmatrix * normalize(normal) );\n"
        "   \n"
        "   gl_Position = postposition;\n"                  
        "   v_TexCoord = texCoord;\n"
        "   v_color = color;\n"
        "   \n"
        "   v_matid = matid;\n"
        "}\n";
    GLchar* MeshFragmentShader =    //also known as pixel shader
            "#version 400 core\n"   //version 4.0, not 440 >> 450
            "\n"                    //GLSL 4, core = non-depricated
            "layout(location = 0) out vec4 color;\n"
            "\n"
            "in vec2 v_TexCoord;\n"
            "in vec4 v_color;\n"
            //"in float v_lightval;\n"  
            "in float v_matid;\n"
            "in vec3 norm;\n"
            "\n"
            "uniform sampler2D u_Texture0;\n"   
            "uniform sampler2D u_Texture1;\n"   
            "uniform sampler2D u_Texture2;\n"   
            "uniform sampler2D u_Texture3;\n"   
            "uniform bool u_LightingFlag;\n"    
            "\n"
            "void main()\n"
            "{\n"
            "   float lightval;\n"
            "   if (u_LightingFlag == true){\n"
            "   vec3 light1 = normalize( vec3(-10.0f, 9.0f, -11.0f) );\n"
            "   lightval = max(dot(norm,light1),0.0f);\n"//Lambert Lighting
            "   } else {\n"
            "   lightval = 0.6f;\n"
            "   }\n"
            "   vec4 texColor;\n"
            "   for (int i = 0; i < 1; i++) {\n"        //not a loop, a goto
            "       if (v_matid < 0.1f) { texColor = texture(u_Texture0, v_TexCoord);
break; }\n"
            "       if (v_matid < 1.1f) { texColor = texture(u_Texture1, v_TexCoord);
break; }\n"
            "       if (v_matid < 2.1f) { texColor = texture(u_Texture2, v_TexCoord);
break; }\n"
            "       if (v_matid < 3.1f) { texColor = texture(u_Texture3, v_TexCoord);
break; }\n"
            "       texColor = v_color;\n"//override
            "   }\n"
            "   vec3 Kolor = texColor.rgb * (lightval + 0.4f);\n"   
            "   color = vec4(Kolor, 1.0f);\n"                       
            //" color = v_color;\n"                 
            "}\n"; 

我通过将其与仅使用一种纹理的版本进行比较,对它进行了基准测试,方法是在nvidia控制面板中强制关闭VSYNC并监视GPU使用情况,效果和指标确实很小,到目前为止,到目前为止还不错,但是如果有人知道im做错了什么或可能做得比请告诉我做得更好的事情for循环可能使用我尝试使用开关的某些工作,但无法使其部分工作,这是类型转换的原因,我想将案例作为变量传递

enter image description here

enter image description here

0 个答案:

没有答案