Drawing Render Target Greater Than 400 Freezes Editor

Hello! I am trying to create a UTextureRenderTarget2D that will display what the in-game world would look like. This is to speed up iterations and make it easier to see and make changes to the procedural world generation. The problem I am encountering is that over about 400px for the width or height, the operation takes approximately 5 minutes to complete. I am using

 WorldCanvas->K2_DrawPolygon(nullptr, FVector2D(DrawX, DrawY), FVector2D(1), 4, Paint);

to draw to the target, since I only need one pixel for each world tile. If comment out the portion that draws to the render target, the operation can complete in less than a second. I don’t know where or how to begin, so here is the code that generates the map and draws to the target. Any suggestions are appreciated. Thanks!

EDIT: Forgot to mention that I am using version 4.27 because it fit the project better

void ALandscapeHelper::DrawWorld(int32 RenderLayer)
{
	// Create our noises
	CreateWrappers(true);

	// Make sure our render target reflects the world size
	PrimeDrawingBoardForDisplay();

	// Start drawing to our target
	UCanvas* WorldCanvas;
	FVector2D CanvasSize;
	FDrawToRenderTargetContext CanvasContext;
	UKismetRenderingLibrary::BeginDrawCanvasToRenderTarget(GWorld, DrawingBoard, WorldCanvas, CanvasSize, CanvasContext);
	UE_LOG(LogTemp, Warning, TEXT("Canvas Draw Size %s, World size is %s"), *CanvasSize.ToString(), *WorldXY.ToString());
	WorldCanvas->bNoSmooth = true;

	// Our variables for looping
	// If our world ref is centered center ours as well
	int32 FirstX = bIsWorldCentered ? (WorldXY.X / 2) * -1 : 1;
	int32 LastX = bIsWorldCentered ? WorldXY.X - (WorldXY.X / 2) : WorldXY.X;
	int32 FirstY = bIsWorldCentered ? (WorldXY.Y / 2) * -1 : 1;
	int32 LastY = bIsWorldCentered ? WorldXY.Y - (WorldXY.Y / 2) : WorldXY.Y;


	// For shifting our hex tiles
	bool bShifted = false;

	// Positions to draw on our target
	// For it to mirror the world generator
	// we need to start x at the begining and
	// y at the end
	int32 DrawX = 1;
	int32 DrawY = WorldXY.Y;

	// If the render layer is greater than the wrappers length
	// set it to the last wrapper
	if (RenderLayer > Wrappers.Num() - 1)
	{
		RenderLayer = Wrappers.Num() - 1;
	}

	// select the start and end of the loop
	// NoiseCount will either be the length of the array or the render layer
	// Start will either be 0 or render layer
	int32 NoiseCount = RenderLayer <= -1 ? Wrappers.Num() : RenderLayer;
	int32 Start = RenderLayer <= -1 ? 0 : RenderLayer;

	// Get the settings of the noise
	TArray<FName> NoiseKeys;
	NoiseInfo.GetKeys(NoiseKeys);

	// This is the loop to create the map
	// A full column is created for every row
	for (int32 xi = FirstX; xi < LastX; xi++) // X loop for world generation. For every X make the whole row of Y
	{
		for (int32 yi = FirstY; yi < LastY; yi++) // Y loop
		{
			// Height of the tile
			float TileZScale = 0.f;

			// This will be used for determining the color to draw
			int32 LandType = 0;
			FVector2D TileLocation;

			// Get the location of the tiles
			TileLocation.X = (TileSpacing * yi) + (yi * 2 * MeshWidth) + (bShifted ? MeshWidth * -1 : 0);
			TileLocation.Y = (HexOffset * xi * 1.5f) + (xi * TileSpacing); // this math is for the hexagon




			float WholeNoiseVal = 0.f;
			float RawHeight; // Unclamped height
			float NoiseVal;

			// Loop through the noises
			for (int32 i = Start; i < NoiseCount; i++)
			{
				UFastNoiseWrapper* CurrentNoise = Wrappers[i];
				FNoiseSettings CurrentSetting = *NoiseInfo.Find(NoiseKeys[i]);


				// Choose the gather mode for this map
				// Afterwards it is just getting the noise and respecting the polish mode
				switch (HeightMode)
				{
				case Group:

					NoiseVal = CurrentNoise->GetNoise2D(TileLocation.X * CurrentSetting.NoiseScale, TileLocation.Y * CurrentSetting.NoiseScale);

					switch (CurrentSetting.PolishMode)
					{
					case Original:
						// Keep noise untouched
						break;

					case Truncate:
						NoiseVal = (float)FMath::TruncToInt(NoiseVal);
						break;

					case Round:
						NoiseVal = FMath::RoundHalfToEven(NoiseVal);
						break;
					}

					WholeNoiseVal += NoiseVal;

					break;


				case Individual:

					NoiseVal = CurrentNoise->GetNoise2D(TileLocation.X * CurrentSetting.NoiseScale, TileLocation.Y * CurrentSetting.NoiseScale);

					switch (CurrentSetting.PolishMode)
					{
					case Original:
						// Keep noise untouched
						break;

					case Truncate:
						NoiseVal = (float)FMath::TruncToInt(NoiseVal);
						break;

					case Round:
						NoiseVal = FMath::RoundHalfToEven(NoiseVal);
						break;
					}
					RawHeight = (((NoiseVal * CurrentSetting.HeightStrength)) / CurrentSetting.Damping);

					if (CurrentSetting.bIsSubtractive)
					{
						WholeNoiseVal -= FMath::Clamp(RawHeight, 0.f, RawHeight + 1.f);
						//TileZScale -= FMath::Clamp(RawHeight, 1.f, 1500.f);
					}
					else
					{
						WholeNoiseVal += RawHeight;
						//TileZScale += FMath::Clamp(RawHeight, 1.f, 1500.f);
					}
					break;

				default:

					NoiseVal = CurrentNoise->GetNoise2D(TileLocation.X * CurrentSetting.NoiseScale, TileLocation.Y * CurrentSetting.NoiseScale);
					switch (CurrentSetting.PolishMode)
					{
					case Original:
						// Keep noise untouched
						break;

					case Truncate:
						NoiseVal = (float)FMath::TruncToInt(NoiseVal);
						break;

					case Round:
						NoiseVal = FMath::RoundHalfToEven(NoiseVal);
						break;
					}

					WholeNoiseVal += NoiseVal;

					break;
				}

			}

			if (HeightMode == Group)
			{
				// Group the noises and use global settings
				RawHeight = (((WholeNoiseVal * WorldGlobalHeightStrength)) / WorldGlobalHeightDamping);

				TileZScale = FMath::Clamp(RawHeight, 1.f, 1500.f);
			}
			else
			{
				TileZScale = FMath::Clamp(WholeNoiseVal, 1.f, 1500.f);
			}

			// Set water level to 1 not matter what
			TileZScale = TileZScale <= Water ? 1.f : TileZScale;
			FLinearColor Paint;


			if (bShowRawValue)
			{
				// Black and white color
				Paint = FMath::Lerp<FLinearColor>(FLinearColor::Black, FLinearColor::White, TileZScale / 750);
				WorldCanvas->K2_DrawBox(FVector2D(xi, yi), CanvasSize, 1.f, Paint);
			}
			else
			{
				// Set draw color
				if (TileZScale <= Water)
				{
					Paint = WaterColor;
				}
				else
				{

					if (TileZScale >= Snow) // Tile is same or higher than snow
					{
						Paint = SnowColor;
					}
					else if (TileZScale >= Rock) // Tile is same or higher than rock
					{
						Paint = RockColor;
					}
					else if (TileZScale >= Grass) // Tile is same or higher than grass
					{
						Paint = GrassColor;
					}
					else if (TileZScale < Grass) // Tile is lower than grass, but not water
					{
						Paint = SandColor;
					}

				}
				//WorldCanvas->K2_DrawLine(WorldXY, WorldXY + FIntPoint(0, 1), 1.f, Paint);
				//WorldCanvas->DrawTile(nullptr, WorldXY.X, WorldXY.Y, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, EBlendMode::BLEND_Opaque);
				WorldCanvas->K2_DrawPolygon(nullptr, FVector2D(DrawX, DrawY), FVector2D(1), 4, Paint);
				//UE_LOG(LogTemp, Warning, TEXT("World X %d | World Y %d"), xi, yi);

				


			}


			DrawY--;
			//CurrentInstance++;

		}

		DrawY = WorldXY.Y;
		DrawX++;// --;

		bShifted = !bShifted;
	}
	UE_LOG(LogTemp, Warning, TEXT("Finished drawing"));
	UKismetRenderingLibrary::EndDrawCanvasToRenderTarget(this, CanvasContext);

	UE_LOG(LogTemp, Warning, TEXT("Finilized drawing"));


}

I found a work around and used a Texture2D instead

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.