顶点/片元着色器的基本架构

《Unity Shader 入门精要读书笔记--初级篇--第五章》

      • 顶点/片元着色器的基本架构
      • 渲染平台的差异
      • 示例代码


顶点/片元着色器的基本架构

顶点/片元着色器不能说是Unity Shader族群中最闪耀的那一个,但却是最为强大的一个。在Unity中,顶点/片元着色器的英文名称是Unlit Shader(以下简称为US),尽管拥有着较为复杂原始的代码,但是US的功能可谓是王者级别的存在。除了US之外,在剩余三种着色器中,最常用的当属标准表面着色器Standard Surface Shader(以下简称SSS)了,而SSS可以实现的,US也全部都能实现。
US与GPU管线的关系相较于SSS看起来更为紧密。在GPU管线中,顶点着色器和片元着色器分属于几何阶段与光栅化阶段;而在US中,顶点着色器由顶点函数实现,片元着色器由片元函数实现。因此,虽然SSS广为人知,但想要真正一窥Unity实时渲染的奥妙与精髓,则需要掌握US的使用说明。
一、 US基本架构:

Shader "ShaderName"{
	Properties{
	//各种面板属性
	}
	SubShader{
	//显卡A的Subshader
	//标签设置
	Pass{
	//标签设置
	CGPRAGMA
	#......
	#......//各种预编译指令
	
	...
	...
	
	ENDCG
	}
	//一个Pass为一个渲染模块
	//其他pass
	}
	
	SubShader{}//其他显卡的
	//回调方法
	Fallback "VertexLit"
}

二、 代码详解

  1. Shader “ShaderName” 是整个shader文件的开头,告诉Unity本shader的名字和相对位置,如
    Shader "Unity Shaders Book/Chapter 5/Simple Shader"
    我们可以在如下位置找到这个shader
    顶点/片元着色器的基本架构_第1张图片
  2. properties属性并不是Unity Shader中一个必要的组件,但却能帮助开发者灵活地调整shader属性。任何写在Properties中的属性都会开放在Unity可视化的组件面板“Inspector”中,供开发者随时调整。
    如:
    	Properties
    		  {       
    			 _Color("Color Tint",Color) = (1.0,1.0,1.0)    
    		  }
    

则:
顶点/片元着色器的基本架构_第2张图片

  1. Subshader中的Tags设置了属于Subshader中所有pass共享的标签属性,具体的标签设置将会在后序介绍。
  2. Pass是Shader的灵魂所在,相当于是Shader最小执行单元。
  3. 在pass内部也可以设置一系列Tags来控制pass的行为,另外,其他所有代码被包含在CGPROGRAMENDCG 之中。
    • #include指令设置了该pass所包含的头文件;而 #pragma定义了一系列预编译指令,其中,最为关键的是:
      #pragma vertex vert_func_name //声明顶点着色器函数
      #pragma fragment frag_func_name //声明片元着色器函数

    • 其次,定义用于在顶点着色器和片元着色器之间通信的结构体与变量:

      a2v-----application to vertex
      v2f------vertex to fragment

    • 之后定义之前声明的顶点和片元函数,片元函数输出最终调制好的像素颜色(格式为fixed4)

  4. 在 SubShader之后声明备用的着色器,以防先前的subshader不可用。例如:Fallback "Specular"
  5. 需要特别注意的是:片元着色器的输入是顶点着色器的输出经过插值之后的结果!

三、 数据类型
ShaderLab与Cg变量类型匹配关系

ShaderLab属性类型 Cg变量类型
Color,Vector float4,half4,fixed4
Range,Float float,half,fixed
2D sampler2D
Cube samplerCube
3D sampler3D
  • 数据宽度:float>half>fixed

四、 语义
语义用于告知系统所声明的变参数的意义。

  • a2v:POSITION、NORMAL、TANGENT、TEXCOORDn、COLOR
  • v2f:SV_POSITION、COLOR0、COLOR1、TEXCOORD0~7
  • fragment:SV_TARGET

渲染平台的差异

DirectX OpenGL
屏幕坐标系原点位于左上角 屏幕坐标系原点位于左下角
不允许缺省参数 一些情况下允许缺省参数
不支持在顶点着色器中使用tex2D 支持在定点着色器中使用tex2D
左手坐标系 右手坐标系
矩阵行优先 矩阵列优先
裁剪空间z坐标[0,1] 裁剪空间z坐标[-1,1]

示例代码

Shader "Unity Shaders Book/Chapter 5/Simple Shader" {    
		Properties{        
			_Color("Color Tint",Color) = (1.0,1.0,1.0)
			  }
        	 SubShader{           
        		Pass{                
	        		CGPROGRAM                                
	        		#pragma vertex vert                
	        		#pragma fragment frag
	                	fixed4 _Color;
	                	struct a2v{                    
	                	float4 vertex : POSITION;                    
	                	float3 normal : NORMAL;                    
	                	float4 texcoord : TEXCOORD0;                
	                     };                
	                struct v2f{                
	                	float4 pos : SV_POSITION;                
	                	fixed3 color : COLOR0;                
	                     };                
                	v2f vert(a2v v){                    
		                v2f o;                    
		                o.pos = UnityObjectToClipPos(v.vertex);                    
		                o.color = v.normal*0.5 + fixed3(0.5, 0.5, 0.5);                    
		                return o;                
	                      }
	                fixed4 frag(v2f i) : SV_Target{                    
	                	fixed3 c = i.color;                    
	                	c *= _Color.rgb;                    
	                	return fixed4(c,1.0);                
                	      }                    
                	ENDCG            
                	   }        
                	 }
                	}

效果如下:顶点/片元着色器的基本架构_第3张图片

你可能感兴趣的:(Unity,Shader)