# Unity 渲染教程（一）：矩阵

创建立方体网格。
· 支持缩放、位移和旋转。

· 使用变换矩阵。

· 创建简单的相机投影。

usingUnityEngine;

publicclassTransformationGrid : MonoBehaviour {

publicTransform prefab;

publicintgridResolution = 10;

Transform[] grid;

voidAwake () {

grid = newTransform[gridResolution * gridResolution * gridResolution];

for(inti = 0, z = 0; z < gridResolution; z++) {

for(inty = 0; y < gridResolution; y++) {

for(intx = 0; x < gridResolution; x++, i++) {

grid[i] = CreateGridPoint(x, y, z);

}

}

}

}


}

Transform CreateGridPoint (intx, inty, intz) {

Transform point = Instantiate<transform>(prefab);

point.localPosition = GetCoordinates(x, y, z);

point.GetComponent<meshrenderer>().material.color = newColor(

(float)x / gridResolution,

(float)y / gridResolution,

(float)z / gridResolution

);

returnpoint;


}</meshrenderer></transform>

Vector3 GetCoordinates (intx, inty, intz) {

returnnewVector3(

x - (gridResolution - 1) * 0.5f,

y - (gridResolution - 1) * 0.5f,

z - (gridResolution - 1) * 0.5f

);


}

need-to-insert-img

need-to-insert-img

need-to-insert-img

usingUnityEngine;

publicabstractclassTransformation : MonoBehaviour {

publicabstractVector3 Apply (Vector3 point);


}

usingUnityEngine;

usingSystem.Collections.Generic;

publicclassTransformationGrid : MonoBehaviour {

…

List<transformation> transformations;

voidAwake () {

…

transformations = newList<transformation>();

}


}</transformation></transformation>

voidUpdate () {

GetComponents<transformation>(transformations);

for(inti = 0, z = 0; z < gridResolution; z++) {

for(inty = 0; y < gridResolution; y++) {

for(intx = 0; x < gridResolution; x++, i++) {

grid[i].localPosition = TransformPoint(x, y, z);

}

}

}


}</transformation>

Vector3 TransformPoint (intx, inty, intz) {

Vector3 coordinates = GetCoordinates(x, y, z);

for(inti = 0; i < transformations.Count; i++) {

coordinates = transformations[i].Apply(coordinates);

}

returncoordinates;


}

usingUnityEngine;

publicclassPositionTransformation : Transformation {

publicVector3 position;


}

publicoverrideVector3 Apply (Vector3 point) {

returnpoint + position;


}

usingUnityEngine;

publicclassScaleTransformation : Transformation {

publicVector3 scale;

publicoverrideVector3 Apply (Vector3 point) {

point.x *= scale.x;

point.y *= scale.y;

point.z *= scale.z;

returnpoint;

}


}

usingUnityEngine;

publicclassRotationTransformation : Transformation {

publicVector3 rotation;

publicoverrideVector3 Apply (Vector3 point) {

returnpoint;

}


}

publicoverrideVector3 Apply (Vector3 point) {

    floatradZ = rotation.z * Mathf.Deg2Rad;

returnpoint;

}


1

2

3

4

5

returnnewVector3(

        point.x * cosZ - point.y * sinZ,

point.x * sinZ + point.y * cosZ,

point.z

);


统一的旋转矩阵

publicoverrideVector3 Apply (Vector3 point) {

floatradX = rotation.x * Mathf.Deg2Rad;

Vector3 xAxis = newVector3(

cosY * cosZ,

cosX * sinZ + sinX * sinY * cosZ,

sinX * sinZ - cosX * sinY * cosZ

);

Vector3 yAxis = newVector3(

-cosY * sinZ,

cosX * cosZ - sinX * sinY * sinZ,

sinX * cosZ + cosX * sinY * sinZ

);

Vector3 zAxis = newVector3(

sinY,

-sinX * cosY,

cosX * cosY

);

returnxAxis * point.x + yAxis * point.y + zAxis * point.z;


}

1publicabstractMatrix4x4 Matrix { get; }

publicVector3 Apply (Vector3 point) {

returnMatrix.MultiplyPoint(point);


}

publicoverrideMatrix4x4 Matrix {

get{

Matrix4x4 matrix = newMatrix4x4();

matrix.SetRow(0, newVector4(1f, 0f, 0f, position.x));

matrix.SetRow(1, newVector4(0f, 1f, 0f, position.y));

matrix.SetRow(2, newVector4(0f, 0f, 1f, position.z));

matrix.SetRow(3, newVector4(0f, 0f, 0f, 1f));

returnmatrix;

}


}

publicoverrideMatrix4x4 Matrix {

        get{

Matrix4x4 matrix = newMatrix4x4();

matrix.SetRow(0, newVector4(scale.x, 0f, 0f, 0f));

matrix.SetRow(1, newVector4(0f, scale.y, 0f, 0f));

matrix.SetRow(2, newVector4(0f, 0f, scale.z, 0f));

matrix.SetRow(3, newVector4(0f, 0f, 0f, 1f));

returnmatrix;

}

}


publicoverrideMatrix4x4 Matrix {

    get{

Matrix4x4 matrix = newMatrix4x4();

matrix.SetColumn(0, newVector4(

cosY * cosZ,

cosX * sinZ + sinX * sinY * cosZ,

sinX * sinZ - cosX * sinY * cosZ,

0f

));

matrix.SetColumn(1, newVector4(

-cosY * sinZ,

cosX * cosZ - sinX * sinY * sinZ,

sinX * cosZ + cosX * sinY * sinZ,

0f

));

matrix.SetColumn(2, newVector4(

sinY,

-sinX * cosY,

cosX * cosY,

0f

));

matrix.SetColumn(3, newVector4(0f, 0f, 0f, 1f));

returnmatrix;

}


}

1Matrix4x4 transformation;

voidUpdate () {

UpdateTransformation();

for(inti = 0, z = 0; z < gridResolution; z++) {

…

}


}

voidUpdateTransformation () {

GetComponents<transformation>(transformations);

if(transformations.Count > 0) {

transformation = transformations[0].Matrix;

for(inti = 1; i < transformations.Count; i++) {

transformation = transformations[i].Matrix * transformation;

}

}


}</transformation>

Vector3 TransformPoint (intx, inty, intz) {

Vector3 coordinates = GetCoordinates(x, y, z);

returntransformation.MultiplyPoint(coordinates);


}

。知道这一点，我们可以忘记具体是哪一行，跳过对0的计算和最后的转换除法。 Matrix4x4.MultiplyPoint4x3方法正是这样做的。但是，我们不会使用该方法，因为有有用的转换会改变底行的值。

usingUnityEngine;

publicclassCameraTransformation : Transformation {

publicoverrideMatrix4x4 Matrix {

get{

Matrix4x4 matrix = newMatrix4x4();

matrix.SetRow(0, newVector4(1f, 0f, 0f, 0f));

matrix.SetRow(1, newVector4(0f, 1f, 0f, 0f));

matrix.SetRow(2, newVector4(0f, 0f, 1f, 0f));

matrix.SetRow(3, newVector4(0f, 0f, 0f, 1f));

returnmatrix;

}

}


}

matrix.SetRow(0, newVector4(1f, 0f, 0f, 0f));

matrix.SetRow(1, newVector4(0f, 1f, 0f, 0f));

matrix.SetRow(2, newVector4(0f, 0f, 0f, 0f));

matrix.SetRow(3, newVector4(0f, 0f, 0f, 1f));

matrix.SetRow(0, newVector4(1f, 0f, 0f, 0f));

matrix.SetRow(1, newVector4(0f, 1f, 0f, 0f));

matrix.SetRow(2, newVector4(0f, 0f, 0f, 0f));

matrix.SetRow(3, newVector4(0f, 0f, 1f, 0f));

1publicfloatfocalLength = 1f;

matrix.SetRow(0, newVector4(focalLength, 0f, 0f, 0f));

matrix.SetRow(1, newVector4(0f, focalLength, 0f, 0f));

matrix.SetRow(2, newVector4(0f, 0f, 0f, 0f));

matrix.SetRow(3, newVector4(0f, 0f, 1f, 0f));

posted @ 2019-08-19 10:37 26周岁 阅读(...) 评论(...) 编辑 收藏