Unity 精灵图集Shader渲染错乱

原因

在使用 Unity 开发游戏过程中,UI 界面上的表现有着举足轻重的地位,优秀的表现效果可以让游戏增色不少。要让 UI 精灵图片有独特的表现效果,需要给图片加上特定的 Shader 着色器,这样一来就能让这个图片表现出独特的效果,比如:溶解、消失等等。然而,在使用中,因为精灵被打包到图集里面,运行起来的效果大相径庭,Shader 里面 uv 坐标不再是单个图片的坐标了,而是图集里面该图片的坐标,使得 Shader 计算错误,最终渲染错乱。

例子

当前测试版本:Unity 5.3.0
测试工程地址:https://github.com/akof1314/uGUISpriteInAtlasShader

正确的表现:

错误的表现:

包含该图片的图集:

图片位于图集的左下角,进行扭曲效果计算时,使用了图集的中心位置,导致出错。

解决

将单个图片的纹理坐标保存到 UV1 中,传递单个图片的纹理坐标和在图集中纹理坐标的比例关系。

纹理坐标

单个图片的纹理基本是(0,0),(0,1),(1,1),(1,0),UGUI 中图片控件只使用了 UV0,那么就可以将单个图片的纹理保存到 UV1 中。

继承BaseMeshEffect,重载ModifyMesh方法,代码如下:

using UnityEngine;
using UnityEngine.UI;

public class VertIndexAsUV1 : BaseMeshEffect
{
    public override void ModifyMesh(VertexHelper vh)
    {
        if (!IsActive())
            return;

        UIVertex vert = new UIVertex();
        for (int i = 0; i < vh.currentVertCount; i++)
        {
            vh.PopulateUIVertex(ref vert, i);
            vert.uv1.x = (i >> 1);
            vert.uv1.y = ((i >> 1) ^ (i & 1));
            vh.SetUIVertex(vert, i);
        }
    }
}

Shader 中加一个float2 texcoord1 : TEXCOORD1,绘制计算的时候,采用这个坐标,如下图所示:

对于简单的处理 Alpha 融合,这样就可以了。

比例关系

对于复杂的 Shader 表现,影响最终的图片绘制效果,那么还需要传递比例关系。可以直接使用 Unity 接口,获取图集里面单个图片的 UV 值,向 Shader 进行传递,代码如下所示:

Image img = GetComponent<Image>();
if (img)
{
    Vector4 uvRect = UnityEngine.Sprites.DataUtility.GetOuterUV(img.overrideSprite);
    m_Graphic.material.SetVector("_UvRect", uvRect);
}

Shader 里面通过单个图片的 UV 坐标,反推出图集里面的 UV 坐标,如下图所示:

结语

对于很多 Shader 算法,都是使用 UV 坐标去计算的,当遇到图集,那么就需要从计算的坐标,反推到真实的坐标。

Github 地址:https://github.com/akof1314/uGUISpriteInAtlasShader

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值