[Unity3D]降低向Shader中传值的开销
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。
[Unity3D]降低向Shader中传值的开销的更多相关文章
- 【Unity Shaders】Shader中的光照
写在前面 自己写过Vertex & Fragment Shader的童鞋,大概都会对Unity的光照痛恨不已.当然,我相信这是因为我们写得少...不过这也是由于官方文档对这方面介绍很少的缘故, ...
- Unity关闭shader中的光照模型以及如何自定义光照模型
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject' // Upgrade NOTE: replaced '_Wor ...
- unity, multi pass shader中的surface pass
今天尝试写一个multi pass shader,但其中有一个Pass是surface pass,总是莫名奇妙地报错.后来看到下面帖子: http://forum.unity3d.com/thread ...
- java中传值及引伸深度克隆的思考(说白了Java只能传递对象指针)
java中传值及引伸深度克隆的思考 大家都知道java中没有指针.难道java真的没有指针吗?句柄是什么?变量地址在哪里?没有地址的话简直不可想象! java中内存的分配方式有两种,一种是在堆中分配, ...
- 关于获取URL中传值的解决方法
在我们页面的URL中包含着很多信息,包括域名,协议等等这里就不一一介绍了),对于我们开发者而言,使用比较多的就是页面之间的传值.为什么要页面传值呢?很简单,当你在浏览一个商品页面的时候你要看到一个商品 ...
- 【Unity Shaders】Diffuse Shading——在Surface Shader中使用properties
本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...
- OpenGL下多个sampler在shader中的使用
在OpenGL中,sampler2D/Cube等做为uniform可以在fragment shader中使用.结合glActiveTexture和glUniform1i,实现texture与sampl ...
- 关于获取URL中传值的解决方法--升级版
这次页面之间的传值是升级版本,为什么是升级版本呢,因为这次页面的传值不一样了.大家可以看一下我原来的文章<关于获取URL中传值的解决方法> 其实上次就已经比较清楚的介绍了页面之间的传值,但 ...
- unity, shader中获得当前像素深度
frag shader中直接访问i.pos.z就是深度,不必除以i.pos.w,因为系统已经自动进行过了透视除法且已将i.pos.w置为0.
随机推荐
- STM32F103C8开发板原理图和管脚图
- 让linux每天定时备份MySQL数据库并删除五天前的备份文件
MYSQL定期备份是一项重要的工作,但人工操作太繁琐,也难避免有所疏漏,使用下面的方法即可让系统定期备份数据.利用系统crontab来定时执行备份文件,按日期对备份结果进行保存,达到备份的目的. 1. ...
- python 阿狸的进阶之路(6)
常用模块 json # 序列化 #将内存的数据存到硬盘中,中间的格式,可以被多种语言识别,跨平台交互数据 #json 可以将字典之类的数据类型存到字典中 import json dic = {&quo ...
- Android虚拟机与Java虚拟机 两种虚拟机的比较
在Android的体系框架中有一部分叫做Android Runtime,即Android运行时环境,这个环境包括了两个部分,一个是Android的核心类库,还有一个就是Dalvik虚拟机了. Andr ...
- RocketMQ服务搭建_1
rocketmq是阿里研发,并贡献给Apache的一款分布式消息中间件. RcoketMQ 是一款低延迟.高可靠.可伸缩.易于使用的消息中间件. ACE环境:(Adapted communicatio ...
- 1037B--Reach Median(中位数)
median 中位数 odd 奇数 even 奇数 You are given an array aa of nn integers and an integer ss. It is guarante ...
- Redis进阶实践之六Redis Desktop Manager连接Windows和Linux系统上的Redis服务(转载6)
Redis进阶实践之六Redis Desktop Manager连接Windows和Linux系统上的Redis服务 一.引言 今天本来没有打算写这篇文章,但是,今天测试Redis的时候发现了两个问题 ...
- 13.Java国际化.md
一.国际化开发概述 软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的.符合来访者阅读习惯的页面或数据. 国际化(internationaliz ...
- eval 用法
计算 eval('1+1') # 2 在字典中提取键 的值 eval('a',{'a':1}) # 1 计算 Boolean 值 eval( 'True',{'a':1}) # True eval(' ...
- 16.2 profile 显示或者隐藏页面 修改密码
我们auth在clent端有更加强大的功能 显示或者隐藏component 或者 我们可以阻止或者允许某个用户访问url