工作的时候一直都听到同事们再说uv坐标,其实我们对这个词很熟悉,但是说到真正是什么,却发现自己了解的并不透彻,写一篇博客,梳理下基础,了解uv到底是干嘛的!
1.uv是什么?
2.uv贴图的作用是什么?
uv就是我们屏幕上的像素所显示的位置,我们可以根据uv坐标拿到每个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的实现方法。
平移:
///
/// 平移贴图
///
/// 贴图
/// 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#用矩阵运算求新的像素位置,但是好像是不成功的,然而用上面的方法是可以成功实现的,缩放操作暂时还没有写,后面或许会补全!