Stripping unused Universal render pipeline shaders and textures on iOS build

I’m building an iOS app using the Universal Render Pipeline and I’m trying to get the file size as small as possible. When taking a look at the build report I noticed that Universal Render Pipeline seems to include a bunch of resources I don’t use in my project, but that are still included in the build package.

Primarily it’s a big UberPost shader 1.7 mb, Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/UberPost.shader
Along with a bunch of 256k textures in Packages/com.unity.render-pipelines.universal/Textures/

These all seem to be related to post processing, that I don’t use. Is there any way make sure these unused (?) resources aren’t included in the build?

While it’s not such a problem for the file size I also notice that a lot of resources are included from Packages/com.unity.render-pipelines.core/Runtime/Debugging/ (various UI widgets, prefabs and images) even though this isn’t supposed to be a debugging build. Shouldn’t these be stripped as well when you’re building for release on iOS?

8 Likes

I should add that this is in 2019.3.0f1 with the latest render pipeline package

Facing the same issue. My UberPost.shader size is 4.6mb even though i am not using any post processing. Is there any way to exclude this shader from the build?

2 Likes

Still the same in 2019.3.0f3 for me, though I just get a 1.7MB UberPost.shader. For some reason they closed the bug I reported on this back in October 2019, but it doesn’t seem to have been fixed so I’ve contacted them and asked for the bug to be re-opened.

I’m still on 7.1.7 due to some incompatibility with some other assets I’m using, but my Android builds take FOREVER because it spends a ton of time compiling the Standard shader and other shaders meant for the built-in pipeline which I’m not even using anymore. Do I take it that 7.1.8 is supposed to solve this?

I haven’t seen anything about URP v7.1.8 solving this anywhere (I’m not sure Unity even considers this a bug any more), and as far as I can tell the problem is still the same on 2019.3.0f6 and URP v 7.1.8

According to the docs here:

It should at least perform some kind of stripping according to the settings in the URP asset. I would think, at minimum, built-in shaders for the built-in pipeline should fall under that stripping, given that they can’t even work with the URP. Yet my builds spend TONS of time compiling all the built-in pipeline shaders.

1 Like

Same here.

Shader is:
4.6 mb 1.1% Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/UberPost.shader

Textures are:
256.1 kb 0.1% Packages/com.unity.render-pipelines.universal/Textures/FilmGrain/Thin02.png
256.1 kb 0.1% Packages/com.unity.render-pipelines.universal/Textures/FilmGrain/Thin01.png
256.1 kb 0.1% Packages/com.unity.render-pipelines.universal/Textures/FilmGrain/Medium06.png
256.1 kb 0.1% Packages/com.unity.render-pipelines.universal/Textures/FilmGrain/Medium05.png
256.1 kb 0.1% Packages/com.unity.render-pipelines.universal/Textures/FilmGrain/Medium04.png
256.1 kb 0.1% Packages/com.unity.render-pipelines.universal/Textures/FilmGrain/Medium03.png
256.1 kb 0.1% Packages/com.unity.render-pipelines.universal/Textures/FilmGrain/Medium02.png
256.1 kb 0.1% Packages/com.unity.render-pipelines.universal/Textures/FilmGrain/Medium01.png
256.1 kb 0.1% Packages/com.unity.render-pipelines.universal/Textures/FilmGrain/Large02.png
256.1 kb 0.1% Packages/com.unity.render-pipelines.universal/Textures/FilmGrain/Large01.png

1 Like

Small workaround for UberPost.shader, create new file called StripShaders.cs to Assets/Editor folder and copy paste following code to it

using System.Collections.Generic;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Rendering;
using UnityEngine;
using UnityEngine.Rendering;

// Simple example of stripping of a debug build configuration
class ShaderDebugBuildProcessor : IPreprocessShaders
{
    public ShaderDebugBuildProcessor()
    {

    }

    // Multiple callback may be implemented.
    // The first one executed is the one where callbackOrder is returning the smallest number.
    public int callbackOrder { get { return 0; } }

    public void OnProcessShader(
        Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> shaderCompilerData)
    {
        //UnityEngine.Debug.Log($"Shader {shader.name}");
        if (shader.name.Contains("UberPost"))
        {
            //UnityEngine.Debug.Log($"- Shader cleared");
            shaderCompilerData.Clear();
        }
    }
}

UberPost.shader will still be included in the build, but its size will be around 0.3 kb

9 Likes

I use a solution based on this hacky github repo:

I use the Whitelist feature of the ShaderStripperVariantCollection. Works like a charm (after realizing tha there are TWO activation checkboxes, one in the stripper and one in each settings asset). You need to add some excludes manually, such as “Sprites/Diffuse” if you want a splash screen that’s not pink.

It has cut down build times by over 20 minutes.

8 Likes

Another strip script, this time for textures in FilmGrain folder. So create script file called RemoveURPTextures.cs to Assets/Editor folder and copy paste following code to it

using System.IO;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;

public class RemoveURPTextures : IPreprocessBuildWithReport
{
    public int callbackOrder { get { return 0; } }
    public void OnPreprocessBuild(BuildReport report)
    {
        Debug.Log("MyCustomBuildProcessor.OnPreprocessBuild for target " + report.summary.platform + " at path " + report.summary.outputPath);

        string packagesPath = Application.dataPath.Replace("/Assets", "") + "/Library/PackageCache";
        Debug.Log($"packagesPath: {packagesPath}");
        string[] directories = Directory.GetDirectories(packagesPath);

        foreach (string directory in directories)
        {
            Debug.Log($"directory: {directory}");
            if (directory.Contains("com.unity.render-pipelines.universal"))
            {
                Debug.Log($"Modifying entries in: {directory}");
                string texturesPath = Path.Combine(directory, "Textures/FilmGrain");
                string[] files = Directory.GetFiles(texturesPath, "*.meta");
                foreach (string filename in files)
                {
                    Debug.Log($"Modifying entry: {filename}");
                    string[] lines = File.ReadAllLines(filename);

                    for (int i = 0; i < lines.Length; i++)
                    {
                        lines[i] = lines[i].Replace("maxTextureSize: 2048", "maxTextureSize: 32");
                    }

                    File.WriteAllLines(filename, lines);
                }
            }
        }
        //throw new BuildFailedException("aa");
    }
}

Filmgrain textures will still be in package, but their sizes will be 1.1 kb. This script reduces APK size with 1.2 MB in our project.

EDIT:
This script does NOT work with Unity 2020 or newer.

9 Likes

I had this same issue and decided to take the time to combine both these techniques into one script:

This strips any shader that has “Universal Render Pipeline” in the name, which surprisingly does not seem to break anything, at least for me.
It also sets any textures originating from that folder to 32x32 (which also catches the SMAA/AreaTex.tga, that isn’t caught by the earlier code posted here). It should be possible to set the files as hidden to keep them out altogether, but I’m not sure if that would make it more annoying to undo if you change your mind. Either way, this is good enough for my purposes.

For me this saves 3.5mb, which isn’t a ton, but seeing as it shouldn’t even have been in there to begin with I think it’s pretty good.

11 Likes

Great, seems to work for me too, removes about 3MB of resources and really speeds up build time, thanks!

Any dev answers to this? Still happening in latest

We are working on the ability to strip post-processing shaders/assets.

8 Likes

Thank you!
It works well.

Any chance we could get an enhancement that would let us strip MOST of the shaders, but not all? We’re using a couple of them, but would love to strip out the others.

Use something like this in the “OnProcessShader” method

6001829--646274--upload_2020-6-20_0-14-41.png

where “Blabla” is something unique in the shader name you are using, you could just use shader.name.equals(“shader exact name”)

1 Like

We’ll try it!

1 Like

OnPreprocessBuild fix no longer works, seems the meta files for those textures get overwritten before they can be read and used in generating the resources

PS: On Unity 2020 beta version