![[译]Unity3D Shader教程(七)Sprite Shaders](https://www.laowangomg.com/wp-content/uploads/2021/09/Result.png)
[译]Unity3D Shader教程(七)Sprite Shaders
原文链接:
Shader Tutorials by Ronja
1. Summary
概要。
在 unity 中,精灵的渲染方式与 3d物体的渲染方式非常相似。 大部分工作由精灵渲染器(Sprite Renderer)组件完成。 我将稍微介绍一下组件正在做什么以及我们如何更改着色器以执行默认精灵渲染器正在执行的一些操作。
本教程将建立在我们之前制作的透明着色器的基础上,因此您最好先了解它。
2. Scene Setup
场景设置。
为了使用Sprite Shader,我将场景更改得更简单,使用正交相机,用精灵渲染器替换了之前示例中使用的立方体,并将我使用的图像转换为Sprite(精灵图)。
3. Changing the Shader
更改着色器。
通过上面场景的更改以及透明材质被放入精灵渲染器的材质槽(Material),似乎已经可以正常工作了。
精灵渲染器(Sprite Renderer)组件根据我们的图像自动生成一个网格并设置它的 UV 坐标,这样精灵图就像我们习惯的 3d 模型一样渲染。Sprite Renderer还将精灵渲染器的颜色放入生成网格的顶点颜色中,并在我们激活翻转 X 或 Y 时将顶点翻转。Sprite Renderer还与Unity的渲染管道(Renderer Pipeline)通信,因此具有更高排序层(Sorting Layer)的精灵将稍后渲染并绘制在顶部。
但我们的着色器目前不支持镜像和顶点颜色,所以让我们解决这个问题。
当我们翻转它时我们的精灵消失(并在我们在 x 和 y 翻转它时重新出现)的原因是x 轴翻转,Sprite Renderer是将其绕 y 轴旋转 180°,然后我们看到背面它以及由于称为“背面剔除”的优化,精灵图的背面不会被渲染。通常背面剔除是好的,因为当我们看不到对象的内部时,就不需要渲染背面。而且因为背面的法线背对着相机,无论怎样背面的光照通常都是错误的。
但是在这里,我们不必担心这两个问题,精灵没有可以优化的“内部”,我们也不做光照,所以我们可以禁用背面剔除。我们可以在SubShader或Pass中做到这一点。
Cull off
为了获得顶点颜色,我们将一个新的 4维向量(red, green, blue, alpha) 添加到我们的输入结构和顶点着色器到片段着色器中,变量名设置为color。 然后在顶点着色器中我们将输入结构体的颜色传递到的 v2f 结构,并在片段着色器中将我们的返回颜色与它相乘;
struct appdata{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
fixed4 color : COLOR;
};
struct v2f{
float4 position : SV_POSITION;
float2 uv : TEXCOORD0;
fixed4 color : COLOR;
};
v2f vert(appdata v){
v2f o;
o.position = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.color = v.color;
return o;
}
fixed4 frag(v2f i) : SV_TARGET{
fixed4 col = tex2D(_MainTex, i.uv);
col *= _Color;
col *= i.color;
return col;
}
通过这些更改,着色器现在将按照我们的预期运行,我们可以扩展它以执行我们将来感兴趣的其他事情。
完整Shader如下。
Shader "Tutorial/007_Sprite"{
Properties{
_Color ("Tint", Color) = (0, 0, 0, 1)
_MainTex ("Texture", 2D) = "white" {}
}
SubShader{
Tags{
"RenderType"="Transparent"
"Queue"="Transparent"
}
Blend SrcAlpha OneMinusSrcAlpha
ZWrite off
Cull off
Pass{
CGPROGRAM
#include "UnityCG.cginc"
#pragma vertex vert
#pragma fragment frag
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
struct appdata{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
fixed4 color : COLOR;
};
struct v2f{
float4 position : SV_POSITION;
float2 uv : TEXCOORD0;
fixed4 color : COLOR;
};
v2f vert(appdata v){
v2f o;
o.position = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.color = v.color;
return o;
}
fixed4 frag(v2f i) : SV_TARGET{
fixed4 col = tex2D(_MainTex, i.uv);
col *= _Color;
col *= i.color;
return col;
}
ENDCG
}
}
}
当然,Sprite Renderer组件做的远不止这些,它还准备网格以便Sprite Sheet(精灵表)、polygon sprites(多边形精灵)和Animation(动画)与我们的着色器一起使用。
Unity自带的精灵着色器已经实现但我们自己的Shader还未实现的功能包括instancing(实例化)、pixel snapping(像素捕捉)和就一个外部 alpha 通道。由于这些要么太复杂要么很少有人使用,所以在这里我决定暂时不实现它们 。