#How addressables works with shaders?
1 messages · Page 1 of 1 (latest)
Test number 1:
Remove URP/lit shader from addressables. Leave only SCV (saving only used shaders into scv file) in addressables.
And result is horrible. The duplicates in memory is horrible.
my understanding is that the built in shaders do not go into your own asset bundles, but a special shader bundle included in the build.
i hope that also applies to the URP package shaders
well if you dont add them they go somewhere indeed. Problem is how they are used in runtime then. For example if you have material that is not in addressables and then material that is in addressables, even if these two materials are the same, in runtime they will be loaded twice, costing RAM to increase.
So in Test number 1, you can see how a lot of materials using new copy of shaders. While if I have shaders in my own created folder I get something like this:
or if more optimized
So the question is not how shaders are beeing packed and where, but where and how they end up in memory in runtime.
as if it is left alone to be added automatically
it will be loaded 15 times for each duplicate.
those 2 materials arent the same though as 1 will end up in an asset bundle. and the other will end up built in.
But according to Unity's docs they should both reference the same Lit shader in the 'unitybuiltinshaders' bundle
i wouldnt be surprised if that tool reports it wrong an it just assumes Lit.shader is a standard file like any other asset and isn't special
"They should" But only if you add them in Packed group, or run "analysis" tool and "fix" possible errors. In unity docs is also said that if you have SCV (the bundle file) adressables SHOULD only include those shaders with those shaders variants that are only used. but it seems dont work either.
But also it does not explain why Lit shader is 26mb in size (MEMORY not storage)?
yeah i dont know what to trust. and what to do with other package shaders/assets. Unity's solution to avoid dupes is to:
Cause
If you have two AssetBundles using the same shader or material, but they are not tagged into any AssetBundle, Unity will pack the shader in each bundle. This could also happen if you use your shader/material in a local scene and pack the shader/material into an AssetBundle.
Resolution
Choose which assets will be on AssetBundles and which in the executable. You can pack your materials or shaders into one common AssetBundle (for example art.unity3d) and load this bundle first."
which you literally cannot do with package assets..
might be worth a test to copy Lit.shader, and stick it in an addressable yourself and see what happens?
I was doing similary. I was able to reduce usage to 15mb of ram. But that still means it includes too many shader variants and load to memory.
em could you elaborate?
copy the shader into your project, and reference your own one not the built in one. stick it in an asset bundle that all other bundles are dependent on. then it definitely wont be duped
Sorry if I was not clear. If you add it manually the built in, it does not get duplicated. The problem then that it contains too many shader variants. these images:
#1146699157126516776 message
but you can't add the Lit.shader to an addressable?
or hmm my bad, you can. I use the bog standard AssetBundles still , which i know you cant add a package asset to a bundle.
Well you msot definently can add shaders from Packages into addressables. I never tried adding full package tho, maybe rules are different for that,
yeah my mistake, im getting confused with asset bundles vs addressable usage.
are you totally sure though that in the situation where you have less variants that it isnt actually stripping variants you do need?
and when it is include din the adressable.. that simply is the actual amount of variants you need
Now I am testing if I Add lit shader in each scene package, will it duplicate on Memory or not. it will duplicate and increase package size as storage, but i wonder how it will work in Memory.
if the shader is in a different bundle from materials that use it, it can often miss out need variants.
so i suspect removing it from the addressables will have that issue
I do believe it works like that:
Scene A have variant B
Scene B have variant C
If I have shader in "shared bundle" the variants included will be B and C. and it will always load both shader variants, not only ones you need in the scene.
move the materials into the shared bundle too
ok i get you. so when you load scene A.
the shared bundle loaded up ALL variatns for both scene A and B.
so it might be a better situation to dupe the shader into each Scene bundle?
Yes. I just tried to include lit shader in only A Scene bundle. It loaded like if lit shader is shader bundle. But the size is way way too big 😦
so Including Unlit shader in each scene bundle does not change the fact it loads all shader variants from everywhere. but even then the size is too big.
I still trying to understand how this is possible.
Example 1: 60 materials references, URP.Lit 67Mb
and example 2:
60 materials references 8Mb
Created new project for testing, which makes me even more confused. Creating shader variants collection and adding it to addressables not only not decrease the shader size in memory, but increases almost double it O.o so how then should use shader variants collection with addressables...
What if you do this:
Lets say we have 3 groups
- Group includes Scene A // "Pack Mode" is set to "Pack Together"
- Group includes Scene B // "Pack Mode" is set to "Pack Together"
- Group includes Shader's. Or let's say you have some commonly used material along with the Shaders added to this group for any scene and let's say it was added here. (Example: "Material A" must use a Shader that is in this group. "Material A" used in both of the Scenes so it is a commonly used Material. "Material A" must be added to this group) // "Pack Mode" is set to "Pack Seperately" or "Pack Labeled"
For this test, lets say you have two Labels named as "Shaders" and "Materials" and "Pack Mode" is set to "Pack Labeled". After that we set the labels as said.
If the number of commonly used materials count increases too much, we should be aware that we can further divide them with labels. Imagine the number of commonly used Materials (Variants) reaches 2,000 and if one of them is loaded the entire package is installed, right? Thus, we can separate them according to tags such as "Land, Walls, Water, etc....".
Can you test this? I have no idea how do you make your tests so
or maybe you already tested this one... 
@wild lotus in case you're didnt took the notification
@wild lotus @minor flame
This example exactly tells what happens when you create a dependency to other bundle.
For example, BundleA contains Addressable assets **RootAsset1 **and RootAsset2. **RootAsset2 **references DependencyAsset3, which is in BundleB. Even though **RootAsset1 **has no reference to BundleB, **BundleB **is still a dependency of **RootAsset1 **because **RootAsset1 **is in BundleA, which has a reference to BundleB.
So if we simplify this:
BundleA(Group) contains RootAsset1(Material), RootAsset2(Material)
BundleB(Group) contains DependencyAsset3(Shader)
RootAsset2(Material) contains a reference to DependencyAsset3(Shader)
So in this example, as expected, if we use loadassetasync for the RootAsset2(Material), the DependencyAsset3(Shader) and their Bundle loads into memory too.
Again, as expected, When you do Release() on that RootAsset2, it releases both Bundle's(BundleA, BundleB) from memory.
Final conclusion is even when you load the RootAsset1, it still loads the **BundleB **since **BundleA **has a dependency(atleast one of the Addressable Asset in the **BundleA **has a reference) to BundleB.
The dependent bundle must be loaded when you load any asset in the current bundle, not just the asset containing the reference. Although none of the assets in this other AssetBundle are loaded, loading a bundle has its own runtime cost. Refer to Memory implications of loading AssetBundle dependencies for more information.
Ref: https://docs.unity3d.com/Packages/com.unity.addressables@1.21/manual/memory-assetbundles.html#loading-assetbundle-dependencies
Deeper Ref(Non-Addressable asset bundles): https://docs.unity3d.com/2022.3/Documentation/Manual/AssetBundles-Dependencies.html
@soft island Sorry was away for a weekend.
What you mentioned is correct, it will pull all references needed. But it depends on how package is loaded. Addressables can load object one by one from package to memory, unloading depends is bundle is packed together or seperatly. It if is packed together it can unload only all bundle, but if packed separately it can unload one by one.
I created testing project last time and were testing various settings and addressables variants. It thave 4 Bundles:
-Scene A
-Scene B
-Scene C
-SharedBundle
I created over 40 different materials with different variations. Then each scene have 20 cubes with different materials. And i load async SceneA reference. The results is still not clear, but the memory usage of URP/Lit shader was changing from 1.5 mb to 44mb depending on setup.
today will try to complete testing and find best way how to reference shaders in order to reduce memory. I want to reach level of shaders usage as if it would be loaded not from addressables. Will report when results will be more clear
Sure. Will be waiting ya
Currently, i am running a test too.
Tested with a windows real build! Editor will mess up the memory!
This test's Project includes those:
URP Shaders > Pack Together
URP Materials > Pack Together (20 Material that has different colours)
MaterialCubes > Pack Together (20 Prefab that includes a cube and each material of URP Materials)

What i am doing is, i just instantiating the **MaterialCubes **via Addressables.InstantiateAsync at once, and releasing them with **Addressables.ReleaseInstance **or Addressables.Release.
It seems it stays fixed even i use multiple materials.
When i release them, the shader size didnt change.
The 20 material size is so small. When loaded, It takes around 300KB which is normal and when unloaded the 20 materials, it takes around 120KB .
I have no idea what is uberpost but seems important.
Now i will increase the count to 40
Well, it works perfectly.** Shader size stays the same** and Materials are just doubled as expected.
Now the question is what if we used those materials inside Addressable Scene? I think the result will be the same since system will tell us that the scene has as a dependency bundle. But it wont unload until you unload the scene.
Of course, if we were used those inside non-Addressable Scene it would get duplicated without a warning. The Addressables Analyze tool is helps us at this point. It tells us which ones are explicit(Addressable) and which ones are implicit(In build).
But of course i dont know if it will detect duplication in non-addressable scenes.
In case anybody didnt used this before:
Thank you for you results. I will share my results then an notices. First I am very suprised your lit shader is so small, how many Quality settings layers you have? As I learned that all quality settings shaders is included in Memory. For example if you load low quality settings scene it will include shader variants needed for high fidelity quality settings needed. So this helped reduce memory size used dramaticly.
However having url/lit shader in seperate library still load all shader variants needed for all scenes.
This is example of scene loaded without addressables, aka only one scene.
but when I load it with addressables it looks like this:
This is results of real project, not testing. On testing platform for one scene loading with or without addressables is the same, but the moment u add more scenes it increases.
I still havent find how to load shades variants that is needed only for this scene. Or even if it is possible
Uberpost I think it is shader for post procesing.
I used Analyze tool and removed all fixable errors. Unfixable is kinda more as report than anything else and not needed to be fixed in most cases. Or at least that how I did understood documentation.
Thank you. I usually set and use Medium as my default Quality Level because it bottlenecks at Quality Level ">=Very High" in a simple level. Besides, i think Quality Level does not affects the Graphics tab. The Graphics has its own tab inside project settings for URP. I also set that to Medium.
So it does not increase shaders variants depending on amount levels in quality settings?
I think it decreases the size of Shader's and Texture's instead of not to include variants