Skip to content
Snippets Groups Projects
Select Git revision
  • b37ea82994776377f5faee7f7e733a494263d61c
  • master default protected
  • feature/refactor
  • 4.24
  • develop
  • Rendering
  • temp-optix-6
7 results

OptiXCameraActor.cpp

  • dgilbert's avatar
    3
    David Gilbert authored
    b37ea829
    History
    OptiXCameraActor.cpp 25.26 KiB
    #undef UpdateResource
    
    #include "OptiXCameraActor.h"
    
    #include "OptiXModule.h"
    #include "OptiXTextureSampler.h"
    #include "OptiXLaserActor.h"
    
    #include "Engine/EngineTypes.h"
    #include <EngineGlobals.h>
    #include "Runtime/Engine/Classes/Camera/PlayerCameraManager.h"
    #include "Runtime/Engine/Classes/Kismet/GameplayStatics.h"
    #include "Runtime/Engine/Classes/Engine/LocalPlayer.h"
    #include "Runtime/Engine/Public/SceneView.h"
    #include <Runtime/Engine/Classes/Engine/Engine.h>
    #include "Runtime/Engine/Public/HighResScreenshot.h"
    #include "Runtime/Engine/Classes/Engine/TextureRenderTarget2D.h"
    #include "Runtime/Engine/Classes/Engine/TextureRenderTargetCube.h"
    #include "Runtime/Engine/Classes/Materials/MaterialInstanceDynamic.h"
    #include "Runtime/Engine/Classes/Engine/Light.h"
    #include "Runtime/Engine/Classes/GameFramework/GameUserSettings.h"
    #include "Runtime/Engine/Classes/GameFramework/PlayerStart.h"
    
    #include "UObject/ConstructorHelpers.h"
    
    // VR
    #include "Runtime/HeadMountedDisplay/Public/IHeadMountedDisplay.h"
    #include "Runtime/HeadMountedDisplay/Public/IXRTrackingSystem.h"
    #include "Runtime/HeadMountedDisplay/Public/IXRCamera.h"
    
    #include "Runtime/Engine/Classes/Camera/CameraActor.h"
    
    //#include "Materials/MaterialInstance.h"
    //#include "Runtime/Engine/Public/MaterialShared.h"
    //#include "Materials/MaterialExpressionMaterialFunctionCall.h"
    //#include "Materials/Material.h"
    //#include "Materials/MaterialInstanceBasePropertyOverrides.h"
    //#include "Materials/MaterialInterface.h"
    
    DEFINE_LOG_CATEGORY(OptiXPluginCameraActor);
    
    
    UOptiXBlendable::UOptiXBlendable(const FObjectInitializer& ObjectInitializer)
    	: Super(ObjectInitializer)
    {
    	BlendWeight = 1.0f;
    }
    
    void UOptiXBlendable::OverrideBlendableSettings(FSceneView & View, float InWeight) const
    {
    	float Weight = FMath::Clamp(BlendWeight, 0.0f, 1.0f) * InWeight;
    }
    
    AOptiXPlayerCameraManager::AOptiXPlayerCameraManager(const FObjectInitializer& ObjectInitializer)
    	: Super(ObjectInitializer)
    {
    	UE_LOG(OptiXPluginCameraActor, Display, TEXT("Optix Camera Manager Constructor!"));
    
    	SceneCaptureComponent = ObjectInitializer.CreateAbstractDefaultSubobject<USceneCaptureComponent2D>(this, TEXT("SceneCaptureComponent0"));
    	RootComponent = SceneCaptureComponent;
    	SceneCaptureComponent->bCaptureEveryFrame = false;
    	SceneCaptureComponent->bCaptureOnMovement = false;
    	//SceneCaptureComponent->bEnableClipPlane = true; // don't want ourself in the capture
    	SceneCaptureComponent->FOVAngle = 90.0f;
    	SceneCaptureComponent->HideActorComponents(this);
    	SceneCaptureComponent->CaptureSource = SCS_FinalColorLDR;
    	//SceneCaptureComponent->HideActorComponents(UGameplayStatics::GetPlayerController(GetWorld(), 0));
    	//SceneCaptureComponent->HideActorComponents(UGameplayStatics::GetPlayerPawn(GetWorld(), 0));
    
    	PostProcessComponent = ObjectInitializer.CreateAbstractDefaultSubobject<UPostProcessComponent>(this, TEXT("PostProcessComponent0"));
    	PostProcessComponent->SetupAttachment(SceneCaptureComponent); // Doesn't matter anyway
    	PostProcessComponent->bUnbound = true; // Should be default anyway
    
    	PrimaryActorTick.bCanEverTick = true;
    	PrimaryActorTick.TickGroup = TG_PostUpdateWork;
    
    
    	//// Create texture targets
    
    	for (uint8 i = 0; i < 6; i++)
    	{
    		UTextureRenderTarget2D* RenderTarget = NewObject<UTextureRenderTarget2D>();
    		//RenderTarget->AddToRoot();
    		RenderTarget->InitCustomFormat(CubemapSize, CubemapSize, PF_B8G8R8A8, false);
    		RenderTarget->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
    		RenderTarget->SRGB = 0;
    		RenderTarget->TargetGamma = 2.2;
    		RenderTarget->NeverStream = 1;
    		//RenderTarget->InitAutoFormat(256, 256);
    		RenderTarget->UpdateResourceImmediate(); //???
    		//RenderTarget->AdjustBrightness = 1.0; // ??? TODO
    		CubemapRenderTargets.Add(RenderTarget);
    	}
    
    	//// Load the materials
    	//static ConstructorHelpers::FObjectFinder<UMaterial> Mat(TEXT("Material'/OptiX/TextureMaterial.TextureMaterial'"));
    
    	//if (Mat.Object != NULL)
    	//{
    	//	RegularMaterial = Mat.Object;
    	//}
    
    	//static ConstructorHelpers::FObjectFinder<UMaterial> Mat2(TEXT("Material'/OptiX/TextureMaterialVR.TextureMaterialVR'"));
    
    	//if (Mat2.Object != NULL)
    	//{
    	//	VRMaterial = Mat2.Object;
    	//}
    
    	//else
    	//{
    	//	UE_LOG(OptiXPluginCameraActor, Error, TEXT("Couldn't load dummy Material!"));
    	//}
    }
    
    void AOptiXPlayerCameraManager::BeginPlay()
    {
    	
    	///////////////////////// TODO look into bLockHMD	
    
    
    	//UGameplayStatics::GetPlayerController(GetWorld(), 0)->SetViewTarget(this);
    	UE_LOG(OptiXPluginCameraActor, Display, TEXT("OptiX Camera Manager Begin Play!"));
    	Super::BeginPlay();
    
    	if (GEngine->XRSystem.IsValid() && GEngine->XRSystem->GetHMDDevice() != nullptr)
    	{
    		bWithHMD = GEngine->XRSystem->GetHMDDevice()->IsHMDEnabled();
    	}
    	else
    	{
    		bWithHMD = false;
    	}
    
    	//GEngine->XRSystem->GetXRCamera()->UseImplicitHMDPosition(false);
    	InitContext();
    	Init();
    
    	//FPostProcessSettings Settings;
    
    	// Get the material from the context manager:
    
    	PostProcessComponent->AddOrUpdateBlendable(FOptiXModule::Get().GetOptiXContextManager()->GetOptiXMID(), 1.0f);
    
    }
    
    void AOptiXPlayerCameraManager::EndPlay(const EEndPlayReason::Type EndPlayReason)
    {
    	// Clean up again TODO
    	Super::EndPlay(EndPlayReason);
    	CleanOptiXObjects();
    }
    
    void AOptiXPlayerCameraManager::Tick(float DeltaSeconds)
    {
    	Super::Tick(DeltaSeconds);
    	
    	//FOptiXModule::Get().GetOptiXContextManager()->bStartTracing = 1; // FIXME
    
    	//static const auto CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("optix.DisableTrace"));
    	//int32 DisableTrace = CVar->GetInt();
    
    
    
    	//if (DisableTrace == 1)
    	//{
    	//	//PostProcessComponent->Deactivate();
    
    	//	//FOptiXModule::Get().GetOptiXContextManager()->OutputTextureColorRightRef = ((FTexture2DResource*)OutputTexture->Resource)->GetTexture2DRHI();
    	//	//FOptiXModule::Get().GetOptiXContextManager()->OutputTextureDepthRightRef = ((FTexture2DResource*)DepthTexture->Resource)->GetTexture2DRHI();
    	//	//FOptiXModule::Get().GetOptiXContextManager()->OutputTextureDepthLeftRef = ((FTexture2DResource*)DepthTexture2->Resource)->GetTexture2DRHI();
    	//	//FOptiXModule::Get().GetOptiXContextManager()->OutputTextureColorLeftRef = ((FTexture2DResource*)OutputTexture2->Resource)->GetTexture2DRHI();
    	//	//DisplayOutput(true);
    	//	//DisplayOutput(false);
    	//	//DynamicMaterial->SetTextureParameterValue("Texture", OutputTexture);
    	//	//DynamicMaterial->SetTextureParameterValue("Depth", DepthTexture);
    	//	//UpdateOptiXCamera();
    	//	//Trace();
    	//	//DisplayOutput();
    	//	//FMaterialInstanceResource* Test = DynamicMaterial->Resources[0];
    	//	//FOptiXModule::Get().GetOptiXContextManager()->OptiXContext = OptiXContext;
    	//	FOptiXModule::Get().GetOptiXContextManager()->bStartTracing = true;
    	//	
    	//	return;
    	//}
    
    	//if (bWithHMD)
    	//{
    	//	UpdateOptiXCamera(EStereoscopicPass::eSSP_RIGHT_EYE);
    	//	Trace();
    	//	DisplayOutput(true);
    	//	UpdateOptiXCamera(EStereoscopicPass::eSSP_LEFT_EYE);
    	//	Trace();
    	//	DisplayOutput(false);
    	//}
    	//else
    	//{
    	//	UpdateOptiXCamera();
    	//	Trace();
    	//	DisplayOutput();
    	//}
    }
    
    void AOptiXPlayerCameraManager::OnViewportResize(FViewport* Viewport, uint32 val)
    {
    	FIntPoint Dims = Viewport->GetSizeXY();
    	ResizeViewport(Dims.X, Dims.Y);
    }
    
    void AOptiXPlayerCameraManager::ResizeViewport(int32 W, int32 H)
    {
    	if (W == 0 || H == 0)
    	{
    		UE_LOG(OptiXPluginCameraActor, Warning, TEXT("Trying to resize viewport to 0 - why are you doing this?!"));
    		return;
    	}
    
    	//Width = W;
    	//Height = H;
    
    	//if (OutputTexture != nullptr && DepthTexture != nullptr)
    	//{
    	//	OutputTexture->RemoveFromRoot();
    	//	OutputTexture->ReleaseResource();		
    	//	DepthTexture->RemoveFromRoot();
    	//	DepthTexture->ReleaseResource();
    	//}
    
    	//OutputTexture = UTexture2D::CreateTransient(Width, Height, PF_B8G8R8A8);
    	////OutputTexture->AddToRoot();
    	////////// Allocate the texture HRI
    	//OutputTexture->UpdateResource();
    
    	//DepthTexture = UTexture2D::CreateTransient(Width, Height, PF_R32_UINT);
    	////DepthTexture->AddToRoot();
    	////////// Allocate the texture HRI
    	//DepthTexture->UpdateResource();
    
    	//TextureRegion->Height = Height;
    	//TextureRegion->Width = Width;
    	//TextureRegion->SrcX = 0;
    	//TextureRegion->SrcY = 0;
    	//TextureRegion->DestX = 0;
    	//TextureRegion->DestY = 0;
    
    	//OutputBuffer->SetSize2D(Width, Height); // I really hope this doesn't break anything?
    	//OutputDepthBuffer->SetSize2D(Width, Height); // I really hope this doesn't break anything?
    }
    
    void AOptiXPlayerCameraManager::Init()
    {
    	FViewport* CurrentViewport = GEngine->GameViewport->Viewport;
    
    	Width = CurrentViewport->GetSizeXY().X / 2;
    	Height = CurrentViewport->GetSizeXY().Y;
    
    	// Apparently those can be 0 in a packaged build? 
    	// Catch that case:
    
    	if (Width == 0 || Height == 0)
    	{
    		UGameUserSettings* GameSettings = GEngine->GetGameUserSettings();
    		Width = GameSettings->GetScreenResolution().X / 2;
    		Height = GameSettings->GetScreenResolution().Y;
    	}
    
    	CapureCubemap();
    
    	InitPrograms();
    
    	//InitBuffers();
    
    	//InitOutputTexture();
    
    	InitCubemap();
    
    	//InitCamera();
    
    	//InitMaterial();
    
    	UE_LOG(OptiXPluginCameraActor, Display, TEXT("Successfully initialized optix camera actor!"));
    }
    
    void AOptiXPlayerCameraManager::InitContext()
    {
    	UE_LOG(OptiXPluginCameraActor, Display, TEXT("Init Camera Manager, trying to get context instance."));
    	OptiXContext = FOptiXModule::Get().GetContext();
    
    	UE_LOG(OptiXPluginCameraActor, Display, TEXT("Context is rooted: %i"), static_cast<int32>(OptiXContext->IsRooted()));
    }
    
    void AOptiXPlayerCameraManager::InitOutputTexture()
    {
    	//FIntPoint Dims = OutputBuffer->GetSize2D();
    	//	
    	//UE_LOG(OptiXPluginCameraActor, Display, TEXT("Trying to create optix output textures with dims: %i, %i"), Dims.X, Dims.Y);
    
    	//OutputTexture = UTexture2D::CreateTransient(Dims.X, Dims.Y, PF_B8G8R8A8);
    	////OutputTexture->AddToRoot();
    	////// Allocate the texture HRI
    	//OutputTexture->UpdateResource();
    
    	//DepthTexture = UTexture2D::CreateTransient(Dims.X, Dims.Y, PF_R32_UINT);
    	////DepthTexture->AddToRoot();
    	////// Allocate the texture HRI
    	//DepthTexture->UpdateResource();
    
    	//TextureRegion = MakeUnique<FUpdateTextureRegion2D>();
    	//TextureRegion->Height = Dims.Y;
    	//TextureRegion->Width = Dims.X;
    	//TextureRegion->SrcX = 0;
    	//TextureRegion->SrcY = 0;
    	//TextureRegion->DestX = 0;
    	//TextureRegion->DestY = 0;
    
    	//FOptiXModule::Get().GetOptiXContextManager()->OutputTextureColorRightRef = ((FTexture2DResource*)OutputTexture->Resource)->GetTexture2DRHI();
    	//FOptiXModule::Get().GetOptiXContextManager()->OutputTextureDepthRightRef = ((FTexture2DResource*)DepthTexture->Resource)->GetTexture2DRHI();
    
    	//if (bWithHMD)
    	//{
    	//	UE_LOG(OptiXPluginCameraActor, Display, TEXT("Initializing secondary textures for HMD"));
    
    
    	//	OutputTexture2 = UTexture2D::CreateTransient(Dims.X, Dims.Y, PF_B8G8R8A8);
    	//	//OutputTexture->AddToRoot();
    	//	//// Allocate the texture HRI
    	//	OutputTexture2->UpdateResource();
    
    	//	DepthTexture2 = UTexture2D::CreateTransient(Dims.X, Dims.Y, PF_R32_UINT);
    	//	//DepthTexture->AddToRoot();
    	//	//// Allocate the texture HRI
    	//	DepthTexture2->UpdateResource();
    
    	//	FOptiXModule::Get().GetOptiXContextManager()->OutputTextureDepthLeftRef = ((FTexture2DResource*)DepthTexture2->Resource)->GetTexture2DRHI();
    
    	//	FOptiXModule::Get().GetOptiXContextManager()->OutputTextureColorLeftRef = ((FTexture2DResource*)OutputTexture2->Resource)->GetTexture2DRHI();
    	//}
    
    	//UE_LOG(OptiXPluginCameraActor, Display, TEXT("Successfully created both optix output textures"));
    }
    
    void AOptiXPlayerCameraManager::InitBuffers()
    {
    	UE_LOG(OptiXPluginCameraActor, Display, TEXT("Initializing output buffers with dims: %i, %i"), Width, Height);
    
    
    	OutputBuffer = OptiXContext->CreateOutputBufferUByte2D(Width, Height);
    	OutputDepthBuffer = OptiXContext->CreateOutputBufferFloat2D(Width, Height);
    
    	OptiXContext->SetBuffer("result_color", OutputBuffer);
    	OptiXContext->SetBuffer("result_depth", OutputDepthBuffer);
    }
    
    void AOptiXPlayerCameraManager::CapureCubemap()
    {
    	TArray<FVector> Directions =
    	{
    		{1, 0, 0},
    		{-1, 0, 0},
    		{0, 1, 0},
    		{0, -1, 0},
    		{0, 0, -1},
    		{0, 0, 1}
    	};
    
    	SceneCaptureComponent->HideActorComponents(UGameplayStatics::GetPlayerController(GetWorld(), 0));
    	SceneCaptureComponent->HideActorComponents(UGameplayStatics::GetPlayerPawn(GetWorld(), 0));
    	
    	TArray<AActor*> FoundLaserActors;
    	UGameplayStatics::GetAllActorsOfClass(GetWorld(), AOptiXLaserActor::StaticClass(), FoundLaserActors);
    
    	for (AActor* Actor : FoundLaserActors)
    	{
    		SceneCaptureComponent->HideComponent(Cast<AOptiXLaserActor>(Actor)->InstancedStaticMeshComponent);
    	}
    
    	// the actual camera position is still 0 here, so the capture would be at the origin and not the actual player start.
    	// Let's move the capture "into" the first lens actor. 
    
    	//TArray<AActor*> FoundPlayerStarts;
    	//UGameplayStatics::GetAllActorsOfClass(GetWorld(), APlayerStart::StaticClass(), FoundPlayerStarts);
    
    	TArray<AActor*> FoundLensActors;
    	UGameplayStatics::GetAllActorsOfClass(GetWorld(), AOptiXLaserActor::StaticClass(), FoundLensActors);
    
    	// Log if there's more than 1:
    
    	//if (FoundPlayerStarts.Num() != 1)
    	//{
    	//	UE_LOG(OptiXPluginCameraActor, Error, TEXT("Wrong number of PlayerStart actors! Num was: %i, should be 1"), FoundPlayerStarts.Num());
    	//}
    
    	FVector Loc = FoundLensActors[0]->GetActorLocation(); // Just use the first one
    
    
    	for (uint8 i = 0; i < 6; i++)
    	{
    		FRotator Rotation = FRotationMatrix::MakeFromX(Directions[i]).Rotator();
    		SceneCaptureComponent->SetWorldRotation(Rotation);
    		SceneCaptureComponent->SetWorldLocation(Loc);
    
    		UE_LOG(OptiXPluginCameraActor, Display, TEXT("Capturing Cubemap from Position: %s"), *Loc.ToString());
    
    
    		CubemapRenderTargets[i]->UpdateResource();
    		SceneCaptureComponent->TextureTarget = CubemapRenderTargets[i];
    		SceneCaptureComponent->CaptureScene();
    	}
    }
    
    void AOptiXPlayerCameraManager::InitPrograms()
    {
    	FString OptiXPTXDir = FOptiXModule::Get().OptiXPTXDir;
    
    	// Generation Program
    	RayGenerationProgram = OptiXContext->CreateProgramFromPTXFile
    	(
    		OptiXPTXDir + "generated/perspective_camera.ptx",
    		"pinhole_camera"
    	);
    	OptiXContext->SetRayGenerationProgram(0, RayGenerationProgram);
    
    	// Exception program
    	ExceptionProgram = OptiXContext->CreateProgramFromPTXFile
    	(
    		OptiXPTXDir + "generated/exception.ptx",
    		"exception"
    	);
    	OptiXContext->SetExceptionProgram(0, ExceptionProgram);
    
    	// Miss Program
    	MissProgram = OptiXContext->CreateProgramFromPTXFile
    	(
    		OptiXPTXDir + "generated/skybox.ptx",
    		"skyboxLookup"
    	);
    	OptiXContext->SetMissProgram(0, MissProgram);
    	OptiXContext->SetFloat3DVector("bg_color", FVector(1.0, 1.0, 1.0));
    }
    
    //void AOptiXPlayerCameraManager::InitMaterial()
    //{
    //	if (DynamicMaterial == nullptr)
    //	{
    //		if (bWithHMD)
    //		{
    //			DynamicMaterial = UMaterialInstanceDynamic::Create(VRMaterial, this);
    //			DynamicMaterial->SetTextureParameterValue("TextureRight", OutputTexture);
    //			DynamicMaterial->SetTextureParameterValue("DepthRight", DepthTexture);
    //			DynamicMaterial->SetTextureParameterValue("TextureLeft", OutputTexture2);
    //			DynamicMaterial->SetTextureParameterValue("DepthLeft", DepthTexture2);
    //
    //			//DynamicMaterial->Resources[0]->
    //
    //		}
    //		else
    //		{
    //			DynamicMaterial = UMaterialInstanceDynamic::Create(RegularMaterial, this);
    //			DynamicMaterial->SetTextureParameterValue("Texture", OutputTexture);
    //			DynamicMaterial->SetTextureParameterValue("Depth", DepthTexture);			
    //		}
    //	}
    //}
    
    void AOptiXPlayerCameraManager::InitCubemap()
    {
    	UE_LOG(OptiXPluginCameraActor, Display, TEXT("Initializing Cubemap"));
    
    	//LoadTextureCube();
    
    	EnvironmentSampler = OptiXContext->CreateTextureSampler();
    	//EnvironmentSampler->AddToRoot();
    	EnvironmentSampler->SetWrapMode(0, RT_WRAP_CLAMP_TO_EDGE);
    	EnvironmentSampler->SetWrapMode(1, RT_WRAP_CLAMP_TO_EDGE);
    	EnvironmentSampler->SetWrapMode(2, RT_WRAP_CLAMP_TO_EDGE);
    	EnvironmentSampler->SetIndexingMode(RT_TEXTURE_INDEX_NORMALIZED_COORDINATES);
    	EnvironmentSampler->SetReadMode(RT_TEXTURE_READ_NORMALIZED_FLOAT);
    	EnvironmentSampler->SetMaxAnisotropy(1.0f);
    	EnvironmentSampler->SetMipLevelCount(1u);
    	EnvironmentSampler->SetArraySize(1u);
    
    	UE_LOG(OptiXPluginCameraActor, Display, TEXT("Successfully initialized optix environmap sampler."));
    
    
    	// No texture cube assigned, use default color
    	// See the nvidia sutil::loadHDRTexture function from the optix sdk
    
    	if (CubemapRenderTargets.Num() <= 0)
    	{
    		UE_LOG(OptiXPluginCameraActor, Warning, TEXT("No Valid Texture Cube was loaded."));
    
    		//FColor DefaultColor = FColor(, 1.0f, 1.0f);
    
    		// Create buffer with single texel set to default_color
    		UOptiXBuffer* Buffer = OptiXContext->CreateCubemapBuffer(1u, 1u);
    		optix::uchar4* BufferData = static_cast<optix::uchar4*>(Buffer->MapNative());
    		BufferData[0].x = 255;
    		BufferData[0].y = 255;
    		BufferData[0].z = 255;
    		BufferData[0].w = 255;
    		Buffer->Unmap();
    
    		EnvironmentSampler->SetBufferWithTextureIndexAndMiplevel(0u, 0u, Buffer);
    		// Although it would be possible to use nearest filtering here, we chose linear
    		// to be consistent with the textures that have been loaded from a file. This
    		// allows OptiX to perform some optimizations.
    		EnvironmentSampler->SetFilteringModes(RT_FILTER_LINEAR, RT_FILTER_LINEAR, RT_FILTER_NONE);
    	}
    	else
    	{
    		UE_LOG(OptiXPluginCameraActor, Display, TEXT("Render Targets exist, trying to load them now..."));
    
    		if (!CubemapRenderTargets.IsValidIndex(0))
    		{
    			UE_LOG(OptiXPluginCameraActor, Error, TEXT("Something is wrong with the render target array!"));
    		}
    
    		// Size is the same for all 6
    		int32 X = CubemapRenderTargets[0]->SizeX;
    		int32 Y = CubemapRenderTargets[0]->SizeY;
    
    		UE_LOG(OptiXPluginCameraActor, Display, TEXT("Loaded %i Texture Render Targets with Size: (%i, %i)"), CubemapRenderTargets.Num(), X, Y);
    
    		UOptiXBuffer* Buffer = OptiXContext->CreateCubemapBuffer(X, Y);
    		optix::uchar4* BufferData = static_cast<optix::uchar4*>(Buffer->MapNative());
    
    		for (uint8 k = 0; k < 6; k++)
    		{
    			UE_LOG(OptiXPluginCameraActor, Display, TEXT("Copying Render Target Data to optix... %i/6"), (k+1));
    
    			if (CubemapRenderTargets[k] == nullptr)
    			{
    				UE_LOG(OptiXPluginCameraActor, Error, TEXT("Render target is nullptr! Something went wrong."));
    			}
    
    			// Alright, Apparently ConstructTexture2D() can only be used WITH THE GOD DAMN EDITOR WTF
    			//UTexture2D* Texture = CubemapRenderTargets[k]->ConstructTexture2D(this, "CubemapTexture", RF_Transient, EConstructTextureFlags::CTF_DeferCompression);
    			//Texture->NeverStream = 1;
    
    			TArray<FColor> SurfData;
    			FRenderTarget* RenderTarget = CubemapRenderTargets[k]->GameThread_GetRenderTargetResource();
    			RenderTarget->ReadPixels(SurfData);
    
    			//UE_LOG(OptiXPluginCameraActor, Error, TEXT("# of mips: %i"), Texture->PlatformData->Mips.Num());
    
    			//FTexture2DMipMap& Mip = Texture->PlatformData->Mips[0];
    
    			//UE_LOG(OptiXPluginCameraActor, Display, TEXT("Got Mip reference, trying to lock for reading access now."));
    
    			//FColor* TextureData = static_cast<FColor*>(Mip.BulkData.Lock(LOCK_READ_ONLY));
    
    			//UE_LOG(OptiXPluginCameraActor, Display, TEXT("Locked Mip Bulkdata to access it."));
    
    
    			// Texture index conversion is a real pain...
    			for (int32 i = 0; i < X; ++i) {
    				for (int32 j = 0; j < Y; ++j) {
    					int32 TextureIndex = 0;
    					if (k == 0) // Front
    					{
    						TextureIndex = (X * Y - 1) - i * X - j;   //((X - 1 - i)*Y + j); //
    					}
    					else if (k == 1) // Back
    					{
    						TextureIndex = i * X + j; // Assume this one fits (Sun as anchor)
    					}
    					else if (k == 2) // Right
    					{
    						TextureIndex = (X - 1 - i) + j * Y; //(X * Y - 1) - j * Y - i; // ((X - 1 - j)*Y + i);
    					}
    					else if (k == 3) // Left
    					{
    						TextureIndex = ((X - 1 - j)*Y + i); //(X * Y - 1) - j * X - i; //j * Y + i;
    					}
    					else if (k == 4) // Bottom
    					{
    						TextureIndex = (X * Y - 1) - i * X - j;
    					}
    					else if (k == 5) // Top
    					{
    						TextureIndex = i * X + j; //((X - 1 - j)*Y + i); //(X * Y - 1) - j * X - i; //j * Y + i;
    
    					}
    
    					int32 BufferIndex = ((j)*(X)+i) + (X * Y * k);
    
    					//UE_LOG(LogTemp, Display, TEXT("Values: %i"), TextureData[BufferIndex]);
    
    					BufferData[BufferIndex].x = SurfData[TextureIndex].R;
    					BufferData[BufferIndex].y = SurfData[TextureIndex].G;
    					BufferData[BufferIndex].z = SurfData[TextureIndex].B;
    					BufferData[BufferIndex].w = SurfData[TextureIndex].A;
    
    				}
    			}
    
    			// Sadly the RGB layout is different in the memory, so we cannot copy directly
    			//FMemory::Memcpy(BufferData + (X * Y * k), TextureData, (X * Y * sizeof(FColor))); // Try copying the buffer data directly here TODO
    
    			//Mip.BulkData.Unlock();
    		}
    
    		Buffer->Unmap();
    
    		UE_LOG(OptiXPluginCameraActor, Display, TEXT("Finished copying data."));
    
    		EnvironmentSampler->SetBufferWithTextureIndexAndMiplevel(0u, 0u, Buffer);
    		EnvironmentSampler->SetFilteringModes(RT_FILTER_LINEAR, RT_FILTER_LINEAR, RT_FILTER_NONE);
    
    		OptiXContext->SetInt("skybox", EnvironmentSampler->GetId());
    	}
    
    	UE_LOG(OptiXPluginCameraActor, Display, TEXT("Successfully initialized cubemap."));
    }
    
    //void AOptiXPlayerCameraManager::InitCamera()
    //{
    //	// Set Up Camera:
    //
    //	ULocalPlayer* Player = Cast<ULocalPlayer>(PCOwner->Player); // This cast should be always save as there is only one player?
    //
    //	FSceneViewProjectionData Data;
    //	FViewport* CurrentViewport = GEngine->GameViewport->Viewport;
    //
    //	// Set resize callback:
    //
    //	CurrentViewport->ViewportResizedEvent.AddUObject(this, &AOptiXPlayerCameraManager::OnViewportResize);
    //	FIntPoint Dims = CurrentViewport->GetSizeXY();
    //	UE_LOG(OptiXPluginCameraActor, Display, TEXT("Current Viewport Dims: %s"), *Dims.ToString());
    //
    //
    //	ResizeViewport(Dims.X, Dims.Y);
    //
    //	UE_LOG(OptiXPluginCameraActor, Display, TEXT("Resized Optix Buffer to: %s"), *Dims.ToString());
    //
    //	Player->GetProjectionData(CurrentViewport, EStereoscopicPass::eSSP_FULL, Data);
    //
    //	FMatrix ViewProjectionMatrix = Data.ComputeViewProjectionMatrix();
    //
    //	UE_LOG(OptiXPluginCameraActor, Display, TEXT("View Projection Matrix: %s"), *ViewProjectionMatrix.ToString());
    //	OptiXContext->SetMatrix("invViewProjection", ViewProjectionMatrix.Inverse());
    //	OptiXContext->SetMatrix("viewProjection", ViewProjectionMatrix); // Check Transpose bool in optix
    //	//OptiXContext->SetFloat4DVector("zConversionTransform", CurrentViewport->z); // Check Transpose bool in optix
    //}
    
    //void AOptiXPlayerCameraManager::Trace()
    //{
    //	//FIntPoint Dims = OutputBuffer->GetSize2D();
    //	
    //	//UE_LOG(LogTemp, Error, TEXT("Launching in game thread"));
    //
    //	OptiXContext->Launch(0, Width, Height);
    //
    //	
    //	//UE_LOG(LogTemp, Warning, TEXT("Trace took %f seconds."), end - start);
    //}
    
    
    //void AOptiXPlayerCameraManager::DisplayOutput(bool IsRightEye)
    //{
    //
    //	if (DynamicMaterial == nullptr)
    //	{
    //		InitMaterial();
    //	}
    //
    //	if(bWithHMD)
    //	{
    //		if (IsRightEye)
    //		{
    //			optix::uchar4* Data = static_cast<optix::uchar4*>(OutputBuffer->MapNative());
    //			OutputTexture->UpdateTextureRegions(0, 1, TextureRegion.Get(), Width * 4, 4, (uint8*)Data);
    //			OutputBuffer->Unmap();
    //
    //			float* DepthData = static_cast<float*>(OutputDepthBuffer->MapNative());
    //			DepthTexture->UpdateTextureRegions(0, 1, TextureRegion.Get(), Width * 4, 4, (uint8*)DepthData);
    //			OutputDepthBuffer->Unmap();
    //
    //			DynamicMaterial->SetTextureParameterValue("TextureRight", OutputTexture);		
    //			DynamicMaterial->SetTextureParameterValue("DepthRight", DepthTexture);
    //		}
    //		else
    //		{
    //			optix::uchar4* Data = static_cast<optix::uchar4*>(OutputBuffer->MapNative());
    //			OutputTexture2->UpdateTextureRegions(0, 1, TextureRegion.Get(), Width * 4, 4, (uint8*)Data);
    //			OutputBuffer->Unmap();
    //
    //			float* DepthData = static_cast<float*>(OutputDepthBuffer->MapNative());
    //			DepthTexture2->UpdateTextureRegions(0, 1, TextureRegion.Get(), Width * 4, 4, (uint8*)DepthData);
    //			OutputDepthBuffer->Unmap();
    //
    //			DynamicMaterial->SetTextureParameterValue("TextureLeft", OutputTexture2);
    //			DynamicMaterial->SetTextureParameterValue("DepthLeft", DepthTexture2);
    //		}
    //		
    //	}
    //	else // Ignore the IsRightEye
    //	{
    //		optix::uchar4* Data = static_cast<optix::uchar4*>(OutputBuffer->MapNative());
    //		OutputTexture->UpdateTextureRegions(0, 1, TextureRegion.Get(), Width * 4, 4, (uint8*)Data);
    //
    //
    //		for (uint32 i = 0; i < Width * Height; i++)
    //		{
    //			UE_LOG(LogTemp, Warning, TEXT("%i %i %i"), Data[i].x, Data[i].y, Data[i].z);
    //		}
    //
    //
    //		OutputBuffer->Unmap();
    //
    //		// TODO is this needed? - nope it's not! - scratch that, it IS needed when deploying, just not in the editor FOR SOME GODFORSAKEN REASON
    //		DynamicMaterial->SetTextureParameterValue("Texture", OutputTexture);
    //
    //		// Depth Texture
    //
    //		float* DepthData = static_cast<float*>(OutputDepthBuffer->MapNative());
    //		DepthTexture->UpdateTextureRegions(0, 1, TextureRegion.Get(), Width * 4, 4, (uint8*)DepthData);
    //		OutputDepthBuffer->Unmap();
    //
    //		DynamicMaterial->SetTextureParameterValue("Depth", DepthTexture);
    //	}
    //}
    
    
    //void AOptiXPlayerCameraManager::UpdateOptiXCamera(EStereoscopicPass Pass)
    //{
    //	ULocalPlayer* Player = Cast<ULocalPlayer>(PCOwner->Player); // This cast should be always save as there is only one player?
    //	
    //	FSceneViewProjectionData Data;
    //	FViewport* CurrentViewport = GEngine->GameViewport->Viewport; 
    //	Player->GetProjectionData(CurrentViewport, Pass, Data);
    //
    //	FMatrix ViewProjectionMatrix = Data.ComputeViewProjectionMatrix();
    //	FMatrix InvViewProjectionMatrix = ViewProjectionMatrix.Inverse();
    //	OptiXContext->SetMatrix("invViewProjection", InvViewProjectionMatrix);
    //	OptiXContext->SetMatrix("viewProjection", ViewProjectionMatrix); // Check Transpose bool in optix
    //
    //	//UE_LOG(LogTemp, Display, TEXT("Camera Manager Actor: HasActivePawnControlCameraComponent: %i"), static_cast<int32>(HasActivePawnControlCameraComponent()));
    //	//UE_LOG(LogTemp, Display, TEXT("Camera Manager Actor: HasActiveCameraComponent: %i"), static_cast<int32>(HasActiveCameraComponent()));
    //
    //}