Cocos Shader入门基础四:Uniform与材质参数控制

image

零、这个时代,太快


如果有朋友年龄和麒麟子相仿的话,小时候应该玩过DVD播放机,就下面图里这东西。

image

那么问题来了,你还记得,如果想要播放自己想看的内容,一共分几步吗?

和把大象装进冰箱一样简单,只需要三步:

第一步、出仓:弹出光盘托盘

第二步、换碟:把想放的光碟放进去

第三步、关仓:收回光盘托盘

如果我们想从刘德华的专辑切换到张学友的专辑,你需要重复上面的步骤。

如果我们想从听歌切换到某电影,你需要重复上面的步骤。

如果我们想从电视剧的某一集切换到另一集,你还是需要重复上面的步骤。

现在让你这样去播放节目,你肯定会觉得烦。

因为我们已经习惯了当下更先进的计算机系统和功能强大的多媒体软件。

不再需要从成堆的光碟中去寻找想要的内容。

不再需要从舒适的沙发里起身去更换想要播放的光碟。

不再需要担心心爱的光碟损坏或者被邻家王哥哥借走。

麒麟子学Shader也经历了类似的时代跨度。

80后嘛,总是免不了处于时代交叉口的命运。

十几年前,人们发现固定渲染管线(Fixed Render Pipeline)难以满足日益增长的画面要求,可编程渲染管线(Programmable Render Pipeline)应运而生。

可编程管线需要硬件支持,由于硬件更新的成本远远大于软件成本,普及速度并不能像软件那样快。

处于时代交替的3D引擎,为了兼顾所有用户的需求,一般都会支持固定管线可编程管线

那处于时代交叉口的程序员,别无选择,要同时掌握固定管线可编程管线,才能吃饱饭。

早期的可编程程管线就是在固定管线的基础上,将T&L(变换与光照)以Vertex Shader方式呈现,而纹理采样和混合则以Fragment Shader方式呈现。

随着固定管线的淘汰,可编程管线不再考虑兼容前者,如今的可编程管线不管是从功能性还是便利性而言,早已经是当初的版本无法比拟的了。

为什么麒麟子要浪费大量篇幅来讲这个。

享受当下,畅想未来,回顾历史,可以让我们生活的充满诗意。

一、什么是Uniform


image

制服?统一的?似乎都不对。

UniformGLSL的关键字,当我们需要从外部传递参数给GLSL时,就需要申明一个uniform常量。比如 uniformfloattime

麒麟子觉得,Direct3D中的称呼更确切,它叫 constant, 常量。

它有两个特点

  • 可以通过图形API(如D3DOpenGLWebGL)修改
  • Shader内不可以修改

这也是为什么Direct3D要把它叫做常量

常量的传递需要使用GPU中的常量寄存器,显然显卡寄存器并非是一个无限资源。

我们可以通过GL的枚举来查看限制。

顶点着色器常量数量限制:GL_MAX_VERTEX_UNIFORM_COMPONENTS

像素着色器常量数量限制:GL_MAX_FRAGMENT_UNIFORM_COMPONENTS

好在,这些限制都比较大,对于日常开发,我们可以暂时不关注这个问题。

如果哪天遇上特殊需求,请记得,硬件资源不是无限的。

二、Cocos Shader中的Uniform


在Cocos中,我们可以使用如下常量类型

bool int float vec2 vec3 vec4

除了声明单个常量之外,我们还可以声明常量数组。

比如,引擎中的骨骼动画(在不使用顶点纹理的情况下),需要将整个骨骼矩阵传递过来,此时就需要用到数组。

接下来,我们将在通过在Cocos Shader中添加变量的方式,一步步让大家掌握Cocos Shader中uniform的使用。

三、第一个Uniform


image

请看上图的示例

Cocos Shader要求,常量需要定义在uniform-block中,麒麟子就直接翻译成常量块了。

不用去管为什么,先记住就行。

我们定义了一个vec4 mainColor和一个vec4 colorScaleAndCutoff

其中mainColor用于物体渲染时的颜色值r,g,b,a通道都用上

colorScaleAndCutoff中,colorScaleAndCutoff.rgb用于颜色因子调子,而colorScaleAndCutoff.w用于Alpha测试判断。

Alpha测试后面会讲,这里我们暂时忽略它。

渲染效果如下,由于我们没有设置变量值,常量的默认值是0.0,所以会渲染出黑色。

image

四、通过代码控制Uniform参数


为了照顾大家迫切的心情,我们先看看如何使用代码控制常量吧。

其实使用代码控制常量非常简单。

1、新建一个TS脚本

麒麟子把脚本取名为MaterialCtrl.ts 然后写上下面这样的代码。

image

这么少的代码,大家手抄吧。

2、将MaterialCtrl.ts挂在了球体上。

3、启动浏览器预览

image

在浏览器中,你就能看到一个紫色的球。

image

注意:在编辑器中是看不到紫色的,因为我们需要TS代码行执行起来才行。

五、通过属性面板(Inspector)控制Uniform参数


有的朋友应该发现了,刚刚我们添加的mainColorcolorScaleAndCutoff并没有出现在Inspector面板里。

接下来我们就来看看,如何将一个uniform显示在面板上。

image

cocos-shader-helloworld.effect中,我们添加上图红框部分的代码。再次回到编辑器,就可以看见材质面板上多出了mainColorcolorScale两个调节参数。

image

通过调节面板,我们就能在编辑器里看到直接的效果变化,是不是很棒?

麒麟子逐一解释一下各个部分的含义。

mainColor: { value: [1, 1, 1, 1], editor: { type: color } }

mainColor:是显示在面板上的属性名称,这个名称直接与下面的uniform Constant中的 vec4 uniform自动匹配。

value:默认值

editor:用于配置编辑器面板相关参数,比如 type则用于指定面板显示内容。如果不指定,mainColor将默认以vec4显示。

这里我们希望mainColor是一个颜色,所以我们指定为color

colorScale: { value: [1, 1, 1], target: colorScaleAndCutoff.xyz }

colorScale:是属性名称,它将显示在面板上。

value:默认值

target:用于指定需要使用的变量,在这里,我们使用colorScaleAndCutoffxyz三个通道。

掌握了上面的知识,足够满足日常Shader编写的需求。如果需要进一步研究的朋友,可以查看官方文档Pass Params对应部分。如下图所示:

image

六、需要注意的点


一、mainColor可以通过Color设置,也可以通过vec4设置。在Cocos代码中,Colorvec4有一个差别,就是Color的分量是按0~255取值的,注意这个细节就行。

二、在使用代码设置材质时,请注意target.sharedMaterialtarget.material的区别。

target.sharedMaterial会直接对材质进行设置,所有引用同一个材质文件的对象均会受到影响。

target.material 若未复制,则target.material会先复制一个sharedMaterial材质,再进行操作。这样设置后,不会对其他对象造成影响,但会影响GPU Instancing等优化效果。使用的时候要慎重。

三、使用代码控制材质,编辑器中看不到效果,需要运行后查看。

四、在使用代码设置时,对于像示例中colorScale这样的定义,我们既可以对colorScaleAndCutoff进行整体设置,也可以单独对colorScale进行设置。换句话说,setProperty方法既能识别Shader中的uniform定义,也能识别Pass描述中的属性定义.

七、总结


本文从uniform含义和用途解释了uniform存在的意义。

并以mainColorcolorScale两个uniform实例演示了如何在Cocos Shader中使用uniform

与此同时,也展示了如何通过代码进行uniform操控。

在掌握本文的内容后,朋友们应该对Cocos Shader的使用流程有了整体认识。

后面的内容虽然多,但已经不再有流程上的新增,只是内容会更丰富。

能走到这里的朋友已经很厉害了,悄悄告诉你。

离渲染出美妙的花花世界,只有一步之遥。

八、预告

image

下一篇文章 《Cocos Shader入门基础五:是纹理给了你这个花花世界》 中,麒麟子将会给大家介绍纹理相关知识。

  • 纹理坐标UV是什么?
  • 纹理类型
  • 纹理寻址方式
  • 纹理采样方式
  • 定义一个类型为smapler2Duniform

关注麒麟子,阅读更多精彩文章


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容