着色器
什么是着色器
着色器是通过代码来模拟物体表面在微观等级上发生的事情,使得我们眼睛看到的最终图像感觉很真实。换个层面讲,着色器是运行在 GPU 上的一段代码。
渲染是透视绘图
绘图过程可以分为:勾勒轮廓阶段、绘图阶段
固定函数渲染管线、可编程渲染管线
着色器的类型
1、顶点着色器—vertex shader:在每个顶点上执行的着色器
2、片元着色器—fragment shader:在每个最终图像中可能出现的像素上的着色器
3、无光照着色器—unlit shader:将 vertex 和 pixel 着色器放在一个文件内
4、表面着色器—surface shader:包含 vertex 和 fragment 着色器的功能。
5、图像特效着色器—image-effect shader:实现屏幕特效,诸如抗锯齿、环境光遮蔽、模糊、溢光等。
6、计算着色器—compute shader:进行一些计算的着色器,实现诸如物理模拟、图像处理、光线追踪等。
坐标系统
每个着色器中的计算都是在特定的坐标系统下面进行的。Shader中的坐标系统主要有如下几个:
1、本地空间(对象空间):指的是带渲染模型的相对坐标系。
2、世界空间:指的是整个带渲染场景的坐标系。
3、视图空间:从观察者(相机)的视角来看的相应的坐标系。
4、剪裁空间:范围从-1.0到1.0
5、屏幕空间:二维的坐标系统
6、切线空间:用来计算法线贴图
在着色器中,经常性地需要从一个坐标空间转换到另一个坐标空间,选择合适的坐标空间将会减少这些转换操作,从而使得计算更加方便,渲染更加快速。
光源类型
Unity中有以下几种光源类型:
1、点光源:一个点向周围相等地发射光,强度随距离衰减
2、方向光源(平行光源):发出的每条光线都是平行的,没有强度衰减
3、区域光源(面光源):只能在烘焙的时候使用,光从一个区域内发出。
渲染类型
前向渲染:在前向渲染中,场景的信息输入到渲染器中,每个三角面都被光栅化,对应每个光源都有一个着色通道。
延迟渲染:将光照/渲染计算推迟到第二步进行计算。我们这样做的目的是为了避免多次(超过1次)渲染同一个像素。
第一个Unity着色器
定义颜色
Shader "Unlit/MonoChromeShader"
{
Properties
{
_Color("_Color", Color) = {
1,0,0,1};
}
SubShader
{
Tags {
"RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 _Color;
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return _Color;
}
ENDCG
}
}
}
图形管线
图形API:
OpenGL
Metal
Vulkan
Direct3D
图形管线(渲染管线)通用结构:
栅格化器
无光照着色器的结构
数据流:
顶点数据结构体:
struct appdata
{
float4 vertex : POSITION;
};
顶点函数:
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
片元数据结构体:
struct v2f
{
float4 vertex : SV_POSITION;
};
片元函数:
fixed4 frag (v2f i) : SV_Target
{
return _Color;
}
添加顶点颜色支持:
Shader "Unlit/MonoChromeShader"
{
Properties
{
_Color("_Color", Color) = (1,0,0,1)
}
SubShader
{
Tags {
"RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
fixed4 _Color;
struct appdata
{
float4 vertex : POSITION;
float4 color : COLOR;
};
struct v2f
{
float4 vertex : SV_POSITION;
float4 color : COLOR;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = v.color;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return i.color;
}
ENDCG
}
}
}
坐标空间变换
对象空间(Object Space)
世界空间(World Space)
相机空间(Camera Space)
剪裁空间(Clip Space)
标准化设备坐标(Normalized Device Space)
屏幕空间(Screen Space)
第一个Unity光照着色器
漫反射(Diffuse)
镜面反射(Specular)
环境光(Ambie