GLSL vertex shader cancels rendering

Can rendering for a pixel be completed in the vertex shader. For example, if a vertex does not satisfy a specific requirement, cancel the rendering of that vertex?

+6
source share
5 answers

You cannot stop rendering a pixel in the vertex shader (it does not apply to pixels), but you can use the discard command in the fragment shader.

+6
source

I assume you said that "rendering for the top will be completed." And no, you cannot; OpenGL is very strict regarding the ratio of input vertices 1: 1 to outputs for VS. Also, this does not mean what you want, since the vertices are not displayed. Primitives are valid, but a primitive can consist of several vertices. What would it mean to drop a vertex in the middle of a triangular strip, for example.

This is why Geometry Shaders have the ability to "select" primitives; they relate specifically to the primitive, and not just one vertex. This is done simply without emitting peaks; GS must clearly emit the vertices that it wants to derive.


Vertex shaders now have the ability to select primitives. This is done using the "cast distance" function of OpenGL 4.5 . It is like gl_ClipDistance , but instead of clipping, it selects the entire primitive if one of the vertices crosses the threshold.

+12
source

In theory, you can use a vertex shader to create a degenerate (zero region) primitive. A primitive with a zero region should not lead to rasterization, and thus the fragment will not be displayed. However, this is not particularly intuitive, especially if you use primitives that share vertices.

But no, undoing the top is almost pointless. This is the fundamental unit on which primitives are built. If you just delete one vertex, you will change the rasterized output to undefined ways.

Simply put, vertices are not what create pixels on the screen. This is a vertex relationship that creates primitives that ultimately result in pixels. Geometric shaders work on a primitive-primitive basis, so they are usually where you cancel the rasterization and shading of fragments programmatically.


UPDATE:

It occurred to me that you are using GL_POINTS as your primitive type. In this special case, all you need to do so that your vertex does not go further along the conveyor is installed in a place somewhere outside the viewing volume of your camera. The top will be trimmed and there will be no rasterization or shading of fragments.

This is a much more effective solution for testing certain conditions in the fragment shader, and then discarding, since you skip rasterization and should not run the fragment shader at all. Not to mention the fact that discard usually works as a post-shader execution flag that tells the GPU to refuse the result - the GPU is often forced to execute the entire shader regardless of where you issue the discard instruction in the shader, so discard rarely gives performance advantage, and in many cases it can disable other potentially more useful hardware optimizations. This is the nature of how GPUs plan their shader workload, unfortunately.

The cheapest snippet is the one you never need to process :)

+9
source

I am developing an answer by Andon M. Coleman, which deserves IMHO to be marked as correct.

Despite the fact that the OpenGL specification is adamant that you cannot skip the fragment shader step (unless you delete the entire primitive in the geometric shader, as Nicole Bolas correctly pointed out, which throws imho a bit), you can do this in practice by allowing OpenGL to discard all geometry, since modern GPUs have early fragment rejection optimizations that are likely to have the same effect.

And for the records, so that all the geometry is discarded, it is really very simple: just write the vertex outside the cube (-1, -1, -1), (1,1,1)

 gl_Position = vec4(2.0, 2.0, 2.0, 1.0); 

... and go away!

Hope this helps

+2
source

You can make changes to the vertex stream, including removing vertices, but the place to be done would be in the geometric shader. If you look into the geometric shaders, you can find the solution you are looking for, just not getting to β€œemit” the top.

EDIT: if you create a triangular strip, you probably also want to take care to start a new primitive when the vertex is removed; you will understand why if you explore geometry. shaders. With GL_POINTS, this will be less problematic.

And yes, if you send a triangular strip from only two vertices, then, indeed, you can not do anything - just like you if you transferred to such a degenerate strip in the first place. This does not mean that the vertex flow cannot be changed on the GL side, however.

Hope that helps> Tom

0
source

Source: https://habr.com/ru/post/951635/


All Articles