Shader其实就是根据你的输入,进行计算转换,再次输出,渲染绘制
1.Shader 结构:
Shader "shader名称" { //属性 Properties { } //子着色器 //可以有多个SubShader,他会根据硬件从上到下,选择当前硬件所支持的代码进行运算 SubShader { Pass { } } . . . //如果不硬件不满足所有SubShadr则调用默认,最基础的shader FallBack "Diffuse" }
2.unity着色器属性介绍(表格借用4.x 入门到精通):ShaderLab: Properties
语法 | 说明 |
名称("显示名称",Vector)=默认值 | 四维向量属性 |
名称("显示名称",Color)=默认值 | 颜色,(0-1四维向量) |
名称("显示名称",Float)=默认值 | 浮点数 |
名称("显示名称",Range(min,max))=默认值 | 范围浮点数 |
名称("显示名称",2D)=默认值 | 2D纹理 |
名称("显示名称",Rect)=默认值 | 矩形纹理 |
名称("显示名称",Cube)=默认值 | 立方体纹理,CubeMap |
3.SubShader Tags主要设置渲染队列、渲染类型、阴影和投影等:ShaderLab: SubShader Tags
SubShader { Tags{"TagName1" = "Value1" "TagName2" = "Value2"} }
TagName1和TagName2为标签名,常用为"Queue"与"RenderType",Value1和Value2为变量,具体参照官网链接
4.Pass Tags,主要是LightMode设置:ShaderLab: Pass Tags
5.还有一些其他很重要的参数参数,比如剔除&深度测试,透明测试,混合等,在编写Shader中都会经常使用:ShaderLab: Pass
上面是shader的一些基本介绍,这里就开始在unity实际的编写shader,在unity中分为三种shader,表面shader、顶点片段shader和固定功能管线shader
1.表面shader(unity再次封装的shader,简单易用)
表面shader只需要将自输入的参数传给他指定的输出参数,即可以显示效果:表面shader的输出参数
表面shader的示例:Surface Shader Examples
创建的第一个表面shader
Shader "Custom/FirstSurfaceShader" { Properties { //基础属性 并显示在属性板上 _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _Glossiness ("Smoothness", Range(0,1)) = 0.5 _Metallic ("Metallic", Range(0,1)) = 0.0 } SubShader { //设置渲染队列、渲染类型、阴影、投影 Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM // Physically based Standard lighting model, and enable shadows on all light types //表面shader的编译命名 相当于函数调用 #pragma surface surf Standard fullforwardshadows // Use shader model 3.0 target, to get nicer looking lighting #pragma target 3.0 sampler2D _MainTex; //输入参数 struct Input { float2 uv_MainTex; }; //需要将属性中的变量再次声明 才能使用 half _Glossiness; half _Metallic; fixed4 _Color; //表面shader的输出函数 void surf (Input IN, inout SurfaceOutputStandard o) { // Albedo comes from a texture tinted by color //计算纹理与颜色的结果 并将rgb赋值给Albedo fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; o.Albedo = c.rgb; // Metallic and smoothness come from slider variables o.Metallic = _Metallic; o.Smoothness = _Glossiness; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
2.顶点片段shader(功能最强大,需要CG语言)
顶点片段shader则相对麻烦得多,不过也是需要掌握的技能,先看一下示例:Vertex and Fragment Shader Examples
创建的第一个顶点片段shader
Shader "Unlit/FirstUnlitShader" { Properties { //基础属性 并显示在属性板上 _MainTex ("Texture", 2D) = "white" {} } SubShader { //设置渲染队列、渲染类型、阴影、投影 Tags { "RenderType"="Opaque" } LOD 100 //顶点片段的Shader需要在Pass通道里编写 //可以有多个通道,每个通道都会渲染一遍 Pass { //CG代码需要编写在CGPROGRAM...ENDCG之间 CGPROGRAM //编译命令 一个顶点程序 一个片段程序 #pragma vertex vert #pragma fragment frag // make fog work #pragma multi_compile_fog #include "UnityCG.cginc" //输入参数 struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; //顶点的数据 struct v2f { float2 uv : TEXCOORD0; UNITY_FOG_COORDS(1) float4 vertex : SV_POSITION; }; //变量声明 sampler2D _MainTex; float4 _MainTex_ST; //计算顶点 v2f vert (appdata v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); UNITY_TRANSFER_FOG(o,o.vertex); return o; } //计算片段 所使用参数是计算顶点后返回的数据 fixed4 frag (v2f i) : SV_Target { // sample the texture //计算纹理的颜色 并返回 fixed4 col = tex2D(_MainTex, i.uv); // apply fog UNITY_APPLY_FOG(i.fogCoord, col); return col; } ENDCG } } }
3.固定功能管线shader(最原始的shader,基本上已经不推荐使用)