is it possible to use fragment shader to set one color channel of a rendering and
glColorPointer(...);
glDrawArray();
to set the 2 others colors channels.
If yes how can I do that ?
If you are stepping to the programmable pipeline then I also suggest stepping away from glColorPointer glVertexPointer and the matrix stack and instead use glVertexAttribPointer and pass the transformation matrices as uniforms.
In the fragment shader you would do
gl_FragColor = vec4(channel1, channels2_3.xy, 1);
Where channel1 and channel2_3 can come from either a uniform or a attribute passed from the vertex shader.
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'm familiar with vertex and fragment shaders but still confused about how a fragment shader determines the amount of fragments from the output of vertex shader.
If I have 3 vertices and I draw a triangle primitive in GLSL, then vertex shader will run three times for every vertex and then fragment shader will run many times (depending upon the number of fragments, once for each fragment).
I want to know how fragment shader determines the fragments? Does it use gl_Position? If I don't set gl_Position in my vertex shader does fragment shader still be able to generate fragments or not?
Is gl_Position is compulsory to set every time in vertex shader?
You're talking about the step in rasterization known as scan-conversion. The GPU takes the positions generated by your vertex shader and interpolates their attributes to produce the fragments that are passed to your fragment shader. So yes, it is essential for you to set gl_Position in the vertex shader.
After converting the coordinates of a triangle to window coordinates, scan conversion takes the triangle and breaks it up based on the arrangement of window pixels over the output image that the triangle covers. Source.
I know that I can get vertex normal in vertex shader from gl_Normal.
Now I want to set up the color of a fragment to be the vertex normal of its first vertex. May I ask how can I do that? How can I know how many vertex the fragment has, and what is the position and normal for each vertex in fragment shader?
What you ask is not quite possible, but you might be able to get close enough.
You cannot get the normal from the 'first vertex' of a primitive. What you can do is pass the normal from the vertex shader to the fragment shader as a varying, but then each fragment will get a normal that is interpolated from each vertex of the polygon.
You can't access specific properties of the vertex from the fragment shader, only interpolated values.
==EDIT==
Looks like I might be incorrect in some cases, see below comments.
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'?
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.