Unity Shader基础( 五)Shader种类

一.Unity Shader种类

1.Surface Shader(表面着色器)

示例

// **********************************************************************
// Copyright (C) 2018 Blazors
// Please contact me if you have any questions
// File Name:             MyShader
// Author:                romantic123fly
// WeChat||QQ:            at853394528 || 853394528 
// **********************************************************************
//片元着色器
Shader "Custom/SurfaceShader" {
	//属性。此语义块的作用仅仅是为了让这些属性显示在材质面板中
	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
	}
		//每一个Shader都可以包含多个SubShader语义块,最少要有一个。当Unity加载shader时就会扫描所有的语义块,
	    //然后选择第一个能在平台上运行的SubShader。如果都不支持,unity就会使用FallBack语义指定的UnityShader。
	SubShader {
	    //标签类型设置,可以设置多个标签,每个标签间以空格隔开
		Tags { "RenderType"="Opaque" "PreviewType" = "Plane"}
		//渲染设置
		LOD 200
		CGPROGRAM
		// Physically based Standard lighting model, and enable shadows on all light types
		#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;	
		void surf (Input IN, inout SurfaceOutputStandard o) {
			// Albedo comes from a texture tinted by color
			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"
}

Unity自己创造的一种着色器代码类型,少量的代码可以实现很大的功能,但其实它扩展开了就是顶点/片元着色器,只不过Unity替你封装好了很多代码,这样反而渲染代价比较大,你可以创建一个Surface Shader模板,看一下代码仅仅几行,然后可以在Inspector上点击show generated code,如下图:

Unity Shader基础( 五)Shader种类_第1张图片

然后你会看到它生成了一个庞大到让你想发狂的代码,立马就不想学了,哈哈,不过其实它就是生成了一个顶点/片元着色器的代码,就那几个模块,建议学完顶点/片元着色器再回头看看。不过写Surface Shader倒是很容易的,尤其是复杂的光照部分不用你管了,后面会有单独章节介绍。

2.Vertex/Fragment Shader(顶点/片元着色器)

示例:

[cpp]  view plain  copy
  1. Shader "Custom/VertexFragmentShader" {  
  2.     Properties {  
  3.         _MainTex ("Texture", 2D) = "white" {}  
  4.     }  
  5.     SubShader {  
  6.         Pass {  
  7.             CGPROGRAM  
  8.             #pragma vertex vert  
  9.             #pragma fragment frag  
  10.               
  11.             #include "UnityCG.cginc"  
  12.   
  13.             struct appdata  
  14.             {  
  15.                 float4 vertex : POSITION;  
  16.                 float2 uv : TEXCOORD0;  
  17.             };  
  18.   
  19.             struct v2f  
  20.             {  
  21.                 float2 uv : TEXCOORD0;  
  22.                 float4 vertex : SV_POSITION;  
  23.             };  
  24.   
  25.             v2f vert (appdata v)  
  26.             {  
  27.                 v2f o;  
  28.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);  
  29.                 o.uv = v.uv;  
  30.                 return o;  
  31.             }  
  32.               
  33.             sampler2D _MainTex;  
  34.   
  35.             fixed4 frag (v2f i) : SV_Target  
  36.             {  
  37.                 fixed4 col = tex2D(_MainTex, i.uv);  
  38.                 return col;  
  39.             }  
  40.             ENDCG  
  41.         }  
  42.     }  
  43. }  

我们主要学习的着色器,可以使用Cg/HLSL语言来编写,相对表面着色器复杂一些,但灵活性更高。

3.Fixed Function Shader(固定函数着色器)

示例:

[cpp]  view plain  copy
  1. Shader "Custom/FixedFunctionShader" {  
  2.     Properties {  
  3.         _Color ("Main Color", Color) = (1,1,1,1)  
  4.     }  
  5.     SubShader {  
  6.         Pass {  
  7.             Material {  
  8.                 Diffuse [_Color]  
  9.             }  
  10.             Lighting On  
  11.         }  
  12.     }  
  13. }  

相对于上面两个可编程管线,固定管线技术已经落伍了,当然旧设备不支持可编程管线的要用固定函数着色器,而现在绝大多数GPU都支持可编程技术,而且Unity5.x目前所有固定函数着色器都会被编译成对应的顶点/片元着色器。

综上所述,虽然表面上Unity有三种着色器类型,但经过转化其实就只有一种:顶点/片元着色器,这也是我们后面着重学习的对象。


4、CG/HLSL,GLSL

相对于早期编写着色器的汇编语言,后来开发出了更高级的着色语言,常见的有DirectX的HLSL(High Level Shading Language),OpenGL的GLSL(OpenGL Shading Language),NVIDIA的CG(C for Graphic)。这些语言会被编译成汇编语言,也叫中间语言(Intermediate Language, IL)。中间语言再交给显卡驱动翻译成机器语言,即GPU可以理解的语言。

我们看到上面的Surface Shader和Vertex/Fragment Shader的代码示例,发现核心代码都放在CGPROGRAM和ENDCG之间,其实它们是在ShaderLab内部嵌套的CG/HLSL语言,因为CG和DX9风格的HLSL从写法上几乎是一样的,所以在Unity里CG和HLSL是等价的。我们也可以用GLSL来写,但发布平台会少一些,GLSL要嵌套在GLSLPROGRAM和ENDGLSL之间。

通常,Unity会自动把这些CG片段编译到所有相关平台上(D3D9,D3D11,OpenGL ES等),我们可以通过点击shader面板上的Compile and show code旁边的下拉按钮来看它当前编译的平台,你也可以更改要编译的平台。如下图:

Unity Shader基础( 五)Shader种类_第2张图片

但当发布游戏时,游戏数据文件中只包含目标平台需要的编译代码,其他平台的代码会被移除。

你可能感兴趣的:(Shader学习之路,游戏渲染着色器)