首页 > 代码库 > Unity的shader学习2

Unity的shader学习2

下面继续看基于surface的shader代码,基本与Vertex&Fragment shader差不多,只是不能写pass,然后只需要声明surface函数,就能处理所有的事情。

 1 Shader "T1/Hero/Diffuse" { 2     Properties { 3         _MainTex ("Base (RGB)", 2D) = "white" {} 4         _Color ("Main Color", Color) = (1,1,1,1) 5         [HideInInspector]_BlendColor("_Blend Color", Color) = (1, 1, 1, 0) 6         [HideInInspector]_BlendIntensity ("BlendColorShininess", Range (1, 4)) = 1 7     } 8     SubShader { 9         Tags { "Queue" = "Geometry+20" "RenderType"="Opaque"}10         LOD 20011 12         CGPROGRAM13        // #include "T1.cginc"14         #pragma surface surf LambertT1HeroSideLight   15         #pragma only_renderers d3d9 opengl 16 17         sampler2D _MainTex;18         fixed4 _Color;19 20         struct Input {21             float2 uv_MainTex;22         };23 24         #include "T1.cginc"25 26         void surf (Input IN, inout SurfaceOutput o) {27             half4 c = tex2D (_MainTex, IN.uv_MainTex) ;28             #if defined (UNITY_PASS_FORWARDBASE) || defined (UNITY_PASS_PREPASSFINAL)29                 o.Albedo =  lerp (c.rgb* _Color.rgb, _BlendColor * _BlendIntensity,  _BlendColor.a);30             #else31                 o.Albedo =  c.rgb* _Color.rgb;32             #endif33             o.Alpha = 0; 34             o.Emission = c.rgb * _heroSelfIllumin;35         }36         ENDCG37     } 38     FallBack "Hidden/T1/VertexLit-Hero"39 }

 第3行的_MainTex声明后,就可以在第17行中引用到。

 第5-6行的HideInInspector意思是不在编辑器的属性界面显示,隐藏起来。然后_BlendColor表示一个颜色,_BlendIntensity表示0-1的值。看后面的意思可以得知是混合颜色和混合强度。

 第9行的RenderType=Opaque表示声明是一个不透明的物体,具体解释在这里,然后"Queue" = "Geometry+20"其实就是说渲染层次是2000+20,就是比一般的不透明物体层次要高一点。

 第10行的LOD这个数值决定了我们能用什么样的 Shader。在Unity的Quality Settings中我们可以设定允许的最大LOD,当设定的LOD小于SubShader所指定的LOD时,这个SubShader将不可用。Unity 内建Shader定义了一组LOD的数值。具体解释在这里。200是默认的diffuse值。

 第14行的#pragma surface surf Lambert,它声明了我们要写一个表面Shader,并指定了光照模型。它的写法是这样的

  #pragma surface surfaceFunction lightModel [optionalparams]

  • surface - 声明的是一个表面着色器
  • surfaceFunction - 着色器代码的方法的名字
  • lightModel - 使用的光照模型。

 Lambert就是普通的diffuse漫反射光照模型。

 第15行#pragma only_renderers d3d9 opengl表示限制这个shader只编译在d3d9和opengl上。具体解释在这里

 第17行sampler2D就是GLSL中的2D贴图的类型,相应的,还有sampler1D,sampler3d,samplerCube等等格式。不啰嗦了

 第18行的fixed4主要用来表示颜色rgba四个数值。

 第20行的Input声明后,主要是用来给surf函数来使用的。

 第26行-34行主要是CG规定了声明为表面着色器的方法(就是我们这里的surf)的参数类型和名字,因此我们没有权利决定surf的输入输出参数的类型,只能按 照规定写。这个规定就是第一个参数是一个Input结构,第二个参数是一个inout的SurfaceOutput结构。

 这里用到了一个tex2d函数,这是CG程序中用来在一张贴图中对一个点进行采样的方法,返回一个float4。这里对_MainTex在输入点上进行了采 样,并将其颜色的rbg值赋予了输出的像素颜色。

 28行的主要意思见这里。这里主要是前向渲染或者延迟渲染的话,物体颜色就需要考虑混合的颜色和混合的亮度,否则就直接取颜色。

 33行,设置无透明。

 34行表示自发光,这个值是图片的颜色乘以t1定义的自发光亮度常量。