[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.
随机推荐
- THML DOM / Element 对象操作
随着Vue等MVVM框架流行,操作DOM已经不想之前那么频繁,因此很多DOM的操作已经陌生,特此回顾HTML中DOM操作 获取Element节点 熟悉的有 通过ID获取,返回element对象 ...
- ubuntu16.04搭建geodjango+postgresql+postgis的WebGIS框架(三)加载空间数据
之前两篇基本上搭好了geodjango开发的环境了,当然你的电脑上肯定要有python和django的环境(这个我就不介绍了,网上一搜一大堆),我自己用的python3.5和django2.0(毕竟2 ...
- 选择、操作web元素
11月1日 什么是web元素 Selenium自动化主要就是:选择界面元素,操作界面元素(输入操作:点击.输入文字.拖拽等,输出操作:获取元素的各种属性),根据界面上获取的数据进行分析和处理 选择元素 ...
- python 如何获取当前文件/文件夹
python 如何获取当前文件/文件夹? 1.获取当前文件的实际路劲: os.path.realpath(__file__) ==> D:\python_test\test_p ...
- Spring Cloud Config中文文档
https://springcloud.cc/spring-cloud-config.html 目录 快速开始 客户端使用 Spring Cloud Config服务器 环境库 健康指标 安全 加密和 ...
- Spring boot http, https
1:同时支持http, https配置 参考文献: https://www.cnblogs.com/lianggp/p/8136540.html 2:http 转发到 https配置 @Bean p ...
- cookie操作:设置cookie、读取cookie、删除cookie
一.设置cookie function setCookie(name, value){ Days = 1; var exp = new Date(); exp.setTime(exp.getTime( ...
- OS位数,基本概念,结合iOS
CPU位数,一般指CPU支持的指令集位数,32位CPU对应32位的指令集,64位的CPU对应64位的指令集,不过为了向下兼容,64位CPU也支持32位的指令集. 操作系统位数,一般指操作系统对应的指令 ...
- js 引入外部文件之 script 标签
在我的理解看来,html 就是一个单纯的管显示问题,js就是单纯的管动作问题,css就是单纯的管布局问题,这三个构成了一个网页 在HTML中,经常会用到引入js 文件. 引入js的方法很简单: 1. ...
- React/anu实现弹出层2
这次是使用了一个比较罕见的APIReactDOM.unstable_renderSubtreeIntoContainer,ReactDOM.unstable_renderSubtreeIntoCont ...