创建一个最简单的顶点/片元着色器
使用unity版本如下:
第一步:去掉初始的天空盒子,只是为了得到更加原始的效果:
第二步:创建Shader文件和材质(前面提到过材质是shader 的载体),并将shader赋给材质(路径可以点开shader查看,也可以自己修改好路径后再赋值)。
第三步:创建物体调整到合适位置,并将材质赋值给物体,这样可以观察到shader 的效果(在没修改过shader 的情况下可以看到默认的效果:标准表面着色器)。
第四步:修改shader,达到自己想要的效果,在这里实现一个最简单的,代码(很多内容在第二篇笔记完整代码中有详细注释)如下:
Shader "Custom/SimpleShader"
{
SubShader
{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
float4 vert(float4 v:POSITION):SV_POSITION{
return UnityObjectToClipPos(v);//模型空间到裁剪空间,即MVP矩阵,等同于mul(UNITY_MATRIX_MVP,*)
}
fixed4 frag():SV_Target{
return fixed4(1.0,1.0,1.0,1.0);//返回一个颜色并存储到了渲染目标中(由语义SV_Target表示)
}
ENDCG
}
}
}
通过语义来限定输入输出。可以使用结构体来丰富着色器的输入输出,通过语义填充到结构体内的数据是由材质的Mesh Render 提供的,在每帧调用Draw Call的时候,Mesh Render组件会负责渲染的模型数据发送给Unity Shader。也可以通过结构体来完成顶点着色器和片元着色器之间的通信。需要注意的是顶点着色器中,必须包含一个由SV_POSITION限定的变量,这样渲染器才能得到裁剪空间下的顶点坐标。顶点着色器是逐顶点调用的,而片元着色器是逐片元,所以片元着色器的输入是把顶点着色器的输出进行插值得到的。
在Properties语义中限定的属性可以在选择该shader的材质的面板上进行调节。ShaderLab属性类型(左)和Cg中变量类型(右)之间的匹配关系:
Cg变量前加上uniform关键字代表提供一些初始值如何指定和存储的信息,且在unity shader中是可以省略的。
Unity提供的内置文件和变量
内置的包含文件:#include “filename” ,文件后缀为.cginc
还提供了一些内置的变量:坐标变换、摄相机参数,用于访问时间、光照、雾效和环境光等目的的变量。大多位于内置文件中。
Cg/HLSL语义
需要注意在DirectX以后,有了新的语义类型:系统数值语义,就是以SV开头的,这类值具有特定含义,要注意使用。
需要注意一个语义可以使用的寄存器只能处理4个浮点值(float),因此矩阵类型可采用分成多个变量的形式。
Debug
第一种方法:假彩色图像(false-color image)——用于可视化一些数据,主要是把需要调试的变量映射到[0,1],然后把他们作为颜色输出到屏幕上,然后通过像素颜色来判断这个值的正确性。
一维数据可以选择一个单独的颜色分量进行输出,其他分量=0。如果是多维数据,则可以选择对每一维数据进行单独调试,或者选择多个颜色分量进行输出。
Shader "Custom/FalseColor"
{
SubShader
{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f{
float4 pos:SV_POSITION;
fixed4 color:COLOR0;
};
v2f vert(appdata_full v)
{
v2f o;
o.pos=UnityObjectToClipPos(v.vertex);
//可视化法线方向
o.color=fixed4(v.normal*0.5+fixed3(0.5,0.5,0.5),1.0);
return o;
}
fixed4 frag(v2f i):SV_Target
{ return i.color; }
ENDCG
}
}
}
效果:
第二种方法:利用Visual Studio——Graphics Debugger,可以查看每个像素的最终颜色、位置等信息,还可以对顶点着色器和片元着色器进行单步调试。(仅可在DirectX11平台运行)
根据官方文档进行安装:https://docs.unity3d.com/Manual/SL-DebuggingD3D11ShadersWithVS.html
第三种方法:帧调试器
渲染平台的差异
在开启了抗锯齿并使用了渲染到纹理技术时,unity不会自动处理翻转问题来消除平台间的差异。这种问题在只处理一张渲染图像的时候也没有影响,但是在处理多张渲染图像的时候要注意,在开启了抗锯齿以后,这些图像在竖直方向上的朝向可能是不同的(该问题仅出现于DirectX中)。
不同平台对shader语义要求也不同,DirectX更严格。还要注意语义差异,例如尽量使用系统数值语义。
注意
- Cg/HLSL中三种精度的数值类型:float、half、fixed(-2.0~+2.0)
- 规范语法
- 避免不必要的计算
- 慎用分支和循环语句
- 不要除0