void Run() { float4x4 *allMat = stackalloc float4x4[6]; PerspCam persp = new PerspCam(); persp.aspect = 1; persp.farClipPlane = 1; persp.nearClipPlane = 0.1f; persp.fov = 90f; GetMatrix(allMat, ref persp, float3(0, 0, 0)); persp.UpdateProjectionMatrix(); for (int i = 0; i < 6; ++i) { float4x4 invvp = inverse(GL.GetGPUProjectionMatrix(mul(persp.projectionMatrix, allMat[i]), false)); string sb = ""; float4 value = mul(invvp, float4(-1, -1, 0, 1)); value /= value.w; sb += "UV00: " + value.xyz; value = mul(invvp, float4(-1, 1, 0, 1)); value /= value.w; sb += " UV01: " + value.xyz; value = mul(invvp, float4(1, 1, 0, 1)); value /= value.w; sb += " UV11: " + value.xyz; value = mul(invvp, float4(1, -1, 0, 1)); value /= value.w; sb += " UV10: " + value.xyz; Debug.Log(sb); } }
public static void GetFrustumPlanes(ref PerspCam perspCam, float4 *planes) { float3 *corners = stackalloc float3[4]; GetFrustumCorner(ref perspCam, perspCam.farClipPlane, corners); planes[0] = VectorUtility.GetPlane(corners[1], corners[0], perspCam.position); planes[1] = VectorUtility.GetPlane(corners[2], corners[3], perspCam.position); planes[2] = VectorUtility.GetPlane(corners[0], corners[2], perspCam.position); planes[3] = VectorUtility.GetPlane(corners[3], corners[1], perspCam.position); planes[4] = VectorUtility.GetPlane(perspCam.forward, perspCam.position + perspCam.forward * perspCam.farClipPlane); planes[5] = VectorUtility.GetPlane(-perspCam.forward, perspCam.position + perspCam.forward * perspCam.nearClipPlane); }
public static void GetFrustumCorner(ref PerspCam perspCam, float distance, float3 *corners) { perspCam.fov = Mathf.Deg2Rad * perspCam.fov * 0.5f; float upLength = distance * tan(perspCam.fov); float rightLength = upLength * perspCam.aspect; float3 farPoint = perspCam.position + distance * perspCam.forward; float3 upVec = upLength * perspCam.up; float3 rightVec = rightLength * perspCam.right; corners[0] = farPoint - upVec - rightVec; corners[1] = farPoint - upVec + rightVec; corners[2] = farPoint + upVec - rightVec; corners[3] = farPoint + upVec + rightVec; }
private static void GetMatrix(float4x4 *allmat, ref PerspCam persp, float3 position) { persp.position = position; //X persp.up = float3(0, 1, 0); persp.right = float3(0, 0, -1); persp.forward = float3(1, 0, 0); persp.UpdateTRSMatrix(); allmat[1] = persp.worldToCameraMatrix; //-X persp.up = float3(0, 1, 0); persp.right = float3(0, 0, 1); persp.forward = float3(-1, 0, 0); persp.UpdateTRSMatrix(); allmat[0] = persp.worldToCameraMatrix; //Y persp.right = float3(-1, 0, 0); persp.up = float3(0, 0, 1); persp.forward = float3(0, 1, 0); persp.UpdateTRSMatrix(); allmat[2] = persp.worldToCameraMatrix; //-Y persp.right = float3(-1, 0, 0); persp.up = float3(0, 0, -1); persp.forward = float3(0, -1, 0); persp.UpdateTRSMatrix(); allmat[3] = persp.worldToCameraMatrix; //Z persp.right = float3(1, 0, 0); persp.up = float3(0, 1, 0); persp.forward = float3(0, 0, 1); persp.UpdateTRSMatrix(); allmat[5] = persp.worldToCameraMatrix; //-Z persp.right = float3(-1, 0, 0); persp.up = float3(0, 1, 0); persp.forward = float3(0, 0, -1); persp.UpdateTRSMatrix(); allmat[4] = persp.worldToCameraMatrix; }
public static void GetFrustumCorner(ref PerspCam perspCam, float3 *corners) { float fov = tan(Mathf.Deg2Rad * perspCam.fov * 0.5f); void GetCorner(float dist, ref PerspCam persp) { float upLength = dist * (fov); float rightLength = upLength * persp.aspect; float3 farPoint = persp.position + dist * persp.forward; float3 upVec = upLength * persp.up; float3 rightVec = rightLength * persp.right; corners[0] = farPoint - upVec - rightVec; corners[1] = farPoint - upVec + rightVec; corners[2] = farPoint + upVec - rightVec; corners[3] = farPoint + upVec + rightVec; corners += 4; } GetCorner(perspCam.nearClipPlane, ref perspCam); GetCorner(perspCam.farClipPlane, ref perspCam); }