关于纹理映射和使用Opengl/GLSL的着色器程序之间关系的简单好奇

关于纹理映射和使用Opengl/GLSL的着色器程序之间关系的简单好奇,opengl,textures,glsl,texture-mapping,texture2d,Opengl,Textures,Glsl,Texture Mapping,Texture2d,我正在开发一个自制的小型3D引擎,更确切地说是渲染优化。在此之前,我开发了一种排序算法,其目标是将最多具有相同材质属性和相同着色器程序的几何体网格收集成批。这样我就最小化了状态更改glBindXXX和draw调用glDrawXXX。因此,如果我有一个由10个长方体组成的场景,所有长方体共享相同的纹理,需要使用相同的着色器程序进行渲染(例如,包括ADS照明),因此这些网格的所有顶点将合并到一个唯一的VBO中,纹理将仅绑定一次,只需要一个简单的绘制调用 Scene description: - 1

我正在开发一个自制的小型3D引擎,更确切地说是渲染优化。在此之前,我开发了一种排序算法,其目标是将最多具有相同材质属性和相同着色器程序的几何体网格收集成批。这样我就最小化了状态更改glBindXXX和draw调用glDrawXXX。因此,如果我有一个由10个长方体组成的场景,所有长方体共享相同的纹理,需要使用相同的着色器程序进行渲染(例如,包括ADS照明),因此这些网格的所有顶点将合并到一个唯一的VBO中,纹理将仅绑定一次,只需要一个简单的绘制调用

Scene description:

- 10 meshes (boxes) mapped with 'texture_1'

Pseudo-code (render):

shaderProgram_1->Bind()
{
     glActiveTexture(texture_1)
     DrawCall(render 10 meshes with 'texture_1')
}
但现在我想确定一件事:假设我们的场景总是由相同的10个框组成,但这次其中5个框将使用不同的纹理进行贴图,而不是多重纹理,只是简单的纹理贴图

Scene description:

- 5 boxes with 'texture_1'
- 5 boxes with 'texture_2'

Pseudo-code (render):

shaderProgram_1->Bind()
{
     glActiveTexture(texture_1)
     DrawCall(render 5 meshes with 'texture_1')
}
shaderProgram_2->Bind()
{
     glActiveTexture(texture_2)
     DrawCall(render 5 meshes with 'texture_2')
}
我的片段着色器有一个独特的sampler2D声明。我的着色器程序的目标是使用简单的纹理贴图和ADS照明渲染几何体:

uniform sampler2D ColorSampler;
我想确定的是,不可能像我之前的示例1一样,使用唯一的绘制调用绘制此场景。这是可能的,因为我对整个几何体使用了相同的纹理。我认为这一次我需要2个批次,因此需要2个绘制调用,当然,对于每个批次的渲染,我将在每个绘制调用之前绑定“texture_1”和“texture_2”,一个用于前5个框,另一个用于其他5个框

综上所述,如果所有网格都使用简单纹理简单纹理贴图进行贴图:

5带有红色纹理\u红色 5带有蓝色纹理 是否可以使用简单的绘制调用渲染场景?我不这么认为,因为我的伪代码如下所示:

Pseudo-code:

shaderProgram->Bind()
{
     glActiveTexture(texture_blue)
     glActiveTexture(texture_red)
     DrawCall(render 10 meshes)
}
我认为当我的片段着色器必须使用唯一的二维均匀变量简单纹理贴图计算像素颜色时,不可能区分这两种纹理

Scene description:

- 5 boxes with 'texture_1'
- 5 boxes with 'texture_2'

Pseudo-code (render):

shaderProgram_1->Bind()
{
     glActiveTexture(texture_1)
     DrawCall(render 5 meshes with 'texture_1')
}
shaderProgram_2->Bind()
{
     glActiveTexture(texture_2)
     DrawCall(render 5 meshes with 'texture_2')
}
下面是我的片段着色器:

#version 440

#define MAX_LIGHT_COUNT 1

/*
** Output color value.
*/
layout (location = 0) out vec4 FragColor;

/*
** Inputs.
*/
in vec3 Position;
in vec2 TexCoords;
in vec3 Normal;

/*
** Material uniforms.
*/
uniform MaterialBlock
{
    vec3 Ka, Kd, Ks;
    float Shininess;

}   MaterialInfos;

uniform sampler2D ColorSampler;

struct Light
{
    vec4 Position;
    vec3 La, Ld, Ls;
    float Kc, Kl, Kq;
};

uniform struct Light LightInfos[MAX_LIGHT_COUNT];

uniform unsigned int LightCount;

/*
** Light attenuation factor.
*/
float getLightAttenuationFactor(vec3 lightDir, Light light)
{
    float lightAtt = 0.0f;
    float dist = 0.0f;

    dist = length(lightDir);
    lightAtt = 1.0f / (light.Kc + (light.Kl * dist) + (light.Kq * pow(dist, 2)));
    return (lightAtt);
}

/*
** Basic phong shading.
*/
vec3 Basic_Phong_Shading(vec3 normalDir, vec3 lightDir, vec3 viewDir, int idx)
{
    vec3 Specular = vec3(0.0f);

    float lambertTerm = max(dot(lightDir, normalDir), 0.0f);

    vec3 Ambient = LightInfos[idx].La * MaterialInfos.Ka;
    vec3 Diffuse = LightInfos[idx].Ld * MaterialInfos.Kd * lambertTerm;

    if (lambertTerm > 0.0f)
    {
        vec3 reflectDir = reflect(-lightDir, normalDir);
        Specular = LightInfos[idx].Ls * MaterialInfos.Ks * pow(max(dot(reflectDir, viewDir), 0.0f), MaterialInfos.Shininess);
    }
    return (Ambient + Diffuse + Specular);
}

/*
** Fragment shader entry point.
*/
void main(void)
{
    vec3 LightIntensity = vec3(0.0f);

    vec4 texDiffuseColor = texture2D(ColorSampler, TexCoords);
    vec3 normalDir = (gl_FrontFacing ? -Normal : Normal);

    for (int idx = 0; idx < LightCount; idx++)
    {
        vec3 lightDir = vec3(LightInfos[idx].Position) - Position.xyz;
        vec3 viewDir = -Position.xyz;

        float lightAttenuationFactor = getLightAttenuationFactor(lightDir, LightInfos[idx]);

        LightIntensity += Basic_Phong_Shading(
            -normalize(normalDir), normalize(lightDir), normalize(viewDir), idx
        ) * lightAttenuationFactor;
    }
    FragColor = vec4(LightIntensity, 1.0f) * texDiffuseColor;
}

你同意我的观点吗?

< P>你也可以:我认为这是一个多重纹理问题,每个片段的函数最好在两个进入片段之间取一个系数为0或1的混合,而不是真正的分支;或者ii将两个纹理合成为一个纹理,这取决于您是否能够有效地包装和夹紧纹理坐标-注意那些依赖的读取-以及最大纹理大小限制


这两种方法是否都能提高性能,这是一个悬而未决的问题。如果可以的话,一定要选ii。

这个问题非常类似于。您好。这个问题是关于多重纹理的问题。例如,Lara Croft可以使用角色硬颜色的颜色贴图进行贴图,为了在她身上渲染一些伪浮雕,我们可以使用附加纹理,如法线贴图或凹凸贴图。这样,我将不得不使用glActiveTexture两次,并在片段着色器中使用这些纹理单元。但正如我上面所说,这不是我的问题。我想知道的是以下问题:我是否需要2个着色器程序实例来渲染一个场景,该场景由2个批次组成:1个使用“texture_1”渲染,另一个使用“texture_2”?我想是的,因为我的片段着色器拥有唯一的统一texture2d采样器声明!我的着色器程序的目标是使用简单的纹理贴图和ADS渲染几何体。