Commit 299a90e6 authored by Chuck Walbourn's avatar Chuck Walbourn
Browse files

Samples refresh

parent 76d236e3
Loading
Loading
Loading
Loading
+15 −15
Original line number Diff line number Diff line
@@ -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
+52 −17
Original line number Diff line number Diff line
@@ -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
}

@@ -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" );
@@ -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;
};

@@ -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,
@@ -98,7 +114,7 @@ public:
const D3D12_SHADER_BYTECODE EffectBase<PBREffectTraits>::VertexShaderBytecode[] =
{
    { PBREffect_VSConstant, sizeof(PBREffect_VSConstant) },

    { PBREffect_VSConstantVelocity, sizeof(PBREffect_VSConstantVelocity) },
};


@@ -106,6 +122,7 @@ const int EffectBase<PBREffectTraits>::VertexShaderIndices[] =
{
    0,      // basic
    0,      // textured
    1,      // textured + velocity
};


@@ -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) }
};


@@ -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" );
@@ -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];
   
@@ -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;
}
@@ -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);        

@@ -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))
{
}

@@ -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[] =
+5 −1
Original line number Diff line number Diff line
@@ -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);

@@ -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;
+18 −6
Original line number Diff line number Diff line
@@ -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
@@ -78,6 +83,7 @@ struct PSInputPixelLightingTxTangent
    float4 Diffuse    : COLOR0;
};


// Common vertex shader code
struct CommonVSOutputPixelLighting
{
@@ -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;
+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