目录
一、前言
二、素材准备
三、准备基础代码
四、准备基础场景
五、SurfaceOutput结构体
六、透明度
七、渲染顺序
八、选错的后果
九、Tags之渲染顺序
十、Cull(正面和反面渲染)
十一、代码汇总
十二、作者的碎碎念
一、前言
因为shader这个专题得到了大家的支持,所以目前在继续更新下去。
之前一直讲的都是rgb模式,我们一直没有带着a玩,因为透明模式和其他的稍微有些不太一样。
二、素材准备
首先我们需要准备一个透明贴图,如果你实在没有,可以选择去
FreePNG | FreePNG is a free to use PNG gallery where you can download high quality transparent PNG images.
不需要账号,直接找一个喜欢的下载就行了,我下载了(如图1所示)
三、准备基础代码
前面讲过的肯定不能再讲了,我们是在这个代码的基础上进行的。
Shader "Custom/011"
{
Properties
{
_MainTex ("MainTex", 2D) = "white" {}
}
SubShader
{
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o)
{
o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
}
ENDCG
}
FallBack "Diffuse"
}
四、准备基础场景
我们拿3D物体中的Quad来做放置的物体。
注释:这里给大家解释一下,为什么不用plane?
plane: 是由很多个三角形组成的矩形,所以在显示地面的时候可以显示的比较细致,但费性能。
Quad:只有两个三角形组成的矩形,所以一般用来放视频之类的,对细节没太多要求的平面,没那么费性能。
五、SurfaceOutput结构体
如果你仔细注意,本次准备的基础代码,有一个新的结构体,和以前用过的只有一个单词的差距,但比那个简单(也可以用上一个,这不是给大家多练习几个吗,嘿嘿)。具体可以查询以下链接。
编写表面着色器 - Unity 手册
struct SurfaceOutput
{
fixed3 Albedo; // 贴图颜色
fixed3 Normal; // 法线
fixed3 Emission;//自发光
half Specular; // 0..1 范围内的镜面反射能力
fixed Gloss; // 镜面反射强度
fixed Alpha; // 透明度 Alpha
};
我们可以观察到,这里面专门有一个透明度的信息,所以我们的第一个目标就是,把透明度先放进去。
六、透明度
我们改一下surf中的内容,把导入进来的贴图信息,分成两份,一份给贴图颜色,一份给透明度。
void surf (Input IN, inout SurfaceOutput o)
{
//我们新建一个fixed4 把转换的所有的颜色信息都接进来
fixed4 c =tex2D (_MainTex, IN.uv_MainTex);
//我们把rgb给了贴图
o.Albedo = c.rgb;
//把透明度给alpha
o.Alpha = c.a;
}
虽然代码已经写好了,可以写入进去,但到此为止,我们的透明是没有打开的,因为透明的种类有很多,需要我们标注一下。
透明的种类(猫一眼就行了,知道有很多种就行了):
alpha或alpha:auto - 自动选择
1.普通光照情况,选择alpha:fade
2.基于物理光照情况,选择alpha:premul
alpha:blend - 启用alpha混合。
alpha:fade - 最常见的透明度
alphatest:VeriableName(alphatest:变量名) - 启用alpha cutout transparency(alpha剔除透明)。剔除变量是用float数值。您可能还想使用addshadow指令来生成正确的阴影投影器的pass。
keepalpha - 用于默认不透明的surface shader。 无论输出结构体的alpha值是什么,或者光照函数返回什么,始终写入alpha通道值为1.0(白色)。
decal:add - 叠加性的decal(贴花)shader(如:地形shader的AddPass)。意思就一个对象的表面在另一个对象表面上使用了additive混合
decal:blend - 半透明的贴花shader。意思就一个对象的表面在另一个对象表面上使用了alpha混合。
总结一下,我们目前最常见的需求是alpha:fade,所以我们无脑选这个,其他我们未来再讲。
写的位置,这个标注的位置在我们引用的后面
#pragma surface surf Lambert alpha:fade
然后,我们就得到了一张透明的树(如图3所示)
七、渲染顺序
因为有了透明,所以渲染顺序就变得重要起来了。以前都是实心的,就没那么重要。
什么叫渲染顺序?
就是计算机画画的顺序。
人可以做到看到什么画什么,但计算机不能,它会一股脑全画上去,那就涉及到一个问题,遮挡关系怎么办?
所以利用画画的顺序,就可以实现遮挡。
感觉很像下面这个视频,就是一层一层盖上去的。
【油画棒】白蔷薇~沉浸式教程_哔哩哔哩_bilibili
如果你看了这个教程,就会知道,如果我先画花,再画背景,花肯定就看不见了,没了!
计算机的渲染顺序是这样的:
- Background:背景,数值为1000,先画背景,没毛病吧!
- Geometry:不透明物体,数值为2000
- AlphaTest:需要进行透明度测试的物体,数值为2450(有些透明设置的比较复杂,计算机也不太确认,所以先测试一下,万一它属于不透明呢?)
- Transparent:一定有透明的物体,数值为3000
- Overlay:叠加效果,数值为4000(如镜头光晕)
所以一般是让你选择的。(如图4所示)
如果你仔细看图了,你会发现三件事。
1.background和overlay是不给你在这选的。
2.上面的数值是什么意思?
3.fromShader是什么意思?
虽然看上去是选项,但实际上是按数值控制的,
如果都是不透明的物体,你也可以通过填写数值,选择先渲染哪个,再渲染哪个。
FromShader的意思就是,我不做选择,我直接填数。
上面的选项和数值其实就是软件给你先填了个数字,大概分了个类。
备注:如果你选了geometry,但是数值写了1000,他俩不匹配,那会按照geometry来渲染,总之就是类别为主要影响,数值是在类别相同的情况下细分。。
八、选错的后果
我们的树是透明物体,但我就想选成不透明的,你会发现,如果我把球一直往后挪,它会在相机里面突然渲染到前面。(如图5所示)
解决方案,就是(如图6所示),调对就可以了。
九、Tags之渲染顺序
这个里面有很多,我们暂时只讲渲染顺序。
我们除了可以在外面手动去选择渲染顺序,我们也可以自己在代码里面写好,有一些可以事先标注的内容,会放在Tags里。
顺序的单词是:Queue
顺序选择透明就写成:“Queue”=“Transparent”
如果选其他的,后面那个Transparent,就写别的。
代码如下:
Tags
{
"Queue" = "Transparent"
}
这时候你会发现,你的fromShader会自动变成Transparent的数值。(如图7所示)
十、Cull(正面和反面渲染)
所有的模型,包含图片,在Unity中,都是有正面和反面一说的。
对于图片来说,背面就是反面(如图8所示)。翻到反面,默认就会看不见。
对于模型来说,内部就是反面。我们只能看见外面。(如图9所示)
摄像机移动到球体内部,就看不见了,因为和图片一样,反面不显示。
如果你希望看见,你就要在shader里面加代码。
Cull Back(默认): 只显示正面,不显示背面
Cull Front: 只显示背面,不显示正面
Cull Off 都显示备注:Cull的中文意思叫做剔除,cull off就是都剔除的意思
所以我们在代码里加上。
SubShader
{
Tags
{
"Queue" = "Transparent"
}
//加在这个位置就可以了
Cull Off
CGPROGRAM
#pragma surface surf Lambert alpha:fade
然后你就会拥有一个,正反面的树。(如图10所示)
十一、代码汇总
本节课所有代码如下,方便你们参考比对。
Shader "Custom/011"
{
Properties
{
_MainTex ("MainTex", 2D) = "white" {}
}
SubShader
{
//Tags放在这里哦
Tags
{
"Queue" = "Transparent"
}
Cull Off
CGPROGRAM
#pragma surface surf Lambert alpha:fade
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o)
{
//我们新建一个fixed4 把转换的所有的颜色信息都接进来
fixed4 c =tex2D (_MainTex, IN.uv_MainTex);
//我们把rgb给了贴图
o.Albedo = c.rgb;
//把透明度给alpha
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
十二、作者的碎碎念
不知不觉已经更新十五集了,非常感谢大家一如既往的支持~up会继续努力更新下去的!~
另外,up已经同步对这个专题进行了视频录制,视频更新的要比文章慢,如果想看视频,大家也可以支持一下~视频已经更新了十二集了。
Unity 什么是shader第一集_哔哩哔哩_bilibili