OpenGL - 在顶点着色器或片段着色器中进行纹理映射?

4

对象/三角形的纹理是在片段着色器还是顶点着色器中进行映射的?

无论是在顶点着色器还是片段着色器中,如果你正在编写着色器,那么这是你必须自己编码的内容,对吧?没有着色器时,你只需分配纹理坐标,OpenGL会在你不知道的情况下进行映射,但使用着色器时,你必须自己完成此过程,对吧?


1
“但是使用着色器,你必须自己完成这个任务,对吧?” - 的确如此。因此,“一个物体/三角形的纹理是在片段着色器还是顶点着色器中映射?”- 只能回答“这完全取决于你的决定”。 - Christian Rau
2个回答

6
通常情况下,纹理映射发生在片元着色器中。这是三角形片元获得颜色的地方。
通常在顶点着色器中计算纹理坐标(或者仅从顶点属性中传递它们而不进行特殊计算)。
我使用“通常”这个词,因为现在你可以在所有着色器中使用纹理:顶点、几何和细分。
更多信息请参见这里

1
这是一个片段着色器的例子,使用GLSL实现了纹理、点光源和定向光源(索引为0),最终还支持雾效果!
varying vec3 vertex;
varying vec3 normal;
varying vec3 eye;

uniform sampler2D DiffuseMap;

void computeLight(in int i, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
{
    ambient += gl_LightSource[i].ambient * gl_FrontMaterial.ambient;

    vec3 light;

    if(gl_LightSource[i].position.w == 1.0)
        light = gl_LightSource[i].position.xyz - vertex;

    else
        light = gl_LightSource[i].position.xyz;

    vec3 lightDiri = normalize(light);

    float NdotL = max(0.0, dot(normal, lightDiri));

    if(NdotL > 0.0)
    {
        float att = 1.0;

        // Calcule l'attinuation dans le cas d'une lumier pointctuelle
        if(gl_LightSource[i].position.w == 1.0)
        {
            float distance = length(light);

            att = 1.0 / (gl_LightSource[i].constantAttenuation
            + gl_LightSource[i].linearAttenuation
            * distance
            + gl_LightSource[i].quadraticAttenuation
            * distance
            * distance);
        }

        float NdotHV = dot(normal, normalize(lightDiri + eye));

        diffuse  += gl_FrontMaterial.diffuse * gl_LightSource[i].diffuse * NdotL * att;
        specular += gl_FrontMaterial.specular * gl_LightSource[i].specular * pow(NdotHV, gl_FrontMaterial.shininess) * NdotL * att;
    }
}

void main()
{
    vec4 ambient = vec4(0);
    vec4 diffuse = vec4(0);
    vec4 specular = vec4(0);

    vec4 finalColor = vec4(0);

    computeLight(0, ambient, diffuse, specular);
    finalColor = ambient + diffuse * shadow;

    finalColor *= gl_Color;
    // *** This is what you asking for !
    finalColor *= texture2D(DiffuseMap, gl_TexCoord[0].st);
    finalColor += specular;

    // Foged ?
    float z = gl_FragCoord.z / gl_FragCoord.w;
    float fogFactor = (gl_Fog.end - z) / (gl_Fog.end - gl_Fog.start);
    fogFactor = clamp(fogFactor, 0.0, 1.0);

    gl_FragColor = mix(gl_Fog.color, finalColor, fogFactor);
    gl_FragColor *= finalColor.aaaa;
}

和顶点着色器相关

varying vec3 vertex;
varying vec3 normal;
varying vec3 eye;

void main()
{
    vertex  = vec3(gl_ModelViewMatrix * gl_Vertex);
    normal  = normalize(gl_NormalMatrix * gl_Normal);
    eye     = -normalize(vertex);

    gl_FrontColor       = gl_Color;
    gl_TexCoord[0].xy   = gl_MultiTexCoord0.xy;
    gl_Position         = ftransform();
    gl_ClipVertex       = gl_ModelViewMatrix*gl_Vertex;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接