【Unity3D】ShaderLab学习笔记

【Unity3D】ShaderLab学习笔记


1、什么是Shader:
Shader(着色器)实际上就是一小段程序,它负责将输入的Mesh(多边形网格,一般使用三角形)以指定的方式和输入的贴图或者颜色等组合作用,然后输出。绘图单元可以依据这个输出来将图像绘制到屏幕上。输入的贴图或者颜色等,加上对应的Shader,以及对Shader的特定的参数设置,将这些内容(Shader及输入参数)打包存储在一起,得到的就是一个Material(材质)。之后,我们便可以将材质赋予合适的renderer(渲染器)来进行渲染(输出)了。
Shader分为顶点着色器和片段着色器(DirectX中又叫做像素着色器),分别对应于GPU中的两个可编程处理器。

2、常用Shader语言:
CG(Nvida公司开发的c for graphics计算机图形编程C语言超集):CG程序可以根据运行时的需要或者事先编译成GPU汇编代码;
HLSL(基于DirectX的High Level Shading Language):只能供微软的Direct3D以及XNA使用,移植性差;
GLSL(基于OpenGL的OpenGL Shading Language):供OpenGL使用,具有良好的跨平台和移植特性。
CG和HLSL的语法类似。GLSL语法体系自成一家。
CG是一个可以被OpenGL和Direct3D广泛支持的图形处理器编程语言。CG语言和OpenGL、DirectX并不是同一层次的语言,而是OpenGL和DirectX的上层,即CG程序是运行在OpenGL和 DirectX标准顶点和像素着色的基础上的。

UnityShader(ShaderLab):Unity3D上自带的一套Shader语言。与其说它是一套语言,不如说它是一套框架比较合适。因为核心的顶点和片段程序是用CG/HLSL语言编写的。按照它的语法规则,可以对外提供一系列属性的输入接口(在Unity Editor材质Inspector面板中可以用图形化方式设置属性和选择资源),但输入的参数最终还是由CG/HLSL程序来处理。

Unity3D的Shader分为三类:
固定功能着色器:Fixed Function Shader
表面着色器:Surface Shader(Unity3D特有的,会被展开为vs和ps)
顶点/片段(像素)着色器:Vertex/Fragment(Pixel) Shader
顶点着色器返回一个顶点信息
片段(像素)着色器返回一个像素信息

3、ShaderLab框架:
Unity3D里面的Shader编程,需要遵循这套框架。
新建一个Shader,打开编辑,可以看到如下框架,默认创建的是Surface Shader。

//以Shader开始,后面跟着自定义的目录结构和名字
Shader "Custom/MyShader" {
	
	//属性部分就是定义对外的输入接口,可以是Range、Color、2D、Rect、Cube、Float、Vector等属性
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
	}
	//SubShader可以有多个,也可以没有,执行的顺序是从上往下,根据当前平台GPU是否支持来判断是否跳过执行并检测下一个SubShader,最多执行一个,也可以因为一个都不支持而一个也不执行
	SubShader {
	
	    //通道,一个SubShader里面可以有多个,顺次执行
	    Pass {
		
		//着色器可以被若干的标签(tags)所修饰,而硬件将通过判定这些标签来决定什么时候调用该着色器
		Tags { "RenderType"="Opaque" }	
		//当设定的LOD小于SubShader所指定的LOD时,这个SubShader将不可用。Unity内建Shader定义了一组LOD的数值,我们在实现自己的Shader的时候可以将其作为参考来设定自己的LOD数值,这样在之后调整根据设备图形性能来调整画质时可以进行比较精确的控制。
		LOD 200
		
		//表示调用的CG语言编写的程序
		CGPROGRAM
		
		//声明了我们要写一个表面着色器,名字为surf,并指定了光照模型,名字为Lambert
		#pragma surface surf Lambert

		sampler2D _MainTex;

		//把所需要参与计算的数据都放到这个Input结构中,传入surf函数使用
		struct Input {
			float2 uv_MainTex;
		};

		//具体的表面着色器函数实现
		void surf (Input IN, inout SurfaceOutput o) {
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}
		ENDCG
		}
	} 
	
	//如果所有的SubShader都不支持,调用FallBack后援,可以在双引号里面指定后援Shader的名字,也可以不指定选择Default的
	FallBack "Diffuse"
}

具体参数和语法规则,参考教程:https://onevcat.com/2013/07/shader-tutorial-1/或者Unity用户手册Shader章节。

4、着色器与材质的关系:
在Unity中材质与着色器之间有着密切的关系。着色器包含着定义了属性和资源使用种类的代码。材质允许你调整属性和分配资源。
着色器是代码。可以定义输入的属性和资源。
属性可以是:
Range:_RangeValue("RangeValue", Range(0, 1)) = 0.5//定义一个浮点数属性,可以通过滑块来拖动范围
Color:_Color ("Main Color", Color) = (1,1,1,1)//定义颜色属性,RGB+Alpha值
2D:_MainTex ("Base (RGB)", 2D) = "white" {}//定义2D纹理(2次方)属性,资源可以在材质里面选择。{}中还有一些纹理属性可以选择。
Rect:_RectMap ("Rect Map", Rect) = "" {}//定义长方形(非2次方)纹理属性
Cube:_CubeMap ("Cube Map", Cube) = "" {}//定义立方体贴图纹理属性
Float:_FloatValue ( "FloatValue", float) = 100//定义一个浮点数属性
Vector:_VectorValue( "VectorValue", vector) = (1,1,1,1)//定义一个四元素的容器(相当于Vector4)属性
材质必须关联一个着色器,所以通过材质Inspector面板,可以图形化的选择资源(如纹理Texture)或者调整属性。

5、Unity3D内置的Shader:

Unity3D内置着色器介绍


6、Unity3D渲染路径:
不同的渲染路径有不同的特点和性能特点,主要影响灯光和阴影。
您的项目所使用的渲染路径在Player Settings选择。此外,您可以为每个摄像机重写(不同摄像机可以是不同的设置)。
如果图形卡不能处理选定的渲染路径,Unity将自动使用一个较低保真度的设置。因此,在GPU上不能处理延迟照明(Deferred Lighting),将使用正向渲染(Forward Rendering )。如果不支持正向渲染(Forward Rendering ),将使用顶点光照(Vertex Lit)。
延时光照:(Deferred Lighting )有着最高保真度的光照和阴影的渲染路径。如果你有很多实时灯光,最好是使用延时光照。它需要一定水平的硬件支持,仅在 Unity Pro可用,移动设备上不支持。
正向渲染:(Forward Rendering)一个基于着色器的渲染路径。它支持逐像素计算光照(包括法线贴图和灯光Cookies)和来自一个平行光的实时阴影。在默认设置中,少数最亮的灯光在逐像素计算光照模式下渲染。其余的灯光计算对象顶点的光照。
顶点光照:(Vertex Lit) 是最低保真度的光照、不支持实时阴影的渲染路径。最好是用于旧机器或受限制的移动平台上。


7、SubShader语法:
Subshader { [Tags] [CommonState] Passdef [Passdef ...] }
Tags分为SubShader Tags和Pass Tags,Tags放在SubShader顶层或者其内部的单个Pass中,这个时候只在Pass中生效。
Tags:表面着色器可以被若干的标签(tags)所修饰,而硬件将通过判定这些标签来决定什么时候调用该着色器。比如Tags { "RenderType"="Opaque" }告诉了系统应该在渲染非透明物体时调用我们。

CommonState:设定开关硬件的各种状态。根据渲染管线,可以设置硬件状态,对渲染的各阶段进行控制。
CommonState属于SubShader的语法规则。

Color, Material, Lighting:
Color color
Material {Material Block}
Lighting On | Off
SeparateSpecular On | Off
ColorMaterial AmbientAndDiffuse | Emission

Culling & Depth Testing:
Cull Back | Front | Off
ZWrite On | Off
ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Always
Offset Factor, Units

Texture Combiners:
SetTexture [TextureName] {Texture Block}
SetTexture [_MainTex] { combine previous * texture, previous + texture } 

Fog:
Fog {Fog Commands}
Mode Off | Global | Linear | Exp | Exp2
Color ColorValue
Density FloatValue
Range FloatValue, FloatValue

Alpha testing:
AlphaTest Off
AlphaTest comparison AlphaValue

Blending:
Blend SrcAlpha OneMinusSrcAlpha // Alpha blending
Blend One One // Additive
Blend OneMinusDstColor One // Soft Additive
Blend DstColor Zero // Multiplicative
Blend DstColor SrcColor // 2x Multiplicative


Unity3D渲染管线

(据此控制各阶段可控部件的状态或者编写顶点/片段着色器)

Passdef:包括regular Pass,Use Pass和Grab Pass。regular Pass包括Name、Tags、Render Setup(Material、Lighting、Cull、ZTest、ZWrite、Fog、AlphaTest、Blend、Color、ColorMask、Offset、SeparateSpecular、ColorMaterial等)
详细描述参考Unity3D用户手册ShaderLab syntax: SubShader部分。


8、编译指令(compilation directives):
#pragma vertex name //定义顶点着色器的功能函数名
#pragma fragment name //定义片段着色器的功能函数名
#pragma geometry name //专为DX10编写着色器,target自动设置为4.0
#pragma hull name //DX11 Hull Shader,target 5.0
#pragma domain name //DX11 Domain Shader,target 5.0
#pragma target name //制定编译的Shader版本,可以为 2.0 3.0 4.0 5.0
#pragma only_renderers space separated names //制定着色器只为特定的渲染器编译,默认为所有
#pragma exclude_renderers space separated names //排除特定的渲染器
……


9、属性类型与CG/HLSL片段变量类型的映射关系:
Color and Vector properties map to float4, half4 or fixed4 variables.
Range and Float properties map to float, half or fixed variables.
Texture properties map to sampler2D variables for regular (2D) textures; Cubemaps map to samplerCUBE; and 3D textures map to sampler3D.

10、Unity3D内置的include文件:
#include "UnityCG.cginc" -- 顶点有关的结构体。通用的全局变量和辅助函数。
float4 vertex is the vertex position
float3 normal is the vertex normal
float4 texcoord is the first UV coordinate
float4 texcoord1 is the second UV coordinate
float4 tangent is the tangent vector (used for normal mapping)
float4 color is per-vertex color
appdata_base: vertex consists of position, normal and one texture coordinate.
appdata_tan: vertex consists of position, tangent, normal and one texture coordinate.
appdata_full: vertex consists of position, tangent, normal, two texture coordinates and color.

HLSLSupport.cginc:自动包含,辅助宏和跨平台编译支持。
AutoLight.cginc:光照、阴影功能。Surface Shader自动包含。
Lighting.cginc:标准的光照模型。Surface Shader自动包含。
TerrainEngine.cginc:地形、植物有关的辅助函数。

11、CG的输入/输出语义:
struct v2f
{
float4 pos:POSITION; 
float4 uv:TEXCOORD0;
float4 col:COLOR;
};
上面POSITION/TEXCOORD0/COLOR即为语义,目的是明确我们定义的Float4变量的类型和作用。

12、Unity3D内置变量:
包含UnityCG.cginc即可使用。
Transformations:
UNITY_MATRIX_MVP:float4x4 Current model * view * projection matrix.
UNITY_MATRIX_MV:float4x4 Current model * view matrix.
UNITY_MATRIX_V:float4x4 Current view matrix.
UNITY_MATRIX_P:float4x4 Current projection matrix.
UNITY_MATRIX_VP:float4x4 Current view * projection matrix.
UNITY_MATRIX_T_MV:float4x4 Transpose of model * view matrix.
UNITY_MATRIX_IT_MV:float4x4 Inverse transpose of model * view matrix.
UNITY_MATRIX_TEXTURE0 to UNITY_MATRIX_TEXTURE3:float4x4 Texture transformation matrices.
_Object2World:float4x4 Current model matrix.
_World2Object:float4x4 Inverse of current world matrix.
_WorldSpaceCameraPos:float3 World space position of the camera.
unity_Scale:float4 xyz components unused; w contains scale for uniformly scaled objects.

Lighting:
_ModelLightColor:float4 Material’s Main * Light color
_SpecularLightColor:float4 Material’s Specular * Light color
_ObjectSpaceLightPos:float4 Light’s position in object space. w component is 0 for directional lights, 1 for other lights
_Light2World:float4x4 Light to World space matrix
_World2Light:float4x4 World to Light space matrix
_Object2Light:float4x4 Object to Light space matrix

Various:
_Time:float4 Time (t/20, t, t*2, t*3), use to animate things inside the shaders.
_SinTime:float4 Sine of time: (t/8, t/4, t/2, t).
_CosTime:float4 Cosine of time: (t/8, t/4, t/2, t).
unity_DeltaTime:float4 Delta time: (dt, 1/dt, smoothDt, 1/smoothDt).
_ProjectionParams:float4 x is 1.0 (or –1.0 if currently rendering with a flipped projection matrix), y is the camera’s near plane, z is the camera’s far plane and w is 1/FarPlane.
_ScreenParams:float4 x is the current render target width in pixels, y is the current render target height in pixels, z is 1.0 + 1.0/width and w is 1.0 + 1.0/height.

13、Unity3D预定义宏:
Target platform:
SHADER_API_OPENGL - desktop OpenGL
SHADER_API_D3D9 - Direct3D 9
SHADER_API_XBOX360 - Xbox 360
SHADER_API_PS3 - PlayStation 3
SHADER_API_D3D11 - desktop Direct3D 11
SHADER_API_GLES - OpenGL ES 2.0 (desktop or mobile), use presence of SHADER_API_MOBILE to determine.
SHADER_API_FLASH - Flash Stage3D
SHADER_API_D3D11_9X - Direct3D 11 target for Windows RT

下面四类参考帮助文档Predefined shader preprocessor macros章节:
Platform difference helpers
Shadow mapping macros
Constant buffer macros
Surface shader pass indicators


posted on 2016-06-12 23:58  nobcaup  阅读(425)  评论(0编辑  收藏  举报

导航