Skip to content

Instantly share code, notes, and snippets.

@sephirot47
Last active August 3, 2023 22:01
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sephirot47/4416160742d982b87f3570eb498a3f5c to your computer and use it in GitHub Desktop.
Save sephirot47/4416160742d982b87f3570eb498a3f5c to your computer and use it in GitHub Desktop.
UE4 C++ Alternative DrawDebugFrustum
#pragma once
#include "CoreMinimal.h"
#include "EngineUtils.h"
#include "DrawDebugHelpers.h"
inline void DrawDebugQuad(const UWorld* World, const FVector& BotLeft, const FVector& TopLeft, const FVector& TopRight, const FVector& BotRight, const FColor& Color = FColor::Green, const bool bPersistentLines = false, const float LifeTime = -1.0f, const uint8_t DepthPriority = 0, const float Thickness = 0.0f)
{
DrawDebugLine(World, BotLeft, TopLeft, Color, bPersistentLines, LifeTime, DepthPriority, Thickness);
DrawDebugLine(World, TopLeft, TopRight, Color, bPersistentLines, LifeTime, DepthPriority, Thickness);
DrawDebugLine(World, TopRight, BotRight, Color, bPersistentLines, LifeTime, DepthPriority, Thickness);
DrawDebugLine(World, BotRight, BotLeft, Color, bPersistentLines, LifeTime, DepthPriority, Thickness);
}
inline void DrawDebugFrustum(const UWorld *World, const FMatrix& ViewProjectionMatrix, const float ZNear, const float ZFar, float AspectRatio = 1.0f, const FColor &Color = FColor::Green, const bool bPersistentLines = false, const float LifeTime = -1.0f, const uint8_t DepthPriority = 0, const float Thickness = 0.0f)
{
const FMatrix InverseViewProjectionMatrix = ViewProjectionMatrix.Inverse();
const float top = 1.0f * AspectRatio;
const float bot = -1.0f * AspectRatio;
const float left = -1.0f;
const float right = 1.0f;
const float ZNearMod = 1.0f / ZNear * 10.0f;
const float ZFarMod = 1.0f / ZFar * 10.0f;
FVector4 NearTopLeft = InverseViewProjectionMatrix.TransformPosition(FVector4(left, top, ZNearMod, 1));
NearTopLeft /= FVector4(NearTopLeft.W, NearTopLeft.W, NearTopLeft.W, NearTopLeft.W);
FVector4 NearTopRight = InverseViewProjectionMatrix.TransformPosition(FVector4(right, top, ZNearMod, 1));
NearTopRight /= FVector4(NearTopRight.W, NearTopRight.W, NearTopRight.W, NearTopRight.W);
FVector4 NearBotLeft = InverseViewProjectionMatrix.TransformPosition(FVector4(left, bot, ZNearMod, 1));
NearBotLeft /= FVector4(NearBotLeft.W, NearBotLeft.W, NearBotLeft.W, NearBotLeft.W);
FVector4 NearBotRight = InverseViewProjectionMatrix.TransformPosition(FVector4(right, bot, ZNearMod, 1));
NearBotRight /= FVector4(NearBotRight.W, NearBotRight.W, NearBotRight.W, NearBotRight.W);
FVector4 FarTopLeft = InverseViewProjectionMatrix.TransformPosition(FVector4(left, top, ZFarMod, 1));
FarTopLeft /= FVector4(FarTopLeft.W, FarTopLeft.W, FarTopLeft.W, FarTopLeft.W);
FVector4 FarTopRight = InverseViewProjectionMatrix.TransformPosition(FVector4(right, top, ZFarMod, 1));
FarTopRight /= FVector4(FarTopRight.W, FarTopRight.W, FarTopRight.W, FarTopRight.W);
FVector4 FarBotLeft = InverseViewProjectionMatrix.TransformPosition(FVector4(left, bot, ZFarMod, 1));
FarBotLeft /= FVector4(FarBotLeft.W, FarBotLeft.W, FarBotLeft.W, FarBotLeft.W);
FVector4 FarBotRight = InverseViewProjectionMatrix.TransformPosition(FVector4(right, bot, ZFarMod, 1));
FarBotRight /= FVector4(FarBotRight.W, FarBotRight.W, FarBotRight.W, FarBotRight.W);
// Near-far plane quads lines
DrawDebugQuad(World, NearBotLeft, NearTopLeft, NearTopRight, NearBotRight, Color, bPersistentLines, LifeTime, DepthPriority, Thickness);
DrawDebugQuad(World, FarBotLeft, FarTopLeft, FarTopRight, FarBotRight, Color, bPersistentLines, LifeTime, DepthPriority, Thickness);
// Near-to-far lines
DrawDebugLine(World, NearTopLeft, FarTopLeft, Color, bPersistentLines, LifeTime, DepthPriority, Thickness);
DrawDebugLine(World, NearTopRight, FarTopRight, Color, bPersistentLines, LifeTime, DepthPriority, Thickness);
DrawDebugLine(World, NearBotLeft, FarBotLeft, Color, bPersistentLines, LifeTime, DepthPriority, Thickness);
DrawDebugLine(World, NearBotRight, FarBotRight, Color, bPersistentLines, LifeTime, DepthPriority, Thickness);
}
// Usage example =======================================
FMinimalViewInfo CameraView;
GetFirstPersonCameraComponent()->GetCameraView(DeltaTime, CameraView);
const float AR = CameraView.AspectRatio / GEngine->GameViewport->Viewport->GetDesiredAspectRatio();
FMatrix UnusedViewMatrix, UnusedProjectionMatrix, ViewProjectionMatrix;
UGameplayStatics::GetViewProjectionMatrix(CameraView, UnusedViewMatrix, UnusedProjectionMatrix, ViewProjectionMatrix);
const float ZNear = 50.0f, ZFar = 1000.0f;
DrawDebugFrustum(GetWorld(), ViewProjectionMatrix, ZNear, ZFar, AR, FColor::Green, false, 0.1f, 0, 3.0f);
// ======================================================
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment