Tag: Breaking

  • 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.