- Home /
Vertex shader coordinates in clip space
I've constructed a matrix that calculates a 4-corner pin perspective transformation. The matrix is calculated in a script, and then passed on to a CG shader.
I've got 4 cubes that represent the 4 corners of my plane, and as they are translated the matrix gets updated and passed to the shader.
At the moment, everything works perfectly when the aspect ratio of the camera is square, and my 4 control points are located at (-1, -1), (-1, 1), (1, 1), and (1, -1). Now I believe this is working because the vertex shader is using coordinates in clip space which run from -1 to 1.
The problem comes when I have an aspect ratio of the camera that is not square. The control points no longer match up with the clip space values, and I get the wrong scaling on my perspective transform.
I'm pretty sure I need to factor in _ScreenParams somewhere in either the shader or script code in order to re-adjust the position values, but I'm not sure how exactly to go about this.
My shader code is as follows:
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord;
o.pos = mul(H, o.pos);
return o;
}
Thanks for any help
Hi,,
If you want to use _ScreenParams, it should in shader, but I have limited knowldge of shader so I want know how you are calulate matrix "H" in your script.
Answer by ajk48n · Dec 01, 2014 at 06:24 AM
Well I've figured this out, so just for anyone else who is interested, here is the solution.
This relies on a combination of adjusting the original transformation matrix by the aspect ratio, as well as adjusting the vertex.x position in the shader.
My matrix was of the form:
x0, y0, 1, 0, 0, 0, -u0*x0, -u0*y0
0, 0, 0, x0, y0, 1, -v0*x0, -v0*y0
and needed to be adjusted to:
aspect = (float)Screen.width / (float)Screen.height;
x0 = x0/aspect;
x0, y0, 1, 0, 0, 0, -u0*x0, -u0*y0
0, 0, 0, x0, y0, 1, -v0*x0, -v0*y0
This will compensate the matrix for the aspect ratio, but the shader itself will be too wide/narrow now. So in the shader, the opposite compensation needs to occur, using:
v2f vert( appdata_img v )
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord;
o.pos = mul(H, o.pos);
o.pos.x /= (_ScreenParams.x / _ScreenParams.y);
return o;
}