I have created a custom projection matrix I use with a native plugin. I want to match Unity3D’s projection matrix perfectly. Problem is Unity is changing the projection matrix “m23” value BEFORE it gets set to UNITY_MATRIX_P but idk what that change is.
If I multiply using the built in values everything is fine:
However if I pass in the matrix values as constant values it doesn’t work.
Here is the code for a custom projection matrix but what do I need to change on “m23” to make it match Unity’s shaders modification?
Matrix4x4 CreateProjection(float near, float far, float fov, float width, float height)
{
float depth = far - near;
float top = 1.0f / Mathf.Tan(MathUtilities.DegToRad(fov) * .5f);
float aspect = (width / height);
float right = top / aspect;
var result = new Matrix4x4();
result.m00 = right;
result.m01 = 0;
result.m02 = 0;
result.m03 = 0;
result.m10 = 0;
result.m11 = top;
result.m12 = 0;
result.m13 = 0;
result.m20 = 0;
result.m21 = 0;
result.m22 = -(far+near) / depth;
result.m23 = -(2*near*far) / depth;// Unity changes this value BEFORE UNITY_MATRIX_P is set
result.m30 = 0;
result.m31 = 0;
result.m32 = -1;
result.m33 = 0;
return result;
}
Unity changes the projection matrix because it depends on the underlying graphics API. For instance, the projection matrices to be passed in openGL and direct3d are not the same. Hence, hardcoding a projection matrix in a script would result in inconsistent results on different plateforms. This is why Unity has to modify them to ensure the consistency.
IDK of any differences in OGL2-3 vs D3D9-11 in the clipping planes that would need this to be different? The only difference Iv’e run into in native GLSL/HLSL is row vs column majors and this is simply fixed by reverse multiply or transposing the matrix. The zbuffer should function the same with the same matrix and bit (unless I’m forgetting something else about GL).
In either case thats probably the solution I wanted, tnx!