博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Unity3D]降低向Shader中传值的开销
阅读量:6883 次
发布时间:2019-06-27

本文共 1183 字,大约阅读时间需要 3 分钟。

Unity3D中提供了很多API用于向shader传值,这篇文章对比测试了两类不同的使用方法的性能。

正文

Unity3D中,通过C#代码向shader传值有两种方式。 

一种是面向具体的material,另一种是面向所有的material。 
以上两种方式分别对应下面两类API:

  • Material.SetXXX();
  • Shader.SetGlobalXXX();

例如,现在的需求是,需要每帧向shader传递一个offset、一个scale、和一个alpha。

普通的做法是:

在shader中添加:

float _Offset;    float _Scale;    float _Alpha;

在C#中通过以下方式进行传值:

Shader.SetGlobalFloat("_Offset", offset);    Shader.SetGlobalFloat("_Scale", scale); Shader.SetGlobalFloat("_Alpha", alpha);

以上写法可以正常工作,但是更好的方法是下面这种:

Shader中:

float4 _Parameter;

C#中:

Vector4 parameter = new Vector4(offset, scale, alpha, 0);    Shader.SetGlobalVector("_Parameter", parameter );

第二种方法在GPU寄存器的使用方面会优于第一种方法,因为不论是SetFloat还是SetVector,都会占用一个寄存器。CPU和GPU通信次数越少性能开销也就越少。 

用下面的方法做一下测试,可以发现两种方式在CPU方面开销变化很明显,在我的电脑上,万次循环一帧大约可以节省2ms左右。

void Update(){    for (int i = 0; i < 10000; i++) { if (_switcher) { Shader.SetGlobalVector("_Parameter", new Vector4(1, 0, 0, 1)); } else { Shader.SetGlobalFloat("_R", 0); Shader.SetGlobalFloat("_G", 1); Shader.SetGlobalFloat("_B", 1); Shader.SetGlobalFloat("_A", 1); } } }

最后

其实这个技巧也不仅仅局限于Unity3d,在dx和gl中也应该是这样,思想是通用的,如果谁能分享一些不是非常难的结合代码的GPU和CPU通信的学习资料大普通将be very appreciate。

转载于:https://www.cnblogs.com/lancidie/p/7832933.html

你可能感兴趣的文章
PAT (Advanced Level) 1107. Social Clusters (30)
查看>>
【开源社群系统研发日记五】ThinkSNS+ 是如何计算字符显示长度的
查看>>
Nodejs日志管理log4js
查看>>
python获取昨日日期
查看>>
海康威视 - 萤石云开放平台 js 版
查看>>
关于分销平台
查看>>
剑指offer---12-**--数值的整数次方
查看>>
PAT - L2-010. 排座位(并查集)
查看>>
Linux下chkconfig命令详解(转)
查看>>
EF中,保存实体报错:Validation failed for one or more entities. 如何知道具体错误在哪?...
查看>>
和积式
查看>>
你不能错过.net 并发解决方案
查看>>
[PHP] 超全局变量$_FILES上传文件
查看>>
linux如何添加telnet服务
查看>>
解决Windows对JDK默认版本切换问题
查看>>
HTML5本地存储localStorage与seesionStorage
查看>>
06笨小猴(1.9)
查看>>
UNIX网络编程——原始套接字的魔力【上】
查看>>
web应用开发技术(第二版)崔尚森第八章部分作业
查看>>
thinkCMF----列表页跳转
查看>>