-
Notifications
You must be signed in to change notification settings - Fork 411
EffectFactory
DirectXTK | Effects |
---|
This is a helper object primarily used by the Model loader implementations to provide sharing of material Effects. This can be used standalone as well, and allows access to any existing ‘materials’ definitions already created.
It uses a simple case-sensitive string-based (wide-character) map for finding effect instances that have already been created by the factory, which avoid duplication of resources in complex models and scenes.
#include <Effects.h>
classDiagram
class IEffectFactory{
<<Interface>>
+CreateEffect()
}
class EffectFactory
EffectFactory --> IEffectFactory
class PBREffectFactory
PBREffectFactory --> IEffectFactory
The EffectFactory and PBREffectFactory constructor requires a Direct3D 12 device, assuming you don't have any textures used in your effects.
std::unique_ptr<EffectFactory> fxFactory;
fxFactory = std::make_unique<EffectFactory>( device );
-or-
std::unique_ptr<PBREffectFactory> fxFactory;
fxFactory = std::make_unique<PBREffectFactory>( device );
To use textures in your effects, you need to provide your resource heaps typically from EffectTextureFactory:
states = std::make_unique<CommonStates>(device);
fxFactory = std::make_unique<EffectFactory>( device,
modelResources->Heap(), states->Heap() );
For exception safety, it is recommended you make use of the C++ RAII pattern and use a std::unique_ptr
or std::shared_ptr
Fill out the EffectInfo
structure, then call CreateEffect to obtain an Effects instance. If the info.name string is provided then any already created effect from the factory that has the same name will be returned as a shared instance rather than a new instance created. If there is a name match, then all the other parameters in the EffectInfo
are ignored. Otherwise a new effect is created from the provided EffectInfo
parameters.
std::shared_ptr<IEffect> CreateEffect(
const EffectInfo& info,
const EffectPipelineStateDescription& opaquePipelineState,
const EffectPipelineStateDescription& alphaPipelineState,
const D3D12_INPUT_LAYOUT_DESC& inputLayout,
int textureDescriptorOffset = 0,
int samplerDescriptorOffset = 0);
The opaquePipelineState and alphaPipelineState pipeline states are selected based on the value of info.alphaValue
by comparing to 1.0. These can both point to the same pipeline state description if desired. The inputLayout
of these pipeline state descriptions should be nullptr. See EffectPipelineStateDescription for more details.
The textureDescriptorOffset and samplerDescriptorOffset values are used as base values when computing the proper descriptor index from info.samplerIndex
and info.samplerIndex2
.
The standard factory will create instances of BasicEffect.
- If info.enableSkinning is true, it returns a SkinnedEffect instance.
- If info.enableDualTexture is true, it returns a DualTextureEffect instance.
- If info.enableNormalMaps is true, then it returns a NormalMapEffect instance.
- If info.enableSkinning and info.enableNormalMaps are true, it return a SkinnedNormalMapEffect instance.
These are kept in distinct 'sharing' lists since they have different input layout requirements.
NormalMapEffect
orSkinnedNormalMapEffect
are only created if the material defines a normal map texture, info.enableNormalMaps is set, and EnableNormalMapEffect is true (the default).
The PBREffectFactory will create instances of PBREffect, and is intended for use with the .SDKMESH
version 2 file variant which defines PBR materials. If info.enableSkinning is true, it creates instances of SkinnedPBREffect.
The albedo (RGB) texture & alpha texture channel is provided in info.diffuseTextureIndex
, and the tangent-space normal map is provided in info.normalTextureIndex
.
The info.specularTextureIndex
value is used to provide the Occlusion/Roughness/Metalness (ORM) texture for PBR models.
You can also optionally provide an emissive channel texture as info.emissiveTextureIndex
.
Note that the resulting effects still need to have Image-Based-Lighting textures assigned which is typically done as part of rendering.
The EffectFactory and PBREffectFactory are concrete implementations of the IEffectFactory interface, and provides a default implementation and caching policy. This allows the developer to create their own custom version of the Effect Factory by deriving from IEffectFactory, which can be used with Model loaders. This could be used for alternative caching policies, substituting special Effects triggered material name, etc.
You can control the sharing cache with two methods that are implemented for all the built-in effect factories.
This method sets the sharing mode which defaults to true. By setting it to false, CreateEffect will always return a new instance rather than returning a cached instance.
fxFactory->SetSharing( false );
This method clears the sharing cache, which might not release all the instances if they are referenced by other objects.
fxFactory->ReleaseCache();
Because of the DirectX 12 Pipeline State Object (PSO) model, all effect options must be determined at the time the effect is created.
These methods are specific to EffectFactory and are not part of the
IEffectFactory
interface.
-
EnableInstancing is used to determine if
EffectFlags::Instancing
will be used for the effects that support it. -
EnableLighting is used to determine if
EffectFlags::Lighting
will be used for BasicEffect instances. This defaults to true. -
EnablePerPixelLighting is used to determine if
EffectFlags::PerPixelLighting
will be used. This defaults to true. -
EnableNormalMapEffect is used to determine if NormalMapEffect or SkinnedNormalMapEffect is used for models containing normal-map textures. This defaults to true. If set to false, it will use BasicEffect or SkinnedEffect instead for these materials.
-
EnableFogging is used to determine if
EffectFlags::Fog
will be used. This defaults to false.
Creation of resources is fully asynchronous, so you can create many effects at the same time.
All content and source code for this package are subject to the terms of the MIT License.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
- Universal Windows Platform apps
- Windows desktop apps
- Windows 11
- Windows 10
- Xbox One
- Xbox Series X|S
- x86
- x64
- ARM64
- Visual Studio 2022
- Visual Studio 2019 (16.11)
- clang/LLVM v12 - v18
- MinGW 12.2, 13.2
- CMake 3.20