It is possible to extend the list of available materials by creating custom ones.
IMPORTANT: When creating custom materials for a production, make sure that it will be supported by the final game engine.
Note: If creating a custom material for UnrealEngine, Unity, Lumberyard, O3DE, AfterEffects, you will need to make sure expected features are supported by our plugins, contact us at email@example.com if in doubt.
Creating custom materials for PopcornFX v2 remains a two-step process:
- Create the material editor shader(s) that will mirror the final game engine shader
- Create the game engine shader that has the same inputs
We want to streamline that process in future PopcornFX versions, and maybe provide a shader export API for engines that would support it.
This page will describe how to create a custom material compatible with a billboard renderer. This remains experimental so it is recommended to follow those steps exactly, you can reach out to us on our discord server if something doesn’t work as expected.
Before doing anything, it’s currently required to enable “Developer Mode” in your editor settings. This will allow edition of materials.
To make sure everything is organized correctly for your production:
- Never directly modify anything located in the Library/PopcornFXCore folder. Everything contained in that folder is subject to change when updating PopcornFX to a newer version
- Create a custom folder for your project in Library/ (here, we’ll be creating one in Library/ExampleContent/)
To make sure Materials and Rendering interfaces are visible in the content browser, you can select the “Filters” dropdown and enable required assets:
Creating the material
In this example, we’ll create a custom material from scratch for Opaque Billboard particles. This material will support the Diffuse from Editor.pkri, and can easily be extended to add support for additional custom features.
To create a material, right click in the content browser:
You’ll be prompted to name your material, you can uncheck “Open asset” for now. We’ll name the material Example_Billboard.
Creating the fragment shader
Next, we’ll create a fragment shader file:
We’ll also name the fragment shader Example_Billboard.
Note: PopcornFX Editor automatically generates a “passthrough” vertex shader for billboard, ribbon and mesh particles. If no custom vertex shader is assigned to the material, rendering will use that passthrough shader. Thanks to this, we only need to create a fragment shader most of the time for such renderers that don’t need custom vertex shader logic. You can take a look at the VAT custom materials to see an example of custom vertex shaders.
Now that the material and its fragment shader are created, you can open the .pkma file by double clicking it:
We have an empty material that has no shader assigned for now, this material is missing the reference “Geometry” rendering feature:
- Each one of those corresponds to one renderer node type in PopcornFX. This is the rendering feature that will determine which renderer is compatible with your material. Each material can only be compatible with one renderer.
- Expand the shader editor properties panel: this material has no valid Geometry feature and cannot be used as-is
- Empty feature list
We have to add the GeometryBillboard feature to the list of feature this material has:
- The mandatory GeometryBillboard has now been added
- The shader editor’s panel now displays additional infos, and lets you pick a fragment shader path
- The renderer preview is now functional: this is what billboard renderer properties will look like when this material is assigned to them
Additional features can be added:
- Marking all features Mandatory makes them enabled by default (ie. not optional)
- We can now see our material being rendered purple (it will need a fragment shader)
The material now needs a fragment shader to be specified:
- Make sure to pick the newly-created fragment shader file
After picking up the newly created .frag, you’ll see the material still does not render properly, we have a compilation error:
This is because Opaque draw calls need to output additional informations, and the generated .frag is invalid:
- Select ‘Preprocessed Shader’ to visualize the fully generated shader file
- Shader expects all output values to be initialized: Opaque render pass requires additional output values
This is an issue that will be resolved in future PopcornFX versions: generated .frag files do not currently automatically work with non-transparent draw calls.
We can easily fix this by writing to all output values:
At this point our material actually renders on screen as Opaque so it can be used by billboard particle renderers in effects. We’ll augment the fragment shader a bit so it supports sampling the Diffuse texture and the per-particle color:
PopcornFX Editor has its own (undocumented) GLSL augmented shading language, with a series of macros (ie. SAMPLE) allowing you to retrieve per particle values, or draw call constants.
You can leverage
#if defined(HAS_*) checks in your shader to detect if a rendering feature was enabled or not by the VFX artist on the renderer node:
- Diffuse is not mandatory: this becomes a toggle on the renderer node.
- Entire parts of the shader becomes ignored / compiled out if Diffuse is not enabled on the renderer
- The default color is chosen, based on shader code logic
As Diffuse is now optional, two shader permutations are generated, you can inspect each:
As mentioned, it’s best to create a specific folder for your production(s) that will contain all public templates, materials, common content.
Currently, there is no way to specify project wide what material is picked up by default when creating a particle renderer. Right now it defaults to Default_RendererType.pkma
This is something that can be addressed easily by creating your own renderer presets, using the “Inlined templates” system.
We’ll be using the same example folder structure, creating a new folder for templates, and an effect file containing them:
Opening that effect file, you can create a template, with the following settings:
- Make sure the template is public
- Auto Inline needs to be checked, this means when this template is placed in a nodegraph, its content will be pasted in, instead of a template instance.
- Class type set to “Renderer” will color the template in yellow
- You can setup some category and keywords for the contextual menu and template shelf
Opening the template, you can now create a single billboard renderer, with the material applied:
Once this is done, you can save and quit this templates file, opening an example effect, opening the contextual menu now properly lists our template as it’s public:
Selecting our template, its content is inlined instead of having a regular template instance placed in the graph:
This setup is ideal so artists work with your materials and renderers.