CS003-2-2-perfermance

44、shader预热

a. 避免游戏运行时shader编译导致的卡顿

b. shader编译过程,着色器代码需要被编译成gpu能够理解的机器码。也就是将高级语言hlsl编写的shader编译成gpu可以直接执行的指令。在编译的过程中,还会有编译优化,展开循环,内联函数,以及对代码进行重新排序等。

45、C#中弱引用

a. 允许引用一个对象,但不阻止该对象被gc。

b. 使用举例

复制代码
public class WeakReferenceTest : MonoBehaviour
{
    WeakReference weakRef;
    // Start is called before the first frame update
    void Start()
    {
        // 创建一个对象
        var myObject = new TestWeakReferenceObj();
 
        // 创建弱引用
        weakRef = new WeakReference(myObject);
 
        // 解除强引用,只保留弱引用
        myObject = null;
 
        // 通过弱引用访问对象
        if (weakRef.IsAlive)
        {
            var obj = weakRef.Target as TestWeakReferenceObj;
            obj.DoSomething();
        }
        else
        {
            Debug.Log("对象已被回收");
        }
    }
 
    // Update is called once per frame
    void Update()
    {
        // 通过弱引用访问对象
        if (weakRef.IsAlive)
        {
            var obj = weakRef.Target as TestWeakReferenceObj;
            obj.DoSomething();
        }
        else
        {
            Debug.Log("对象已被回收");
        }
    }
}
 
class TestWeakReferenceObj { 
    public void DoSomething()
    {
        Debug.Log("对象没有被回收");
    }
}

C. 泛型写法

复制代码
public class WeakReferenceTest : MonoBehaviour
{
    WeakReference<TestWeakReferenceObj> weakRefGeneric;
    // Start is called before the first frame update
    void Start()
    {
        weakRefGeneric = new WeakReference<TestWeakReferenceObj>(new TestWeakReferenceObj());
 
        if (weakRefGeneric.TryGetTarget(out TestWeakReferenceObj obj))
        {
            obj.DoSomething();
        }
        else
        {
            Debug.Log("对象已被回收");
        }
    }
 
    // Update is called once per frame
    void Update()
    {
        if (weakRefGeneric.TryGetTarget(out TestWeakReferenceObj obj))
        {
            obj.DoSomething();
        }
        else
        {
            Debug.Log("对象已被回收");
        }
    }
}
 
class TestWeakReferenceObj { 
    public void DoSomething()
    {
        Debug.Log("对象没有被回收");
    }
}

d. 适用场景,缓存大型对象,但允许gc在需要时回收它们。

e. 性能上,频繁检查弱引用是否存在可能影响性能。

46、贴图的格式

a. read/write,纹理资源的内存占用是计算在显存中的,也就是传向gpu端的部分。而开启read/write enabled选项的纹理资源还会保留一份在cpu端,从而造成该资源内存占用翻倍。

b. mipmap,当一张纹理开启mipmap时,它的内存占用会上升为原始数据的1.33倍。对于3d对象,比如场景中的地形、物件或人物,其纹理的mipmap功能是建议开启的,可以在运行时降低带宽。对于2d项目或ui界面资源,建议将对应的mipmap功能关闭,从而避免不必要的内存开销。

47、网格资源

Unity移动端游戏性能优化简谱之 常见游戏内存控制 - 知乎

a. 顶点和面数

v是顶点数,t是三角面数,不同part,比如脸部、头部、身体、脚网格加起来,大致有个概念。

顶点数在2w个,三角面在3w左右。

nami模型的复杂度举例:

v 5295 t 7732

v 3544 t 4607

v 4063 t 6275

v 8288 t 12836

2w顶点 31450三角面

luffy模型的复杂度举例:

v 2403 t 3906

v 3825 t 5736

v 7734 t 12755

v 1150 t 1769

v 644 t 642

v 1176 t 1456

16932顶点 26264 三角面

b. 顶点属性,去除不需要的顶点属性

c. read/write enabled,一般而言,不需要在cpu端进行修改的网格是不需要开启read/write的。可以在编辑器中通过api修改这些网格的read/write属性,或者编辑器面板中直接设置。

48、shader.parse

a. shader.parse将shader源代码字符串解析为unity可以识别的shader对象,但不会编译为gpu程序。

b. shader.creategpuprogram,显示编译shader代码为gpu可执行的程序,生成渲染管线中使用的底层指令。creategpuprogram编译shader可能会引起卡顿。

49、unsafe和fixed

a. 在unity中,以下情况通常需要fixed。处理NativeArray时。

b. unsafe代码块,不一定总是需要fixed,但当你需要通过指针操作托管堆撒上的对象时,就必须使用fixed来固定内存。

复制代码
unsafe void ProcessArray(int[] managedArray)
{
    fixed (int* ptr = managedArray) // 必须fixed,因为数组在托管堆上
    {
        for(int i = 0; i < managedArray.Length; i++)
        {
            ptr[i] *= 2;
        }
    }
}

c. fixed使用访问托管对象的,会"钉住"对象,阻止gc在固定期间移动对象。

d. 不需要fixed的举例

复制代码
unsafe void StackAllocExample()
{
    int* array = stackalloc int[10]; // 栈上分配,不需要fixed
    for(int i = 0; i < 10; i++) 
    {
        array[i] = i;
    }
}

50、astc

a. 区块编码

最简单的块编码,从定义两种颜色的"端点"开始。端点定义了两种颜色,通过在两种颜色之间进行插值生成许多额外的颜色。

b. astc是有损压缩格式。

c. astc使用块压缩。所谓的块压缩,即将贴图分为固定大小的块,每个块内的颜色值压缩在一起。当随机访问一个贴图的像素时,只要计算其所属的块,将块解压缩即可获得颜色值。这样就充分利用gpu的并行处理能力。

d. 原理Unity ASTC贴图压缩格式探秘 - 知乎

astc采用梯度渐变gradient存储颜色值。每个block会存储一对终点颜色(end-point colors),每个纹素存储一个插值权重,根据权重插值end-point colors即可获得原始颜色。

e. astc支持4x4到12x12的block大小,block大小以像素为单位。8x8的block即表示块对应原始贴图里width和height为8x8 texels区域。

f. 一个block的压缩后,大小固定128bits。也就是不管4x4、5x5、8x8最后压缩都是在128位内。所以block越大,压缩越严重,失真越严重。

相关推荐
有梦想的骇客5 小时前
书籍“之“字形打印矩阵(8)0609
java·算法·矩阵
yours_Gabriel6 小时前
【java面试】微服务篇
java·微服务·中间件·面试·kafka·rabbitmq
门前云梦7 小时前
《C语言·源初法典》---C语言基础(上)
c语言·开发语言·学习
hashiqimiya7 小时前
android studio中修改java逻辑对应配置的xml文件
xml·java·android studio
liuzhenghua668 小时前
Python任务调度模型
java·运维·python
結城8 小时前
mybatisX的使用,简化springboot的开发,不用再写entity、mapper以及service了!
java·spring boot·后端
小前端大牛马8 小时前
java教程笔记(十一)-泛型
java·笔记·python
sjtu_cjs8 小时前
Tensorrt python api 10.11.0笔记
开发语言·笔记·python
东阳马生架构8 小时前
商品中心—2.商品生命周期和状态的技术文档
java
哆啦A梦的口袋呀8 小时前
深入理解系统:UML类图
开发语言·python·uml