UnityShader学习教程之<详解uv坐标,c#类似uv坐标的值以及贴图操作>

基础篇(五)

一.uv坐标

工作的时候一直都听到同事们再说uv坐标,其实我们对这个词很熟悉,但是说到真正是什么,却发现自己了解的并不透彻,写一篇博客,梳理下基础,了解uv到底是干嘛的!
1.uv是什么?
这里写图片描述
2.uv贴图的作用是什么?
uv就是我们屏幕上的像素所显示的位置,我们可以根据uv坐标拿到每个uv点上面的颜色值。

二.基于shader的uv坐标控制图形,旋转缩放和平移的操作

                //旋转需要的π
				float PI = 3.141592654;
				//弧度制
				float rotaAngle =(_DiffuseAngle * PI)/180;
				//三角函数
				float CosAngle = cos(rotaAngle);
				float SinAngle = sin(rotaAngle);
				//旋转的中心点
				float2 centerUV = float2(0.5,0.5);
				//uv坐标值
				float2 uvXY = i.uvdiffuse;
                //平移矩阵
				float2 uvdiffuse = (mul(float3(uvXY - centerUV,1),float3x3(1,0,0,0,1,0,_DiffuseShiftX,_DiffuseShiftY,1))).xy;
				//缩放矩阵
				uvdiffuse = mul(uvdiffuse,float2x2(_DiffuseRepeat,0,0,_DiffuseRepeat));
				//旋转矩阵
				uvdiffuse = mul(uvdiffuse,float2x2(CosAngle,-SinAngle,SinAngle,CosAngle)) + centerUV;

对uv坐标进行上面的一系列矩阵操作,可以实现旋转平移和缩放,原理可以参考前面的矩阵一章!这是shader的实现方法。

三.基于c#的像素坐标控制图形,旋转和平移的操作

平移:

    /// <summary>
    /// 平移贴图
    /// </summary>
    /// <param name="texture">贴图</param>
    /// <param name="transformX">x值</param>
    /// <param name="transformY">y值</param>
    /// <returns></returns>
    Texture2D TransfromTextrue(Texture2D texture, float transformX,float transformY)
    {
        Texture2D newImg = new Texture2D(texture.width, texture.height);

        for (int i=1;i< texture.width; i++)
        {
            for(int j = 1; j < texture.height; j++)
            {
                //移动过后的UV坐标
                float u = i + transformX;
                float v = j + transformY;
                //显示的原本的贴图像素
                Color col = texture.GetPixel(i, j);
                if (u <= newImg.width && v <= newImg.height)
                {
                    newImg.SetPixel((int)u, (int)v, col);
                }
            }
        }
        newImg.Apply();
        return newImg;
    }

旋转:

    /// <summary>
    /// 旋转图片
    /// </summary>
    /// <param name="texture"></param>
    /// <param name="eulerAngles"></param>
    /// <returns></returns>
    Texture2D RotateTexture(Texture2D texture, float eulerAngles)
    {
        float centerU = texture.width / 2;
        float centerV = texture.height / 2;
        Texture2D newImg = new Texture2D(texture.width, texture.height);
        for (int i=0;i< texture.width; i++)
        {
            for(int j=0;j< texture.height; j++)
            {
                float u = (i - centerU) * Mathf.Cos(eulerAngles) + (j - centerV) * Mathf.Sin(eulerAngles) + centerU;
                float v = -(i - centerU) * Mathf.Sin(eulerAngles) + (j - centerV) * Mathf.Cos(eulerAngles) + centerV;
                Color col = texture.GetPixel((int)u, (int)v);
                newImg.SetPixel(i, j, col);
            }
        }
        newImg.Apply();
        return newImg;
    }

缩放(补全):

    /// <summary>
    /// 缩放图片
    /// </summary>
    /// <param name="source"></param>
    /// <param name="targetWidth"></param>
    /// <param name="targetHeight"></param>
    /// <returns></returns>
    Texture2D ScaleTextureVHBilinear(Texture2D source, int targetWhite, int targetHeight, int k)
    {
        Texture2D result = new Texture2D(targetWhite, targetHeight, source.format, false);

        float incX = (1.0f / (float)targetWhite);
        float incY = (1.0f / (float)targetHeight);

        for (int i = 0; i < result.height; ++i)
        {
            for (int j = 0; j < result.width; ++j)
            {
                Color newColor = source.GetPixelBilinear((float)j / (float)result.width, (float)i / (float)result.height);
                result.SetPixel(j, i, newColor);
            }
        }
        result.Apply();
        return result;
    }

总结:c#由于运行在cpu上面处理图形的速度要比shader慢很多,但是有些特殊需求可能需要用到,shader是通过矩阵运算得到的,我曾尝试在c#用矩阵运算求新的像素位置,但是好像是不成功的,然而用上面的方法是可以成功实现的,缩放操作暂时还没有写,后面或许会补全!

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值