DreamShaderLang
Plugin reference

Contributing

Contributing

Contributing

DreamShader » Contributing

Building the plugin itself, the layout of its five C++ modules, and where each subsystem's code lives.

Repositoryhttps://github.com/TypeDreamMoon/DreamShader
Kindcontributor reference
Plugin version2.2.0 — descriptor Version 220, IsBetaVersion false
EnginesUnreal Engine 5.3 – 5.8, Win64 verified
LicenseMIT

Synopsis

Validate the plugin standalone, without building a full project target:

& "<EngineDir>\Engine\Build\BatchFiles\RunUAT.bat" BuildPlugin `
  -Plugin="<PluginDir>\DreamShader.uplugin" `
  -Package="<OutputDir>\DreamShader" `
  -TargetPlatforms=Win64 `
  -Rocket

<PluginDir> is the directory holding DreamShader.uplugin. -Package must point at a directory that does not overlap the source tree — UAT stages a clean copy there.

One engine proves nothing about the others, so run the whole matrix with .skill/build-plugin.ps1.

Repository layout

PathContentsIn the release archive
Source/The five C++ modulesyes
Docs/This manualyes
.skill/The agent skill set, its dsc.ps1 driver, and build-plugin.ps1yes (since 1.5.1)
Resources/Icon128.png, the plugin iconyes
DreamShader.upluginPlugin descriptoryes
README.mdEnglish readmeyes
README.zh-CN.mdChinese readmeyes (since 1.5.1)
CHANGELOG.mdVersion history; the release workflow reads its ## <VersionName> sectionyes
LICENSEMITyes
Content/Localization/DreamShader/.locmeta plus one .locres per culture; loaded through the LocalizationTargets entry in the descriptoryes (since 2.1.2)
Shaders/DreamShaderBuiltins.ush and the Custom Pass shaders under Pass/, mounted at /Plugin/DreamShaderyes (since 1.5.1)
Tests/Corpus/Data-driven fixtures and .expected.json goldensno
Tools/Localization/localization_lint.ps1 and the gather baseline it emitsno
Config/FilterPlugin.ini — the stock commented template; it declares no extra packaged filesno
Images/Readme artworkno
.github/workflows/release.ymlThe only workflow in the repositoryno
Binaries/, Intermediate/Build output; git-ignoredno

Modules

ModuleTypeLoading phasePublic headersExport macro
DreamShaderLangRuntimePostConfigInit31DREAMSHADERLANG_API
DreamShaderRuntimePostConfigInit8DREAMSHADER_API
DreamShaderPass (since 2.1.0)RuntimePostConfigInit11DREAMSHADERPASS_API
DreamShaderCompilerEditorDefault20DREAMSHADERCOMPILER_API
DreamShaderEditorEditorDefault0 — there is no Public/ folderDREAMSHADEREDITOR_API is defined by UBT and never used in source

The order is the descriptor's. DreamShaderPass loads at PostConfigInit because it maps a shader source directory and its global shader types register when its DLL loads, both of which have to happen before the engine commits the shader type list.

The descriptor declares two enabled plugin dependencies: WebSocketNetworking (the preview WebSocket server) and SQLiteCore (the bridge database). Both are engine plugins.

Build rules

All five modules set PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs. Three of them add definitions, each from a probe of the engine being built against:

ModuleDefinitions
DreamShaderPublicDefinitions: DREAMSHADER_WITH_MOON_ENGINE and DREAMSHADER_WITH_PARAMETER_COLLECTION_PARAMETERS, 0 or 1 from header probes — see Version compatibility
DreamShaderPassPublicDefinitions: DREAMSHADER_WITH_CUSTOM_PASS, 1 from UE 5.8 on — see DREAMSHADER_WITH_CUSTOM_PASS. At 1 it also adds the Renderer's Internal folder to its private include paths
DreamShaderEditorPrivateDefinitions: MOON_ENGINE=1, only when the engine's SceneTypes.h declares MP_MoonEncodedAttribute0; no source file reads it
ModuleDependency list
DreamShaderLangPublic (1): Core. No private dependencies.
DreamShaderPublic (7): Core, CoreUObject, DeveloperSettings, DreamShaderLang, Engine, Projects, RenderCore. No private dependencies.
DreamShaderPassPublic (7): Core, CoreUObject, DeveloperSettings, DreamShader, Engine, RenderCore, RHI. Private (2): Projects, Renderer.
DreamShaderCompilerPublic (5): Core, CoreUObject, DreamShader, DreamShaderLang, Engine. Private (10): AssetRegistry, AssetTools, DreamShaderPass, Json, MaterialEditor, Projects, RenderCore, RHI, TargetPlatform, UnrealEd.
DreamShaderEditorPrivate (31): ApplicationCore, AssetRegistry, AssetTools, ContentBrowser, Core, CoreUObject, DesktopPlatform, DirectoryWatcher, DreamShader, DreamShaderCompiler, DreamShaderLang, DreamShaderPass, Engine, InputCore, Json, MaterialEditor, Projects, PropertyEditor, RHI, RenderCore, Renderer, Settings, Slate, SlateCore, SQLiteCore, TargetPlatform, ToolMenus, ToolWidgets, UnrealEd, WebSocketNetworking, WorkspaceMenuStructure. No public dependencies.

DreamShaderPass is a private dependency of DreamShaderCompiler and DreamShaderEditor. Both read its public definition DREAMSHADER_WITH_CUSTOM_PASS instead of testing the engine version again. DreamShaderPass itself depends on DreamShader — for the project source root its .dreampass/ folder lives in — and on no editor module.

DreamShader is a public dependency of DreamShaderCompiler, so anything that links DreamShaderCompiler transitively gets the runtime headers.

Why the runtime module needs each of its dependencies: DeveloperSettings for UDeveloperSettings; Engine for EngineTypes.h, MaterialDomain.h and UMaterialInstanceConstant; RenderCore for AllShaderSourceDirectoryMappings / AddShaderSourceDirectoryMapping; Projects for IPluginManager.

Source tree

Source/DreamShader — Runtime

PathResponsibility
Public/The eight exported headers. Documented under C++ API.
Private/DreamShaderModule.cppModule bootstrap: creates the source, package and generated-shader directories, registers the /DreamShaderGenerated and /Plugin/DreamShader shader mappings, and implements the source roots, the directory getters, SanitizeIdentifier, NormalizeSourceFilePath and the file-classification predicates.
Private/DreamShaderSettings.cppUDreamShaderSettings: constructor defaults, NormalizeMappingKey, the three TryResolve* methods, the three BuildDefault*Mappings alias catalogues, and the define-revision and pre-2.0 config hooks.
Private/DreamShaderTypes.cppNormalizeSettingKey, FTextShaderDefinition::TryGetSetting / GetSetting.
Private/DreamShaderMaterialInstance.cppUDreamShaderMaterialInstance::HasOverridenBaseProperties and IsAsset.
Private/DreamShaderDefineResolution.cppThe engine-facing half of the preprocessor define table: the builtin DS_ defines, project settings, C++ providers and the command line merged into one table.
Private/DreamShaderCompilerInterface.cppThe registry behind GetDreamShaderCompiler(), which the compiler module fills when it starts.

(since 2.0.0) The 1.x parser that lived in Private/Parser/ is gone. A .dsm / .dsf / .dsh is read by the legacy front end of DreamShaderLang — see DreamShaderLang.

Source/DreamShaderPass — Runtime

(since 2.1.0) The Custom Pass runtime: the asset a .dsp compiles to, the subsystem that decides which pipelines apply to a view, and the scene view extension that runs their passes. The module builds on every engine; what needs the renderer is compiled only where DREAMSHADER_WITH_CUSTOM_PASS is 1. See DreamShaderPass and Custom Pass runtime.

PathResponsibility
DreamShaderPass.Build.csThe UE 5.8 gate: DREAMSHADER_WITH_CUSTOM_PASS, and the Renderer Internal include path that only the 5.8 build needs.
Public/The eleven exported headers: the module (LogDreamPass and the UE::DreamPass paths of the user shader directory, the slot registry files and the slot folders), DreamPassTypes.h, DreamPassPipeline.h (UDreamPassPipeline, FOnDreamPassPipelineChanged), DreamPassSettings.h, DreamPassSubsystem.h, DreamPassVolume.h, DreamPassComponent.h, DreamPassLayerComponent.h, DreamPassBlueprintLibrary.h, and under Materials/ the two material expressions.
Private/DreamShaderPassModule.cppModule startup at 5.8: the /DreamPassUser shader directory mapping to the project source root's .dreampass/, the empty registry files the slot shaders include, and the removal of registry sections whose snapshot is missing. Below 5.8, one log line.
Private/DreamPassPipeline.cpp, DreamPassTypes.cpp, DreamPassSettings.cppThe asset and its Validate, the shared enums and their spellings, the project settings.
Private/DreamPassSubsystem.cpp, DreamPassVolume.cpp, DreamPassComponent.cpp, DreamPassLayerComponent.cpp, DreamPassBlueprintLibrary.cppActivation: what makes a pipeline apply to a view, pass layers and lists, and the Blueprint surface.
Private/DreamPassConsole.{h,cpp}r.DreamPass.Enable, r.DreamPass.DisablePipelines, r.DreamPass.Visualize and the DreamPass.Dump command.
Private/Materials/UMaterialExpressionDreamPassOutput and UMaterialExpressionDreamPassBuffer — UE.DreamPassOutput and UE.DreamPassBuffer.
Private/Render/The renderer half, compiled at 5.8 only: the scene view extension and its scheduler, the per-frame snapshot, buffers, the fullscreen, compute, mesh, clear and copy passes, the slot global shaders FDreamPassCS / FDreamPassPS, exports, buffer visualization, and DreamPassRendererInternal.cpp — the one file that includes from the Renderer's Internal folder.

The shaders these passes compile live in the plugin's Shaders/Pass/, mounted at /Plugin/DreamShader.

Source/DreamShaderCompiler — Editor

PathResponsibility
Public/The twenty exported headers — the compiler service (DreamShaderCompilerService.h, the one implementation of IDreamShaderCompiler, whose interface lives in DreamShader), the compile pipeline, the IR emitter, the builtin catalog and the asset layer. See Compiler module.
Private/DreamShaderCompilerService.cpp, DreamShaderCompilerModule.cppThe service — every compile route ends there — and the module, which registers it.
Private/Pipeline/The compile pipeline: preprocess, front end by extension, bind, lower, validate, emit; the build key; #include resolution; the 1.x texture-default class check (DSH1043 / DSH1044); diagnostics in their wire form.
Private/Emitter/The IR emitter — IR to UMaterial / UMaterialFunction / instance nodes — and the builtin catalog reflected from the running engine.
Private/Assets/Package and asset creation, Root= and Path(...) resolution with the plugin-mount checks, the source metadata and output digest, the rollback of a failed rebuild, instance schemas and ThinCustom parameter overrides.
Private/Reflection/Applying material settings, parsing setting values, writing reflected literal properties, and the reflected class surface behind material-expressions.json.
Private/Layout/Graph layout: the IR styles applied to the built graph, and the Classic 1.x layout.
Private/Sources/Source discovery, the dependency graph between sources and headers, and the product index.
Private/Preview/The (line, name) probe table a breakpoint preview reads.
Public/DreamShaderPassPipelines.h (since 2.1.0)The Custom Pass slot registry from outside a compile: the listing and its slot states, garbage collection, the reset of an unreadable Registry.json, the rewrite of the registry files, the slot pre-check of dsc check -Shaders, and the .usf ↔ .dsp lookups the bridge watches with. See DreamShaderPassPipelines.h.
Private/Pass/ (since 2.1.0)The HLSL slots. DreamShaderPassSlotRegistry plans the slots, pre-checks the changed ones in process, commits the snapshots, Registry.json and the registry .ush files, and hot-reloads the slot shaders; DreamShaderPassShaderText reads a .usf as text — where a Shader = "..." reference lands, what the file defines, which files it includes by a relative path; DreamShaderPassPipelines.cpp implements the public header.
Private/Pipeline/DreamShaderPipelineReferences.{h,cpp} (since 2.1.0)The two stages that cross between a .dsp and the .dss sources around it: a .dsp's Material and Shader references resolved and read for the facts the binder checks, before the bind; a .dss's UE.DreamPassBuffer resolved to its pipeline and buffer, after the lower.
Private/Emitter/DreamShaderIREmitterPassPipeline.{h,cpp} (since 2.1.0)The PassPipeline product: the UDreamPassPipeline, the render targets of its exported buffers and its HLSL slots — everything staged first, so that a failure writes nothing.

The compiler itself — the compile pipeline, the IR emitter and the asset layer — moved into this module in 2.0, replacing the 1.x generator (DreamShaderEditor/Private/MaterialAssetGeneration/); see Compiler module.

Source/DreamShaderLang — Runtime, Core only

PathResponsibility
Private/Preprocessor/#if / #define and the define table
Private/Lang/Lexer, the .dss / .dsi / .dsp parser, the legacy front end (LangLegacy*.cpp) that reads .dsm / .dsf / .dsh into the same tree, the printer behind fmt
Private/Semantic/The binder (LangBinder*.cpp), the 1.x legacy rules included
Private/IR/IR lowering, the validator, custom-HLSL code, IR layout, dump and compare
Private/Decompile/, Private/Migrate/IR back to text, and dsc migrate

See DreamShaderLang and The 2.0 language.

Source/DreamShaderEditor — Editor

Everything is under Private/; nothing is exported.

PathResponsibility
DreamShaderEditorModule.cppModule entry. Gates the bridge on IsRunningCommandlet(), the cook-director check and -NoDreamShaderEditorBridge; owns the cook-time materialization pass.
DreamShaderEditorPersistenceUtils.hBindAndExecute — the shared prepared-statement helper both SQLite writers use.
Bridge/The editor bridge: request-file polling, directory watcher, debounce and compile queue, material-compile diagnostics, and the preview WebSocket server.
Commandlet/UDreamShaderCommandlet and the compile / decompile / dump-graph runners plus the shared argument helpers; DreamShaderMigrate.{h,cpp}, the migrate verb (2.0). See Commandlet. (since 2.1.0) DreamShaderPassRegistryCommandlet.{h,cpp}: the pass-registry verb — the listing, -Gc and -Rebuild.
Tools/ (2.0)The other 2.0 verbs (check, dump-ir, dump-layout, index, export-catalog, fmt, list-generated), the HLSL shader check of check -Shaders, the decompile request helpers and the catalog manifest.
Decompiler/The 2.0 decompiler (DreamShaderIRDecompiler, DreamShaderGraphImport, DreamShaderInstanceDecompiler): graph → IR → .dss / .dsi; the 1.x .dsm / .dsf export (DreamShaderGraphDecompiler*) kept behind -Format=Legacy; the decompile service. See Decompiler. (since 2.1.0) DreamShaderPipelineDecompiler.{h,cpp}: a UDreamPassPipeline read back into the payload a .dsp binds to — for dsc decompile, which prints it and checks the text by parsing and binding it again, and for Adopt, which splices the payload into the existing .dsp.
Diagnostics/FDreamShaderDiagnosticsStore: error-location parsing, diagnostics.json, the per-file diagnostics/ tree and the SQLite diagnostics table.
Navigation/Node ↔ source-line navigation over the DreamShader.SourceSpans metadata a compile stamps.
Provenance/Revert to Source, Adopt Into Source and Detach — see Divergence.
Pass/ (since 2.1.0)FDreamPassPipelineCustomization — the details panel of a UDreamPassPipeline, registered on every engine the asset types build on — and DreamPassSpellings, the .dsp spelling of every DreamShaderPass enumeration the decompiler, the graph dump, the details panel and pass-keys.json write.
Preview/FDreamShaderPreviewRenderer: thumbnail scene, render targets, orbit and mesh handling, PNG encoding, blocking and async readback; the streaming session and the breakpoint probe. See Preview.
SourceFiles/The asset rename sync service. Source discovery itself moved to DreamShaderCompiler/Private/Sources/ in 2.0.
Tests/The automation suite and the corpus runners. See Testing.
UI/The Material Content Browser tab — navigation, the Sources and Assets views, the inspector and its live preview, New source, the instance factory and the generated-asset path helpers.
VirtualFunction/VirtualFunction declaration authoring and the startup sync service. See VirtualFunction tools.
Workspace/FDreamShaderWorkspaceService: the .code-workspace writer, the three bridge manifests, bridge.db, and the external-editor launch helpers. See Workspace.

Inside MaterialAssetGeneration/

(removed in 2.0.0) The 1.x generator — source loading with textual import inlining, the Graph statement walker, the per-concern lowering units and the generated .ush writer — was deleted. Where each of its jobs is done now:

1.x jobNow
Loading a source, inlining imports, mapping a byte index back to a lineDreamShaderCompiler/Private/Pipeline/ and DreamShaderLang/Private/Preprocessor/: a header is parsed on its own and every diagnostic carries its own line and column
Parsing and lowering Graph statements, builtins, calls and swizzlesDreamShaderLang: the legacy front end, the binder and IR lowering
Creating UMaterialExpression nodes, node reuseDreamShaderCompiler/Private/Emitter/
Assets, Root= / Path(...), settings, reflected properties, metadata and the skip checkDreamShaderCompiler/Private/Assets/ and Private/Reflection/
Graph layout and teardownDreamShaderCompiler/Private/Layout/ and Private/Assets/ (the rollback)
HLSL functions as Custom nodes and the generated .ushDreamShaderLang/Private/IR/IRCustomHlsl.cpp; no .ush is written

Building

GoalHow
Iterate on the plugin inside a projectBuild the host project's editor target normally. The plugin is EnabledByDefault.
Validate the plugin standalone, exactly as the consumer sees itRunUAT BuildPlugin, as in the Synopsis.
Prove an engine-version gate on every supported engine.skill/build-plugin.ps1.
Reproduce the release archiveStage the eleven shipped items by hand, or push a tag and let the release workflow do it.

BuildPlugin compiles all five modules against the target engine and fails on the first UBT or UHT error. It is the check that matters when adding an engine-version gate, because the project build only ever exercises one engine version. It is also the only check that sees a link error: an engine class that compiles everywhere and only resolves from UE 5.6 on is invisible to every compile-time gate. See the note under UE ≥ 5.6 on version compatibility.

The engine matrix

.skill/build-plugin.ps1 runs BuildPlugin once per engine root, each into its own -Package directory, and prints one PASS / FAIL line per engine plus the compiler diagnostics of the ones that failed. The plugin's own Binaries/ and Intermediate/ are never touched. Its exit code is the number of engines that failed, so 0 means the matrix is green.

./.skill/build-plugin.ps1 -Engine C:\UE\UE_5.5, C:\UE\UE_5.6, C:\UE\UE_5.7
SwitchEffect
-EngineEngine roots. An array, or one comma-separated string
-PluginThe .uplugin. Defaults to the one at or above the script
-PackageStaging root. Defaults to %TEMP%\DreamShaderBuildPlugin; must be outside the plugin tree and every engine root
-TargetPlatformsUAT syntax, +-separated. Defaults to Win64
-StopOnFailureStop at the first failing engine instead of finishing the matrix
-KeepOutputKeep the staged plugin. Without it only the log survives — a green build is a few hundred MB per engine
-RawEcho the whole UAT log instead of diagnostics and step lines
-NoRocketDrop -Rocket

The full UAT log of every engine is kept under <Package>\Logs\<Engine>.log, pass or fail.

Each engine builds into <Package>\<Engine> (UE_5.8, from Build.version), and that directory is deleted before the build, emptied by BuildPlugin itself, and deleted again after it unless -KeepOutput. So before anything is built or written, the script checks every engine's output directory and stops when one is a drive root, is or contains or sits inside an engine root or the plugin tree (-Engine C:\UE\UE_5.8 -Package C:\UE would otherwise name the engine itself), or already exists with files in it that the script did not put there. Its own output directories carry a .build-plugin-output marker, so a run after -KeepOutput reclaims them.

Engine versions

EngineStatus
5.8Verified with RunUAT BuildPlugin (2.2.0)
5.7Verified with RunUAT BuildPlugin through 1.8.0; not re-run for 2.0.0 to 2.2.0, whose gates are written so that 5.7 needs no answer of its own — see Asked of the type. 2.1.0's Custom Pass is compiled out below 5.8 (DREAMSHADER_WITH_CUSTOM_PASS 0); that side of the code was built on 5.8 with the gate forced off (Invoke-DreamShaderTests.ps1 -WithoutCustomPass) during its development; 2.1.2 adds gates at 5.5, 5.6 and 5.7, the last of which 5.7 takes the newer side of, untested
5.6Verified with RunUAT BuildPlugin (2.2.0)
5.5Verified with RunUAT BuildPlugin (2.2.0)
5.4Source-compatible; see the toolchain warning below
5.3Source-compatible; see the toolchain warning below

[!WARNING] Unreal Engine 5.3 and 5.4 do not build under a recent MSVC toolchain, whatever plugin you point at them. ConcurrentLinearAllocator.h writes #elif __has_feature(address_sanitizer) without a defined() guard, inside #if PLATFORM_HAS_ASAN_INCLUDE — which is __has_include(<sanitizer/asan_interface.h>), true for every toolchain that ships the ASan headers. MSVC has no __has_feature, so the line raises C4668, and UBT compiles engine code with /we4668. UE 5.5 fixed the header by splitting the test.

The failure is in engine code, before any plugin source is reached, and Source/DreamShader* is named nowhere in it. Epic's own ExampleDeviceProfileSelector fails identically on the same engine, which is the cheapest way to confirm the cause on a given machine. Note that installing MSVC 14.38 does not by itself help — it ships sanitizer/asan_interface.h too. It takes a toolchain without those headers, or a one-line patch to the engine header.

Every engine-version test in the plugin goes through the macros in DreamShaderVersionCompat.h; there are no raw ENGINE_MAJOR_VERSION or UE_VERSION_NEWER_THAN uses anywhere in Source/. When you add version-dependent code, add it there and use DREAMSHADER_UE_VERSION_AT_LEAST(Major, Minor) or DREAMSHADER_WITH_SUBSTRATE_BUILTINS. The one exception is Custom Pass: DreamShaderPass.Build.cs tests Target.Version and defines DREAMSHADER_WITH_CUSTOM_PASS, and code that depends on DreamShaderPass tests that definition with #if instead of the version. Both sides compile and test on a 5.8 machine: see Both sides of the Custom Pass gate. The complete list of currently gated behaviour is on Version compatibility.

Localization

Editor-facing text is LOCTEXT/NSLOCTEXT. The wire format is not: diagnostics.json, diagnostics/*.json, bridge.db, preview.json and the preview WebSocket are parsed by the VSCode and Rider extensions and must read the same in every editor culture.

The rule that keeps both true:

  • Text that reaches the wire stays an FText all the way there, and the write goes through ToInvariantWireString() (Diagnostics/DreamShaderTextWireUtils.h). That function replays the FText's historic format data — pattern, arguments, nested formats — in the invariant culture. FTextInspector::GetSourceString alone is not enough: for an FText::Format result it returns the localized substituted display.
  • Never collapse such an FText with ToString() on the way. ToString() is the localized display, and re-wrapping the result in FText::FromString cannot recover the English. An API whose error channel is FString-typed — FDreamShaderPreviewRenderContext, the asset layer's FDreamShaderError — therefore keeps literal FString::Printf messages, marked I18N-EXEMPT.
  • Text that only ever reaches Slate has no such constraint; localize it normally.
pwsh -File Tools/Localization/localization_lint.ps1

Checks LOCTEXT_NAMESPACE define/undef pairing, rejects the define in headers, and flags literals gather cannot see (FText::FromString(TEXT(...)), FString::Printf(TEXT(...))). A deliberate non-display literal is exempted with an I18N-EXEMPT comment on the same line as the call — the check reads one line, not a span. -IncludeDeferred widens which files those literal rules run on.

-EmitBaseline regenerates Tools/Localization/BASELINE.md, whose gather count is the regression check; it covers every source file, because GatherText does. A count that moves without a matching .locres update means the translations are behind.

There is no Config/Localization/DreamShader.ini yet, so the Dashboard cannot re-gather the target and the checked-in zh-Hans .locres is a hand-made snapshot. New LOCTEXT falls back to English until it is regenerated.

Notes

  • DreamShaderEditor exports nothing. It has no Public/ folder, and DREAMSHADEREDITOR_API never appears in source, so third-party C++ cannot link against the bridge or the decompiler. The supported C++ extension point is IDreamShaderCompiler — declared in DreamShader, implemented in DreamShaderCompiler, reached through GetDreamShaderCompiler(); everything else is reachable only through the editor UI, the commandlet or the bridge.
  • No module singletons. No module class has Get() / IsAvailable() accessors. Use FModuleManager::LoadModuleChecked<FDreamShaderModule>(TEXT("DreamShader")). The public delegates are OnDreamShaderSourceGenerated (a compile finished, in DreamShaderCompiler), the define-provider delegate of DreamShaderDefineResolution.h, and FOnDreamPassPipelineChanged in DreamShaderPass.
  • The compiler is game-thread, editor-only. The compile pipeline opens an FScopedSlowTask, creates and modifies UPackages and UMaterials, and calls PostEditChange().
  • Three different "normalize" helpers exist and are easy to confuse: NormalizeSettingKey (trim + lowercase), UDreamShaderSettings::NormalizeMappingKey (trim + lowercase + strip spaces, _ and -), and NormalizeSourceFilePath (absolute path with / separators). SanitizeIdentifier is an identifier sanitizer, not a key normalizer.
  • The generated documentation site is built from Docs/; DocsURL in the descriptor points at https://shader.toolchain.64hz.cn/.

Example

A complete standalone build of the plugin against a 5.7 engine:

& "C:\Program Files\Epic Games\UE_5.7\Engine\Build\BatchFiles\RunUAT.bat" BuildPlugin `
  -Plugin="D:\Work\MyProject\Plugins\DreamShader\DreamShader.uplugin" `
  -Package="D:\Work\Out\DreamShader" `
  -TargetPlatforms=Win64 `
  -Rocket

Staged output:

D:\Work\Out\DreamShader\
  Binaries\Win64\UnrealEditor-DreamShaderLang.dll
  Binaries\Win64\UnrealEditor-DreamShader.dll
  Binaries\Win64\UnrealEditor-DreamShaderPass.dll
  Binaries\Win64\UnrealEditor-DreamShaderCompiler.dll
  Binaries\Win64\UnrealEditor-DreamShaderEditor.dll
  Binaries\Win64\UnrealEditor.modules
  Intermediate\              UBT and UHT working files
  Source\                    copied from the plugin tree
  Shaders\                   copied from the plugin tree
  Resources\                 copied from the plugin tree
  Docs\                      copied from the plugin tree
  DreamShader.uplugin

The same five module names appear in a normal project build under <Plugin>/Binaries/Win64/, alongside their .pdb files.

See also

  • Testing — the automation suite, the fixture corpus, and how to run both headlessly
  • Release — tag conventions, the release workflow, and what the archive contains
  • C++ API — the exported headers, class by class
  • Compiler module — IDreamShaderCompiler, the supported extension point
  • Version compatibility — the compat macros and every gated behaviour
  • Commandlet — -run=DreamShader, the headless entry point
  • Editor bridge — request files, bridge.db, the preview WebSocket
  • Generation pipeline — what a compile does, end to end
  • Project settings — UDreamShaderSettings, including the source directory

On this page