A couple of questions and issues in Unity 4.2

Author Topic: A couple of questions and issues in Unity 4.2  (Read 4850 times)

Got a couple of issues, questions regarding substances in Unity 4.2, hopefully someone here can help.

The first one relates to the way substance texture outputs get assigned to the material texture slots when using a custom shader. I know this has been answered to some extent before, but I still get some unsatisfactory behaviour in 4.2. The project I'm working on is very substance intensive and I do a lot of real time modifications to substances, so my ideal scenario is to use the substance materials directly rather than having a separate custom material that inherits it’s textures from the substance. As I understand it, when you import a substance into Unity for the first time, it only generates the first textures labelled diffuse and normal (Presumably based on the order they were created?). Incidentally is there any reason why only these 2 textures are created and non-of the others are? Wouldn’t it be easier to have a system where you flag which textures should be generated and exposed on the substance designer end, rather than having a default ‘diffuse and normal output’ or a ‘check box that forces the generation of everything’, there appears to be no middle ground? Moving on, if you set the ‘generate all‘ checkbox and assign the output textures to their relevant shader slots within the substance everything now works in 4.2 i.e. the textures remain in their slots after you click off the substance. However if you run your game and try making real time changes to the substance upon exiting and returning to the editor the substance you tweaked decides to reset back to its default state losing all your custom texture assignments:(. Which really is quite frustrating, as you effectively have to re-assign your textures every time you want to run the game, is this a bug?
So with this in mind is there any way of getting a substance to automatically assign the generated textures to any other slots than diffuse and normal? There is very little/no documentation on this behaviour. So any light that can be shed would be extremely helpful. For example is it possible to automatically assign a texture to a specular slot? How does a substance interpret the shader and know where to put the output textures?

My other question relates to the way source textures within the substance are handled. Say for instance you have a 2048 source texture in your substance and you set its inheritance to ‘relative to parent’ rather than ‘Absolute’ (I’ve found that according to the performance info in substance designer, substances generate more quickly at lower resolutions with ‘relative to parent’, presumably because it’s not having to downsize a 2048 every time you make an adjustment such as with ‘absolute’?). However the main problem I’ve found with setting textures to ‘relative to parent’ is when the parent output size is set to 0x0, substance designer exports your sbsar file with all the source textures at 256x256. Which in turn in Unity defaults at 512x512 but all the source textures have been downsized to 256x256 and the detail has been permanently lost (BTW this is really confusing as to why the defaults sizes are different between various applications, any reason why this is the case?).
To work around this issue and to try and claim the apparent performance benefit of using ‘relative to parent’ I have exported my substance at 3x3 instead of 0x0. However when this is imported into Unity the default 512x512 become 4096x4096. I appreciate these are really arbitrary numbers and changing the interface size makes no real difference to the final output. It just seems annoying that I can’t export a file from substance designer and have it interpreted by Unity such that they are equal 1 to 1.
I guess the most important question here is, is the performance info in substance designer accurate in the case of having 2048 source textures and using ‘relative to parent’ to ensure that they automatically scale appropriately with the rest of the graph? Or should I just stick with 'absolute' for source textures?

Sorry for the long questions, appreciate this might take a while to answer. Happy to try and clarify any of the above should it not make sense :).

Thanks and love your work.

Hopefully someone can answer the most important parts of my initial question;

1/In Unity how do you force a substance to automatically assign outputs to shader texture slots other than diffuse and normal? How would you automatically assign to a specular slot for instance?

2/Do you gain any performance benefit setting source textures to relative to parent so that they scale with the graph rather than remaining absolute?

Also does upgrading to a commercial license provide better access to support/help?

Hi Andy, sorry for the very late reply you message slipped through this summer...

1/ Unity can't automatically assign outputs other than diffuse/normal, this was a design decision from Unity to make it as simple as possible with their built-in shaders. Also, the _MainTex and _BumpMap identifiers are the only recurring names in Unity shaders so that's why only these 2 are plugged automatically.

2/ The best practice with image inputs is to have the image node as an absolute size and have the node just after set to relative to parent.
This way, cooking the substance will keep the input image in full resolution but the graph will be calculated at the chosen resolution depending on the parent. This should give you pretty much the same performances as if you had put the bitmap in relative to parent.

Concerning support, we usually answer equally to commercial and non commercial users and we try to answer within 48h. If you don't have any answer after a few days, do not hesitate to ping us again.
Last Edit: October 16, 2013, 08:02:09 am

Fantastic thanks Jeremie for the prompt response and answers :),

Hopefully you can also answer whether it's a bug or unavoidable feature that modifying a substance at runtime in Unity causes the substance to reset to it's default state upon return to the editor and subsequently loses all custom texture/shader allocations.

Thanks again Andy

Actually, the "substance output to shader slot" automatic mappings are the following ones:
 - diffuse -> _MainTex
 - normal -> _BumpMap
 - height -> _ParallaxMap
 - emissive -> _Illum

Also, the "specular" output is used as the source for the alpha channel of the _MainTex because that's the way most Unity built-in shaders work. I wrote a bit more details here: http://forum.allegorithmic.com/index.php/topic,550.msg2198.html#msg2198

This allows for example the automatic selection of the outputs from a B2M filters to a variety of Unity shaders from Diffuse to the Bumped ones to the Parallax ones).

The "Substance modifications done in Play mode do not persist and cause the substance to be reimported when exiting Play mode" is a consequence of the Unity design decision that "what happens in Play mode stays in Play mode". Since we only have one copy of the overall Substance system, we need to revert the modifications made to the Substance in Play mode and the quickest way to do so is to reimport it (and re-render it).

Best Regards,
Eric

Hi Eric,

That info is music to my ears, now I know how the textures are assigned and that I have 4 automatic slots to play with I hopefully won’t need to worry about the substance resetting after run time tweaks ;D.
Lastly could you possibly reconfirm that there is no performance benefit to setting source textures to relative to parent?
 Say you want your substance to run on multiple platforms, sometimes you want the source to be 2048 and other times 256 depending on the system. If those textures are relative to parent does it reduce the step of re-sizing the textures every time a change is made? Performance feedback within substance designer would seem to indicate it yields a small advantage, although not sure how reliable this info is or if my tests are sufficiently robust. I appreciate absolute is much easier to work with, I’m just trying to speed up generation on low end devices while maintaining a singular source. Mind you having written that last sentence it would probably be even more efficient to have a separate substance for each resolution/platform such that the .sbsar file would in turn be smaller for not having to carry the full resolution resources…
Anyway your thoughts would be appreciated.
Many thanks,

Andy

If you have one fixed texture size per platform, I think you could make your substances "Relative to Parent/Input", and set the source texture inside Unity, so that the Unity build process will embed the correctly sized texture and will feed it to the Substance engine at runtime, so that no fillrate is wasted downsizing huge bitmaps textures on an Android device for example.

Jeremie, do you confirm this would work given the "different texture sizes per platform" constraint?

Best Regards,
Eric