Hi, I would like to know if material functions are inlined at compile time. I am concerned about potential performance loss when using lots of functions for modularity purpose. Thanks!
When you are inside the material editor you can see the HLSL code generated using Menu Window->HLSL Code option. Then you can see for yourself.
Well, I when open HLSL code I see tons of functions which have no relationship with the graph I wrote. Try to write a simple function with 2 nodes and open HLSL code, you’ll see…
You have to connect all the way to the outputs in the material or you won’t see it. The easiest way to find a specific code is to make a copy of the HLSL and then you add something and finally get the resulting HLSL comparing with the first one. This is because the material compiler does a lot of optimizations depending on your material demand. Such optimizations mostly exists in order for you do not worry with things like if certain piece of code will be inlined or not.
You should only be worried if the profiler says you got a problem otherwise you are spending time chasing ghosts.
Exactly! Thanks for the better words.
Shader compilers inline almost everything. Only when it see beneficial not to inline it will not.
Cool, that’s great ! So there is no reason not to make functions even lots of them for good modularity.
Sorry but I totally disagree with that, if the ambition is to make a game and build a library of components, those need to be highly optimized since they will be used all over the place. When I’ll be adding more and more content and see my fps go down, this is not the moment I will got back to my root material content that I have designed months ago, I want them to be optimized from the beginning and confidently build on the top of them.
My point is not to disregard the importance of optimizing your code but to pick your battles. The benefit of doing less function calls could be meaningless compared to changing the complexity of the function itself.
The material you create is an abstraction. Any game engine will change the resulting shader code to an approach which fits the packaging you are currently using. Something which performs greatly for a Windows packaging, may not perform the same for Mobile, or OSX, or PS4. This means that no matter how you try to organize your library, you might need in the end to have a substitute material for a specific packaging. The profiler tool is great for this, because you might have developed a great material library, but as you used them into different environments they perform differently under conditions like: type of lights, vertex counts, tesselation on/off, the aliasing being used and the rendering: forward or deferred or msaa…
There are tricks on making materials per use case, that are a must to be known. These tricks in some cases are not even to be considered, but depending on the scene complexity they are very needed. Don’t get me wrong, there are materials for a number of different applications, but there are applications that will require specific techniques to be used or the scene will not flow well.
Also middleware like Simplygon will drastically change your materials (and even mesh geometry) during its optimization…