Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL: Defining variables in shaders

Tags:

opengl

glsl

My OpenGL program, using GLSL for shaders, has a simple vertex and fragment shader (given by a tutorial).

The vertex shader is:

#version 330

layout (location = 0) in vec3 Position;

void main()
{
    gl_Position = vec4(0.5 * Position.x, 0.5 * Position.y, Position.z, 1.0);
}

And the fragment shader is:

#version 330

out vec4 FragColor;

void main()
{
    FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

What is happening here is that the vertex shader divides the vertex coordinates by 2, and the fragment shader then colors it in red.

Now from my understanding, gl_Position tells the fragment shader the pixel coordinates of this vector. And gl_Position is an existing variable that both shaders know about, so the fragment shader will always look for gl_Position when deciding where to draw that vertex.

However, what about FragColor? In this example, it has been manually defined in the fragment shader. So how does OpenGL then know that FragColor is the variable we are using to set the vertex's color? FragColor can have been defined with a different name and the program still runs in the same way.

So I am wondering why gl_Position is a variable that has already been defined by OpenGL, whereas FragColor is manually defined, and how OpenGL knows how to interpret FragColor?

like image 269
Karnivaurus Avatar asked Jun 22 '15 14:06

Karnivaurus


People also ask

How do shaders work in OpenGL?

A Shader is a user-defined program designed to run on some stage of a graphics processor. Shaders provide the code for certain programmable stages of the rendering pipeline. They can also be used in a slightly more limited form for general, on-GPU computation.

What is a uniform variable in a shader?

A uniform is a global Shader variable declared with the "uniform" storage qualifier. These act as parameters that the user of a shader program can pass to that program. Their values are stored in a program object.

What is vec3 in OpenGL?

vec3 is a floating point vector with three components. It can be initialized by: Providing a scalar value for each component. Providing one scalar value. This value is used for all components.

What is a shader attribute?

Attributes are GLSL variables which are only available to the vertex shader (as variables) and the JavaScript code. Attributes are typically used to store color information, texture coordinates, and any other data calculated or retrieved that needs to be shared between the JavaScript code and the vertex shader.


1 Answers

1. Question: Why is gl_Position a variable that has already been defined?

This is because OpenGL/the rendering pipeline has to know which data should be used as basis for rasterization and interpolation. Since there is always exactly one such variable, OpenGL has the predefined variable glPosition for this. There are also some other predefined variables which also serve specific purposes in the rendering pipeline. For a complete list, have a look here.

2. Question: FragColor is manually defined, how does OpenGL knows how to interpret it?

A fragment shader can have an arbitrary number of output variables, especially needed when working with framebuffers. There are basically two options how to tell OpenGL which variable should be written to which render buffer: One can set this locations from application side with the glBindFragDataLocation method. The second option is to specify this location(s) directly in the shaders using Layout Qualifiers. In both cases, the location of the variable defines to which render buffer the data is written.

When no custom framebuffers are used (as in your case), the default backbuffer is will get data from the fragment output variable at location 0. Since your shader has only one output variable, it is highly likely that this one will have location 0. (Although I think it is not guaranteed, correct me if I'm wrong).

like image 180
BDL Avatar answered Sep 20 '22 23:09

BDL