Unity学习笔记-Shader第一期

Unity学习笔记-Shader第一期

  • Shader是什么
  • Shader和Material的关系
  • Shader的主要类型
  • Shader的结构
    • Shader
      • Properties
      • SubShader
        • Tags
        • LOD
        • Shader主体部分
      • FallBack
  • 总结

参考文献 https://onevcat.com/2013/07/shader-tutorial-1/

Shader是什么

用Unity做游戏开发的小伙伴对此一定不陌生,Shader也称之为“着色器”,实际上就是一小段程序,它负责将输入的Mesh(网格)以指定的方式和输入的贴图或者颜色等进行组合处理,然后输出,同时绘图单元可以依据输出的内容来将图像绘制到屏幕上。

Shader和Material的关系

我们在Unity中输入的贴图或者颜色等属性,加上对应写好的Shader,经过Shader的处理过后我们得到了我们想要的纹理效果,将这些内容打包存储在一起,得到的就是一个Material(材质)。之后,我们便可以将材质赋予合适的renderer(渲染器)来进行渲染(绘制)了。

Shader的主要类型

类型 说明
Surface 通俗来讲Surface Shader(表面着色器)已替我们完成大部分的工作,只需要简单的技巧即可实现很多不错的效果。
Fragment FragmentShader(片段着色器)可以在比较低的层级上进行更复杂更有针对性地开发,因此可以做更多的事情,但比较难写。

Shader的结构

这里直接先给出一段Unity预制的Standard Surface Shader,下面会针对每一个层级进行解释

Shader "Custom/Diffuse Texture" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
	}
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		#pragma surface surf Lambert

		sampler2D _MainTex;

		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
	} 
	FallBack "Diffuse"
}

从上面的代码中不难看出Shader的结构主要由【Shader】【Properties】【SubShader】【FallBack】构成,值得一提的是,一个【Shader】下可以包含多个【SubShader】,原因后面会讲。

Shader

Shader "Custom/Diffuse Texture" {...}
//此处声明了一个叫做"Diffuse Texture"的Shader,同时将其放置在自定义的Custom父级菜单下。

需要注意的是"Custom/Diffuse Texture"并非指代项目Assets下的目录层级,而是Unity根据你此处自定义的层级自动生成的Shader选项菜单,在Unity中你看到的是这样的
Unity学习笔记-Shader第一期_第1张图片

Properties

Properties {
	//此处存放声明的属性
}

Properties是存放所有声明属性的容器,属性的声明有格式上的要求,如下:

_属性名称 ("Unity中可见名称" , 属性类型名称) = 属性初始默认值

就拿例子中的shader来说

_MainTex ("Base (RGB)", 2D) = "white" {}

MainTex = 属性名称 (注意名称前的"_"不可缺失)
Base (RGB) = Unity中可见名称
2D = 属性类型名称
white = 属性初始默认值 (此处即为空白)

Properties {
	_MainTex ("Base (RGB)", 2D) = "white" {}
}

紧接着我们来看看几种常见的Type(属性类型)

类型 说明
Color 一种颜色,由RGBA(红绿蓝和透明度)四个量来定义
2D 一张2的阶数大小(256,512之类)的贴图。这张贴图将在采样后被转为对应基于模型UV的每个像素的颜色,最终被显示出来
Rect 一个非2阶数大小的贴图
Cube 立方体纹理,简单说就是6张有联系的2D贴图的组合,主要用来做反射效果(比如天空盒和动态反射),也会被转换为对应点的采样
Range(min, max) 一个介于最小值和最大值之间的浮点数,一般用来当作调整Shader某些特性的参数(比如透明度渲染的截止值可以是从0至1的值等)
Float 任意一个浮点数
Vector 一个四维数

SubShader

Shader的作用是将输入的贴图或者颜色等进行组合处理,然后输出得到我们想要的效果,整个处理的逻辑都在SubShader中。在解释SubShader的逻辑含义之前,首先我们要来说说两个在SubShader中常见的属性Tags和LOD:

Tags

之前我们提到一个Shader下可以包含若干个SubShader,那么当我们想让系统在渲染时调用Shader进行处理时,有那么多的SubShader,系统最终会调用哪一个呢?Tags就起到了引导的作用,硬件会判定Tags修饰标签的内容,然后在渲染时调用指定的SubShader进行处理。
我们来看一下例子:

SubShader {
	Tags { "RenderType"="Opaque" }
} 

此处"RenderType"="Opaque"即表示,当进行渲染非透明物体时,调用该SubShader下的逻辑方法。

LOD

LOD是Level Of Detail的缩写,顾名思义,它是一种控制细节级别的技术。LOD的数值越高,画面的渲染质量越高,但是对硬件也有较高的要求。在Unity中,我们可以在Quality面板为项目设置Maximum LOD Level(最大LOD等级)
在这里插入图片描述
Maximum LOD Level可以设置7个等级,Maximum LOD Level会与Shader LOD进行大小比较,只有在Maximum LOD Level范围内的Shader才可以被调用,因此使用LOD可以针对不同平台进行渲染质量的调节,Shader LOD具体对照如下

Maximum LOD Level Shader LOD说明
0 任何LOD值的Shader都可以被调用
1 LOD 100
2 LOD 200
3 LOD 300
4 LOD 400
5 LOD 500
6 LOD 600

回到例子

SubShader {
	LOD 200
} 

此处设置的LOD值为200,参照上述表格,假设当Maximum LOD Level小于等于2时,这个Shader就可以被调用,反之不可。

Shader主体部分

SubShader {
	CGPROGRAM
	#pragma surface surf Lambert

	sampler2D _MainTex;

	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
} 

主体部分由CGPROGRAM开始,于ENDCG结束,这里面包含了整个Shader的核心逻辑,输入端的内容将会在这里进行处理并进行输出,由于主体相对比较复杂先大概扫一眼就好,我会在下一期专门做有关Shader主体部分的笔记。

FallBack

FallBack "Diffuse"

这个很好理解,当上面所有的SubShader都无法运行时,会直接执行FallBack命令,并使用FallBack所指向的Shader,简单来说就是Shader给自己留的一条“后路”。

总结

这一期的笔记主要整理了UnityShader的一些基础知识,笔者是个刚跨入计算机图形学领域的小白,也还在学习相关的知识,开始写博客的目的也是希望能给自己所学的知识做一个巩固,同时也希望各位行业大大们纠正指出我理解有误的地方,从而提升自己的技术水平。那么,下期笔记见!

你可能感兴趣的:(Unity学习笔记)