I introduced a geometry shader to my OpenGL application. My shaders have quite a few of "varying" variables that I pass from the vertex shader to the fragment shader. Now, having introduced the geometry shader I have to manually pass every varying value in the geometry shader for each vertex. Is there a way to avoid that and do things "automatically"?
No.
As soon as you introduce a geometry shader in your pipeline, if you want to pass variables from the vertex shader to the fragment shader you have to pass them manually, creating an input variable from the vertex shader and an output variable to the fragment shader. I don't know which GLSL version you're using, but you might want to check section 4.3.4 of the GLSL 3.30 spec.
No, because there's no sensible way to do that for anything except a noop geometry shader, and if your geometry shader isn't doing anything to the geometry, why is it enabled in the first place?
In general, a geometry shader takes a number of vertexes as input and produces a (different) number of vertexes as output. So which input vertex(es) should be mapped to which output vertex(es) 'automatically'?
Related
I want to some objects using shader. I name these objects obj_1, obj_2, ...obj_n.
One object's data stores in one vbo. I name these vbos vbo_1, vbo_2, ...vbo_n.
I need use vertex shader, geometry shader , and fragment shader for every object.
All vertex shader is just multiple the vertex with a modelviewprojectoin matrix.
All fragment shader is just set the color.
However, every geometry shader is different.
Here is my planA:
I create one program. The vertex shader has a uniform variable named ModelViewProjection. The fragment shader has a uniform variable named color.
In the loop of all objects, I set the vertex shader's ModelViewProjection uniform variable and set the fragment shader's color uniform variable.
Then change the geometry shader using corresponding GLSL code.
However, I can not find a way to replace the geometry shader in a program while changing vertex shader and fragment shader unchanged.
So I have a planB:
I create lots of programs as many as objects. It is feasible.
However, it means that the varialbe shader and fragment shader is repeated as many as numbers of objects. It is a waste of space and it's hard to expand.
So my question is, is there a plan C for my case? Or that there is a way to change geometry shader in program?
I want to run the geometry shader only if a certain uniform has some value, otherwise go directly to the fragment shader. I know I can duplicate the shader, but I wanted a more elegant solution. Any ideas?
It is available as output variable in all shaders except fragment shader. So which shader stage must write it? Is its value taken from the last shader stage that wrote it?
Also please explan what is the purpose of having the value gl_ClipDistance in fragment shader?
As long as you only work with vertex and fragment shaders, you write it in the vertex shader. According to the GLSL spec, geometry and tessellation shaders can write it as well.
The fragment shader can read the value. Based on the way I read the documentation, it would give you the interpolated value of the clip distance for your fragment.
Considering it is really only useful for clipping... you need to write it in the last stage of vertex processing in your GLSL program. Currently there is only one stage that does not fall under the category of vertex processing, so whatever comes immediately before the fragment shader needs to output this.
If you are using a geometry shader, that would be where you write it. Now, generally in a situation like this you might also write it in the vertex shader that runs before the geometry shader, passing it through. You don't have to do anything like that, but that is typical. Since it is part of gl_PerVertex, it is designed to be passed through multiple vertex processing stages that way.
Name
gl_ClipDistance — provides a forward-compatible mechanism for vertex clipping
Description
[...]
The value of gl_ClipDistance (or the gl_ClipDistance member of the gl_out[] array, in the case of the tessellation control shader) is undefined after the vertex, tessellation control, and tessellation evaluation shading stages if the corresponding shader executable does not write to gl_ClipDistance.
If you do not write to it in the final vertex processing stage, then it becomes undefined immediately before clipping occurs.
If i use opengl 3.2+ with compatibility context and have a fragment shader, is it necessary to have a vertex shader? I would like to know if per vertex lighting calculation and other per vertex calculations can be done by the fixed function pipeline and i can just use the fragment shader.
Also what implications would this have for per-vertex attribute binding locations?
if per vertex lighting calculation and other per vertex calculations
can be done by the fixed function pipeline
They can be done if you use fixed pipeline lights.Otherwise, part of it (like transformed normals,uv's and positions) must be computed elsewhere before being passed to the fragment shader.This "elsewhere" is called vertex shader.So yes,if you don't use fixed pipeline lightning system you must use vertex and fragment shader to process it.
Also,if you use fixed pipeline lightning you can still use shaders where you can access fixed light and material properties.But I see no point doing so unless you wish to break the defaul behavior.
How to transfer data from vertex shader to fragment shader without changes?
I need to say to the vertex pixels that they have this color. This color I can obtain only in the vertex shader.
You have to use a varying, because each fragment is "influenced" by more than one vertex (unless you are rendering GL_POINTS), so you have to interpolate them across the line/polygon. Recent versions of GLSL allow to specify flat shading interpolation, which doesn't interpolate the value throughout the primitive, ignoring the values from the other vertices.
I suspect thought that what you want to do is to render only the pixels corresponding to the vertices in a different color, is that correct? In that case it's not so easy, you would probably want to render the filled polygons first, and then re-render as GL_POINTS. At that point, varying variables are not interpolated because each fragment is influenced by a single vertex.
Here's a good tutorial on GLSL: NeHe GLSL tutorial
If you want to share data between vertex and fragment shaders use one of the built in types, for example gl_Color
If you want to pass through the color computed by the vertex shader to through the fragment shader you would create a fragment shader with the following line: gl_FragColor = gl_Color
gl_Color will be automatically set for you from the colors written by the vertex shader. You write a color from the vertex shader by setting one of the built-in variables, like gl_FrontColor, or one of it's peers: gl_BackColor etc.