Unity - Shader Compiled Log

news2024/11/18 19:28:56

文章目录

  • 吐槽
  • 开启 Log Shader Compilation
  • 实践
    • 资源准备
    • Build AB
    • Testing Script
    • Shader Compiled Log
  • Project


吐槽

先说一下,最近几天前,纷纷看到 unity install fee 的天才收费方案
真的忍不住吐槽,我只想说: “no zuo no die”

(吃相太难看了)


开启 Log Shader Compilation

如果要做变体优化,或是 Shader.CreateGPUProgram 的 CPU 卡顿优化
都可以使用 Shader Compiled Log,只要在开启:Project Settings/Graphics/Shader Loading/Log Shader Compilation 即可

在这里插入图片描述

这样的话,就可以真机上查看编译情况,每个以 Compiled Log 都是对应 Shader.CreateGPUProgram,因此如果要做: 变体优化,变体预热,都是一个比较好的调试Log


实践

在这里插入图片描述


资源准备

顺便编写简单的 shader,创建 material,创建 prefab
设置 AB 信息,build AB

如下

在这里插入图片描述


Build AB

// jave.lin : 测试 打 AB

using System.IO;
using UnityEditor;
using UnityEngine;

public class TestingBuildAB : MonoBehaviour
{
    [MenuItem("实用工具/BuildAB")]
    public static void Build()
    {
        var curBuildTarget = EditorUserBuildSettings.activeBuildTarget;
        var outputPath = $"{curBuildTarget}/ABs";
        try
        {
            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            BuildPipeline.BuildAssetBundles(
                outputPath,
                BuildAssetBundleOptions.ChunkBasedCompression
                | BuildAssetBundleOptions.DeterministicAssetBundle,
                 curBuildTarget);

            EditorUtility.DisplayDialog("Build ABs Result", $"Build {outputPath} Successfully!", "OK");
        }
        catch (System.Exception er)
        {
            Debug.LogError(er);
            EditorUtility.DisplayDialog("Build ABs Result", $"Build {outputPath} Failure! See Console Plz.", "OK");
        }
    }
}


Testing Script

// jave.lin : 测试 ab loading & unloading

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestingScript : MonoBehaviour
{
    private Dictionary<string, AssetBundle> loaded_AB_Dict = new Dictionary<string, AssetBundle>();

    private Dictionary<string, bool> isLoadByMajor_Dict = new Dictionary<string, bool>();

    private AssetBundleManifest manifest;
    private bool isLoadedManifest;

    private AssetBundleManifest GetManifest(string platform = "Android")
    {
        if (manifest == null)
        {
            var buildTarget = platform;
            var projectPath = Application.dataPath.Replace("/Assets", "");
            var platformABPath = $"{projectPath}/{buildTarget}/ABs";
            var manifest_bundle = AssetBundle.LoadFromFile($"{platformABPath}/ABs");
            manifest = manifest_bundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
            //Debug.Log($"loaded manifest : {platformABPath}, manifest : {manifest}");
        }
        return manifest;
    }

    private AssetBundle LoadAB(string abName, bool isMajorAB)
    {
        ///*
        //shader.ab // all shader
        //* common.svc
        //* height_fog.svc
        //* gi.svc
        //* xxx.svc
        // * 
        // */

        //AssetBundle ab = AssetBundle.LoadFromFile("shaders.ab");

         1. 游戏通用 shader warmup (可能会卡顿,因为编译时间长),注意: 一般不用 warmup
        //ab.LoadAsset<ShaderVariantCollection>("common.svc").WarmUp(); // 一般不用 warmup
         2. 进入一些需要 height fog 的场景
        //ab.LoadAsset<ShaderVariantCollection>("height_fog.svc").WarmUp();
         3. 进入一些【不】需要 height fog,但需要 gi 的场景,但是这块管理很有风险,我记得 unity 的 shader一旦 Shader.Find 不到会导致闪退
        //GameObject.Destroy(ab.LoadAsset<Shader>("height_fog1.shader"));
        //GameObject.Destroy(ab.LoadAsset<Shader>("height_fog2.shader"));
        //ab.LoadAsset<ShaderVariantCollection>("gi.svc").WarmUp();
         4. 再次进入需要 height fog ,不需要 gi的场景
        //GameObject.Destroy(ab.LoadAsset<Shader>("gi.shader"));
        //ab.LoadAsset<Shader>("height_fog1.shader"); // 之前 destroy ,现在重现 load 回来
        //ab.LoadAsset<Shader>("height_fog2.shader"); // 之前 destroy ,现在重现 load 回来
        //ab.LoadAsset<ShaderVariantCollection>("height_fog.svc").WarmUp();


        var buildTarget = "Android";
        //Debug.Log($"Application.dataPath : {Application.dataPath}"); // Application.dataPath : E:/WorkFiles/UnityStudies/Testing_AB_Load_Unload/Assets
        var projectPath = Application.dataPath.Replace("/Assets", "");
        //Debug.Log($"projectPath : {projectPath}"); // projectPath : E:/WorkFiles/UnityStudies/Testing_AB_Load_Unload
        var platformABPath = $"{projectPath}/{buildTarget}/ABs";
        //Debug.Log($"platformABPath : {platformABPath}"); // projectPath : E:/WorkFiles/UnityStudies/Testing_AB_Load_Unload
        var ps_ab_path = $"{platformABPath}/{abName.ToLower()}";
        //Debug.Log($"ps_ab_path : {ps_ab_path}"); // ps_ab_path : e:/workfiles/unitystudies/testing_ab_load_unload/testingeffect_1
        if (!loaded_AB_Dict.TryGetValue(abName, out var ab))
        {
            ab = AssetBundle.LoadFromFile(ps_ab_path);
            loaded_AB_Dict.Add(abName, ab);
            if (isMajorAB)
            {
                isLoadByMajor_Dict[abName] = isMajorAB;
            }
            Debug.Log($"loaded ab : {abName}");
        }
        return ab;
    }

    private bool UnLoadAB(string abName)
    {
        if (loaded_AB_Dict.TryGetValue(abName, out var ab))
        {
            ab.Unload(true);
            loaded_AB_Dict.Remove(abName);
            Debug.Log($"unload ab : {abName}");
            return true;
        }
        return false;
    }

    private int instCount;

    public void OnLoadPS_Btn()
    {
        //var manifest = GetManifest();

        // load deps
        var abNames = new string[] 
        {
            "Assets/Textures/tex_1.png",
            "Assets/Textures/tex_2.png",
            "Assets/Materials/ps_mat_1.mat",
            "Assets/Materials/ps_mat_2.mat",
        };

        var isAnyChildABUnload = false;
        foreach (var abName1 in abNames)
        {
            if (!loaded_AB_Dict.ContainsKey(abName1))
                isAnyChildABUnload = true;
            LoadAB(abName1, false);
        }

        // load main ab
        var abName = "Assets/Effects/TestingEffect_1.prefab";
        if (isAnyChildABUnload)
        {
            UnLoadAB(abName);
        }
        var ab = LoadAB(abName, true);

        var prefab = ab.LoadAsset<GameObject>(abName.ToLower());
        var inst = GameObject.Instantiate<GameObject>(prefab);
        inst.transform.position = Vector3.zero + Vector3.up * (instCount++);
    }

    public void OnUnloadPS_Btn()
    {
        var abName = "Assets/Effects/TestingEffect_1.prefab";
        UnLoadAB(abName);
    }

    public void OnUnloadMat_Btn()
    {
        var abName = "Assets/Materials/ps_mat_2.mat";
        UnLoadAB(abName);
    }

    public void OnUnloadTex_Btn()
    {
        var abName = "Assets/Textures/tex_2.png";
        UnLoadAB(abName);
    }

    public void OnLoadMat_Btn()
    {
        var abName = "Assets/Materials/ps_mat_2.mat";
        LoadAB(abName, false);
    }
}


Shader Compiled Log

在这里插入图片描述


Project

TestingShaderCompiledLog.rar
提取码:yv4d

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1011648.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

旋转框/微调按钮的基类--QAbstractSpinBox 类

1、 QAbstractSpinBox 类是 QWidget 类的直接子类&#xff0c;虽然该类不是抽象类&#xff0c;但该类并未提供实 际的功能&#xff0c;仅为旋转框提供了一些外观的形式以及需要子类实现了成员&#xff0c; 也就是说点击微调按钮的上/下按钮&#xff0c;不会使其中的数值有变化。…

Visual Studio批量删除换行

1. 使用ctrlh可以打开替换窗体 2.alte选择窗体中的正则表达式 使用正则表达式&#xff1a; ^\s*$ ^代表行首 $代表行尾 \s代表任意不可见字符&#xff0c;例如空格、Tab等 *代表匹配\s任意次 结果&#xff1a;

002 Linux 权限

前言 本文将会向您介绍关于linux权限方面的内容&#xff0c;包括文件类型&#xff0c;如何切换用户、基本权限、粘滞位等等 Linux具体的用户 超级用户&#xff1a;可以再linux系统下做任何事情&#xff0c;不受限制 普通用户&#xff1a;在linux下做有限的事情。 超级用户的…

安卓预制权限添加规则

android:protectionLevel 可以在 android/frameworks/base/core/res/AndroidManifest.xml查询 signature|preinstalled 加在 这个文件里 privapp-permissions-xx.xml dangerous 加在 default-permissions/default-mega-permissions.xml normal 不需要加 不存在两个文件都加…

【LeetCode-中等题】18. 四数之和

文章目录 题目方法一&#xff1a;双指针&#xff08;定2动2&#xff09; 题目 方法一&#xff1a;双指针&#xff08;定2动2&#xff09; 这题可以参考【LeetCode-中等题】15. 三数之和 区别在于&#xff0c;三数之和只需要用一个for循环定住一个数&#xff0c;然后设置两个前…

类和对象(3)

文章目录 1.回顾上节2. 拷贝构造3. 运算符重载&#xff08;非常重要&#xff09;4. 赋值运算符重载 1.回顾上节 默认成员函数&#xff1a;我们不写&#xff0c;编译器自动生成。我们不写&#xff0c;编译器不会自动生成 默认生成构造和析构&#xff1a; 对于内置类型不做处理对…

mysql远程连接失败

先上结论&#xff0c;只提出最容易忽略的地方 服务器是阿里云、腾讯云等平台&#xff0c;平台本身自带的防火墙没有开启iptables规则中禁用了3306&#xff0c;即使你根本没有启用iptables服务 第二条是最离谱的 从这里可以看到&#xff0c;我服务器并未启用 iptables 服务 但…

应用在电子体温计中的国产温度传感芯片

电子体温计由温度传感芯片&#xff0c;液晶显示器&#xff0c;纽扣电池&#xff0c;专用集成电路及其他电子元器件组成。能快速准确地测量人体体温&#xff0c;与传统的水银玻璃体温计相比&#xff0c;具有读数方便&#xff0c;测量时间短&#xff0c;测量精度高&#xff0c;能…

如何分析Apple搜索广告效果

Apple搜索广告提供了一系列指标&#xff0c;报告和功能&#xff0c;可为广告效果、用户行为和关键词有效性提供有价值的见解。通过利用此工具&#xff0c;广告商可以更深入地了解他们的广告活动&#xff0c;优化他们的策略&#xff0c;并取得更好的结果。 1、在研究数据之前&a…

深入解析NLP情感分析技术:从篇章到属性

目录 1. 情感分析概述1.1 什么是情感分析&#xff1f;- 情感分析的定义- 情感分析的应用领域 1.2 为什么情感分析如此重要&#xff1f;- 企业和研究的应用- 社交媒体和公共意见的影响 2. 篇章级情感分析2.1 技术概览- 文本分类的基本概念- 机器学习与深度学习方法- 词嵌入的力量…

webStorm内存溢出问题

手动启动vue项目正常运行&#xff0c;修改部分内容保存后会自动重新run一下&#xff0c; 这个时候就报错内存溢出&#xff0c;然后很悲伤的需要再手动重启一下。 每个人的情况不同&#xff0c;下面几种方法可以都试一试。 1、修改help里的内存配置 &#xff08;图片只参考修改…

puttygen工具ppk文件版本配置

有时一些程序要用到ppk密钥文件&#xff0c;如果用puttygen去生成的话&#xff0c;ppk文件版本是可以配置的&#xff0c;有版本2、版本3&#xff0c;如果出现密钥文件无效&#xff0c;可以试一下选择不用的文件版本。 配置位置&#xff1a;打开puttygen-选择菜单栏Key-选择Para…

差分+差分矩阵(更适合新手宝宝体质)

快速掌握差分以及差分矩阵 文章目录 快速掌握差分以及差分矩阵前言差分差分的定义【官方解释】差分自定义【跟前缀和放在一起理解】差分数组的应用 题目描述差分矩阵【与前缀和矩阵进行比较】差分矩阵定义【官方解释】自定义修改操作【跟前缀和对比】 题目描述代码 前言 之前我…

微信小程序——小程序的API介绍

小程序的宿主环境-API 1.小程序API概述 小程序中的API是由宿主环境提供的&#xff0c;通过这些丰富的小程序API&#xff0c;开发者可以方便的调用微信提供的能力&#xff0c;例如&#xff1a;获取用户信息&#xff0c;本地存储&#xff0c;支付功能等。 2.小程序API的3大分类…

wav文件碎片多删除后恢复案例

wav是微软针对音频提供的一种文件&#xff0c;其本质上和qt类文件&#xff08;如mp4 mov&#xff09;是一样的&#xff0c;都是“容器”类文件。但凡是容器类的文件其关注的点就是制定规则&#xff0c;一切按规则来&#xff08;wav中就是速率、时长、编码类型等&#xff09;。这…

Linux下利用文件IO函数完成多进程复制图片,父进程复制前一半,子进程复制后一半

Linux下利用文件IO函数完成多进程复制图片&#xff0c;父进程复制前一半&#xff0c;子进程复制后一半 一 、概述 在Linux环境下&#xff0c;利用多进程完成图片的复制操作本demo用到了两个进程&#xff0c;一个是主函数所在的父进程&#xff0c;一个在主函数里面创建的子进程…

安装系统作为启动盘的U盘恢复原样

1、插U盘 2、winr——cmd&#xff0c;输入diskpart 3、此电脑——管理——磁盘管理——查看磁盘号&#xff1a;磁盘 1 4、输入&#xff1a;select disk 1——clean 5、磁盘管理——右击新建简单卷——下一步即可

u盘传输数据的时候拔出会怎么样?小心这些危害

U盘是我们日常生活和工作中常使用的一种便携式存储设备。然而&#xff0c;在使用U盘传输数据时&#xff0c;有时我们会不小心将它拔出&#xff0c;而这个看似微不足道的行为实际上可能会带来严重的后果。本文将向您介绍U盘在传输数据时突然拔出可能导致的各种危害&#xff0c;其…

如何恢复U盘里面的已经损坏的数据?

弹出使用驱动器之前&#xff0c;先将U盘格式化的信息框&#xff0c;是Windows系统针对某些特定类型的U盘或移动硬盘的一种常见处理方式。一般来说&#xff0c;如果U盘或移动硬盘出现某些故障或问题&#xff0c;Windows系统会建议用户将其格式化。 格式化是一种常规的操作&…

Kafka消费者组重平衡(二)

文章目录 概要重平衡通知机制消费组组状态消费端重平衡流程Broker端重平衡流程 概要 上一篇Kafka消费者组重平衡主要介绍了重平衡相关的概念&#xff0c;本篇主要梳理重平衡发生的流程。 为了更好地观察&#xff0c;数据准备如下&#xff1a; kafka版本&#xff1a;kafka_2.1…