Implementing visual effects - is this good practice?

I have spent a year building my first game and I have the core mechanics done. I am now moving onto graphics and am a complete newbie on this topic.

Effectively I need to implement visual effects in my game, e.g. shields, fading animations, explosions, smoke, particle trails etc. I do not want to simply download free effects from the asset store but rather build my own, as this forces me to learn rather than rely on others.

My idea was to use the standard unity shader for textures and light interaction, and then add additional shaders (materials) for my own custom “effects”. Is this a good idea? If anyone has any knowledge on this subject, your advice on the below would be appreciated:

  • Is it acceptable to couple custom shaders with the standard unity shader?
  • Is it okay to have multiple materials on one object, reserving certain materials for certain effects? If not, is there a better way to do this?
  • Is it a good idea to disable “effects” materials until we need them? I suppose we don’t want that material rendering all the time if we only use the effect occasionally.
  • Should any of the above be avoided for mobile? My game runs on iOS.

I have tried searching online for these answers but I cannot find much, it seems graphics is a more specialist subject than other unity topics. But if you have any links that discuss the above then I would very much appreciate them.

Thank you.

unless the effect needs lighting you do not use standard shaders on mobile

mobile shaders tend to be a texture*vertex color or a process multiplying 2 textures
textures A = illustrative shape
texture B = interference pattern, dissolve or distortion.

you want to get into VFX for mobile I suggest you start with a site dedicated to RTVFX and learn the essential craft techniques, plenty of guides and demos to show you how to tackle them

loading and unloading materials is just like loading unloading assets, typically objects are pooled and disabled but still in memory even if certain animation processes are suspended

when possible VFX may use an atlas or runtime atlas to ensure they batch, this is as long as they use a shader that has as much as is needed, all of this is conditional to your use case

  • Acceptable is the right word, depends on what effect you want. IE. an outline effect, you could write an outline shader and just use that separately, sure. A ‘shield’ effect - probably would be better combined into your surface shader for performance purposes.
  • In general, this is fine and how a lot of games work (ie. a full-body FPS game might have a first-person material that’s only enabled when the player is controlling that model).
  • Yes
  • Mobile is a difficult first place to start writing your own VFX shaders, because performance is critical, and can be destroyed very fast. However, if you’re only targeting very modern iOS devices, they’re powerful enough that you can probably still have a crack.

Thank you so much for your advice. When you say do not use the standard shaders on mobile, I am assuming you do not mean the standard surface shader? I was planning to keep this for textures, as I assumed it was very optimised.

Also thank you for the link… I will definitely look into that.

Thank you for these tips, much appreciated!

Regarding Point 1 - What do you mean by IE?
Regarding Point 4 - Do you know of any links that can advise performance optimisations? I am trying to target anything that runs iOS 14+ which includes many generations of devices.

IE = for example
Re: Mobile optimisations, it’s really one of the biggest topics out there, but even Unity has some good resources like this: Optimize your mobile game performance: Expert tips on graphics and assets
Shader-specific, this manual article is good too: Unity - Manual: Optimize shader runtime performance
In general - you want your mobile shaders to be doing super simple math, using the lowest precision numbers you can get away with, as infrequently as possible.

I am currently using the default Built-in render pipeline and I am writing my own custom shaders in code using ShaderLab/Cg. It is interesting that Unity recommend using the URP and Shader Graph for creating optimised mobile shaders.

So perhaps I should move to URP + Shader Graph, it does actually look easier to use but I suspect there may be downsides to this approach? Part of the challenge is that there are so many ways of doing the same thing… and it’s hard to know which one is best for a given use case.

:eyes: what?

I am not a rendering engineer this was my impression after years of working with them ----i’d think to not recommend shadergraph for actual deploy ----they are a mess of unparsable jargon to debug

shaders in CG by hand is to make them absolutely as light as possible, easy to debug, and the include snippets (like classes correct?) so they are best resources management

the URP versions are probably fine for most assets, you are still going to need to profile your project and assuming that you want a wide deploy you would benefit from some choice fallbacks that you make yourself.

Thanks Torbach… so it sounds like either way I should be using URP. I will migrate my project to URP and then experiment between Cg and ShaderGraph.

As I say I am a complete novice when it comes to graphics, so ShaderGraph may help me to learn the concepts. I noticed a lot of the YouTube tutorials use ShaderGraph.

May I please ask what you mean by “you would benefit from some choice fallbacks that you make yourself”?

Please can you elaborate on this point? Do you mean implementing some kind of backup shader?

yeah backups

; depending on how far back you support devices
lower end hardware might need variants incase you want to remove features to save performance

shadergraph is artist friendly, high level scripting; When it comes to visual tutorials among artists it will be popular online because of the show-n-tell nature

Just want to interject and say I would highly recommend not moving to URP. It is still really slow, and most I have talked to or seen on the forums regret migrating to URP. Built in is still great, and you can get good results on mobile, even with the built in standard shaders. Don’t let anyone sway you to make big project decisions, especially related to performance, until you profile your game. What everyone else says is meaningless, but the numbers don’t lie. What works in some games on some devices will not work with other games or other devices.

Also you can 100% use lighting for visual effects on mobile devices. Even on mid tier mobile devices. Most people optimize poorly and so believe mobile performs worse than it does.

In short, profile, and then figure out what you need to do.

Joshua can you please elaborate, in what way is it slow? Do you mean that the same graphics run at lower FPS in URP vs Built in? Bear in mind I am developing a basic 3D game for mobile so I won’t be doing any advanced graphics.

It’s really confusing because almost every blog I read states that URP is more performant and easier to work with than Built in. But then some people advise the opposite. What’s more unnerving is that it seems very important to make one decision and stick with it, so I really don’t want to make the wrong decision.

My use case is as follows:

I want to:

  • Build simple effects for my game from scratch, e.g. shields, smoke, explosions, dust clouds, fading animations etc.
  • Use standard shaders where possible for surfaces and textures.
  • Retain a high level of mobile performance, i.e. 60FPS from iPhone 5S+
  • Minimise the complexity of code as I am a beginner in graphics.
  • Build lots of animations and effects for my UI and HUD, e.g. animating circles, lines etc.
  • Develop a nice and distinct “look” to my game
  • Do all of the above in Unity 2020.3 LTS.

I do not want to:

  • Develop high-end graphics (I am doing mobile only)
  • Make use of any complex lighting or shadows (my game is set in space)
  • Use the asset store or rely on third party assets
  • Write very complex shader code as I still have a bucket load of non-graphics tasks to do (I am a solo dev doing this in my spare time)

Given the above, do you still recommend me to avoid URP and stick with built-in? Also I apologise for not specifying all of this in the OP, I probably should’ve clarified this from the start.

If you have the capacity to make a vertical slice of gameplay in both render pipelines to investigate, well that would be a strong A:B test, — this is usually a RnD time soak, as you said

this is common you pick the pipeline and stick with it to gain the expertise.

as Josh put it, stuff is conditional; your experience/project so your mileage may vary. and you absolutely need to be data oriented and informed

Josh also implied something quite crucial… capability just as (if not more) important than choosing Built-in vs Universal RP

therefore josh essentially told you, 1 pipeline is not the ruler of all mobile development, just know that 1 pipeline is not perfect and so we can’t really tell you to pick one without checking your numbers and profiling your project.

you might want to consider the pipeline due to its support/knowledge/resource network
if you are certain you are in a learning phase, perhaps learning a certain pipeline is a better use of your time come 1-2 years from now… a small thing to consider as well.

Thank you Torbach.

To be honest my profiling skills are not great, this is my first game in Unity and my game’s performance has been very smooth so far so I haven’t had much need to dig into the profiler. No doubt this will change as I now start to add graphics.

That being said, all things considered I think I will stick with the Built-in pipeline and do manual shader coding in Cg. My reasons for this are:

  • If URP was so great, why isn’t it the default? Presumably the default is more robust
  • ShaderGraph isn’t too important to me as I want to learn the industry standard method for developing shaders
  • Many people, including in this thread, state that great mobile performance can be achieved with built-in
  • Most mobile games are probably released using Built-in so it must be solid

I suspect this decision means that I’ll need to pay closer attention to mobile optimisation since the Built-in isn’t tailored to this in the same way URP is, but you guys have already given me some resources on that. I appreciate the help… I hope I am making the correct decision!