目录
前言
最近想做一个物体两套材质随时间插值渐变的效果,本以为可以通过unity自带的Material.Lerp()实现,后来发现这个方法只适用于纯色的情况,其实与Color.Lerp()是同样的效果,后研究发现这个效果需要通过自定义shader来实现,因此记录如下
一、shader代码
新建一个shader名为TextureBlendShader
Shader "Custom/TextureBlendShader"
{
Properties
{
_StartTex ("Texture 1", 2D) = "white" {}
_TargetTex ("Texture 2", 2D) = "white" {}
_BlendAmount ("Blend Amount", Range(0, 1)) = 0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float2 uv1 : TEXCOORD1;
};
struct v2f
{
float2 uv : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float4 vertex : SV_POSITION;
};
sampler2D _StartTex;
sampler2D _TargetTex;
float _BlendAmount;
v2f vert (appdata_t v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.uv1 = v.uv1;
return o;
}
half4 frag (v2f i) : SV_Target
{
// 在这里使用 lerp 函数对两个贴图进行插值
half4 col1 = tex2D(_StartTex, i.uv1);
half4 col2 = tex2D(_TargetTex, i.uv1);
half4 finalColor = lerp(col1, col2, _BlendAmount);
return finalColor;
}
ENDCG
}
}
}
二、材质准备
首先有两套渲染好的材质
新建材质,使用上一步自定义的shader,然后将对应的贴图附上去
三、控制代码
新建一个脚本名为TextureBlendController.cs
cs
using UnityEngine;
public class TextureBlendController : MonoBehaviour {
public Material materialWithShader; // 包含自定义Shader的材质
public Texture targetTexture; // 目标贴图
public float transitionSpeed = 1.0f; // 渐变速度
private Material currentMaterial; // 当前材质
private float blendAmount = 0.0f; // 渐变值
void Start() {
currentMaterial = GetComponent<Renderer>().material;
}
void Update() {
// 在指定速度下进行渐变
blendAmount += Time.deltaTime * transitionSpeed;
blendAmount = Mathf.Clamp01(blendAmount); // 将值限制在0到1之间
// 更新Shader中的 BlendAmount 变量
currentMaterial.SetFloat("_BlendAmount", blendAmount);
// 渐变完成后停止
if (blendAmount >= 1.0f) {
enabled = false; // 可以根据需求停止更新
}
}
}
将这个脚本挂到所有需要渐变的物体上,通过改变blendAmount可以控制前后两套材质的混合程度。
效果如下