|
Summary
第二节,我将解释要使Unity Shader显示图形,必须执行哪些操作。最终会得到一个只有一种颜色的对象,但可以稍后再添加一些效果。如果您发现理解所有内容都有困难,我建议您阅读:【译】Ronja的Shader入门教程(一)
Shaderlab 框架
当在Unity中编写Shader时,我们首先必须告诉Unity它应该如何使用我们的Shader。这就是为什么我们首先用着色器的名称定义“Shader”部分,然后在“SubShader”部分内部定义。我们可以为每个Shader定义多个SubShader,并告诉Unity何时使用哪个SubShader,但大多数情况下,我们希望在任何地方都使用相同的SUbShader。
Shader "Tutorial/02_Simple"{
Subshader{
}
}在该SubShader中,我们将写Shader pass。渲染SubShader时,所有过程都是连续绘制的,但目前我们只需要一个pass。在该pass中,我们添加一些Tags来告诉Unity我们希望它如何处理该pass。对于此Shader,我们希望渲染的对象是Opaque,完全不透明的,并且希望它与其他不透明对象一起渲染。
Shader "Tutorial/02_Simple"{
Subshader{
Pass{
Tags{
"RenderType"="Opaque"
"Queue"="Geometry"
}
}
}
}HLSL Code
现在我们可以开始编写Shader的HLSL部分。了解数据在Shader中的处理方式非常重要。首先,3D模型中的信息被提供给顶点Shader(vertex shader),使其相对于屏幕,然后结果通过光栅化器(Rasterizer),将点和三角形转换为可以在屏幕上绘制的像素。但此时Shader还不知道每个像素具有哪种颜色,因此对于对象的每个像素,都会调用片段Shader(fragment shader)。它接收顶点shader的输出,顶点之间带有插补值。然后,片段shader返回在屏幕上绘制的颜色。
Rasterizer:光栅化器
为了让Unity知道我们在这里编写HLSL代码,我们从CGPROGRAM开始,以ENDCG结束。为了使用unity提供给我们的实用函数,我们需要包含“UnityCG.cginc”文件。
Shader "Tutorial/02_Simple"{
Subshader{
Pass{
Tags{
"RenderType"="Opaque"
"Queue"="Geometry"
}
CGPROGRAM
#include "unityCG.cginc"
ENDCG
}
}
}我们首先为输入数据添加一个结构。它通常被称为“appdata”,目前我们只获取对象的顶点位置。
struct appdata{
float4 vertex : POSITION;
}然后我们编写一个结构,顶点shader将返回该结构。现在我们只需要顶点相对于屏幕的位置。为了让unity知道这就是变量中的数据,我们用SV_POSITION属性标记它。
struct v2f{
float4 position : SV_POSITION;
}接下来是顶点Shader,它将顶点返回到片段结构,并获取appdata中的对象信息。首先,我们初始化结构的新实例,然后用顶点的屏幕坐标填充它,并将其返回给光栅化器处理。UnityObjectToClipPos函数位于UnityCG.cginc文件中,帮我们解决了坐标转换的矩阵乘法。
v2f vert(appdata v){
v2f o;
o.position = UnityObjectToClipPos(v.vertex);
return o;
}最后,编写片段Shader。现在我们只返回红色,后面的教程会加入更多东西。我们必须将函数标记为SV_TARGET,以便Unity知道此函数的结果将在屏幕上绘制。
fixed4 frag(v2f i) : SV_TARGET{
return fixed4(0.5, 0, 0, 1);
}在编写了我们的数据类型和函数之后,我们必须告诉unity哪个函数是用来做什么的,这是通过 #scrima shaderFunction 来完成的,所以我们用#pragma vertex vert 告诉Unity我们的顶点shader,用 #pragma fragment frag 告诉Unity我们的片段着shader。
Shader "Tutorial/01_Basic"{
SubShader{
Tags{
"RenderType"="Opaque"
"Queue"="Geometry"
}
Pass{
CGPROGRAM
#include "UnityCG.cginc"
#pragma vertex vert
#pragma fragment frag
struct appdata{
float4 vertex : POSITION;
};
struct v2f{
float4 position : SV_POSITION;
};
v2f vert(appdata v){
v2f o;
o.position = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag(v2f i) : SV_TARGET{
return fixed4(0.5, 0, 0, 1);
}
ENDCG
}
}
}下图展示了如何将编写好的shader指定给材质并渲染物体。
源码repo地址:
You can find the source code of the shader here: https://github.com/ronja-tutorials/ShaderTutorials/blob/master/Assets/002_basic/basic_color.shader
作者本人信息:
You can also find me on twitter at @totallyRonja. If you liked my tutorial and want to support me you can do that on Patreon (patreon.com/RonjaTutorials) or Ko-Fi (ko-fi.com/RonjaTutorials). |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|