透明度测试与透明度混合详解《unity shader入门精要》学习笔记
来源:互联网 发布:sql server 2008 sa 编辑:程序博客网 时间:2024/06/06 03:26
透明度测试
QUEUE标签用于决定模型用于哪个渲染队列(队列索引号越小越先渲染越适合背景一类)
名称 队列索引号 描述
Background 1000 适合背景物体
Geometry 2000 不透明物体,默认的
AlphaTest 2450 需要透明度测试的物体
Transparent 3000 半透明物体,使用透明度混合的物体
Overlay 4000 叠加特效,需要最后渲染的物体
SubShader
{
//Queue标签用于决定模型用于哪个渲染队列(队列索引号越小越先渲染越适合背景一类)
Tags { "Queue"="AlphaTest" }
pass{...}
}
Shader "LT/AlphaTest"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Color("Color",Color) = (1,1,1,1)
_Cutoff("Cutoff",Range(0,1)) = 0.5
}
SubShader
{
//Queue标签用于决定模型用于哪个渲染队列(队列索引号越小越先渲染越适合背景一类)
Tags { "QUEUE"="AlphaTest" "IGNOREPROJECTOR"="True" "RenderType"="TransparentCutout" } //这一行千万要注意空格,不然模型会出现一会儿部分透明一会儿不透明的问题
Pass
{
Tags{"LightMode" = "ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _Color;
fixed _Cutoff;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal :NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float3 worldNormal :TEXCOORD1;
float3 worldPos :TEXCOORD2;
};
//坐标系转换,模型空间->世界空间
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
fixed4 col = tex2D(_MainTex, i.uv);
//alpha test
clip(col.a - _Cutoff);
//上面这句等同与下面这个
//if((col.a - _Cutoff)<0.0)
// {
// disscard;
// }
fixed3 albedo = col.rgb * _Color.rgb;
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
fixed3 diffuse = _LightColor0.rgb * albedo * max(0,dot(worldNormal,worldLightDir));
return fixed4(ambient + diffuse,1.0);
}
ENDCG
}
}
FallBack "Transparent/Cutout/VertexLit"
}
Blend透明度混合
Blend 混合等式为加法操作,默认情况
BlendOp BlendOperation混合操作命令
Untiy 官网有详细说明:https://docs.unity3d.com/Manual/SL-Blend.html
我再根据阅读《unity shader入门精要》后我的理解详细说下具体的计算公式:
ShaderLab 中设置混合因子的命令
命令 描述
Blend SrcFactor DstFactor 开启混合,设置混合因子。Orgba= SrcFactor*Srgba + DstFactor*Drgba
Blend SrcFactor DstFactor, 开启混合,设置混合因子,但是透明通道使用了不同的混合因子,公式如下:
SrcFactorA DstFactorA Orgb= SrcFactor*Srgb + DstFactor*Drgb,Alpha通道部分SrcFactorA和DstFactorA 公式:
Oa= SrcFactorA*Sa + DstFactorA*Da
公式中的变量:
Srgba:源颜色(该片元产生的颜色),可以理解为:当前物体的颜色
Drgba:目标颜色(已存在于颜色缓存的颜色),可以暂时理解为:先写入颜色缓冲区的颜色
SrcFactor:源颜色的混合因子
DstFactor :目标颜色的混合因子
Blend factors
All following properties are valid for both SrcFactor & DstFactor in theBlend command.Source refers to the calculated color,Destination is the color already on the screen. The blend factors are ignored ifBlendOp is using logical operations.
One
因子为1,The value of one - use this to let either the source or the destination color come through fully.
Zero
因子为0,The value zero - use this to remove either the source or the destination values.
SrcColor
源颜色值,The value of this stage is multiplied by the source color value.
SrcAlpha
源颜色的透明通道(A通道)值The value of this stage is multiplied by the source alpha value.
DstColor
目标颜色值The value of this stage is multiplied by frame buffer source color value.
DstAlpha
目标颜色的透明通道(A通道)值The value of this stage is multiplied by frame buffer source alpha value.
OneMinusSrcColor
1-源颜色值The value of this stage is multiplied by (1 - source color).
OneMinusSrcAlpha
1-源颜色的透明通道(A通道)值The value of this stage is multiplied by (1 - source alpha).
OneMinusDstColor
1-目标颜色值The value of this stage is multiplied by (1 - destination color).
OneMinusDstAlpha
1-目标颜色的透明通道(A通道)值The value of this stage is multiplied by (1 - destination alpha).
Blend SrcFactor DstFactor, SrcFactorA DstFactorA可以使用不同参数混合透明通道,例如我们想要混合后输出颜色的透明度值就是源颜色的透明度。
Blend SrcAlpha OneMinusSrcAlpha , One Zero
Blend operations混合操作
The following blend operations can be used:
Add
Add source and destination together.
源颜色+目标颜色
Orgb = SrcFactor*Srgb + DstFactor*Drgb
Oa = SrcFactorA*Sa + DstFactorA*Da
Sub
Subtract destination from source.
源颜色-目标颜色
Orgb = SrcFactor*Srgb - DstFactor*Drgb
Oa = SrcFactorA*Sa - DstFactorA*Da
RevSub
Subtract source from destination.
目标颜色-源颜色
Orgb = DstFactor*Drgb - SrcFactor*Srgb
Oa = DstFactorA*Da - SrcFactorA*Sa
Min
Use the smaller of source and destination.
取源颜色和目标颜色最小值(与混合因子无关)
Orgba =(min(Sr,Cr), min(Sg,Cg), min(Sb,Cb), min(Sa,Ca))
Max
Use the larger of source and destination.
取源颜色和目标颜色最大值(与混合因子无关)
Orgba =(max(Sr,Cr), max (Sg,Cg), max (Sb,Cb), max (Sa,Ca))
LogicalClear
Logical operation: Clear (0)DX11.1 only.
DX11.1 only(只支持DX11)
LogicalSet
Logical operation: Set (1)DX11.1 only.
LogicalCopy
Logical operation: Copy (s)DX11.1 only.
LogicalCopyInverted
Logical operation: Copy inverted (!s)DX11.1 only.
LogicalNoop
Logical operation: Noop (d)DX11.1 only.
LogicalInvert
Logical operation: Invert (!d)DX11.1 only.
LogicalAnd
Logical operation: And (s & d)DX11.1 only.
LogicalNand
Logical operation: Nand !(s & d)DX11.1 only.
LogicalOr
Logical operation: Or (s | d)DX11.1 only.
LogicalNor
Logical operation: Nor !(s | d)DX11.1 only.
LogicalXor
Logical operation: Xor (s ^ d)DX11.1 only.
LogicalEquiv
Logical operation: Equivalence !(s ^ d)DX11.1 only.
LogicalAndReverse
Logical operation: Reverse And (s & !d)DX11.1 only.
LogicalAndInverted
Logical operation: Inverted And (!s & d)DX11.1 only.
LogicalOrReverse
Logical operation: Reverse Or (s | !d)DX11.1 only.
LogicalOrInverted
Logical operation: Inverted Or (!s | d)DX11.1 only.
//正常混合,透明度混合
Blend SrcAlpha OneMinusSrcAlpha
//柔和相加
Blend OneMinusSrcAlpha
//正片叠底,源颜色和目标颜色相乘
Blend DstColor Zero
//两倍相乘
Blend DstColor SrcColor
//变暗取当前颜色最小值,后面这句Blend One One不会对结果产生影响
BlendOp Min
Blend One One // Blend Zero Zero效果也是一样的
//变亮
BlendOp Max
Blend One One
//滤色
Blend OneMinusDstColor One //等同于
Blend One OneMinusSrcColor
//线性减淡
Blend One One
shader 实例
Shader "LT/AlphaBlend"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Color("Color",Color) = (1,1,1,1)
_AlphaScale("Alpha Scale",Range(0,1)) = 1
}
SubShader
{
Tags { "QUEUE"="Transparent" "IGNOREPROJECTOR"="True" "RenderType"="Transparent" }//这一行千万要注意空格,不然模型会出现一会儿部分透明一会儿不透明的问题
Pass
{
Tags{"LightMode" = "ForwardBase"}
ZWrite off //如果不关闭深度写入,半透明物体离相机更近的话,进行深度测试后会将其后的物体表面剔除。导致没有半透效果了,因此关闭深度写入。
Blend SrcAlpha OneMinusSrcAlpha //透明度混合
// Blend OneMinusDstColor One //柔和相加
// Blend DstColor Zero //正片叠底,目标颜色*源颜色
// BlendOp Min //取颜色最小值
// Blend Zero Zero
// BlendOp Max ////取颜色最大值
// Blend One One
// Blend OneMinusDstColor One //滤色,与下面这句等价
// Blend One OneMinusSrcColor
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _Color;
fixed _AlphaScale;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal :NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float3 worldNormal :TEXCOORD1;
float3 worldPos :TEXCOORD2;
};
//坐标系转换,模型空间->世界空间
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
fixed4 col = tex2D(_MainTex, i.uv);
//alpha test
// clip(col.a - _Cutoff);
//上面这句等同与下面这个
//if((col.a - _Cutoff)<0.0)
// {
// disscard;
// }
fixed3 albedo = col.rgb * _Color.rgb;
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
fixed3 diffuse = _LightColor0.rgb * albedo * max(0,dot(worldNormal,worldLightDir));
return fixed4(ambient + diffuse,col.a * _AlphaScale);
}
ENDCG
}
}
FallBack "Transparent/VertexLit"
}
测试结果对比:
- 透明度测试与透明度混合详解《unity shader入门精要》学习笔记
- 透明度测试与透明度混合详解《unity shader入门精要》学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要 学习笔记一
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- Unity Shader入门精要学习笔记
- 微信小程序获取获取openid
- 通过ContentObserver监听数据库某表的增加、删除、更新动作,实现listView异步单项Item的刷新
- Java面试之路(一)Java基础部分
- Maven编译打包过程(clean install)中遇到相关jdk版本导致的问题
- 杭电oj1865
- 透明度测试与透明度混合详解《unity shader入门精要》学习笔记
- LINTCODE————最小划分
- 程序员 30 岁前,该如何规划自己的职业发展?
- 淡入淡出js 原生实现以及css 实现方法
- 最不可思议的巧合,这些电影一定是穿越者拍的了!
- 腾讯换logo了!还出了套“腾讯字体”:6763个汉字 !
- 简单的计算100000以内的质数(JAVA实现)
- 机器学习算法总结
- 三种方式打印杨辉三角形(JAVA实现)