2
votes

I am learning opengl and I thought I pretty much understand fragment shader. My intuition is that fragment shader gets applied once to every pixel but recently when working with texture, I became confused on how they exactly work.

First of all, fragment shader typically takes in a series of texture coordinate so if I have a quad, the fragment shader would takes in the texture coordinates for the 4 corners of the quads. Now what I don't understand is the sampling process which is the process of taking the texture coordinates and getting the appropriate color value at that texture coordinates. Specifically, since I only supply 4 texture coordinates, how does opengl knows to samples the coordinates in between for color value.

This task is made even more confusing when you consider the fact that vertex shader goes straight to fragment shader and vertex shader gets applied per vertex. This means that at any given time, the fragment shader only knows about the texture coordinate corresponding to a single vertex rather than the whole 4 coordinates that make up the quads. Thus how exactly it knows to samples the values that fit the shapes on the screen when it only have one texture coordinates available at a time?

2
"vertex shader goes straight to fragment shader" Have you actually looked at a diagram of the OpenGL rendering pipeline? Because a lot of things happen between the end of the VS and the start of the FS.Nicol Bolas

2 Answers

1
votes

All varying variables are interpolated automatically.

Thus if you put texture coordinates for each vertex into a varying, you don't need to do anything special with them after that.

It could be as simple as this:

// Vertex
#version 330 compatibility
attribute vec2 a_texcoord;
varying vec2 v_texcoord;

void main()
{
    v_texcoord = a_texcoord;
}

// Fragment
uniform vec2 u_texture;
varying vec2 v_texcoord;

void main()
{
    gl_FragColor = texture2D(u_texture, v_texcoord);
}

Disclaimer: I used the old GLSL syntax. In newer GLSL versions, attribute would be replaced with in. varying would replaced with out in the vertex shader and with in in the fragment shader. gl_FragColor would be replaced with a custom out vec4 variable. texture2D() would be replaced with texture()

Notice how this fragment shader doesn't do any manual interpolation. It receives just a single vec2 v_texcoord, which was interpolated under the hood from v_texcoords of vertices comprising a primitive1 current fragment belongs to.

1. A primitive means a point, a line, a triangle or a quad.

0
votes

first : in core context you still can use gl_FragColor.

second : you have texel ,fragment and real_monitor_pixel.These are different things. say this line is about convert texel to fragment(or to pixel idk exactly what it does):

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

when texel is less then fragment(pixel)