PKFxMaterialFactory V3

From PopcornFX
Jump to navigation Jump to search

What is a material factory?

The material factories are objects that are here to create the materials for the PopcornFX particles. We implemented two material factories, the default one (when not using SRP with Unity) and the HDRP one. We will implement a LWRP material factory later.

The material factory is an asset referenced in the PKFxSettings. If you choose not to create the material factory asset, the PKFxSettings will create a default material factory at startup.


Default material factory

The default material factory is a material factory that works with the default Unity rendering pipeline.


The asset references the shaders used to render the particles and the render queue in which the semi-transparent particles will be rendered by default (the draw order is added to this queue number to get particles to render on top of the others).


There is also a list of custom materials that you can define. It is very easy to associate a custom material with a renderer in PopcornFX, you just need to add an element to the custom materials list and type a user data to link with a material:

In the PopcornFX editor

In Unity

HDRP/LWRP materials factories

The HDRP material factory work just like the default one but uses HDRP materials.

The LWRP material factory work just like the default one but uses LWRP materials. Note that distortion is disabled in this mode, as the specifications of LWRP don't allow it.

Material factory interface (advanced)

This section is for advanced users that want to implement their own material factory.

For each PopcornFX renderer, the material factory will setup the corresponding game object in Unity with the correct material.

The PKFxMaterialFactory abstract class has 3 abstract methods that need to be implemented to setup the renderers:

public abstract void		SetupRenderer(PKFxManager.SBatchDesc batchDesc, GameObject gameObject, MeshRenderer meshRenderer);
public abstract void		SetupMeshRenderer(PKFxManager.SBatchDesc batchDesc, GameObject gameObject, PKFxMeshInstancesRenderer meshRenderer);
public abstract Material	ResolveParticleMaterial(PKFxManager.SBatchDesc batchDesc);

All of those methods are taking the PKFxManager.SBatchDesc as parameter. This class contains the description of the PopcornFX renderer that is currently being setup. Here are the members of PKFxManager.SBatchDesc that are used to setup the materials and the gameobjects:

PKFxManager.SBatchDesc members

ERendererType m_Type

The type of the renderer (Billboard, Ribbon or Mesh as the other renderers are not implemented in Unity).


int m_MaterialFlags

You can check if a flag exist by calling the "HasMaterialFlag" method. Those flags represent a change in the shader inputs, so it's a different shader that is build for each combination of those flags. This member is a combination of the following possible material flags:


For the ribbon renderers, if the quality setting is set to "CorrectDeformation".


This adds 3 vertex inputs that are used to remap the UVs in the vertex shader:

float2 UVFactors
float2 UVScale
float2 UVOffset


If soft animation blending is enabled on this renderer.


This adds 2 vertex inputs (in addition to the standard UV, you cannot have the Has_AnimBlend flag without the Has_Diffuse):

float2 UV1 // UV for the next atlas
float2 AtlasIdAlphaCursor // AtlasId used to lerp between the color of the texture sampled at UV0 and UV1


If alpha remap is enabled on this renderer.


This adds one vertex input and one sampler to the shader:

float AlphaCursor // Vertex input that contains the particle AlphaCursorField
sampler2D _AlphaMap // Alpha remap texture


If the renderer has a lit material.


This adds one vertex input:

float4 Normal // The normal of the vertex to compute lighting


If the renderer uses a soft material.


This adds the camera depth texture as a sampler in the shader:

sampler2D _CameraDepthTexture

This also adds an inverse softness distance property to the shader

float _InvSoftnessDistance


If the renderer uses a distortion material.


This also adds the camera depth texture as a sampler in the shader:

sampler2D _CameraDepthTexture


If the renderer has a Color field. Not filling that field means the color is white for all the particles.


This adds 1 vertex input:

float4 Color


In the editor, a diffuse texture is needed or an ugly "Replace me" magenta texture is used on the particles, but in Unity the particles will be rendered without a texture which can be useful if you just want plain color particles. This flag is always present.


This adds one vertex input and one sampler to the shader:

float2 UV0 // UV of the current atlas
sampler2D _MainTex // Diffuse texture


If the renderer is double sided (planar aligned for the billboards and the ribbons that are not ViewposAligned)

This flag only exist if you have checked the "Split the draw calls of the particles that require disabling the back-face culling" option, otherwise double sided particles are batched with the others.


int m_UniformFlags

The uniform flags are flags that are passed as a property to the shaders. So they do not define a shader variation (as they do not change the shader inputs or the shader code), but are used inside the shaders (for the blending mode for example).

if neither Is_AdditiveAlphaBlend, Is_Additive or Is_AdditiveNoAlpha are present, this means that the material should use alpha blending:

Blend SrcAlpha OneMinusSrcAlpha



For all the alpha-blend additive materials.

Blend One OneMinusSrcAlpha



For all the additive materials that premultiply the color by the alpha channel.

Blend One One



For all the additive materials, but does not take the alpha into account.

Blend One One



Flip the u and the v of the sampled texture coordinates (texture rotated 90 degres). Only for ribbons.

int m_DrawOrder

The draw order of the renderer. The greater the draw order, the later the particles are rendered (so particles with a greater draw order will be rendered on top of the smaller draw order).



string m_UserData

The UserData of the renderer.

string m_DiffuseTexture

The path of the renderer's diffuse texture.

string m_AlphaRemapTexture

The path of the renderer's alpha remap texture

float m_InvSofnessDistance

The inverse softness distance of the renderer (taken into account if the renderer uses a soft material).

string m_GeneratedName

The generated name for the Unity game object created to render this particle batch with the following format:

[Billboard|Mesh|Ribbon] [MaterialFlags] [UniformFlags] [UserData] [Difffuse texture path] [Alpha remap texture path] [InverseSoftnessDistance]

string m_EffectNames

The name of each renderer of each .pkfx that are rendered in the same batch, separated by semicolon.