Skip to content

Instantly share code, notes, and snippets.

@fuqunaga
Created September 4, 2018 05:22
Show Gist options
  • Save fuqunaga/d87a0123efde61d0aa9cf9718c38a63c to your computer and use it in GitHub Desktop.
Save fuqunaga/d87a0123efde61d0aa9cf9718c38a63c to your computer and use it in GitHub Desktop.
CalculateObliqueMatrix inplement
// https://forum.unity.com/threads/oblique-near-plane-clipping.194722/
public class Clipper : MonoBehaviour
{
Matrix4x4 projection;
Camera offscreenCam;
void Start ()
{
projection = camera.projectionMatrix;
}
void OnPreRender()
{
camera.projectionMatrix = projection;
Matrix4x4 obliqueProjection = projection;
Vector4 cameraSpaceClipPlane = CameraSpacePlane(camera, new Vector3(0.0f, 0.0f, 0.0f), Vector3.up, 1.0f);
CalculateObliqueMatrix(ref obliqueProjection, cameraSpaceClipPlane);
camera.projectionMatrix = obliqueProjection;
}
static Vector4 CameraSpacePlane(Camera cam, Vector3 pos, Vector3 normal, float sideSign)
{
Vector3 offsetPos = pos + normal * 0.07f;
Matrix4x4 m = cam.worldToCameraMatrix;
Vector3 cpos = m.MultiplyPoint(offsetPos);
Vector3 point = m.inverse.MultiplyPoint(new Vector3(0.0f, 0.0f, 0.0f));
cpos -= new Vector3(0.0f, point.y, 0.0f);
Vector3 cnormal = m.MultiplyVector( normal ).normalized * sideSign;
return new Vector4(cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot(cpos,cnormal));
}
static void CalculateObliqueMatrix(ref Matrix4x4 projection, Vector4 clipPlane)
{
Vector4 q = projection.inverse * new Vector4(
sgn(clipPlane.x),
sgn(clipPlane.y),
1.0f,
1.0f
);
Vector4 c = clipPlane * (2.0F / (Vector4.Dot (clipPlane, q)));
// third row = clip plane - fourth row
projection[2] = c.x - projection[3];
projection[6] = c.y - projection[7];
projection[10] = c.z - projection[11];
projection[14] = c.w - projection[15];
}
private static float sgn(float a)
{
if (a > 0.0f) return 1.0f;
if (a < 0.0f) return -1.0f;
return 0.0f;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment