shader学习基础之五(详解uv坐标,c#类似uv坐标的值以及贴图操作)

来源:互联网 发布:oracle数据库 监控 编辑:程序博客网 时间:2024/06/05 15:53

基础篇(五)

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

原创粉丝点击