Is it possible to create a custom wireframe shader/material in Unreal 5 that only (mostly) renders quads (and not triangles) like in this Unity engine shader example?

Hi,

It looks like it is possible to do so in Unity, but seems to be very complicated to achieve in Unreal.

This is how it can be achieved in Unity:

I’ve been looking for a solution for a while and I always end up in a dead end. I’m not a graphics programmer unfortunately, and this is a bit beyond my skill set. I understand the general principles, but all my attempts to convert this code into something that could be used in Unreal have failed so far.

Does anyone knows if it’s possible to convert this Unity Shader/Material code to Unreal? If yes, any pointers would be greatly appreciated about how to do it (even if it requires modifying the engine source). And if not, why? I’m just trying to fully understand why it’s so challenging to replicate such a Shader/Material in Unreal 5.

The closest solution that I have found to this problem is this one (using barycentric coordinates like in the Unity example):

Unfortunately, this solution doesn’t implement the part about removing inner triangles, like it is done in the Unity example posted above (and also, it requires a custom unwrap, unlike the Unity solution). If anyone has some insights about this subject that they are willing to share with the community, it would be immensely appreciated.

Thank you.

1 Like

Hey @Onoa!

The good news is, this is a lot easier than you would believe. You can set up a wireframe directly in your material.

3y7YZY7WWR

Check out these non-Epic affiliated tutorials covering very similar effects as well (one is a material, the other a post process effect:

I hope the above is the solution you need!

1 Like

Hi Quetzalcodename,

Thanks a lot for your reply. Like you’ve said, creating a triangulated wireframe shader is very simple, when using the native material wireframe option.

Unfortunately, that’s not what I am trying to achieve.

All of these solutions are based on the native engine wireframe shader, which can only output a triangulated wireframe. Also, with this method you can’t control the thickness of the wireframe lines, and most importantly: you can’t remove inner the lines that forms triangles and display only (well, mostly) quads.

If you look at the Unity example videos above, they explain in details what I am trying to achieve in Unreal. Which is basically a customizable (line width, color, Anti-aliasing using Smoothstep) wireframe material that renders Quads and not triangles.

I’ve been researching this subject for a long time, and as far as I know no one has ever came up with a solution to this problem for the Unreal engine.

This video above, titled “Unity shader stories - Rendering a quad wireframe” details how to achieve this in a Unity shader. What I am trying to understand, is how to do this, but in Unreal 5.

Thank you!

1 Like

Here is a customizable wireframe material that uses UV coordinates. It should allow you to do most of what you described. In order to do the same with quads, you’d instead need to generate a UV map where each quad exists as across an entire UV square (it’s okay if they overlap), so that you can step through the coordinates to find the desired border thickness.
Imagine how you’d unwrap a cube if you wanted the same texture on all sides - you’d simple overlap each quad across the entire 0-1 space. The same can be done for the quads of any mesh to get suitable UVs for a quad wireframe.

2 Likes

Thanks for your answer BananableOffense.

How would you modify the HLSL code from this example to handle quads instead of triangles? This is the part that I am curious about and not sure how to to handle.

Could you share the HLSL code that would handle quads instead of triangles?

Thanks!

1 Like

The shader is actually not the important part - the UVs of the mesh are. In order for this to work, the mesh needs each quad occupying a full 0-1 UV space. That looks like this:


You’ll notice that while the cube has 6 sides, its UV is just a single box. That’s because each quad is overlapping the entire 0-1 space. On our UV, we have the X and Y axis (R&G respectively) going from (0,0) in the top left corner to (1,1) in the bottom right.

Next, let’s alter the coordinates. We don’t really want them from 0-1, that’s just a convenient starting point for us to get where we want.
We actually want them to go from 0 on the edge to 1 in the middle, and then back to 0 on the edge again.

Now we can separate our X&Y/R&G values and use a step or smoothstep operation to choose our edge thickness and softness.


Now we can use this as a mask to drive any effects we want.

A minor optimization would be to use the minimum value between the R&G and just finding that edge instead of finding their edges individually. That looks like this:

3 Likes

Thank you so much for your detailed answer BananableOffense. This solution works really well with meshes that are made of only of quads.

Since you seem to be well versed on this subject, I would like to ask you more questions on the subject if you don’t mind.

The solution that you have proposed requires a custom unwrap that unwraps all the quads within the the 0-1 UV space (I was able to use your solution, with good results, as showcased in the screenshot included in this post). The Unity shader example that I have posted above, created by Firnox, doesn’t require a custom UV unwrap. Also, his solution is using barycentric coordinates to calculate the longest edge of each triangle to determine if it should be displayed or not. Like explained in this video:

Basically his solution/algorithm appears to be UV unwrap agnostic and can process any type of mesh that is made out of Ngons, Triangles or Quads (and if I understand correctly, all the mesh data is triangulated in Unreal anyways, so his solution works on triangles) and yet still output a very good result that displays (mostly) only quads, whenever possible. So while the result isn’t purely displaying quads, in terms of workflow VS end result quality (e.g. not requiring a custom unwrap), it seems to be an acceptable trade off.

Based on this information, do you think that a similar result could be possible to achieve in Unreal, and if so, how? Would it require custom HLSL code? Would it require to add the barycentric coordinates in the mesh using geometry scripting, like the example you have posted above?

I know that many people have been looking for a solution about this subject, for many years. I hope that the information contained in this thread will help them, like me, solve this issue. Again, thank you so much for your time. Your help on this subject is greatly appreciated.

1 Like

His shader is not UV agnostic because it requires barycentric UVs. Sounds like he may be generating these UVs with a computer shader or something, rather than unwrapping them that way. But regardless it has the same limitation.

His technique of rendering quads is essentially the same as mine, but he’s just procedurally converting triangular barycentric UVs into quad Barycentric UVs. By UV unwrapping in the way we have, we created barycentric Quad UVs too, with a coordinate system that is fundamentally the same as he did after removing the extra line.
He states that sometimes the wrong line will be removed from each triangle, resulting in a quad failing to convert to a triangle, my technique is not prone to this issue.
With mine, for any triangle that is not part of a quad, you would unwrap it in the same manner (one vert in each corner, but one will be missing. This will cause it to miss one edge, and that edge will be too thin. As he explains his shader has this issue too. It has no special handling for ngons and is less reliable at combining squares than my technique as his has the chance to remove the wrong one, whereas in mine, the two triangles are linked by their UVs and thus are guaranteed to combine into the quad if possible.

Here is my material on a mesh with both triangles and quads:


Note that the edge between the triangles and the quads are slightly thinner than the rest due to that edge being omitted from the wireframe.
Here’s the required UV layout.
image
This is actually the default UV layout in blender, so you can rapidly get this layout by selecting your mesh, hitting “U” to bring up the UV menu, and then “R” for reset. N-gons will also become centric, however they wont span the full 0-1 UV space. For example a 6 vertex n-gon will turn into a hexagonal UV, which while technically each vertex will be 1 unit away from the center of the UV, stretching from the severe misalignment of the true geometry vs the hexagon’s UV would cause really bizarre stretching as seen here:

You can see how the edge thickness on the n-gon is not sufficiently consistent. Technically any non rectangle or right triangle will see some minor variation of its edge thickness (somewhat visible on the trapezoids, but only because the edge is extra thick in this example.

Also note that blender’s reset UV rotated the hypotenuse of two adjacent but non coplanar triangles to face each other, causing one whole edge to be missing. Firnox’s method could potentially do this too.
It also aligned one of the hypotenuse to along a ridge (left side), which when viewed from above also looks like it’s missing because we can’t see the lower edge.
If these bother you, you may want to manually reorient the UVs of the problem triangles. The advantage of doing this in a real UV map is that you do have control over these details.

2 Likes

I’ve been making some tests earlier using the same method that you have described with Blender and the result is very good and what I am looking to achieve.

We finally have a solution to this problem, but for Unreal!

Thank you so much for taking the time to help me solve this issue as well as explaining it in great details. I’m sure other people will be happy as well.

Thanks!

4 Likes

Thanks a lot it works !

1 Like