游戏中常见的对图片挖洞方法的一种实现
直接上原理:
用一张与目标图大小一样的贴图,填充其alpha通道,将需要挖洞的区域的alpha值设置为>0的值,在shader里处理alpha>0的区域将目标图的alpha设置为0即可,比较简单吧
shader代码:
(1).在Properties中加一个_AlphaTex (“Alpha Texture”, 2D) = “white” {}
// 加一个alpha贴图
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_AlphaTex ("Alpha Texture", 2D) = "white" {}
}
(2).frag着色器中的处理
// A code block
fixed4 frag(v2f IN) : SV_Target
{
fixed4 texcol = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
fixed4 alphacol = (tex2D(_AlphaTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
fixed4 color = texcol;
color.a *= step(alphacol.a,0); //即当alphacol.a <= 0的时候返回1 当alphacol.a > 0的时候返回0
return color;
}
逻辑代码:
(1).三角形洞
--作用:图片挖洞(三角形洞)
--参数说明:
--pt1,pt2,pt3三角形的三个顶点
function UIHoleUtil.setTriangleHole(image,pt1,pt2,pt3)
if goutil.isNil(image) then return end
if not image.material or image.material.shader ~= UIHoleUtil.Shader then
local size = image.transform.sizeDelta
local newMat = UnityEngine.Material.New(UIHoleUtil.Shader)
local alphaTex = UnityEngine.Texture2D.New(size.x,size.y) --UnityEngine.TextureFormat.Alpha8,false
for i = 0,size.x - 1 do
for j = 0,size.y - 1 do
local alpha = 0
if isInTriangle(pt1,pt2,pt3,Vector2(i,j)) then
alpha = 1
end
alphaTex:SetPixel(i,j,Color.New(0,0,0,alpha))
end
end
alphaTex:Apply()
newMat:SetTexture("_AlphaTex",alphaTex)
image.material = newMat
end
end
(2).圆形洞
--作用:图片挖洞(圆形洞)
--参数说明:
--pt1,pt2,pt3三角形的三个顶点
function UIHoleUtil.setTriangleHole(image,pt1,pt2,pt3)
if goutil.isNil(image) then return end
if not image.material or image.material.shader ~= UIHoleUtil.Shader then
local size = image.transform.sizeDelta
local newMat = UnityEngine.Material.New(UIHoleUtil.Shader)
local alphaTex = UnityEngine.Texture2D.New(size.x,size.y) --UnityEngine.TextureFormat.Alpha8,false
for i = 0,size.x - 1 do
for j = 0,size.y - 1 do
local alpha = 0
if (i-offsetx)*(i-offsetx) + (j-offsety)*(j-offsety) <= radius * radius then
alpha = 1
end
alphaTex:SetPixel(i,j,Color.New(0,0,0,alpha))
end
end
alphaTex:Apply()
newMat:SetTexture("_AlphaTex",alphaTex)
image.material = newMat
end
end
(3).矩形洞
--作用:图片挖洞(矩形洞)
--参数说明:
--pt1,pt2,pt3三角形的三个顶点
function UIHoleUtil.setTriangleHole(image,pt1,pt2,pt3)
if goutil.isNil(image) then return end
if not image.material or image.material.shader ~= UIHoleUtil.Shader then
local size = image.transform.sizeDelta
local newMat = UnityEngine.Material.New(UIHoleUtil.Shader)
local alphaTex = UnityEngine.Texture2D.New(size.x,size.y) --UnityEngine.TextureFormat.Alpha8,false
for i = 0,size.x - 1 do
for j = 0,size.y - 1 do
local alpha = 0
if i >= offsetx - width and i <= offsetx + width and j >= offsety - height and j <= offsety + height then
alpha = 1
end
alphaTex:SetPixel(i,j,Color.New(0,0,0,alpha))
end
end
alphaTex:Apply()
newMat:SetTexture("_AlphaTex",alphaTex)
image.material = newMat
end
end
(4).自定义贴图
--作用:图片挖洞(自定义的alpha单通道贴图形状)
--参数说明:
--alphaTex2d:该贴图只需要写入alpha通道的值,alpha > 0的区域将会被挖空
function UIHoleUtil.setHoleByTex2D(image,alphaTex2d)
if goutil.isNil(image) then return end
if not image.material or image.material.shader ~= UIHoleUtil.Shader then
newMat:SetTexture("_AlphaTex",alphaTex2d)
image.material = newMat
end
end