UPL9-18——优化移动端渲染性能
UPL9-18——优化移动端渲染性能 避免 alpha 测试 对于一些低端移动设备,透明度测试是一项特别消耗资源的任务 在大多数的情况下,我们应该尽量避免使用透明测试,而是使用透明混合来代替 最小化 DrawCall 移动设备上高 DrawCall 通常比填充率更容易造成性能瓶颈 因此利用批处理或者自己合并网格来降低 DrawCall 是移动平台上提高性能表现的有效手段 我们应该尽量在移动平台上保证最小的 DrawCall 最小化材质数量 材质数量和 DrawCall 数量息息相关,使用更少的材质,可以有效减少 DrawCall,还可以避免打断批处理 并且它有有助于解决内存带宽问题,因此我们应该在移动平台上保证最小化材质数量 最小化纹理大小 和桌面 GPU 相比,大多数的移动设备的纹理缓存都非常小,对于一些老移动设备(iphone6s 以前),最大纹理大小仅支持 1024 * 1024 大小 目前市面上的大部分移动设备已经支持 2048 *...
UPL9-17-g——Compute Shader 常用 API
UPL9-17-g——Compute Shader 常用 API Compute Shader 常用 API 我们目前已经掌握了 Compute Shader 的核心知识点,已经能够使用 Compute Shader 来帮助我们来完成计算需求 这里整理 Compute Shader 中的常用 API (大部分学习过,补充部分新 API) C# 常用 API 通过 ComputeShader 对象调用 查找入口函数索引 1ComputeShader.FindKernel(string name) 示例可见:UPL9-17——Compute Shader 按线程组数量启用GPU执行 1ComputeShader.Dispatch(int kernelIndex, int x, int y, int z) 示例可见:UPL9-17——Compute Shader 设置参数相关API 12345678ComputeShader.SetFloat(string name, float value) //...
UPL9-17-f——获取 GPU 数据
UPL9-17-f——获取 GPU 数据 本章代码关键字 12345678computeBuffer.GetData() // 同步获取ComputeBuffer对象的计算结果,传入需要获取结果的数组即可AsyncGPUReadback.Request() // 异步读取GPU计算结果请求,需要传入要异步获取数据的对象,例如ComputeBuffer和RenderTextureAsyncGPUReadbackRequest // 异步读取GPU计算结果的请求类,通过该类获取计算结果asyncGPUReadbackRequest.GetData<>() // 获取GPU计算结果,返回NativeArray<>,泛型参数如果是数组传入数组元素的类型,如果是数组传入Color类型asyncGPUReadbackRequest.hasError // GPU计算是否有报错RenderTexture.active ...
UPL9-17-e——参数的系统语义
UPL9-17-e——参数的系统语义 本章代码关键字 123SV_DispatchThreadID // 调度线程 ID,每个线程的全局索引(系统自动传入)SV_GroupThreadID // 组内线程 ID,当前线程在组内的局部索引SV_GroupID // 线程组 ID,当前线程组在整个 Dispatch 中的索引 入口函数参数的系统语义 Compute Shader 的内核入口函数中参数的主要有三个系统语义: SV_GroupID SV_GroupThreadID SV_DispatchThreadID 语义:是 CG / HLSL 中的一种“数据标签” 用来告诉 GPU 某个变量在渲染管线或计算管线中代表什么意义 语义是 Shader 输入、输出变量的角色标签 它告诉 GPU,这个变量从哪里来、要传到哪里去、它在管线中扮演什么角色 具体可见:US2S3L9——语义 例如:新创建出来 Compute Shader 中的默认入口函数的默认参数 id 语义就是...
UPL9-17-d——组内线程数量
UPL9-17-d——组内线程数量 Compute Shader 中的执行模型 Compute Shader 的执行模型可分为三层结构 第一层 —— 线程 HLSL 函数内部自动生成,由 GPU 并行执行的最小计算单元,负责执行入口函数的一次调用 第二层 —— 线程组 Compute Shader 中由 [numthreads(x, y, z)] 定义, 每个组内包含固定数量的线程,共享组内内存、可进行同步 第三层 —— 线程组网格 C# 侧 Dispatch() 调用,定义多少个组要被 GPU 启动,控制全局总线程数 相当于: GPU 线程会执行入口函数 入口函数前的 [numthreads(x, y, z)] 决定单个 线程组内 线程数量 C# 侧调用 Dispatch 时传入的 x、y、z 决定要启动多少个 线程组 三个轴向的数字代表什么 入口函数前的 [numthreads(x, y, z)] 用于控制 每个线程组一共有多少个线程 比如:[numthreads(8, 8, 1)],表示每个线程组有 8 * 8 * 1 = 64...
UPL9-17-c——数据输入规则
UPL9-17-c——数据输入规则 本章代码关键字 12345678910111213computeShader.SetFloat() // 设置float类型基本数据computeShader.SetInt() // 设置int类型基本数据,也可以用于设置uint类型数据computeShader.SetBool() // 设置bool类型基本数据computeShader.SetVector() // 设置float4(Vector4)向量数据,也可以用于非float4(Vector4)向量数据传递computeShader.SetFloats() // 可以用于设置float3, float2向量数据,也可以用于设置float数组数据computeShader.SetInts() // 可以用于设置int3, int2向量数据,也可以用于设置int数组数据computeShader.SetMatrix() //...
UPL9-17-b——数据类型
UPL9-17-b——数据类型 Compute Shader 中的数据类型 Compute Shader 的数据类型和普通 HLSL(即 Unity Shader)非常接近, 但由于它不走渲染管线,它的重点在于 通用计算与内存访问,因此在类型体系上有一些专门针对 数据并行 和 存储 的扩展 主要分为: 标量类型 向量类型 矩阵类型 复合类型 纹理类型 常量缓冲区 注意:这里只强调常用的类型 标量类型 bool:布尔类型 uint:32位无符号整形 int:32位整形 float:32位浮点数,符号:f double:64位浮点数 half:16位浮点数,符号:h 注意:虽然支持 half,但是由于对齐问题和平台支持问题以及和 C# 数据交互问题(C# 没有 half 类型),不建议在 ComputeShader 中使用 123456bool b; // 1byteint i; // 4byteuint ui; // 4bytefloat f; // 4bytedouble d; // 8bytehalf h; ...
UPL9-17-a——多个入口函数
UPL9-17-a——多个入口函数 本章代码关键字 1#pragma kernel // 通过 #pragma kernel 声明入口函数,可以有多个(请注意在 #pragma kernel 指令的同一行上不允许 "// text" 样式的注释) 多个入口函数的含义 一个 Compute Shader 文件可以定义多个 Kernel(内核),即多个入口函数 每个 Kernel(内核)入口函数可以有独立的线程数量配置 我们在 CPU 端(C# 侧)需要为每个入口函数单独调用 Dispatch() 基本原理:我们每声明一个入口函数,都会被编译为一个独立的 内核(Kernel),相当于 GPU 上的一个可单独调用的计算程序 多个入口函数声明和使用方式 在 Compute Shader 中使用 #pragma kernel 定义多个内核入口函数 注意: 入口函数不能重名(在一个 Compute Shader 文件中) 入口函数可以共享该 Compute Shader 中声明的变量 ...
UPL9-17——Compute Shader
UPL9-17——Compute Shader 本章代码关键字 123ComputeShader // ComputeShader类,可以关联计算Shader资源computeShader.FindKernel() // 查找computeShader某个kernel函数的索引,需要传入函数名,通过索引去执行入口函数computeShader.Dispatch() // 传入要执行的kernel函数的索引,同时传入xyz线程组,线程组传入数量和kernel函数声明的线程组的线程数量有关 Compute Shader Compute Shader (计算着色器) 是让 GPU 帮你算东西的程序,是一种在 GPU 上运行的 通用计算程序 属于 GPGPU(通用 GPU 计算 —— General-Purpose GPU Computing)的一部分 它的核心目标是:让开发者脱离渲染管线,直接利用 GPU 的并行计算能力来处理计算任何类型的数据 举例说明 CPU...
UPL9-16——善用 GPU 并行特性
UPL9-16——善用 GPU 并行特性 善用 GPU 并行特性是什么意思 GPU 的强项是高度并行,同时处理成百上千个像素和顶点、线程同时工作 善用并行特性,意思就是把计算分成许多相对简单、独立、可并行的工作单元,避免会破坏并行效率的做法! 目标是让每个 GPU 线程做少量且规则的工作,从而提高吞吐量并降低延迟与功耗 向量化运算 GPU 的 ALU(算术逻辑单元)通常以 4-wide SIMD 形式工作,能同时处理 4 个 float 分量 4-wide SIMD (单指令多数据流,Single Instruction, Multiple Data),即 GPU(或某个执行单元)一次执行同样的运算指令时,会并行处理 4 个数据元素 因此我们在着色器中进行计算时,最好进行一次性“向量运算”,比如: 不好的做法:分开计算 123float r = tex2D(_Tex, uv).r;float g = tex2D(_Tex, uv).g;float b = tex2D(_Tex, uv).b; 好的做法:一次性向量运算 1float3 rgb = tex2D(_Tex,...
