[Unity3D]降低向Shader中传值的开销
2015-06-05 01:29
399 查看
摘要
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。相关文章推荐
- Kinect结合Unity3D引擎开发体感游戏(一)
- Flex 性能优化常用手法总结
- oracle 性能优化建议小结
- Lua性能优化技巧(一):前言
- Lua性能优化技巧(五):削减、重用和回收
- Lua性能优化技巧(三):关于表
- Lua性能优化技巧(四):关于字符串
- MySQL性能优化 出题业务SQL优化
- PowerShell脚本性能优化技巧总结
- SQL SERVER性能优化综述(很好的总结,不要错过哦)第1/3页
- MySQL Index Condition Pushdown(ICP)性能优化方法实例
- Ajax无刷新分页的性能优化方法
- dedecms负载性能优化实例,三招让你的dedecms快10倍以上第1/2页
- 如何减少浏览器的reflow和repaint
- JQuery教学之性能优化
- jQuery 性能优化手册 推荐
- jQuery 性能优化指南(2)
- JQuery性能优化的几点建议
- jQuery 性能优化指南(3)