Glass Breaking

via RenderTargets

https://youtu.be/fqTEgB1NkHA

Glass Breaking via RenderTargets:

  • The AGlass actor creates a RenderTarget per actor, then it acquires the glass Material in which it creates a DynamicMaterialInstance, and finally passes the RenderTarget to it.
RenderTarget = CreateDefaultSubobject<UTextureRenderTarget2D>(TEXT("RenderTarget"));
if (RenderTarget)
{
	RenderTarget->InitAutoFormat(256, 256);
	RenderTarget->ClearColor = FLinearColor::Black;
	RenderTarget->bAutoGenerateMips = false;
	RenderTarget->AddressX = TA_Clamp;
	RenderTarget->AddressY = TA_Clamp;
}
  • AGlass creates the GlassBreakBrush as a MaterialInstanceDynamic in OnBegin().
// Setup Glass Material Render Target
GlassMaterial = GlassMesh->CreateDynamicMaterialInstance(0, GlassMesh->GetMaterial(0));
if (GlassMaterial && RenderTarget)
{
	GlassMaterial->SetTextureParameterValue(FName("RenderTarget"), RenderTarget);
	GlassMesh->SetMaterial(0, GlassMaterial);
}

// Setup Glass Break Brush
if (GlassBreakMaterial)
{
	GlassBreakBrush = UMaterialInstanceDynamic::Create(GlassBreakMaterial, this);
}
  • When the AGlass gets hit:
TRACE_CPUPROFILER_EVENT_SCOPE_STR("Glass-BreakAtLocation");
if (GlassBreakMaterial && RenderTarget)
{
	if (UWorld* World = GetWorld())
	{
	  // 1. Find line hit collison location in UV space
		FVector2D HitColLoc;
		UGameplayStatics::FindCollisionUV(Hit, 0, HitColLoc);

		// 2. Begin drawing to our Canvas
		UCanvas* Canvas; FVector2D Size; FDrawToRenderTargetContext Context;
		UKismetRenderingLibrary::BeginDrawCanvasToRenderTarget(World, RenderTarget, Canvas, Size, Context);
		// 3.We calculate the brush size, then draw it at given HitColLoc, we randomize the rotation
		const FVector2D HitSize = (Size * HitColLoc) - (GlassBreakBrushSize / 2.0f);
		Canvas->K2_DrawMaterial(GlassBreakMaterial, HitSize, FVector2D(GlassBreakBrushSize), FVector2D(0.0),
								FVector2D::UnitVector, FMath::FRandRange(0.0f, 360.0f));
		// 4. End drawing to our Canvas
		UKismetRenderingLibrary::EndDrawCanvasToRenderTarget(World, Context);
	}
}

Notes:

  • The GlassBreak texture is stored as a RGB mask, in which each channel stores a different opacity level.
  • In order to create the illusion of depth, we use 2 copies of the RenderTarget as well as the BumpOffset node.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *