工程截图
CorrosionEffect.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 腐蚀效果
/// </summary>
public class CorrosionEffect : MonoBehaviour
{
[SerializeField]
private RawImage m_RawImage;
//定义结构元素(Sturcture Element),即模板
//模板可以定义成各种形状,用1表示有效区域,不同的模板形状产生的效果不同。
private int[,] SE;
private int SE_W, SE_H;//模板宽,高
[SerializeField]
private SturctureElement m_SturctureElement;
//定义模板类型
public enum SturctureElement
{
SE_3X3,
SE_4X4,
SE_5X5_PRISMATIC
}
private void Awake()
{
switch (m_SturctureElement)
{
case SturctureElement.SE_3X3:
SE = new int[,] {
{ 1, 1, 1 },
{ 1, 1, 1 },
{ 1, 1, 1 } };
SE_W = 3;
SE_H = 3;
break;
case SturctureElement.SE_4X4:
SE = new int[,] {
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 }};
SE_W = 4;
SE_H = 4;
break;
case SturctureElement.SE_5X5_PRISMATIC: //5x5棱形
SE = new int[,] {
{ 0, 0, 1, 0, 0 },
{ 0, 1, 1, 1, 0 },
{ 1, 1, 1, 1, 1 },
{ 0, 1, 1, 1, 0 },
{ 0, 0, 1, 0, 0 }};
SE_W = 5;
SE_H = 5;
break;
}
}
void Start()
{
Corrode();
}
/// <summary>
/// 腐蚀
/// </summary>
public void Corrode()
{
Texture2D tex = m_RawImage.texture as Texture2D;
if (tex == null)
return;
Texture2D newTex = new Texture2D(tex.width, tex.height);
newTex.SetPixels( tex.GetPixels() );
int rowCount = tex.height - SE_H;
int columnCount = tex.width - SE_W;
//用模板去扫描Texture的每一行
for (int y=0; y < rowCount; y += 1)
{
//扫描一行
for (int x = 0; x < columnCount; x += 1)
{
if (!HitWhite(x, y, SE_W, SE_H, tex))
continue;
//腐蚀原理: 模板形状覆盖区发现白色,则将整个模板形状区设置成白色
SetAreaColor(x, y, SE_W, SE_H, Color.white, newTex);
}
}
newTex.Apply();
m_RawImage.texture = newTex;
}
//模板覆盖区是否存在白色 (对黑色进行腐蚀)
private bool HitWhite(int x, int y, int blockWidth, int blockHeight, Texture2D tex)
{
for (int i=x, tx=0; i<x+blockWidth; i++, tx++)
{
for (int j=y, ty=0; j<y+blockHeight; j++, ty++)
{
if (SE[tx,ty] == 0)
continue;//不在模板形状内
Color c = tex.GetPixel(i, j);
//粗略判断
if (c.r > 0.5f && c.g > 0.5f && c.b > 0.5f)
{
return true;
}
}
}
return false;
}
//设置模板形状所覆盖的区域颜色
private void SetAreaColor(int x, int y, int blockWidth, int blockHeight, Color color, Texture2D tex)
{
int size = blockWidth * blockHeight;
Color[] colors = new Color[size];
for (int i = 0; i < size; i++)
colors[i] = color;
for (int i=0; i<blockHeight; i++)
{
for (int j=0; j<blockWidth; j++)
{
if (SE[i, j] == 0)
continue;
tex.SetPixel(x+j, y+i, color);
}
}
}
}
运行效果