Skip to content

Effects

Chuck Walbourn edited this page Dec 14, 2017 · 61 revisions

This is a native Direct3D 12 implementation of the five built-in effects from XNA Game Studio 4, providing identical functionality and API:

  • BasicEffect supports texture mapping, vertex coloring, directional lighting, and fog
  • AlphaTestEffect supports per-pixel alpha testing
  • DualTextureEffect supports two layer multi-texturing (for light maps or detail textures)
  • EnvironmentMapEffect supports cubic environment mapping
  • SkinnedEffect supports skinned animation with up to 72 bones and 1, 2, or 4 bone influences per vertex.

DirectX Tool Kit also includes the following built-in effects:

  • NormalMapEffect which extends BasicEffect to support normal maps and optional specular map.
  • PBREffect which implements a Disney-style (Roughness/Metalness workflow) Physically-Based Renderer effect using image-based lighting.
  • DebugEffect which implements debugging shaders such as visualization of normals, tangents, and bi-tangents.

DirectX Tool Kit for DirectX 12 does not support the Visual Studio Shader Designer (DGSL) content pipeline (i.e. DGSLEffect) that is supported by the DirectX 11 version.

See also EffectFactory, EffectTextureFactory

Related tutorials: Simple rendering, 3D shapes, Rendering a model, Using advanced shaders

Header

#include <Effects.h>

Initialization

The built-in effect constructors require a Direct3D 12 device, optional effect flags, and state description:

std::unique_ptr<BasicEffect> effect;

RenderTargetState rtState(m_deviceResources->GetBackBufferFormat(),
    m_deviceResources->GetDepthBufferFormat());

EffectPipelineStateDescription pd(
    &VertexPositionNormalTexture::InputLayout,
    CommonStates::Opaque,
    CommonStates::DepthDefault,
    CommonStates::CullNone,
    rtState);

effect = std::make_unique<BasicEffect>(device,
    EffectFlags::Lighting,
    pd);

For exception safety, it is recommended you make use of the C++ RAII pattern and use a std::unique_ptr or std::shared_ptr

Flags

Effects flags supported for built-in shaders:

  • EffectFlags::None
  • EffectFlags::Fog: Enables fogging.
  • EffectFlags::Lighting: Enables lighting which requires a vertex normal in the input layout.
  • EffectFlags::PerPixelLighting: Enables per-pixel lighting which requires a vertex normal in the input layout.
  • EffectFlags::VertexColor: Enables use of a per-vertex color which requires a vertex color in the input layout.
  • EffectFlags::Texture: Enables use of texturing which requires texture coordinates in the input layout.
  • EffectFlags::BiasedVertexNormals: Enables support for compressed vertex normals and tangents which require *2 - 1 biasing at runtime.

Textures and samplers

When you set a texture for an effect, you provide a texture descriptor and a sampler descriptor. Typically you make use of a DescriptorHeap for the texture descriptors and CommonStates for the sampler descriptors.

// Effect had to be created with EffectFlags::Texture
effect->SetTexture(resourceDescriptors->GetGpuHandle(Descriptors::MyTexture),
    states->AnisotropicWrap());

Set effect parameters

effect->SetWorld(world);
effect->SetView(view);
effect->SetProjection(projection);

// Effect had to be created with EffectFlags::Lighting or ::PerPixelLighting
effect->EnableDefaultLighting();

The built-in effects default to a standard lighting and color set

  • Matrices are all set to identity
  • Ambient, diffuse, and emissive colors default to black
  • Fully opaque (alpha set to 1)
  • Specular defaults to white with a power of 16
  • Default lights are set to white with no specular highlight and a default direction of [0, -1, 0]. All lights are disabled by default.

The EnableDefaultLighting method sets up a standard three light setup (key, fill, and back) with some ambient light and some soft specular highlights.

Draw using the effect

ID3D12DescriptorHeap* heaps[] = { resourceDescriptors->Heap(), states->Heap() };
commandList->SetDescriptorHeaps(_countof(heaps), heaps);

effect->Apply(commandList);

commandList->IASetVertexBuffers(...);
commandList->IASetIndexBuffer(...);
commandList->IASetPrimitiveTopology(...);
commandList->OMSetBlendFactor(...);
commandList->OMSetStencilRef(...);

commandList->DrawIndexedInstanced(...);

Effects Apply method typically calls SetGraphicsRootSignature, SetGraphicsRootDescriptorTable, SetGraphicsRootConstantBufferView, and SetPipelineState.

To provide flexibility, setting the proper descriptor heaps to render with via SetDescriptorHeaps is left to the caller. You can create as many heaps as you wish in your application, but remember that you can have only a single texture descriptor heap and a single sampler descriptor heap active at a given time.

Interfaces

The built-in effects support a number of different settings, some of which are organized into more 'generic' interfaces.

  • IEffect is the basic interface for all effects which sets the Pipeline State Object (PSO) to the command list.
  • IEffectMatrices is the interface for setting an effects' world, view, and projection matrices. All the built-in effects support this interface.
  • IEffectLights is the interface for controlling the effects' lighting computations and settings. This is supported by BasicEffect, EnvironmentMapEffect, and SkinningEffect if EffectFlags::Lighting or EffectFlags::PerPixelLighting is provided at creation.
  • IEffectFog is the interface to control the effects' fog settings. This is supported by BasicEffect, AlphaTestEffect, DualTextureEffect, EnvironmentMapEffect, and SkinnedEffect if EffectFlags::Fog is provided at creation.
  • IEffectSkinning is the interface to control skinned animation settings. This is supported by SkinnedEffect. This includes setting the bone transform matrices, and optimizing the number of bone influences per vertex to process (1, 2, or 4; defaults to 4).

Coordinate systems

The built-in effects work equally well for both right-handed and left-handed coordinate systems. The one difference is that the fog settings start & end for left-handed coordinate systems need to be negated (i.e. SetFogStart(6), SetFogEnd(8) for right-handed coordinates becomes SetFogStart(-6), SetFogEnd(-8) for left-handed coordinates).

Remarks

Because DirectX 12 Pipeline State Objects (PSOs) are immutable, all options must be provided to the effect constructor. Any change to state, input layout, or combination of options that would result in different shader being used requires creating a new effect instance.

Threading model

Creation is fully asynchronous, so you can instantiate multiple effect instances at the same time on different threads. Each instance only supports drawing from one thread at a time, but you can simultaneously draw on multiple threads if you create a separate effect instance per command list.

Work Submission in Direct3D 12

State management

When Apply is called on an effect, it will set the states needed to render including the root signature and the Pipeline State Object (PSO).

Further reading

New built-in effects in XNA Game Studio 4.0
Built-in effects, permutations, and performance

For Use

  • Universal Windows Platform apps
  • Windows desktop apps
  • Windows 11
  • Windows 10
  • Xbox One
  • Xbox Series X|S

Architecture

  • x86
  • x64
  • ARM64

For Development

  • Visual Studio 2022
  • Visual Studio 2019 (16.11)
  • clang/LLVM v12 - v18
  • MinGW 12.2, 13.2
  • CMake 3.20

Related Projects

DirectX Tool Kit for DirectX 11

DirectXMesh

DirectXTex

DirectXMath

Tools

Test Suite

Model Viewer

Content Exporter

DxCapsViewer

See also

DirectX Landing Page

Clone this wiki locally