前言
在时隔两个月后,这个游戏引擎技术系列再次更新了,我都没想到整整摸了两个月的鱼,最近生活也比较稳定了,以后这一系列会尽量多更一些。
今天要说的就是透明贴图的实现技术,从技术原理来说,大致有透切(AC——AlphaCutout)、透混(AB——AlphaBlend)以及透叠(AD——Additive)。
以下会详细说一下不同技术的特点和实现方式。
透切AC
所谓透切就是使用透明贴图对物体进行裁切,一般用于有复杂轮廓和明确边缘的物体,例如镂空金属、裙摆边缘、卡通风格的头发、树叶、风格化的特效等等。优点是没有前后排序问题,不会出现前后遮挡关系混乱;缺点则是边缘较实,移动端性能较差。
在Unity中实现透切AC的shader代码如下:
// shader的路径和名称 Shader "Shader Forge/AlphaCutoff" { // 暴露属性到面板 Properties { _ACmap("RGB: Color A: Alpha", 2d) = "white"{} _Cutoff("Cutoff Threshold", range(0.0, 1.0)) = 0.5 } SubShader { Tags { "RenderType"="TransparentCutout" //改为cutoff对应的 "ForceNoShadowCasting"="True" //关闭阴影投射 "IgnoreProjector"="True" //不响应投射器 } Pass { Name "FORWARD" Tags { "LightMode"="ForwardBase" } Cull Off //双面显示 CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #pragma multi_compile_fwdbase_fullshadows #pragma target 3.0 // 声明变量 uniform sampler2D _ACmap; uniform float4 _ACmap_ST; //支持UV TillingOffset uniform half _Cutoff; // 输入结构 struct VertexInput { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; // 输出结构 struct VertexOutput { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; // 顶点shader VertexOutput vert (VertexInput v) { VertexOutput o = (VertexOutput)0; o.pos = UnityObjectToClipPos( v.vertex ); o.uv = TRANSFORM_TEX(v.uv, _ACmap); return o; } // 像素shader float4 frag(VertexOutput i) : COLOR { half4 var_ACmap = tex2D(_ACmap, i.uv); clip(var_ACmap.a - _Cutoff); return var_ACmap; } ENDCG } } FallBack "Diffuse" }
效果如下:
可以看出裁切的范围是通过Cutoff Threshold阈值控制的,边缘过渡不够自然。
透混AB
透混则是通过混合模式进行叠加,一般用于有复杂轮廓而无明确边缘的物体,例如头发、特效底层等。优点是边缘效果较好,缺点则是会有前后排序问题。
所谓透明排序问题,其实是因为默认情况下为节省性能消耗,在物体有前后遮挡关系时,先通过Z-buffer深度缓存计算物体每个顶点与摄像机的距离,渲染时只渲染靠摄像机最近的物体部分,被遮挡的物体部分或其他物体会被剔除掉,那么当最前方物体是透明的时候,后方物体也不会进行渲染。
在Unity中实现透混AB的shader代码如下:
// shader的路径和名称 Shader "Shader Forge/AlphaBlend" { // 暴露属性到面板 Properties { _ABmap("RGB: Color A: Alpha", 2d) = "gray"{} _Opacity("Opacity", range(0.0, 1.0)) = 1.0 } SubShader { Tags { "Queue"="Transparent" //调整渲染顺序 "RenderType"="Transparent" //改为对应的 "ForceNoShadowCasting"="True" //关闭阴影投射 "IgnoreProjector"="True" //不响应投射器 } Pass { Name "FORWARD" Tags { "LightMode"="ForwardBase" } Blend One OneMinusSrcAlpha //修改混合模式,如果不预乘也不shader乘此处应为SrcAlpha OneMinusSrcAlpha Cull Off //双面显示 CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #pragma multi_compile_fwdbase_fullshadows #pragma target 3.0 // 声明变量 uniform sampler2D _ABmap; uniform float4 _ABmap_ST; //支持UV TillingOffset uniform half _Opacity; // 输入结构 struct VertexInput { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; // 输出结构 struct VertexOutput { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; // 顶点shader VertexOutput vert (VertexInput v) { VertexOutput o = (VertexOutput)0; o.pos = UnityObjectToClipPos( v.vertex ); o.uv = TRANSFORM_TEX(v.uv, _ABmap); return o; } // 像素shader float4 frag(VertexOutput i) : COLOR { half4 var_ABmap = tex2D(_ABmap, i.uv); half finalOpacity = var_ABmap.a * _Opacity; return half4(var_ABmap.rgb * _Opacity,finalOpacity); } ENDCG } } FallBack "Diffuse" }
效果如下:
可以看出裁切边缘过渡是通过Alpha控制的,效果比较自然,并可以通过Opacity参数整体控制透明度,但缺点则是会产生前后排序问题,在旋转时会有很明显的穿帮,需要再使用其他技术进行修复。
透叠AD
透叠与透混类似,同样是通过混合模式叠加,常用于发光体、辉光物体。一般特效会先使用AB打底,再叠加上AD辉光,但要注意AD也有排序问题,而且多层AD叠加会叠爆性能(OverDraw),因此辉光特效更适合使用后处理代替。
在Unity中实现透叠AD的shader代码如下:
// shader的路径和名称 Shader "Shader Forge/Additive" { // 暴露属性到面板 Properties { _ADmap("RGB: Color A:Alpha", 2d) = "gray"{} _Opacity("Opacity", range(0.0, 1.0)) = 1.0 } SubShader { Tags { "Queue"="Transparent" //调整渲染顺序 "RenderType"="Transparent" //改为对应的 "ForceNoShadowCasting"="True" //关闭阴影投射 "IgnoreProjector"="True" //不响应投射器 } Pass { Name "FORWARD" Tags { "LightMode"="ForwardBase" } Blend One One Cull Off //双面显示 CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #pragma multi_compile_fwdbase_fullshadows #pragma target 3.0 // 声明变量 uniform sampler2D _ADmap; uniform float4 _ADmap_ST; //支持UV TillingOffset uniform half _Opacity; // 输入结构 struct VertexInput { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; // 输出结构 struct VertexOutput { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; // 顶点shader VertexOutput vert (VertexInput v) { VertexOutput o = (VertexOutput)0; o.pos = UnityObjectToClipPos( v.vertex ); o.uv = TRANSFORM_TEX(v.uv, _ABmap); return o; } // 像素shader float4 frag(VertexOutput i) : COLOR { half4 var_ADmap = tex2D(_ADmap, i.uv); half finalOpacity = var_ADmap.a * _Opacity; return half4(var_ADmap.rgb * _Opacity,finalOpacity);//如果非预乘Alpha的话为return half4(var_ADmap.rgb * finalOpacity,finalOpacity); } ENDCG } } FallBack "Diffuse" }
效果如下:
可以看出参数、效果和AB类似,也产生了和AB同样的前后排序问题。
自定义混合模式
从上面的代码可以看出AB和AD都是通过不同混合模式的叠加实现的,因此可以通过将叠加功能作为可选项实现一个可自由选择的透明贴图模式。
在Unity中实现shader代码如下:
// shader的路径和名称 Shader "Shader Forge/CustomBlend" { // 暴露属性到面板 Properties { _ADmap("RGB: Color", 2d) = "gray"{} _Opacity("Opacity", range(0.0, 1.0)) = 1.0 [Enum(UnityEngine.Rendering.BlendMode)] _BlendSrc ("Blend Source", int) = 0 [Enum(UnityEngine.Rendering.BlendMode)] _BlendDst ("Blend Destination", int) = 0 [Enum(UnityEngine.Rendering.BlendOp)] _BlendOp ("Blend Operation", int) = 0 } SubShader { Tags { "Queue"="Transparent" //调整渲染顺序 "RenderType"="Transparent" //改为对应的 "ForceNoShadowCasting"="True" //关闭阴影投射 "IgnoreProjector"="True" //不响应投射器 } Pass { Name "FORWARD" Tags { "LightMode"="ForwardBase" } BlendOp [_BlendOp] Blend [_BlendSrc] [_BlendDst] //修改混合模式 Cull Off //双面显示 CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #pragma multi_compile_fwdbase_fullshadows #pragma target 3.0 // 声明变量 uniform sampler2D _ADmap; uniform float4 _ADmap_ST; //支持UV TillingOffset uniform half _Opacity; // 输入结构 struct VertexInput { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; // 输出结构 struct VertexOutput { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; // 顶点shader VertexOutput vert (VertexInput v) { VertexOutput o = (VertexOutput)0; o.pos = UnityObjectToClipPos( v.vertex ); o.uv = TRANSFORM_TEX(v.uv, _ADmap); return o; } // 像素shader float4 frag(VertexOutput i) : COLOR { half4 var_ADmap = tex2D(_ADmap, i.uv); half finalOpacity = var_ADmap.a * _Opacity; return half4(var_ADmap.rgb * _Opacity,finalOpacity); //如果非预乘Alpha的话则为return half4(var_ADmap.rgb * finalOpacity,finalOpacity); } ENDCG } } FallBack "Diffuse" }
效果如下:
也可以将选定的几种组合方式进行包装,做成预设供用户选择,是的,PhotoShop的图层混合模式就是这样做的。
本文同样参考自B站庄懂的技术美术入门课,感谢。
学习的本质,
不在于记住哪些知识,
而在于它触发了你的思考。
——迈克尔·桑德尔
评论
711781 630025Can I just say what a relief to search out somebody who really is aware of what theyre speaking about on the internet. You undoubtedly know how to deliver a difficulty to light and make it essential. Extra folks need to learn this and perceive this facet with the story. I cant consider youre no a lot more common because you positively have the gift. 97033
Some genuinely fantastic information, Gladiola I observed this. “‘Beauty is truth, truth beauty,’ — that is allYe know on Earth, and all ye need to know.” by John Keats.
https://www.tiendapc.com/674-televisores/389629-samsung-qe65qn800btxxc-series-8-65qn800b-165-1-cm-65-8k-ultra-hd-smart-tv-wifi-acero-inoxidab-8806094194647.html
What is Alpha Tonic? Alpha Tonic stands as a natural health supplement designed to comprehensively address men’s overall well-being.
https://youtu.be/xx76FOUm9Ms
FitSpresso is a natural weight loss supplement that will help you maintain healthy body weight without having to deprive your body of your favorite food or take up exhausting workout routines.
https://youtu.be/bWMIB55wfaU
I was wondering if you ever considered changing the layout of your site? Its very well written; I love what youve got to say. But maybe you could a little more in the way of content so people could connect with it better. Youve got an awful lot of text for only having 1 or two pictures. Maybe you could space it out better?
https://youtu.be/dwqHphZKTtA
Hey There. I found your blog using msn. This is a really well written article. I’ll be sure to bookmark it and come back to read more of your useful information. Thanks for the post. I’ll certainly return.
https://youtu.be/u-1NI679V24
I saw a lot of website but I think this one has something special in it in it
https://youtu.be/8t6cCMoxSDs
I like this web site very much, Its a real nice berth to read and obtain info . “It is impossible for a man to learn what he thinks he already knows.” by Epictetus.
https://youtu.be/PFgLnyztAhg