Merge pull request #4865 from aws-lumberyard-dev/Atom/antonmic/DepthOfField01
Atom/antonmic/depth of field01
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
{
|
||||
"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": "AutoFocus",
|
||||
"TemplateName": "DepthOfFieldReadBackFocusDepthTemplate",
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "DepthInput",
|
||||
"AttachmentRef": {
|
||||
"Pass": "Parent",
|
||||
"Attachment": "Depth"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"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": "Tile5x5",
|
||||
"TemplateName": "NewDepthOfFieldTile3x3Template",
|
||||
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "Input",
|
||||
"AttachmentRef": {
|
||||
"Pass": "Tile3x3",
|
||||
"Attachment": "Output"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "LargeFilter",
|
||||
"TemplateName": "NewDepthOfFieldFilterLargeTemplate",
|
||||
|
||||
"Connections": [
|
||||
{
|
||||
"LocalSlot": "ColorAndCoc",
|
||||
"AttachmentRef": {
|
||||
"Pass": "Downsample",
|
||||
"Attachment": "OutputColorAndCoC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"LocalSlot": "CocTile",
|
||||
"AttachmentRef": {
|
||||
"Pass": "Tile5x5",
|
||||
"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,42 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
// Todo: remove the old depth of field implementation and rename NewDepthOfField -> DepthOfField
|
||||
//{
|
||||
// "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 +164,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,27 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#define SAMPLES_LOOP_TOTAL 48
|
||||
|
||||
// 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,120 @@
|
||||
/*
|
||||
* 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
|
||||
// Auto-filled by the pass system when "ShaderImageDimensionsConstant" is specified in the .pass file
|
||||
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);
|
||||
|
||||
// --- Weights based on CoC similarity ---
|
||||
|
||||
// Gather CoCs
|
||||
float4 cocGather = PassSrg::m_halfResColorAndCoc.GatherAlpha(PassSrg::LinearSampler, halfResUV);
|
||||
|
||||
// Calculate differences
|
||||
float4 diff = saturate(cocGather - coc);
|
||||
|
||||
// Slide differences such that small difference (i.e. most similar CoC) will become 0
|
||||
// (which then gets inverted in the next step)
|
||||
float minDiff = min4(diff);
|
||||
diff -= minDiff;
|
||||
|
||||
// Invert the differences with a slope multiplier of 2
|
||||
float4 cocDiffWeights = saturate(1 - (2 * diff));
|
||||
|
||||
// --- Weights based on pixel proximity ---
|
||||
|
||||
// Based on which pixel we're shading, we'll be closer/farther to half res pixels
|
||||
// Here are the pre-calculated weights, arranged to match the Gather pattern
|
||||
//
|
||||
// W Z
|
||||
// X Y
|
||||
//
|
||||
// Note: These weights come down to the same contributions as if we did a linear sample
|
||||
int2 pixel = int2(fullResPixelPos);
|
||||
float4 weights = (pixel.x & 1)
|
||||
? ( (pixel.y & 1) ? float4(0.1875f, 0.0625f, 0.1875f, 0.5625f)
|
||||
: float4(0.5625f, 0.1875f, 0.0625f, 0.1875f) )
|
||||
: ( (pixel.y & 1) ? float4(0.0625f, 0.1875f, 0.5625f, 0.1875f)
|
||||
: float4(0.1875f, 0.5625f, 0.1875f, 0.0625f) );
|
||||
|
||||
// Combine and normalize weights
|
||||
weights *= cocDiffWeights;
|
||||
weights /= (weights.x + weights.y + weights.z + weights.w);
|
||||
|
||||
// --- Color ---
|
||||
|
||||
// For each color channel, do a gather and multiply the samples by the weights calculated above
|
||||
float3 color;
|
||||
float4 red = PassSrg::m_halfResColorAndCoc.GatherRed(PassSrg::LinearSampler, halfResUV);
|
||||
color.r = dot(red, weights);
|
||||
float4 blue = PassSrg::m_halfResColorAndCoc.GatherBlue(PassSrg::LinearSampler, halfResUV);
|
||||
color.b = dot(blue, weights);
|
||||
float4 green = PassSrg::m_halfResColorAndCoc.GatherGreen(PassSrg::LinearSampler, halfResUV);
|
||||
color.g = dot(green, weights);
|
||||
|
||||
|
||||
// --- Alpha ---
|
||||
|
||||
// Calculate alpha such that we fully take the half res texture value if the CoC of the full
|
||||
// resolution pixel is greater than the size of a half resolution pixel
|
||||
float cocRadius = abs(coc) * ViewSrg::m_dof.m_cocToScreenRatio * 0.5f;
|
||||
float alpha = saturate(cocRadius / PassSrg::m_halfResDimensions.w);
|
||||
|
||||
// We may have objects in focus (CoC = 0) but that receive contribution from background bokeh
|
||||
// (which have a negative CoC that we calculated in the large filter). Take the max here.
|
||||
float minCoc = min4(cocGather);
|
||||
alpha = max(alpha, -minCoc);
|
||||
|
||||
PSOutput OUT;
|
||||
OUT.m_color.rgb = color.rgb;
|
||||
OUT.m_color.a = alpha;
|
||||
return OUT;
|
||||
}
|
||||
|
||||
+31
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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
|
||||
// Auto-filled by the pass system when "ShaderImageDimensionsConstant" is specified in the .pass file
|
||||
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);
|
||||
|
||||
// Weight samples by CoC to avoid in focus 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;
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"Source" : "NewDepthOfFieldDownsample",
|
||||
|
||||
"DepthStencilState" : {
|
||||
"Depth" : { "Enable" : false }
|
||||
},
|
||||
|
||||
"ProgramSettings":
|
||||
{
|
||||
"EntryPoints":
|
||||
[
|
||||
{
|
||||
"name": "MainVS",
|
||||
"type": "Vertex"
|
||||
},
|
||||
{
|
||||
"name": "MainPS",
|
||||
"type": "Fragment"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
// Texture dimensions. XY channels are width and height and ZW channels are 1 / width and 1 / height
|
||||
// Auto-filled by the pass system when "ShaderImageDimensionsConstant" is specified in the .pass file
|
||||
float4 m_textureDimensions;
|
||||
|
||||
NewDepthOfFieldConstants m_dofConstants;
|
||||
|
||||
Sampler LinearSampler
|
||||
{
|
||||
MinFilter = Linear;
|
||||
MagFilter = Linear;
|
||||
MipFilter = Linear;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
AddressW = Clamp;
|
||||
};
|
||||
|
||||
Sampler PointSampler
|
||||
{
|
||||
MinFilter = Point;
|
||||
MagFilter = Point;
|
||||
MipFilter = Point;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
AddressW = Clamp;
|
||||
};
|
||||
}
|
||||
|
||||
float3 GetOffset(uint index, float2 offsetUVMultiplier)
|
||||
{
|
||||
float3 offset = PassSrg::m_dofConstants.samplePositions[index].xyz;
|
||||
offset.xy *= offsetUVMultiplier;
|
||||
return offset;
|
||||
}
|
||||
|
||||
float CalculateWeight(float offsetRadius, float samplingRadius, float sampleCoc, float centerCoc)
|
||||
{
|
||||
// The maximum distance for which samples are valid is the min of the sample CoC and the center CoC
|
||||
float maxRadius = abs(min(sampleCoc, centerCoc));
|
||||
|
||||
// Easy human readable calculations:
|
||||
// radius = samplingRadius * offsetRadius;
|
||||
// falloff = maxRadius - radius;
|
||||
// weight = 1 + (4 * falloff)
|
||||
//
|
||||
// The same thing in mad form:
|
||||
float falloff = mad(-samplingRadius, offsetRadius, maxRadius);
|
||||
return saturate(mad(4, falloff, 1));
|
||||
}
|
||||
|
||||
// This shader blurs by sampling 48 pixels in a circle around the center pixel
|
||||
// See http://advances.realtimerendering.com/s2013/Sousa_Graphics_Gems_CryENGINE3.pptx
|
||||
// for a detailed explanation.
|
||||
PSOutput MainPS(VSOutput IN)
|
||||
{
|
||||
// Get center sample
|
||||
float2 pixelUV = IN.m_texCoord;
|
||||
float4 color = PassSrg::m_colorAndCoc.Sample(PassSrg::LinearSampler, pixelUV).rgba;
|
||||
float centerCoc = color.a;
|
||||
|
||||
// Get tile min CoC
|
||||
int2 tile = int2(IN.m_position.xy) / 16;
|
||||
float minCoc = PassSrg::m_minMaxCocTile[tile].x;
|
||||
|
||||
// Aspect ratio is needed because sample offsets are calculated in a perfect circle, but
|
||||
// UV space is stretched due to normalized device coordinates. Correct this with aspect ratio
|
||||
// Aspect ratio = texture.x / texture.y = dimensions.x * dimensions.w
|
||||
float aspectRatio = PassSrg::m_textureDimensions.x * PassSrg::m_textureDimensions.w;
|
||||
|
||||
// Sampling radius
|
||||
float cocRadius = max( abs(centerCoc), -minCoc);
|
||||
float screenRadius = cocRadius * ViewSrg::m_dof.m_cocToScreenRatio * 0.5f;
|
||||
float2 offsetMultiplier = float2(screenRadius / aspectRatio, screenRadius);
|
||||
|
||||
// Background samples are samples behind the current pixel. Because of how depth of field works,
|
||||
// these pixels can contribute to the center pixel even if they are out of range of the center pixel's CoC
|
||||
// We accumulate them seperately and calculate a new estimated alpha value based on the ratio of samples
|
||||
// that were background pixels.
|
||||
float4 backgroundColor = float4(0, 0, 0, 0);
|
||||
|
||||
// If there are only positive CoCs in our region, we don't need to consider background blur
|
||||
// Do the faster and nicer approach
|
||||
if(minCoc >= 0)
|
||||
{
|
||||
for(uint i = 0; i < SAMPLES_LOOP_TOTAL; ++i)
|
||||
{
|
||||
// Calculate sample offset
|
||||
float3 offset = GetOffset(i, offsetMultiplier);
|
||||
|
||||
// Get sample
|
||||
float4 sampleColorCoc = PassSrg::m_colorAndCoc.Sample(PassSrg::LinearSampler, pixelUV + offset.xy).rgba;
|
||||
|
||||
// Calculate weight for sample
|
||||
float weight = CalculateWeight(offset.z, cocRadius, sampleColorCoc.a, centerCoc);
|
||||
|
||||
// Accumulate
|
||||
color += weight * sampleColorCoc;
|
||||
}
|
||||
}
|
||||
else // Some CoCs in the region are negative, need to consider possible background bokeh contribution
|
||||
{
|
||||
// Distance behind which samples are considered background samples
|
||||
float backgroundMin = min(0, centerCoc);
|
||||
|
||||
// Linear sampling colors pre-multiplied with CoC yields artefacts when combined with this background technique
|
||||
// We therefore do point sampling and unpack the original color value per sample
|
||||
color.rgb /= abs(color.a);
|
||||
color.a = 1;
|
||||
|
||||
for(uint i = 0; i < SAMPLES_LOOP_TOTAL; ++i)
|
||||
{
|
||||
// Calculate sample offset
|
||||
float3 offset = GetOffset(i, offsetMultiplier);
|
||||
|
||||
// Get sample + unpack
|
||||
float4 sampleColorCoc = PassSrg::m_colorAndCoc.Sample(PassSrg::PointSampler, pixelUV + offset.xy).rgba;
|
||||
sampleColorCoc.rgb /= abs(sampleColorCoc.a);
|
||||
|
||||
// Calculate weight for sample
|
||||
float weight = CalculateWeight(offset.z, cocRadius, sampleColorCoc.a, centerCoc);
|
||||
sampleColorCoc.rgb *= weight;
|
||||
|
||||
bool isBackground = (sampleColorCoc.a < backgroundMin);
|
||||
|
||||
// We accumulate weight in alpha channel of color and backgroundColor
|
||||
sampleColorCoc.a = weight;
|
||||
|
||||
// Accumulate
|
||||
backgroundColor += isBackground * sampleColorCoc;
|
||||
color += !isBackground * sampleColorCoc;
|
||||
}
|
||||
|
||||
// Average background samples
|
||||
backgroundColor.rgb /= max(backgroundColor.a, COC_EPSILON);
|
||||
}
|
||||
|
||||
// Calculate background ratio. If greater than the current CoC, replace the current CoC with
|
||||
// background ratio. This is so background bokeh effects will still render on in-focus objects
|
||||
float backgroundRatio = saturate( backgroundColor.a / float(SAMPLES_LOOP_TOTAL) );
|
||||
float alpha = backgroundRatio > abs(centerCoc) ? -backgroundRatio : centerCoc;
|
||||
|
||||
// Average accumulated color samples and combine with background samples
|
||||
color.rgb /= max(color.a, COC_EPSILON);
|
||||
color = lerp(color, backgroundColor, backgroundRatio);
|
||||
|
||||
PSOutput OUT = (PSOutput)0;
|
||||
OUT.m_color.rgb = color.rgb;
|
||||
OUT.m_color.a = alpha;
|
||||
return OUT;
|
||||
}
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"Source" : "NewDepthOfFieldFilterLarge",
|
||||
|
||||
"DepthStencilState" : {
|
||||
"Depth" : { "Enable" : false }
|
||||
},
|
||||
|
||||
"ProgramSettings":
|
||||
{
|
||||
"EntryPoints":
|
||||
[
|
||||
{
|
||||
"name": "MainVS",
|
||||
"type": "Vertex"
|
||||
},
|
||||
{
|
||||
"name": "MainPS",
|
||||
"type": "Fragment"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
// Texture dimensions. XY channels are width and height and ZW channels are 1 / width and 1 / height
|
||||
// Auto-filled by the pass system when "ShaderImageDimensionsConstant" is specified in the .pass file
|
||||
float4 m_textureDimensions;
|
||||
|
||||
NewDepthOfFieldConstants m_dofConstants;
|
||||
|
||||
Sampler LinearSampler
|
||||
{
|
||||
MinFilter = Linear;
|
||||
MagFilter = Linear;
|
||||
MipFilter = Linear;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
AddressW = Clamp;
|
||||
};
|
||||
|
||||
Sampler PointSampler
|
||||
{
|
||||
MinFilter = Point;
|
||||
MagFilter = Point;
|
||||
MipFilter = Point;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
AddressW = Clamp;
|
||||
};
|
||||
}
|
||||
|
||||
float3 GetOffset(uint index, float2 offsetUVMultiplier)
|
||||
{
|
||||
float3 offset = PassSrg::m_dofConstants.samplePositions[index].xyz;
|
||||
offset.xy *= offsetUVMultiplier;
|
||||
return offset;
|
||||
}
|
||||
|
||||
float CalculateWeight(float offsetRadius, float samplingRadius, float sampleCoc, float centerCoc)
|
||||
{
|
||||
// The maximum distance for which samples are valid is the min of the sample CoC and the center CoC
|
||||
float maxRadius = abs(min(sampleCoc, centerCoc));
|
||||
|
||||
// Easy human readable calculations:
|
||||
// radius = samplingRadius * offsetRadius;
|
||||
// falloff = maxRadius - radius;
|
||||
// weight = 1 + (4 * falloff)
|
||||
//
|
||||
// The same thing in mad form:
|
||||
float falloff = mad(-samplingRadius, offsetRadius, maxRadius);
|
||||
return saturate(mad(4, falloff, 1));
|
||||
}
|
||||
|
||||
// This shader attempts to fill the gaps left by the large filter by sampling 8 pixels around the center pixel
|
||||
// See http://advances.realtimerendering.com/s2013/Sousa_Graphics_Gems_CryENGINE3.pptx
|
||||
// for a detailed overview of the technique
|
||||
PSOutput MainPS(VSOutput IN)
|
||||
{
|
||||
// Get center sample
|
||||
float2 pixelUV = IN.m_texCoord.xy;
|
||||
float4 color = PassSrg::m_colorAndCoc.Sample(PassSrg::PointSampler, pixelUV).rgba;
|
||||
float centerCoc = color.a;
|
||||
|
||||
// Get tile min CoC
|
||||
int2 tile = int2(IN.m_position.xy) / 16;
|
||||
float minCoc = PassSrg::m_minMaxCocTile[tile].x;
|
||||
|
||||
// Aspect ratio is needed because sample offsets are calculated in a perfect circle, but
|
||||
// UV space is stretched due to normalized device coordinates. Correct this with aspect ratio
|
||||
// Aspect ratio = texture.x / texture.y = dimensions.x * dimensions.w
|
||||
float aspectRatio = PassSrg::m_textureDimensions.x * PassSrg::m_textureDimensions.w;
|
||||
|
||||
// Sampling radius
|
||||
float cocRadius = max( abs(centerCoc), -minCoc) * 0.5f; // Small filter pass so half the radius
|
||||
float screenRadius = cocRadius * ViewSrg::m_dof.m_cocToScreenRatio * 0.5f;
|
||||
float2 offsetMultiplier = float2(screenRadius / aspectRatio, screenRadius);
|
||||
|
||||
// Weight accumulation. Start with 1 for center pixel.
|
||||
float totalWeight = 1;
|
||||
|
||||
for(uint i = 0; i < SAMPLES_LOOP_1; ++i)
|
||||
{
|
||||
// Calculate sample offset
|
||||
float3 offset = GetOffset(i, offsetMultiplier);
|
||||
|
||||
// Get sample
|
||||
float4 sampleColorCoc = PassSrg::m_colorAndCoc.Sample(PassSrg::PointSampler, pixelUV + offset.xy).rgba;
|
||||
|
||||
// Calculate weight
|
||||
float weight = CalculateWeight(offset.z, cocRadius, sampleColorCoc.a, centerCoc);
|
||||
|
||||
// Accumulate sample and weight
|
||||
color.rgb += sampleColorCoc.rgb * weight;
|
||||
totalWeight += weight;
|
||||
}
|
||||
|
||||
|
||||
// Normalize accumulated sample
|
||||
color.rgb /= totalWeight;
|
||||
|
||||
PSOutput OUT;
|
||||
OUT.m_color.rgb = color.rgb;
|
||||
OUT.m_color.a = centerCoc;
|
||||
return OUT;
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"Source" : "NewDepthOfFieldFilterSmall",
|
||||
|
||||
"DepthStencilState" : {
|
||||
"Depth" : { "Enable" : false }
|
||||
},
|
||||
|
||||
"ProgramSettings":
|
||||
{
|
||||
"EntryPoints":
|
||||
[
|
||||
{
|
||||
"name": "MainVS",
|
||||
"type": "Vertex"
|
||||
},
|
||||
{
|
||||
"name": "MainPS",
|
||||
"type": "Fragment"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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
|
||||
// Auto-filled by the pass system when "ShaderImageDimensionsConstant" is specified in the .pass file
|
||||
float4 m_textureDimensions;
|
||||
|
||||
Sampler PointSampler
|
||||
{
|
||||
MinFilter = Point;
|
||||
MagFilter = Point;
|
||||
MipFilter = Point;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
AddressW = Clamp;
|
||||
};
|
||||
}
|
||||
|
||||
struct PSOutput
|
||||
{
|
||||
float2 m_color : SV_Target0;
|
||||
};
|
||||
|
||||
// Expands the min and max tiles so each tile contains the min and max of it's 3x3 neighborhood
|
||||
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 pixelSizeInUV = PassSrg::m_textureDimensions.zw;
|
||||
float2 startUV = startPixelPos * pixelSizeInUV;
|
||||
|
||||
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), pixelSizeInUV, 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,87 @@
|
||||
/*
|
||||
* 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
|
||||
// Auto-filled by the pass system when "ShaderImageDimensionsConstant" is specified in the .pass file
|
||||
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];
|
||||
|
||||
// Calculates the min and max CoC (Circle of Confusion) for 16x16 pixel tiles
|
||||
[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;
|
||||
}
|
||||
|
||||
// Min the mins and max the maxs
|
||||
InterlockedMin( LDS_MIN_COC[0], LDS_MIN_COC[group_thread_id.x] );
|
||||
InterlockedMax( LDS_MAX_COC[0], LDS_MAX_COC[group_thread_id.x] );
|
||||
|
||||
// Each group write to just one pixel. If we're the last thread in the group, write out
|
||||
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);
|
||||
}
|
||||
}
|
||||
+14
@@ -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
|
||||
@@ -161,8 +160,6 @@ set(FILES
|
||||
Passes/LutGeneration.pass
|
||||
Passes/MainPipeline.pass
|
||||
Passes/MainPipelineRenderToTexture.pass
|
||||
Passes/ToolsPipeline.pass
|
||||
Passes/ToolsPipelineRenderToTexture.pass
|
||||
Passes/MeshMotionVector.pass
|
||||
Passes/ModulateTexture.pass
|
||||
Passes/MorphTarget.pass
|
||||
@@ -170,6 +167,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
|
||||
@@ -205,11 +209,17 @@ set(FILES
|
||||
Passes/SsaoParent.pass
|
||||
Passes/SubsurfaceScattering.pass
|
||||
Passes/Taa.pass
|
||||
Passes/ToolsPipeline.pass
|
||||
Passes/ToolsPipelineRenderToTexture.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
|
||||
@@ -218,6 +228,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
|
||||
@@ -225,8 +237,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
|
||||
@@ -284,17 +294,23 @@ set(FILES
|
||||
ShaderLib/Atom/Features/PostProcessing/GlyphRender.azsli
|
||||
ShaderLib/Atom/Features/PostProcessing/HDRColorGradingCommon.azsl
|
||||
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/NormalOffsetShadows.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
|
||||
@@ -305,6 +321,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
|
||||
@@ -321,14 +339,20 @@ set(FILES
|
||||
Shaders/ColorGrading/LutGeneration.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
|
||||
@@ -348,6 +372,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
|
||||
@@ -362,6 +389,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
|
||||
@@ -418,6 +447,19 @@ set(FILES
|
||||
Shaders/PostProcessing/MSAAResolveCustom.shader
|
||||
Shaders/PostProcessing/MSAAResolveDepth.azsl
|
||||
Shaders/PostProcessing/MSAAResolveDepth.shader
|
||||
Shaders/PostProcessing/NewDepthOfFieldCommon.azsli
|
||||
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
|
||||
@@ -434,13 +476,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
|
||||
@@ -469,6 +515,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
|
||||
|
||||
@@ -51,6 +51,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>
|
||||
@@ -250,6 +251,10 @@ 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);
|
||||
|
||||
// Add FastDepthAwareBlur passes
|
||||
passSystem->AddPassCreator(Name("FastDepthAwareBlurHorPass"), &FastDepthAwareBlurHorPass::Create);
|
||||
passSystem->AddPassCreator(Name("FastDepthAwareBlurVerPass"), &FastDepthAwareBlurVerPass::Create);
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* 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 shader computes 16x16 tiles with groups of 8x8 threads,
|
||||
// each thread outputting to a single pixel in the tiled min/max texture
|
||||
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;
|
||||
|
||||
// Calculate all the offset positions
|
||||
for (uint32_t loop = 0; loop < NewDepthOfFieldConstants::numberOfLoops; ++loop)
|
||||
{
|
||||
float radius = (loop + 1.0f) / float(NewDepthOfFieldConstants::numberOfLoops);
|
||||
float loopCount = NewDepthOfFieldConstants::loopCounts[loop];
|
||||
|
||||
float angleStep = Constants::TwoPi / loopCount;
|
||||
|
||||
// Every other loop slightly rotate sample ring so they don't line up
|
||||
float angle = (loop & 1) ? (angleStep * 0.5f) : 0;
|
||||
|
||||
for (float i = 0.0f; i < loopCount; ++i)
|
||||
{
|
||||
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;
|
||||
angle += angleStep;
|
||||
}
|
||||
}
|
||||
|
||||
m_shaderResourceGroup->SetConstant(m_constantsIndex, dofConstants);
|
||||
|
||||
RPI::FullscreenTrianglePass::FrameBeginInternal(params);
|
||||
}
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
// Technique
|
||||
//
|
||||
// 1. This Depth of Field technique starts by downsampling the lighting buffer and calculating
|
||||
// the circle of confusion (CoC) for each downsampled pixel.
|
||||
//
|
||||
// 2. It then computes the min and max CoC for tiles of 16x16 pixels
|
||||
//
|
||||
// 3. It expands the min and max in a 3x3 region (twice, so 5x5 at the end) so that each tile
|
||||
// tile pixel has the min and max CoCs of the 5x5 tile region around it
|
||||
//
|
||||
// 4. We perform a 48 tap scatter-as-gather blur around each pixel
|
||||
//
|
||||
// 5. We perform a follow up 8 tap scatter-as-gather blur to fill the holes from the first blur
|
||||
//
|
||||
// 6. We composite the blurred half resolution image onto the full resolution lighting buffer
|
||||
//
|
||||
// See http://advances.realtimerendering.com/s2013/Sousa_Graphics_Gems_CryENGINE3.pptx
|
||||
// for a more detailed explanation.
|
||||
//
|
||||
// Notes: The name NewDepthOfField is in contrast to the previously implemented depth of field method
|
||||
// That method will be removed in a follow up change and at that point NewDepthOfField will be renamed
|
||||
// to simple DepthOfField.
|
||||
|
||||
//! Parent pass for the new depth of field technique
|
||||
//! Main updates the view srg via the depth of field settings
|
||||
//! And enables/disables all depth of field passes based on component activation
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
//! Need a class for the tile reduce pass because it dispatches a non-trivial number of threads
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
//! Filter pass used to render the bokeh blur effect on downsampled image buffer
|
||||
//! This class is used for both the large filter and the small filter
|
||||
//! It's main purpose is calculating the sample positions and setting srg constants
|
||||
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";
|
||||
};
|
||||
|
||||
|
||||
} // namespace Render
|
||||
} // namespace AZ
|
||||
@@ -168,7 +168,6 @@ 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;
|
||||
|
||||
// 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);
|
||||
|
||||
@@ -243,6 +243,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,40 @@ 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));
|
||||
|
||||
[[maybe_unused]]
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user