本篇主要用于记录自己的实战操作,以及一些碎碎念(观后感),如果有什么好想法或者本篇出现什么错误,请多指教~
本篇的内容参考视频:庄懂的技术美术入门课(美术向)
使用软件:Unity 2019 3.6f1 ,ShaderForge
本篇内容主要包括:对透明的补充,UV流动,UV扰动
一.透明补充
1.排序问题
如下图,由于排序的问题,除了AC外其他三个效果看起来很不对劲
简单的解决方法:
- Detach,Attach,可以在Max或Maya里对有透明排序问题的东西将其Detach出来,最后再Attach进去,可以得到一定程度缓解(而非解决,原理是改变其渲染顺序)
- 一些情况下用Zwrite Off解决(关闭Z深度,一半特效排序三个手段,最上一级为render cube,接下来是sorting layer,再低一节是sorting order,渲染图形前,会先渲染一层Z深度)
2.Alpha预乘问题
预乘即是将Alpha透贴与颜色乘下然后再放入RGB中
- 左图无预乘,右图做了预乘;
- AB中预乘可用One OneMinusSrcAlpha,不预乘用SrcAlpha OneMinusSrcAlpha(源乘子为源Alpha,目标乘子为1-Alpha),或在Shader里做乘法(可以在贴图,混合模式,shader里做,在贴图里乘边缘会发黑);
- AD中预乘可以没有A通道;不预乘需要在Shader里做乘法;
- 具体视项目情况而定,一般特效库里的带不带Alpha的都有一堆,具体再看
3.代码修改
二.UV流动
代码:
Shader "Unlit/co12-UVflow"{
Properties
{
_MainTex ("RGB:颜色 A:透贴", 2D) = "white" {}
_Opacity ("透明度", range(0, 1)) = 0.5
_NoiseTex ("噪声图", 2d) = "gray"{}
_NoiseInt ("噪声强度", range(0, 5)) = 0.5
_FlowSpeedU("流动速度U", range(-10, 10)) = 5
_FlowSpeedV("流动速度V", range(-10, 10)) = 5
}
SubShader
{
Tags {
"Queue" = "Transparent" //加个渲染序列,调整渲染顺序
"RenderType" = "Transparent"
"ForceNoShadowCasting"= "True" //特效里默认关闭阴影投影
"IgnoreProjector" = "True" //特效里默认不响应投射器
}
Pass
{
Tags{"LightMode" = "ForwardBase"}
Blend SrcAlpha OneMinusSrcAlpha //修改混合方式
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform half _Opacity;
uniform sampler2D _NoiseTex;
uniform float4 _NoiseTex_ST;
uniform half _NoiseInt;
uniform half _FlowSpeedU;
uniform half _FlowSpeedV;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float4 pos : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv0 = v.uv;
o.uv1 = TRANSFORM_TEX(v.uv, _NoiseTex);
o.uv1.y = o.uv1.y+frac(-_Time.x*_FlowSpeedV); //流速可控,farc是取余操作,低配机不取余可能会花掉
o.uv1.x = o.uv1.x+frac(-_Time.x*_FlowSpeedU);
return o;
}
fixed4 frag (v2f i) : COLOR
{
half4 var_MainTex = tex2D(_MainTex, i.uv0);
half4 var_NoiseTex= tex2D(_NoiseTex,i.uv1).r;
half3 finalRGB = var_MainTex.rgb;
half noise = lerp(1.0,var_NoiseTex*2.0,_NoiseInt);//Remap噪声,使其变亮
noise = max(0.0,noise);//舍弃负值
half opacity = var_MainTex.a*_Opacity*noise;
return half4(finalRGB,opacity);
}
ENDCG
}
}FallBack "Diffuse"
}
三.UV扰动
比起上面的UV流动使用的单通道的黑白噪声图,扭曲图是三通道的,因为UV是双通道,所以三个通道,两个扰动UV,一个还是噪声图;
- SD中的准备
- 代码
Shader "Unlit/co12-UVWarp"
{
Properties
{
_MainTex ("RGB:颜色 A:透贴", 2D) = "white" {}
_Opacity ("透明度", range(0, 1)) = 0.5
_WarpTex ("扭曲图", 2d) = "gray"{}
_WarpInt ("扭曲强度", range(0, 1)) = 0.5
_NoiseInt ("噪声强度", range(0, 5)) = 0.5
_FlowSpeedU("流动速度U", range(-10, 10)) = 5
_FlowSpeedV ("流动速度V", range(-10, 10)) = 5
}
SubShader
{
Tags {
"Queue" = "Transparent" //加个渲染序列,调整渲染顺序
"RenderType" = "Transparent"
"ForceNoShadowCasting"= "True" //特效里默认关闭阴影投影
"IgnoreProjector" = "True" //特效里默认不响应投射器
}
Pass
{
Tags{"LightMode" = "ForwardBase"}
Blend One OneMinusSrcAlpha //修改混合方式
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform half _Opacity;
uniform sampler2D _WarpTex;
uniform float4 _WarpTex_ST;
uniform half _WarpInt;
uniform half _NoiseInt;
uniform half _FlowSpeedU;
uniform half _FlowSpeedV;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float4 pos : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv0 = v.uv;
o.uv1 = TRANSFORM_TEX(v.uv, _WarpTex);
o.uv1.y = o.uv1.y+frac(-_Time.x*_FlowSpeedV); //流速可控,farc是取余操作,低配机不取余可能会花掉
o.uv1.x = o.uv1.x+frac(-_Time.x*_FlowSpeedU);
return o;
}
fixed4 frag (v2f i) : COLOR
{
half4 var_WarpTex = tex2D(_WarpTex,i.uv1).r;
float2 uvBias = 2*(var_WarpTex-0.5)*_WarpInt;//计算偏移值-0.5为了正负方向都偏移
float2 uv0 = i.uv0+uvBias;
half4 var_MainTex = tex2D(_MainTex, i.uv0);//采用偏移后的uv
half3 finalRGB = var_MainTex.rgb;
half noise = lerp(1.0,var_WarpTex*2.0,_NoiseInt);//Remap噪声,使其变亮
noise = max(0.0,noise);//舍弃负值
half opacity = var_MainTex.a*_Opacity*noise;
return half4(finalRGB,opacity);
}
ENDCG
}
}FallBack "Diffuse"
}