Is it possible to access all vertices in a polygon in a vertex shader?
Asked Answered
H

1

6

I'm trying to create a wireframe vertex/fragment shader in Unity. It seems possible according to this paper. The general ideas seems to be that you pass a distance vector calculated in the vertex shader to each fragment in the fragment shader, which it can use to determine what brightness to draw the wireframe line at based on its position within a polygon.

From everything else I've read, though, it appears that you only get access to a single vertex in a vertex shader. I would need access to all of the neighbouring vertices in a polygon for ecah vertex. The paper seems to imply that a geometry shader is not necessary, which is good because Unity doesn't support them yet.

What am I missing? Is it never possible to access neighbouring vertices in a vertex shader? Is what I'm trying to do impossible without geometry shaders?

Harewood answered 18/1, 2012 at 18:24 Comment(0)
L
3

You seem to indeed have over-read the paragraph in 2.1 that says

Step G1 is generally always performed in the vertex shader. Step G2 should be performed in the geometry shader since the geometry shader has access to all vertices of the polygon (provided it is a triangle). Consequently, if the geometry shader is not used, the vertex shader needs to receive the other vertices as attributes in order to compute the distances. This entails that the application code is not invariant to whether the wireframe method is used, that additional data needs to be transmitted, and, finally, that the use of indexed primitives is precluded since the attributes of a vertex depend on which triangle is drawn.

So when not using the geometry shader you indeed don't know the other vertices of a triangle and therefore have to transmit them as additional vertex attributes. So for each vertex of a triangle you got two additional vec3 attributes containing the positions of the other two vertices of this triangle. And of course, like the text says, you cannot use indexed drawing, since those two attributes don't only depend on the vertex position, but also on the triangle this vertex belongs to.

Lucillelucina answered 18/1, 2012 at 18:47 Comment(10)
Thanks for your help. Do you know if these constraints are something that can be overcome within the Unity engine? Is it possible to pass this extra information in a Cg shader like those that Unity uses? Where would that passing be performed from?Harewood
@Harewood These constraints cannot be overcome as they are constraints of the underlying hardware/interface and not of the engine or shading language. A vertex shader only has access to a single vertex and you need to give the other two as attributes of this vertex. I don't have any experience with Unity, but Cg of course has per-vertex attributes and I'm sure Unity has some means to give your model's vertices custom attributes.Lucillelucina
@Harewood So do you have any further questions regarding your original question (if you can access neighbors in VS and if your goal is impossible without GS)? You won't get any different answers from anybody who understands vertex and geometry shaders. Unity doesn't have anything to do with it, as it cannot magically overcome the limitations of the underlying graphics hardware.Lucillelucina
Well, your answer certainly helps, but I was hoping for more specific guidance in terms of how to implement it in Unity. My thought last night was to pass the other two vertices of the triangle as UV coordinates, and then unpack them in the vertex shader to do the distance calculation. I'm not sure if that's realistic or even possible, but I'd like to try it before accepting an answer.Harewood
@Harewood I guessed it, but then you could update your question or create a new one (as it doesn't ask for anything Unity as it stands). But nevermind, your idea sounds like the best approach, if Unity supports multiple 3d texCoords. Or if it only supports 2d texCoords, you can use 3 2d texCoords and unpack them into 2 float3s yourself in the shader.Lucillelucina
@Harewood Another option would be to use the object-space distance instead of the screen-space distance. This has the disadvantage that you won't get a correct wireframe with a constant line-width. But on the other hand you can compute this once before rendering and only need a single float attribute per triangle vertex.Lucillelucina
Hmm... that sounds interesting! I'm really new to this whole world of 3D, so right now I'm just doing a lot of reading and trying to figure out what the heck is going on. I appreciate your help. I'm going to try out this stuff tonight and see how it goes.Harewood
Even if I computed the object-space distance (from the camera to the object, I think you mean?), I'd still need to know when I was on a triangle edge and when I wasn't, right? So I'd still need to know the distance from the vertices... unless I'm missing something!Harewood
@Harewood No, I mean instead of computing the distance from the vertex to its opposite edge in screen-space (after projecting the vertices), for which you need a shader, as this depends on the camera, you just compute this distance in object space, not transforming the vertices. As this doesn't change based on the object's transformation, it can be precomputed. The algorithm is the same then, you just use the vertex distance to the edge in object-space instead of screen-space.Lucillelucina
Interesting! I'll see what I can accomplish this evening -- thanks again for all of your help!Harewood

© 2022 - 2024 — McMap. All rights reserved.