Shader基础笔记(1)-基本结构

## 新建Shader的分类 1. Standard Surface Shader - 产生一个包含标准光照模型的表面着色器模板。 1. Unlit Shader(推荐) - 产生一个不包含光照(但包含雾效)的基本顶点/片元着色器。 1. Image Effect Shader - 为实现各种屏幕处理后效果提供的基本模板。 1. Compute Shader - 特殊Shader,利用GPU的并行特性计算一些计算。 * **ShaderLab 是 Unity 提供的编写 Unity Shader 的一种说明性语言。在 Unity 中,所有的 Unity Shader 都是使用 ShaderLab 来编写的。** ## Shader 的基本结构 ``` c# Shader "MyShader/Temp01" { Properties { _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM ENDCG } } } ``` ## Shader 基本结构说明 ### 1. 给Shader起个名字 ``` Shader "MyShader/Temp01" ``` 这一行代码设置了 Shader 在材质中出现的位置及名称: ![](http://upload-images.jianshu.io/upload_images/2223065-e4f363d0f090273f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ### 2. 属性 ``` c# Properties { _MainTex ("Texture", 2D) = "white" {} } ``` 声明这些属性是为了在材质面板中能够方便地调整各种材质属性。在 Unity 中,这些属性的名字通常由一个下划线开始。括号中的第一个参数,是属性显示在材质面板上的名字。第二个参数,是数据类型。 下面的代码给出了一个展示所有属性类型的例子: ``` c# Shader "MyShader/Temp01" { Properties { // Unmbers and Sliders _Int("Int", Int) = 2 _Float("Float", Float) = 1.5 _Range("Range", Range(0.0, 5.0)) = 3.0 // Colors and Vectors _Color("Color", Color) = (1,1,1,1) _Vector("Vector", Vector) = (2,3,6,1) // Textures _2D("2D", 2D) = ""{} _Cube("Cube", Cube) = "white"{} _3D("3D", 3D) = "black"{} } FallBack "Diffuse" } ``` ![](http://upload-images.jianshu.io/upload_images/2223065-099a9a5d67963bf9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) **TIPS:**编译器对 Shader 的支持普遍不好,其中比较好用的还是 JetBrans 公司的 Rider。 ### 3. SubShader 每一个 Unity Shader 文件可以包含多个 SubShader 语义块,但至少一个。当 Unity 需要加载这个 Unity Shader 时, Unity 会扫描所有的SubShader 语义块,然后选择第一个能够在目标平台上运行的 SubShader。如果都不支持,Unity 会使用 Fallback 语义指定的 Unity Shader。 每个Pass定义了一次完整的渲染流程,但如果Pass的数目过多,往往会造成渲染性能的下降。因此,应当尽量使用最小数目的Pass。 SubShader 语义块中包含的定义通常如下: ··· Subshader{ // 标签,可选的 [Tags] // 状态,可选的 [RenderSetup] Pass{ } // Other Passes } ··· SubShader 内的具体内容放到以后再写。 ## 最简单的 Unity Shader 尽管 Unity Shader 可以做的事情非常多(例如设置渲染状态等),但其最重要的任务还是指定各种着色器所需的代码。这些着色器代码可以写在 SubShader 语义块中(表面着色器的做法),也可以写在 Pass 语义块中(顶点/片元着色器和固定函数着色器的做法)。 在 Unity 中,我们可以使用2种最常用的形式来编写 Unity Shader。 ### 1. 表面着色器(Surface Shader) 表面着色器是 Unity 自己创造的一种着色器代码类型,它需要的代码量很少,Unity 在背后做了很多工作,但渲染的代价比较大。其本质与接下来的顶点/片元着色器一样,我们可以理解成 Unity 对顶点/片元着色器的更高一层的抽象。它存在的价值在于,Unity为我们处理了很多光照细节,使得我们不需要再操心这些“烦人的事情”。 一个非常简单的例子: ```c# Shader "MyShader/Temp01" { Subshader{ Tags { "RenderType" = "Opaque" } CGPROGRAM #pragma surface surf Lambert struct Input{ float4 clolr : COLOR; }; void surf (Input IN, inout SurfaceOutput o){ o.Albedo = 1; } ENDCG } FallBack "Diffuse" } ``` 可见,表面着色器被定义在 SubShader 语义块(而非Pass语义块)中的 CGPROGRAM 和 ENDCG 之间。原因是:表面着色器不需要开发者关心使用多少个 Pass、每个 Pass 如何渲染等问题,Unity 会在背后为我们做好这些事情。我们要做的只是告诉它:“嘿,使用这些纹理去填颜色,使用这个法线纹理去填充法线,使用Lambert光照模型,其他的不要来烦我!” ### 2. 顶点/片元着色器(Vertex/Fragment Shader) 顶点/片元着色器更加复杂,但也更加灵活。 一个非常简单的例子: ```c# Shader "MyShader/Temp01" { Subshader{ Pass{ CGPROGRAM #pragma vertex vertex #pragma fragment fra float4 vert(float4 v : POSITION) : SV_POSITION { return UnityObjectToClipPos (v); } fixed4 frag() : SV_Target { return fixed4(1.0, 0.0, 0.0, 1.0); } ENDCG } } } ``` 我们将主要使用顶点/片元着色器。 ## 扩展阅读 Unity官网的 Unity Shader 文档:[官方文档](https://docs.unity3d.com/Manual/SL-Reference.html)

你可能感兴趣的:(Shader基础笔记(1)-基本结构)