Materials & Geometry shaders


I’m moving from unity to ue4 …
In unity I could write material script (shaders) that uses geometry shader to do some thing that i want to acomplish.
For example I want to move triangles of the mesh in direction of their face normals - how to acomplish this in ue4 ?
(Yes I want them to separate and have triangle look, something like this:

In material editor I only see displacement map output and world position offset output, but none of them is what I want.
In unity I’v just wrote some simple geometry shader, that for each triangle calculated face normal, and then moved vertices of that primitive in direction of that normal - any way to do this in ue4

Any WORKING examples of using geometry shaders and some magic to create this kind of material ? (note that the artists need to assign this material to the various meshes, it’s not just for one custom mesh)
(that raises my doubts about skinning code and so on, but meybe there is some solution to this (unity skins by either software or vertex streamout, so vertex shader is have just one version no mather if mesh is skinned or not))

Thanks for any information on that topic.

It is possible to move vertices in the direction of their normals.

Create a vertexNormalWS node and connect that into the world position offset in the material. Add in a multiply inbetween to control the strength.

Looking at the image youve supplied as reference, I can see that you want the faces separated which is something you will have to do in your third party modeling program. If the faces share vertices, then they cant separate.

Yes, but I want it for arbitrary mesh that have specified material assigned, that was ‘piece of cake’ in unity (and artist was not forced to ‘separate all the faces that makes me crazy modeling my character thing’ ;)).
Realy no way to put geometry shaders at work ?

Not from the material editor. However, you can also dive into the usf shaders and implement it manually.

You could probably do that with a custom HLSL node as part of World Position Offset. Just search for ‘Custom’ in the Material Editor. That node will allow you to type in your own HLSL. Be aware however, it won’t cross-compile for other platforms, so you need to write it in whatever code the platform your shipping to supports.

The problem you have is that all the vertices on the models will be welded, especially in the case of skinned meshes. Unless you’re generating vertices of your own in that Vertex Shader, then that image won’t be possible without creating faces with separate vertices anyway.

EDIT: There is also the Procedural Mesh Component for Blueprints / C++. See if that can do what you’re looking for.

Unfortunately that won’t work in this situation, as all a custom node does is generate a function in the resulting shader code, so you would not be able to implement a geometry shader via the custom node.

@MXADD: There is no way to implement geometry shader functionality in the material editor, so your best bet would be to look at implementing is via a USF file and a custom vertex factory. Thats if you want to implement the geometry shader as is, otherwise it might be best to consider either re-authoring your models, or doing as TheJamsh mentioned and look at the procedural mesh component to maybe duplicate the mesh with the faces already detached.

Thanks GalaxyMan2015 for clarification.
Is there any working/complete example of use USF/VertexFactory to look at, I’v searched for haour or two about this topic, but found only general ranting on forums that this does not work, some incomplete code snippets and the conclusion that this is not the way to go (and many dead links/ removed project od github).
I’m fresh to unreal - so meybe a stupid question - all this can be realized as a plugin ? - or it needs to touch engine source code in any way ?

Also I do not understand the logic behind creating my own vertex factory - i just want create new material - it should not change the way engine handles vertex shader input data (so gfx artist should be able to bind this to arbitrary mesh on the scene)
I’m not sure if vertex factory is what I want, judging from documentation FVertexFactoryType is intended to introduce new type of MESH, not MATERIAL - I’m right ?

The vertex factory defines the inputs of a mesh for a material, ie. Will it need Position, Normals, Texture Coordinates and such and takes care of binding the shaders for rendering the mesh. Each time you compile a material, it creates an instance for each vertex factory type there is, creating the combined vertex, pixel, domain and hull shaders, currently none of the factories provide a geometry shader (But last I saw, there is now code to allow you to bind a geometry shader to a vertex factory, where as you used to have to modify the source to do so). This should all be possible from within a plugin. So you would need to create your own vertex factory (or extend the static mesh one) so you can bind your own geometry shader, and write the appropriate USF. I have done this in the past, with success, but the engine has changed since, I doubt my original version would work anymore, but looking at it, its probably even easier now.

Ok, one more thing I do not understand, after lurkinng for a while into ue4.8.1 code I’v found for examle ‘FLocalVertexFactory’ class


  • A vertex factory which simply transforms explicit vertex attributes from local to world space.
    class ENGINE_API FLocalVertexFactory : public FVertexFactory
    { … }

so I’v picked it, put into my project /Source directory, renamed to for example FragmentumVertexFactory (and acomplying FragmentumVertexFactoryShaderParameters) - it compiles jus fine …
but now … how to use it ? for example I want to have my super fancy vertex factory on a cube, so I’v put cube into scene (it’s derived from StaticMeshComponent) and now what … how to tell this cube to use my vertex factory ?

From what I understand the flow should be:
1] create own vertex factory (or possibly more than one, for example one for skinned meshes, one for static meshes)
2] assign somehow those factories to objects in scene
3] assign any material from ‘Surface’ domain to those meshes

and it should call my custom vertex/geometry shader and then with go with interpolants from GS into PS (with will be composed inside MaterialEditor)
but point ‘2’ is total mystery for me right now (and not only for me, as the google reveals no one ansfered that simple question ‘how to use vertex factory’)
(is there a place in editor somewhere that allows to assign it to mesh or this needs to be done in blueprint/c++ ?)

Additional question (as there is no documenation about this) WHERE the FragmentumVertexFactory.usf should be if the declaration of my factory is as follows:
IMPLEMENT_VERTEX_FACTORY_TYPE(FragmentumVertexFactory, “FragmentumVertexFactory”, true, true, true, true, true);

<ProjectRoot>/Content/Shaders/FragmentumVertexFactory.usf ??
(and even one more question, if body contains #include “VertexFactoryCommon.usf”, then I need to put VertexFactoryCommon.usf in that same directory (and all it’s dependencies) or it will automagically resolve into Engine/Shaders directory
where the rest of includes lives)

Just for the record, after 2 days of strugle, I’v finally put it all together:
The way to do this (hope the proper one) is:

1] (probably) create new module - if you do not have one that is loaded at ‘PostConfigInit’

2] Create your vertex factory class that derives from FVertexFactory

  • this will allow you to execute your custom vertex shader, and work nicelly with MaterialEditor
    for details see LocalVertexFactory.h/cpp

3] Create your mesh scene proxy class that derives from FStaticMeshSceneProxy
but replace standard vertex factory with your own (to see what methods you need to override see: SplineMeshSceneProxy.h/cpp)

4] Create your mesh component class that derives from UStaticMeshComponent (or USkinnedMeshComponent if you want skined meshes, or both if you want normal & skinned)
only override ‘CreateSceneProxy’ method there and return your own proxy, this will finally allow you to use your factory for rendering

to use in engine, just create empty actor, and add your class (the one you derived from UStaticMeshComponent), add to it any normal model, assign material etc. etc.

Hope this helps someone.

Now the only way I need is to figure out is: HOW TO ADD GEOMETRY SHADER to my newly created vertex factory :]
(As there is no example/documentation there again ;(()

Do someone have any ideas about how to do this? I’m breaking my head over it :smiley:

IMHO the only way to add geometry shader to vertex factory is to modify engine code itself, it’s not a trivial as geometry shaders are already used for shadows rendering, so this must be nicelly handled as well … untill i dont know something

Ahh I see… Someone should write some deeper documentation or tutorial items on .USF’s. I toyed with them a long time ago but never really got very far. Visual Assist didn’t work with it and naturally I crumbled :frowning:

(slight necro)

The biggest (at least for me) problem with USF files is that ALL the shaders gets recompilled each time the usf file is changed (ANY USF FILE) … the iteration time is creased insanelly by this behaviour.

Yeah I don’t think much effort has been put into making those easy to HotReload, since I doubt Epic ever really expects people to mess around with them.

Posting a feature request thread and linking this thread and a few others might draw some attention to that. It would be nice to see USF files made easier to edit and debug. Hell is it even possible to add .USF’s via plugins or anything?

Yes - it’s possible to add USF via plugin/module
Debugging is quite problematic couse this is not ‘pure’ hlsl, and what you see in .usf, is not what you get in nsight for example, but it’s waaaaaaay better than in unity anyway :slight_smile:

Hi @MXADD: just one question did you use engine source to compile your own implementation of FLocalVertexFactory? I did something similar but I get “inconsistent dll linkage”.


Never mind I made it compile =). Thnxs.

I get the same error in my customVertexFactory.cpp file, how did you solve that?