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

基础篇(五)

一.uv坐标

工作的时候一直都听到同事们再说uv坐标,其实我们对这个词很熟悉,但是说到真正是什么,却发现自己了解的并不透彻,写一篇博客,梳理下基础,了解uv到底是干嘛的!
1.uv是什么?
UnityShader学习教程之<详解uv坐标,c#类似uv坐标的值以及贴图操作>_第1张图片
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#的像素坐标控制图形,旋转和平移的操作

平移:

    /// 
    /// 平移贴图
    /// 
    /// 贴图
    /// x值
    /// y值
    /// 
    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;
    }

旋转:

    /// 
    /// 旋转图片
    /// 
    /// 
    /// 
    /// 
    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;
    }

缩放(补全):

    /// 
    /// 缩放图片
    /// 
    /// 
    /// 
    /// 
    /// 
    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#用矩阵运算求新的像素位置,但是好像是不成功的,然而用上面的方法是可以成功实现的,缩放操作暂时还没有写,后面或许会补全!

你可能感兴趣的:(Shader学习旅程,图形,c#)