Skip to content

Instantly share code, notes, and snippets.

@ilexp
Last active December 17, 2017 18:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ilexp/2671965b4ba05d27c550a71796d4b499 to your computer and use it in GitHub Desktop.
Save ilexp/2671965b4ba05d27c550a71796d4b499 to your computer and use it in GitHub Desktop.
Projection Test
float near = 50;
float far = 100000;
float focus = 500;
Matrix4 projMat = Matrix4.CreatePerspectiveOffCenter(-100, 100, 100, -100, near, far);
// Flip Z direction from "out of the screen" to "into the screen".
Matrix4 flipZDir;
Matrix4.CreateScale(1.0f, 1.0f, -1.0f, out flipZDir);
projMat = flipZDir * projMat;
// Apply custom "focus distance", where objects appear at 1:1 scale.
// Otherwise, that distance would be the near plane.
projMat.M33 *= near / focus; // Output Z scale
projMat.M43 *= near / focus; // Output Z offset
projMat.M34 *= near / focus; // Perspective divide scale
Vector4 test1 = new Vector4(100, 0, 10, 1);
Vector4 test2 = new Vector4(100, 0, near, 1);
Vector4 test3 = new Vector4(100, 0, 250, 1);
Vector4 test4 = new Vector4(100, 0, 500, 1);
Vector4 test5 = new Vector4(100, 0, 5000, 1);
Vector4 test6 = new Vector4(100, 0, far, 1);
test1 = Vector4.Transform(test1, projMat);
test2 = Vector4.Transform(test2, projMat);
test3 = Vector4.Transform(test3, projMat);
test4 = Vector4.Transform(test4, projMat);
test5 = Vector4.Transform(test5, projMat);
test6 = Vector4.Transform(test6, projMat);
// In case of depth buffer precision issues, do this in the vertex shader
// after projection. This will make fragment depth values logarithmic,
// distributing precision more equally between near and far plane. It can
// introduce interpolation issues between vertices though. More info:
// http://outerra.blogspot.de/2012/11/maximizing-depth-buffer-range-and.html
test1.Z = 2.0f * MathF.Log(test1.W / (projMat.M34 * near)) / MathF.Log(far / near) - 1.0f;
test1.Z *= test1.W;
test2.Z = 2.0f * MathF.Log(test2.W / (projMat.M34 * near)) / MathF.Log(far / near) - 1.0f;
test2.Z *= test2.W;
test3.Z = 2.0f * MathF.Log(test3.W / (projMat.M34 * near)) / MathF.Log(far / near) - 1.0f;
test3.Z *= test3.W;
test4.Z = 2.0f * MathF.Log(test4.W / (projMat.M34 * near)) / MathF.Log(far / near) - 1.0f;
test4.Z *= test4.W;
test5.Z = 2.0f * MathF.Log(test5.W / (projMat.M34 * near)) / MathF.Log(far / near) - 1.0f;
test5.Z *= test5.W;
test6.Z = 2.0f * MathF.Log(test6.W / (projMat.M34 * near)) / MathF.Log(far / near) - 1.0f;
test6.Z *= test6.W;
test1 /= test1.W;
test2 /= test2.W;
test3 /= test3.W;
test4 /= test4.W;
test5 /= test5.W;
test6 /= test6.W;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment