2018-09-18学习shader

那么我们就从编写第一个Shader开始。

首先,我们在Unity里创建一个Shader。


双击打开这个shader,shader里的内容我们先不管,直接清空,贴入下面这段代码:

Shader"Custom/BasicDiffuse"{

Properties {

_MainTex ("Albedo (RGB)",2D) ="white"{}

}

SubShader {

Tags {"RenderType"="Opaque"}

LOD200

CGPROGRAM

#pragma surface surf Lambert

sampler2D _MainTex;

structInput{

float2 uv_MainTex;

};

voidsurf(Input IN, inout SurfaceOutput o){

fixed4 c = tex2D (_MainTex, IN.uv_MainTex);

o.Albedo = c.rgb;

o.Alpha = c.a;

}

ENDCG

}

FallBack"Diffuse"

}

这是一个最简单的shader。

Properties里面包含的是shader的属性。以_MainTex为例, _MainTex表示变量名,Albedo(RGB)是在编辑器里显示的名称,2D是它的类型,表示它是一个纹理,white是默认值。

表面着色器的属性类型:

Range (min, max)

创建 Float 属性,以滑动条的形式便于在最大值和最小值之间进行调节创建色块,

Color

可以在 Inspector 面板上通过拾色器获取颜色值 = (float,float,float,float)

2D

创建纹理属性,允许直接拖曳一个纹理

Rect

创建一个非 2 次方的纹理属性,作为 2D GUI 元素

Cube

在 Inspector 面板上创建一个立方贴图属性,允许用户直接拖曳立方贴图作为着色器属性

Float

在 Inspector 面板上创建一个非滑动条的 float 属性

Vector

创建一个拥有 4个float值的属性,可以用于标记方向或颜色 

SubShader是子着色器,一个着色器中可以包含多个SubShader。子着色器这是代码的主体,计算着色的时候,平台会按顺序选择一个可以使用的子着色器进行执行,如果所有的子着色器都无法使用,则会执行最后FallBack里指定的着色器。

我们来看SubShader的主体:

Tags(标签)标记了着色器的一些特性。

常用的Tag有:

RenderType:渲染类型,常用就是Opaque(不透明)和Transparent(透明)。

IgnoreProjector:是否忽略投影器,True or False。

ForceNoShadowCasting:是否强制无阴影,True or False。

Queue:渲染队列,内置值Background=1000,Geometry=2000,AlphaTest=2450,Transparent=3000,Overlay=4000,但是并不限于这些值,你可以填写自己的值,或者写成"Queue"="Transparent+10"也是可以的。

LOD是Level of Details的缩写,表示着色器的细节层级,高于Unity的最大LOD(Quality Settings里设置)的shader将不可用。在调低画质时,可以根据这个值舍弃掉一部分shader。

紧接着是CGPROGRAM,它与ENDCG对应,表明在二者范围内是一段Cg(C for graphics)代码。

#pragma surface surf Lambert

这一行表明我们使用的是一个表面着色器,方法名称是surf,光照模型是Lambert。

然后是

sampler2D _MainTex;

sampler2D对应于Properties里面的2D,是2D贴图的数据结构。而_MainTex也对应于Properties里面的_MainTex,保存了编辑器(或者代码)里设置的贴图。二者必须是同名,才能将贴图数据链接起来。简而言之,下面的_MainTex是上面的_MainTex在Cg代码里的代理。

然后是一个结构(struct)定义:

structInput{

float2 uv_MainTex;

};

这个结构是为surf方法定义了输入参数的数据结构。

float2表示这是一个二维的浮点型坐标。

其他的内置类型还包括:

half:半精度浮点型,范围[-60000,60000]

fixed:低精度定点型,范围[-2,2]

int:整型

bool:布尔型

sample*d:纹理类型

uv_MainTex表示_MainTex的纹理坐标(参考百度百科UV坐标),这是一种命名约定。

最后是surf方法:

voidsurf(Input IN, inout SurfaceOutput o){

fixed4 c = tex2D (_MainTex, IN.uv_MainTex);

o.Albedo = c.rgb;

o.Alpha = c.a;

}

Input结构是我们在上面定义的。

SurfaceOutput的数据结构:

structSurfaceOutput {

half3 Albedo;//像素的颜色

half3 Normal;//像素的法向值

half3 Emission;//像素的发散颜色

half Specular;//像素的镜面高光

half Gloss;//像素的发光强度

half Alpha;//像素的透明度

};

surf方法主体第一行:

fixed4 c = tex2D (_MainTex, IN.uv_MainTex);

使用tex2D方法从_MainTex里面取出指定纹理坐标(IN.uv_MainTex)的色彩值。

取出来色彩值之后,很简单,将c的rgb分量赋值给输出o的Albedo,把c的a分量赋值给输出o的Alpha。

那么我们已经可以读懂一个最简单的shader了,那么是不是应该自己再写一个:

Shader"Custom/TestColor"{

Properties {

_Color ("Color", Color) = (1,1,1,1)

}

SubShader {

Tags {"RenderType"="Opaque"}

LOD200

CGPROGRAM

#pragma surface surf Lambert

fixed4 _Color;

structInput{

float2 uv_MainTex;

};

voidsurf(Input IN, inout SurfaceOutput o){

o.Albedo = _Color.rgb;

o.Alpha = _Color.a;

}

ENDCG

}

FallBack"Diffuse"

}

在Unity编辑器里新建一个材质,将材质的shader设置成我们新写的TestColor。然后在场景里面加入一个Cube,并将Cube的材质设置为我们新建的材质。

这样我们就完成了一个最简单的单色材质,可以通过调节材质的颜色来调节Cube的颜色了。

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

推荐阅读更多精彩内容