1.unity的shader是通过Materials绑定的。在制作Materials的时候就指定了一个shader。
2.生成一个sprite的时候会指定他的Materials,这样shader就与sprite建立了联系。修改Materials的shader,所有应用这个Materials的物体都会受影响。
3. unity的shader语法:
unity包含几种shader:
1) Surface Shaders: 主要处理光照和阴影,利用了Unity的光照流水线,是一种较高层次的抽象。如果不使用光照则不要使用这种shader,因为会有不必要的性能消耗。使用Cg/HLSL编写shader代码,但最终的shader是需要编译生成的。
2)Vertex and Fragment Shaders: 一般shader了,可以实现任意效果,当然也要处理所有的事情,并且不能利用Unity的光照系统了。同样也使用Cg/HLSL编写。
Shader "xx/xx/shaderName":指定shader的name。在为Materials指定shader的时候,就是指定的这个name。
默认创建的shader分为:Properties和SubShader两个部分。
Properties部分:
在Properties{}中定义着色器属性(应该是opengl的uniform吧),在这里定义的属性将被作为输入提供给所有的子着色器。每一条属性的定义的语法是这样的:
_Name("Display Name", type) = defaultValue[{options}]
_Name - 属性的名字,简单说就是变量名,在之后整个Shader代码中将使用这个名字来获取该属性的内容。但是在使用前也要申明该变量。
Display Name - Unity的材质编辑器中属性的名字,可以在这里指定属性的值。 type - 这个属性的类型,可能的type所表示的内容有以下几种: Color:一种颜色,由RGBA四个量来定义; 2D:2的阶数大小的贴图。 Rect :非2阶数大小的贴图。 Cube :即Cube map texture(立方体纹理),简单说就是6张有联系的2D贴图的组合。 Float:浮点数; Vector:四维数;defaultValue 定义了这个属性的默认值,
option:它只对2D,Rect或者Cube贴图有关,在写输入时我们最少要在贴图之后写一对什么都不含的空白的{}
SubShader部分( 每个shader包含多个子shader, 至少包含有一个。当加载shader时, Unity会遍历所有子shader.从上往下选择与你显卡兼容的SubShader,并顺序执行他们。这对多平台编码是非常有用,因为你可以在一个文件中编写同一shader的不同版本。如果没有可以支持的, Unity会试着用Fallback shader):
Tags { "RenderType"="Opaque" }
表面着色器可以被若干的标签(tags)所修饰,而硬件将通过判定这些标签来决定什么时候调用该着色器。比如上面那句话,告诉了系统应该在渲染非透明物体时调用它。
LOD:这个数值决定了我们能用什么样的Shader。在Unity的Quality Settings中我们可以设定允许的最大LOD,当设定的LOD小于SubShader所指定的LOD时,这个SubShader将不可用。
Cull Back—— 不绘制背离观察者的几何面
Cull Front—— 不绘制面向观察者的几何面,用于由内自外的旋转对象 Cull Off —— 显示所有面。用于特殊效果。Lighting On:开启光照
Lighting Off:关闭光照ZWrite On | Off:用于控制是否将对象的像素写入深度缓冲(默认开启),如果需要绘制纯色物体,便将此项打开。如果要绘制半透明效果,关闭深度缓冲,则用ZWrite Off。
Blend One OneMinusSrcAlpha:设置混合方式。
Pass:具体对渲染进行操作的单元。在这里可以设置颜色,材质,贴图等。
shader本体:
CGPROGRAM表示开始CG程序,ENDCG表示CG结束。
#pragma surface surf Standard fullforwardshadows表示我们要写一个表面Shader。
shader的传值(通过properties接收):
Object [] renderers = GameObject.FindObjectsOfType(typeof(Renderer));
int i_max = renderers.Length; for (int i = 0; i < i_max; i++) { Material[] materials = ((Renderer)renderers[i]).materials; int j_max = materials.Length; for (int j = 0; j < j_max; j++) { if (materials[i].shader.name == "Light_Value") {//SetColor...
materials[i].SetFloat("Attend", 10.0f); } } }在顶点shader里面:OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);表示将物体顶点变换到屏幕坐标。UNITY_MATRIX_MVP是一个uniform,表示物体的视投影矩阵。
4.shader常用函数:
clip:检查它的参数是否小于0。如果是,就调用discard舍弃该fragment;否则就放过它。
比如clip(col.a-_Cutoff);将只显示col.a>_Cutoff的
5.shader数据类型
float:32位高精度浮点数。
half:16位中精度浮点数。范围是[-6万, +6万],能精确到十进制的小数点后3.3位。 fixed:11位低精度浮点数。范围是[-2, 2],精度是1/256。