Unity渲染矩阵变换编辑器

前言

编辑器可以快速得到每个环节计算出的数据,方便我们学习矩阵变换。
具体的渲染管线矩阵变换流程可以看这篇:矩阵变换计算流程参考文章

效果在这里插入图片描述

实现

有一个主摄像机,有一个正方体即可。然后将脚本随便挂到一个对象上,赋值正方体。
在这里插入图片描述在这里插入图片描述

输出

运行时,会有Log输出整个流程的矩阵的数值。
在这里插入图片描述在这里插入图片描述

脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PointMartixTest : MonoBehaviour
{
    
    
    public Transform Cubu;
    private Vector3 point;
    private Matrix4x4 pointMartix;

    private Matrix4x4 pointWorldMartix;

    private Matrix4x4 pointCameraMartix;

    private Matrix4x4 pointProjectionMartix;

    private Vector2 scenePoint;
    private Matrix4x4 pointSceneMartix;

    private GUIStyle textGUIStyle;

    private string inputX;
    private string inputY;
    private string inputZ;

    private string rotationX;
    private string rotationY;
    private string rotationZ;
    private Quaternion quaternion;
    private Vector3 rotation;

    private string positionX;
    private string positionY;
    private string positionZ;
    private Vector3 position;

    private bool showWorld;
    private bool showCamera;
    private bool showProjection;
    private bool showScene;

    void Start()
    {
    
    
        textGUIStyle = new GUIStyle();
        textGUIStyle.fontSize = 30;
        GUIStyleState normalStyleState = new GUIStyleState();
        normalStyleState.textColor = Color.white;
        textGUIStyle.normal = normalStyleState;

        inputX = "0";
        inputY = "0";
        inputZ = "0";

        quaternion = Cubu.rotation;
        Vector3 rotation = quaternion.eulerAngles;
        rotationX = rotation.x.ToString();
        rotationY = rotation.y.ToString();
        rotationZ = rotation.z.ToString();

        Vector3 position = Cubu.position;
        positionX = position.x.ToString();
        positionY = position.x.ToString();
        positionZ = position.x.ToString();
    }

    // Update is called once per frame
    void Update()
    {
    
    
        pointMartix = new Matrix4x4(new Vector4(point.x, point.y, point.z, 1), Vector4.zero, Vector4.zero, Vector4.zero);
        computePointWorld();
        computePointCamera();
        computePointProjection();
        computePointScene();
    }

    private void OnGUI()
    {
    
    
        int firstHeight = 30;
        showInputPosition(firstHeight, "cube上的位置。", ref point);

        firstHeight += 50;
        showRotation(firstHeight, "cube旋转角度。", ref rotation);
        quaternion.eulerAngles = rotation;
        Cubu.rotation = quaternion;

        firstHeight += 50;
        showPosition(firstHeight, "cube位置。", ref position);
        Cubu.position = position;

        firstHeight += 50;
        if (GUI.Button(new Rect(20, firstHeight, 200, 40), "point -> world"))
        {
    
    
            showWorld = !showWorld;
            if (showWorld)
            {
    
    
                showCamera = false;
                showProjection = false;
                showScene = false;
            }
        }
        if (GUI.Button(new Rect(230, firstHeight, 200, 40), "world -> camera"))
        {
    
    
            showCamera = !showCamera;
            if (showCamera)
            {
    
    
                showWorld = false;
                showProjection = false;
                showScene = false;
            }
        }
        if (GUI.Button(new Rect(440, firstHeight, 200, 40), "camera -> projection"))
        {
    
    
            showProjection = !showProjection;
            if (showProjection)
            {
    
    
                showWorld = false;
                showCamera = false;
                showScene = false;
            }
        }
        if (GUI.Button(new Rect(650, firstHeight, 200, 40), "projection -> scene"))
        {
    
    
            showScene = !showScene;
            if (showScene)
            {
    
    
                showWorld = false;
                showCamera = false;
                showProjection = false;
            }
        }

        firstHeight += 50;
        if (showWorld)
        {
    
    
            showMatrix4x4(firstHeight, "M (world)", Cubu.localToWorldMatrix);
            showMatrix4x4(firstHeight+150, "P (world)",pointWorldMartix);
        }
        if(showCamera)
        {
    
    
            showMatrix4x4(firstHeight, "M (camera)", Camera.main.worldToCameraMatrix);
            showMatrix4x4(firstHeight + 150, "P (camera)", pointCameraMartix);
        }
        if (showProjection)
        {
    
    
            showMatrix4x4(firstHeight, "M (projection)", Camera.main.projectionMatrix);
            showMatrix4x4(firstHeight + 150, "P (projection)", pointProjectionMartix);
        }
        if (showScene)
        {
    
    
            GUI.Label(new Rect(20, firstHeight, 300, 30), "Screen Width:" + Screen.width + " Screen Height:" + Screen.height, textGUIStyle);
            showPosition(firstHeight+30, "P (scene)", scenePoint);
            GUI.Label(new Rect(scenePoint.x - 5, Screen.height - (scenePoint.y + 5), 10, 10), "*", textGUIStyle);
        }
    }
    private void showInputPosition(float height,string title,ref Vector3 point)
    {
    
    
        GUI.Label(new Rect(20, height, 250, 30), title, textGUIStyle);

        GUI.Label(new Rect(260, height, 20, 30), "x:", textGUIStyle);
        inputX = GUI.TextField(new Rect(290, height, 60, 30), inputX, textGUIStyle);
        if (!string.IsNullOrEmpty(inputX))
        {
    
    
            float px;
            if (float.TryParse(inputX, out px))
            {
    
    
                point.x = px;
            }
        }

        GUI.Label(new Rect(420, height, 20, 30), "y:", textGUIStyle);
        inputY = GUI.TextField(new Rect(450, height, 60, 30), inputY, textGUIStyle);
        if (!string.IsNullOrEmpty(inputY))
        {
    
    
            float py;
            if (float.TryParse(inputY, out py))
            {
    
    
                point.y = py;
            }
        }

        GUI.Label(new Rect(570, height, 20, 30), "z:", textGUIStyle);
        inputZ = GUI.TextField(new Rect(620, height, 60, 30), inputZ, textGUIStyle);
        if (!string.IsNullOrEmpty(inputZ))
        {
    
    
            float pz;
            if (float.TryParse(inputZ, out pz))
            {
    
    
                point.z = pz;
            }
        }
    }

    private void showRotation(float height, string title, ref Vector3 point)
    {
    
    
        GUI.Label(new Rect(20, height, 250, 30), title, textGUIStyle);

        GUI.Label(new Rect(260, height, 20, 30), "x:", textGUIStyle);
        rotationX = GUI.TextField(new Rect(290, height, 60, 30), rotationX, textGUIStyle);
        if (!string.IsNullOrEmpty(rotationX))
        {
    
    
            float px;
            if (float.TryParse(rotationX, out px))
            {
    
    
                if (px == 0)
                {
    
    
                    point.x = 0;
                }
                else
                {
    
    
                    point.x = px;
                }
            }
        }

        GUI.Label(new Rect(420, height, 20, 30), "y:", textGUIStyle);
        rotationY = GUI.TextField(new Rect(450, height, 60, 30), rotationY, textGUIStyle);
        if (!string.IsNullOrEmpty(rotationY))
        {
    
    
            float py;
            if (float.TryParse(rotationY, out py))
            {
    
    
                if (py == 0)
                {
    
    
                    point.y = 0;
                }
                else
                {
    
    
                    point.y = py ;
                }
            }
        }

        GUI.Label(new Rect(570, height, 20, 30), "z:", textGUIStyle);
        rotationZ = GUI.TextField(new Rect(620, height, 60, 30), rotationZ, textGUIStyle);
        if (!string.IsNullOrEmpty(rotationZ))
        {
    
    
            float pz;
            if (float.TryParse(rotationZ, out pz))
            {
    
    
                if (pz == 0)
                {
    
    
                    point.z = 0;
                }
                else
                {
    
    
                    point.z = pz;
                }
            }
        }
    }

    private void showPosition(float height, string title, ref Vector3 point)
    {
    
    
        GUI.Label(new Rect(20, height, 250, 30), title, textGUIStyle);

        GUI.Label(new Rect(260, height, 20, 30), "x:", textGUIStyle);
        positionX = GUI.TextField(new Rect(290, height, 60, 30), positionX, textGUIStyle);
        if (!string.IsNullOrEmpty(positionX))
        {
    
    
            float px;
            if (float.TryParse(positionX, out px))
            {
    
    
                if (px == 0)
                {
    
    
                    point.x = 0;
                }
                else
                {
    
    
                    point.x = px;
                }
            }
        }

        GUI.Label(new Rect(420, height, 20, 30), "y:", textGUIStyle);
        positionY = GUI.TextField(new Rect(450, height, 60, 30), positionY, textGUIStyle);
        if (!string.IsNullOrEmpty(positionY))
        {
    
    
            float py;
            if (float.TryParse(positionY, out py))
            {
    
    
                if (py == 0)
                {
    
    
                    point.y = 0;
                }
                else
                {
    
    
                    point.y = py;
                }
            }
        }

        GUI.Label(new Rect(570, height, 20, 30), "z:", textGUIStyle);
        positionZ = GUI.TextField(new Rect(620, height, 60, 30), positionZ, textGUIStyle);
        if (!string.IsNullOrEmpty(positionZ))
        {
    
    
            float pz;
            if (float.TryParse(positionZ, out pz))
            {
    
    
                if (pz == 0)
                {
    
    
                    point.z = 0;
                }
                else
                {
    
    
                    point.z = pz;
                }
            }
        }
    }


    private void showMatrix4x4(float height, string title, Matrix4x4 matrix)
    {
    
    
        GUI.Label(new Rect(20, height, 250, height), title, textGUIStyle);

        GUI.Label(new Rect(260, height, 200, 200), matrix.ToString(), textGUIStyle);
    }

    private void showPosition(float height, string title, Vector3 point)
    {
    
    
        GUI.Label(new Rect(20, height, 250, 30), title, textGUIStyle);
        GUI.Label(new Rect(260, height, 200, 200), point.ToString(), textGUIStyle);
    }

    private void computePointWorld()
    {
    
    
        Matrix4x4 localToWorldMatrix = Cubu.localToWorldMatrix;
        pointWorldMartix = Cubu.localToWorldMatrix * pointMartix;

        Debug.Log("point -> world. \n "  + "\n" + localToWorldMatrix + " \n*\n " + pointMartix + " \n=\n " + pointWorldMartix);
    }

    private void computePointCamera()
    {
    
    
        Matrix4x4 worldToCameraMatrix = Camera.main.worldToCameraMatrix;
        pointCameraMartix = worldToCameraMatrix * pointWorldMartix;

        Debug.Log("world -> camera. \n "  + "\n" + worldToCameraMatrix + " \n*\n " + pointWorldMartix + " \n=\n " + pointCameraMartix);
    }

    private void computePointProjection()
    {
    
    
        Matrix4x4 projectionMatrix = Camera.main.projectionMatrix;
        pointProjectionMartix = projectionMatrix * pointCameraMartix;

        Debug.Log("camera -> projection. \n "  + "\n" + projectionMatrix + " \n*\n " + pointCameraMartix + " \n=\n " + pointProjectionMartix);
    }

    private void computePointScene()
    {
    
    
        scenePoint = Vector3.zero;
        float width = Screen.width;
        float height = Screen.height;
        float x = pointProjectionMartix.m00;
        float y = pointProjectionMartix.m10;
        float w = pointProjectionMartix.m30;
        scenePoint.x = ((x * width) / (2 * w)) + width / 2;
        scenePoint.y = ((y * height) / (2 * w)) + height / 2;

        Debug.Log("projection -> scene . \n scenePoint:" + scenePoint + "\n width:" + width + " height:" + height);
    }
}

猜你喜欢

转载自blog.csdn.net/sinat_34870723/article/details/113926155