混合模式
1:在所有计算完成后,决定当前的计算结果输出到帧缓冲区时,如何混合源和目标,通常用
来绘制半透明的物体;
2:Blend off 关闭混合
3:Blend 源因子,目标因子:配置并开启混合,产生的颜色和源因子相乘,然后两个颜色相加
4:Blend 源因子,目标因子,源因子A,目标因子A:源因子与目标因子用户混合颜色值,源因子A,与目标因子A,用于混合alpha
5:BlandOp操作命令:不是将颜色混合在一起,而是对他们进行操作,主要有:
Min, Max, Sub, RevSub
6:混合因子的类型:
One 使用源或目标色完全显示出来;
zero 删除源颜色或目标颜色;
SrcColor 这个阶段的值*源颜色值;
SrcAlpha 这个阶段的值*源颜色Alpha值
DstColor 这个阶段的值* 帧缓冲颜色值;
DstAlpha这个阶段的值*帧缓冲源Alpha值
OneMinusSrccolor 阶段值*(1-源颜色的值)
OneMinusSrcAlpha 阶段值*(1-源颜色的Alpha值)
OneMinusDstcolor 阶段值*(1-目标颜色的值);
OneMinusDstAlha 阶段值*(1-目标颜色Alpha值)
6:一般放在放在Pass通道里面;
Alpha测试
1:Alpha测试:阻止片元被写到屏幕的最后机会,最终渲染出来的颜色计算出来后可通过透明
度和最后一个固定值比较,如果通过测试则绘制次片元,否则丢弃此片元;
2:AlphaTest off/on:开启/关闭Alpha测试,默认是关闭的;
-3:比较测试值的模式:
Greater >, GEqual >=,Less <, LEqual <=, Equal ==, NotEqual !=,
Always(永远渲染),Never(从不渲染);
4:AlphaTest 条件[交量]/常数,一般放在放在pass通道里面;
深度测试
1:为了使近距离的物体挡佳远距离的物体,当片元写入到缓冲的时候,需要将片元的深度值
与缓冲区的深度值进行比较,测试成功写入帧缓冲区;
2:zWrite 深度写开关,控制是否将深度z的片元写入缓冲区中,如果不绘制透明物体设置为
On, 否则的话设置为Off,默认为On;
3:ZTest 深度测试模式:设置深度测试的执行方式,默认为LEqual,深度测试的模式:
Less <, Greater >, LEqual <= , GEqual >=, Equal ==, NotEqual !=,Always 总是绘制关闭深度测试;
4:ZTest 条件
5:一般放在放在Pass通道里面;
通道遮罩
1:通道遮罩可以是开发人员指定渲染结果输出的通道,而不是通常情况下的RGBA四个通道;
2:可选的是RGBA的任意组合以及0,如果为0意味着不会写入到任何通道:
3: ColorMask RG ... ColorMask 0
面剔除
1:通过不谊染背对摄像机的几何体的面来提高性能优化错误,所有的几何体都包含正面和反面
2:面剔除操作,大多数都是封闭的物体,所以不需要绘制背面;
3:面剔除操作:
Cull Back: 不绘制背对摄像机的面,默认项
Cull Front, 不绘制面向摄像机的面,
Cull Off,关闭面剔除操作
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Color("Color",Color) = (1.0,0.0,0.0,1.0)
_Alpha("Alp",float) = 1.0
}
SubShader
{
Tags { "RenderType"="Opaque" "Queue"="Transparent"} // "Queue"="Transparent" 这里渲染队列选择带透明度的队列 ,方块墙后面的球就能看到了,否则是看不到的。
LOD 100
Pass
{
// 如果是变量 一定要加中括号包住参数[]
// 如果是常量 则直接写即可 比如这里的 0
AlphaTest Never [_Alpha]
//AlphaTest Never 0
//深度测试也类似 AlphaTest写法
//ZTest Never
// 面剔除 开关
//Cull Off
}
}
混合模式案例:
1.在Unity中,新建一个Unlit shader,新加一个颜色修改属性,然后在着色部分,使用该颜色
_Color("Color",Color) = (1.0,0.0,0.0,1.0)
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
//fixed4 col = tex2D(_MainTex, i.uv);
fixed4 col = _Color;
return col;
}
2.然后在Unity中新建一个球和一面墙,让墙在球的前面,遮挡作用。
给墙使用我们的shader,并修改下色盘的alpha,效果如下,虽然透明度是修改了,但是没有效果;
3.此时用到了 Blend SrcAlpha OneMinusSrcAlpha 来开启渲染混合通道
注意:这里通道的命令一般都是写在Pass内,且不在cg代码块中
shader同样的设置,效果如图:(很明显,已经有了透明效果,但是在墙别后的球是被遮挡了的,看不到)
4.此时用到了渲染队列里的内容,一般物体是在Geometry(默认)使用这个队列的,不包含透明度,此时我们将渲染队列修改,使用Transparent有透明度的渲染通道,效果如图:(墙后面的球也能看到了,而且颜色是叠加的,本来白色的球,通过红色的墙,也会有红色)
实例代码:
Shader "GFStudy/BlendShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Color("Color",Color) = (1.0,0.0,0.0,1.0)
}
SubShader
{
Tags { "RenderType"="Opaque" "Queue"="Transparent"} // "Queue"="Transparent" 这里渲染队列选择带透明度的队列 ,方块墙后面的球就能看到了,否则是看不到的。
LOD 100
Pass
{
// 渲染通道 一定要在cg代码块外部写
// 开启混合通道 就会有透明度 否则在色盘里调整alpha是没有反应的
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
//fixed4 col = tex2D(_MainTex, i.uv);
fixed4 col = _Color;
return col;
}
ENDCG
}
}
}
通道遮罩案例:
1.在Unity新建一个默认shader,然后把内容全部去掉,只剩一个简单的SubShader:
这里在pass中给定了一个颜色,白色
hader "GFStudy/colorMask"
{
SubShader
{
Pass
{
// 颜色遮罩 R 只输出Rad通道,R的值是多少就是什么颜色 B指输出蓝色通道 0是都不输出,就看不到了, RGBA是都输出
ColorMask R //R B G RGBA 0
// 定义一个颜色 白色
Color(1.0,1.0,1.0,1.0)
}
}
FallBack "Diffuse"
}
2.默认情况下,没有颜色遮罩命令 ColorMask R,看效果可以先把这个注释掉
效果如图:
3.当加入颜色遮罩命令后,ColorMask R 是显示R通道颜色:
这个命令设置,有 R 、 G 、 B 、 RGBA 、 0
0就是什么通道也不显示:
ColorMask 0 效果: