在写shader的时候,其实一些写法对于其执行影响非常大,而且由于gpu和cpu在架构上的不同,代码的优化思想也不一样,最近一直在写几个shader,为了性能问题,查阅了很多资料,把一些tips总结下来。

首先要树立几个思想:

1.gpu是SIMD的架构,即单指令多数据流架构,即在gpu上同时执行n个数据和执行1个数据的效率是一样的,我们要

尽量的把并行的计算搬到gpu上

2.gpu是以向量计算为基础设计的,也就是说在gpu上执行一个向量乘法和执行一个float的乘法的效率是一样的,

并不向cpu那样要多执行几次

3、通常,需要渲染的像素比顶点数多,而顶点数又比物体数多很多。所以如果可以,尽量将运算从PS移到VS,或直接通过script来设置某些固定值;

所以

1.尽量把一些计算合并成向量计算,记住一个向量计算和一个float计算那样快!

比如

float x,y;

x = x * a;

y = y * b;

不如写成 float2 v = float2(x,y);

v = v*float2(a,b);

因为前一种写法是两次乘法计算,而后一种只要1次

2.不要在gpu里面用分支或者条件判断这种语句,尽管大多数gpu 的shader支持这种语法,但是多数gpu里面的

这种控制语句涉及到一些同步等消耗的操作,其实大多数这种语句都可以用数值的方式替代。

比如 你想写

  1. float4 a;
  2. if(b > 1)
  3. {
  4. a.a=1;
  5. }
  6. else
  7. {
  8. a.a =0.5;
  9. }

可以改写成

  1. float4 a;
  2. float tmp = step(b,1);
  3. a = tmp * 0.5 + (1-tmp);

if else可以被step出来的0 或1的乘法代替又比如

  1. float4 a;
  2. if(b && c || d && e)
  3. {
  4. a.a = 1;
  5. }
  6. else
  7. {
  8. a.a = 0.5;
  9. }

可以写成

  1. float4 a;
  2. float tmp = step(1, (float)b*(float)c + float(d)*float(e));
  3. a = tmp + (1-tmp) * 0.5;

&& 我们用转换到float后的乘法代替,||可以被判断加法step 1代替

而这种操作,尤其是shader内置的函数比条件判断和分支的效率要高很多,别忘了,GPU纯粹是为了计算的,而不是做判断

3.尽量使用shader为我们提供的内置函数,这些内置的函数比我们想象的要快很多,往往应用了某些gpu的特殊特性。

比如要比较a和b谁大用max(a,b),还有例如上面反复用的step,虽然你可以写用(float)(a>=1)来替换step(1,a),

但是这还是没有内置函数更快的,包括常用的saturate()把一个数归到0-1,总之一句话,如果能用一个内置函数替换

你的某些代码,就尽量替换。而且这些内置函数基本上都是支持对向量操作的,所以如果用step(a,fixed3(1,2,3))其

实只是一条指令,但是却可以同时返回用a同1 2 3分别比较的结果。

4.使用swizzle是非常快的,例float4 a = float4(1,1,1,1),用a.wz = float2(2,3)要比 a.w=3; a.z=2要高效很多

5.浮点数精度相关:
  float:最高精度,通常32位
  half:中等精度,通常16位,-60000到60000,
  fixed:最低精度,通常11位,-2.0到2.0,1/256的精度。
  尽量使用低精度。对于color和unit length vectors,使用fixed,其他情况,根据取值范围尽量使用half,实在不够则使用float。
  在移动平台,关键是在fragment shader中尽可能多的使用低精度数据。另外,对于多数移动GPU,在低精度和高精度之间转换是非常耗的,在fixed上做swizzle操作也是很费事的。

6.Alpha Test
  Alpha test和clip()函数,在不同平台有不同的性能开销。
  通常使用它来cull那些完全透明的像素。
  但是,在ios和一些android上使用的PowerVR GPUs上面,alpha test非常的昂贵。

7、Color Mask
  在移动设备上,Color Mask也是非常昂贵的,所以尽量别使用它,除非真的是需要。

8、在使用Surface Shader时,可以通过一些指令让shader优化很多。
  通常情况下,Surface shader的很多默认选项都是开启的,以适应大多数情况,但是很多时候,你可以关闭其中的一些选项,从而让你的shader运行的更快:
  (1) approxview 对于使用了view direction的shader,该选项会让view dir的normalize操作per-vertex进行,而不是per-pixel。这个优化通常效果明显。
  (2) halfasview 可以让Specular shader变得快一些,使用一个介于光照方向和观察方向之间的half vector来代替真正的观察方向viewDir来计算光照函数。
  (3) noforwardadd Forward Render时,完全只支持一盏方向光的per-pixel渲染,其余的光照全部按照per-vertex或SH渲染。这样可以确保shader在一个pass里渲染完成。
  (4) noambient 禁掉ambient lighting和SH lighting,可以让shader快一点儿。

shader程序员需要注意的优化Tips的更多相关文章

  1. 面向.Net程序员的后端性能优化实战

    最近2个月没做什么新项目 完全是对于旧的系统进行性能优化 避免超时 死锁 数据处理能力不够等常见的性能问题 这里不从架构方面出发 毕竟动大手脚成本比较高 那么我们以实例为前提 从细节开始 优化角度 一 ...

  2. C++程序员容易走入性能优化误区!对此你怎么看呢?

    有些C++ 程序员,特别是只写C++ 没有写过 Python/PHP 等慢语言的程序员,容易对性能有心智负担,就像着了魔一样,每写3 行代码必有一行代码因为性能考虑而优化使得代码变形(复杂而晦涩). ...

  3. 程序员修炼之道中所有tips总结

    1         关心你的技艺 如果你不在乎能否漂亮地开发出软件,你又为何要耗费生命去开发软件呢? 2         思考!你的工作 关掉自动驾驶仪,接管操作.不断地批评和评估你的工作. 3    ...

  4. 程序员必备SQL语句优化技巧

    1.任何地方都不要使用 select * from t ,用具体的字段列表代替"*",不要返回用不到的任何字段. 2.尽量使用数字型字段,字符型会降低查询和连接的性能,并会增加存储 ...

  5. Oracle学习总结(8)—— 面向程序员的数据库访问性能优化法则

    特别说明: 1.  本文只是面对数据库应用开发的程序员,不适合专业DBA,DBA在数据库性能优化方面需要了解更多的知识: 2.  本文许多示例及概念是基于Oracle数据库描述,对于其它关系型数据库也 ...

  6. PHP程序员福利“看免费直播,学MySQL索引优化”

    六星教育了解到,MySQL是目前所知PHP最流行的关系型数据库管理系统之一,它将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性.之所以它会成为主流使用数据库,这 ...

  7. fir.im Weekly - 每个程序员都应当拥有的技能树

    本周收集了一些优秀的 iOS & Android 开发资源和程序员 IT 技能拓展的 Tips. 知道创宇研发技能表 v3.0 作为程序员可能都听说过[知道创宇],他们是一家黑客文化浓厚的安全 ...

  8. 对于长沙互联网发展,一个外来两年Java程序员的所见所感所愿

    惟楚有材,于斯为盛 本文有感于2019长沙互联网求职招聘大会,内容比较多,但都是我自己的一些所见.所感和所愿. 2019年3月的最后一天,参加2019长沙互联网求职招聘大会,看到了很多的招聘企业,也看 ...

  9. PHP对程序员的要求更高

     我这个文章标题可不是和大家开玩笑的哦  首先, 大家都知道, PHP也是一种编译型脚本语言, 和其他的预编译型语言不同, 它不是编译成中间代码, 然后发布.. 而是每次运行都需要编译.. 为此, 也 ...

随机推荐

  1. 使用javascript正则表达式实现遍历html字符串

    最近在尝试实现一个js模板引擎,其中涉及到使用js解析html字符串的功能.由于我实现的这个模板不止是要能替换参数输出html字符串,还要可以解析出每个dom元素的名称及参数啥的. 网上找到了一个叫做 ...

  2. jersey实现文件下载

    好久没有更新博客了,今天来再次总结一下,之前有整理过关于jersey实现文件上传功能的相关知识,但是前一阵子在实习过程中写接口又要实现文件下载的功能,由于这些东西基本都是使用jersey提供的注解和接 ...

  3. Requests模块 HTTP for Humans

    安装方式 $ pip install requests 基本GET请求(headers参数 和 parmas参数) 1.最基本的GET请求可以直接用get方法 response = requests. ...

  4. JavaScrpit判断横竖屏

    JavaScript function setLandscapeClass(){ if(window.orientation === 90 || window.orientation === -90 ...

  5. Python中import机制

    Python语言中import的使用很简单,直接使用import module_name语句导入即可.这里我主要写一下"import"的本质. Python官方定义:Python ...

  6. scrollTop的兼容性

    各浏览器下 scrollTop的差异 IE6/7/8: 对于没有doctype声明的页面里可以使用 document.body.scrollTop 来获取 scrollTop高度 : 对于有docty ...

  7. Java中 &&与&,||与|的区别

    区别 &&  || 是逻辑运算,支持短路运算 & | 是位运算,不支持短路运算 短路运算 当有多个表达式时,左边的表达式值可以确定结果时,就再继续运算右边的表达式的值; 举例 ...

  8. 视觉SLAM

    SLAM:Simultaneous Localization And Mapping.中文:同时定位与地图重建. 它是指搭载特定传感器的主体,在没有实验先验信息的情况下,于运动过程中建立环境的模型,同 ...

  9. Another option for file sharing(转)

    原文地址  https://security.googleblog.com/2017/02/another-option-for-file-sharing.html Another option fo ...

  10. Python函数篇(7)-正则表达式

    1.正则表达式   正则表达式为高级的文本模式匹配,抽取,与/或文本形式的搜索和替换功能提供了基础,简单的来说,正则表达式是由一些字符和特殊符号组成的字符串.Python通过标准库中的re模块来支持正 ...