本系列文章系学习 唐福幸《Unity ShaderLab 新手宝典》的笔记,包含个人理解,如有错误欢迎批评指出
顶点-片段着色器基础
4.3 CG语法基础
Unity Shader中,ShaderLab只是起到组织代码结构的作用,而真正实现渲染效果的是CG语言编写的
4.3.1 编译指令
CG程序片段嵌入在Pass中,夹在CGPROGRAM和ENDCG之间
Pass
{
CGPROGRAM
//编译指令
#pragma vertex vert
#pragma fragment frag
#pragma target 3.5
#pragma require integers 2darray instancing
ENDCG
}
以上两条编译指令告诉Unity,vert函数包含顶点着色器的代码,frag函数包含片元(段)着色器的代码。
编译指令 | 作用 |
---|---|
#pragma vertex name | 定义顶点着色器的名称,通常使用vert |
#pragma fragment name | 定义片元(段)着色器,通常使用frag |
#pragma target number | 定义Shader要编译的目标级别,默认2.5 |
#pragma require 功能名称1 功能名称2… | 定义Shader要使用到的一些功能 |
#pragma target number
- 设置高等级的编译目标等级意味着可以使用更高级的GPU功能
- 同时也会导致在旧设备上无法使用
详情参考
默认情况下,所有着色器程序都编译到所有支持的渲染器中。
也可以使用 #pragma only_renderers 或 #pragma exclude_renderers 指定要编译的渲染器
用法如下:
#pragma only_renderers d3d11
名称 | 对应渲染平台 |
---|---|
d3d11 | Direct3D 11/12 |
glcore | OpenGL 3.x/4.x |
gles | OpenGL ES 2.0 |
gles3 | OpenGL ES 3.x |
metal | iOS/Mac Metal |
vulkan | Vulkan |
d3d11_9x | Direct3D 11 9.x 功能级别,通常在 WSA 平台上使用 |
xboxone | Xbox One |
ps4 | PlayStation 4 |
n3ds | Nintendo 3DS |
wiiu | Nintendo Wii U |
4.3.2 着色器函数
- 无返回值函数
Shader "test1/NewUnlitShader"
{
Properties
{
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
void vert(in float4 vertex : POSITION, out float4 position: SV_POSITION)
{
position = UnityObjectToClipPos(vertex);//将输入的vertex经过UnityObjectToClipPos把模型空间坐标转换成裁剪空间坐标,输出为float4类型
}
void frag(in float4 vertex : SV_POSITION, out fixed4 color : SV_TARGET)
{
color = fixed4(1,0,0,1);//不管输入,将输出的color赋值为RGBA=1,0,0,1红色
}
ENDCG
}
}
}
其中vert函数是无返回值的,它是通过out输出的
格式如下
void name(in 参数, out 参数)
{
//函数体
}
void: 表示无返回值
name: 自定义的函数名称,通过这个名称调用这个函数
in: 输入参数,语法为:in+数据类型+名称,一个函数可以有多个输入
out: 输出函数,语法为:out+数据类型+名称,一个函数可以有多个输出
注:关键词in可以省略,out不可
- 有返回值函数(效果同无返回值函数)
Shader "test1/NewUnlitShader2"
{
Properties
{
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float4 vert(in float4 vertex : POSITION) : SV_POSITION
{
return UnityObjectToClipPos(vertex);
}
fixed4 frag(in float4 vertex : SV_POSITION) : SV_TARGET
{
return fixed4(1,0,0,1);
}
ENDCG
}
}
}
其中vert函数是有返回值的,它是通过return输出的,其属性于函数名前面的类型
格式如下
type name(in 参数, out 参数)
{
//函数体
}
顶点和片段函数中,输入、输出的数据类型如下
数据类型 | 描述 | 用途 |
---|---|---|
fixed,fixed2,fixed3,fixed4 | 低精度浮点数(11位精度),[-2.0, 2.0],精度为 1/256 | 固定精度对于常规颜色(通常存储在常规纹理中)以及对它们执行简单运算非常有用 |
half,half2,half3,half4 | 中精度浮点数(16位精度),[-60000, 60000],精度约为 3 位小数 | 半精度对于短矢量、方向、对象空间位置、高动态范围颜色非常有用。 |
float,float2,float3,float4 | 中精度浮点数(32位精度) | 通常用于世界空间位置、纹理坐标或涉及复杂函数(如三角函数或幂/取幂)的标量计算 |
struct | 结构体 | 可以将多个变量进行整体打包 |