文章目录
- 前言
- 一、半透明混合自定义调整
- 1、属性面板
- 2、SubShader中
- 3、在片元着色器(可选)
- 3、根据纹理情况自己调节
- 二、适配Build In Render Pipeline
- 三、最终代码
前言
在前几篇文章中,我们依次解决了实现Shader序列帧动画所遇到的问题。
- Unity中Shader序列图动画(UV流动的通用起始点)
- Unity中Shader序列帧动画(U、V方向的走格)
- Unity中Shader的_Time精度问题
我们在这篇文章中,对其进行优化、适配BRP 和 总结。
一、半透明混合自定义调整
1、属性面板
[Enum(UnityEngine.Rendering.BlendMode)]_SrcFactor(“SrcFactor”,int) = 0
[Enum(UnityEngine.Rendering.BlendMode)]_DstFactor(“DstFactor”,int) = 0
2、SubShader中
Blend [_SrcFactor] [_DstFactor]
3、在片元着色器(可选)
- 使用返回颜色的rgb值与alpha值相乘输出,防止雾效影响透明度
col.rgb = col.rgb * col.a;
3、根据纹理情况自己调节
- Unity中Shader的混合模式Blend
二、适配Build In Render Pipeline
SubShader
{
Tags
{
//渲染类型
"RenderType"="Transparent"
//渲染队列
"Queue"="Transparent"
}
Blend [_SrcFactor] [_DstFactor]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float3 vertexOS : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertexCS : SV_POSITION;
float2 uv : TEXCOORD1;
UNITY_FOG_COORDS(2)
};
float4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
half4 _Sequence;
v2f vert(appdata v)
{
v2f o;
o.vertexCS = UnityObjectToClipPos(v.vertexOS);
o.uv = float2(v.uv.x / _Sequence.y, v.uv.y / _Sequence.x + (_Sequence.x - 1) / _Sequence.x);
o.uv.x += frac(floor(_Time.y * _Sequence.y * _Sequence.z) / _Sequence.y);
o.uv.y -= frac(floor(_Time.y * _Sequence.y * _Sequence.z / _Sequence.y) / _Sequence.x);
//o.uv.x += floor(_Time.y);
//o.uv = float2(v.uv.x/4,v.uv.y/4);
//o.uv = TRANSFORM_TEX(v.uv,_MainTex);
UNITY_TRANSFER_FOG(o, o.vertex)
return o;
}
half4 frag(v2f i) : SV_Target
{
float4 mainTex = tex2D(_MainTex, i.uv);
float4 col = mainTex * _Color;
UNITY_APPLY_FOG(i.fogCoord, col)
col.rgb = col.rgb * col.a;
return col;
}
ENDCG
}
}
三、最终代码
Shader "MyShader/URP/P3_9"
{
Properties
{
[Enum(UnityEngine.Rendering.BlendMode)]_SrcFactor("SrcFactor",int) = 0
[Enum(UnityEngine.Rendering.BlendMode)]_DstFactor("DstFactor",int) = 0
_Color("Color",Color) = (1,1,1,1)
_MainTex("MainTex",2D) = "white"{}
_Sequence("Row(X) Column(Y) Speed(Z)",Vector) = (1,1,1,1)
}
SubShader
{
Tags
{
//告诉引擎,该Shader只用于 URP 渲染管线
"RenderPipeline"="UniversalPipeline"
//渲染类型
"RenderType"="Transparent"
//渲染队列
"Queue"="Transparent"
}
Blend [_SrcFactor] [_DstFactor]
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct Attribute
{
float3 vertexOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varying
{
float4 vertexCS : SV_POSITION;
float2 uv : TEXCOORD1;
float fogCoord : TEXCOORD2;
};
CBUFFER_START(UnityPerMaterial)
float4 _Color;
float4 _MainTex_ST;
half4 _Sequence;
CBUFFER_END
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
Varying vert(Attribute v)
{
Varying o;
o.vertexCS = TransformObjectToHClip(v.vertexOS);
o.uv = float2(v.uv.x / _Sequence.y, v.uv.y / _Sequence.x + (_Sequence.x - 1) / _Sequence.x);
o.uv.x += frac(floor(_Time.y * _Sequence.y * _Sequence.z) / _Sequence.y);
o.uv.y -= frac(floor(_Time.y * _Sequence.y * _Sequence.z / _Sequence.y) / _Sequence.x);
//o.uv.x += floor(_Time.y);
//o.uv = float2(v.uv.x/4,v.uv.y/4);
//o.uv = TRANSFORM_TEX(v.uv,_MainTex);
o.fogCoord = ComputeFogFactor(o.vertexCS.z);
return o;
}
half4 frag(Varying i) : SV_Target
{
float4 mainTex = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
float4 col = mainTex * _Color;
col.rgb = MixFog(col, i.fogCoord);
col.rgb = col.rgb * col.a;
return col;
}
ENDHLSL
}
}
SubShader
{
Tags
{
//渲染类型
"RenderType"="Transparent"
//渲染队列
"Queue"="Transparent"
}
Blend [_SrcFactor] [_DstFactor]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float3 vertexOS : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertexCS : SV_POSITION;
float2 uv : TEXCOORD1;
UNITY_FOG_COORDS(2)
};
float4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
half4 _Sequence;
v2f vert(appdata v)
{
v2f o;
o.vertexCS = UnityObjectToClipPos(v.vertexOS);
o.uv = float2(v.uv.x / _Sequence.y, v.uv.y / _Sequence.x + (_Sequence.x - 1) / _Sequence.x);
o.uv.x += frac(floor(_Time.y * _Sequence.y * _Sequence.z) / _Sequence.y);
o.uv.y -= frac(floor(_Time.y * _Sequence.y * _Sequence.z / _Sequence.y) / _Sequence.x);
//o.uv.x += floor(_Time.y);
//o.uv = float2(v.uv.x/4,v.uv.y/4);
//o.uv = TRANSFORM_TEX(v.uv,_MainTex);
UNITY_TRANSFER_FOG(o, o.vertex)
return o;
}
half4 frag(v2f i) : SV_Target
{
float4 mainTex = tex2D(_MainTex, i.uv);
float4 col = mainTex * _Color;
UNITY_APPLY_FOG(i.fogCoord, col)
col.rgb = col.rgb * col.a;
return col;
}
ENDCG
}
}
}