unity_ObjectToWorld에서 스케일 성분을 추출하고 싶습니다.

5085 단어 ShaderUnity

unity_ObjectToWorld에서 스케일 성분을 추출하고 싶습니다.




참고로 했는지 그대로 가져 왔습니다.

The Matrix and Quaternions FAQ
OpenGL 프로그래밍 메모 행렬 : 합성 행렬에서 배율 조정 요소 추출

Unity5.5부터 unity_Scale의 내용이 float(1,1,1,1)이 되었습니다.
보통 그것은 문제가되지 않지만 여전히 규모의 수치를 소득하고 싶습니다!
그래서 unity_ObjectToWorld에 포함되어야 할 스케일 성분을 추출해 보았습니다.

변환 행렬의 내용은 대체로 이런 느낌

unityScale =
\begin{bmatrix}
1 & 0 & 0 & 0\\
0 & 1 & 0 & 0\\
0 & 0 & 1 & 0\\
0 & 0 & 0 & 1
\end{bmatrix}
\begin{matrix}
XScale成分(1,0,0),平行移動成分X\\
YScale成分(0,1,0),平行移動成分Y\\
ZScale成分(0,0,1),平行移動成分Z\\
0,0,0,1\\
\end{matrix}


그런데 참고로 한 사이트 그대로입니다만,
변환 행렬의 평행 이동 성분을 제외하고 각 열 3개 요소의
벡터의 크기를 계산하면 스케일 성분을 추출할 수 있습니다.

\begin{vmatrix}
A
\end{vmatrix} = \sqrt{A{x}^2+A{y}^2+A{z}^2
}


이것을 Script로 하면 이런 느낌이 듭니다.
float sX = sqrt(unity_ObjectToWorld[0].x * unity_ObjectToWorld[0].x + unity_ObjectToWorld[0].y * unity_ObjectToWorld[0].y + unity_ObjectToWorld[0].z * unity_ObjectToWorld[0].z);
float sY = sqrt(unity_ObjectToWorld[1].x * unity_ObjectToWorld[1].x + unity_ObjectToWorld[1].y * unity_ObjectToWorld[1].y + unity_ObjectToWorld[1].z * unity_ObjectToWorld[1].z);
float sZ = sqrt(unity_ObjectToWorld[2].x * unity_ObjectToWorld[2].x + unity_ObjectToWorld[2].y * unity_ObjectToWorld[2].y + unity_ObjectToWorld[2].z * unity_ObjectToWorld[2].z);

검증용 Shader 코드입니다.
Shader "Unlit/ScaleSample"
{
    Properties{ }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float mX = sqrt(unity_ObjectToWorld[0].x * unity_ObjectToWorld[0].x + unity_ObjectToWorld[0].y * unity_ObjectToWorld[0].y + unity_ObjectToWorld[0].z * unity_ObjectToWorld[0].z);
                float mY = sqrt(unity_ObjectToWorld[1].x * unity_ObjectToWorld[1].x + unity_ObjectToWorld[1].y * unity_ObjectToWorld[1].y + unity_ObjectToWorld[1].z * unity_ObjectToWorld[1].z);
                float mZ = sqrt(unity_ObjectToWorld[2].x * unity_ObjectToWorld[2].x + unity_ObjectToWorld[2].y * unity_ObjectToWorld[2].y + unity_ObjectToWorld[2].z * unity_ObjectToWorld[2].z);
                float3 matrixDat = float3(mX, mY, mZ);
                return float4(matrixDat, 1);
            }
            ENDCG
        }
    }
}

그렇다면 실행 결과입니다. 스케일을 만지면, 색이 변화하고 있는 것을 알 수 있군요.


다음 메모



평행 이동 행렬

T =
\begin{bmatrix}
1 & 0 & 0 & X \\
0 & 1 & 0 & Y \\
0 & 0 & 1 & Z \\
0 & 0 & 0 & 1
\end{bmatrix}


스케일 행렬

S =
\begin{bmatrix}
x & 0 & 0 & 0 \\
0 & y & 0 & 0 \\
0 & 0 & z & 0 \\
0 & 0 & 0 & 1
\end{bmatrix}

회전 행렬

Rx =
\begin{bmatrix}
1 & 0 & 0 & 0\\
0 & cos\theta & -sin\theta & 0\\
0 & sin\theta & cos\theta & 0\\
0 & 0 & 0 & 1
\end{bmatrix}
Ry =
\begin{bmatrix}
cos\theta & 0 & sin\theta & 0 \\
0 & 1 & 0 & 0\\
-sin\theta & 0 & cos\theta & 0\\
0 & 0 & 0 & 1
\end{bmatrix}
Rz =
\begin{bmatrix}
cos\theta & -sin\theta & 0 & 0\\
sin\theta & cos\theta & 0 & 0\\
0 & 0 & 1 & 0\\
0 & 0 & 0 & 1
\end{bmatrix}


회전 행렬 3축

M = X · Y · Z로 계산한다고 전개하면 이렇게 된다

M =
\begin{bmatrix}
(cos\theta{y} * cos\theta{z}) & (-cos\theta{y} * -sin\theta{z}) & (-sin\theta{y}) & 0\\
(sin\theta{x} * sin\theta{y} * cos\theta{z} + cos\theta{x} * sin\theta{z}) & (-sin\theta{x} * sin\theta{y} * sin\theta{z} + cos\theta{x} * cos\theta{z}) & (-sin\theta{x} * cos\theta{y}) & 0\\
(-sin\theta{x} * sin\theta{y} * cos\theta{z} + sin\theta{x} * sin\theta{z}) & (cos\theta{x} * sin\theta{y} * sin\theta{z} + sin\theta{x} * cos\theta{z}) & (cos\theta{x} * cos\theta{y}) & 0\\
0 & 0 & 0 & 1
\end{bmatrix}

좋은 웹페이지 즐겨찾기