转https://blog.youkuaiyun.com/o83290102o5/article/details/117428173
一个cube是24个顶点,12个三角面
Shader "my/jc"
{
SubShader
{
Tags
{
"RenderType"="Opaque"
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float4 normal:NORMAL;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex + v.normal * 0.1);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
return fixed4(1, 1, 1, 1);
}
ENDCG
}
}
}
cube不是8个顶点而是24个顶点,即在cube每个顶点的位置,实际上有三个相同的且法线垂直且互不相连的顶点。由于传递过程中顶点是无法被得知是属于哪个面片上的顶点,而且每个顶点连接 3 个面片,因此一个顶点同时拥有 3 个法线等属性,这就需要 3 个顶点来表示,这就有了 3 * 8 = 24 个顶点。
Q:如何立方体6个面贴上不同的图
A:spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class uv : MonoBehaviour {
MeshFilter msf;
Mesh mesh;
[SerializeField]
Vector2[] uvs;
// Use this for initialization
void Start () {
msf = GetComponent<MeshFilter>();
Mesh meshCopy = Mesh.Instantiate(msf.sharedMesh) as Mesh; // Make a deep copy
meshCopy.name = "Cube2";
mesh = msf.mesh = meshCopy; // Assign the copy to the meshes
if (mesh == null || mesh.uv.Length != 24)
{
Debug.Log("Script needs to be attached to built-in cube");
return;
}
uvs = mesh.uv;
// Front
uvs[0] =new Vector2(0.0f, 0.0f);
uvs[1] =new Vector2(0.333f, 0.0f);
uvs[2] =new Vector2(0.0f, 0.333f);
uvs[3] = new Vector2(0.333f, 0.333f);
// Top
uvs[8] = new Vector2(0.334f, 0.0f);
uvs[9] = new Vector2(0.666f, 0.0f);
uvs[4] = new Vector2(0.334f, 0.333f);
uvs[5] = new Vector2(0.666f, 0.333f);
// Back
uvs[10] = new Vector2(0.667f, 0.0f);
uvs[11] = new Vector2(1.0f, 0.0f);
uvs[6] = new Vector2(0.667f, 0.333f);
uvs[7] = new Vector2(1.0f, 0.333f);
// Bottom
uvs[15] = new Vector2(0.0f, 0.333f);
uvs[14] = new Vector2(0.333f, 0.334f);
uvs[12] = new Vector2(0.0f, 0.666f);
uvs[13] = new Vector2(0.333f, 0.666f);
// Left
uvs[19] = new Vector2(0.334f, 0.334f);
uvs[18] = new Vector2(0.666f, 0.334f);
uvs[16] = new Vector2(0.334f, 0.666f);
uvs[17] = new Vector2(0.666f, 0.666f);
// Right
uvs[23] = new Vector2(0.667f, 0.334f);
uvs[22] = new Vector2(1.00f, 0.334f);
uvs[20] = new Vector2(0.667f, 0.666f);
uvs[21] =new Vector2(1.0f, 0.666f);
mesh.uv = uvs;
}
}
类似于展开UV,把贴图的每一块赋值给每个uv点
meshfilter组件有个mesh属性,mesh属性又有个uv属性,这个uv属性会直接控制显示贴图的哪一部分,以及如何显示贴图
uv中的每一项和vertices中的每一项都是一一对应的
在unity中,UV坐标划分,分下面两大步骤
- 参考的标准是,unity刚导入时的那张图,即原图
- 原图的左下角uv坐标定为(0,0),原图的右上角的uv坐标定位(1,1),原图的其它任何一个位置按照比例都会有一个uv坐标,比如原图的左上角的uv坐标定位(0,1),原图的右下角的UV坐标定位(1,0),原图的中心(对角线的交点)位置为(0.5,0.5),等等
总结:uv中的每一项和vertices中的每一项都是一一对应的,unity在贴图的时候,会把uv中每一个点和vertices中对应索引的顶点一一关联起来,这样可以实现贴图任意形状显示