OpenGL - Texture mapping in vertex or fragment shader?

16,344

Solution 1

Usually the texturing happens in the fragment shader. This is the place where triangle's fragments gain a color.

Usually in the vertex shader you calculate texture coords (or simply pass them through from vertex attribs without special computation).

I wrote usually because right now you can use textures in all shaders: vertex, geometry, tesselation.

See here for further information.

Solution 2

This is an example of a fragment shader that implements lighting on GLSL with support of texturing, point and directional lighting (indexed as 0) and eventually fog!

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;
}

And the vertex shader

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;
}
Share:
16,344
marcg11
Author by

marcg11

Updated on June 04, 2022

Comments

  • marcg11
    marcg11 about 2 years

    Is there texture of an object/triangles mapped in the fragment shader or the vertex shader?

    Whether if it is on the vertex or fragment shader, if you are programming shaders it's something that you have to code yourself right? Without shader you just assinged the tex coords and opengl mapps it without you knowing, but with shaders you have to do it yourself, right?

    • Christian Rau
      Christian Rau about 11 years
      "but with shaders you have to do it yourself, right?" - Indeed, that's why "is there texture of an object/triangles mapped in the fragment shader or the vertex shader?" - can only be answered with "that's entirely your decision".