DreamShaderLang
Plugin referenceC++ API

DreamShaderPass

DreamShaderPass

DreamShaderPass

DreamShader » C++ API » DreamShaderPass

The Custom Pass runtime: the asset a .dsp compiles to, what decides which pipelines apply to a view, and the scene view extension that runs their passes inside the renderer. This page is the module's C++ and Blueprint surface; what the passes do at run time is Custom Pass runtime.

ModuleDreamShaderPass (Runtime, PostConfigInit loading phase)
Enginesevery engine the plugin supports; the render side only on 5.8 and later — see DREAMSHADER_WITH_CUSTOM_PASS
Export macroDREAMSHADERPASS_API
Log categoryLogDreamPass
Public dependenciesCore, CoreUObject, DeveloperSettings, DreamShader, Engine, RenderCore, RHI
Private dependenciesProjects, Renderer
Blueprint categoryDreamShader | Custom Pass

Public headers

HeaderContents
DreamShaderPassModule.hLogDreamPass; the slot counts; where the HLSL slot registry and snapshots live
DreamPassTypes.hthe enums and descriptors a pipeline is made of — injection points, pass kinds, buffer formats, parameters and their values, bindings, mesh filters — and the .dsp spellings of the enums
DreamPassPipeline.hUDreamPassPipeline, the asset
DreamPassSettings.hUDreamPassSettings — the project settings
DreamPassSubsystem.hUDreamPassSubsystem, IDreamPassActivationSource, FDreamPassHandle
DreamPassBlueprintLibrary.hUDreamPassBlueprintLibrary
DreamPassVolume.hADreamPassVolume
DreamPassComponent.hUDreamPassComponent, EDreamPassComponentScope
DreamPassLayerComponent.hUDreamPassLayerComponent ("Dream Pass Layers") — gives the primitives of its actor the pass layers a mesh pass selects with Filter = Layer(...)
Materials/MaterialExpressionDreamPassOutput.hUMaterialExpressionDreamPassOutput — UE.DreamPassOutput
Materials/MaterialExpressionDreamPassBuffer.hUMaterialExpressionDreamPassBuffer — UE.DreamPassBuffer; its static ResolveExportTarget(Pipeline, Buffer, OutProblem) is the check both the node and DreamShader use

DREAMSHADER_WITH_CUSTOM_PASS

A public definition of the module, set by DreamShaderPass.Build.cs from the target engine: 1 on 5.8 and later, 0 below — or on any engine built with -ProjectDefine:DREAMSHADER_FORCE_NO_CUSTOM_PASS, for testing. Every module that depends on this one reads the same answer.

  • Reflected types exist on every engine — the asset, the settings, the subsystem, the volume and the components compile anywhere, so a project that opens on an older engine still loads and saves them.
  • Everything that touches the renderer is compiled out at 0: the scene view extension, the passes, the global and mesh-pass shaders. Nothing runs, and the module says so once in the log at startup.

Activating a pipeline

From C++, through the world's subsystem:

#include "DreamPassSubsystem.h"

UDreamPassSubsystem* Passes = UDreamPassSubsystem::Get(GetWorld());
FDreamPassHandle Handle = Passes->AddPipeline(HighlightPipeline, /*Priority*/ 0.0f, /*Overrides*/ {});
Passes->SetParameter(Handle, TEXT("Thickness"), FDreamPassParameterValue::MakeFloat(3.0f));
Passes->SetWeight(Handle, 0.5f);
// ...
Passes->RemovePipeline(Handle);

From Blueprints, the same calls are on UDreamPassBlueprintLibrary with a world context, plus SetFloatParameter, SetColorParameter, SetBoolParameter, SetIntParameter, SetTextureParameter and the Make…Value helpers.

Or place a source in the level — an ADreamPassVolume, a UDreamPassComponent — or list the pipeline in the project settings. How the four kinds combine is in What makes a pipeline apply.

UDreamPassSubsystem

A UWorldSubsystem of game, PIE and editor worlds; an editor preview world has none. Game thread only.

Function
static Get(const UWorld*)the world's subsystem, or null
AddPipeline(Pipeline, Priority, Overrides, PlayerIndex = -1)runs the pipeline in every view of the world — or one local player's — until RemovePipeline; returns its handle
RemovePipeline(Handle) · IsActive(Handle)
SetParameter(Handle, Name, Value)sets or adds one override; false for an unknown handle or parameter, or a value of the wrong type
SetWeight(Handle, Weight)0–1
AddToList(List, Primitive) · RemoveFromList · ClearListthe named lists a mesh pass selects with Filter = List(Name)
RegisterSource(Object, Source) · UnregisterSource(Object)an activation source of your own
ResolveView(Query, OutPipelines)every pipeline that applies to a view, blended, in execution order — what the renderer is given each frame
DumpState(Ar)what DreamPass.Dump prints for this world

FDreamPassHandle is a BlueprintType struct; a default one is not valid (IsValid()).

ADreamPassVolume

An AVolume that runs its pipeline in the views inside it, with a post-process volume's arithmetic.

PropertyDefault
Pipelinenonenone: the volume does nothing
bEnabledtrue
bUnboundfalseapplies to every view of the world, wherever it is; an unbound volume is not spatially loaded
Priority0where its overrides sit among every activation of the same pipeline: higher wins
BlendRadius100cm outside the volume over which its weight fades from BlendWeight to 0; below 1, a hard edge
BlendWeight10–1, inside the volume
Overridesemptyparameter values; one left out keeps what lower priorities give it

SetEnabled, SetBlendWeight and SetParameter(Name, Value) are Blueprint-callable; GetWeightAt(Location) is the weight a view there would get. Outside a game world the volume follows its editor visibility: hiding it in the outliner takes it out of the editor viewports. A volume spawned at runtime has no brush, and applies only when unbound.

UDreamPassComponent

An actor component that runs its pipeline from any actor.

PropertyDefault
Pipelinenone
bEnabledtrue
Priority0
Weight10–1
ScopeWorldWorld: every view of its world · ViewTarget: the views whose view target is the owner — the player looking through it and anyone spectating it
PlayerIndex-1only that local player's views (the controller id); -1: any view, editor viewports included
Overridesempty

SetEnabled, SetWeight, SetParameter, SetFloatParameter and SetColorParameter are Blueprint-callable; SetColorParameter sets a float3 or a float4 parameter, whichever the pipeline declares.

Writing an activation source

Anything can activate pipelines by implementing IDreamPassActivationSource and registering with the subsystem while it should apply:

class FMyGameModeSource : public IDreamPassActivationSource
{
public:
    virtual void GatherDreamPassActivations(const FDreamPassViewQuery& View, TArray<FDreamPassActivation>& Out) const override
    {
        if (View.PlayerIndex == 0)   // the first player only
        {
            FDreamPassActivation& Activation = Out.AddDefaulted_GetRef();
            Activation.Pipeline = Pipeline;
            Activation.Weight = Fade;
        }
    }

    UDreamPassPipeline* Pipeline = nullptr;   // keep it referenced elsewhere: the subsystem does not
    float Fade = 1.0f;
};

Subsystem->RegisterSource(Owner, &Source);   // Owner: the UObject whose lifetime bounds the registration
Subsystem->UnregisterSource(Owner);

GatherDreamPassActivations is called on the game thread for every view of every frame, so it should be cheap. FDreamPassViewQuery gives the view's location, local player, view target, kind and capabilities; an activation's Overrides is a view into storage the source owns, valid for the call.

UDreamPassPipeline

The compiled pipeline. Its fields mirror the .dsp — Order, DefaultInjection, Views, Requires, EnabledParameter, Parameters, Buffers, Passes, the exported render targets — and SourceFilePath and SourceHash say which source built it. Edit the .dsp, not the asset: a compile overwrites it, and an edit made in the details panel is a divergence to adopt or discard. A pass's HLSL written in the .dsp is kept in the editor's data only -- HlslSource on the pass says where its code is, InlineHlsl and InlineHlslLine hold its own hlsl block, and the pipeline's SharedHlsl the file's -- for the way back to text: what runs is the slot's snapshot, and a cook carries no HLSL text.

Member
GetExportTarget(Buffer)the render target an exported buffer is copied into; Blueprint-pure
FindBuffer(Name) · FindParameter(Name) · FindPassIndex(Name)lookups
Validate(OutProblems)the checks the runtime relies on, for the whole asset
NotifyChanged() · OnPipelineChangedafter an edit — the compiler calls it after writing the asset, PostLoad and the details panel too: re-checks every pass, skipping one that fails with a warning naming the problem, and broadcasts the static OnPipelineChanged. The renderer reads the asset afresh every frame

The HLSL slot registry

Function (UE::DreamPass)Returns
GetUserShaderDirectory()<project source root>/.dreampass — commit it
GetUserShaderVirtualDirectory()/DreamPassUser
GetRegistryFilePath(bCompute)RegistryCompute.ush or RegistryPixel.ush in it
GetSlotDirectory(bCompute, Slot) · GetSlotVirtualDirectorySlots/C07, Slots/P07: one slot's snapshot
GetComputeSlotCount() · GetPixelSlotCount()DREAMSHADER_PASS_COMPUTE_SLOTS (32), DREAMSHADER_PASS_PIXEL_SLOTS (16)

The counts are overridable from a Target.cs (GlobalDefinitions.Add("DREAMSHADER_PASS_COMPUTE_SLOTS=48")); raising one recompiles the two global shader types, nothing else. How the registry is written is HLSL passes.

See also

On this page