Loading Kits/ATGTK/HDR/HDRCommon.h +15 −15 Original line number Diff line number Diff line Loading @@ -21,70 +21,70 @@ namespace DX { // The ST.2084 spec defines max nits as 10,000 nits const float g_MaxNitsFor2084 = 10000.0f; const float c_MaxNitsFor2084 = 10000.0f; // Apply the ST.2084 curve to normalized linear values and outputs normalized non-linear values float LinearToST2084(float normalizedLinearValue) inline float LinearToST2084(float normalizedLinearValue) { float ST2084 = pow((0.8359375f + 18.8515625f * pow(abs(normalizedLinearValue), 0.1593017578f)) / (1.0f + 18.6875f * pow(abs(normalizedLinearValue), 0.1593017578f)), 78.84375f); return ST2084; // Don't clamp between [0..1], so we can still perform operations on scene values higher than 10,000 nits } // ST.2084 to linear, resulting in a linear normalized value float ST2084ToLinear(float ST2084) inline float ST2084ToLinear(float ST2084) { float normalizedLinear = pow(__max(pow(abs(ST2084), 1.0f / 78.84375f) - 0.8359375f, 0.0f) / (18.8515625f - 18.6875f * pow(abs(ST2084), 1.0f / 78.84375f)), 1.0f / 0.1593017578f); return normalizedLinear; } // Takes as inout the non-normalized value from the HDR scene. This function is only used to output UI values float LinearToST2084(float hdrSceneValue, float paperWhiteNits) inline float LinearToST2084(float hdrSceneValue, float paperWhiteNits) { // HDR scene will have values zero to larger than 1, e.g. [0..100], but the ST.2084 curve // transforms a normalized linear value, so we first need to normalize the HDR scene value. // To do this, we need define at what brightness/nits paper white is, i.e. how bright is // the value of 1.0f in the HDR scene. float normalizedLinearValue = hdrSceneValue * paperWhiteNits / g_MaxNitsFor2084; float normalizedLinearValue = hdrSceneValue * paperWhiteNits / c_MaxNitsFor2084; return LinearToST2084(normalizedLinearValue); } // Calculates the normalized linear value going into the ST.2084 curve, using the nits float CalcNormalizedLinearValue(float nits) inline float CalcNormalizedLinearValue(float nits) { return nits / g_MaxNitsFor2084; // Don't clamp between [0..1], so we can still perform operations on scene values higher than 10,000 nits return nits / c_MaxNitsFor2084; // Don't clamp between [0..1], so we can still perform operations on scene values higher than 10,000 nits } // Calc normalized linear value from hdrScene and paper white nits float CalcNormalizedLinearValue(float hdrSceneValue, float paperWhiteNits) inline float CalcNormalizedLinearValue(float hdrSceneValue, float paperWhiteNits) { float normalizedLinearValue = hdrSceneValue * paperWhiteNits / g_MaxNitsFor2084; float normalizedLinearValue = hdrSceneValue * paperWhiteNits / c_MaxNitsFor2084; return normalizedLinearValue; // Don't clamp between [0..1], so we can still perform operations on scene values higher than 10,000 nits } // Calculates the brightness in nits for a certain normalized linear value float CalcNits(float normalizedLinearValue) inline float CalcNits(float normalizedLinearValue) { return normalizedLinearValue * g_MaxNitsFor2084; return normalizedLinearValue * c_MaxNitsFor2084; } // Calculates the brightness in nits for a certain linear value in the HDR scene float CalcNits(float hdrSceneValue, float paperWhiteNits) inline float CalcNits(float hdrSceneValue, float paperWhiteNits) { float normalizedLinear = CalcNormalizedLinearValue(hdrSceneValue, paperWhiteNits); return CalcNits(normalizedLinear); } // Calc the value that the HDR scene has to use to output a certain brightness float CalcHDRSceneValue(float nits, float paperWhiteNits) inline float CalcHDRSceneValue(float nits, float paperWhiteNits) { return nits / paperWhiteNits; } // Calc HDR scene value from normalized value and paper white nits float CalcHDRSceneValueFromNormalizedValue(float normalizedLinearValue, float paperWhiteNits) inline float CalcHDRSceneValueFromNormalizedValue(float normalizedLinearValue, float paperWhiteNits) { float hdrSceneValue = normalizedLinearValue * g_MaxNitsFor2084 / paperWhiteNits; float hdrSceneValue = normalizedLinearValue * c_MaxNitsFor2084 / paperWhiteNits; return hdrSceneValue; } } No newline at end of file Kits/ATGTK/PBREffect/PBREffect.cpp +52 −17 Original line number Diff line number Diff line Loading @@ -19,15 +19,20 @@ namespace { #if defined(_XBOX_ONE) && defined(_TITLE) #include "Compiled/XboxOnePBREffect_VSConstant.inc" #include "Compiled/XboxOnePBREffect_VSConstantVelocity.inc" #include "Compiled/XboxOnePBREffect_PSConstant.inc" #include "Compiled/XboxOnePBREffect_PSTextured.inc" #include "Compiled/XboxOnePBREffect_PSTexturedVelocity.inc" #else #include "Compiled/PBREffect_VSConstant.inc" #include "Compiled/PBREffect_VSConstantVelocity.inc" #include "Compiled/PBREffect_PSConstant.inc" #include "Compiled/PBREffect_PSTextured.inc" #include "Compiled/PBREffect_PSTexturedVelocity.inc" #endif } Loading @@ -38,16 +43,20 @@ struct PBREffectConstants XMMATRIX world; XMVECTOR worldInverseTranspose[3]; XMMATRIX worldViewProj; XMMATRIX prevWorldViewProj; // for velocity generation XMVECTOR lightDirection[IEffectLights::MaxDirectionalLights]; XMVECTOR lightDiffuseColor[IEffectLights::MaxDirectionalLights]; // New PBR Parameters // PBR Parameters XMVECTOR Albedo; float Metallic; float Roughness; int numRadianceMipLevels; // Size of render target float targetWidth; float targetHeight; }; static_assert( ( sizeof(PBREffectConstants) % 16 ) == 0, "CB size not padded correctly" ); Loading @@ -58,9 +67,9 @@ struct PBREffectTraits { typedef PBREffectConstants ConstantBufferType; static const int VertexShaderCount = 1; static const int PixelShaderCount = 2; static const int ShaderPermutationCount = 2; static const int VertexShaderCount = 2; static const int PixelShaderCount = 3; static const int ShaderPermutationCount = 3; static const int RootSignatureCount = 1; }; Loading @@ -69,15 +78,22 @@ struct PBREffectTraits class ATG::PBREffect::Impl : public EffectBase<PBREffectTraits> { public: Impl(_In_ ID3D12Device* device, int effectFlags, const EffectPipelineStateDescription& pipelineDescription); Impl(_In_ ID3D12Device* device, int effectFlags, const EffectPipelineStateDescription& pipelineDescription, bool generateVelocity); void Apply(_In_ ID3D12GraphicsCommandList* commandList); int GetPipelineStatePermutation(bool textureEnabled) const; int GetPipelineStatePermutation(bool textureEnabled, bool velocityEnabled) const; static const int MaxDirectionalLights = 3; int flags; // When PBR moves into DirectXTK, this could become an effect flag. bool doGenerateVelocity; enum RootParameterIndex { AlbedoTexture, Loading @@ -98,7 +114,7 @@ public: const D3D12_SHADER_BYTECODE EffectBase<PBREffectTraits>::VertexShaderBytecode[] = { { PBREffect_VSConstant, sizeof(PBREffect_VSConstant) }, { PBREffect_VSConstantVelocity, sizeof(PBREffect_VSConstantVelocity) }, }; Loading @@ -106,6 +122,7 @@ const int EffectBase<PBREffectTraits>::VertexShaderIndices[] = { 0, // basic 0, // textured 1, // textured + velocity }; Loading @@ -113,6 +130,7 @@ const D3D12_SHADER_BYTECODE EffectBase<PBREffectTraits>::PixelShaderBytecode[] = { { PBREffect_PSConstant, sizeof(PBREffect_PSConstant) }, { PBREffect_PSTextured, sizeof(PBREffect_PSTextured) }, { PBREffect_PSTexturedVelocity, sizeof(PBREffect_PSTexturedVelocity) } }; Loading @@ -120,15 +138,17 @@ const int EffectBase<PBREffectTraits>::PixelShaderIndices[] = { 0, // basic 1, // textured 2, // textured + velocity }; // Global pool of per-device PBREffect resources. Required by EffectBase<>, but not used. SharedResourcePool<ID3D12Device*, EffectBase<PBREffectTraits>::DeviceResources> EffectBase<PBREffectTraits>::deviceResourcesPool; // Constructor. PBREffect::Impl::Impl(_In_ ID3D12Device* device, int effectFlags, const EffectPipelineStateDescription& pipelineDescription) PBREffect::Impl::Impl(_In_ ID3D12Device* device, int effectFlags, const EffectPipelineStateDescription& pipelineDescription, bool generateVelocity) : EffectBase(device), flags(effectFlags), doGenerateVelocity(generateVelocity), descriptors{} { static_assert( _countof(EffectBase<PBREffectTraits>::VertexShaderIndices) == PBREffectTraits::ShaderPermutationCount, "array/max mismatch" ); Loading Loading @@ -189,7 +209,8 @@ PBREffect::Impl::Impl(_In_ ID3D12Device* device, int effectFlags, const EffectPi mRootSignature = GetRootSignature(0, rsigDesc); // Create pipeline state int sp = GetPipelineStatePermutation((effectFlags & EffectFlags::Texture) != 0); int sp = GetPipelineStatePermutation((effectFlags & EffectFlags::Texture) != 0, doGenerateVelocity); int vi = EffectBase<PBREffectTraits>::VertexShaderIndices[sp]; int pi = EffectBase<PBREffectTraits>::PixelShaderIndices[sp]; Loading @@ -202,11 +223,12 @@ PBREffect::Impl::Impl(_In_ ID3D12Device* device, int effectFlags, const EffectPi } int PBREffect::Impl::GetPipelineStatePermutation(bool textureEnabled) const int PBREffect::Impl::GetPipelineStatePermutation(bool textureEnabled, bool velocityEnabled) const { int permutation = 0; if (textureEnabled) permutation += 1; if (velocityEnabled) permutation = 2; // only textured velocity is supported return permutation; } Loading @@ -215,6 +237,9 @@ int PBREffect::Impl::GetPipelineStatePermutation(bool textureEnabled) const // Sets our state onto the D3D device. void PBREffect::Impl::Apply(_In_ ID3D12GraphicsCommandList* commandList) { // Store old wvp for velocity calculation in shader constants.prevWorldViewProj = constants.worldViewProj; // Compute derived parameter values. matrices.SetConstants(dirtyFlags, constants.worldViewProj); Loading Loading @@ -275,8 +300,11 @@ void PBREffect::Impl::Apply(_In_ ID3D12GraphicsCommandList* commandList) } // Public constructor. PBREffect::PBREffect(_In_ ID3D12Device* device, int effectFlags, const EffectPipelineStateDescription& pipelineDescription) : pImpl(new Impl(device, effectFlags, pipelineDescription)) PBREffect::PBREffect(_In_ ID3D12Device* device, int effectFlags, const EffectPipelineStateDescription& pipelineDescription, bool generateVelocity) : pImpl(new Impl(device, effectFlags, pipelineDescription, generateVelocity)) { } Loading Loading @@ -440,6 +468,13 @@ void PBREffect::SetIBLTextures(_In_ D3D12_GPU_DESCRIPTOR_HANDLE radiance, pImpl->dirtyFlags |= EffectDirtyFlags::ConstantBuffer; } void PBREffect::SetRenderTargetSizeInPixels(int width, int height) { pImpl->constants.targetWidth = static_cast<float>(width); pImpl->constants.targetHeight = static_cast<float>(height); pImpl->dirtyFlags |= EffectDirtyFlags::ConstantBuffer; } //-------------------------------------------------------------------------------------- // PBR const D3D12_INPUT_ELEMENT_DESC VertexPositionNormalTextureTangent::InputElements[] = Loading Kits/ATGTK/PBREffect/PBREffect.h +5 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,8 @@ namespace ATG { public: explicit PBREffect(_In_ ID3D12Device* device, int effectFlags, const DirectX::EffectPipelineStateDescription& pipelineDescription); const DirectX::EffectPipelineStateDescription& pipelineDescription, bool generateVelocity = false); PBREffect(PBREffect&& moveFrom); PBREffect& operator= (PBREffect&& moveFrom); Loading Loading @@ -62,6 +63,9 @@ namespace ATG _In_ D3D12_GPU_DESCRIPTOR_HANDLE irradiance, _In_ D3D12_GPU_DESCRIPTOR_HANDLE sampler); // Render target size, required for velocity buffer output void __cdecl SetRenderTargetSizeInPixels(int width, int height); private: // Private implementation. class Impl; Loading Kits/ATGTK/PBREffect/PBREffect_Common.hlsli +18 −6 Original line number Diff line number Diff line Loading @@ -39,15 +39,20 @@ cbuffer PBR_Constants : register(b0) float4x4 PBR_World : packoffset(c1); float3x3 PBR_WorldInverseTranspose : packoffset(c5); float4x4 PBR_WorldViewProj : packoffset(c8); float4x4 PBR_PrevWorldViewProj : packoffset(c12); float3 PBR_LightDirection[3] : packoffset(c12); float3 PBR_LightColor[3] : packoffset(c15); // "Specular and diffuse light" in PBR float3 PBR_LightDirection[3] : packoffset(c16); float3 PBR_LightColor[3] : packoffset(c19); // "Specular and diffuse light" in PBR float3 PBR_ConstantAlbedo : packoffset(c18); // Constant values if not a textured effect float PBR_ConstantMetallic : packoffset(c19.x); float PBR_ConstantRoughness : packoffset(c19.y); float3 PBR_ConstantAlbedo : packoffset(c22); // Constant values if not a textured effect float PBR_ConstantMetallic : packoffset(c23.x); float PBR_ConstantRoughness : packoffset(c23.y); int PBR_NumRadianceMipLevels : packoffset(c19.z); int PBR_NumRadianceMipLevels : packoffset(c23.z); // Size of render target float PBR_TargetWidth : packoffset(c23.w); float PBR_TargetHeight : packoffset(c24.x); }; // Vertex formats Loading Loading @@ -78,6 +83,7 @@ struct PSInputPixelLightingTxTangent float4 Diffuse : COLOR0; }; // Common vertex shader code struct CommonVSOutputPixelLighting { Loading @@ -86,6 +92,12 @@ struct CommonVSOutputPixelLighting float3 Normal_ws; }; struct VSOut_Velocity { VSOutputPixelLightingTxTangent current; float4 prevPosition : TEXCOORD4; }; CommonVSOutputPixelLighting ComputeCommonVSOutputPixelLighting(float4 position, float3 normal, float4x4 world, float4x4 worldViewProj, float3x3 worldInverseT) { CommonVSOutputPixelLighting vout; Loading Kits/ATGTK/PBREffect/PBREffect_PSTexturedVelocity.hlsl 0 → 100644 +51 −0 Original line number Diff line number Diff line //-------------------------------------------------------------------------------------- // PBREffect_PSTextured.hslsi // // A physically based shader for forward rendering on DirectX 12. // // Advanced Technology Group (ATG) // Copyright (C) Microsoft Corporation. All rights reserved. //-------------------------------------------------------------------------------------- #include "PBREffect_Common.hlsli" #include "PixelPacking_Velocity.hlsli" struct PSOut_Velocity { float3 color : SV_Target0; packed_velocity_t velocity : SV_Target1; }; // Pixel shader: pixel lighting + texture. [RootSignature(PBREffectRS)] PSOut_Velocity PSTexturedVelocity(VSOut_Velocity pin) { PSOut_Velocity output; // vectors const float3 V = normalize(PBR_EyePosition - pin.current.PositionWS.xyz); // view vector const float3 L = normalize(-PBR_LightDirection[0]); // light vector ("to light" oppositve of light's direction) // Before lighting, peturb the surface's normal by the one given in normal map. float3 localNormal = BiasX2(PBR_NormalTexture.Sample(PBR_SurfaceSampler, pin.current.TexCoord).xyz); float3 N = PeturbNormal( localNormal, pin.current.NormalWS, pin.current.TangentWS); // Get albedo, then roughness, metallic and ambient occlusion float3 albedo = PBR_AlbedoTexture.Sample(PBR_SurfaceSampler, pin.current.TexCoord).rgb; float3 RMA = PBR_RMATexture.Sample(PBR_SurfaceSampler, pin.current.TexCoord); // Shade surface output.color = PBR_LightSurface(V, N, 3, PBR_LightColor, PBR_LightDirection, albedo, RMA.x, RMA.y, RMA.z); // Calculate velocity of this point float4 prevPos = pin.prevPosition; prevPos.xyz /= prevPos.w; prevPos.xy *= float2(0.5f, -0.5f); prevPos.xy += 0.5f; prevPos.xy *= float2(PBR_TargetWidth, PBR_TargetHeight); output.velocity = PackVelocity(prevPos.xyz - pin.current.PositionPS.xyz); return output; } Loading
Kits/ATGTK/HDR/HDRCommon.h +15 −15 Original line number Diff line number Diff line Loading @@ -21,70 +21,70 @@ namespace DX { // The ST.2084 spec defines max nits as 10,000 nits const float g_MaxNitsFor2084 = 10000.0f; const float c_MaxNitsFor2084 = 10000.0f; // Apply the ST.2084 curve to normalized linear values and outputs normalized non-linear values float LinearToST2084(float normalizedLinearValue) inline float LinearToST2084(float normalizedLinearValue) { float ST2084 = pow((0.8359375f + 18.8515625f * pow(abs(normalizedLinearValue), 0.1593017578f)) / (1.0f + 18.6875f * pow(abs(normalizedLinearValue), 0.1593017578f)), 78.84375f); return ST2084; // Don't clamp between [0..1], so we can still perform operations on scene values higher than 10,000 nits } // ST.2084 to linear, resulting in a linear normalized value float ST2084ToLinear(float ST2084) inline float ST2084ToLinear(float ST2084) { float normalizedLinear = pow(__max(pow(abs(ST2084), 1.0f / 78.84375f) - 0.8359375f, 0.0f) / (18.8515625f - 18.6875f * pow(abs(ST2084), 1.0f / 78.84375f)), 1.0f / 0.1593017578f); return normalizedLinear; } // Takes as inout the non-normalized value from the HDR scene. This function is only used to output UI values float LinearToST2084(float hdrSceneValue, float paperWhiteNits) inline float LinearToST2084(float hdrSceneValue, float paperWhiteNits) { // HDR scene will have values zero to larger than 1, e.g. [0..100], but the ST.2084 curve // transforms a normalized linear value, so we first need to normalize the HDR scene value. // To do this, we need define at what brightness/nits paper white is, i.e. how bright is // the value of 1.0f in the HDR scene. float normalizedLinearValue = hdrSceneValue * paperWhiteNits / g_MaxNitsFor2084; float normalizedLinearValue = hdrSceneValue * paperWhiteNits / c_MaxNitsFor2084; return LinearToST2084(normalizedLinearValue); } // Calculates the normalized linear value going into the ST.2084 curve, using the nits float CalcNormalizedLinearValue(float nits) inline float CalcNormalizedLinearValue(float nits) { return nits / g_MaxNitsFor2084; // Don't clamp between [0..1], so we can still perform operations on scene values higher than 10,000 nits return nits / c_MaxNitsFor2084; // Don't clamp between [0..1], so we can still perform operations on scene values higher than 10,000 nits } // Calc normalized linear value from hdrScene and paper white nits float CalcNormalizedLinearValue(float hdrSceneValue, float paperWhiteNits) inline float CalcNormalizedLinearValue(float hdrSceneValue, float paperWhiteNits) { float normalizedLinearValue = hdrSceneValue * paperWhiteNits / g_MaxNitsFor2084; float normalizedLinearValue = hdrSceneValue * paperWhiteNits / c_MaxNitsFor2084; return normalizedLinearValue; // Don't clamp between [0..1], so we can still perform operations on scene values higher than 10,000 nits } // Calculates the brightness in nits for a certain normalized linear value float CalcNits(float normalizedLinearValue) inline float CalcNits(float normalizedLinearValue) { return normalizedLinearValue * g_MaxNitsFor2084; return normalizedLinearValue * c_MaxNitsFor2084; } // Calculates the brightness in nits for a certain linear value in the HDR scene float CalcNits(float hdrSceneValue, float paperWhiteNits) inline float CalcNits(float hdrSceneValue, float paperWhiteNits) { float normalizedLinear = CalcNormalizedLinearValue(hdrSceneValue, paperWhiteNits); return CalcNits(normalizedLinear); } // Calc the value that the HDR scene has to use to output a certain brightness float CalcHDRSceneValue(float nits, float paperWhiteNits) inline float CalcHDRSceneValue(float nits, float paperWhiteNits) { return nits / paperWhiteNits; } // Calc HDR scene value from normalized value and paper white nits float CalcHDRSceneValueFromNormalizedValue(float normalizedLinearValue, float paperWhiteNits) inline float CalcHDRSceneValueFromNormalizedValue(float normalizedLinearValue, float paperWhiteNits) { float hdrSceneValue = normalizedLinearValue * g_MaxNitsFor2084 / paperWhiteNits; float hdrSceneValue = normalizedLinearValue * c_MaxNitsFor2084 / paperWhiteNits; return hdrSceneValue; } } No newline at end of file
Kits/ATGTK/PBREffect/PBREffect.cpp +52 −17 Original line number Diff line number Diff line Loading @@ -19,15 +19,20 @@ namespace { #if defined(_XBOX_ONE) && defined(_TITLE) #include "Compiled/XboxOnePBREffect_VSConstant.inc" #include "Compiled/XboxOnePBREffect_VSConstantVelocity.inc" #include "Compiled/XboxOnePBREffect_PSConstant.inc" #include "Compiled/XboxOnePBREffect_PSTextured.inc" #include "Compiled/XboxOnePBREffect_PSTexturedVelocity.inc" #else #include "Compiled/PBREffect_VSConstant.inc" #include "Compiled/PBREffect_VSConstantVelocity.inc" #include "Compiled/PBREffect_PSConstant.inc" #include "Compiled/PBREffect_PSTextured.inc" #include "Compiled/PBREffect_PSTexturedVelocity.inc" #endif } Loading @@ -38,16 +43,20 @@ struct PBREffectConstants XMMATRIX world; XMVECTOR worldInverseTranspose[3]; XMMATRIX worldViewProj; XMMATRIX prevWorldViewProj; // for velocity generation XMVECTOR lightDirection[IEffectLights::MaxDirectionalLights]; XMVECTOR lightDiffuseColor[IEffectLights::MaxDirectionalLights]; // New PBR Parameters // PBR Parameters XMVECTOR Albedo; float Metallic; float Roughness; int numRadianceMipLevels; // Size of render target float targetWidth; float targetHeight; }; static_assert( ( sizeof(PBREffectConstants) % 16 ) == 0, "CB size not padded correctly" ); Loading @@ -58,9 +67,9 @@ struct PBREffectTraits { typedef PBREffectConstants ConstantBufferType; static const int VertexShaderCount = 1; static const int PixelShaderCount = 2; static const int ShaderPermutationCount = 2; static const int VertexShaderCount = 2; static const int PixelShaderCount = 3; static const int ShaderPermutationCount = 3; static const int RootSignatureCount = 1; }; Loading @@ -69,15 +78,22 @@ struct PBREffectTraits class ATG::PBREffect::Impl : public EffectBase<PBREffectTraits> { public: Impl(_In_ ID3D12Device* device, int effectFlags, const EffectPipelineStateDescription& pipelineDescription); Impl(_In_ ID3D12Device* device, int effectFlags, const EffectPipelineStateDescription& pipelineDescription, bool generateVelocity); void Apply(_In_ ID3D12GraphicsCommandList* commandList); int GetPipelineStatePermutation(bool textureEnabled) const; int GetPipelineStatePermutation(bool textureEnabled, bool velocityEnabled) const; static const int MaxDirectionalLights = 3; int flags; // When PBR moves into DirectXTK, this could become an effect flag. bool doGenerateVelocity; enum RootParameterIndex { AlbedoTexture, Loading @@ -98,7 +114,7 @@ public: const D3D12_SHADER_BYTECODE EffectBase<PBREffectTraits>::VertexShaderBytecode[] = { { PBREffect_VSConstant, sizeof(PBREffect_VSConstant) }, { PBREffect_VSConstantVelocity, sizeof(PBREffect_VSConstantVelocity) }, }; Loading @@ -106,6 +122,7 @@ const int EffectBase<PBREffectTraits>::VertexShaderIndices[] = { 0, // basic 0, // textured 1, // textured + velocity }; Loading @@ -113,6 +130,7 @@ const D3D12_SHADER_BYTECODE EffectBase<PBREffectTraits>::PixelShaderBytecode[] = { { PBREffect_PSConstant, sizeof(PBREffect_PSConstant) }, { PBREffect_PSTextured, sizeof(PBREffect_PSTextured) }, { PBREffect_PSTexturedVelocity, sizeof(PBREffect_PSTexturedVelocity) } }; Loading @@ -120,15 +138,17 @@ const int EffectBase<PBREffectTraits>::PixelShaderIndices[] = { 0, // basic 1, // textured 2, // textured + velocity }; // Global pool of per-device PBREffect resources. Required by EffectBase<>, but not used. SharedResourcePool<ID3D12Device*, EffectBase<PBREffectTraits>::DeviceResources> EffectBase<PBREffectTraits>::deviceResourcesPool; // Constructor. PBREffect::Impl::Impl(_In_ ID3D12Device* device, int effectFlags, const EffectPipelineStateDescription& pipelineDescription) PBREffect::Impl::Impl(_In_ ID3D12Device* device, int effectFlags, const EffectPipelineStateDescription& pipelineDescription, bool generateVelocity) : EffectBase(device), flags(effectFlags), doGenerateVelocity(generateVelocity), descriptors{} { static_assert( _countof(EffectBase<PBREffectTraits>::VertexShaderIndices) == PBREffectTraits::ShaderPermutationCount, "array/max mismatch" ); Loading Loading @@ -189,7 +209,8 @@ PBREffect::Impl::Impl(_In_ ID3D12Device* device, int effectFlags, const EffectPi mRootSignature = GetRootSignature(0, rsigDesc); // Create pipeline state int sp = GetPipelineStatePermutation((effectFlags & EffectFlags::Texture) != 0); int sp = GetPipelineStatePermutation((effectFlags & EffectFlags::Texture) != 0, doGenerateVelocity); int vi = EffectBase<PBREffectTraits>::VertexShaderIndices[sp]; int pi = EffectBase<PBREffectTraits>::PixelShaderIndices[sp]; Loading @@ -202,11 +223,12 @@ PBREffect::Impl::Impl(_In_ ID3D12Device* device, int effectFlags, const EffectPi } int PBREffect::Impl::GetPipelineStatePermutation(bool textureEnabled) const int PBREffect::Impl::GetPipelineStatePermutation(bool textureEnabled, bool velocityEnabled) const { int permutation = 0; if (textureEnabled) permutation += 1; if (velocityEnabled) permutation = 2; // only textured velocity is supported return permutation; } Loading @@ -215,6 +237,9 @@ int PBREffect::Impl::GetPipelineStatePermutation(bool textureEnabled) const // Sets our state onto the D3D device. void PBREffect::Impl::Apply(_In_ ID3D12GraphicsCommandList* commandList) { // Store old wvp for velocity calculation in shader constants.prevWorldViewProj = constants.worldViewProj; // Compute derived parameter values. matrices.SetConstants(dirtyFlags, constants.worldViewProj); Loading Loading @@ -275,8 +300,11 @@ void PBREffect::Impl::Apply(_In_ ID3D12GraphicsCommandList* commandList) } // Public constructor. PBREffect::PBREffect(_In_ ID3D12Device* device, int effectFlags, const EffectPipelineStateDescription& pipelineDescription) : pImpl(new Impl(device, effectFlags, pipelineDescription)) PBREffect::PBREffect(_In_ ID3D12Device* device, int effectFlags, const EffectPipelineStateDescription& pipelineDescription, bool generateVelocity) : pImpl(new Impl(device, effectFlags, pipelineDescription, generateVelocity)) { } Loading Loading @@ -440,6 +468,13 @@ void PBREffect::SetIBLTextures(_In_ D3D12_GPU_DESCRIPTOR_HANDLE radiance, pImpl->dirtyFlags |= EffectDirtyFlags::ConstantBuffer; } void PBREffect::SetRenderTargetSizeInPixels(int width, int height) { pImpl->constants.targetWidth = static_cast<float>(width); pImpl->constants.targetHeight = static_cast<float>(height); pImpl->dirtyFlags |= EffectDirtyFlags::ConstantBuffer; } //-------------------------------------------------------------------------------------- // PBR const D3D12_INPUT_ELEMENT_DESC VertexPositionNormalTextureTangent::InputElements[] = Loading
Kits/ATGTK/PBREffect/PBREffect.h +5 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,8 @@ namespace ATG { public: explicit PBREffect(_In_ ID3D12Device* device, int effectFlags, const DirectX::EffectPipelineStateDescription& pipelineDescription); const DirectX::EffectPipelineStateDescription& pipelineDescription, bool generateVelocity = false); PBREffect(PBREffect&& moveFrom); PBREffect& operator= (PBREffect&& moveFrom); Loading Loading @@ -62,6 +63,9 @@ namespace ATG _In_ D3D12_GPU_DESCRIPTOR_HANDLE irradiance, _In_ D3D12_GPU_DESCRIPTOR_HANDLE sampler); // Render target size, required for velocity buffer output void __cdecl SetRenderTargetSizeInPixels(int width, int height); private: // Private implementation. class Impl; Loading
Kits/ATGTK/PBREffect/PBREffect_Common.hlsli +18 −6 Original line number Diff line number Diff line Loading @@ -39,15 +39,20 @@ cbuffer PBR_Constants : register(b0) float4x4 PBR_World : packoffset(c1); float3x3 PBR_WorldInverseTranspose : packoffset(c5); float4x4 PBR_WorldViewProj : packoffset(c8); float4x4 PBR_PrevWorldViewProj : packoffset(c12); float3 PBR_LightDirection[3] : packoffset(c12); float3 PBR_LightColor[3] : packoffset(c15); // "Specular and diffuse light" in PBR float3 PBR_LightDirection[3] : packoffset(c16); float3 PBR_LightColor[3] : packoffset(c19); // "Specular and diffuse light" in PBR float3 PBR_ConstantAlbedo : packoffset(c18); // Constant values if not a textured effect float PBR_ConstantMetallic : packoffset(c19.x); float PBR_ConstantRoughness : packoffset(c19.y); float3 PBR_ConstantAlbedo : packoffset(c22); // Constant values if not a textured effect float PBR_ConstantMetallic : packoffset(c23.x); float PBR_ConstantRoughness : packoffset(c23.y); int PBR_NumRadianceMipLevels : packoffset(c19.z); int PBR_NumRadianceMipLevels : packoffset(c23.z); // Size of render target float PBR_TargetWidth : packoffset(c23.w); float PBR_TargetHeight : packoffset(c24.x); }; // Vertex formats Loading Loading @@ -78,6 +83,7 @@ struct PSInputPixelLightingTxTangent float4 Diffuse : COLOR0; }; // Common vertex shader code struct CommonVSOutputPixelLighting { Loading @@ -86,6 +92,12 @@ struct CommonVSOutputPixelLighting float3 Normal_ws; }; struct VSOut_Velocity { VSOutputPixelLightingTxTangent current; float4 prevPosition : TEXCOORD4; }; CommonVSOutputPixelLighting ComputeCommonVSOutputPixelLighting(float4 position, float3 normal, float4x4 world, float4x4 worldViewProj, float3x3 worldInverseT) { CommonVSOutputPixelLighting vout; Loading
Kits/ATGTK/PBREffect/PBREffect_PSTexturedVelocity.hlsl 0 → 100644 +51 −0 Original line number Diff line number Diff line //-------------------------------------------------------------------------------------- // PBREffect_PSTextured.hslsi // // A physically based shader for forward rendering on DirectX 12. // // Advanced Technology Group (ATG) // Copyright (C) Microsoft Corporation. All rights reserved. //-------------------------------------------------------------------------------------- #include "PBREffect_Common.hlsli" #include "PixelPacking_Velocity.hlsli" struct PSOut_Velocity { float3 color : SV_Target0; packed_velocity_t velocity : SV_Target1; }; // Pixel shader: pixel lighting + texture. [RootSignature(PBREffectRS)] PSOut_Velocity PSTexturedVelocity(VSOut_Velocity pin) { PSOut_Velocity output; // vectors const float3 V = normalize(PBR_EyePosition - pin.current.PositionWS.xyz); // view vector const float3 L = normalize(-PBR_LightDirection[0]); // light vector ("to light" oppositve of light's direction) // Before lighting, peturb the surface's normal by the one given in normal map. float3 localNormal = BiasX2(PBR_NormalTexture.Sample(PBR_SurfaceSampler, pin.current.TexCoord).xyz); float3 N = PeturbNormal( localNormal, pin.current.NormalWS, pin.current.TangentWS); // Get albedo, then roughness, metallic and ambient occlusion float3 albedo = PBR_AlbedoTexture.Sample(PBR_SurfaceSampler, pin.current.TexCoord).rgb; float3 RMA = PBR_RMATexture.Sample(PBR_SurfaceSampler, pin.current.TexCoord); // Shade surface output.color = PBR_LightSurface(V, N, 3, PBR_LightColor, PBR_LightDirection, albedo, RMA.x, RMA.y, RMA.z); // Calculate velocity of this point float4 prevPos = pin.prevPosition; prevPos.xyz /= prevPos.w; prevPos.xy *= float2(0.5f, -0.5f); prevPos.xy += 0.5f; prevPos.xy *= float2(PBR_TargetWidth, PBR_TargetHeight); output.velocity = PackVelocity(prevPos.xyz - pin.current.PositionPS.xyz); return output; }