Throwing up Depth of Field WIP so Galib can investigate AP crash with shader processing

Signed-off-by: antonmic <56370189+antonmic@users.noreply.github.com>
This commit is contained in:
antonmic
2021-10-20 14:10:11 -07:00
parent aabb519452
commit 9e8e08a815
38 changed files with 1657 additions and 31 deletions
@@ -0,0 +1,143 @@
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "PassAsset",
"ClassData": {
"PassTemplate": {
"Name": "NewDepthOfFieldTemplate",
"PassClass": "NewDepthOfFieldParentPass",
"Slots": [
{
"Name": "Depth",
"SlotType": "Input"
},
{
"Name": "LightingBuffer",
"SlotType": "InputOutput",
"ScopeAttachmentUsage": "RenderTarget"
}
],
"PassRequests": [
{
"Name": "Downsample",
"TemplateName": "NewDepthOfFieldDownsampleTemplate",
"Connections": [
{
"LocalSlot": "ColorInput",
"AttachmentRef": {
"Pass": "Parent",
"Attachment": "LightingBuffer"
}
},
{
"LocalSlot": "DepthInput",
"AttachmentRef": {
"Pass": "Parent",
"Attachment": "Depth"
}
}
]
},
{
"Name": "TileReduce",
"TemplateName": "NewDepthOfFieldTileReduceTemplate",
"Connections": [
{
"LocalSlot": "ColorAndCocInput",
"AttachmentRef": {
"Pass": "Downsample",
"Attachment": "OutputColorAndCoC"
}
}
]
},
{
"Name": "Tile3x3",
"TemplateName": "NewDepthOfFieldTile3x3Template",
"Connections": [
{
"LocalSlot": "Input",
"AttachmentRef": {
"Pass": "TileReduce",
"Attachment": "MinMaxCoC"
}
}
]
},
{
"Name": "LargeFilter",
"TemplateName": "NewDepthOfFieldFilterLargeTemplate",
"Connections": [
{
"LocalSlot": "ColorAndCoc",
"AttachmentRef": {
"Pass": "Downsample",
"Attachment": "OutputColorAndCoC"
}
},
{
"LocalSlot": "CocTile",
"AttachmentRef": {
"Pass": "Tile3x3",
"Attachment": "Output"
}
}
]
},
{
"Name": "SmallFilter",
"TemplateName": "NewDepthOfFieldFilterSmallTemplate",
"Connections": [
{
"LocalSlot": "ColorAndCoc",
"AttachmentRef": {
"Pass": "LargeFilter",
"Attachment": "OutputColorAndCoc"
}
},
{
"LocalSlot": "CocTile",
"AttachmentRef": {
"Pass": "Tile3x3",
"Attachment": "Output"
}
}
]
},
{
"Name": "Composite",
"TemplateName": "NewDepthOfFieldCompositeTemplate",
"Connections": [
{
"LocalSlot": "Depth",
"AttachmentRef": {
"Pass": "Parent",
"Attachment": "Depth"
}
},
{
"LocalSlot": "HalfResColorAndCoC",
"AttachmentRef": {
"Pass": "SmallFilter",
"Attachment": "OutputColorAndCoc"
}
},
{
"LocalSlot": "ColorInputOutput",
"AttachmentRef": {
"Pass": "Parent",
"Attachment": "LightingBuffer"
}
}
]
}
]
}
}
}
@@ -0,0 +1,37 @@
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "PassAsset",
"ClassData": {
"PassTemplate": {
"Name": "NewDepthOfFieldCompositeTemplate",
"PassClass": "FullScreenTriangle",
"Slots": [
{
"Name": "Depth",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader",
"ShaderImageDimensionsConstant": "m_fullResDimensions"
},
{
"Name": "HalfResColorAndCoC",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader",
"ShaderImageDimensionsConstant": "m_halfResDimensions"
},
{
"Name": "ColorInputOutput",
"SlotType": "InputOutput",
"ScopeAttachmentUsage": "RenderTarget"
}
],
"PassData": {
"$type": "FullscreenTrianglePassData",
"ShaderAsset": {
"FilePath": "Shaders/PostProcessing/NewDepthOfFieldComposite.shader"
},
"PipelineViewTag": "MainCamera"
}
}
}
}
@@ -0,0 +1,72 @@
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "PassAsset",
"ClassData": {
"PassTemplate": {
"Name": "NewDepthOfFieldDownsampleTemplate",
"PassClass": "FullScreenTriangle",
"Slots": [
{
"Name": "ColorInput",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader",
"ShaderImageDimensionsConstant": "m_inputDimensions"
},
{
"Name": "DepthInput",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader",
"ImageViewDesc": {
"AspectFlags": [
"Depth"
]
}
},
{
"Name": "OutputColorAndCoC",
"SlotType": "Output",
"ScopeAttachmentUsage": "RenderTarget",
"ShaderImageDimensionsConstant": "m_outputDimensions",
"LoadStoreAction": {
"LoadAction": "Clear"
}
}
],
"ImageAttachments": [
{
"Name": "OutputAttachment",
"SizeSource": {
"Source": {
"Pass": "This",
"Attachment": "ColorInput"
},
"Multipliers": {
"WidthMultiplier": 0.5,
"HeightMultiplier": 0.5
}
},
"ImageDescriptor": {
"Format": "R16G16B16A16_FLOAT"
}
}
],
"Connections": [
{
"LocalSlot": "OutputColorAndCoC",
"AttachmentRef": {
"Pass": "This",
"Attachment": "OutputAttachment"
}
}
],
"PassData": {
"$type": "FullscreenTrianglePassData",
"ShaderAsset": {
"FilePath": "Shaders/PostProcessing/NewDepthOfFieldDownsample.shader"
},
"PipelineViewTag": "MainCamera"
}
}
}
}
@@ -0,0 +1,62 @@
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "PassAsset",
"ClassData": {
"PassTemplate": {
"Name": "NewDepthOfFieldFilterLargeTemplate",
"PassClass": "NewDepthOfFieldFilterPass",
"Slots": [
{
"Name": "ColorAndCoc",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader",
"ShaderImageDimensionsConstant": "m_textureDimensions"
},
{
"Name": "CocTile",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "OutputColorAndCoc",
"SlotType": "Output",
"ScopeAttachmentUsage": "RenderTarget",
"LoadStoreAction": {
"LoadAction": "Clear"
}
}
],
"ImageAttachments": [
{
"Name": "OutputAttachment",
"SizeSource": {
"Source": {
"Pass": "This",
"Attachment": "ColorAndCoc"
}
},
"ImageDescriptor": {
"Format": "R16G16B16A16_FLOAT"
}
}
],
"Connections": [
{
"LocalSlot": "OutputColorAndCoc",
"AttachmentRef": {
"Pass": "This",
"Attachment": "OutputAttachment"
}
}
],
"PassData": {
"$type": "FullscreenTrianglePassData",
"ShaderAsset": {
"FilePath": "Shaders/PostProcessing/NewDepthOfFieldFilterLarge.shader"
},
"PipelineViewTag": "MainCamera"
}
}
}
}
@@ -0,0 +1,62 @@
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "PassAsset",
"ClassData": {
"PassTemplate": {
"Name": "NewDepthOfFieldFilterSmallTemplate",
"PassClass": "NewDepthOfFieldFilterPass",
"Slots": [
{
"Name": "ColorAndCoc",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader",
"ShaderImageDimensionsConstant": "m_textureDimensions"
},
{
"Name": "CocTile",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader"
},
{
"Name": "OutputColorAndCoc",
"SlotType": "Output",
"ScopeAttachmentUsage": "RenderTarget",
"LoadStoreAction": {
"LoadAction": "Clear"
}
}
],
"ImageAttachments": [
{
"Name": "OutputAttachment",
"SizeSource": {
"Source": {
"Pass": "This",
"Attachment": "ColorAndCoc"
}
},
"ImageDescriptor": {
"Format": "R16G16B16A16_FLOAT"
}
}
],
"Connections": [
{
"LocalSlot": "OutputColorAndCoc",
"AttachmentRef": {
"Pass": "This",
"Attachment": "OutputAttachment"
}
}
],
"PassData": {
"$type": "FullscreenTrianglePassData",
"ShaderAsset": {
"FilePath": "Shaders/PostProcessing/NewDepthOfFieldFilterSmall.shader"
},
"PipelineViewTag": "MainCamera"
}
}
}
}
@@ -0,0 +1,57 @@
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "PassAsset",
"ClassData": {
"PassTemplate": {
"Name": "NewDepthOfFieldTile3x3Template",
"PassClass": "FullScreenTriangle",
"Slots": [
{
"Name": "Input",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader",
"ShaderImageDimensionsConstant": "m_textureDimensions"
},
{
"Name": "Output",
"SlotType": "Output",
"ScopeAttachmentUsage": "RenderTarget",
"LoadStoreAction": {
"LoadAction": "Clear"
}
}
],
"ImageAttachments": [
{
"Name": "OutputAttachment",
"SizeSource": {
"Source": {
"Pass": "This",
"Attachment": "Input"
}
},
"ImageDescriptor": {
"Format": "R16G16_SNORM"
}
}
],
"Connections": [
{
"LocalSlot": "Output",
"AttachmentRef": {
"Pass": "This",
"Attachment": "OutputAttachment"
}
}
],
"PassData": {
"$type": "FullscreenTrianglePassData",
"ShaderAsset": {
"FilePath": "Shaders/PostProcessing/NewDepthOfFieldTile3x3.shader"
},
"PipelineViewTag": "MainCamera"
}
}
}
}
@@ -0,0 +1,63 @@
{
"Type": "JsonSerialization",
"Version": 1,
"ClassName": "PassAsset",
"ClassData": {
"PassTemplate": {
"Name": "NewDepthOfFieldTileReduceTemplate",
"PassClass": "NewDepthOfFieldTileReducePass",
"Slots": [
{
"Name": "ColorAndCocInput",
"SlotType": "Input",
"ScopeAttachmentUsage": "Shader",
"ShaderImageDimensionsConstant": "m_inputDimensions"
},
{
"Name": "MinMaxCoC",
"SlotType": "Output",
"ScopeAttachmentUsage": "Shader",
"ShaderImageDimensionsConstant": "m_outputDimensions",
"LoadStoreAction": {
"LoadAction": "Clear"
}
}
],
"ImageAttachments": [
{
"Name": "MinMaxCoCAttachment",
"SizeSource": {
"Source": {
"Pass": "This",
"Attachment": "ColorAndCocInput"
},
"Multipliers": {
// 1/16 = 0.0625
"WidthMultiplier": 0.0625,
"HeightMultiplier": 0.0625
}
},
"ImageDescriptor": {
"Format": "R16G16_SNORM"
}
}
],
"Connections": [
{
"LocalSlot": "MinMaxCoC",
"AttachmentRef": {
"Pass": "This",
"Attachment": "MinMaxCoCAttachment"
}
}
],
"PassData": {
"$type": "ComputePassData",
"ShaderAsset": {
"FilePath": "Shaders/PostProcessing/NewDepthOfFieldTileReduce.shader"
},
"PipelineViewTag": "MainCamera"
}
}
}
}
@@ -185,6 +185,34 @@
"Path": "Passes/DepthOfFieldWriteFocusDepthFromGpu.pass"
},
{
"Name": "NewDepthOfFieldTemplate",
"Path": "Passes/NewDepthOfField.pass"
},
{
"Name": "NewDepthOfFieldDownsampleTemplate",
"Path": "Passes/NewDepthOfFieldDownsample.pass"
},
{
"Name": "NewDepthOfFieldTileReduceTemplate",
"Path": "Passes/NewDepthOfFieldTileReduce.pass"
},
{
"Name": "NewDepthOfFieldTile3x3Template",
"Path": "Passes/NewDepthOfFieldTile3x3.pass"
},
{
"Name": "NewDepthOfFieldFilterLargeTemplate",
"Path": "Passes/NewDepthOfFieldFilterLarge.pass"
},
{
"Name": "NewDepthOfFieldFilterSmallTemplate",
"Path": "Passes/NewDepthOfFieldFilterSmall.pass"
},
{
"Name": "NewDepthOfFieldCompositeTemplate",
"Path": "Passes/NewDepthOfFieldComposite.pass"
},
{
"Name": "EsmShadowmapsTemplate",
"Path": "Passes/EsmShadowmaps.pass"
},
@@ -112,20 +112,41 @@
}
]
},
//{
// "Name": "DepthOfFieldPass",
// "TemplateName": "DepthOfFieldTemplate",
// "Enabled": true,
// "Connections": [
// {
// "LocalSlot": "DoFColorInput",
// "AttachmentRef": {
// "Pass": "TaaPass",
// "Attachment": "OutputColor"
// }
// },
// {
// "LocalSlot": "DoFDepthInput",
// "AttachmentRef": {
// "Pass": "Parent",
// "Attachment": "Depth"
// }
// }
// ]
//},
{
"Name": "DepthOfFieldPass",
"TemplateName": "DepthOfFieldTemplate",
"TemplateName": "NewDepthOfFieldTemplate",
"Enabled": true,
"Connections": [
{
"LocalSlot": "DoFColorInput",
"LocalSlot": "LightingBuffer",
"AttachmentRef": {
"Pass": "TaaPass",
"Attachment": "OutputColor"
}
},
{
"LocalSlot": "DoFDepthInput",
"LocalSlot": "Depth",
"AttachmentRef": {
"Pass": "Parent",
"Attachment": "Depth"
@@ -142,7 +163,7 @@
"LocalSlot": "InputOutput",
"AttachmentRef": {
"Pass": "DepthOfFieldPass",
"Attachment": "DoFOutput"
"Attachment": "LightingBuffer"
}
}
]
@@ -14,6 +14,14 @@ inline float InvertDepth(float depth)
return 1.0f - depth;
}
inline float4 InvertDepth(float4 depth)
{
// Convert depth from [1.0 - 0.0] to [0.0 - 1.0].
// Set the front(near side) to 0.0 and the back(far side) to 1.0.
return float4(1, 1, 1, 1) - depth;
}
inline float ConvertDofFactor(float depth, float far, float near, float focusDistance)
{
// dofFactor : The value Calculated from depth.
@@ -0,0 +1,29 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <viewsrg.srgi>
#define COC_EPSILON 0.0001
#define SAMPLES_LOOP_1 8
#define SAMPLES_LOOP_2 16
#define SAMPLES_LOOP_3 24
// Must match the struct in NewDepthOfFieldPasses.cpp
struct NewDepthOfFieldConstants
{
float4 samplePositions[60]; // XY are sample positions (normalized so max lenght is 1)
// Z is the length of XY (0 - 1)
// W is unused
};
@@ -0,0 +1,80 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Atom/Features/PostProcessing/FullscreenPixelInfo.azsli>
#include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
#include <Atom/RPI/Math.azsli>
#include "NewDepthOfFieldCommon.azsli"
#include "DepthOfField.azsli"
#include <viewsrg.srgi>
#define COC_EPSILON 0.0001
ShaderResourceGroup PassSrg : SRG_PerPass
{
Texture2D<float4> m_depth;
Texture2D<float4> m_halfResColorAndCoc;
// Texture dimensions. XY channels are width and height and ZW channels are 1 / width and 1 / height
float4 m_fullResDimensions;
float4 m_halfResDimensions;
Sampler LinearSampler
{
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
AddressW = Clamp;
};
}
PSOutput MainPS(VSOutput IN)
{
// Sampling positions
float2 fullResPixelPos = IN.m_position.xy;
float2 halfResPixelPos = fullResPixelPos * 0.5f;
float2 fullResUV = fullResPixelPos * PassSrg::m_fullResDimensions.zw;
float2 halfResUV = halfResPixelPos * PassSrg::m_halfResDimensions.zw;
// Full res CoC (Circle of Confusion)
float depth = PassSrg::m_depth.Sample(PassSrg::LinearSampler, fullResUV);
float far = ViewSrg::m_dof.m_cameraParameters.x;
float near = ViewSrg::m_dof.m_cameraParameters.y;
float focusDistance = ViewSrg::m_dof.m_cameraParameters.z;
float coc = ConvertDofFactor(InvertDepth(depth), far, near, focusDistance);
// Calculate Alpha
float cocRadius = abs(coc) * ViewSrg::m_dof.m_cocToScreenRatio * 0.5f;
float maxPixelDist = max(PassSrg::m_halfResDimensions.z, PassSrg::m_halfResDimensions.w);
float alpha = saturate(0.25f * cocRadius / maxPixelDist);
// Sample half res color and CoC
float4 colorAndCoC = PassSrg::m_halfResColorAndCoc.Sample(PassSrg::LinearSampler, halfResUV);
// Make out of focus foreground increasingly blue
float multiplier = saturate(1.0f + coc);
colorAndCoC.r *= multiplier;
colorAndCoC.g *= multiplier;
// Make out of focus background increasingly red
multiplier = saturate(1.0f - coc);
colorAndCoC.b *= multiplier;
colorAndCoC.g *= multiplier;
// Output
PSOutput OUT;
OUT.m_color.rgb = colorAndCoC.rgb;
OUT.m_color.a = alpha;
return OUT;
}
@@ -0,0 +1,31 @@
{
"Source" : "NewDepthOfFieldComposite",
"DepthStencilState" :
{
"Depth" : { "Enable" : false },
"Stencil" : { "Enable" : false }
},
"BlendState" : {
"Enable" : true,
"BlendSource" : "AlphaSource",
"BlendDest" : "AlphaSourceInverse",
"BlendOp" : "Add"
},
"ProgramSettings":
{
"EntryPoints":
[
{
"name": "MainVS",
"type": "Vertex"
},
{
"name": "MainPS",
"type": "Fragment"
}
]
}
}
@@ -0,0 +1,100 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Atom/Features/PostProcessing/FullscreenPixelInfo.azsli>
#include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
#include <Atom/RPI/Math.azsli>
#include "NewDepthOfFieldCommon.azsli"
#include "DepthOfField.azsli"
#include <viewsrg.srgi>
#define COC_EPSILON 0.0001
ShaderResourceGroup PassSrg : SRG_PerPass
{
Texture2D<float4> m_colorTexture;
Texture2D<float4> m_depth;
// Texture dimensions. XY channels are width and height and ZW channels are 1 / width and 1 / height
float4 m_inputDimensions;
float4 m_outputDimensions;
Sampler PointSampler
{
MinFilter = Point;
MagFilter = Point;
MipFilter = Point;
AddressU = Clamp;
AddressV = Clamp;
AddressW = Clamp;
};
}
PSOutput MainPS(VSOutput IN)
{
// Sampling positions
float2 outputPixelPos = IN.m_position.xy;
float2 inputPixelPos = outputPixelPos * 2.0f;
float2 inputUV = inputPixelPos * PassSrg::m_inputDimensions.zw;
// Gather Depth
float4 depthGather = PassSrg::m_depth.Gather(PassSrg::PointSampler, inputUV);
depthGather = InvertDepth(depthGather);
// Calculate CoC (Circle of Confusion)
float far = ViewSrg::m_dof.m_cameraParameters.x;
float near = ViewSrg::m_dof.m_cameraParameters.y;
float focusDistance = ViewSrg::m_dof.m_cameraParameters.z;
float4 cocGather;
cocGather.x = ConvertDofFactor(depthGather.x, far, near, focusDistance);
cocGather.y = ConvertDofFactor(depthGather.y, far, near, focusDistance);
cocGather.z = ConvertDofFactor(depthGather.z, far, near, focusDistance);
cocGather.w = ConvertDofFactor(depthGather.w, far, near, focusDistance);
// Clamp CoC
cocGather = clamp(cocGather, -1.0f, 1.0f);
// Weigh samles by CoC to avoid in foces pixels bleeding into bokeh effect
float4 weights = abs(cocGather) + COC_EPSILON;
weights = weights / (weights.x + weights.y + weights.z + weights.w);
PSOutput OUT;
// Red
float4 redGather = PassSrg::m_colorTexture.GatherRed(PassSrg::PointSampler, inputUV);
OUT.m_color.r = dot(redGather, weights);
// Green
float4 greenGather = PassSrg::m_colorTexture.GatherGreen(PassSrg::PointSampler, inputUV);
OUT.m_color.g = dot(greenGather, weights);
// Blue
float4 blueGather = PassSrg::m_colorTexture.GatherBlue(PassSrg::PointSampler, inputUV);
OUT.m_color.b = dot(blueGather, weights);
// CoC - Take the CoC with the maximum absolute value (note CoC can be negative) to get the fullest bokeh effect
// The above weighting by CoC mitigates bokeh bleeding from taking the max CoC
float coc = cocGather.x;
coc = abs(coc) < abs(cocGather.y) ? cocGather.y : coc;
coc = abs(coc) < abs(cocGather.z) ? cocGather.z : coc;
coc = abs(coc) < abs(cocGather.w) ? cocGather.w : coc;
// CoC weighting #2: we use linear sampling when we compute the CoC blur
// This can lead to in focus pixels bleeding into the bokeh blur
// Pre-multiply the color values by the CoC to avoid this type of bleeding
// Because we then re-multiply by the CoC value after the linear sampling, we want to avoid coc values of 0
// See http://advances.realtimerendering.com/s2013/Sousa_Graphics_Gems_CryENGINE3.pptx
coc = abs(coc) > COC_EPSILON ? coc : -COC_EPSILON;
OUT.m_color.rgb *= abs(coc);
OUT.m_color.a = coc;
return OUT;
}
@@ -0,0 +1,22 @@
{
"Source" : "NewDepthOfFieldDownsample",
"DepthStencilState" : {
"Depth" : { "Enable" : false }
},
"ProgramSettings":
{
"EntryPoints":
[
{
"name": "MainVS",
"type": "Vertex"
},
{
"name": "MainPS",
"type": "Fragment"
}
]
}
}
@@ -0,0 +1,50 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Atom/Features/PostProcessing/FullscreenPixelInfo.azsli>
#include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
#include "DepthOfField.azsli"
#include "NewDepthOfFieldCommon.azsli"
#include <viewsrg.srgi>
ShaderResourceGroup PassSrg : SRG_PerPass
{
Texture2D<float4> m_colorAndCoc;
Texture2D<float2> m_minMaxCocTile;
float4 m_textureDimensions;
NewDepthOfFieldConstants m_dofConstants;
Sampler LinearSampler
{
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
AddressW = Clamp;
};
}
PSOutput MainPS(VSOutput IN)
{
PSOutput OUT = (PSOutput)0;
float4 centerSample = PassSrg::m_colorAndCoc.Sample(PassSrg::LinearSampler, IN.m_texCoord);
float3 centerColor = centerSample.rgb;
float centerCoc = centerSample.a;
centerColor /= centerCoc;
OUT.m_color.rgb = centerColor;
OUT.m_color.a = centerCoc;
return OUT;
}
@@ -0,0 +1,22 @@
{
"Source" : "NewDepthOfFieldFilterLarge",
"DepthStencilState" : {
"Depth" : { "Enable" : false }
},
"ProgramSettings":
{
"EntryPoints":
[
{
"name": "MainVS",
"type": "Vertex"
},
{
"name": "MainPS",
"type": "Fragment"
}
]
}
}
@@ -0,0 +1,74 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Atom/Features/PostProcessing/FullscreenPixelInfo.azsli>
#include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
#include "DepthOfField.azsli"
#include "NewDepthOfFieldCommon.azsli"
#include <viewsrg.srgi>
ShaderResourceGroup PassSrg : SRG_PerPass
{
Texture2D<float4> m_colorAndCoc;
Texture2D<float2> m_minMaxCocTile;
float4 m_textureDimensions;
NewDepthOfFieldConstants m_dofConstants;
Sampler LinearSampler
{
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
AddressW = Clamp;
};
}
float2 GetOffsetUV(uint index, float radiusMultiplier)
{
return PassSrg::m_dofConstants.samplePositions[index] * radiusMultiplier * PassSrg::m_textureDimensions.zw;
}
PSOutput MainPS(VSOutput IN)
{
// UV of pixel being shaded
float2 pixelUV = IN.m_texCoord.xy;
// Sample pixel being shaded
float4 centerSample = PassSrg::m_colorAndCoc.Sample(PassSrg::LinearSampler, pixelUV).rgba;
float centerCoc = centerSample.a;
// Color and weight accumulation
float3 color = centerSample.rgb;
float totalWeight = 1;
// Sampling radius
float cocRadius = abs(centerCoc) * ViewSrg::m_dof.m_cocToScreenRatio * 0.5f;
cocRadius *= 0.5f; // This is the small filter, half the sampling radius
for(uint i = 0; i < SAMPLES_LOOP_1; ++i)
{
float2 offsetUV = GetOffsetUV(i, cocRadius);
float4 sample = PassSrg::m_colorAndCoc.Sample(PassSrg::LinearSampler, pixelUV + offsetUV).rgba;
float cocDiff = abs(sample.a - centerCoC);
float weight = saturate( 2 - (20 * cocDiff));
color += sample.rgb * weight;
totalWeight += weight;
}
// Output
PSOutput OUT;
OUT.m_color.rgb = color / totalWeight;
OUT.m_color.a = centerCoc;
return OUT;
}
@@ -0,0 +1,22 @@
{
"Source" : "NewDepthOfFieldFilterSmall",
"DepthStencilState" : {
"Depth" : { "Enable" : false }
},
"ProgramSettings":
{
"EntryPoints":
[
{
"name": "MainVS",
"type": "Vertex"
},
{
"name": "MainPS",
"type": "Fragment"
}
]
}
}
@@ -0,0 +1,66 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Atom/Features/SrgSemantics.azsli>
#include <Atom/Features/PostProcessing/FullscreenVertex.azsli>
#include "NewDepthOfFieldCommon.azsli"
ShaderResourceGroup PassSrg : SRG_PerPass
{
Texture2D<float2> m_minMaxSource;
// Texture dimensions. XY channels are width and height and ZW channels are 1 / width and 1 / height
float4 m_textureDimensions;
Sampler PointSampler
{
MinFilter = Point;
MagFilter = Point;
MipFilter = Point;
AddressU = Clamp;
AddressV = Clamp;
AddressW = Clamp;
};
}
struct PSOutput
{
float2 m_color : SV_Target0;
};
PSOutput MainPS(VSOutput IN)
{
// We want the min/max in a 3x3 region. Start sampling up left.
float2 startPixelPos = IN.m_position.xy - float2(1, 1);
float2 stepSize = PassSrg::m_textureDimensions.zw;
float2 startUV = startPixelPos * stepSize;
float cocMin = 1.0f;
float cocMax = -1.0f;
// Gather min/max in 3x3 region
[unroll]
for(float Y = 0.0f; Y < 3.0f; Y += 1.0f)
{
[unroll]
for(float X = 0.0f; X < 3.0f; X += 1.0f)
{
float2 sampleUV = mad(float2(X, Y), stepSize, startUV);
float2 minMax = PassSrg::m_minMaxSource.SampleLevel(PassSrg::PointSampler, sampleUV, 0).xy;
cocMin = min(cocMin, minMax.x);
cocMax = max(cocMax, minMax.y);
}
}
PSOutput output;
output.m_color.x = cocMin;
output.m_color.y = cocMax;
return output;
}
@@ -0,0 +1,22 @@
{
"Source" : "NewDepthOfFieldTile3x3",
"DepthStencilState" : {
"Depth" : { "Enable" : false }
},
"ProgramSettings":
{
"EntryPoints":
[
{
"name": "MainVS",
"type": "Vertex"
},
{
"name": "MainPS",
"type": "Fragment"
}
]
}
}
@@ -0,0 +1,83 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <Atom/Features/SrgSemantics.azsli>
#include <Atom/RPI/Math.azsli>
#include "NewDepthOfFieldCommon.azsli"
ShaderResourceGroup PassSrg : SRG_PerPass
{
// For this shader we're only interested in the CoC values, which are in the alpha channel
Texture2D<float4> m_colorAndCoC;
// Tiled min/max CoC values
RWTexture2D<float2> m_minMaxCoC;
// Texture dimensions. XY channels are width and height and ZW channels are 1 / width and 1 / height
float4 m_inputDimensions;
float4 m_outputDimensions;
Sampler LinearSampler
{
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
AddressW = Clamp;
};
}
groupshared uint LDS_MIN_COC[8];
groupshared uint LDS_MAX_COC[8];
[numthreads(8, 8, 1)]
void MainCS(uint3 group_thread_id : SV_GroupThreadID, uint3 group_id : SV_GroupID, uint3 dispatch_id: SV_DispatchThreadID, uint linear_id : SV_GroupIndex)
{
// Initialize groupshared mem for atomic min/max operations
if(group_thread_id.y == 0)
{
LDS_MIN_COC[group_thread_id.x] = 0xFFFFFFFF;
LDS_MAX_COC[group_thread_id.x] = 0;
}
// We use gather to get 2x2 values at once, so thread samples are spaced 2 pixels apart (+1 so the sample position is in between the four pixels)
float2 samplePos = float2(dispatch_id.xy) * 2 + float2(1, 1);
float2 sampleUV = samplePos * PassSrg::m_inputDimensions.zw;
// Gather CoC
float4 cocGather = PassSrg::m_colorAndCoC.GatherAlpha(PassSrg::LinearSampler, sampleUV);
float cocMin = min4(cocGather);
float cocMax = max4(cocGather);
// For atomic min/max to work with uints, floating point values should be positive
// Map from [-1, 1] range to [0, 2] and cast as uint
InterlockedMin( LDS_MIN_COC[group_thread_id.x], asuint(cocMin + 1) );
InterlockedMax( LDS_MAX_COC[group_thread_id.x], asuint(cocMax + 1) );
// Sync LDS
GroupMemoryBarrierWithGroupSync();
if(group_thread_id.y != 0)
{
return;
}
InterlockedMin( LDS_MIN_COC[0], LDS_MIN_COC[group_thread_id.x] );
InterlockedMax( LDS_MAX_COC[0], LDS_MAX_COC[group_thread_id.x] );
if(group_thread_id.x == 0)
{
// Unpack uints
cocMin = asfloat(LDS_MIN_COC[0]) - 1;
cocMax = asfloat(LDS_MAX_COC[0]) - 1;
// Output min/max coc of 16x16 region
PassSrg::m_minMaxCoC[group_id.xy] = float2(cocMin, cocMax);
}
}
@@ -0,0 +1,14 @@
{
"Source" : "NewDepthOfFieldTileReduce",
"ProgramSettings" :
{
"EntryPoints":
[
{
"name" : "MainCS",
"type" : "Compute"
}
]
}
}
@@ -1,9 +1,8 @@
#
# Copyright (c) Contributors to the Open 3D Engine Project.
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
# Copyright (c) Contributors to the Open 3D Engine Project.
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
set(FILES
@@ -86,7 +85,6 @@ set(FILES
Passes/CascadedShadowmaps.pass
Passes/CheckerboardResolveColor.pass
Passes/CheckerboardResolveDepth.pass
Passes/HDRColorGrading.pass
Passes/ContrastAdaptiveSharpening.pass
Passes/ConvertToAcescg.pass
Passes/DebugOverlayParent.pass
@@ -144,6 +142,7 @@ set(FILES
Passes/ForwardSubsurfaceMSAA.pass
Passes/FullscreenCopy.pass
Passes/FullscreenOutputOnly.pass
Passes/HDRColorGrading.pass
Passes/ImGui.pass
Passes/KawaseShadowBlur.pass
Passes/LightAdaptationParent.pass
@@ -160,8 +159,6 @@ set(FILES
Passes/LuminanceHistogramGenerator.pass
Passes/MainPipeline.pass
Passes/MainPipelineRenderToTexture.pass
Passes/ThumbnailPipeline.pass
Passes/ThumbnailPipelineRenderToTexture.pass
Passes/MeshMotionVector.pass
Passes/ModulateTexture.pass
Passes/MorphTarget.pass
@@ -169,6 +166,13 @@ set(FILES
Passes/MSAAResolveColor.pass
Passes/MSAAResolveCustom.pass
Passes/MSAAResolveDepth.pass
Passes/NewDepthOfField.pass
Passes/NewDepthOfFieldComposite.pass
Passes/NewDepthOfFieldDownsample.pass
Passes/NewDepthOfFieldFilterLarge.pass
Passes/NewDepthOfFieldFilterSmall.pass
Passes/NewDepthOfFieldTile3x3.pass
Passes/NewDepthOfFieldTileReduce.pass
Passes/OpaqueParent.pass
Passes/PostProcessParent.pass
Passes/ProjectedShadowmaps.pass
@@ -204,11 +208,17 @@ set(FILES
Passes/SsaoParent.pass
Passes/SubsurfaceScattering.pass
Passes/Taa.pass
Passes/ThumbnailPipeline.pass
Passes/ThumbnailPipelineRenderToTexture.pass
Passes/Transparent.pass
Passes/TransparentParent.pass
Passes/UI.pass
Passes/UIParent.pass
Scripts/material_find_overrides_demo.lua
Scripts/material_property_overrides_demo.lua
ShaderLib/3rdParty/Features/PostProcessing/KelvinToRgb.azsli
ShaderLib/3rdParty/Features/PostProcessing/PSstyleColorBlends_NonSeparable.azsli
ShaderLib/3rdParty/Features/PostProcessing/PSstyleColorBlends_Separable.azsli
ShaderLib/Atom/Features/BlendUtility.azsli
ShaderLib/Atom/Features/IndirectRendering.azsli
ShaderLib/Atom/Features/MatrixUtility.azsli
@@ -217,6 +227,8 @@ set(FILES
ShaderLib/Atom/Features/SphericalHarmonicsUtility.azsli
ShaderLib/Atom/Features/SrgSemantics.azsli
ShaderLib/Atom/Features/ColorManagement/TransformColor.azsli
ShaderLib/Atom/Features/ColorManagement/GeneratedTransforms/AcesCcToAcesCg.azsli
ShaderLib/Atom/Features/ColorManagement/GeneratedTransforms/AcesCgToAcesCc.azsli
ShaderLib/Atom/Features/ColorManagement/GeneratedTransforms/AcesCg_To_LinearSrgb.azsli
ShaderLib/Atom/Features/ColorManagement/GeneratedTransforms/Aces_To_AcesCg.azsli
ShaderLib/Atom/Features/ColorManagement/GeneratedTransforms/CalculateLuminance_AcesCg.azsli
@@ -224,8 +236,6 @@ set(FILES
ShaderLib/Atom/Features/ColorManagement/GeneratedTransforms/LinearSrgb_To_AcesCg.azsli
ShaderLib/Atom/Features/ColorManagement/GeneratedTransforms/LinearSrgb_To_Srgb.azsli
ShaderLib/Atom/Features/ColorManagement/GeneratedTransforms/Srgb_To_LinearSrgb.azsli
ShaderLib/Atom/Features/ColorManagement/GeneratedTransforms/AcesCcToAcesCg.azsli
ShaderLib/Atom/Features/ColorManagement/GeneratedTransforms/AcesCgToAcesCc.azsli
ShaderLib/Atom/Features/CoreLights/PhotometricValue.azsli
ShaderLib/Atom/Features/Decals/DecalTextureUtil.azsli
ShaderLib/Atom/Features/LightCulling/LightCullingShared.azsli
@@ -282,18 +292,23 @@ set(FILES
ShaderLib/Atom/Features/PostProcessing/GlyphData.azsli
ShaderLib/Atom/Features/PostProcessing/GlyphRender.azsli
ShaderLib/Atom/Features/PostProcessing/PostProcessUtil.azsli
ShaderLib/Atom/Features/PostProcessing/Shapers.azsli
ShaderLib/Atom/Features/RayTracing/RayTracingMaterialSrg.azsli
ShaderLib/Atom/Features/RayTracing/RayTracingMaterialUtils.azsli
ShaderLib/Atom/Features/RayTracing/RayTracingSceneSrg.azsli
ShaderLib/Atom/Features/RayTracing/RayTracingSceneUtils.azsli
ShaderLib/Atom/Features/RayTracing/RayTracingSrgs.azsl
ShaderLib/Atom/Features/RayTracing/RayTracingSrgs.shader
ShaderLib/Atom/Features/ScreenSpace/ScreenSpaceUtil.azsli
ShaderLib/Atom/Features/Shadow/BicubicPcfFilters.azsli
ShaderLib/Atom/Features/Shadow/DirectionalLightShadow.azsli
ShaderLib/Atom/Features/Shadow/JitterTablePcf.azsli
ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli
ShaderLib/Atom/Features/Shadow/ReceiverPlaneDepthBias.azsli
ShaderLib/Atom/Features/Shadow/Shadow.azsli
ShaderLib/Atom/Features/Shadow/ShadowmapAtlasLib.azsli
ShaderLib/Atom/Features/Skin/SkinObjectSrg.azsli
ShaderLib/Atom/Features/Vertex/VertexHelper.azsli
ShaderLib/3rdParty/Features/PostProcessing/KelvinToRgb.azsli
ShaderLib/3rdParty/Features/PostProcessing/PSstyleColorBlends_NonSeparable.azsli
ShaderLib/3rdParty/Features/PostProcessing/PSstyleColorBlends_Separable.azsli
ShaderResourceGroups/SceneSrg.azsli
ShaderResourceGroups/SceneSrgAll.azsli
ShaderResourceGroups/ViewSrg.azsli
@@ -304,6 +319,8 @@ set(FILES
ShaderResourceGroups/PostProcessing/SceneSrg.azsli
ShaderResourceGroups/PostProcessing/ViewSrg.azsli
ShaderResourceGroups/SkyBox/SceneSrg.azsli
Shaders/ForwardPassSrg.azsl
Shaders/ForwardPassSrg.shader
Shaders/AuxGeom/AuxGeomObject.azsl
Shaders/AuxGeom/AuxGeomObject.shader
Shaders/AuxGeom/AuxGeomObjectLit.azsl
@@ -318,14 +335,20 @@ set(FILES
Shaders/Checkerboard/CheckerboardColorResolveCS.shader
Shaders/Depth/DepthPass.azsl
Shaders/Depth/DepthPass.shader
Shaders/Depth/DepthPassCommon.azsli
Shaders/Depth/DepthPassSkin.azsl
Shaders/Depth/DepthPassSkin.shader
Shaders/Depth/DepthPassTransparentMax.shader
Shaders/Depth/DepthPassTransparentMin.shader
Shaders/DiffuseGlobalIllumination/DiffuseComposite.azsl
Shaders/DiffuseGlobalIllumination/DiffuseComposite.shader
Shaders/DiffuseGlobalIllumination/DiffuseComposite_nomsaa.azsl
Shaders/DiffuseGlobalIllumination/DiffuseGlobalFullscreen.azsl
Shaders/DiffuseGlobalIllumination/DiffuseGlobalFullscreen.shader
Shaders/DiffuseGlobalIllumination/DiffuseGlobalFullscreen_nomsaa.azsl
Shaders/DiffuseGlobalIllumination/DiffuseProbeGridDownsample.azsl
Shaders/DiffuseGlobalIllumination/DiffuseProbeGridDownsample.shader
Shaders/DiffuseGlobalIllumination/DiffuseProbeGridDownsample_nomsaa.azsl
Shaders/ImGui/ImGui.azsl
Shaders/ImGui/ImGui.shader
Shaders/LightCulling/LightCulling.azsl
@@ -345,6 +368,9 @@ set(FILES
Shaders/MotionVector/CameraMotionVector.shader
Shaders/MotionVector/MeshMotionVector.azsl
Shaders/MotionVector/MeshMotionVector.shader
Shaders/MotionVector/MeshMotionVectorCommon.azsli
Shaders/MotionVector/MeshMotionVectorSkin.azsl
Shaders/MotionVector/MeshMotionVectorSkin.shader
Shaders/PostProcessing/AcesOutputTransformLut.azsl
Shaders/PostProcessing/AcesOutputTransformLut.shader
Shaders/PostProcessing/ApplyShaperLookupTable.azsl
@@ -359,6 +385,8 @@ set(FILES
Shaders/PostProcessing/BloomCompositeCS.shader
Shaders/PostProcessing/BloomDownsampleCS.azsl
Shaders/PostProcessing/BloomDownsampleCS.shader
Shaders/PostProcessing/ContrastAdaptiveSharpening.azsl
Shaders/PostProcessing/ContrastAdaptiveSharpening.shader
Shaders/PostProcessing/ConvertToAcescg.azsl
Shaders/PostProcessing/ConvertToAcescg.shader
Shaders/PostProcessing/DepthDownsample.azsl
@@ -415,6 +443,18 @@ set(FILES
Shaders/PostProcessing/MSAAResolveCustom.shader
Shaders/PostProcessing/MSAAResolveDepth.azsl
Shaders/PostProcessing/MSAAResolveDepth.shader
Shaders/PostProcessing/NewDepthOfFieldComposite.azsl
Shaders/PostProcessing/NewDepthOfFieldComposite.shader
Shaders/PostProcessing/NewDepthOfFieldDownsample.azsl
Shaders/PostProcessing/NewDepthOfFieldDownsample.shader
Shaders/PostProcessing/NewDepthOfFieldFilterLarge.azsl
Shaders/PostProcessing/NewDepthOfFieldFilterLarge.shader
Shaders/PostProcessing/NewDepthOfFieldFilterSmall.azsl
Shaders/PostProcessing/NewDepthOfFieldFilterSmall.shader
Shaders/PostProcessing/NewDepthOfFieldTile3x3.azsl
Shaders/PostProcessing/NewDepthOfFieldTile3x3.shader
Shaders/PostProcessing/NewDepthOfFieldTileReduce.azsl
Shaders/PostProcessing/NewDepthOfFieldTileReduce.shader
Shaders/PostProcessing/OutputTransform.azsl
Shaders/PostProcessing/OutputTransform.shader
Shaders/PostProcessing/ScreenSpaceSubsurfaceScatteringCS.azsl
@@ -431,13 +471,17 @@ set(FILES
Shaders/PostProcessing/SMAAUtils.azsli
Shaders/PostProcessing/SsaoCompute.azsl
Shaders/PostProcessing/SsaoCompute.shader
Shaders/PostProcessing/Taa.azsl
Shaders/PostProcessing/Taa.shader
Shaders/PostProcessing/UniformColor.azsl
Shaders/PostProcessing/UniformColor.shader
Shaders/Reflections/ReflectionCommon.azsli
Shaders/Reflections/ReflectionComposite.azsl
Shaders/Reflections/ReflectionComposite.shader
Shaders/Reflections/ReflectionComposite_nomsaa.azsl
Shaders/Reflections/ReflectionGlobalFullscreen.azsl
Shaders/Reflections/ReflectionGlobalFullscreen.shader
Shaders/Reflections/ReflectionGlobalFullscreen_nomsaa.azsl
Shaders/Reflections/ReflectionProbeBlendWeight.azsl
Shaders/Reflections/ReflectionProbeBlendWeight.shader
Shaders/Reflections/ReflectionProbeRenderCommon.azsli
@@ -466,6 +510,9 @@ set(FILES
Shaders/Shadow/KawaseShadowBlur.shader
Shaders/Shadow/Shadowmap.azsl
Shaders/Shadow/Shadowmap.shader
Shaders/Shadow/ShadowmapCommon.azsli
Shaders/Shadow/ShadowmapSkin.azsl
Shaders/Shadow/ShadowmapSkin.shader
Shaders/SkinnedMesh/LinearSkinningCS.azsl
Shaders/SkinnedMesh/LinearSkinningCS.shader
Shaders/SkinnedMesh/LinearSkinningPassSRG.azsli
@@ -50,6 +50,7 @@
#include <PostProcessing/DepthOfFieldParentPass.h>
#include <PostProcessing/DepthOfFieldReadBackFocusDepthPass.h>
#include <PostProcessing/DepthOfFieldWriteFocusDepthFromGpuPass.h>
#include <PostProcessing/NewDepthOfFieldPasses.h>
#include <PostProcessing/EyeAdaptationPass.h>
#include <PostProcessing/LuminanceHistogramGeneratorPass.h>
#include <PostProcessing/FastDepthAwareBlurPasses.h>
@@ -248,6 +249,14 @@ namespace AZ
passSystem->AddPassCreator(Name("DepthOfFieldReadBackFocusDepthPass"), &DepthOfFieldReadBackFocusDepthPass::Create);
passSystem->AddPassCreator(Name("DepthOfFieldWriteFocusDepthFromGpuPass"), &DepthOfFieldWriteFocusDepthFromGpuPass::Create);
passSystem->AddPassCreator(Name("NewDepthOfFieldParentPass"), &NewDepthOfFieldParentPass::Create);
passSystem->AddPassCreator(Name("NewDepthOfFieldTileReducePass"), &NewDepthOfFieldTileReducePass::Create);
passSystem->AddPassCreator(Name("NewDepthOfFieldFilterPass"), &NewDepthOfFieldFilterPass::Create);
passSystem->AddPassCreator(Name("NewDepthOfFieldCompositePass"), &NewDepthOfFieldCompositePass::Create);
// Add FastDepthAwareBlur passes
passSystem->AddPassCreator(Name("FastDepthAwareBlurHorPass"), &FastDepthAwareBlurHorPass::Create);
passSystem->AddPassCreator(Name("FastDepthAwareBlurVerPass"), &FastDepthAwareBlurVerPass::Create);
@@ -0,0 +1,196 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Math/MathUtils.h>
#include <PostProcess/PostProcessFeatureProcessor.h>
#include <PostProcess/DepthOfField/DepthOfFieldSettings.h>
#include <PostProcessing/NewDepthOfFieldPasses.h>
#include <Atom/RPI.Public/RenderPipeline.h>
#include <Atom/RPI.Public/Scene.h>
#include <Atom/RPI.Public/View.h>
namespace AZ
{
namespace Render
{
// Must match the struct in NewDepthOfFieldCommon.azsli
struct NewDepthOfFieldConstants
{
static constexpr uint32_t numberOfLoops = 3;
static constexpr float loopCounts[] = { 8.0f, 16.0f, 24.0f };
AZStd::array<float[4], 60> m_samplePositions; // XY are sample positions (normalized so max lenght is 1)
// Z is the length of XY (0 - 1)
// W is unused
};
// --- Depth of Field Parent Pass ---
RPI::Ptr<NewDepthOfFieldParentPass> NewDepthOfFieldParentPass::Create(const RPI::PassDescriptor& descriptor)
{
RPI::Ptr<NewDepthOfFieldParentPass> pass = aznew NewDepthOfFieldParentPass(descriptor);
return AZStd::move(pass);
}
NewDepthOfFieldParentPass::NewDepthOfFieldParentPass(const RPI::PassDescriptor& descriptor)
: RPI::ParentPass(descriptor)
{ }
bool NewDepthOfFieldParentPass::IsEnabled() const
{
if (!ParentPass::IsEnabled())
{
return false;
}
RPI::Scene* scene = GetScene();
if (!scene)
{
return false;
}
PostProcessFeatureProcessor* fp = scene->GetFeatureProcessor<PostProcessFeatureProcessor>();
AZ::RPI::ViewPtr view = GetRenderPipeline()->GetDefaultView();
if (!fp)
{
return false;
}
PostProcessSettings* postProcessSettings = fp->GetLevelSettingsFromView(view);
if (!postProcessSettings)
{
return false;
}
DepthOfFieldSettings* dofSettings = postProcessSettings->GetDepthOfFieldSettings();
return (dofSettings != nullptr) && dofSettings->GetEnabled();
}
void NewDepthOfFieldParentPass::FrameBeginInternal(FramePrepareParams params)
{
RPI::Scene* scene = GetScene();
PostProcessFeatureProcessor* fp = scene->GetFeatureProcessor<PostProcessFeatureProcessor>();
AZ::RPI::ViewPtr view = GetRenderPipeline()->GetDefaultView();
if (fp)
{
PostProcessSettings* postProcessSettings = fp->GetLevelSettingsFromView(view);
if (postProcessSettings)
{
DepthOfFieldSettings* dofSettings = postProcessSettings->GetDepthOfFieldSettings();
if (dofSettings)
{
dofSettings->SetValuesToViewSrg(view->GetShaderResourceGroup());
}
}
}
ParentPass::FrameBeginInternal(params);
}
// --- Tile Reduce Pass ---
RPI::Ptr<NewDepthOfFieldTileReducePass> NewDepthOfFieldTileReducePass::Create(const RPI::PassDescriptor& descriptor)
{
RPI::Ptr<NewDepthOfFieldTileReducePass> pass = aznew NewDepthOfFieldTileReducePass(descriptor);
return AZStd::move(pass);
}
NewDepthOfFieldTileReducePass::NewDepthOfFieldTileReducePass(const RPI::PassDescriptor& descriptor)
: RPI::ComputePass(descriptor)
{
// Though this is a fullscreen pass, the algorithm used makes each thread output 3 blurred pixels, so
// it's not a 1-to-1 ratio and requires custom calculation of target thread counts
m_isFullscreenPass = false;
}
void NewDepthOfFieldTileReducePass::FrameBeginInternal(FramePrepareParams params)
{
AZ_Assert(GetOutputCount() > 0, "NewDepthOfFieldTileReducePass: No output bindings!");
RPI::PassAttachment* outputAttachment = GetOutputBinding(0).m_attachment.get();
AZ_Assert(outputAttachment != nullptr, "NewDepthOfFieldTileReducePass: Output binding has no attachment!");
RHI::Size outputSize = outputAttachment->m_descriptor.m_image.m_size;
// The algorithm outputs the min/max CoC values from a 16x16 region using 8x8 threads
u32 targetThreadCountX = outputSize.m_width * 8;
u32 targetThreadCountY = outputSize.m_height * 8;
SetTargetThreadCounts(targetThreadCountX, targetThreadCountY, 1);
RPI::ComputePass::FrameBeginInternal(params);
}
// --- Filter Pass ---
RPI::Ptr<NewDepthOfFieldFilterPass> NewDepthOfFieldFilterPass::Create(const RPI::PassDescriptor& descriptor)
{
RPI::Ptr<NewDepthOfFieldFilterPass> pass = aznew NewDepthOfFieldFilterPass(descriptor);
return AZStd::move(pass);
}
NewDepthOfFieldFilterPass::NewDepthOfFieldFilterPass(const RPI::PassDescriptor& descriptor)
: RPI::FullscreenTrianglePass(descriptor)
{ }
void NewDepthOfFieldFilterPass::FrameBeginInternal(FramePrepareParams params)
{
NewDepthOfFieldConstants dofConstants;
uint32_t sampleIndex = 0;
for (uint32_t loop = 0; loop < NewDepthOfFieldConstants::numberOfLoops; ++loop)
{
float radius = (loop + 1.0f) / float(NewDepthOfFieldConstants::numberOfLoops);
float loopCount = NewDepthOfFieldConstants::loopCounts[loop];
for (float i = 0.0f; i < loopCount; ++i)
{
float angle = Constants::TwoPi * i / loopCount;
Vector2 pos = Vector2::CreateFromAngle(angle);
pos = pos * radius;
dofConstants.m_samplePositions[sampleIndex][0] = pos.GetX();
dofConstants.m_samplePositions[sampleIndex][1] = pos.GetY();
dofConstants.m_samplePositions[sampleIndex][2] = radius;
dofConstants.m_samplePositions[sampleIndex][3] = 0.0f;
++sampleIndex;
}
}
m_shaderResourceGroup->SetConstant(m_constantsIndex, dofConstants);
// TODO HERE
RPI::FullscreenTrianglePass::FrameBeginInternal(params);
}
// --- Composite Pass ---
RPI::Ptr<NewDepthOfFieldCompositePass> NewDepthOfFieldCompositePass::Create(const RPI::PassDescriptor& descriptor)
{
RPI::Ptr<NewDepthOfFieldCompositePass> pass = aznew NewDepthOfFieldCompositePass(descriptor);
return AZStd::move(pass);
}
NewDepthOfFieldCompositePass::NewDepthOfFieldCompositePass(const RPI::PassDescriptor& descriptor)
: RPI::ComputePass(descriptor)
{ }
void NewDepthOfFieldCompositePass::FrameBeginInternal(FramePrepareParams params)
{
// TODO HERE
RPI::ComputePass::FrameBeginInternal(params);
}
} // namespace Render
} // namespace AZ
@@ -0,0 +1,117 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <Atom/RPI.Public/Pass/ComputePass.h>
#include <Atom/RPI.Public/Pass/FullscreenTrianglePass.h>
#include <Atom/RPI.Public/Pass/ParentPass.h>
#include <PostProcessing/PostProcessingShaderOptionBase.h>
namespace AZ
{
namespace Render
{
//!
class NewDepthOfFieldParentPass final
: public RPI::ParentPass
{
AZ_RPI_PASS(NewDepthOfFieldParentPass);
public:
AZ_RTTI(AZ::Render::NewDepthOfFieldParentPass, "{71F4998B-447C-4BAC-A5BE-2D2850FABB57}", AZ::RPI::ParentPass);
AZ_CLASS_ALLOCATOR(NewDepthOfFieldParentPass, SystemAllocator, 0);
virtual ~NewDepthOfFieldParentPass() = default;
static RPI::Ptr<NewDepthOfFieldParentPass> Create(const RPI::PassDescriptor& descriptor);
bool IsEnabled() const override;
protected:
// Behavior functions override...
void FrameBeginInternal(FramePrepareParams params) override;
private:
NewDepthOfFieldParentPass(const RPI::PassDescriptor& descriptor);
};
//!
class NewDepthOfFieldTileReducePass final
: public RPI::ComputePass
{
AZ_RPI_PASS(NewDepthOfFieldTileReducePass);
public:
AZ_RTTI(AZ::Render::NewDepthOfFieldTileReducePass, "{2E072695-0847-43A6-9BE4-D6D85CFFBA41}", AZ::RPI::ComputePass);
AZ_CLASS_ALLOCATOR(NewDepthOfFieldTileReducePass, SystemAllocator, 0);
virtual ~NewDepthOfFieldTileReducePass() = default;
static RPI::Ptr<NewDepthOfFieldTileReducePass> Create(const RPI::PassDescriptor& descriptor);
protected:
// Behavior functions override...
void FrameBeginInternal(FramePrepareParams params) override;
private:
NewDepthOfFieldTileReducePass(const RPI::PassDescriptor& descriptor);
};
//!
class NewDepthOfFieldFilterPass final
: public RPI::FullscreenTrianglePass
{
AZ_RPI_PASS(NewDepthOfFieldFilterPass);
public:
AZ_RTTI(AZ::Render::NewDepthOfFieldFilterPass, "{F8A98E53-1A50-4178-A6EB-2BD0148C038B}", AZ::RPI::FullscreenTrianglePass);
AZ_CLASS_ALLOCATOR(NewDepthOfFieldFilterPass, SystemAllocator, 0);
virtual ~NewDepthOfFieldFilterPass() = default;
static RPI::Ptr<NewDepthOfFieldFilterPass> Create(const RPI::PassDescriptor& descriptor);
protected:
// Behavior functions override...
void FrameBeginInternal(FramePrepareParams params) override;
private:
NewDepthOfFieldFilterPass(const RPI::PassDescriptor& descriptor);
// SRG binding indices...
AZ::RHI::ShaderInputNameIndex m_constantsIndex = "m_dofConstants";
};
//!
class NewDepthOfFieldCompositePass final
: public RPI::ComputePass
{
AZ_RPI_PASS(NewDepthOfFieldCompositePass);
public:
AZ_RTTI(AZ::Render::NewDepthOfFieldCompositePass, "{63270A3A-EAE5-4C0C-98AA-43CA55279613}", AZ::RPI::ComputePass);
AZ_CLASS_ALLOCATOR(NewDepthOfFieldCompositePass, SystemAllocator, 0);
virtual ~NewDepthOfFieldCompositePass() = default;
static RPI::Ptr<NewDepthOfFieldCompositePass> Create(const RPI::PassDescriptor& descriptor);
protected:
// Behavior functions override...
void FrameBeginInternal(FramePrepareParams params) override;
private:
NewDepthOfFieldCompositePass(const RPI::PassDescriptor& descriptor);
};
} // namespace Render
} // namespace AZ
@@ -168,7 +168,7 @@ namespace AZ::Render
// The ImageViewDescriptor must be specified to make sure the frame graph compiler doesn't treat this as a transient image.
RHI::ImageViewDescriptor viewDesc = RHI::ImageViewDescriptor::Create(imageDesc.m_format, 0, 0);
viewDesc.m_aspectFlags = RHI::ImageAspectFlags::Color;
viewDesc.m_overrideBindFlags = RHI::ImageBindFlags::ShaderReadWrite;
//viewDesc.m_overrideBindFlags = RHI::ImageBindFlags::ShaderReadWrite;
// The full path name is needed for the attachment image so it's not deduplicated from accumulation images in different pipelines.
AZStd::string imageName = RPI::ConcatPassString(GetPathName(), attachment->m_path);
@@ -240,6 +240,8 @@ set(FILES
Source/PostProcessing/LookModificationTransformPass.h
Source/PostProcessing/LuminanceHistogramGeneratorPass.h
Source/PostProcessing/LuminanceHistogramGeneratorPass.cpp
Source/PostProcessing/NewDepthOfFieldPasses.cpp
Source/PostProcessing/NewDepthOfFieldPasses.h
Source/PostProcessing/PostProcessingShaderOptionBase.cpp
Source/PostProcessing/PostProcessingShaderOptionBase.h
Source/PostProcessing/SMAABasePass.cpp
@@ -67,6 +67,10 @@ namespace AZ
bool IsInitialized() const;
void AssetInialized() const;
// Retrieves the underlying name. Should only be used for debug purposes like printing the name when we fail to bind to the SRG.
// All regular functionality should go through the above functions.
const Name& GetNameForDebug() const;
private:
enum class IndexType : u32
@@ -227,5 +227,11 @@ namespace AZ
}
const Name& ShaderInputNameIndex::GetNameForDebug() const
{
AZ_Assert(HasName(), "GetNameForDebug() called on ShaderInputNameIndex that doesn't have a name set. Please initialize it with a name.", m_name.GetCStr());
return m_name;
}
}
}
@@ -31,6 +31,8 @@ void swap(inout float a, inout float b)
b = c;
}
// ---------- Power -----------
float Pow2(float x)
{
return x * x;
@@ -48,6 +50,44 @@ float Pow5(float x)
{
return x * Pow4(x);
}
// ---------- Min & Max -----------
float min3(float a, float b, float c)
{
return min(min(a, b), c);
}
float min4(float a, float b, float c, float d)
{
return min(min3(a, b, c), d);
}
float max3(float a, float b, float c)
{
return max(max(a, b), c);
}
float max4(float a, float b, float c, float d)
{
return max(max3(a, b, c), d);
}
float min3(float3 abc)
{
return min3(abc.x, abc.y, abc.z);
}
float min4(float4 abcd)
{
return min4(abcd.x, abcd.y, abcd.z, abcd.w);
}
float max3(float3 abc)
{
return max3(abc.x, abc.y, abc.z);
}
float max4(float4 abcd)
{
return max4(abcd.x, abcd.y, abcd.z, abcd.w);
}
// ---------- Intersection -----------
// a simple ray sphere intersection function, didn't take limited precision
@@ -10,6 +10,8 @@
#include <AtomCore/Instance/Instance.h>
#include <AtomCore/Instance/InstanceData.h>
#include <Atom/RHI.Reflect/ShaderInputNameIndex.h>
#include <Atom/RPI.Reflect/Pass/PassAttachmentReflect.h>
namespace AZ
@@ -145,7 +147,11 @@ namespace AZ
//! Name of the SRG member this binds to (see PassSlot::m_shaderInputName for more details)
Name m_shaderInputName = Name("AutoBind");
//! Name index of the SRG constant to which, if specified, we automatically calculate
//! and bind the image dimensions (if this binding is of type image)
RHI::ShaderInputNameIndex m_shaderImageDimensionsNameIndex;
//! Whether binding is an input, output or inputOutput
PassSlotType m_slotType = PassSlotType::Uninitialized;
@@ -119,7 +119,7 @@ namespace AZ
private:
// Helper function that binds a single attachment to the pass shader resource group
void BindAttachment(const RHI::FrameGraphCompileContext& context, const PassAttachmentBinding& binding, int16_t& imageIndex, int16_t& bufferIndex);
void BindAttachment(const RHI::FrameGraphCompileContext& context, PassAttachmentBinding& binding, int16_t& imageIndex, int16_t& bufferIndex);
// Helper function to get the query by the scope index and query type
RHI::Ptr<Query> GetQuery(ScopeQueryType queryType);
@@ -87,6 +87,13 @@ namespace AZ
//! The keyword "NoBind" means the slot will not bind it's attachment to the SRG
Name m_shaderInputName = Name("AutoBind");
//! Name of the shader resource group constant (must be float4) to which the pass can automatically bind the following:
//! X component = image width
//! Y component = image height
//! Z component = 1 / image width
//! W component = 1 / image height
Name m_shaderImageDimensionsName;
//! This is to specify an array index if the shader input is an array.
//! e.g. Texture2DMS<float4> m_color[4];
uint16_t m_shaderInputArrayIndex = 0;
@@ -187,6 +187,7 @@ namespace AZ
{
m_name = slot.m_name;
m_shaderInputName = slot.m_shaderInputName;
m_shaderImageDimensionsNameIndex = slot.m_shaderImageDimensionsName;
m_shaderInputArrayIndex = slot.m_shaderInputArrayIndex;
m_slotType = slot.m_slotType;
m_scopeAttachmentUsage = slot.m_scopeAttachmentUsage;
@@ -16,6 +16,7 @@
#include <Atom/RHI.Reflect/ImageScopeAttachmentDescriptor.h>
#include <Atom/RPI.Reflect/Pass/RenderPassData.h>
#include <Atom/RHI.Reflect/RenderAttachmentLayoutBuilder.h>
#include <Atom/RHI.Reflect/Size.h>
#include <Atom/RPI.Public/GpuQuery/Query.h>
#include <Atom/RPI.Public/Pass/PassUtils.h>
@@ -272,15 +273,8 @@ namespace AZ
}
}
void RenderPass::BindAttachment(const RHI::FrameGraphCompileContext& context, const PassAttachmentBinding& binding, int16_t& imageIndex, int16_t& bufferIndex)
void RenderPass::BindAttachment(const RHI::FrameGraphCompileContext& context, PassAttachmentBinding& binding, int16_t& imageIndex, int16_t& bufferIndex)
{
if (binding.m_shaderInputIndex == PassAttachmentBinding::ShaderInputNoBind ||
binding.m_scopeAttachmentUsage == RHI::ScopeAttachmentUsage::RenderTarget ||
binding.m_scopeAttachmentUsage == RHI::ScopeAttachmentUsage::DepthStencil)
{
return;
}
PassAttachment* attachment = binding.m_attachment.get();
if (attachment)
{
@@ -293,11 +287,39 @@ namespace AZ
inputIndex = imageIndex;
}
const RHI::ImageView* imageView = context.GetImageView(attachment->GetAttachmentId(), binding.m_attachmentUsageIndex);
m_shaderResourceGroup->SetImageView(RHI::ShaderInputImageIndex(inputIndex), imageView, arrayIndex);
++imageIndex;
if (binding.m_shaderImageDimensionsNameIndex.HasName())
{
RHI::Size size = attachment->m_descriptor.m_image.m_size;
AZ::Vector4 imageDimensions;
imageDimensions.SetX(float(size.m_width));
imageDimensions.SetY(float(size.m_height));
imageDimensions.SetZ(1.0f / float(size.m_width));
imageDimensions.SetW(1.0f / float(size.m_height));
bool success = m_shaderResourceGroup->SetConstant(binding.m_shaderImageDimensionsNameIndex, imageDimensions);
AZ_Assert(success, "Pass [%s] Could not find float4 constant [%s] in Shader Resource Group [%s]",
GetPathName().GetCStr(),
binding.m_shaderImageDimensionsNameIndex.GetNameForDebug().GetCStr(),
m_shaderResourceGroup->GetDatabaseName());
}
if (binding.m_shaderInputIndex != PassAttachmentBinding::ShaderInputNoBind &&
binding.m_scopeAttachmentUsage != RHI::ScopeAttachmentUsage::RenderTarget &&
binding.m_scopeAttachmentUsage != RHI::ScopeAttachmentUsage::DepthStencil)
{
m_shaderResourceGroup->SetImageView(RHI::ShaderInputImageIndex(inputIndex), imageView, arrayIndex);
++imageIndex;
}
}
else if (attachment->GetAttachmentType() == RHI::AttachmentType::Buffer)
{
if (binding.m_shaderInputIndex == PassAttachmentBinding::ShaderInputNoBind)
{
return;
}
if (inputIndex == PassAttachmentBinding::ShaderInputAutoBind)
{
inputIndex = bufferIndex;
@@ -56,9 +56,10 @@ namespace AZ
;
serializeContext->Class<PassSlot>()
->Version(1)
->Version(2)
->Field("Name", &PassSlot::m_name)
->Field("ShaderInputName", &PassSlot::m_shaderInputName)
->Field("ShaderImageDimensionsConstant", &PassSlot::m_shaderImageDimensionsName)
->Field("ShaderInputArrayIndex", &PassSlot::m_shaderInputArrayIndex)
->Field("SlotType", &PassSlot::m_slotType)
->Field("ScopeAttachmentUsage", &PassSlot::m_scopeAttachmentUsage)