via RenderTargets
Glass Breaking via RenderTargets:
- The
AGlassactor creates aRenderTargetper actor, then it acquires the glass Material in which it creates aDynamicMaterialInstance, and finally passes theRenderTargetto 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;
}AGlasscreates theGlassBreakBrushas aMaterialInstanceDynamicinOnBegin().
// 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
AGlassgets 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
RenderTargetas well as the BumpOffset node.