0
votes

With GLSL, I'd be performing lighting calculations, texturing and all sorts; but does it make any difference which shader it is done in? For example, is there a performance benefit in performing lighting calculations in the vertex shader rather than the fragment shader? I'd have to pass only the end-result to the fragment shader and have it added to the fragment color. Can the same be so vice-versa?

My next question is, with regards to vertex attributes and uniforms:

Are vertex attributes global to all shaders in any shader program? For example, suppose we have:

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertices), (GLvoid*)0);

If I then declare in the vertex shader:

layout (location = 0) in vec3 VertexPosition; 

Can I also do the same in the fragment shader? Can I also do the same in a vertex shader pertaining to a second shader program?

With regards to uniforms, is it possible for me to use uniforms in all the shaders of that shader program so long as I declare them?.

uniform mat4 modelMatrix; // In the vertex shader

uniform mat4 modelMatrix; // In the fragment shader

My last question is, should all vertex attributes be consistent throughout the main program? As in, if I allocate vertex attribute 0 as VertexPosition, then I can no longer allocate that attribute to something else such as VertexNormal, correct? That could only happen unless I disable the vertex attribute array with:

glDisableVertexAttribArray(0);
1

1 Answers

4
votes

I'd be performing lighting calculations, texturing and all sorts; but does it make any difference which shader it is done in?

Think about the dataflow in the OpenGL pipeline.

Most primitives are made up of 1 (point), 2 (line) or 3 (triangle) vertices, but generate potentially thousands of fragments. So anything you can compute per-vertex will be cheaper than per-fragment by virtue of the fact that the vertex shader runs far less often.

Generally you try not to compute the entire lighting equation per-vertex (gouraud) because it looks terrible unless you use an excessive number of vertices. However, you can transform all of your lighting vectors into the same coordinate space in the vertex shader to simplify your fragment shader and improve performance.

Are vertex attributes global to all shaders in any shader program?

Vertex attributes are assigned to generic locations, and those locations are global. But fragment shaders operate per-fragment and have no notion of vertices (again, think back to the dataflow).

Is it possible for me to use uniforms in all the shaders of that shader program so long as I declare them?

Uniforms, on the other hand, are shared among all shader stages. As long as the name and type are consistent you can use them from vertex, geometry, tessellation or fragment shaders.

Should all vertex attributes be consistent throughout the main program?

This really does not matter, the programmable pipeline is programmable. As long as you know what vertex attribute N represents when your shader is executed, you are good to go. If you establish a standard convention, however, you can swap shader programs on the fly without changing your vertex attribute pointers.

In the days of the fixed-function pipeline, there was a standardized convention where vertex position aliased to 0, color aliased to 3, normal aliased to 2 and so forth. But that is purely historical and you can follow that convention if you want or create your own.