Reputation: 11
i am currently writing a glumpy based renderer in Python.
I am using glumpys OpenGl features for rendering a bunch of points and lines. My points are actually a graph so the lines are edges, multiple edges can have one shared point.
I implemented a picker, which enables me to draw a specific subgraph.
I have a alpha value stored on a buffer for each vertex. When i click, the alpha values are changed, so that only the points of the selected subgraph are drawn with alpha = 1. The shader is called twice:
# Draw Points
self.program_points.draw(gl.GL_POINTS)
# Draw Lines
self.program_points.draw(gl.GL_LINES, self.edge_buffer)
My problem is: The alpha values are set correctly, also the edges with both points alpha = 1 are rendered correctly but the edges that have one point with alpha = 1 and one with alpha = 0 fades out.
I want to don't color the fading edges at all. Is there a way to check on both nodes of an edge and always pick the lower alpha value or something equally useful.
My vertex shader:
uniform vec2 resolution;
attribute vec3 position;
attribute float radius;
attribute float color;
attribute float color_alpha;
attribute float id;
// for AA
varying vec4 v_position;
varying float v_radius;
varying float v_color_alpha;
varying vec4 v_id;
varying float v_color;
void main (void)
{
// this is for the picker!
v_id = vec4 (mod(floor(id / (256*256)), 256) / 255.0,
mod(floor(id / (256)), 256) / 255.0,
mod(floor(id / (1)), 256) / 255.0,
1.0 );
// values to the fragment shader
v_color = color;
v_color_alpha = color_alpha;
v_radius = radius;
//two pixel for AA
gl_PointSize = 2.0+ ceil(2.0*radius);
// hook for the Cameramovement
v_position = <transform(position)>;
gl_Position = v_position;
} ```
Upvotes: 1
Views: 176
Reputation: 45332
Well, basically, there are two options:
flat
interpolation qualifier. It the primitive is not just a point, this means the data has to come from one of the vertices only, which is called the proviking vertex. For GL_LINES
, this is usually the first vertex of each line.None of the two modes will solve your issue in the general case. Consider the Following case of two connected Edges AB
and BC
with attached alpha values 1
, 1
and 0
, respectively:
A B C
|------+------|
1 1 0
What you really want here is a sharp transition from opaque to fully transparent, and the standard solution for that is to actually split the vertices:
A B D C
|-----+++-----|
1 1 0 0
Now B
and D
have the same position, but different alpha values - and that is what GPU's model of a vertex really is: a set of attributes - not just position - and if a single attribute differs, it is technically a different vertex.
For your use case, you could probably remove the element buffer completely and always keep two distinct vertices per line.
Is there a way to check on both nodes of an edge and always pick the lower alpha value or something equally useful.
Not directly. There are some non-standard GL extensions which will give you access to the associated data of each vertex, like AMD_shader_explicit_vertex_parameter
orNV_fragment_shader_barycentric
, but none of these is generally supported and it is also way above the version of GL you seem to be using here.
However, for your use case, you could do some simple fragment shader hacks like:
gl_FragColor.a = step(0.99999, v_color_alpha);
which will basically set alpha to 0.0 if it is below 0.99999 so it will remove most part of the transition. Note that fragments with alpha=0 might still be written to the depth and stencil buffers, so you might want a conditional discard
instead.
Upvotes: 1