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中传值的开销的更多相关文章

  1. 【Unity Shaders】Shader中的光照

    写在前面 自己写过Vertex & Fragment Shader的童鞋,大概都会对Unity的光照痛恨不已.当然,我相信这是因为我们写得少...不过这也是由于官方文档对这方面介绍很少的缘故, ...

  2. Unity关闭shader中的光照模型以及如何自定义光照模型

    // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject' // Upgrade NOTE: replaced '_Wor ...

  3. unity, multi pass shader中的surface pass

    今天尝试写一个multi pass shader,但其中有一个Pass是surface pass,总是莫名奇妙地报错.后来看到下面帖子: http://forum.unity3d.com/thread ...

  4. java中传值及引伸深度克隆的思考(说白了Java只能传递对象指针)

    java中传值及引伸深度克隆的思考 大家都知道java中没有指针.难道java真的没有指针吗?句柄是什么?变量地址在哪里?没有地址的话简直不可想象! java中内存的分配方式有两种,一种是在堆中分配, ...

  5. 关于获取URL中传值的解决方法

    在我们页面的URL中包含着很多信息,包括域名,协议等等这里就不一一介绍了),对于我们开发者而言,使用比较多的就是页面之间的传值.为什么要页面传值呢?很简单,当你在浏览一个商品页面的时候你要看到一个商品 ...

  6. 【Unity Shaders】Diffuse Shading——在Surface Shader中使用properties

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  7. OpenGL下多个sampler在shader中的使用

    在OpenGL中,sampler2D/Cube等做为uniform可以在fragment shader中使用.结合glActiveTexture和glUniform1i,实现texture与sampl ...

  8. 关于获取URL中传值的解决方法--升级版

    这次页面之间的传值是升级版本,为什么是升级版本呢,因为这次页面的传值不一样了.大家可以看一下我原来的文章<关于获取URL中传值的解决方法> 其实上次就已经比较清楚的介绍了页面之间的传值,但 ...

  9. unity, shader中获得当前像素深度

    frag shader中直接访问i.pos.z就是深度,不必除以i.pos.w,因为系统已经自动进行过了透视除法且已将i.pos.w置为0.

随机推荐

  1. Mysql索引,有哪几种索引,什么时候该(不该)建索引;SQL怎么进行优化以及SQL关键字的执行顺序

    索引(Index)是帮助MySQL高效获取数据的数据结构.提取句子主干,就可以得到索引的本质:索引是数据结构. 1.按照索引列值的唯一性,索引可分为唯一索引和非唯一索引 非唯一索引:B树索引 crea ...

  2. Spring boot 配置嵌入式Servlet容器

    SpringBoot默认使用Tomcat作为嵌入式的Servlet容器 1.修改和server有关的配置(ServerProperties[也是EmbeddedServletContainerCust ...

  3. python-玉米(小米)商城作业

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. css-图片垂直居中

    1. img { vertical-align: middle; }   2. <body> <div> <img src="1.jpg" alt=& ...

  5. css:调整placeholder样式

    input::-webkit-input-placeholder, textarea::-webkit-input-placeholder { color: #C5CACF; } input:-moz ...

  6. 知识点4: 配置echarts折线图和饼图

    折线图 效果图 html <template> <div id="v11-charts3"></div> </template> j ...

  7. img标签插入图片返回403,浏览器可以直接打开

    参考:https://segmentfault.com/q/1010000011752614/a-1020000011764026 博客园引入外部图片出现,出现403问题,应该是加了防盗链,会检测访问 ...

  8. 16.监听器-基础.md

    目录 概念 监听器功能 监听创建或销毁 监听属性变化 session相关监听 概念 实现特定接口的普通java类 *监听特定对象的创建.销毁或属性变化: 对象自己创建自己用:无需监听 对象别人创建自己 ...

  9. 15.Colection集合和Iterator接口.md

    目录 1.Collection 1.1概念 1.1遍历方法-Lambda表达式 1.2遍历方法-Iterator接口 1.3使用Lambda方法遍历Iterator接口 1.4使用Foreach方法遍 ...

  10. Hibernate 再接触 一对多单向关联

    在1的方向加多的集合 Group.java package com.bjsxt.hibernate; import java.util.HashSet; import java.util.Set; i ...