Hello again everyone!
The last week I’ve been playing around with postprocess-shaders, and most of my experiments have gone well. I do however have one problem that I thought I would share with everyone. I can’t seem to get dynamic (code-editable) materials to work with postprocess volumes (they work fine with normal meshes however. The first problem is that the Blendables-collection that contains the materials to be used in post-process is not available through a TSubObjectPtr. I can of course get around this by Get():ing the underlying pointer and access the settings from there. However, doing this and setting the material (I’ve tried in ctor, at startup and during runtime) does not seem to have any effect. I’m guessing that like almost all other properties, setting the correct instance in a collection is not enough. It probably has to be done through an appropriate setter or other properties that are related to the materials init proc are not run.
Now before I start debugging what happens when the editor sets this property and what might not be triggering I’m wondering if anyone else has gotten this to work? Any insights would be much appreciated
For reference, here is my test code for when I tried adding it in runtime:
Header:
#include "Test.generated.h"
#pragma once
UCLASS(Blueprintable, BlueprintType)
class ATest: public AActor
{
GENERATED_UCLASS_BODY()
public:
void BeginPlay() override;
public:
virtual void OnHoverEnter();
virtual void OnHoverLeave();
virtual void OnInteraction();
public:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = ItemProperties)
TSubobjectPtr<class UStaticMeshComponent> WorldMesh;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = ItemProperties)
TSubobjectPtr<class UPostProcessComponent> PostProcessVolume;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = ItemProperties)
FLinearColor HoverColor;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = ItemProperties)
FLinearColor PendingInteractionHoverColor;
private:
UMaterialInstance* HoverMaterial;
UMaterialInstanceDynamic* DynamicMaterial;
};
CPP:
#include "TestProj.h"
#include "Test.h"
#pragma once
AInteractableEntity::AInteractableEntity(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
WorldMesh = PCIP.CreateDefaultSubobject<UStaticMeshComponent>(this, TEXT("WorldMesh"));
WorldMesh->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
WorldMesh->AttachTo(InteractionBounds);
RootComponent = WorldMesh;
PostProcessVolume = PCIP.CreateDefaultSubobject<UPostProcessComponent>(this, TEXT("PostProcessVolume"));
PostProcessVolume->bUnbound = false;
UPostProcessComponent* Volume = PostProcessVolume.Get();
Volume->Settings.Blendables.Empty(); //This is added in runtime now
PostProcessVolume->AttachTo(WorldMesh);
HoverColor = FLinearColor(0.0f, 0.8f, 0.0f, 1.0f);
PendingInteractionHoverColor = FLinearColor(0.8f, 0.0f, 0.0f, 1.0f);
static ConstructorHelpers::FObjectFinder<UObject> InteractableObjectHoverMaterialFinder(TEXT("Material'/Game/Materials/Test/M_Interactable_Hover_Outline.M_Interactable_Hover_Outline'"));
UMaterialInstance* HoverMaterial = Cast<UMaterialInstance>(InteractableObjectHoverMaterialFinder.Object);
}
void AInteractableEntity::BeginPlay()
{
UPostProcessComponent* Volume = PostProcessVolume.Get();
DynamicMaterial = UMaterialInstanceDynamic::Create(Cast<UMaterialInstance>(HoverMaterial), GetWorld());
Volume->Settings.Blendables.Empty();
Volume->Settings.Blendables.Add(DynamicMaterial);
}
void AInteractableEntity::OnHoverEnter()
{
WorldMesh->SetRenderCustomDepth(true);
}
void AInteractableEntity::OnHoverLeave()
{
WorldMesh->SetRenderCustomDepth(false);
}
void AInteractableEntity::OnInteraction()
{
if (DynamicMaterial)
{
DynamicMaterial->SetVectorParameterValue(FName(TEXT("OutlineColor")), NewColor);
}
}