1可视空间
Unity Shader是怎么知道一个像素该画在哪个位置?下面是先展示一组Cube
1-1.操控一组3维坐标
创建一10*10*10的3维Cube数组,并作为UnityMatrices对象的成员变量,接下来显示这些Cube在空间中的位置
void InitCubeArray() { for (int i =0 , z = 0; z < generalCount; z++) { for (int y = 0; y < generalCount; y++) { for (int x = 0; x < generalCount; x++) { cubes[i++] = CreateCubesPoint(x, y, z); } } } }
Transform CreateCubesPoint(int x, int y, int z) { GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f); cube.transform.localPosition = CreateCoordinate(x, y, z); cube.GetComponent<MeshRenderer>().material.color = CreateColor(x, y, z); return cube.transform; }
设置每个Cube的位置,都以(0,0,0)为原点,(10-1)*0.5为Center左右两边对称
Vector3 CreateCoordinate(int x, int y, int z) { return new Vector3( x - center, y - center, z - center ); }
然后再用自身坐标xyz分量与Center的比率初始化颜色rgb。效果如上图1-1
Color CreateColor(int x, int y, int z) { return new Color( (float)x / generalCount, (float)y / generalCount, (float)z / generalCount ); }
2空间变换
positionning,rotating,and scaling
Cube数组中每个元素在空间中的变换有可能会有差异,虽然每个Cube变换的细节不同,但它们都需要经过一个方法来变换到空间中的某个坐标点。为此我们可以为所有变换创建一个abstract 基类,包含一个抽象的Applay()成员方法,由具体的变换组件去实现这个方法。
public abstract class Transformation : MonoBehaviour { public abstract Vector3 Apply(Vector3 point); }
我们给这个UnityMatrices对象添加这样的组件,同时检索Cube数组每个对象,将其坐标传入这个组件的Apply()方法进行计算得到新坐标并应用,这里始终以(0,0,0)作为每个Cube对象的原点坐标,而不能依赖其实际坐标,因为会每帧实时计算并改变。最后我们用泛型列表存储这种一系列变换组件方便统一计算。
private void Update() { GetComponents<Transformation>(transformations); //for (int i = 0; i < cubes.Length; i++) //{ // cubes[i].localPosition = TransformPoint(cubes[i].localPosition); //} for (int i =0 , z = 0; z < generalCount; z++) { for (int y = 0; y < generalCount; y++) { for (int x = 0; x < generalCount; x++) { cubes[i++].localPosition = TransformPoint(x, y, z); } } } }
Vector3 TransformPoint(int x, int y, int z) { Vector3 coordinates = CreateCoordinate(x, y, z); for (int i = 0; i < transformations.Count; i++) { coordinates = transformations[i].Apply(coordinates); } return coordinates; }
2.1位移
现在来做第一种变换:translation位移,这很简单。首先创建一个继承自Transformation组件子类,并定义一个表示自身位置属性的变量,并实现基类的抽象方法。然后添加给Cube数组对象
public class PositionTransformation : Transformation
{
public Vector3 position;
public override Vector3 Apply(Vector3 point)
{
return point + position;
}
}
现在可以向UnityMatrices对象添加位置转换组件。这允许我们在不移动UnityMatrices对象的情况下移动数组中每个对象的坐标,所有的变换都发生在其局部空间。
位移
2.2缩放
接下来做第二种变换:Scaling缩放,这更简单。
public class ScaleTransformation : Transformation
{
public Vector3 scale;
public override Vector3 Apply(Vector3 point)
{
point.x *= scale.x;
point.y *= scale.y;
point.z *= scale.z;
return point;
}
}
缩放