Trying to use custom ModelViewProjection but failing

Apologies if the is RTFM (or RTF Forum maybe), but I’m having some trouble synthesizing the correct projection matrix for a custom vertex shader. I am very new to Unity (only started poking around a couple of days ago), so I am probably doing something stupid.

I am rendering all geometry with custom shaders (DX11). I also have custom property blocks per object. As best I can, I have verified that everything in the pipeline works, so long as I use UNITY_MATRIX_MVP. But as soon as I try to make my own MVP matrix, things go south.

Enclosed are two pictures - one good and one bad. Very sorry the post is long - wanted to be as complete as possible.

Here is the vertex and fragment shader:

float		_test;
float4x4	_MVP;
v2f vert( appdata_base v ) {
	v2f o;
	o.pos = mul( UNITY_MATRIX_MVP, v.vertex ); //GOOD!
	//o.pos = mul( _MVP, v.vertex ); //BAD!!!
	return o;
}
half4 frag (v2f input) : COLOR {
	half4	vOutput;
	vOutput.rgb =_test;
	vOutput.a = 1;
	return vOutput;
}

And here is the (likely terrible) script code on the camera to seed the _MVP matrix:

function OnPostRender() {
...
	var allRenderers : Renderer[] = FindObjectsOfType(Renderer) as Renderer[];
	var testColor = 0.0f;
	for (var curRenderer : Renderer in allRenderers) {
        	var propertyBlock : MaterialPropertyBlock = new MaterialPropertyBlock();        
	        var mModel : Matrix4x4 = curRenderer.transform.localToWorldMatrix;
	        var mView : Matrix4x4 = Camera.main.worldToCameraMatrix;
	        var mProj : Matrix4x4 = Camera.main.projectionMatrix;
	        var mMVP : Matrix4x4 = mProj * mView * mModel;
        
        	propertyBlock.AddMatrix ("_MVP", mMVP);
	        propertyBlock.AddFloat ("_test", testColor);
        	testColor += .05;
	        curRenderer.SetPropertyBlock(propertyBlock);
        }
	
	cam.RenderWithShader (shader, "RenderType");
}

It looks as if the projection matrix is horked, but in some non-obvious way? Or maybe there is a mystery scale on Y? I am afraid I am so new to Unity I don’t even know how to inspect script values (that’s on tomorrow’s plate). I wonder if Unity has an internal representation of the projection matrix that is not what DX is expecting? Or maybe I just screwed something else up??

Thanks!

Ben


Interestingly, someone else had a similar problem, and substituted Camera.main.projectionMatrix with GL.GetGPUProjectionMatrix(Camera.main.projectionMatrix, false)

That made no difference in my case (which indicates either that Camera.main.projectionMatrix is platform specific - IMO the correct state of affairs - or happens to match DX).

However, I did notice that all the objects which are getting scaled incorrectly in Y also happen to have a non-uniform scale in Y. So it looks like maybe I’m getting double scaling. But that would mean that curRenderer.localToWorldMatrix is probably the screwed up parameter? Could Unity be doing some vertex scaling on the CPU beforehand, or is curRenderer.localToWorldMatrix not the right call to make??

Ben

Well, to close this out, apparently even though the docs talk about curRenderer.transform.localToWorldMatrix vs curRenderer.localToWorldMatrix, it’s all lies. Non-uniformly scaled objects appear to go through some strange and un(der)documented path.

If you want to construct your own projection matrix, you just need to “know” that objects which are not uniformly scaled have a scale of one on entry to the shader, I am guessing because some CPU process (silently?) handles scaling verts beforehand.

Calls to transform.lossyScale appear to be a reasonable way to check if the scale is not uniform, and then you can proceed from there. sigh…