From e5b5fc449eefb49807881bd3c1393cd64b5ff6a2 Mon Sep 17 00:00:00 2001 From: Wolfe Date: Tue, 8 Oct 2024 13:58:34 -0700 Subject: [PATCH] Shader asserts are in. Thanks Alexey Gladkov aka @Rewlion! Example: /*$(Assert: i < 5, "i was %f", i)*/ See UserDocumentation/GigiShaders_Documentation for more info. Functionality: * Set Variables have support for min and max * Subgraph loops can use CONSTANT variables for loop count. Dynamic variable support coming later. Compiler: * Better error messaging when subgraphs fail to inline. Says what the problem is. * Large graphs were having slow downs due to ReferenceFixupVisitor scanning the graph too deeply too often. A visited flag cleaned this up. Viewer: * Variables can have a UI scope to group them better in the UI * Conditional Copy Resource nodes now say whether their condition is true or false in the render graph window. * Better protection against using bad formats for depth textures * Better explanation when a texture can't be created (like, when it has an invalid size specified) * New snapshots interface to be able to save and load cameras, variable values, imported resource settings, or what window is being viewed. Generalizes a couple pre-existing features that needed more functionality. --- .../Backends/DX12/Backend_DX12.cpp | 21 +- GigiCompilerLib/Backends/Shared.h | 2 +- GigiCompilerLib/SubGraphs.cpp | 72 +- GigiCompilerLib/gigicompiler.cpp | 22 +- GigiCompilerLib/gigiinterpreter.h | 6 + GigiEdit/MakeUI.h | 53 + GigiEdit/main.cpp | 19 + .../GigiInterpreterPreviewWindowDX12.cpp | 105 ++ .../GigiInterpreterPreviewWindowDX12.h | 33 +- .../GigiInterpreterPreviewWindowDX12_UI.cpp | 39 +- .../RenderGraphNode_Action_ComputeShader.cpp | 2 +- .../RenderGraphNode_Action_CopyResource.cpp | 5 + .../RenderGraphNode_Action_DrawCall.cpp | 8 + .../RenderGraphNode_Resource_Texture.cpp | 26 +- GigiViewerDX12/ViewerPython.cpp | 81 +- GigiViewerDX12/ViewerPython.h | 7 + GigiViewerDX12/main.cpp | 788 +++++----- MakeCode_UnitTests_DX12.py | 1 + README.md | 2 + RenderGraph/Visitors.h | 472 +++++- Schemas/PreviewWindow/PreviewWindowSchemas.h | 44 +- Schemas/RenderGraphNodes.h | 5 +- Schemas/Schemas.h | 7 + Schemas/SchemasShaders.h | 12 + Schemas/SchemasVariables.h | 3 +- Techniques/Denoising/SVGF/Atrous.gg | 237 +++ Techniques/Denoising/SVGF/ClearBuffersCS.hlsl | 19 + Techniques/Denoising/SVGF/ColorHelpers.slang | 415 +++++ Techniques/Denoising/SVGF/LICENSE.md | 26 + .../Denoising/SVGF/MathConstants.slangh | 130 ++ Techniques/Denoising/SVGF/MathHelpers.slang | 771 ++++++++++ Techniques/Denoising/SVGF/README.txt | 1 + Techniques/Denoising/SVGF/SVGF.gg | 1343 +++++++++++++++++ Techniques/Denoising/SVGF/SVGF.gguser | 172 +++ Techniques/Denoising/SVGF/SVGFAtrous.ps.slang | 154 ++ Techniques/Denoising/SVGF/SVGFCommon.slang | 64 + .../Denoising/SVGF/SVGFFilterMoments.ps.slang | 138 ++ .../Denoising/SVGF/SVGFFinalModulate.ps.slang | 46 + .../SVGF/SVGFPackLinearZAndNormal.ps.slang | 48 + .../Denoising/SVGF/SVGFReproject.ps.slang | 255 ++++ Techniques/Denoising/SVGF/SwapTextures.gg | 108 ++ Techniques/PostProcessing/BoxBlur/BoxBlur.gg | 221 +++ .../PostProcessing/BoxBlur/BoxBlur.gguser | 29 + .../PostProcessing/BoxBlur/BoxBlurCS.hlsl | 48 + Techniques/PostProcessing/DFT/DFT.gg | 193 +++ Techniques/PostProcessing/DFT/DFT.gguser | 27 + Techniques/PostProcessing/DFT/DFTCS.hlsl | 59 + .../PostProcessing/DFT/NormalizeCS.hlsl | 19 + .../DepthOfField/GatherDOF2018/BlurFarCS.hlsl | 71 + .../DepthOfField/GatherDOF2018/Common.hlsli | 84 ++ .../GatherDOF2018/DownscaleTileMap_1_4.hlsl | 22 + .../GatherDOF2018/FloodFillFarCS.hlsl | 88 ++ .../GatherDOF2018/NearBlurCS.hlsl | 61 + .../GatherDOF2018/NearBorderCS.hlsl | 38 + .../GatherDOF2018/NearHaloCS.hlsl | 37 + .../GatherDOF2018/RecombineCS.hlsl | 135 ++ .../DepthOfField/GatherDOF2018/SetupCS.hlsl | 176 +++ .../DepthOfField/GatherDOF2018/dof.gg | 1058 +++++++++++++ .../DepthOfField/GatherDOF2018/readme.txt | 3 + .../DepthOfField/Gustafsson2018/dof.gg | 147 ++ .../DepthOfField/Gustafsson2018/dof.hlsl | 71 + .../DepthOfField/Gustafsson2018/readme.txt | 4 + .../PostProcessing/DepthOfField/IW2007/dof.gg | 502 ++++++ .../DepthOfField/IW2007/dof_apply_dof.hlsl | 105 ++ .../IW2007/dof_blur_near_coc.hlsl | 32 + .../IW2007/dof_calculate_near_coc.hlsl | 20 + .../IW2007/dof_downsample_coc.hlsl | 83 + .../DepthOfField/IW2007/dof_gauss_blur.hlsl | 39 + .../DepthOfField/IW2007/readme.txt | 3 + .../PostProcessing/DepthOfField/dof_demo.gg | 959 ++++++++++++ .../DepthOfField/dof_demo.gguser | 1141 ++++++++++++++ .../DepthOfField/dof_demo_brightlight.hlsl | 86 ++ .../DepthOfField/dof_demo_ps.hlsl | 165 ++ .../DepthOfField/dof_demo_tonemap.hlsl | 124 ++ .../DepthOfField/dof_demo_vs.hlsl | 33 + .../DepthOfField/textures/background.png | 3 + .../DepthOfField/textures/background_bump.png | 3 + .../DepthOfField/textures/chain_texture.png | 3 + .../textures/chain_texture_bump.png | 3 + .../textures/chain_texture_mask.png | 3 + .../DepthOfField/textures/floor_gloss.png | 3 + .../DepthOfField/textures/lion.png | 3 + .../DepthOfField/textures/lion2_bump.png | 3 + .../DepthOfField/textures/lion_bump.png | 3 + .../textures/spnza_bricks_a_bump.png | 3 + .../textures/spnza_bricks_a_diff.png | 3 + .../textures/spnza_bricks_a_spec.png | 3 + .../textures/sponza_arch_bump.png | 3 + .../textures/sponza_arch_diff.png | 3 + .../textures/sponza_arch_spec.png | 3 + .../textures/sponza_ceiling_a_diff.png | 3 + .../textures/sponza_ceiling_a_spec.png | 3 + .../textures/sponza_column_a_bump.png | 3 + .../textures/sponza_column_a_diff.png | 3 + .../textures/sponza_column_a_spec.png | 3 + .../textures/sponza_column_b_bump.png | 3 + .../textures/sponza_column_b_diff.png | 3 + .../textures/sponza_column_b_spec.png | 3 + .../textures/sponza_column_c_bump.png | 3 + .../textures/sponza_column_c_diff.png | 3 + .../textures/sponza_column_c_spec.png | 3 + .../textures/sponza_curtain_blue_diff.png | 3 + .../textures/sponza_curtain_diff.png | 3 + .../textures/sponza_curtain_green_diff.png | 3 + .../textures/sponza_details_diff.png | 3 + .../textures/sponza_details_spec.png | 3 + .../textures/sponza_fabric_blue_diff.png | 3 + .../textures/sponza_fabric_diff.png | 3 + .../textures/sponza_fabric_green_diff.png | 3 + .../textures/sponza_fabric_purple.png | 3 + .../textures/sponza_fabric_spec.png | 3 + .../textures/sponza_flagpole_diff.png | 3 + .../textures/sponza_flagpole_spec.png | 3 + .../textures/sponza_floor_a_diff.png | 3 + .../textures/sponza_floor_a_spec.png | 3 + .../textures/sponza_roof_diff.png | 3 + .../textures/sponza_thorn_bump.png | 3 + .../textures/sponza_thorn_diff.png | 3 + .../textures/sponza_thorn_mask.png | 3 + .../textures/sponza_thorn_spec.png | 3 + .../DepthOfField/textures/vase_bump.png | 3 + .../DepthOfField/textures/vase_dif.png | 3 + .../DepthOfField/textures/vase_hanging.png | 3 + .../DepthOfField/textures/vase_plant.png | 3 + .../DepthOfField/textures/vase_plant_mask.png | 3 + .../DepthOfField/textures/vase_plant_spec.png | 3 + .../DepthOfField/textures/vase_round.png | 3 + .../DepthOfField/textures/vase_round_bump.png | 3 + .../DepthOfField/textures/vase_round_spec.png | 3 + .../PostProcessing/GaussBlur/GaussBlur.gg | 217 +++ .../PostProcessing/GaussBlur/GaussBlur.gguser | 33 + .../PostProcessing/GaussBlur/GaussBlurCS.hlsl | 87 ++ .../TemporalAccumulation/Accumulate.hlsl | 22 + .../TemporalAccumulation.gg | 114 ++ .../ShaderAssert/assertFormatting.gg | 28 + .../ShaderAssert/assertFormatting_cs.hlsl | 13 + .../UnitTests/ShaderAssert/assertsTest.py | 175 +++ .../ShaderAssert/noFmtStringAssert.gg | 28 + .../noFmtStringAssertWithStub_cs.hlsl | 9 + .../ShaderAssert/noFmtStringAssert_cs.hlsl | 7 + .../ShaderAssert/noFmtStringSubgraph.gg | 56 + .../ShaderAssert/sameShaderWithSubgraphs.gg | 83 + .../sameShaderWithSubgraphs.gguser | 1 + .../ShaderAssert/simpleAssertCsYes.gg | 28 + .../ShaderAssert/simpleAssertNO_vs.hlsl | 15 + .../ShaderAssert/simpleAssertVsNoPsYes.gg | 80 + .../ShaderAssert/simpleAssertVsNoPsYes.gguser | 1 + .../ShaderAssert/simpleAssertVsYesPsYes.gg | 80 + .../simpleAssertVsYesPsYes.gguser | 1 + .../ShaderAssert/simpleAssertYES_cs.hlsl | 7 + .../ShaderAssert/simpleAssertYES_ps.hlsl | 29 + .../ShaderAssert/simpleAssertYES_vs.hlsl | 15 + .../GigiShaders_Documentation.docx | Bin 144091 -> 143376 bytes .../GigiShaders_Documentation.pdf | Bin 275759 -> 292803 bytes .../GigiViewerDX12_Documentation.docx | Bin 27438 -> 26507 bytes .../GigiViewerDX12_Documentation.pdf | Bin 203278 -> 205286 bytes UserDocumentation/PythonTypes.txt | 51 +- external/df_serialize/Config.h | 8 +- external/df_serialize/MakeJSONWriteHeader.h | 4 +- gigihelp.html | 84 +- gigischema.json | 22 +- 161 files changed, 12633 insertions(+), 472 deletions(-) create mode 100644 Techniques/Denoising/SVGF/Atrous.gg create mode 100644 Techniques/Denoising/SVGF/ClearBuffersCS.hlsl create mode 100644 Techniques/Denoising/SVGF/ColorHelpers.slang create mode 100644 Techniques/Denoising/SVGF/LICENSE.md create mode 100644 Techniques/Denoising/SVGF/MathConstants.slangh create mode 100644 Techniques/Denoising/SVGF/MathHelpers.slang create mode 100644 Techniques/Denoising/SVGF/README.txt create mode 100644 Techniques/Denoising/SVGF/SVGF.gg create mode 100644 Techniques/Denoising/SVGF/SVGF.gguser create mode 100644 Techniques/Denoising/SVGF/SVGFAtrous.ps.slang create mode 100644 Techniques/Denoising/SVGF/SVGFCommon.slang create mode 100644 Techniques/Denoising/SVGF/SVGFFilterMoments.ps.slang create mode 100644 Techniques/Denoising/SVGF/SVGFFinalModulate.ps.slang create mode 100644 Techniques/Denoising/SVGF/SVGFPackLinearZAndNormal.ps.slang create mode 100644 Techniques/Denoising/SVGF/SVGFReproject.ps.slang create mode 100644 Techniques/Denoising/SVGF/SwapTextures.gg create mode 100644 Techniques/PostProcessing/BoxBlur/BoxBlur.gg create mode 100644 Techniques/PostProcessing/BoxBlur/BoxBlur.gguser create mode 100644 Techniques/PostProcessing/BoxBlur/BoxBlurCS.hlsl create mode 100644 Techniques/PostProcessing/DFT/DFT.gg create mode 100644 Techniques/PostProcessing/DFT/DFT.gguser create mode 100644 Techniques/PostProcessing/DFT/DFTCS.hlsl create mode 100644 Techniques/PostProcessing/DFT/NormalizeCS.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/GatherDOF2018/BlurFarCS.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/GatherDOF2018/Common.hlsli create mode 100644 Techniques/PostProcessing/DepthOfField/GatherDOF2018/DownscaleTileMap_1_4.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/GatherDOF2018/FloodFillFarCS.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/GatherDOF2018/NearBlurCS.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/GatherDOF2018/NearBorderCS.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/GatherDOF2018/NearHaloCS.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/GatherDOF2018/RecombineCS.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/GatherDOF2018/SetupCS.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/GatherDOF2018/dof.gg create mode 100644 Techniques/PostProcessing/DepthOfField/GatherDOF2018/readme.txt create mode 100644 Techniques/PostProcessing/DepthOfField/Gustafsson2018/dof.gg create mode 100644 Techniques/PostProcessing/DepthOfField/Gustafsson2018/dof.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/Gustafsson2018/readme.txt create mode 100644 Techniques/PostProcessing/DepthOfField/IW2007/dof.gg create mode 100644 Techniques/PostProcessing/DepthOfField/IW2007/dof_apply_dof.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/IW2007/dof_blur_near_coc.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/IW2007/dof_calculate_near_coc.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/IW2007/dof_downsample_coc.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/IW2007/dof_gauss_blur.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/IW2007/readme.txt create mode 100644 Techniques/PostProcessing/DepthOfField/dof_demo.gg create mode 100644 Techniques/PostProcessing/DepthOfField/dof_demo.gguser create mode 100644 Techniques/PostProcessing/DepthOfField/dof_demo_brightlight.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/dof_demo_ps.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/dof_demo_tonemap.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/dof_demo_vs.hlsl create mode 100644 Techniques/PostProcessing/DepthOfField/textures/background.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/background_bump.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/chain_texture.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/chain_texture_bump.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/chain_texture_mask.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/floor_gloss.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/lion.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/lion2_bump.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/lion_bump.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/spnza_bricks_a_bump.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/spnza_bricks_a_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/spnza_bricks_a_spec.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_arch_bump.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_arch_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_arch_spec.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_ceiling_a_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_ceiling_a_spec.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_column_a_bump.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_column_a_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_column_a_spec.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_column_b_bump.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_column_b_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_column_b_spec.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_column_c_bump.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_column_c_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_column_c_spec.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_curtain_blue_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_curtain_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_curtain_green_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_details_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_details_spec.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_blue_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_green_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_purple.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_spec.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_flagpole_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_flagpole_spec.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_floor_a_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_floor_a_spec.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_roof_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_bump.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_diff.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_mask.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_spec.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/vase_bump.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/vase_dif.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/vase_hanging.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/vase_plant.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/vase_plant_mask.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/vase_plant_spec.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/vase_round.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/vase_round_bump.png create mode 100644 Techniques/PostProcessing/DepthOfField/textures/vase_round_spec.png create mode 100644 Techniques/PostProcessing/GaussBlur/GaussBlur.gg create mode 100644 Techniques/PostProcessing/GaussBlur/GaussBlur.gguser create mode 100644 Techniques/PostProcessing/GaussBlur/GaussBlurCS.hlsl create mode 100644 Techniques/PostProcessing/TemporalAccumulation/Accumulate.hlsl create mode 100644 Techniques/PostProcessing/TemporalAccumulation/TemporalAccumulation.gg create mode 100644 Techniques/UnitTests/ShaderAssert/assertFormatting.gg create mode 100644 Techniques/UnitTests/ShaderAssert/assertFormatting_cs.hlsl create mode 100644 Techniques/UnitTests/ShaderAssert/assertsTest.py create mode 100644 Techniques/UnitTests/ShaderAssert/noFmtStringAssert.gg create mode 100644 Techniques/UnitTests/ShaderAssert/noFmtStringAssertWithStub_cs.hlsl create mode 100644 Techniques/UnitTests/ShaderAssert/noFmtStringAssert_cs.hlsl create mode 100644 Techniques/UnitTests/ShaderAssert/noFmtStringSubgraph.gg create mode 100644 Techniques/UnitTests/ShaderAssert/sameShaderWithSubgraphs.gg create mode 100644 Techniques/UnitTests/ShaderAssert/sameShaderWithSubgraphs.gguser create mode 100644 Techniques/UnitTests/ShaderAssert/simpleAssertCsYes.gg create mode 100644 Techniques/UnitTests/ShaderAssert/simpleAssertNO_vs.hlsl create mode 100644 Techniques/UnitTests/ShaderAssert/simpleAssertVsNoPsYes.gg create mode 100644 Techniques/UnitTests/ShaderAssert/simpleAssertVsNoPsYes.gguser create mode 100644 Techniques/UnitTests/ShaderAssert/simpleAssertVsYesPsYes.gg create mode 100644 Techniques/UnitTests/ShaderAssert/simpleAssertVsYesPsYes.gguser create mode 100644 Techniques/UnitTests/ShaderAssert/simpleAssertYES_cs.hlsl create mode 100644 Techniques/UnitTests/ShaderAssert/simpleAssertYES_ps.hlsl create mode 100644 Techniques/UnitTests/ShaderAssert/simpleAssertYES_vs.hlsl diff --git a/GigiCompilerLib/Backends/DX12/Backend_DX12.cpp b/GigiCompilerLib/Backends/DX12/Backend_DX12.cpp index cdac965f..f20e304f 100644 --- a/GigiCompilerLib/Backends/DX12/Backend_DX12.cpp +++ b/GigiCompilerLib/Backends/DX12/Backend_DX12.cpp @@ -1069,7 +1069,7 @@ struct BackendDX12 : public BackendBase stringReplacementMap[destinationString] << " = "; } - // Handle SetVariableOperator::BitwiseNot + // Handle operations which require a prefix to the operands if (setVar.op == SetVariableOperator::BitwiseNot) { const Variable& destVar = renderGraph.variables[setVar.destination.variableIndex]; @@ -1082,6 +1082,14 @@ struct BackendDX12 : public BackendBase { stringReplacementMap[destinationString] << "Pow2GE("; } + else if (setVar.op == SetVariableOperator::Minimum) + { + stringReplacementMap[destinationString] << "min("; + } + else if (setVar.op == SetVariableOperator::Maximum) + { + stringReplacementMap[destinationString] << "max("; + } // Write out the first operand if (setVar.AVar.variableIndex != -1) @@ -1120,6 +1128,9 @@ struct BackendDX12 : public BackendBase case SetVariableOperator::Divide: stringReplacementMap[destinationString] << " / "; break; case SetVariableOperator::Modulo: stringReplacementMap[destinationString] << " % "; break; + case SetVariableOperator::Minimum: + case SetVariableOperator::Maximum: stringReplacementMap[destinationString] << ", "; break; + case SetVariableOperator::BitwiseOr: stringReplacementMap[destinationString] << (destVarIsBool ? " || " : " | "); break; case SetVariableOperator::BitwiseAnd: stringReplacementMap[destinationString] << (destVarIsBool ? " && " : " & "); break; case SetVariableOperator::BitwiseXor: stringReplacementMap[destinationString] << " ^ "; break; @@ -1142,6 +1153,11 @@ struct BackendDX12 : public BackendBase { stringReplacementMap[destinationString] << setVar.BLiteral; } + + if (setVar.op == SetVariableOperator::Minimum || setVar.op == SetVariableOperator::Maximum) + { + stringReplacementMap[destinationString] << ")"; + } } // All done @@ -1815,6 +1831,9 @@ void CopyShaderFileDX12(const Shader& shader, const std::unordered_map& stringReplacementMap, const RenderGraph& renderGraph) { - // Gigi "preprocessor" + // Gigi preprocessor size_t offset = 0; while (1) { diff --git a/GigiCompilerLib/SubGraphs.cpp b/GigiCompilerLib/SubGraphs.cpp index 5c0af59b..8e4a6189 100644 --- a/GigiCompilerLib/SubGraphs.cpp +++ b/GigiCompilerLib/SubGraphs.cpp @@ -874,11 +874,51 @@ static bool InlineSubGraph(RenderGraph& parentGraph, RenderGraphNode_Action_SubG // Handle variable replacement // This is when subgraph variables are replaced by parent graph variables { + // Handle "replaceWithValue" - make a constant var with that as the default, and set replaceWithStr to it + { + for (SubGraphVariableSettings& variableSettings : subGraphNode.variableSettings) + { + if (variableSettings.replaceWithValue.empty()) + continue; + + int childVariableIndex = GetVariableIndex(childGraph, variableSettings.name.c_str()); + if (childVariableIndex == -1) + { + ShowErrorMessage("Could not find variable \"%s\" in \"%s\" for node \"%s\".", variableSettings.name.c_str(), childFileName.c_str(), subGraphNode.name.c_str()); + continue; + } + + // make a unique name for the new variable + char variableName[1024]; + int index = 0; + do + { + sprintf_s(variableName, "__literal_%i", index); + index++; + } + while (VariableNameExists(parentGraph, variableName)); + + // make a new variable in the parent graph + Variable newVariable; + newVariable.name = variableName; + newVariable.comment = "Made to replace variable \"" + variableSettings.name + "\" with a constant value in subgraph node \"" + subGraphNode.name + "\""; + newVariable.type = childGraph.variables[childVariableIndex].type; + newVariable.Const = true; + newVariable.dflt = variableSettings.replaceWithValue; + newVariable.transient = true; + parentGraph.variables.push_back(newVariable); + + // tell the subgraph to use this new variable instead + variableSettings.replaceWithStr = variableName; + } + } + // Replace variable references { RenameData renameData; for (const SubGraphVariableSettings& variableSettings : subGraphNode.variableSettings) { + // if no variable replacement to do, skip this if (variableSettings.replaceWithStr.empty() && !variableSettings.isLoopIndex) continue; @@ -1077,10 +1117,25 @@ bool ExpandLoopedSubgraphs(RenderGraph& renderGraph) const RenderGraphNode_Action_SubGraph& subGraph = node.actionSubGraph; - if (subGraph.loopCount > 1) + // Get the loop count + // If a variable is specified, it overrides the literal value given. + int loopCount = subGraph.loopCount; + if (!subGraph.loopCountVariable.name.empty()) + { + for (const Variable& var : renderGraph.variables) + { + if (var.name == subGraph.loopCountVariable.name) + { + sscanf_s(var.dflt.c_str(), "%i", &loopCount); + break; + } + } + } + + if (loopCount > 1) { // Loop over the number of iterations we want - for (int loopIdx = 0; loopIdx < subGraph.loopCount; ++loopIdx) + for (int loopIdx = 0; loopIdx < loopCount; ++loopIdx) { // Copy the original node RenderGraphNode loopNode = node; @@ -1111,7 +1166,7 @@ bool ExpandLoopedSubgraphs(RenderGraph& renderGraph) // If this is the last iteration, other nodes in the parent graph need to have references // to the original subgraph updated to point to the last iteration. - if (loopIdx == subGraph.loopCount-1) + if (loopIdx == loopCount-1) { renameData.m_nodeRenames[oldName] = loopSubGraph.name; } @@ -1304,8 +1359,15 @@ bool InlineSubGraphs(RenderGraph& renderGraph) // detect and report the error of not being able to make progress if (subgraphNodesRemain && !madeProgress) { - ShowErrorMessage("Unable to make progress inlining subgraphs"); - return false; + for (int nodeIndex = 0; nodeIndex < renderGraph.nodes.size(); ++nodeIndex) + { + RenderGraphNode& node = renderGraph.nodes[nodeIndex]; + if (node._index != RenderGraphNode::c_index_actionSubGraph) + continue; + + ShowErrorMessage("Unable to make progress inlining subgraphs. Node \"%s\" could not be inlined, are all of it's inputs plugged in?", node.actionSubGraph.name.c_str()); + return false; + } } } diff --git a/GigiCompilerLib/gigicompiler.cpp b/GigiCompilerLib/gigicompiler.cpp index 1cf6f854..407c7043 100644 --- a/GigiCompilerLib/gigicompiler.cpp +++ b/GigiCompilerLib/gigicompiler.cpp @@ -259,6 +259,21 @@ GigiCompileResult GigiCompile(GigiBuildFlavor buildFlavor, const std::string& js if (PostLoad) PostLoad(renderGraph); + // Shader references need to be resolved first + { + ShaderReferenceFixupVisitor visitor(renderGraph); + if (!Visit(renderGraph, visitor, "renderGraph")) + return GigiCompileResult::ReferenceFixup; + } + + // Process Asserts declarations inside shaders + if (backend == Backend::Interpreter) + { + ShaderAssertsVisitor visitor{ renderGraph }; + if (!Visit(renderGraph, visitor, "renderGraph")) + return GigiCompileResult::ShaderAsserts; + } + // Get data from shaders { ShaderDataVisitor visitor(renderGraph); @@ -273,13 +288,6 @@ GigiCompileResult GigiCompile(GigiBuildFlavor buildFlavor, const std::string& js return GigiCompileResult::Validation; } - // Shader references need to be resolved first - { - ShaderReferenceFixupVisitor visitor(renderGraph); - if (!Visit(renderGraph, visitor, "renderGraph")) - return GigiCompileResult::ReferenceFixup; - } - // resolve the node references from names into indices { ReferenceFixupVisitor visitor(renderGraph); diff --git a/GigiCompilerLib/gigiinterpreter.h b/GigiCompilerLib/gigiinterpreter.h index 2aaf8cd4..422081c3 100644 --- a/GigiCompilerLib/gigiinterpreter.h +++ b/GigiCompilerLib/gigiinterpreter.h @@ -376,6 +376,9 @@ class IGigiInterpreter break; } + case SetVariableOperator::Minimum: dest = std::min(A, B); break; + case SetVariableOperator::Maximum: dest = std::max(A, B); break; + case SetVariableOperator::Noop: dest = A; break; } } @@ -410,6 +413,9 @@ class IGigiInterpreter break; } + case SetVariableOperator::Minimum: dest = std::min(A, B); break; + case SetVariableOperator::Maximum: dest = std::max(A, B); break; + case SetVariableOperator::Noop: dest = A; break; } } diff --git a/GigiEdit/MakeUI.h b/GigiEdit/MakeUI.h index ad69e2c0..e06141cb 100644 --- a/GigiEdit/MakeUI.h +++ b/GigiEdit/MakeUI.h @@ -1483,7 +1483,58 @@ inline UIOverrideResult ShowUIOverride(RenderGraph& renderGraph, uint64_t _FLAGS // Sort the list of variables std::vector vars; for (const Variable& var : renderGraph.variables) + { + if (var.Const) + continue; + vars.push_back(var.name); + } + CaseInsensitiveSort(vars); + + // add a blank to the beginning + vars.insert(vars.begin(), ""); + + // Show a drop down + for (const std::string& label : vars) + { + bool is_selected = value.name == label; + std::string safeLabel = label + "##"; + if (ImGui::Selectable(safeLabel.c_str(), is_selected)) + { + value.name = label; + dirtyFlag = true; + } + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + + ImGui::EndCombo(); + } + ShowUIToolTip(tooltip); + + ImGui::SameLine(); + if (ArrowButton2("GoToData", ImGuiDir_Right, true, false)) + OnGoToVariable(value.name.c_str()); + ShowUIToolTip("Go to Variable"); + + ImGui::PopID(); + + return UIOverrideResult::Finished; +} + +inline UIOverrideResult ShowUIOverride(RenderGraph& renderGraph, uint64_t _FLAGS, bool& dirtyFlag, const char* label, const char* tooltip, VariableReferenceConstOnly& value, TypePathEntry path, ShowUIOverrideContext showUIOverrideContext) +{ + ImGui::PushID(label); + + if (ImGui::BeginCombo(label, value.name.c_str())) + { + // Sort the list of variables + std::vector vars; + for (const Variable& var : renderGraph.variables) + { + if (!var.Const) + continue; vars.push_back(var.name); + } CaseInsensitiveSort(vars); // add a blank to the beginning @@ -1922,6 +1973,8 @@ struct ShaderTypeCodeGenerator "struct VSInput\n" "{\n" "\tfloat3 position : POSITION;\n" + "\tuint vertexID : SV_VertexID;\n" + "\tuint instanceId : SV_InstanceID;\n" "\t//TODO: fill this out\n" "};\n" "\n" diff --git a/GigiEdit/main.cpp b/GigiEdit/main.cpp index a48df82f..42a491a6 100644 --- a/GigiEdit/main.cpp +++ b/GigiEdit/main.cpp @@ -1676,6 +1676,24 @@ struct Example : name << ")"; break; } + case SetVariableOperator::Minimum: + { + name << "Min("; + name << GetRHS(item.ALiteral, item.ANode, item.AVar, item.AVarIndex); + name << ","; + name << GetRHS(item.BLiteral, item.BNode, item.BVar, item.BVarIndex); + name << ")"; + break; + } + case SetVariableOperator::Maximum: + { + name << "Max("; + name << GetRHS(item.ALiteral, item.ANode, item.AVar, item.AVarIndex); + name << ","; + name << GetRHS(item.BLiteral, item.BNode, item.BVar, item.BVarIndex); + name << ")"; + break; + } case SetVariableOperator::BitwiseOr: { name << GetRHS(item.ALiteral, item.ANode, item.AVar, item.AVarIndex); @@ -1761,6 +1779,7 @@ struct Example : EnsureVariableExists("JitteredViewProjMtx", VariableVisibility::Host, DataFieldType::Float4x4, "1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f"); EnsureVariableExists("InvJitteredViewProjMtx", VariableVisibility::Host, DataFieldType::Float4x4, "1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f"); EnsureVariableExists("CameraPos", VariableVisibility::Host, DataFieldType::Float3, "0.0f, 0.0f, 0.0f"); + EnsureVariableExists("CameraAltitudeAzimuth", VariableVisibility::Host, DataFieldType::Float2, "0.0f, 0.0f"); EnsureVariableExists("CameraChanged", VariableVisibility::Host, DataFieldType::Bool, "false"); EnsureVariableExists("CameraJitter", VariableVisibility::Host, DataFieldType::Float2, "0.5f, 0.5f"); EnsureVariableExists("ShadingRateImageTileSize", VariableVisibility::Host, DataFieldType::Uint, "16"); diff --git a/GigiViewerDX12/Interpreter/GigiInterpreterPreviewWindowDX12.cpp b/GigiViewerDX12/Interpreter/GigiInterpreterPreviewWindowDX12.cpp index a23e4ca0..70b3677f 100644 --- a/GigiViewerDX12/Interpreter/GigiInterpreterPreviewWindowDX12.cpp +++ b/GigiViewerDX12/Interpreter/GigiInterpreterPreviewWindowDX12.cpp @@ -402,4 +402,109 @@ void RuntimeTypes::RenderGraphNode_Base::HandleViewableResource(GigiInterpreterP interpreter.m_commandList->CopyResource(resource, uploadBuffer->buffer); } } +} + +std::vector GigiInterpreterPreviewWindowDX12::MarkShaderAssertsForReadback() +{ + std::vector assertsBuffers; + const size_t nodesCount = m_renderGraph.nodes.size(); + for (size_t i = 0; i < nodesCount; ++i) + { + std::vector* viewableResources = nullptr; + RuntimeNodeDataLambda( + m_renderGraph.nodes[i], + [&](auto node, auto* runtimeData) + { + std::string renderGraphText; + + if (runtimeData) + viewableResources = &(runtimeData->m_viewableResources); + } + ); + + if (!viewableResources) + continue; + + for (RuntimeTypes::ViewableResource& res : *viewableResources) + { + std::string_view displayName = res.m_displayName; + const bool isAssertBuf = displayName.find("__GigiAssertUAV") != displayName.npos; + const bool isAfter = displayName.ends_with("(UAV - After)"); + if (isAssertBuf && isAfter) + { + res.m_wantsToBeViewed = true; + res.m_wantsToBeReadBack = true; + + assertsBuffers.push_back(&res); + } + } + } + + return assertsBuffers; +} + +void GigiInterpreterPreviewWindowDX12::CollectShaderAsserts(const std::vector& assertsBuffers) +{ + collectedAsserts.clear(); + + for (const RuntimeTypes::ViewableResource* res : assertsBuffers) + { + if (res->m_resourceReadback) + { + std::vector bytes(res->m_size[0]); + unsigned char* data = nullptr; + res->m_resourceReadback->Map(0, nullptr, reinterpret_cast(&data)); + if (!data) + continue; + + memcpy(bytes.data(), data, res->m_size[0]); + res->m_resourceReadback->Unmap(0, nullptr); + + const uint32_t* assertBufData = reinterpret_cast(bytes.data()); + const uint32_t isFired = assertBufData[0]; + const uint32_t fmtId = assertBufData[1]; + + const std::vector& fmtStrings = m_renderGraph.assertsFormatStrings; + if (fmtId >= fmtStrings.size()) + { + Assert(false, "OOB in asserts format strings array"); + return; + } + + const char* fmt = fmtStrings[fmtId].c_str(); + std::unordered_set& firedAsserts = m_renderGraph.firedAssertsIdentifiers; + const bool isNewAssert = firedAsserts.find(res->m_displayName) == firedAsserts.end(); + + if (isFired && isNewAssert) + { + firedAsserts.insert(res->m_displayName); + + std::string context = res->m_displayName.substr(0, res->m_displayName.find(':')); + + const float* v = reinterpret_cast(bytes.data() + 2 * sizeof(uint32_t)); + + const int fmtSize = std::snprintf(nullptr, 0, fmt, v[0], v[1], v[2], v[3], v[4], v[5]); + if (fmtSize <= 0) + { + Assert(false, "Failed to format the assert message '%s'", fmt); + return; + } + + std::string assertMsg; + assertMsg.resize(fmtSize+1); + std::snprintf(assertMsg.data(), fmtSize+1, fmt, v[0], v[1], v[2], v[3], v[4], v[5]); + + collectedAsserts.push_back({fmtId, fmt, std::move(context), std::move(assertMsg)}); + } + } + } +} + +void GigiInterpreterPreviewWindowDX12::LogCollectedShaderAsserts() const +{ + for (const FiredAssertInfo& a : collectedAsserts) + { + std::string msgHeader = "ASSERT FAILED: [" + a.displayName + "]"; + ShowErrorMessage("%s\nmsg: %s", msgHeader.data(), a.msg.data()); + } } \ No newline at end of file diff --git a/GigiViewerDX12/Interpreter/GigiInterpreterPreviewWindowDX12.h b/GigiViewerDX12/Interpreter/GigiInterpreterPreviewWindowDX12.h index 11e57a16..110fad70 100644 --- a/GigiViewerDX12/Interpreter/GigiInterpreterPreviewWindowDX12.h +++ b/GigiViewerDX12/Interpreter/GigiInterpreterPreviewWindowDX12.h @@ -480,6 +480,18 @@ class GigiInterpreterPreviewWindowDX12 : public IGigiInterpreter return m_profiler.GetProfilingData(); } + struct FiredAssertInfo + { + uint32_t formatStringId; + std::string fmt; + std::string displayName; + std::string msg; + }; + const std::vector& getCollectedShaderAsserts() const { return collectedAsserts; } + std::vector MarkShaderAssertsForReadback(); + void CollectShaderAsserts(const std::vector& assertsBuffers); + void LogCollectedShaderAsserts() const; + public: bool m_showVariablesUI = true; bool m_compileShadersForDebug = false; @@ -648,13 +660,15 @@ class GigiInterpreterPreviewWindowDX12 : public IGigiInterpreter enum class FileWatchOwner { - FileCache, + FileCache = 0, Shaders, TextureCache, ObjCache, FBXCache, PLYCache, GGFile, + + Count }; FileWatcher getFileWatcher() @@ -682,6 +696,8 @@ class GigiInterpreterPreviewWindowDX12 : public IGigiInterpreter bool DrawCall_MakeRootSignature(const RenderGraphNode_Action_DrawCall& node, RuntimeTypes::RenderGraphNode_Action_DrawCall& runtimeData); bool DrawCall_MakeDescriptorTableDesc(std::vector& descs, const RenderGraphNode_Action_DrawCall& node, const Shader& shader, int pinOffset, std::vector& queuedTransitions, const std::unordered_map& importantResourceStates); + std::vector collectedAsserts; + ID3D12Device2* m_device = nullptr; ID3D12CommandQueue* m_commandQueue = nullptr; ID3D12GraphicsCommandList* m_commandList = nullptr; @@ -739,3 +755,18 @@ class GigiInterpreterPreviewWindowDX12 : public IGigiInterpreter D3D12_FEATURE_DATA_D3D12_OPTIONS10 m_dx12_options10 = {}; D3D12_FEATURE_DATA_D3D12_OPTIONS11 m_dx12_options11 = {}; }; + +inline const char* EnumToString(GigiInterpreterPreviewWindowDX12::FileWatchOwner e) +{ + switch (e) + { + case GigiInterpreterPreviewWindowDX12::FileWatchOwner::FileCache: return "FileCache"; + case GigiInterpreterPreviewWindowDX12::FileWatchOwner::Shaders: return "Shaders"; + case GigiInterpreterPreviewWindowDX12::FileWatchOwner::TextureCache: return "TextureCache"; + case GigiInterpreterPreviewWindowDX12::FileWatchOwner::ObjCache: return "ObjCache"; + case GigiInterpreterPreviewWindowDX12::FileWatchOwner::FBXCache: return "FBXCache"; + case GigiInterpreterPreviewWindowDX12::FileWatchOwner::PLYCache: return "PLYCache"; + case GigiInterpreterPreviewWindowDX12::FileWatchOwner::GGFile: return "GGFile"; + default: return ""; + } +} diff --git a/GigiViewerDX12/Interpreter/GigiInterpreterPreviewWindowDX12_UI.cpp b/GigiViewerDX12/Interpreter/GigiInterpreterPreviewWindowDX12_UI.cpp index 5c34485f..f5cafc37 100644 --- a/GigiViewerDX12/Interpreter/GigiInterpreterPreviewWindowDX12_UI.cpp +++ b/GigiViewerDX12/Interpreter/GigiInterpreterPreviewWindowDX12_UI.cpp @@ -572,6 +572,22 @@ static void ShowUI_Count(const RenderGraph& renderGraph, const bool paused, cons // No-op. Shouldn't ever happen } +static std::string VariableUIScope(const Variable& variable) +{ + std::string ret; + + ret = variable.scope; + + if (!variable.UIGroup.empty()) + { + if (!ret.empty()) + ret += "."; + ret += variable.UIGroup + "."; + } + + return ret; +} + void GigiInterpreterPreviewWindowDX12::ShowUI(bool minimalUI, bool paused) { // Minimal UI only shows public variables. @@ -626,25 +642,26 @@ void GigiInterpreterPreviewWindowDX12::ShowUI(bool minimalUI, bool paused) ImGui::PushID(variableGroup.label); // get the list of scopes in this group of variables - std::unordered_set scopes; + std::unordered_set UIScopes; for (const RuntimeVariable& variable : m_runtimeVariables) { if (variable.variable->visibility != variableGroup.visibility) continue; - scopes.insert(variable.variable->scope); + std::string UIScope = VariableUIScope(*variable.variable); + UIScopes.insert(UIScope); } // make an alpha sorted list of scopes - std::vector scopesSorted; - for (const std::string& scope : scopes) - scopesSorted.push_back(scope); - std::sort(scopesSorted.begin(), scopesSorted.end()); + std::vector UIScopesSorted; + for (const std::string& UIScope : UIScopes) + UIScopesSorted.push_back(UIScope); + std::sort(UIScopesSorted.begin(), UIScopesSorted.end()); // show the scopes, one at a time, in alpha order bool visibilityHeaderShown = false; bool visibilityHeaderOpen = true; - for (const std::string& scope : scopesSorted) + for (const std::string& currentUIScope : UIScopesSorted) { // If this visibility header is closed, nothing to do if (!visibilityHeaderOpen) @@ -654,7 +671,7 @@ void GigiInterpreterPreviewWindowDX12::ShowUI(bool minimalUI, bool paused) std::vector runtimeVariablesSorted; for (const RuntimeVariable& variable : m_runtimeVariables) { - if (variable.variable->visibility != variableGroup.visibility || variable.variable->scope != scope) + if (variable.variable->visibility != variableGroup.visibility || VariableUIScope(*variable.variable) != currentUIScope) continue; runtimeVariablesSorted.push_back(&variable); @@ -678,15 +695,15 @@ void GigiInterpreterPreviewWindowDX12::ShowUI(bool minimalUI, bool paused) } // if the scope isn't empty, indent and make a collapsing header - if (!scope.empty()) + if (!currentUIScope.empty()) { - std::string scopeLabel = scope.substr(0, scope.length() - 1); // trim off the dot + std::string scopeLabel = currentUIScope.substr(0, currentUIScope.length() - 1); // trim off the dot if (!ImGui::CollapsingHeader(scopeLabel.c_str())) continue; } // push the scope to make the variable imgui IDs unique - ImGui::PushID(scope.c_str()); + ImGui::PushID(currentUIScope.c_str()); // Show variable labels and value for (const RuntimeVariable* var : runtimeVariablesSorted) diff --git a/GigiViewerDX12/Interpreter/RenderGraphNode_Action_ComputeShader.cpp b/GigiViewerDX12/Interpreter/RenderGraphNode_Action_ComputeShader.cpp index c6ff9651..700a7d54 100644 --- a/GigiViewerDX12/Interpreter/RenderGraphNode_Action_ComputeShader.cpp +++ b/GigiViewerDX12/Interpreter/RenderGraphNode_Action_ComputeShader.cpp @@ -329,7 +329,7 @@ bool GigiInterpreterPreviewWindowDX12::OnNodeAction(const RenderGraphNode_Action if (!desc.m_resource) { std::ostringstream ss; - ss << "Cannot run due to resource not existing:\n" << GetNodeTypeString(resourceNode) << " " << GetNodeName(resourceNode) << " (" << GetNodeOriginalName(resourceNode) << ")"; + ss << "Cannot run due to resource not existing:\n" << GetNodeTypeString(resourceNode) << " \"" << GetNodeName(resourceNode) << "\" (\"" << GetNodeOriginalName(resourceNode) << "\")"; runtimeData.m_renderGraphText = ss.str(); return true; } diff --git a/GigiViewerDX12/Interpreter/RenderGraphNode_Action_CopyResource.cpp b/GigiViewerDX12/Interpreter/RenderGraphNode_Action_CopyResource.cpp index 682ccc6a..0534b8b9 100644 --- a/GigiViewerDX12/Interpreter/RenderGraphNode_Action_CopyResource.cpp +++ b/GigiViewerDX12/Interpreter/RenderGraphNode_Action_CopyResource.cpp @@ -12,6 +12,11 @@ bool GigiInterpreterPreviewWindowDX12::OnNodeAction(const RenderGraphNode_Action if (nodeAction == NodeAction::Execute) { + std::ostringstream ss; + if (IsConditional(node.condition)) + ss << "\nCondition: " << (EvaluateCondition(node.condition) ? "true" : "false"); + runtimeData.m_renderGraphText = ss.str(); + bool executionConditionMet = EvaluateCondition(node.condition); if (!executionConditionMet) return true; diff --git a/GigiViewerDX12/Interpreter/RenderGraphNode_Action_DrawCall.cpp b/GigiViewerDX12/Interpreter/RenderGraphNode_Action_DrawCall.cpp index 97341db2..dd921c91 100644 --- a/GigiViewerDX12/Interpreter/RenderGraphNode_Action_DrawCall.cpp +++ b/GigiViewerDX12/Interpreter/RenderGraphNode_Action_DrawCall.cpp @@ -623,6 +623,14 @@ bool GigiInterpreterPreviewWindowDX12::DrawCall_MakeRootSignature(const RenderGr psoDesc.DepthStencilState.FrontFace.StencilFunc = DepthTestFunctionToD3D12_COMPARISON_FUNC(node.frontFaceStencilFunc); psoDesc.DepthStencilState.BackFace.StencilFunc = DepthTestFunctionToD3D12_COMPARISON_FUNC(node.backFaceStencilFunc); } + if (!textureInfoFormatInfo.isDepth) + { + static bool erroredHere = false; + if (!erroredHere) + m_logFn(LogLevel::Error, "Depth texture \"%s\" is not a valid depth format: %s", resourceNode.resourceTexture.name.c_str(), textureInfoFormatInfo.name); + erroredHere = true; + return SetupPSODescRet::False; + } } } diff --git a/GigiViewerDX12/Interpreter/RenderGraphNode_Resource_Texture.cpp b/GigiViewerDX12/Interpreter/RenderGraphNode_Resource_Texture.cpp index b35b55d6..ebae2f20 100644 --- a/GigiViewerDX12/Interpreter/RenderGraphNode_Resource_Texture.cpp +++ b/GigiViewerDX12/Interpreter/RenderGraphNode_Resource_Texture.cpp @@ -1077,7 +1077,31 @@ bool GigiInterpreterPreviewWindowDX12::OnNodeActionNotImported(const RenderGraph bool hasFileName = !node.loadFileName.empty() && FileNameSafe(node.loadFileName.c_str()); std::string fullLoadFileName = m_tempDirectory + "assets\\" + node.loadFileName; - if (desiredFormat != DXGI_FORMAT_FORCE_UINT && (hasSize || hasFileName) && !runtimeData.m_failed) + if (!(desiredFormat != DXGI_FORMAT_FORCE_UINT && (hasSize || hasFileName) && !runtimeData.m_failed)) + { + std::ostringstream ss; + ss << "Texture can't be created:"; + + if (desiredFormat == DXGI_FORMAT_FORCE_UINT) + { + ss << "\nCould not determine desired format of texture"; + } + + if (!(hasSize || hasFileName)) + { + ss << "\nCould not determine size of texture"; + if (!hasFileName && desiredSize[2] == 0) + ss << "\nThe z component of the texture size is 0, should be > 0."; + } + + if (runtimeData.m_failed) + { + ss << "\nCreation Failed"; + } + + runtimeData.m_renderGraphText = ss.str(); + } + else { std::vector loadedTextures; diff --git a/GigiViewerDX12/ViewerPython.cpp b/GigiViewerDX12/ViewerPython.cpp index ed7956e6..d8b94334 100644 --- a/GigiViewerDX12/ViewerPython.cpp +++ b/GigiViewerDX12/ViewerPython.cpp @@ -696,6 +696,80 @@ static PyObject* Python_GetGPUString(PyObject* self, PyObject* args) return Py_BuildValue("s", g_interface->GetGPUString().c_str()); } +static PyObject* Python_SetShaderAssertsLogging(PyObject* self, PyObject* args) +{ + int value = 1; + if (!PyArg_ParseTuple(args, "p:Python_SetShaderAssertsLogging", &value)) + return PyErr_Format(PyExc_TypeError, "type error in " __FUNCTION__ "()"); + + g_interface->SetShaderAssertsLogging(value == 1); + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject* Python_GetCollectedShaderAssertsCount(PyObject* self, PyObject* args) +{ + const int count = g_interface->GetCollectedShaderAssertsCount(); + return Py_BuildValue("i", count); +} + +static PyObject* Python_GetShaderAssertFormatStrId(PyObject* self, PyObject* args) +{ + int assertId = 1; + if (!PyArg_ParseTuple(args, "i:Python_GetShaderAssertFormatStrId", &assertId)) + return PyErr_Format(PyExc_TypeError, "type error in " __FUNCTION__ "()"); + + const int count = (int)g_interface->GetCollectedShaderAssertsCount(); + if (assertId >= count) + return PyErr_Format(PyExc_TypeError, "type error in " __FUNCTION__ "(). OOB access (id:%d, asserts count: %d)", assertId, count); + + const int strId = g_interface->GetShaderAssertFormatStrId(assertId); + return Py_BuildValue("i", strId); +} + +static PyObject* Python_GetShaderAssertFormatString(PyObject* self, PyObject* args) +{ + int assertId = 1; + if (!PyArg_ParseTuple(args, "i:Python_GetShaderAssertFormatString", &assertId)) + return PyErr_Format(PyExc_TypeError, "type error in " __FUNCTION__ "()"); + + const int count = (int)g_interface->GetCollectedShaderAssertsCount(); + if (assertId >= count) + return PyErr_Format(PyExc_TypeError, "type error in " __FUNCTION__ "(). OOB access (id:%d, asserts count: %d)", assertId, count); + + const std::string fmt = g_interface->GetShaderAssertFormatString(assertId); + return Py_BuildValue("s", fmt.c_str()); +} + +static PyObject* Python_GetShaderAssertDisplayName(PyObject* self, PyObject* args) +{ + int assertId = 1; + if (!PyArg_ParseTuple(args, "i:Python_GetShaderAssertDisplayName", &assertId)) + return PyErr_Format(PyExc_TypeError, "type error in " __FUNCTION__ "()"); + + const int count = (int)g_interface->GetCollectedShaderAssertsCount(); + if (assertId >= count) + return PyErr_Format(PyExc_TypeError, "type error in " __FUNCTION__ "(). OOB access (id:%d, asserts count: %d)", assertId, count); + + const std::string displayName = g_interface->GetShaderAssertDisplayName(assertId); + return Py_BuildValue("s", displayName.c_str()); +} + +static PyObject* Python_GetShaderAssertMsg(PyObject* self, PyObject* args) +{ + int assertId = 1; + if (!PyArg_ParseTuple(args, "i:Python_GetShaderAssertMsg", &assertId)) + return PyErr_Format(PyExc_TypeError, "type error in " __FUNCTION__ "()"); + + const int count = (int)g_interface->GetCollectedShaderAssertsCount(); + if (assertId >= count) + return PyErr_Format(PyExc_TypeError, "type error in " __FUNCTION__ "(). OOB access (id:%d, asserts count: %d)", assertId, count); + + const std::string msg = g_interface->GetShaderAssertMsg(assertId); + return Py_BuildValue("s", msg.c_str()); +} + // Enum FromString #include "external/df_serialize/_common.h" #define ENUM_BEGIN(_NAME, _DESCRIPTION) \ @@ -831,7 +905,12 @@ void PythonInit(PythonInterface* interface, int argc, char** argv, int firstPyth {"GGEnumLabel", Python_GGEnumLabel, METH_VARARGS, "Gets the string label of an enum defined in the loaded .gg file."}, {"GGEnumCount", Python_GGEnumCount, METH_VARARGS, "Returns the number of enum values for an enum defined in the loaded .gg file."}, {"GetGPUString", Python_GetGPUString, METH_VARARGS, "Returns the name of the gpu and driver version."}, - + {"SetShaderAssertsLogging", Python_SetShaderAssertsLogging, METH_VARARGS, "Toggles auto error logging of the collected shader asserts after a technique execution."}, + {"GetCollectedShaderAssertsCount", Python_GetCollectedShaderAssertsCount, METH_VARARGS, "Returns the number of collected shader asserts. Assert getters works with this collection."}, + {"GetShaderAssertFormatStrId", Python_GetShaderAssertFormatStrId, METH_VARARGS, "Returns the ID of format string of the specified shader assert."}, + {"GetShaderAssertFormatString", Python_GetShaderAssertFormatString, METH_VARARGS, "Returns the format string of the specified shader assert."}, + {"GetShaderAssertDisplayName", Python_GetShaderAssertDisplayName, METH_VARARGS, "Returns the display name of the specified shader assert."}, + {"GetShaderAssertMsg", Python_GetShaderAssertMsg, METH_VARARGS, "Returns the message of the specified assert."}, // Enum FromString and ToString functions #include "external/df_serialize/_common.h" #define ENUM_BEGIN(_NAME, _DESCRIPTION) \ diff --git a/GigiViewerDX12/ViewerPython.h b/GigiViewerDX12/ViewerPython.h index 314d14e4..57a227b8 100644 --- a/GigiViewerDX12/ViewerPython.h +++ b/GigiViewerDX12/ViewerPython.h @@ -69,6 +69,13 @@ class PythonInterface virtual void ForceEnableProfiling(bool forceEnable) = 0; virtual std::vector GetProfilingData() = 0; + virtual void SetShaderAssertsLogging(bool set) = 0; + virtual int GetCollectedShaderAssertsCount() = 0; + virtual int GetShaderAssertFormatStrId(int i) = 0; + virtual std::string GetShaderAssertFormatString(int i) = 0; + virtual std::string GetShaderAssertDisplayName(int i) = 0; + virtual std::string GetShaderAssertMsg(int i) = 0; + virtual void Log(LogLevel level, const char* msg, ...) = 0; virtual void OnExecuteFinished() = 0; diff --git a/GigiViewerDX12/main.cpp b/GigiViewerDX12/main.cpp index def0afbb..27e191d8 100644 --- a/GigiViewerDX12/main.cpp +++ b/GigiViewerDX12/main.cpp @@ -149,12 +149,6 @@ static bool g_imageLinearFilter = true; static bool g_hideUI = false; static bool g_hideResourceNodes = true; // in profiler, and render graph window. To reduce clutter of things that we don't care about. static bool g_onlyShowWrites = true; // Hide SRV, UAV before, etc. Only show the result of writes. -static bool g_hideFileCacheDetails = true; // in internal variables. To reduce clutter of things that we don't care about. -static bool g_hideTrackedFilesDetails = true; // in internal variables. To reduce clutter of things that we don't care about. -static bool g_hideObjectCacheDetails = true; // in internal variables. To reduce clutter of things that we don't care about. -static bool g_hideFBXCacheDetails = true; // in internal variables. To reduce clutter of things that we don't care about. -static bool g_hidePLYCacheDetails = true; // in internal variables. To reduce clutter of things that we don't care about. -static bool g_hideTextureCacheDetails = true; // in internal variables. To reduce clutter of things that we don't care about. static bool g_fullscreen = false; @@ -393,7 +387,6 @@ struct ResourceViewState float systemVarMouseState[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; float systemVarMouseStateLastFrame[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; -private: void StoreLast() { lastType = type; @@ -404,9 +397,8 @@ struct ResourceViewState static ResourceViewState g_resourceView; static GGUserFile_SystemVars g_systemVariables; -static std::vector g_bookmarks; -static std::vector g_importedResourcePresets; -static char g_importedResourcePresetsName[1024] = { 0 }; +static std::vector g_userSnapshots; +static int g_userSnapshotIndex = -1; // Forward declarations of helper functions bool CreateDeviceD3D(HWND hWnd); @@ -433,6 +425,8 @@ int g_executeTechniqueCountRemain = 0; bool g_executeTechnique = true; bool g_techniquePaused = false; +bool g_logCollectedShaderAsserts = true; + std::string g_commandLineLoadGGFileName; std::string g_runPyFileName; @@ -666,59 +660,91 @@ GGUserFile_ImportedResource ImportedResourceDesc_To_GGUserFile_ImportedResource( return outDesc; } -void SaveGGUserFile() +void ScatterSnapshotData(const GGUserFileV2Snapshot& snapshot, bool switchingSnapshots, bool loadCamera, bool loadView, bool loadResources) { - // if saving gguser files is disabled by script, don't do it - if (g_disableGGUserSave) - return; + if (loadCamera) + { + g_systemVariables.camera.cameraPos = snapshot.cameraPos; + g_systemVariables.camera.cameraAltitudeAzimuth = snapshot.cameraAltitudeAzimuth; + g_systemVariables.camera.cameraChanged = true; + } - // If we didn't properly load & compile the render graph, saving the gguser file would corrupt it, so we don't want to do that - if (!g_saveGGUserFile) - return; + if (loadView) + { + g_resourceView.type = (RuntimeTypes::ViewableResource::Type)snapshot.resourceViewType; + g_resourceView.nodeIndex = snapshot.resourceViewNodeIndex; + g_resourceView.resourceIndex = snapshot.resourceViewResourceIndex; + } - // nothing to do if no file name - if (g_renderGraphFileName.empty()) - return; + if (loadResources) + { + std::filesystem::path renderGraphDir = std::filesystem::path(g_renderGraphFileName).remove_filename(); + for (const GGUserFile_ImportedResource& inDesc : snapshot.importedResources) + { + GigiInterpreterPreviewWindowDX12::ImportedResourceDesc desc = GGUserFile_ImportedResource_To_ImportedResourceDesc(inDesc, renderGraphDir); - // make .gguser file name - std::string extension; - size_t extensionStart = g_renderGraphFileName.find_last_of("."); - if (extensionStart != std::string::npos) - extension = g_renderGraphFileName.substr(extensionStart); + if (!switchingSnapshots) + desc.stale = true; - std::string ggUserFileName; - if (extension == ".gg") - ggUserFileName = g_renderGraphFileName + "user"; - else - ggUserFileName = g_renderGraphFileName + ".gguser"; + desc.state = GigiInterpreterPreviewWindowDX12::ImportedResourceState::dirty; + + if (g_interpreter.m_importedResources.count(inDesc.nodeName) > 0) + { + desc.nodeIndex = g_interpreter.m_importedResources[inDesc.nodeName].nodeIndex; + desc.resourceIndex = g_interpreter.m_importedResources[inDesc.nodeName].resourceIndex; + } + + g_interpreter.m_importedResources[inDesc.nodeName] = desc; + } + } +} + +void ScatterSnapshotVariables(const GGUserFileV2Snapshot& snapshot) +{ + for (const auto& savedVariable : snapshot.savedVariables) + { + int rtVarIndex = g_interpreter.GetRuntimeVariableIndex(savedVariable.name.c_str()); + if (rtVarIndex == -1) + continue; + g_interpreter.SetRuntimeVariableFromString(rtVarIndex, savedVariable.value.c_str()); + } +} + +void GatherSnapshotData(GGUserFileV2Snapshot& snapshot) +{ + snapshot.resourceViewType = (int)g_resourceView.type; + snapshot.resourceViewNodeIndex = g_resourceView.nodeIndex; + snapshot.resourceViewResourceIndex = g_resourceView.resourceIndex; + + snapshot.cameraPos = g_systemVariables.camera.cameraPos; + snapshot.cameraAltitudeAzimuth = g_systemVariables.camera.cameraAltitudeAzimuth; - // Fill out the GGUserFile std::filesystem::path renderGraphDir = std::filesystem::path(g_renderGraphFileName).remove_filename(); - GGUserFile ggUserData; - ggUserData.resourceViewType = (int)g_resourceView.type; - ggUserData.resourceViewNodeIndex = g_resourceView.nodeIndex; - ggUserData.resourceViewResourceIndex = g_resourceView.resourceIndex; - ggUserData.syncInterval = g_syncInterval; + snapshot.importedResources.clear(); for (const auto& it : g_interpreter.m_importedResources) - ggUserData.importedResources.push_back(ImportedResourceDesc_To_GGUserFile_ImportedResource(it.first, it.second, renderGraphDir)); + snapshot.importedResources.push_back(ImportedResourceDesc_To_GGUserFile_ImportedResource(it.first, it.second, renderGraphDir)); // sort the names of the imported resources so we can save them in a stable (alphabetical) order - std::sort(ggUserData.importedResources.begin(), ggUserData.importedResources.end(), + std::sort(snapshot.importedResources.begin(), snapshot.importedResources.end(), [](const GGUserFile_ImportedResource& a, const GGUserFile_ImportedResource& b) { return a.nodeName < b.nodeName; } ); - ggUserData.systemVars = g_systemVariables; - ggUserData.bookmarks = g_bookmarks; - ggUserData.importedResourcePresets = g_importedResourcePresets; - // Fill out the variables for (int varIndex = 0; varIndex < g_interpreter.GetRuntimeVariableCount(); ++varIndex) { const auto& rtVar = g_interpreter.GetRuntimeVariable(varIndex); + // don't save const vars + if (rtVar.variable->Const) + continue; + + // don't save transient vars + if (rtVar.variable->transient) + continue; + // don't save system variables if (rtVar.variable->name == g_systemVariables.iResolution_varName || rtVar.variable->name == g_systemVariables.iTime_varName || @@ -739,31 +765,77 @@ void SaveGGUserFile() rtVar.variable->name == g_systemVariables.JitteredViewProjMtx_varName || rtVar.variable->name == g_systemVariables.InvJitteredViewProjMtx_varName || rtVar.variable->name == g_systemVariables.CameraPos_varName || + rtVar.variable->name == g_systemVariables.CameraAltitudeAzimuth_varName || rtVar.variable->name == g_systemVariables.CameraChanged_varName || rtVar.variable->name == g_systemVariables.CameraJitter_varName || rtVar.variable->name == g_systemVariables.WindowSize_varName || rtVar.variable->name == g_systemVariables.ShadingRateImageTileSize_varName) continue; - // don't save const vars, or transient vars - if (rtVar.variable->Const || rtVar.variable->transient) - continue; - GGUserFile_SavedVariable var; var.name = rtVar.variable->name; var.value = g_interpreter.GetRuntimeVariableValueAsString(varIndex); - ggUserData.savedVariables.push_back(var); + snapshot.savedVariables.push_back(var); } +} + +void SaveGGUserFile() +{ + // if saving gguser files is disabled by script, don't do it + if (g_disableGGUserSave) + return; + + // If we didn't properly load & compile the render graph, saving the gguser file would corrupt it, so we don't want to do that + if (!g_saveGGUserFile) + return; + + // nothing to do if no file name + if (g_renderGraphFileName.empty()) + return; + + // make .gguser file name + std::string extension; + size_t extensionStart = g_renderGraphFileName.find_last_of("."); + if (extensionStart != std::string::npos) + extension = g_renderGraphFileName.substr(extensionStart); + + std::string ggUserFileName; + if (extension == ".gg") + ggUserFileName = g_renderGraphFileName + "user"; + else + ggUserFileName = g_renderGraphFileName + ".gguser"; + + // Fill out the GGUserFile + GGUserFileV2 ggUserData; + GatherSnapshotData(ggUserData.snapshot); + ggUserData.syncInterval = g_syncInterval; + ggUserData.systemVars = g_systemVariables; + ggUserData.snapshots = g_userSnapshots; // Save the data WriteToJSONFile(ggUserData, ggUserFileName.c_str()); } -GGUserFile LoadGGUserFile() +// When we have more version we can string these conversions together +bool ConvertGGUserFile(const GGUserFileV1& oldFile, GGUserFileV2& newFile) +{ + newFile.syncInterval = oldFile.syncInterval; + newFile.systemVars = oldFile.systemVars; + + newFile.snapshot.resourceViewType = oldFile.resourceViewType; + newFile.snapshot.resourceViewNodeIndex = oldFile.resourceViewNodeIndex; + newFile.snapshot.resourceViewResourceIndex = oldFile.resourceViewResourceIndex; + newFile.snapshot.importedResources = oldFile.importedResources; + newFile.snapshot.savedVariables = oldFile.savedVariables; + + return true; +} + +GGUserFileV2 LoadGGUserFile() { // nothing to do if no file name if (g_renderGraphFileName.empty()) - return GGUserFile(); + return GGUserFileV2(); // make .gguser file name std::string extension; @@ -778,34 +850,45 @@ GGUserFile LoadGGUserFile() ggUserFileName = g_renderGraphFileName + ".gguser"; // only try to load it if the file exists - GGUserFile ggUserData; + GGUserFileV2 ggUserData; FILE* file = nullptr; fopen_s(&file, ggUserFileName.c_str(), "rb"); + bool loadFailed = false; if (file) { fclose(file); - if (!ReadFromJSONFile(ggUserData, ggUserFileName.c_str())) - ggUserData = GGUserFile(); + GGUserFileVersionOnly ggUserDataVersion; + if (ReadFromJSONFile(ggUserDataVersion, ggUserFileName.c_str())) + { + if (ggUserDataVersion.version == "1.0") + { + GGUserFileV1 ggUserDataOld; + + if (!ReadFromJSONFile(ggUserDataOld, ggUserFileName.c_str()) || !ConvertGGUserFile(ggUserDataOld, ggUserData)) + loadFailed = true; + } + else if (ggUserDataVersion.version == "2.0") + { + if (!ReadFromJSONFile(ggUserData, ggUserFileName.c_str())) + loadFailed = true; + } + else + { + loadFailed = true; + } + } + + if (loadFailed) + ggUserData = GGUserFileV2(); } // restore the saved data - std::filesystem::path renderGraphDir = std::filesystem::path(g_renderGraphFileName).remove_filename(); - g_resourceView.type = (RuntimeTypes::ViewableResource::Type)ggUserData.resourceViewType; - g_resourceView.nodeIndex = ggUserData.resourceViewNodeIndex; - g_resourceView.resourceIndex = ggUserData.resourceViewResourceIndex; - g_syncInterval = ggUserData.syncInterval; g_interpreter.m_importedResources.clear(); - for (const GGUserFile_ImportedResource& inDesc : ggUserData.importedResources) - { - GigiInterpreterPreviewWindowDX12::ImportedResourceDesc desc = GGUserFile_ImportedResource_To_ImportedResourceDesc(inDesc, renderGraphDir); - desc.stale = true; - g_interpreter.m_importedResources[inDesc.nodeName] = desc; - } - + ScatterSnapshotData(ggUserData.snapshot, false, true, true, true); + g_syncInterval = ggUserData.syncInterval; g_systemVariables = ggUserData.systemVars; - g_bookmarks = ggUserData.bookmarks; - g_importedResourcePresets = ggUserData.importedResourcePresets; - g_importedResourcePresetsName[0] = 0; + g_userSnapshots = ggUserData.snapshots; + g_userSnapshotIndex = -1; g_systemVariables.camera.cameraPos = g_systemVariables.camera.startingCameraPos; g_systemVariables.camera.cameraAltitudeAzimuth = g_systemVariables.camera.startingCameraAltitudeAzimuth; @@ -829,7 +912,7 @@ bool LoadGGFile(const char* fileName, bool preserveState) // save the old gg user file, and then load the new one after we change our file name SaveGGUserFile(); g_renderGraphFileName = fileName; - GGUserFile ggUserData = LoadGGUserFile(); + auto ggUserData = LoadGGUserFile(); // clear if we should if (g_renderGraphFileName.empty()) @@ -862,14 +945,7 @@ bool LoadGGFile(const char* fileName, bool preserveState) return false; } - // Load the saved variable values from the GGUser file, now that the render graph is loaded and compiled - for (const auto& savedVariable : ggUserData.savedVariables) - { - int rtVarIndex = g_interpreter.GetRuntimeVariableIndex(savedVariable.name.c_str()); - if (rtVarIndex == -1) - continue; - g_interpreter.SetRuntimeVariableFromString(rtVarIndex, savedVariable.value.c_str()); - } + ScatterSnapshotVariables(ggUserData.snapshot); // Set all const variables to their const value for (const Variable& variable : g_interpreter.GetRenderGraph().variables) @@ -1239,7 +1315,10 @@ void HandleMainMenu() if (ImGui::Button("Open Editor")) { char commandLine[1024]; - sprintf_s(commandLine, "GigiEdit.exe \"%s\"", g_renderGraphFileName.c_str()); + if (g_renderGraphFileName.empty()) + sprintf_s(commandLine, "GigiEdit.exe"); + else + sprintf_s(commandLine, "GigiEdit.exe \"%s\"", g_renderGraphFileName.c_str()); STARTUPINFOA si; ZeroMemory(&si, sizeof(si)); @@ -1628,6 +1707,7 @@ void ShowNodeDropDown(const std::string& label, int nodeType, std::string& value value = labelsStr[selection]; } +// if assignVariable is false, it will assign "value" the value from the variable template bool AssignVariable(const char* name, DataFieldType type, T value) { @@ -1660,7 +1740,7 @@ DirectX::XMMATRIX GetViewMatrix() return DirectX::XMMatrixTranslation(-g_systemVariables.camera.cameraPos[0], -g_systemVariables.camera.cameraPos[1], -g_systemVariables.camera.cameraPos[2]) * rot; } -void UpdateSystemVariables() +void SynchronizeSystemVariables() { auto context = ImGui::GetCurrentContext(); @@ -1695,19 +1775,24 @@ void UpdateSystemVariables() AssignVariable(g_systemVariables.WindowSize_varName.c_str(), DataFieldType::Float2, size); } + // Time AssignVariable(g_systemVariables.iTime_varName.c_str(), DataFieldType::Float, (float)(context->Time - g_startTime)); - if (g_forcedFrameDeltaTime > 0.0f) + // Frame Delta { - AssignVariable(g_systemVariables.iTimeDelta_varName.c_str(), DataFieldType::Float, g_forcedFrameDeltaTime); - AssignVariable(g_systemVariables.iFrameRate_varName.c_str(), DataFieldType::Float, 1.0f / g_forcedFrameDeltaTime); - } - else - { - AssignVariable(g_systemVariables.iTimeDelta_varName.c_str(), DataFieldType::Float, (float)context->IO.DeltaTime); - AssignVariable(g_systemVariables.iFrameRate_varName.c_str(), DataFieldType::Float, (float)context->IO.Framerate); + if (g_forcedFrameDeltaTime > 0.0f) + { + AssignVariable(g_systemVariables.iTimeDelta_varName.c_str(), DataFieldType::Float, g_forcedFrameDeltaTime); + AssignVariable(g_systemVariables.iFrameRate_varName.c_str(), DataFieldType::Float, 1.0f / g_forcedFrameDeltaTime); + } + else + { + AssignVariable(g_systemVariables.iTimeDelta_varName.c_str(), DataFieldType::Float, context->IO.DeltaTime); + AssignVariable(g_systemVariables.iFrameRate_varName.c_str(), DataFieldType::Float, context->IO.Framerate); + } } + // Frame Index AssignVariable(g_systemVariables.iFrame_varName.c_str(), DataFieldType::Int, g_techniqueFrameIndex); // Mouse @@ -1934,40 +2019,48 @@ void UpdateSystemVariables() } } - DirectX::XMMATRIX invProjMtx = DirectX::XMMatrixInverse(nullptr, projMtx); - DirectX::XMMATRIX invJitteredProjMtx = DirectX::XMMatrixInverse(nullptr, jitteredProjMtx); - - DirectX::XMMATRIX viewMtx = GetViewMatrix(); - DirectX::XMMATRIX invViewMtx = DirectX::XMMatrixInverse(nullptr, viewMtx); + { + DirectX::XMMATRIX invProjMtx = DirectX::XMMatrixInverse(nullptr, projMtx); + DirectX::XMMATRIX invJitteredProjMtx = DirectX::XMMatrixInverse(nullptr, jitteredProjMtx); - // Send all the camera info to the appropriate variables + DirectX::XMMATRIX viewMtx = GetViewMatrix(); + DirectX::XMMATRIX invViewMtx = DirectX::XMMatrixInverse(nullptr, viewMtx); - AssignVariable(g_systemVariables.ViewMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(viewMtx)); - AssignVariable(g_systemVariables.InvViewMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(invViewMtx)); + DirectX::XMMATRIX viewProjMtx = viewMtx * projMtx; + DirectX::XMMATRIX invViewProjMtx = XMMatrixInverse(nullptr, viewProjMtx); - AssignVariable(g_systemVariables.ProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(projMtx)); - AssignVariable(g_systemVariables.InvProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(invProjMtx)); + DirectX::XMMATRIX jitteredViewProjMtx = viewMtx * jitteredProjMtx; + DirectX::XMMATRIX invJitteredViewProjMtx = XMMatrixInverse(nullptr, jitteredViewProjMtx); - AssignVariable(g_systemVariables.JitteredProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(jitteredProjMtx)); - AssignVariable(g_systemVariables.InvJitteredProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(invJitteredProjMtx)); + // Camera Matrices + { + AssignVariable(g_systemVariables.ViewMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(viewMtx)); + AssignVariable(g_systemVariables.InvViewMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(invViewMtx)); - DirectX::XMMATRIX viewProjMtx = viewMtx * projMtx; - DirectX::XMMATRIX invViewProjMtx = XMMatrixInverse(nullptr, viewProjMtx); + AssignVariable(g_systemVariables.ProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(projMtx)); + AssignVariable(g_systemVariables.InvProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(invProjMtx)); - AssignVariable(g_systemVariables.ViewProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(viewProjMtx)); - AssignVariable(g_systemVariables.InvViewProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(invViewProjMtx)); + AssignVariable(g_systemVariables.JitteredProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(jitteredProjMtx)); + AssignVariable(g_systemVariables.InvJitteredProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(invJitteredProjMtx)); - DirectX::XMMATRIX jitteredViewProjMtx = viewMtx * jitteredProjMtx; - DirectX::XMMATRIX invJitteredViewProjMtx = XMMatrixInverse(nullptr, jitteredViewProjMtx); + AssignVariable(g_systemVariables.ViewProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(viewProjMtx)); + AssignVariable(g_systemVariables.InvViewProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(invViewProjMtx)); - AssignVariable(g_systemVariables.JitteredViewProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(jitteredViewProjMtx)); - AssignVariable(g_systemVariables.InvJitteredViewProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(invJitteredViewProjMtx)); + AssignVariable(g_systemVariables.JitteredViewProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(jitteredViewProjMtx)); + AssignVariable(g_systemVariables.InvJitteredViewProjMtx_varName.c_str(), DataFieldType::Float4x4, XMMatrixTranspose(invJitteredViewProjMtx)); + } - AssignVariable(g_systemVariables.CameraPos_varName.c_str(), DataFieldType::Float3, g_systemVariables.camera.cameraPos); + // Camera Position and altitude azimuth + // Variables read/write + AssignVariable(g_systemVariables.CameraPos_varName.c_str(), DataFieldType::Float3, g_systemVariables.camera.cameraPos); + AssignVariable(g_systemVariables.CameraAltitudeAzimuth_varName.c_str(), DataFieldType::Float2, g_systemVariables.camera.cameraAltitudeAzimuth); - AssignVariable(g_systemVariables.CameraJitter_varName.c_str(), DataFieldType::Float2, jitter); + // camera jitter + AssignVariable(g_systemVariables.CameraJitter_varName.c_str(), DataFieldType::Float2, jitter); - AssignVariable(g_systemVariables.ShadingRateImageTileSize_varName.c_str(), DataFieldType::Uint, g_interpreter.GetOptions6().ShadingRateImageTileSize); + // Shading rate image tile size + AssignVariable(g_systemVariables.ShadingRateImageTileSize_varName.c_str(), DataFieldType::Uint, g_interpreter.GetOptions6().ShadingRateImageTileSize); + } } } @@ -2158,10 +2251,7 @@ void ShowInternalVariables() ImGui::EndTable(); } - ImGui::SeparatorText(""); - ImGui::Checkbox("Hide File Cache Details", &g_hideFileCacheDetails); - - if (!g_hideFileCacheDetails) + if (ImGui::CollapsingHeader("File Cache")) { //hold values as they don't change that often to reduce CPU usage when vieweing interpreter states (internal variables) static std::vector c_file_cache_details_file_display; @@ -2200,54 +2290,20 @@ void ShowInternalVariables() } } - ImGui::SeparatorText(""); - ImGui::Checkbox("Hide Tracked Files Details", &g_hideTrackedFilesDetails); - - if (!g_hideTrackedFilesDetails) + if (ImGui::CollapsingHeader("Tracked Files")) { - //hold values as they don't change that often to reduce CPU usage when vieweing interpreter states (internal variables) - static std::vector c_file_watcher_details_file_display; - static std::vector c_file_watcher_details_file_type; - if (has_elapsed || c_file_watcher_details_file_display.size() == 0) { - c_file_watcher_details_file_display = {}; - c_file_watcher_details_file_type = {}; - for (auto const& ent1 : g_interpreter.getFileWatcher().getTrackedFiles()) { - auto const& key = ent1.first; - auto const& val = ent1.second; - auto const& type_data = val.data; - std::string base_filename = key.substr(key.find_last_of("/\\") + 1); - const char* for_display_name = base_filename.c_str(); - std::string for_display_type_tmp; - //TODO: can't properly display enum values of type GigiInterpreterPreviewWindowDX12::FileWatchOwner, so using it's index value to convert for now - int value_loc = static_cast(type_data); - switch (value_loc) - { - case 0: - for_display_type_tmp = "FileCache"; - break; - case 1: - for_display_type_tmp = "Shaders"; - break; - case 2: - for_display_type_tmp = "TextureCache"; - break; - case 3: - for_display_type_tmp = "ObjCache"; - break; - case 4: - for_display_type_tmp = "FBXCache"; - break; - case 5: - for_display_type_tmp = "PLYCache"; - break; - case 6: - for_display_type_tmp = "GGFile"; - break; - } - const char* for_display_type = for_display_type_tmp.c_str(); - c_file_watcher_details_file_display.push_back(for_display_name); - c_file_watcher_details_file_type.push_back(for_display_type); + static int filterSelected = -1; + if (ImGui::BeginCombo("Type", filterSelected == -1 ? "All" : EnumToString((GigiInterpreterPreviewWindowDX12::FileWatchOwner)filterSelected))) + { + if (ImGui::Selectable("All", filterSelected == -1)) + filterSelected = -1; + + for (int typeIndex = 0; typeIndex < (int)GigiInterpreterPreviewWindowDX12::FileWatchOwner::Count; ++typeIndex) + { + if (ImGui::Selectable(EnumToString((GigiInterpreterPreviewWindowDX12::FileWatchOwner)typeIndex), filterSelected == typeIndex)) + filterSelected = typeIndex; } + ImGui::EndCombo(); } if (ImGui::BeginTable("tracked files details", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) @@ -2258,25 +2314,31 @@ void ShowInternalVariables() ImGui::TableHeadersRow(); ImGui::TableNextRow(); ImGui::TableNextColumn(); - for (int rowCtr = 0; rowCtr < c_file_watcher_val; rowCtr++) { - ImGui::Text("%d", rowCtr + 1); - const char* file_name = c_file_watcher_details_file_display[rowCtr].c_str(); - const char* file_type = c_file_watcher_details_file_type[rowCtr].c_str(); + + int index = 0; + for (auto const& entry : g_interpreter.getFileWatcher().getTrackedFiles()) + { + auto const& key = entry.first; + auto const& val = entry.second; + + if (filterSelected != -1 && (int)val.data != filterSelected) + continue; + + ImGui::Text("%d", index); ImGui::TableNextColumn(); - ImGui::TextUnformatted(file_name); + ImGui::TextUnformatted(key.substr(key.find_last_of("/\\") + 1).c_str()); + ShowToolTip(key.c_str()); ImGui::TableNextColumn(); - ImGui::TextUnformatted(file_type); + ImGui::TextUnformatted(EnumToString(val.data)); ImGui::TableNextRow(); ImGui::TableNextColumn(); + index++; } ImGui::EndTable(); } } - ImGui::SeparatorText(""); - ImGui::Checkbox("Hide Object Cache Details", &g_hideObjectCacheDetails); - - if (!g_hideObjectCacheDetails) + if (ImGui::CollapsingHeader("OBJ Cache")) { //hold values as they don't change that often to reduce CPU usage when vieweing interpreter states (internal variables) static std::vector c_obj_cache_details_file_display; @@ -2327,10 +2389,7 @@ void ShowInternalVariables() } } - ImGui::SeparatorText(""); - ImGui::Checkbox("Hide FBX Cache Details", &g_hideFBXCacheDetails); - - if (!g_hideFBXCacheDetails) + if (ImGui::CollapsingHeader("FBX Cache")) { //hold values as they don't change that often to reduce CPU usage when vieweing interpreter states (internal variables) static std::vector c_fbx_cache_details_file_display; @@ -2370,10 +2429,7 @@ void ShowInternalVariables() } } - ImGui::SeparatorText(""); - ImGui::Checkbox("Hide PLY Cache Details", &g_hidePLYCacheDetails); - - if (!g_hidePLYCacheDetails) + if (ImGui::CollapsingHeader("PLY Cache")) { //hold values as they don't change that often to reduce CPU usage when vieweing interpreter states (internal variables) static std::vector c_ply_cache_details_file_display; @@ -2416,10 +2472,7 @@ void ShowInternalVariables() } } - ImGui::SeparatorText(""); - ImGui::Checkbox("Hide Texture Cache Details", &g_hideTextureCacheDetails); - - if (!g_hideTextureCacheDetails) + if (ImGui::CollapsingHeader("Texture Cache")) { //hold values as they don't change that often to reduce CPU usage when vieweing interpreter states (internal variables) static std::vector c_texture_cache_details_file_display; @@ -2530,6 +2583,7 @@ void ShowSystemVariables() ImGui::SeparatorText("Camera Variables"); ShowVariableDropDown("CameraPos", DataFieldType::Float3, g_systemVariables.CameraPos_varName); + ShowVariableDropDown("CameraAltitudeAzimuth", DataFieldType::Float2, g_systemVariables.CameraAltitudeAzimuth_varName); ShowVariableDropDown("Camera Changed", DataFieldType::Bool, g_systemVariables.CameraChanged_varName); ShowVariableDropDown("View Matrix", DataFieldType::Float4x4, g_systemVariables.ViewMtx_varName); @@ -2624,7 +2678,7 @@ void ShowShaders() std::sort(scopesSorted.begin(), scopesSorted.end()); // for each scope - for const std::string& scope: scopesSorted) + for (const std::string& scope: scopesSorted) { // get a sorted list of shaders in this scope std::vector sortedShaders; @@ -2780,101 +2834,6 @@ void ShowImportedResources() return; } - // Show imported resource preset drop down - { - std::vector presets; - for (const GGUserFile_ImportedResourcePreset& preset : g_importedResourcePresets) - presets.push_back(preset.name.c_str()); - - std::sort(presets.begin(), presets.end(), [](const char* A, const char* B) { return strcmp(A, B) < 0; }); - presets.insert(presets.begin(), "Presets"); - - float comboWidth = 0.0f; - for (const char* s : presets) - comboWidth = std::max(comboWidth, ImGui::CalcTextSize(s).x + ImGui::GetStyle().FramePadding.x * 2.0f); - - ImGui::SetNextItemWidth(comboWidth + ImGui::GetTextLineHeightWithSpacing() + 10); - int selectedIndex = 0; - if (ImGui::Combo("##Presets", &selectedIndex, presets.data(), (int)presets.size())) - { - selectedIndex--; - if (selectedIndex >= 0 && selectedIndex < presets.size()) - { - std::filesystem::path renderGraphDir = std::filesystem::path(g_renderGraphFileName).remove_filename(); - - // map the index from the alpha sorted list back to the unsorted list - for (size_t i = 0; i < g_importedResourcePresets.size(); ++i) - { - if (g_importedResourcePresets[i].name == presets[selectedIndex + 1]) - { - selectedIndex = (int)i; - break; - } - } - - // Set the preset name box - strcpy(g_importedResourcePresetsName, g_importedResourcePresets[selectedIndex].name.c_str()); - - // Load the preset - for (const GGUserFile_ImportedResource& preset : g_importedResourcePresets[selectedIndex].importedResources) - { - if (g_interpreter.m_importedResources.count(preset.nodeName) == 0) - continue; - - GigiInterpreterPreviewWindowDX12::ImportedResourceDesc& importedResource = g_interpreter.m_importedResources[preset.nodeName]; - - int nodeIndex = importedResource.nodeIndex; - int resourceIndex = importedResource.resourceIndex; - - importedResource = GGUserFile_ImportedResource_To_ImportedResourceDesc(preset, renderGraphDir); - importedResource.state = GigiInterpreterPreviewWindowDX12::ImportedResourceState::dirty; - - importedResource.nodeIndex = nodeIndex; - importedResource.resourceIndex = resourceIndex; - } - } - } - } - - // Preset name and save button - { - ImGui::InputText("##Preset", g_importedResourcePresetsName, _countof(g_importedResourcePresetsName)); - - ImGui::SameLine(); - if (ImGui::Button("Save")) - { - std::filesystem::path renderGraphDir = std::filesystem::path(g_renderGraphFileName).remove_filename(); - - // Find the index (by name) to over write, or make a new index for it - int index = 0; - while (index < g_importedResourcePresets.size() && _stricmp(g_importedResourcePresets[index].name.c_str(), g_importedResourcePresetsName)) - index++; - if (index == g_importedResourcePresets.size()) - g_importedResourcePresets.resize(index + 1); - GGUserFile_ImportedResourcePreset& preset = g_importedResourcePresets[index]; - - // save the data - preset.name = g_importedResourcePresetsName; - preset.importedResources.clear(); - for (auto& it : g_interpreter.m_importedResources) - preset.importedResources.push_back(ImportedResourceDesc_To_GGUserFile_ImportedResource(it.first, it.second, renderGraphDir)); - } - - ImGui::SameLine(); - if (ImGui::Button("Delete")) - { - g_importedResourcePresets.erase( - std::remove_if(g_importedResourcePresets.begin(), g_importedResourcePresets.end(), - [&](const GGUserFile_ImportedResourcePreset& preset) - { - return preset.name == g_importedResourcePresetsName; - } - ), - g_importedResourcePresets.end() - ); - } - } - // Put the imported resources into alphabetical order struct ImportedResourceInfo { @@ -3455,6 +3414,19 @@ void ShowLog() return; } + if (ImGui::Button("Copy")) + { + std::ostringstream text; + constexpr const char* msgType[3] = { "", "[Warning] ", "[Error] " }; + for (const auto& msg : g_log) + text << msgType[static_cast(msg.level)] << msg.msg.c_str() << "\n"; + + std::string textStr = text.str(); + + SetClipboardDataEx(CF_TEXT, (void*)textStr.c_str(), (DWORD)textStr.length() + 1); + } + + ImGui::SameLine(); if (ImGui::Button("Clear")) g_log.clear(); @@ -5145,68 +5117,143 @@ void ShowResourceView() return; } - if (!g_hideUI || g_bookmarks.size() > 1) // only show the bookmark drop down in hide ui mode if there is more than 1 book mark + // show snapshot drop down, even when UI is hidden, as that user may want to use it. { - // Show the bookmark drop down - { - // make a list of bookmarks for the drop down - std::vector bookmarks; - for (const GGUserFile_Bookmark& bookmark : g_bookmarks) - bookmarks.push_back(bookmark.name.c_str()); + std::vector snapshots; + for (const GGUserFileV2Snapshot& snapshot : g_userSnapshots) + snapshots.push_back(snapshot.name.c_str()); - // sort bookmarks alphabetically - std::sort(bookmarks.begin(), bookmarks.end(), [](const char* A, const char* B) { return strcmp(A, B) < 0; }); - bookmarks.insert(bookmarks.begin(), "Bookmarks"); + std::sort(snapshots.begin(), snapshots.end(), [](const char* A, const char* B) { return strcmp(A, B) < 0; }); - float comboWidth = 0.0f; - for (const char* s : bookmarks) - comboWidth = std::max(comboWidth, ImGui::CalcTextSize(s).x + ImGui::GetStyle().FramePadding.x * 2.0f); + float comboWidth = ImGui::CalcTextSize("Snapshots").x + ImGui::GetStyle().FramePadding.x * 2.0f; + ImGui::SetNextItemWidth(comboWidth + ImGui::GetTextLineHeightWithSpacing() + 10); - ImGui::SetNextItemWidth(comboWidth + ImGui::GetTextLineHeightWithSpacing() + 10); - int selected = 0; - if (ImGui::Combo("##Bookmarks", &selected, bookmarks.data(), (int)bookmarks.size())) + int deleteIndex = -1; + if (ImGui::BeginCombo("##Snapshots", "Snapshots", ImGuiComboFlags_HeightLargest)) + { + if (ImGui::BeginTable("snapshots", 2, ImGuiTableFlags_None)) { - int selectedBookmarkIndex = -1; - for (const GGUserFile_Bookmark& bookmark : g_bookmarks) + ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed); + + for (int snapShotNameIndex = 0; snapShotNameIndex < snapshots.size(); ++snapShotNameIndex) { - selectedBookmarkIndex++; - if (bookmark.name == bookmarks[selected]) - break; + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + + const char* snapshotName = snapshots[snapShotNameIndex]; + + ImGui::Text(snapshotName); + + ImGui::TableNextColumn(); + + ImGui::PushID(snapShotNameIndex); + + for (int i = 0; i < g_userSnapshots.size(); ++i) + { + if (!strcmp(g_userSnapshots[i].name.c_str(), snapshotName)) + { + ImGui::Checkbox("Vars", &g_userSnapshots[i].loadVars); + ImGui::SameLine(); + + ImGui::Checkbox("Camera", &g_userSnapshots[i].loadCamera); + ImGui::SameLine(); + + ImGui::Checkbox("Resources", &g_userSnapshots[i].loadResources); + ImGui::SameLine(); + + ImGui::Checkbox("View", &g_userSnapshots[i].loadView); + ImGui::SameLine(); + + break; + } + } + + if (ImGui::Button("Load")) + { + for (int i = 0; i < g_userSnapshots.size(); ++i) + { + if (!strcmp(g_userSnapshots[i].name.c_str(), snapshotName)) + { + if (g_userSnapshots[i].loadView) // make this work with the A/B button + g_resourceView.StoreLast(); + + ScatterSnapshotData(g_userSnapshots[i], true, g_userSnapshots[i].loadCamera, g_userSnapshots[i].loadView, g_userSnapshots[i].loadResources); + + if (g_userSnapshots[i].loadVars) + ScatterSnapshotVariables(g_userSnapshots[i]); + break; + } + } + } + + ImGui::SameLine(); + if (ImGui::Button("Save")) + { + for (int i = 0; i < g_userSnapshots.size(); ++i) + { + if (!strcmp(g_userSnapshots[i].name.c_str(), snapshotName)) + { + GatherSnapshotData(g_userSnapshots[i]); + break; + } + } + } + ImGui::SameLine(); + if (ImGui::Button("Delete")) + deleteIndex = snapShotNameIndex; + + ImGui::PopID(); } - bool found = false; - if (selectedBookmarkIndex >= 0) - for (int nodeIndex : renderGraph.flattenedNodeList) + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + + static char newSnapshotName[512] = { 0 }; + ImGui::InputText("##NewSnapshot", newSnapshotName, _countof(newSnapshotName)); + ImGui::SameLine(); + if (ImGui::Button("Save") && newSnapshotName[0] != 0) { - g_interpreter.RuntimeNodeDataLambda( - renderGraph.nodes[nodeIndex], - [&](auto node, auto* runtimeData) + int existingIndex = -1; + for (int i = 0; i < g_userSnapshots.size(); ++i) + { + if (!strcmp(g_userSnapshots[i].name.c_str(), newSnapshotName)) { - int resourceIndex = -1; - for (const RuntimeTypes::ViewableResource& viewableResource : runtimeData->m_viewableResources) + existingIndex = i; + break; + } + } + + if (existingIndex == -1) + { + existingIndex = (int)g_userSnapshots.size(); + g_userSnapshots.resize(existingIndex + 1); + g_userSnapshots[existingIndex].name = newSnapshotName; + } + + GatherSnapshotData(g_userSnapshots[existingIndex]); + + newSnapshotName[0] = 0; + } + + ImGui::TableNextColumn(); + + ImGui::EndTable(); + + ImGui::EndCombo(); + + if (deleteIndex >= 0) + { + g_userSnapshots.erase( + std::remove_if(g_userSnapshots.begin(), g_userSnapshots.end(), + [&](const GGUserFileV2Snapshot& snapshot) { - resourceIndex++; - if (viewableResource.m_displayName == g_bookmarks[selectedBookmarkIndex].viewableResourceDisplayName) - { - found = true; - switch (viewableResource.m_type) - { - case RuntimeTypes::ViewableResource::Type::Texture2D: - case RuntimeTypes::ViewableResource::Type::Texture2DArray: - case RuntimeTypes::ViewableResource::Type::Texture3D: - case RuntimeTypes::ViewableResource::Type::TextureCube: g_resourceView.Texture(node.nodeIndex, resourceIndex, viewableResource.m_type); break; - case RuntimeTypes::ViewableResource::Type::ConstantBuffer: g_resourceView.ConstantBuffer(node.nodeIndex, resourceIndex); break; - case RuntimeTypes::ViewableResource::Type::Buffer: g_resourceView.Buffer(node.nodeIndex, resourceIndex); break; - } - } + return snapshot.name == snapshots[deleteIndex]; } - } + ), + g_userSnapshots.end() ); } - - // if the bookmark selected wasn't found, delete it - if (!found && selectedBookmarkIndex >= 0) - g_bookmarks.erase(g_bookmarks.begin() + selectedBookmarkIndex); } } } @@ -5236,55 +5283,6 @@ void ShowResourceView() res.m_wantsToBeReadBack = true; } - // Let the user edit the bookmark name of this resource - if (!g_hideUI) - { - char bookmarkName[1024]; - bookmarkName[0] = 0; - int existingBookmarkIndex = -1; - for (int bookmarkIndex = 0; bookmarkIndex < g_bookmarks.size(); ++bookmarkIndex) - { - const GGUserFile_Bookmark& bookmark = g_bookmarks[bookmarkIndex]; - - if (bookmark.viewableResourceDisplayName == res.m_displayName) - { - existingBookmarkIndex = bookmarkIndex; - strcpy(bookmarkName, bookmark.name.c_str()); - break; - } - } - - ImGui::SameLine(); - ImGui::SetNextItemWidth(200.0f); - if (ImGui::InputText("Bookmark", bookmarkName, 1024)) - { - // If there is a bookmark name - if (strlen(bookmarkName) > 0) - { - // Add a new bookmark if it doesn't already exist - if (existingBookmarkIndex == -1) - { - GGUserFile_Bookmark newBookmark; - newBookmark.name = bookmarkName; - newBookmark.viewableResourceDisplayName = res.m_displayName; - g_bookmarks.push_back(newBookmark); - } - // else update it - else - { - g_bookmarks[existingBookmarkIndex].name = bookmarkName; - } - } - // else there is not a bookmark name - else - { - // If there is a bookmark, we need to remove it - if (existingBookmarkIndex != -1) - g_bookmarks.erase(g_bookmarks.begin() + existingBookmarkIndex); - } - } - } - if (!g_hideUI) { ImGui::SameLine(); @@ -6863,6 +6861,40 @@ class Python : public PythonInterface return ret; } + void SetShaderAssertsLogging(bool set) override final + { + g_logCollectedShaderAsserts = set; + } + + int GetCollectedShaderAssertsCount() override final + { + return (int)g_interpreter.getCollectedShaderAsserts().size(); + } + + int GetShaderAssertFormatStrId(int i) override final + { + const auto& asserts = g_interpreter.getCollectedShaderAsserts(); + return (int)asserts[i].formatStringId; + } + + std::string GetShaderAssertFormatString(int i) override final + { + const auto& asserts = g_interpreter.getCollectedShaderAsserts(); + return asserts[i].fmt; + } + + std::string GetShaderAssertDisplayName(int i) override final + { + const auto& asserts = g_interpreter.getCollectedShaderAsserts(); + return asserts[i].displayName; + } + + std::string GetShaderAssertMsg(int i) override final + { + const auto& asserts = g_interpreter.getCollectedShaderAsserts(); + return asserts[i].msg; + } + int GGEnumValue(const char* enumName, const char* enumLabel) override final { const RenderGraph& renderGraph = g_interpreter.GetRenderGraph(); @@ -6987,7 +7019,7 @@ Python g_python; void RenderFrame(bool forceExecute) { - UpdateSystemVariables(); + SynchronizeSystemVariables(); // Start the Dear ImGui frame ImGui_ImplDX12_NewFrame(); @@ -7024,6 +7056,8 @@ void RenderFrame(bool forceExecute) g_pd3dCommandList->Reset(frameCtx->CommandAllocator, NULL); + std::vector assertsBuffers = g_interpreter.MarkShaderAssertsForReadback(); + // Run the Gigi technique if we should g_python.Tick(); g_interpreter.Tick(); @@ -7034,6 +7068,10 @@ void RenderFrame(bool forceExecute) g_techniqueFrameIndex++; } + g_interpreter.CollectShaderAsserts(assertsBuffers); + if (g_logCollectedShaderAsserts) + g_interpreter.LogCollectedShaderAsserts(); + D3D12_RESOURCE_BARRIER barrier = {}; barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; diff --git a/MakeCode_UnitTests_DX12.py b/MakeCode_UnitTests_DX12.py index a2c6ec54..5d74a4c3 100644 --- a/MakeCode_UnitTests_DX12.py +++ b/MakeCode_UnitTests_DX12.py @@ -22,6 +22,7 @@ "Data\\binaryTexF32", "Python\\GPUWrite", "Python\\profiling", + "ShaderAssert\\assertsTest", # Viewer Only - These make sure the viewer will make mips of imported textures when asked "Textures\\Mips_Imported_2D", diff --git a/README.md b/README.md index 320cc5a3..3b1a0531 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,8 @@ Created by Alan Wolfe **Contributors:** +Alexey Gladkov + Berk Emre Saribas Chris Lewin diff --git a/RenderGraph/Visitors.h b/RenderGraph/Visitors.h index 017daa31..848ae1f4 100644 --- a/RenderGraph/Visitors.h +++ b/RenderGraph/Visitors.h @@ -594,7 +594,9 @@ struct ReferenceFixupVisitor { ReferenceFixupVisitor(RenderGraph& renderGraph_) : renderGraph(renderGraph_) - { } + { + visitedNode.resize(renderGraph.nodes.size(), false); + } template bool Visit(TDATA& data, const std::string& path) @@ -847,6 +849,10 @@ struct ReferenceFixupVisitor bool Visit(RenderGraphNode_Resource_Buffer& data, const std::string& path) { + if (visitedNode[data.nodeIndex]) + return true; + visitedNode[data.nodeIndex] = true; + if (data.visibility == ResourceVisibility::Internal) return true; @@ -863,6 +869,10 @@ struct ReferenceFixupVisitor bool Visit(RenderGraphNode_Action_ComputeShader& data, const std::string& path) { + if (visitedNode[data.nodeIndex]) + return true; + visitedNode[data.nodeIndex] = true; + int connectionIndex = -1; Shader& shader = *data.shader.shader; for (NodePinConnection& connection : data.connections) @@ -915,6 +925,10 @@ struct ReferenceFixupVisitor bool Visit(RenderGraphNode_Action_RayShader& data, const std::string& path) { + if (visitedNode[data.nodeIndex]) + return true; + visitedNode[data.nodeIndex] = true; + // Remember that this render graph uses ray tracing! renderGraph.usesRaytracing = true; @@ -970,6 +984,10 @@ struct ReferenceFixupVisitor bool Visit(RenderGraphNode_Action_SubGraph& data, const std::string& path) { + if (visitedNode[data.nodeIndex]) + return true; + visitedNode[data.nodeIndex] = true; + for (int connectionIndex = 0; connectionIndex < (int)data.connections.size(); ++connectionIndex) { // set the source pin @@ -997,6 +1015,10 @@ struct ReferenceFixupVisitor bool Visit(RenderGraphNode_Action_Barrier& data, const std::string& path) { + if (visitedNode[data.nodeIndex]) + return true; + visitedNode[data.nodeIndex] = true; + for (int connectionIndex = 0; connectionIndex < (int)data.connections.size(); ++connectionIndex) { // set the source pin @@ -1024,6 +1046,10 @@ struct ReferenceFixupVisitor bool Visit(RenderGraphNode_Action_CopyResource& data, const std::string& path) { + if (visitedNode[data.nodeIndex]) + return true; + visitedNode[data.nodeIndex] = true; + Visit(data.source, path + ".source"); Visit(data.dest, path + ".dest"); return true; @@ -1031,6 +1057,10 @@ struct ReferenceFixupVisitor bool Visit(RenderGraphNode_Action_DrawCall& data, const std::string& path) { + if (visitedNode[data.nodeIndex]) + return true; + visitedNode[data.nodeIndex] = true; + int connectionIndex = -1; Shader* vertexShader = data.vertexShader.shader; Shader& pixelShader = *data.pixelShader.shader; @@ -1257,6 +1287,26 @@ struct ReferenceFixupVisitor return false; } + bool Visit(VariableReferenceConstOnly& data, const std::string& path) + { + if (data.name.empty()) + return true; + + for (size_t index = 0; index < renderGraph.variables.size(); ++index) + { + const Variable& variable = renderGraph.variables[index]; + + if (!_stricmp(data.name.c_str(), variable.name.c_str())) + { + data.variableIndex = (int)index; + return true; + } + } + + Assert(data.variableIndex != -1, "Could not find variable %s\nIn %s\n", data.name.c_str(), path.c_str()); + return false; + } + bool Visit(StructReference& data, const std::string& path) { if (data.name.empty()) @@ -1333,6 +1383,7 @@ struct ReferenceFixupVisitor } RenderGraph& renderGraph; + std::vector visitedNode; // Helpers int GetNodeIndexByName(const char* name) @@ -1851,6 +1902,12 @@ struct SanitizeVisitor return true; } + bool Visit(VariableReferenceConstOnly& data, const std::string& path) + { + Sanitize(data.name); + return true; + } + bool Visit(NodePinReference& data, const std::string& path) { Sanitize(data.node); @@ -1946,6 +2003,413 @@ struct SanitizeVisitor RenderGraph& renderGraph; }; +struct ShaderAssertsVisitor +{ + constexpr static std::string_view AssertUavSuffix = "__GigiAssertUAV"; + + ShaderAssertsVisitor(RenderGraph& renderGraph_) + :renderGraph(renderGraph_) + { } + + template + bool Visit(TDATA& data, const std::string& path) + { + return true; + } + + bool Visit(RenderGraphNode& node, const std::string& path) + { + std::vector shadersWithAsserts; + std::string actionNodeName; + + if (node._index == RenderGraphNode::c_index_actionComputeShader) + { + RenderGraphNode_Action_ComputeShader& shaderNode = node.actionComputeShader; + actionNodeName = shaderNode.name; + + if (!ProcessNodeShader(shaderNode.shader.shader, shadersWithAsserts, path)) + return false; + } + + if (node._index == RenderGraphNode::c_index_actionDrawCall) + { + RenderGraphNode_Action_DrawCall& shaderNode = node.actionDrawCall; + actionNodeName = shaderNode.name; + + if (!ProcessNodeShader(shaderNode.amplificationShader.shader, shadersWithAsserts, path)) + return false; + + if (!ProcessNodeShader(shaderNode.meshShader.shader, shadersWithAsserts, path)) + return false; + + if (!ProcessNodeShader(shaderNode.vertexShader.shader, shadersWithAsserts, path)) + return false; + + if (!ProcessNodeShader(shaderNode.pixelShader.shader, shadersWithAsserts, path)) + return false; + } + + if (!shadersWithAsserts.empty()) + { + const size_t currentNodeId = std::distance(renderGraph.nodes.data(), &node); + const StructReference& structRef = InsertAssertUAVStruct(); + + for (Shader* shader : shadersWithAsserts) + { + RenderGraphNode* newUAVBufNode = InsertAssertsUAVNode(*shader, actionNodeName, structRef); + if (!AddResourceReference(renderGraph.nodes[currentNodeId], shader, newUAVBufNode->resourceBuffer)) + return false; + } + } + + return true; + } + + bool ProcessNodeShader(Shader* shader, std::vector& shaderWithAssert, const std::string& path) + { + if (shader) + { + const auto [isValid, hasAsserts] = ProcessShader(*shader, path); + if (!isValid) + return false; + + if (hasAsserts) + shaderWithAssert.push_back(shader); + } + + return true; + } + + struct ShaderProcessResult + { + bool isValid = false; + bool hasAsserts = false; + }; + + struct ShaderParsingResult + { + bool isValid = false; + std::unordered_map uniqueAssertsCalls; + }; + + ShaderProcessResult ProcessShader(Shader& shader, const std::string& path) + { + auto [isValid, uniqueAssertsCalls] = ParseShader(shader, path); + if (!isValid) + return {}; + + const bool hasAsserts = !uniqueAssertsCalls.empty(); + if (hasAsserts) + InsertStringReplacements(shader, uniqueAssertsCalls); + + return { true, hasAsserts }; + } + + ShaderParsingResult ParseShader(Shader& shader, const std::string& path) + { + std::string fileName = (std::filesystem::path(renderGraph.baseDirectory) / shader.fileName).string(); + + std::vector fileContents; + if (!LoadFile(fileName, fileContents)) + { + Assert(false, "Could not load file %s\nIn %s\n", fileName.c_str(), path.c_str()); + return {}; + } + fileContents.push_back(0); + + auto BeginsWith = [](const char* haystack, const char* needle) -> bool + { + size_t needleLen = strlen(needle); + if (_strnicmp(haystack, needle, needleLen) != 0) + return false; + return true; + }; + + auto GetCondition = [](std::string_view& content) + { + const size_t commaPos = content.find_first_of(','); + const bool isLastArg = commaPos == content.npos; + + const size_t argLen = isLastArg + ? content.length() + : commaPos; + + std::string_view res = content.substr(0, argLen); + content = content.substr(argLen); + + return res; + }; + + auto GetFmt = [](std::string_view& content) + { + const size_t firstQuotaPos = content.find_first_of('"'); + + std::string_view res; + if (firstQuotaPos != content.npos) + { + const size_t lastQuotaPos = content.find_first_of('"', firstQuotaPos + 1); + const size_t substrLen = lastQuotaPos != content.npos ? lastQuotaPos - firstQuotaPos + 1 : content.npos; + + std::string_view res = content.substr(firstQuotaPos, substrLen); + content = content.substr(firstQuotaPos + substrLen); + + return res; + } + + return std::string_view{}; + }; + + auto GetFmtArgs = [](const std::string_view content) + { + const size_t commaPos = content.find(','); + if (commaPos != content.npos) + return content.substr(commaPos + 1); + + return std::string_view{}; + }; + + auto CountFmtArgs = [](const std::string_view fmt, const std::string_view args) + { + size_t requestedFmtArgsCount = 0; + for (const char ch : fmt) + if (ch == '%') + ++requestedFmtArgsCount; + + size_t providedFmtArgsCount = 0; + size_t hasChars = 0; + for (const char ch : args) + { + hasChars |= !!iswalnum(ch); + if (ch == ',') + ++providedFmtArgsCount; + } + providedFmtArgsCount += hasChars; + + return std::pair{ requestedFmtArgsCount, providedFmtArgsCount }; + }; + + auto AcquireFormatStringId = [this](const std::string_view fmtStr) + { + std::string str(fmtStr); + + const auto it = fmtStrToId.find(str); + if (it != fmtStrToId.end()) + return it->second; + + const size_t newId = renderGraph.assertsFormatStrings.size(); + renderGraph.assertsFormatStrings.push_back(str); + fmtStrToId.insert({ str, newId }); + + return newId; + }; + + bool hasValidDeclarations = true; + std::unordered_map uniqueAssertsCalls; + + ForEachToken((char*)fileContents.data(), + [&](const std::string& tokenStr, const char* stringStart, const char* cursor) + { + const auto declError = [&](const char* error) + { + ShowErrorMessage("'%s' has an invalid declaration, %s", tokenStr.c_str(), error); + hasValidDeclarations = false; + }; + + std::string_view token(tokenStr); + const std::string_view prefix("/*$(Assert:"); + const std::string_view suffix(")*/"); + + if (!BeginsWith(token.data(), prefix.data())) + return; + + std::string_view arguments = token.substr(prefix.length(), token.length() - prefix.length() - suffix.length()); + if (arguments.empty()) + { + declError("missed arguments"); + return; + } + + const std::string_view condition = GetCondition(arguments); + + if (condition.empty() || condition.find_first_of('"') != condition.npos) + { + declError("invalid condition"); + return; + } + + const std::string_view fmtStr = GetFmt(arguments); + if (!fmtStr.empty() && (fmtStr.back() != '"')) + { + declError("format string misses closing \""); + return; + } + + const std::string_view fmtArgs = !fmtStr.empty() ? GetFmtArgs(arguments) : ""; + const auto [requestedArgsCount, providedArgsCount] = CountFmtArgs(fmtStr, fmtArgs); + if (requestedArgsCount != providedArgsCount) + { + declError("invalid number of the format arguments"); + return; + } + + //store assert token to the function call replacement + { + std::string replValue = "__gigiAssert("; + replValue += condition; + + const std::string formatIdStr = std::to_string(AcquireFormatStringId(fmtStr.empty() ? condition : fmtStr)); + replValue += ", " + formatIdStr; + + if (!fmtStr.empty() && !fmtArgs.empty()) + { + replValue += ", "; + replValue += fmtArgs; + } + + replValue += ");"; + uniqueAssertsCalls.insert({ std::string(token), std::move(replValue) }); + } + }); + + return { hasValidDeclarations, std::move(uniqueAssertsCalls) }; + } + + std::string GetShaderAssertUAVName(const Shader shader) + { + return "__" + shader.name + AssertUavSuffix.data(); + } + + void InsertStringReplacements(Shader& shader, std::unordered_map& uniqueAssertsCalls) + { + for (const auto& [tokenName, tokenReplacement] : uniqueAssertsCalls) + { + TokenReplacement replacement; + replacement.name = tokenName; + replacement.value = tokenReplacement; + shader.tokenReplacements.push_back(std::move(replacement)); + } + + const std::string assertBufName = GetShaderAssertUAVName(shader); + + TokenReplacement replacement; + replacement.name = "/*$(ShaderResources)*/"; + replacement.value = + "\nvoid __gigiAssert(bool condition, uint fmtId," + "\n float v1 = 0, float v2 = 0, float v3 = 0," + "\n float v4 = 0, float v5 = 0, float v6 = 0)" + "\n{" + "\n if (!condition)" + "\n {" + "\n uint wasFired;" + "\n InterlockedExchange(" + assertBufName + "[0].isFired, 1, wasFired); " + "\n if (wasFired)" + "\n return;" + "\n" + "\n Struct_GigiAssert newAssert = (Struct_GigiAssert)0;" + "\n newAssert.isFired = 1;" + "\n newAssert.fmtId = fmtId;" + "\n newAssert.v1 = v1;" + "\n newAssert.v2 = v2;" + "\n newAssert.v3 = v3;" + "\n newAssert.v4 = v4;" + "\n newAssert.v5 = v5;" + "\n newAssert.v6 = v6;" + "\n " + assertBufName + "[0] = newAssert; " + "\n " + "\n }" + "\n}"; + shader.tokenReplacements.push_back(std::move(replacement)); + } + + const StructReference& InsertAssertUAVStruct() + { + if (assertStructRef.structIndex >= 0) + return assertStructRef; + + Struct assertStruct; + assertStruct.name = "GigiAssert"; + + auto makeStructField = [](const char* name, DataFieldType type) + { + StructField newField; + newField.name = name; + newField.type = type; + return newField; + }; + + assertStruct.fields.push_back(makeStructField("isFired", DataFieldType::Uint)); + assertStruct.fields.push_back(makeStructField("fmtId", DataFieldType::Uint)); + assertStruct.fields.push_back(makeStructField("v1", DataFieldType::Float)); + assertStruct.fields.push_back(makeStructField("v2", DataFieldType::Float)); + assertStruct.fields.push_back(makeStructField("v3", DataFieldType::Float)); + assertStruct.fields.push_back(makeStructField("v4", DataFieldType::Float)); + assertStruct.fields.push_back(makeStructField("v5", DataFieldType::Float)); + assertStruct.fields.push_back(makeStructField("v6", DataFieldType::Float)); + + assertStructRef.name = assertStruct.name; + assertStructRef.structIndex = (int)renderGraph.structs.size(); + + renderGraph.structs.push_back(std::move(assertStruct)); + + return assertStructRef; + } + + RenderGraphNode* InsertAssertsUAVNode(const Shader& shader, const std::string& actionNodeName, const StructReference& assertStructRef) + { + BufferFormatDesc format; + format.structureType = assertStructRef; + + BufferCountDesc countDesc; + countDesc.multiply = 1; + + RenderGraphNode newBufferNode; + newBufferNode._index = RenderGraphNode::c_index_resourceBuffer; + newBufferNode.resourceBuffer.visibility = ResourceVisibility::Internal; + newBufferNode.resourceBuffer.format = format; + newBufferNode.resourceBuffer.count = countDesc; + newBufferNode.resourceBuffer.transient = true; + newBufferNode.resourceBuffer.name = actionNodeName + "__GigiAssertUAV_" + shader.name; + newBufferNode.resourceBuffer.originalName = newBufferNode.resourceBuffer.name; + + renderGraph.nodes.push_back(newBufferNode); + + return &renderGraph.nodes.back(); + } + + bool AddResourceReference(RenderGraphNode& node, Shader* shader, RenderGraphNode_Resource_Buffer& resourceBuffer) + { + ShaderResource newResource; + newResource.name = GetShaderAssertUAVName(*shader); + newResource.type = ShaderResourceType::Buffer; + newResource.access = ShaderResourceAccessType::UAV; + newResource.buffer.typeStruct = resourceBuffer.format.structureType; + + NodePinConnection newConnection; + newConnection.srcPin = newResource.name; + newConnection.dstNode = resourceBuffer.name; + newConnection.dstPin = "resource"; + + shader->resources.push_back(std::move(newResource)); + + if (node._index == RenderGraphNode::c_index_actionComputeShader) + node.actionComputeShader.connections.push_back(std::move(newConnection)); + else if (node._index == RenderGraphNode::c_index_actionDrawCall) + node.actionDrawCall.connections.push_back(std::move(newConnection)); + else + { + ShowErrorMessage("Shaders Assert: failed to add node connection: unsupported node type '%d'", node._index); + return false; + } + + return true; + } + + RenderGraph& renderGraph; + + StructReference assertStructRef; + std::unordered_map fmtStrToId; +}; + struct ShaderDataVisitor { ShaderDataVisitor(RenderGraph& renderGraph_) @@ -2455,6 +2919,9 @@ struct ShaderDataVisitor for (const ShaderResource& resource : shader.resources) { + if (resource.name.find(ShaderAssertsVisitor::AssertUavSuffix) != std::string::npos) + continue; + if (fileContents.find(resource.name) == std::string::npos) { bool isLoadedTexture = false; @@ -2529,4 +2996,5 @@ struct ResolveBackendRestrictions } RenderGraph& renderGraph; -}; \ No newline at end of file +}; + diff --git a/Schemas/PreviewWindow/PreviewWindowSchemas.h b/Schemas/PreviewWindow/PreviewWindowSchemas.h index d8594feb..4dfaa024 100644 --- a/Schemas/PreviewWindow/PreviewWindowSchemas.h +++ b/Schemas/PreviewWindow/PreviewWindowSchemas.h @@ -152,6 +152,7 @@ STRUCT_BEGIN(GGUserFile_SystemVars, "") STRUCT_FIELD(std::string, JitteredViewProjMtx_varName, "JitteredViewProjMtx", "ViewProjMtx with jitter.", 0) STRUCT_FIELD(std::string, InvJitteredViewProjMtx_varName, "InvJitteredViewProjMtx", "Inverted ViewProjMtx with jitter.", 0) STRUCT_FIELD(std::string, CameraPos_varName, "CameraPos", "", 0) + STRUCT_FIELD(std::string, CameraAltitudeAzimuth_varName, "CameraAltitudeAzimuth", "", 0) STRUCT_FIELD(std::string, CameraChanged_varName, "CameraChanged", "", 0) STRUCT_FIELD(std::string, CameraJitter_varName, "CameraJitter", "", 0) STRUCT_FIELD(std::string, ShadingRateImageTileSize_varName, "ShadingRateImageTileSize", "", 0) @@ -163,25 +164,42 @@ STRUCT_BEGIN(GGUserFile_SavedVariable, "Saved Variable Values") STRUCT_FIELD(std::string, value, "", "", 0) STRUCT_END() -STRUCT_BEGIN(GGUserFile_Bookmark, "A bookmark for resources to show up in a short list, to be more quickly found.") - STRUCT_FIELD(std::string, name, "", "", 0) - STRUCT_FIELD(std::string, viewableResourceDisplayName, "", "", 0) -STRUCT_END() - -STRUCT_BEGIN(GGUserFile_ImportedResourcePreset, "A preset of imported resource settings") - STRUCT_FIELD(std::string, name, "", "", 0) +STRUCT_BEGIN(GGUserFileV1, "The contents of a .gguser file") + STRUCT_FIELD(std::string, version, "1.0", "The version of the .gguser file", SCHEMA_FLAG_SERIALIZE_DFLT) + STRUCT_FIELD(GGUserFile_SystemVars, systemVars, {}, "", 0) + STRUCT_FIELD(int, resourceViewType, 0, "The type of resource being viewed", 0) + STRUCT_FIELD(int, resourceViewNodeIndex, -1, "The index of the node bieng viewed", 0) + STRUCT_FIELD(int, resourceViewResourceIndex, -1, "The index of that resource within that node being used", 0) + STRUCT_FIELD(int, syncInterval, 1, "IDXGISwapChain::Present() parameter: Synchronize presentation after the nth vertical blank.", 0) STRUCT_DYNAMIC_ARRAY(GGUserFile_ImportedResource, importedResources, "", 0) + STRUCT_DYNAMIC_ARRAY(GGUserFile_SavedVariable, savedVariables, "", 0) STRUCT_END() -STRUCT_BEGIN(GGUserFile, "The contents of a .gguser file") - STRUCT_FIELD(std::string, version, "1.0", "The version of the .gguser file", 0) - STRUCT_FIELD(GGUserFile_SystemVars, systemVars, {}, "", 0) +STRUCT_BEGIN(GGUserFileV2Snapshot, "The snapshot of a GGUserFileV2") + STRUCT_FIELD(std::string, name, "", "The snapshot name", 0) STRUCT_FIELD(int, resourceViewType, 0, "The type of resource being viewed", 0) STRUCT_FIELD(int, resourceViewNodeIndex, -1, "The index of the node bieng viewed", 0) STRUCT_FIELD(int, resourceViewResourceIndex, -1, "The index of that resource within that node being used", 0) - STRUCT_FIELD(int, syncInterval, true, "IDXGISwapChain::Present() parameter: Synchronize presentation after the nth vertical blank.", 0) + + STRUCT_FIELD(bool, loadVars, true, "Whether variables will be loaded from this snapshot", 0) + STRUCT_FIELD(bool, loadCamera, true, "Whether the camera will be loaded from this snapshot", 0) + STRUCT_FIELD(bool, loadResources, true, "Whether imported resources will be loaded from this snapshot", 0) + STRUCT_FIELD(bool, loadView, true, "Whether the resource viewed will be loaded from this snapshot", 0) + + STRUCT_STATIC_ARRAY(float, cameraPos, 3, { 0.0f COMMA 0.0f COMMA - 10.0f }, "Used by snapshots to capture the camera position", 0) + STRUCT_STATIC_ARRAY(float, cameraAltitudeAzimuth, 2, { 0.0f COMMA 0.0f }, "Used by snapshots to capture the camera orientation", 0) STRUCT_DYNAMIC_ARRAY(GGUserFile_ImportedResource, importedResources, "", 0) STRUCT_DYNAMIC_ARRAY(GGUserFile_SavedVariable, savedVariables, "", 0) - STRUCT_DYNAMIC_ARRAY(GGUserFile_Bookmark, bookmarks, "", 0) - STRUCT_DYNAMIC_ARRAY(GGUserFile_ImportedResourcePreset, importedResourcePresets, "", 0) +STRUCT_END() + +STRUCT_BEGIN(GGUserFileV2, "The contents of a .gguser file") + STRUCT_FIELD(std::string, version, "2.0", "The version of the .gguser file", SCHEMA_FLAG_SERIALIZE_DFLT) + STRUCT_FIELD(int, syncInterval, 1, "IDXGISwapChain::Present() parameter: Synchronize presentation after the nth vertical blank.", 0) + STRUCT_FIELD(GGUserFile_SystemVars, systemVars, {}, "", 0) + STRUCT_FIELD(GGUserFileV2Snapshot, snapshot, {}, "", 0) + STRUCT_DYNAMIC_ARRAY(GGUserFileV2Snapshot, snapshots, "", 0) +STRUCT_END() + +STRUCT_BEGIN(GGUserFileVersionOnly, "Only the version of the .gguser file") + STRUCT_FIELD(std::string, version, "1.0", "The version of the .gguser file", SCHEMA_FLAG_SERIALIZE_DFLT) STRUCT_END() diff --git a/Schemas/RenderGraphNodes.h b/Schemas/RenderGraphNodes.h index 23ccc0b3..04b2329d 100644 --- a/Schemas/RenderGraphNodes.h +++ b/Schemas/RenderGraphNodes.h @@ -231,6 +231,7 @@ STRUCT_BEGIN(SubGraphVariableSettings, "Cached data about a subgraph") STRUCT_FIELD(std::string, name, "", "variable name", SCHEMA_FLAG_UI_CONST) STRUCT_FIELD(VariableVisibility, visibility, VariableVisibility::Internal, "Who can see and interact with this variable", 0) STRUCT_FIELD(std::string, replaceWithStr, {}, "If set, the subgraph variable will be deleted and all references will use this parent graph variable instead.", 0) + STRUCT_FIELD(std::string, replaceWithValue, {}, "Replace the variable with a literal value. At gigi compile time it makes an internal private variable of the correct type with this string as the default value.", 0) STRUCT_FIELD(bool, isLoopIndex, false, "If true, this variable will recieve the loop index.", 0) // deprecated in 0.97b @@ -255,7 +256,7 @@ STRUCT_BEGIN(RenderGraphNode_Base, "The base type of all node types") STRUCT_FIELD(std::unordered_map, inputPinIds, {}, "", SCHEMA_FLAG_NO_UI | SCHEMA_FLAG_NO_SERIALIZE) STRUCT_FIELD(std::unordered_map, outputPinIds, {}, "", SCHEMA_FLAG_NO_UI | SCHEMA_FLAG_NO_SERIALIZE) - STRUCT_FIELD(int, nodeIndex, -1, "The index in the list of render graph nodes", SCHEMA_FLAG_NO_SERIALIZE) + STRUCT_FIELD(int, nodeIndex, -1, "The index in the list of render graph nodes. This is filled in after loading by the ReferenceFixupVisitor and is in [0,N) with no gaps.", SCHEMA_FLAG_NO_SERIALIZE) STRUCT_FIELD(std::string, originalName, "", "The name before renames and sanitization", SCHEMA_FLAG_NO_SERIALIZE) STRUCT_END() @@ -447,6 +448,8 @@ STRUCT_INHERIT_BEGIN(RenderGraphNode_Action_SubGraph, RenderGraphNode_ActionBase STRUCT_FIELD(int, loopCount, 1, "Number of times to execute the technique.", 0) + STRUCT_FIELD(VariableReferenceConstOnly, loopCountVariable, {}, "The variable to use for the loopCount. Only const variables supported currently.", 0) + STRUCT_FIELD(int, loopIndex, -1, "When unrolling subgraph loops, the loop index of the node is stored here.", SCHEMA_FLAG_NO_SERIALIZE) STRUCT_END() diff --git a/Schemas/Schemas.h b/Schemas/Schemas.h index bcbe5ff3..c90dca63 100644 --- a/Schemas/Schemas.h +++ b/Schemas/Schemas.h @@ -17,6 +17,7 @@ ENUM_BEGIN(GigiCompileResult, "") ENUM_ITEM(WrongVersion, "") ENUM_ITEM(WrongParams, "") ENUM_ITEM(CantLoadRenderGraph, "") + ENUM_ITEM(ShaderAsserts, "") ENUM_ITEM(ShaderReflection, "") ENUM_ITEM(Validation, "") ENUM_ITEM(ReferenceFixup, "") @@ -118,6 +119,9 @@ ENUM_BEGIN(SetVariableOperator, "") ENUM_ITEM(PowerOf2GE, "The next power of two, greater or equal to the current value") + ENUM_ITEM(Minimum, "min(A,B)") + ENUM_ITEM(Maximum, "max(A,B)") + ENUM_ITEM(BitwiseOr, "A | B") ENUM_ITEM(BitwiseAnd, "A & B") ENUM_ITEM(BitwiseXor, "A ^ B") @@ -195,4 +199,7 @@ STRUCT_BEGIN(RenderGraph, "The root type of the render graph") STRUCT_FIELD(BackendTemplateConfig, templateConfig, {}, "Code generation template config", SCHEMA_FLAG_NO_SERIALIZE) STRUCT_FIELD(bool, generateGraphVizFlag, false, "Set to true if the generating GraphViz. Should be set to true from a command line parameter", SCHEMA_FLAG_NO_SERIALIZE) + + STRUCT_FIELD(std::vector, assertsFormatStrings, {}, "The unique formatting strings of the asserts messages", SCHEMA_FLAG_NO_SERIALIZE) + STRUCT_FIELD(std::unordered_set, firedAssertsIdentifiers, {}, "The identifiers of the fired asserts to ignore them later on", SCHEMA_FLAG_NO_SERIALIZE) STRUCT_END() diff --git a/Schemas/SchemasShaders.h b/Schemas/SchemasShaders.h index c45bb6d4..5a99cb2a 100644 --- a/Schemas/SchemasShaders.h +++ b/Schemas/SchemasShaders.h @@ -106,6 +106,12 @@ STRUCT_BEGIN(VariableReferenceNoConst, "A reference to a variable. No const vari STRUCT_FIELD(int, variableIndex, -1, "Calculated for convenience.", SCHEMA_FLAG_NO_SERIALIZE) STRUCT_END() +STRUCT_BEGIN(VariableReferenceConstOnly, "A reference to a variable. Only const variables allowed.") + STRUCT_FIELD(std::string, name, "", "The name of the variable.", 0) + + STRUCT_FIELD(int, variableIndex, -1, "Calculated for convenience.", SCHEMA_FLAG_NO_SERIALIZE) +STRUCT_END() + STRUCT_BEGIN(StructReference, "A reference to a struct") STRUCT_FIELD(std::string, name, "", "The name of the struct.", 0) @@ -292,6 +298,11 @@ STRUCT_BEGIN(ShaderDefine, "A shader define as part of shader compilation") STRUCT_FIELD(std::string, value, "", "The value of the define.", 0) STRUCT_END() +STRUCT_BEGIN(TokenReplacement, "A shader token replacement") + STRUCT_FIELD(std::string, name, "", "The token string.", 0) + STRUCT_FIELD(std::string, value, "", "The replacement.", 0) +STRUCT_END() + STRUCT_BEGIN(LoadedTextureReference, "Information about a loaded texture referenced by this shader.") STRUCT_FIELD(std::string, token, "", "The token as it appears in the shader.", 0) STRUCT_FIELD(std::string, resourceName, "", "The name of the resource to replace it with.", 0) @@ -331,6 +342,7 @@ STRUCT_BEGIN(Shader, "A declaration of a shader") STRUCT_FIELD(std::string, entryPoint, "", "The shader entrypoint.", 0) STRUCT_DYNAMIC_ARRAY(ShaderDefine, defines, "The defines the shader is compiled with.", SCHEMA_FLAG_UI_COLLAPSABLE | SCHEMA_FLAG_UI_ARRAY_FATITEMS) + STRUCT_DYNAMIC_ARRAY(TokenReplacement, tokenReplacements, "The token replacements specific for the shader.", SCHEMA_FLAG_NO_SERIALIZE) // deprecated in 0.95b // replaced by NumThreads diff --git a/Schemas/SchemasVariables.h b/Schemas/SchemasVariables.h index 2be18eb6..87d1c422 100644 --- a/Schemas/SchemasVariables.h +++ b/Schemas/SchemasVariables.h @@ -32,12 +32,13 @@ STRUCT_BEGIN(Variable, "A variable definition") STRUCT_FIELD(DataFieldType, type, DataFieldType::Count, "The type of the variable", 0) STRUCT_FIELD(bool, Const, false, "If true, the variable is declared const and cannot change at runtime", 0) STRUCT_FIELD(bool, Static, false, "If true, the variable has the same value for all instances of the technique", 0) - STRUCT_FIELD(std::string, dflt, "", "The default value of the variable", 0) + STRUCT_FIELD(std::string, dflt, "", "The default value of the variable. The default memory is zero initialized before this is parsed, so if you don't give it enough initializers, it will use zero for the unlisted fields.", 0) STRUCT_FIELD(VariableVisibility, visibility, VariableVisibility::Internal, "Who can see and interact with this variable", 0) STRUCT_FIELD(std::string, Enum, "", "Integer types can specify an enum, which will then make symbols in both C++ and shader code.", 0) STRUCT_FIELD(BackendRestriction, backends, {}, "This variable can be limited to specific backends", SCHEMA_FLAG_UI_COLLAPSABLE) STRUCT_FIELD(bool, transient, false, "If true, the variable should not be saved between runs of this technique. The Gigi viewer uses this to decide if it should save it in the gguser file or not, for example.", 0) STRUCT_FIELD(VariableUISettings, UISettings, {}, "UI Settings.", 0) + STRUCT_FIELD(std::string, UIGroup, "", "Used to organize variables into folders in the viewer. separate folders with dots. For instance: settings.controls", 0) STRUCT_FIELD(int, enumIndex, -1, "Calculated for convenience.", SCHEMA_FLAG_NO_SERIALIZE) diff --git a/Techniques/Denoising/SVGF/Atrous.gg b/Techniques/Denoising/SVGF/Atrous.gg new file mode 100644 index 00000000..94ddd105 --- /dev/null +++ b/Techniques/Denoising/SVGF/Atrous.gg @@ -0,0 +1,237 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "variables": [ + { + "name": "PhiColor", + "type": "Float", + "dflt": "10.0f" + }, + { + "name": "PhiNormal", + "type": "Float", + "dflt": "128.0f", + "visibility": "User" + }, + { + "name": "LoopIndex", + "type": "Int", + "visibility": "Host" + }, + { + "name": "FeedbackTap", + "type": "Int", + "dflt": "1", + "visibility": "User" + } + ], + "shaders": [ + { + "name": "AtrousCS", + "fileName": "SVGFAtrous.ps.slang", + "entryPoint": "csmain", + "slangOptions": { + "process": true + }, + "resources": [ + { + "name": "gAlbedo", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gLinearZAndNormal", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gHistoryLength", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gIllumination", + "type": "Texture", + "access": "SRV" + }, + { + "name": "Output", + "type": "Texture", + "access": "UAV" + } + ] + } + ], + "nodes": [ + { + "resourceTexture": { + "name": "Albedo", + "editorPos": [ + -21.0, + 18.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "LinearZAndNormal", + "editorPos": [ + -60.0, + 66.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "HistoryLength", + "editorPos": [ + -28.0, + 114.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "PingPongFbo_0", + "editorPos": [ + -33.0, + 162.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "PingPongFbo_1 ", + "editorPos": [ + -37.0, + 210.0 + ], + "visibility": "Imported" + } + }, + { + "actionComputeShader": { + "name": "Atrous", + "editorPos": [ + 233.0, + 66.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "gIllumination", + "dstNode": "PingPongFbo_0", + "dstPin": "resource" + }, + { + "srcPin": "gAlbedo", + "dstNode": "Albedo", + "dstPin": "resource" + }, + { + "srcPin": "gHistoryLength", + "dstNode": "HistoryLength", + "dstPin": "resource" + }, + { + "srcPin": "gLinearZAndNormal", + "dstNode": "LinearZAndNormal", + "dstPin": "resource" + }, + { + "srcPin": "Output", + "dstNode": "PingPongFbo_1 ", + "dstPin": "resource" + } + ], + "shader": { + "name": "AtrousCS" + }, + "dispatchSize": { + "node": { + "name": "Albedo" + } + } + } + }, + { + "actionSubGraph": { + "name": "Swap", + "editorPos": [ + 677.0, + 114.0 + ], + "linkProperties": [ + {}, + {} + ], + "connections": [ + { + "srcPin": "A", + "dstNode": "Atrous", + "dstPin": "gIllumination" + }, + { + "srcPin": "B", + "dstNode": "FeedbackTap", + "dstPin": "source" + } + ], + "fileName": "SwapTextures.gg", + "subGraphData": { + "importedResources": [ + "A", + "B" + ] + } + } + }, + { + "resourceTexture": { + "name": "FilteredPastFbo", + "editorPos": [ + 298.0, + 226.0 + ], + "visibility": "Imported" + } + }, + { + "actionCopyResource": { + "name": "FeedbackTap", + "editorPos": [ + 485.0, + 162.0 + ], + "condition": { + "variable1": "FeedbackTap", + "comparison": "Equals", + "variable2": "LoopIndex" + }, + "linkProperties": [ + {}, + {} + ], + "source": { + "node": "Atrous", + "pin": "Output" + }, + "dest": { + "node": "FilteredPastFbo", + "pin": "resource" + } + } + } + ] +} \ No newline at end of file diff --git a/Techniques/Denoising/SVGF/ClearBuffersCS.hlsl b/Techniques/Denoising/SVGF/ClearBuffersCS.hlsl new file mode 100644 index 00000000..024782be --- /dev/null +++ b/Techniques/Denoising/SVGF/ClearBuffersCS.hlsl @@ -0,0 +1,19 @@ +// Unnamed technique, shader ClearBuffersCS +/*$(ShaderResources)*/ + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + uint2 px = DTid.xy; + LinearZAndNormal[px] = float4(0.0f, 0.0f, 0.0f, 0.0f); + PrevLinearZAndNormal[px] = float4(0.0f, 0.0f, 0.0f, 0.0f); + FilteredPastFbo[px] = float4(0.0f, 0.0f, 0.0f, 0.0f); + PrevReprojFbo_0[px] = float4(0.0f, 0.0f, 0.0f, 0.0f); + PrevReprojFbo_1[px] = float4(0.0f, 0.0f, 0.0f, 0.0f); + PrevReprojFbo_2[px] = float4(0.0f, 0.0f, 0.0f, 0.0f); + CurReprojFbo_0[px] = float4(0.0f, 0.0f, 0.0f, 0.0f); + CurReprojFbo_1[px] = float4(0.0f, 0.0f, 0.0f, 0.0f); + CurReprojFbo_2[px] = float4(0.0f, 0.0f, 0.0f, 0.0f); + PingPongFbo_0[px] = float4(0.0f, 0.0f, 0.0f, 0.0f); + PingPongFbo_1[px] = float4(0.0f, 0.0f, 0.0f, 0.0f); + Final_Fbo[px] = float4(0.0f, 0.0f, 0.0f, 0.0f); +} diff --git a/Techniques/Denoising/SVGF/ColorHelpers.slang b/Techniques/Denoising/SVGF/ColorHelpers.slang new file mode 100644 index 00000000..a7b2c9f8 --- /dev/null +++ b/Techniques/Denoising/SVGF/ColorHelpers.slang @@ -0,0 +1,415 @@ +/*************************************************************************** + # Copyright (c) 2015-24, NVIDIA CORPORATION. All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in the + # documentation and/or other materials provided with the distribution. + # * Neither the name of NVIDIA CORPORATION nor the names of its + # contributors may be used to endorse or promote products derived + # from this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY + # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **************************************************************************/ + +/** + * This file contains host/device shared color utility functions. + */ + +/** + * Returns a relative luminance of an input linear RGB color in the ITU-R BT.709 color space + * @param RGBColor linear HDR RGB color in the ITU-R BT.709 color space + */ +float luminance(float3 rgb) +{ + return dot(rgb, float3(0.2126f, 0.7152f, 0.0722f)); +} + +#ifndef HOST_CODE +// TODO: Unify this code with the host-side functions in ColorUtils.h when #175 is solved. +/** + * Transforms an RGB color in Rec.709 to CIE XYZ. + */ +float3 RGBtoXYZ_Rec709(float3 c) +{ + static const float3x3 M = { + // clang-format off + 0.4123907992659595, 0.3575843393838780, 0.1804807884018343, // row 0 + 0.2126390058715104, 0.7151686787677559, 0.0721923153607337, // row 1 + 0.0193308187155918, 0.1191947797946259, 0.9505321522496608, // row 2 + // clang-format off + }; + return mul(M, c); +} + +/** + * Transforms an XYZ color to RGB in Rec.709. + */ +float3 XYZtoRGB_Rec709(float3 c) +{ + static const float3x3 M = { + // clang-format off + 3.240969941904522, -1.537383177570094, -0.4986107602930032, // row 0 + -0.9692436362808803, 1.875967501507721, 0.04155505740717569, // row 1 + 0.05563007969699373, -0.2039769588889765, 1.056971514242878, // row 2 + // clang-format on + }; + return mul(M, c); +} +#endif + +/** + * Converts color from RGB to YCgCo space + * @param RGBColor linear HDR RGB color + */ +inline float3 RGBToYCgCo(float3 rgb) +{ + float Y = dot(rgb, float3(0.25f, 0.50f, 0.25f)); + float Cg = dot(rgb, float3(-0.25f, 0.50f, -0.25f)); + float Co = dot(rgb, float3(0.50f, 0.00f, -0.50f)); + return float3(Y, Cg, Co); +} + +/** + * Converts color from YCgCo to RGB space + * @param YCgCoColor linear HDR YCgCo color + */ +inline float3 YCgCoToRGB(float3 YCgCo) +{ + float tmp = YCgCo.x - YCgCo.y; + float r = tmp + YCgCo.z; + float g = YCgCo.x + YCgCo.y; + float b = tmp - YCgCo.z; + return float3(r, g, b); +} + +/** + * Returns a YUV version of an input linear RGB color in the ITU-R BT.709 color space + * @param RGBColor linear HDR RGB color in the ITU-R BT.709 color space + */ +inline float3 RGBToYUV(float3 rgb) +{ + float3 ret; + ret.x = dot(rgb, float3(0.2126f, 0.7152f, 0.0722f)); + ret.y = dot(rgb, float3(-0.09991f, -0.33609f, 0.436f)); + ret.z = dot(rgb, float3(0.615f, -0.55861f, -0.05639f)); + return ret; +} + +/** + * Returns a RGB version of an input linear YUV color in the ITU-R BT.709 color space + * @param YUVColor linear HDR YUV color in the ITU-R BT.709 color space + */ +inline float3 YUVToRGB(float3 yuv) +{ + float3 ret; + ret.x = dot(yuv, float3(1.0f, 0.0f, 1.28033f)); + ret.y = dot(yuv, float3(1.0f, -0.21482f, -0.38059f)); + ret.z = dot(yuv, float3(1.0f, 2.12798f, 0.0f)); + return ret; +} + +/** + * Returns a linear-space RGB version of an input RGB channel value in the ITU-R BT.709 color space + * @param sRGBColor sRGB input channel value + */ +inline float sRGBToLinear(float srgb) +{ + if (srgb <= 0.04045f) + { + return srgb * (1.0f / 12.92f); + } + else + { + return pow((srgb + 0.055f) * (1.0f / 1.055f), 2.4f); + } +} + +/** + * Returns a linear-space RGB version of an input RGB color in the ITU-R BT.709 color space + * @param sRGBColor sRGB input color + */ +inline float3 sRGBToLinear(float3 srgb) +{ + return float3(sRGBToLinear(srgb.x), sRGBToLinear(srgb.y), sRGBToLinear(srgb.z)); +} + +/** + * Returns a sRGB version of an input linear RGB channel value in the ITU-R BT.709 color space + * @param LinearColor linear input channel value + */ +inline float linearToSRGB(float lin) +{ + if (lin <= 0.0031308f) + { + return lin * 12.92f; + } + else + { + return pow(lin, (1.0f / 2.4f)) * (1.055f) - 0.055f; + } +} + +/** + * Returns a sRGB version of an input linear RGB color in the ITU-R BT.709 color space + * @param LinearColor linear input color + */ +inline float3 linearToSRGB(float3 lin) +{ + return float3(linearToSRGB(lin.x), linearToSRGB(lin.y), linearToSRGB(lin.z)); +} + +/** + * Returns Michelson contrast given minimum and maximum intensities of an image region + * @param iMin minimum intensity of an image region + * @param iMax maximum intensity of an image region + */ +inline float computeMichelsonContrast(float iMin, float iMax) +{ + if (iMin == 0.0f && iMax == 0.0f) + return 0.0f; + else + return (iMax - iMin) / (iMax + iMin); +} + +static const float3 kD65ReferenceIlluminant = float3(0.950428545, 1.000000000, 1.088900371); +static const float3 kInvD65ReferenceIlluminant = float3(1.052156925, 1.000000000, 0.918357670); + +#ifndef HOST_CODE +[BackwardDifferentiable] +#endif +inline float3 linearRGBToXYZ(float3 linColor) +{ + // Source: https://www.image-engineering.de/library/technotes/958-how-to-convert-between-srgb-and-ciexyz + // Assumes D65 standard illuminant. + const float a11 = 10135552.0f / 24577794.0f; + const float a12 = 8788810.0f / 24577794.0f; + const float a13 = 4435075.0f / 24577794.0f; + const float a21 = 2613072.0f / 12288897.0f; + const float a22 = 8788810.0f / 12288897.0f; + const float a23 = 887015.0f / 12288897.0f; + const float a31 = 1425312.0f / 73733382.0f; + const float a32 = 8788810.0f / 73733382.0f; + const float a33 = 70074185.0f / 73733382.0f; + + float3 xyzColor; + xyzColor.r = a11 * linColor.r + a12 * linColor.g + a13 * linColor.b; + xyzColor.g = a21 * linColor.r + a22 * linColor.g + a23 * linColor.b; + xyzColor.b = a31 * linColor.r + a32 * linColor.g + a33 * linColor.b; + + return xyzColor; +} + +#ifndef HOST_CODE +[BackwardDifferentiable] +#endif +inline float3 XYZToLinearRGB(float3 xyzColor) +{ + // Return values in linear RGB, assuming D65 standard illuminant. + const float a11 = 3.241003275f; + const float a12 = -1.537398934f; + const float a13 = -0.498615861f; + const float a21 = -0.969224334f; + const float a22 = 1.875930071f; + const float a23 = 0.041554224f; + const float a31 = 0.055639423f; + const float a32 = -0.204011202f; + const float a33 = 1.057148933f; + + float3 linColor; + linColor.r = a11 * xyzColor.r + a12 * xyzColor.g + a13 * xyzColor.b; + linColor.g = a21 * xyzColor.r + a22 * xyzColor.g + a23 * xyzColor.b; + linColor.b = a31 * xyzColor.r + a32 * xyzColor.g + a33 * xyzColor.b; + + return linColor; +} + +#ifndef HOST_CODE + +[BackwardDifferentiable] +float actualPow(float x, float y) +{ + if (x >= 0.f) + return pow(x, y); + else + return -pow(-x, y); +} + +[BackwardDifferentiable] +float3 actualPow(float3 in, float y) +{ + return float3(actualPow(in.x, y), actualPow(in.y, y), actualPow(in.z, y)); +} + +[BackwardDifferentiable] +inline float3 XYZToOklab(float3 xyzColor) +{ + static const float3x3 M1 = { + 0.8189330101f, + 0.3618667424f, + -0.1288597137f, + 0.0329845436f, + 0.9293118715f, + 0.0361456387f, + 0.0482003018f, + 0.2643662691f, + 0.6338517070f + }; + float3 lms = mul(M1, xyzColor); + lms = actualPow(lms, 1.f / 3.f); + static const float3x3 M2 = { + 0.2104542553f, + 0.7936177850f, + -0.0040720468f, + 1.9779984951f, + -2.4285922050f, + 0.4505937099f, + 0.0259040371f, + 0.7827717662f, + -0.8086757660f + }; + return mul(M2, lms); +} + +[BackwardDifferentiable] +inline float3 OklabToXYZ(float3 oklabColor) +{ + float3x3 M2inv = + float3x3(1.00000000f, 0.39633779f, 0.21580376f, 1.00000001f, -0.10556134f, -0.06385417f, 1.00000005f, -0.08948418f, -1.29148554f); + float3 lms = mul(M2inv, oklabColor); + lms = lms * lms * lms; + float3x3 M1inv = + float3x3(1.22701385f, -0.55779998f, 0.28125615f, -0.04058018f, 1.11225687f, -0.07167668f, -0.07638128f, -0.42148198f, 1.58616322f); + return mul(M1inv, lms); +} + +[BackwardDifferentiable] +inline float3 OklabToHCL(float3 oklabColor) +{ + float L = oklabColor.x; + float a = oklabColor.y; + float b = oklabColor.z; + + float H = atan2(b, a); + float C = sqrt(a * a + b * b); + return float3(H, C, L); +} + +[BackwardDifferentiable] +inline float3 HCLToOklab(float3 hclColor) +{ + float H = hclColor.x; + float C = hclColor.y; + float L = hclColor.z; + + float a = C * cos(H); + float b = C * sin(H); + return float3(L, a, b); +} + +[BackwardDifferentiable] +inline float3 RGBToOklab(float3 lColor) +{ + return XYZToOklab(linearRGBToXYZ(lColor)); +} + +[BackwardDifferentiable] +inline float3 OklabToRGB(float3 lab) +{ + return XYZToLinearRGB(OklabToXYZ(lab)); +} + +#endif + +inline float3 XYZToCIELab(float3 xyzColor, const float3 invReferenceIlluminant = kInvD65ReferenceIlluminant) +{ + // The default illuminant is D65. + float3 tmpColor = xyzColor * invReferenceIlluminant; + + float delta = 6.0f / 29.0f; + float deltaSquare = delta * delta; + float deltaCube = delta * deltaSquare; + float factor = 1.0f / (3.0f * deltaSquare); + float term = 4.0f / 29.0f; + + tmpColor.r = (tmpColor.r > deltaCube ? pow(tmpColor.r, 1.0f / 3.0f) : factor * tmpColor.r + term); + tmpColor.g = (tmpColor.g > deltaCube ? pow(tmpColor.g, 1.0f / 3.0f) : factor * tmpColor.g + term); + tmpColor.b = (tmpColor.b > deltaCube ? pow(tmpColor.b, 1.0f / 3.0f) : factor * tmpColor.b + term); + + float3 labColor; + labColor.r = 116.0f * tmpColor.g - 16.0f; + labColor.g = 500.0f * (tmpColor.r - tmpColor.g); + labColor.b = 200.0f * (tmpColor.g - tmpColor.b); + + return labColor; +} + +inline float3 CIELabToXYZ(float3 labColor, const float3 referenceIlluminant = kD65ReferenceIlluminant) +{ + // The default illuminant is D65. + float Y = (labColor.r + 16.0f) / 116.0f; + float X = labColor.g / 500.0f + Y; + float Z = Y - labColor.b / 200.0f; + + float delta = 6.0f / 29.0f; + float factor = 3.0f * delta * delta; + float term = 4.0f / 29.0f; + X = ((X > delta) ? X * X * X : (X - term) * factor); + Y = ((Y > delta) ? Y * Y * Y : (Y - term) * factor); + Z = ((Z > delta) ? Z * Z * Z : (Z - term) * factor); + + return float3(X, Y, Z) * referenceIlluminant; +} + +inline float3 XYZToYCxCz(float3 xyzColor, const float3 invReferenceIlluminant = kInvD65ReferenceIlluminant) +{ + // The default illuminant is D65. + float3 tmpColor = xyzColor * invReferenceIlluminant; + + float3 ycxczColor; + ycxczColor.x = 116.0f * tmpColor.g - 16.0f; + ycxczColor.y = 500.0f * (tmpColor.r - tmpColor.g); + ycxczColor.z = 200.0f * (tmpColor.g - tmpColor.b); + + return ycxczColor; +} + +inline float3 YCxCzToXYZ(float3 ycxczColor, const float3 referenceIlluminant = kD65ReferenceIlluminant) +{ + // The default illuminant is D65. + float Y = (ycxczColor.r + 16.0f) / 116.0f; + float X = ycxczColor.g / 500.0f + Y; + float Z = Y - ycxczColor.b / 200.0f; + + return float3(X, Y, Z) * referenceIlluminant; +} + +inline float3 linearRGBToCIELab(float3 lColor) +{ + return XYZToCIELab(linearRGBToXYZ(lColor)); +} + +inline float3 YCxCzToLinearRGB(float3 ycxczColor) +{ + return XYZToLinearRGB(YCxCzToXYZ(ycxczColor)); +} + +inline float3 linearRGBToYCxCz(float3 lColor) +{ + return XYZToYCxCz(linearRGBToXYZ(lColor)); +} + diff --git a/Techniques/Denoising/SVGF/LICENSE.md b/Techniques/Denoising/SVGF/LICENSE.md new file mode 100644 index 00000000..af9caafb --- /dev/null +++ b/Techniques/Denoising/SVGF/LICENSE.md @@ -0,0 +1,26 @@ +Copyright (c) 2020, NVIDIA CORPORATION. All rights reserved. +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions +are met: + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of NVIDIA CORPORATION nor the names of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +--- + +This software links to the following components which are not licensed under the above license text. +For details on the specific licenses please refer to the provided links. + +- DLSS: https://github.com/NVIDIA/DLSS/blob/main/LICENSE.txt +- RTXGI: https://github.com/NVIDIAGameWorks/RTXGI/blob/main/License.txt +- RTXDI: https://github.com/NVIDIAGameWorks/RTXDI/blob/main/LICENSE.txt +- NRD: https://github.com/NVIDIAGameWorks/RayTracingDenoiser/blob/master/LICENSE.txt diff --git a/Techniques/Denoising/SVGF/MathConstants.slangh b/Techniques/Denoising/SVGF/MathConstants.slangh new file mode 100644 index 00000000..fb9d5aa1 --- /dev/null +++ b/Techniques/Denoising/SVGF/MathConstants.slangh @@ -0,0 +1,130 @@ +/*************************************************************************** + # Copyright (c) 2015-24, NVIDIA CORPORATION. All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in the + # documentation and/or other materials provided with the distribution. + # * Neither the name of NVIDIA CORPORATION nor the names of its + # contributors may be used to endorse or promote products derived + # from this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY + # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **************************************************************************/ +#pragma once +//#include "Utils/HostDeviceShared.slangh" + +/** + * This file contains useful numeric constants for use on the GPU. + * + * It should be included with #include rather than import, as imported files + * do not export macro definitions. + * + * Note the possible differences between declaring constants using static + * float vs macro definitions. The compiler may treat these differently with + * respect to what precision is used for compile-time constant propagation. + * Slang currently uses fp32 for constant propagation. We get higher + * precision using the pre-evaluated constants below. Ideally, all + * compile-time constants should be evaluated at fp64 or higher precision. + */ + +#ifdef HOST_CODE +// @skallweit: We should use a different way to make math constants available on the host. +#include +#include +#include + +#else + +// clang-format off + +// Constants from +#define M_E 2.71828182845904523536 // e +#define M_LOG2E 1.44269504088896340736 // log2(e) +#define M_LOG10E 0.434294481903251827651 // log10(e) +#define M_LN2 0.693147180559945309417 // ln(2) +#define M_LN10 2.30258509299404568402 // ln(10) +#define M_PI 3.14159265358979323846 // pi +#define M_PI_2 1.57079632679489661923 // pi/2 +#define M_PI_4 0.785398163397448309616 // pi/4 +#define M_1_PI 0.318309886183790671538 // 1/pi +#define M_2_PI 0.636619772367581343076 // 2/pi +#define M_1_SQRTPI 0.564189583547756279280 // 1/sqrt(pi) +#define M_2_SQRTPI 1.12837916709551257390 // 2/sqrt(pi) +#define M_SQRT2 1.41421356237309504880 // sqrt(2) +#define M_SQRT1_2 0.707106781186547524401 // 1/sqrt(2) + +// Numeric limits from +#define UINT32_MAX 4294967295 +#define INT32_MIN -2147483648 +#define INT32_MAX 2147483647 + +// Numeric limits from +#define DBL_DECIMAL_DIG 17 // # of decimal digits of rounding precision +#define DBL_DIG 15 // # of decimal digits of precision +#define DBL_EPSILON 2.2204460492503131e-016 // smallest such that 1.0+DBL_EPSILON != 1.0 +#define DBL_HAS_SUBNORM 1 // type does support subnormal numbers +#define DBL_MANT_DIG 53 // # of bits in mantissa +#define DBL_MAX 1.7976931348623158e+308 // max value +#define DBL_MAX_10_EXP 308 // max decimal exponent +#define DBL_MAX_EXP 1024 // max binary exponent +#define DBL_MIN 2.2250738585072014e-308 // min positive value +#define DBL_MIN_10_EXP (-307) // min decimal exponent +#define DBL_MIN_EXP (-1021) // min binary exponent +#define DBL_RADIX 2 // exponent radix +#define DBL_TRUE_MIN 4.9406564584124654e-324 // min positive value + +#define FLT_DECIMAL_DIG 9 // # of decimal digits of rounding precision +#define FLT_DIG 6 // # of decimal digits of precision +#define FLT_EPSILON 1.192092896e-07F // smallest such that 1.0+FLT_EPSILON != 1.0 +#define FLT_HAS_SUBNORM 1 // type does support subnormal numbers +#define FLT_GUARD 0 +#define FLT_MANT_DIG 24 // # of bits in mantissa +#define FLT_MAX 3.402823466e+38F // max value +#define FLT_MAX_10_EXP 38 // max decimal exponent +#define FLT_MAX_EXP 128 // max binary exponent +#define FLT_MIN 1.175494351e-38F // min normalized positive value +#define FLT_MIN_10_EXP (-37) // min decimal exponent +#define FLT_MIN_EXP (-125) // min binary exponent +#define FLT_NORMALIZE 0 +#define FLT_RADIX 2 // exponent radix +#define FLT_TRUE_MIN 1.401298464e-45F // min positive value + +#endif // !HOST_CODE + +// Additional constants +#define M_2PI 6.28318530717958647693 // 2pi +#define M_4PI 12.5663706143591729539 // 4pi +#define M_4_PI 1.27323954473516268615 // 4/pi +#define M_1_2PI 0.159154943091895335769 // 1/2pi +#define M_1_4PI 0.079577471545947667884 // 1/4pi +#define M_SQRT3 1.732050807568877293527 // sqrt(3) +#define M_SQRTPI 1.77245385090551602730 // sqrt(pi) +#define M_1_SQRT2 0.707106781186547524401 // 1/sqrt(2) + +// Numeric limits for half (IEEE754 binary16) +#define HLF_EPSILON 9.765625e-04F // smallest such that 1.0+HLF_EPSILON != 1.0 +#define HLF_HAS_SUBNORM 1 // type does support subnormal numbers +#define HLF_MANT_DIG 11 +#define HLF_MAX 6.5504e+4F // max value +#define HLF_MAX_EXP 16 // max binary exponent +#define HLF_MIN 6.097555160522461e-05F // min normalized positive value +#define HLF_MIN_EXP (-14) // min binary exponent +#define HLF_RADIX 2 +#define HLF_TRUE_MIN 5.960464477539063e-08F // min positive value + +// clang-format on diff --git a/Techniques/Denoising/SVGF/MathHelpers.slang b/Techniques/Denoising/SVGF/MathHelpers.slang new file mode 100644 index 00000000..3ef0964c --- /dev/null +++ b/Techniques/Denoising/SVGF/MathHelpers.slang @@ -0,0 +1,771 @@ +/*************************************************************************** + # Copyright (c) 2015-24, NVIDIA CORPORATION. All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in the + # documentation and/or other materials provided with the distribution. + # * Neither the name of NVIDIA CORPORATION nor the names of its + # contributors may be used to endorse or promote products derived + # from this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY + # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **************************************************************************/ + +/** + * This file contains various math utility helper functions. + * + * Included functionality (in order): + * + * - Sherical coordinates mapping functions + * - Octahedral mapping functions + * - Sampling functions (disk, sphere, triangle etc.) + * - Misc stuff (matrix inversion, bounding cones etc.) + * + */ + +// Include math constants (M_PI etc.). These are for use in this file only, +// as macro definitions are not exported from a Slang module. +#include "MathConstants.slangh" + +/****************************************************************************** + + Spherical coordinates + + Functions for converting Cartesian coordinates to spherical coordinates + using standard mathematical notations. + + The latitude-longitude map uses (phi,theta) as positions in two dimensions. + Its using using other conventions to orient and wrap the map the same way + as in common 3D software (e.g. Autodesk Maya). + +******************************************************************************/ + +/** + * Converts Cartesian coordinates to spherical coordinates (unsigned normalized). + * 'theta' is the polar angle (inclination) between the +z axis and the vector from origin to p, normalized to [0,1]. + * 'phi' is the azimuthal angle from the +x axis in the xy-plane, normalized to [0,1]. + * @param[in] p Cartesian coordinates (x,y,z). + * @return Spherical coordinates (theta,phi). + */ +float2 cartesian_to_spherical_unorm(float3 p) +{ + p = normalize(p); + float2 sph; + sph.x = acos(p.z) * M_1_PI; + sph.y = atan2(-p.y, -p.x) * M_1_2PI + 0.5f; + return sph; +} + +/** + * Converts Cartesian coordinates to spherical coordinates (radians). + * 'theta' is the polar angle (inclination) between the +z axis and the vector from origin to p, in the range [0,pi]. + * 'phi' is the azimuthal angle from the +x axis in the xy-plane, in the range [0,2pi]. + * @param[in] p Cartesian coordinates (x,y,z). + * @return Spherical coordinates (theta,phi). + */ +float2 cartesian_to_spherical_rad(float3 p) +{ + p = normalize(p); + float2 sph; + sph.x = acos(p.z); + sph.y = atan2(-p.y, -p.x) + M_PI; + return sph; +} + +/** + * Converts spherical coordinates (radians) to Cartesian coordinates. + * Inverse of cartesian_to_spherical_rad. + * @param[in] sph Spherical coordinates (theta,phi). + * @return Cartesian coordinates (x,y,z). + */ +float3 spherical_to_cartesian_rad(float2 sph) +{ + float3 p; + p.x = -cos(sph.y - M_PI) * sin(sph.x); + p.y = -sin(sph.y - M_PI) * sin(sph.x); + p.z = cos(sph.x); + return p; +} + +/** + * Convert world space direction to (u,v) coord in latitude-longitude map (unsigned normalized). + * The map is centered around the -z axis and wrapping around in clockwise order (left to right). + * @param[in] dir World space direction (unnormalized). + * @return Position in latitude-longitude map in [0,1] for each component. + */ +float2 world_to_latlong_map(float3 dir) +{ + float3 p = normalize(dir); + float2 uv; + uv.x = atan2(p.x, -p.z) * M_1_2PI + 0.5f; + uv.y = acos(p.y) * M_1_PI; + return uv; +} + +/** + * Convert a coordinate in latitude-longitude map (unsigned normalized) to a world space direction. + * The map is centered around the -z axis and wrapping around in clockwise order (left to right). + * @param[in] latlong Position in latitude-longitude map in [0,1] for each component. + * @return Normalized direction in world space. + */ +float3 latlong_map_to_world(float2 latlong) +{ + float phi = M_PI * (2.f * saturate(latlong.x) - 1.f); + float theta = M_PI * saturate(latlong.y); + float sinTheta = sin(theta); + float cosTheta = cos(theta); + float sinPhi = sin(phi); + float cosPhi = cos(phi); + return float3(sinTheta * sinPhi, cosTheta, -sinTheta * cosPhi); +} + +/****************************************************************************** + + Octahedral mapping + + The center of the map represents the +z axis and its corners -z. + The rotated inner square is the xy-plane projected onto the upper hemi- + sphere, the outer four triangles folds down over the lower hemisphere. + There are versions for equal-area and non-equal area (slightly faster). + + For details refer to: + - Clarberg 2008, "Fast Equal-Area Mapping of the (Hemi)Sphere using SIMD". + - Cigolle et al. 2014, "Survey of Efficient Representations for Independent Unit Vectors". + +******************************************************************************/ + +/** + * Helper function to reflect the folds of the lower hemisphere + * over the diagonals in the octahedral map. + */ +float2 oct_wrap(float2 v) +{ + return (1.f - abs(v.yx)) * select(v.xy >= 0.f, 1.f, -1.f); +} + +/** + * Converts normalized direction to the octahedral map (non-equal area, signed normalized). + * @param[in] n Normalized direction. + * @return Position in octahedral map in [-1,1] for each component. + */ +float2 ndir_to_oct_snorm(float3 n) +{ + // Project the sphere onto the octahedron (|x|+|y|+|z| = 1) and then onto the xy-plane. + float2 p = n.xy * (1.f / (abs(n.x) + abs(n.y) + abs(n.z))); + p = (n.z < 0.f) ? oct_wrap(p) : p; + return p; +} + +/** + * Converts normalized direction to the octahedral map (non-equal area, unsigned normalized). + * @param[in] n Normalized direction. + * @return Position in octahedral map in [0,1] for each component. + */ +float2 ndir_to_oct_unorm(float3 n) +{ + return ndir_to_oct_snorm(n) * 0.5f + 0.5f; +} + +/** + * Converts point in the octahedral map to normalized direction (non-equal area, signed normalized). + * @param[in] p Position in octahedral map in [-1,1] for each component. + * @return Normalized direction. + */ +float3 oct_to_ndir_snorm(float2 p) +{ + float3 n = float3(p.xy, 1.0 - abs(p.x) - abs(p.y)); + n.xy = (n.z < 0.0) ? oct_wrap(n.xy) : n.xy; + return normalize(n); +} + +/** + * Converts point in the octahedral map to normalized direction (non-equal area, unsigned normalized). + * @param[in] p Position in octahedral map in [0,1] for each component. + * @return Normalized direction. + */ +float3 oct_to_ndir_unorm(float2 p) +{ + return oct_to_ndir_snorm(p * 2.f - 1.f); +} + +/** + * Converts normalized direction to the octahedral map (equal-area, unsigned normalized). + * @param[in] n Normalized direction. + * @return Position in octahedral map in [0,1] for each component. + */ +float2 ndir_to_oct_equal_area_unorm(float3 n) +{ + // Use atan2 to avoid explicit div-by-zero check in atan(y/x). + float r = sqrt(1.f - abs(n.z)); + float phi = atan2(abs(n.y), abs(n.x)); + + // Compute p = (u,v) in the first quadrant. + float2 p; + p.y = r * phi * M_2_PI; + p.x = r - p.y; + + // Reflect p over the diagonals, and move to the correct quadrant. + if (n.z < 0.f) + p = 1.f - p.yx; + p *= sign(n.xy); + + return p * 0.5f + 0.5f; +} + +/** + * Converts point in the octahedral map to normalized direction (equal area, unsigned normalized). + * @param[in] p Position in octahedral map in [0,1] for each component. + * @return Normalized direction. + */ +float3 oct_to_ndir_equal_area_unorm(float2 p) +{ + p = p * 2.f - 1.f; + + // Compute radius r without branching. The radius r=0 at +z (center) and at -z (corners). + float d = 1.f - (abs(p.x) + abs(p.y)); + float r = 1.f - abs(d); + + // Compute phi in [0,pi/2] (first quadrant) and sin/cos without branching. + // TODO: Analyze fp32 precision, do we need a small epsilon instead of 0.0 here? + float phi = (r > 0.f) ? ((abs(p.y) - abs(p.x)) / r + 1.f) * M_PI_4 : 0.f; + + // Convert to Cartesian coordinates. Note that sign(x)=0 for x=0, but that's fine here. + float f = r * sqrt(2.f - r * r); + float x = f * sign(p.x) * cos(phi); + float y = f * sign(p.y) * sin(phi); + float z = sign(d) * (1.f - r * r); + + return float3(x, y, z); +} + +/****************************************************************************** + + Sampling functions + +******************************************************************************/ + +/** + * Uniform sampling of the unit disk using polar coordinates. + * @param[in] u Uniform random number in [0,1)^2. + * @return Sampled point on the unit disk. + */ +float2 sample_disk(float2 u) +{ + float2 p; + float r = sqrt(u.x); + float phi = M_2PI * u.y; + p.x = r * cos(phi); + p.y = r * sin(phi); + return p; +} + +/** + * Uniform sampling of direction within a cone + * @param[in] u Uniform random number in [0,1)^2. + * @param[in] cosTheta Cosine of the cone half-angle + * @return Sampled direction within the cone with (0,0,1) axis + */ +float3 sample_cone(float2 u, float cosTheta) +{ + float z = u.x * (1.f - cosTheta) + cosTheta; + float r = sqrt(1.f - z * z); + float phi = M_2PI * u.y; + return float3(r * cos(phi), r * sin(phi), z); +} + +/** + * Uniform sampling of the unit sphere using spherical coordinates. + * @param[in] u Uniform random numbers in [0,1)^2. + * @return Sampled point on the unit sphere. + */ +float3 sample_sphere(float2 u) +{ + float phi = M_2PI * u.y; + float cosTheta = 1.0f - 2.0f * u.x; + float sinTheta = sqrt(max(0.0f, 1.0f - cosTheta * cosTheta)); + return float3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta); +} + +/** + * Uniform sampling of the unit hemisphere using sphere sampling. + * @param[in] u Uniform random numbers in [0,1)^2. + * @return Sampled point on the unit hemisphere. + */ +float3 sample_hemisphere(float2 u) +{ + float3 w = sample_sphere(u); + w.z = abs(w.z); + return w; +} + +/** + * Uniform sampling of the unit disk using Shirley's concentric mapping. + * @param[in] u Uniform random numbers in [0,1)^2. + * @return Sampled point on the unit disk. + */ +float2 sample_disk_concentric(float2 u) +{ + u = 2.f * u - 1.f; + if (u.x == 0.f && u.y == 0.f) + return u; + float phi, r; + if (abs(u.x) > abs(u.y)) + { + r = u.x; + phi = (u.y / u.x) * M_PI_4; + } + else + { + r = u.y; + phi = M_PI_2 - (u.x / u.y) * M_PI_4; + } + return r * float2(cos(phi), sin(phi)); +} + +/** + * Cosine-weighted sampling of the hemisphere using Shirley's concentric mapping. + * @param[in] u Uniform random numbers in [0,1)^2. + * @param[out] pdf Probability density of the sampled direction (= cos(theta)/pi). + * @return Sampled direction in the local frame (+z axis up). + */ +float3 sample_cosine_hemisphere_concentric(float2 u, out float pdf) +{ + float2 d = sample_disk_concentric(u); + float z = sqrt(max(0.f, 1.f - dot(d, d))); + pdf = z * M_1_PI; + return float3(d, z); +} + +/** + * Cosine-weighted sampling of the hemisphere using a polar coordinates. + * @param[in] u Uniform random numbers in [0,1)^2. + * @param[out] pdf Probability density of the sampled direction (= cos(theta)/pi). + * @return Sampled direction in the local frame (+z axis up). + */ +float3 sample_cosine_hemisphere_polar(float2 u, out float pdf) +{ + float3 p; + float r = sqrt(u.x); + float phi = M_2PI * u.y; + p.x = r * cos(phi); + p.y = r * sin(phi); + p.z = sqrt(1.f - u.x); + pdf = p.z * M_1_PI; + return p; +} + +/** + * Cosine-weighted sampling of the hemisphere using a polar coordinates. + * This overload does not compute the pdf for the generated sample. + * @param[in] u Uniform random numbers in [0,1)^2. + * @return Sampled direction in the local frame (+z axis up). + */ +float3 sample_cosine_hemisphere_polar(float2 u) +{ + float pdf; + return sample_cosine_hemisphere_polar(u, pdf); +} + +/** + * Uniform sampling of a triangle. + * @param[in] u Uniform random numbers in [0,1)^2. + * @return Barycentric coordinates (1-u-v,u,v) of the sampled point. + */ +float3 sample_triangle(float2 u) +{ + float su = sqrt(u.x); + float2 b = float2(1.f - su, u.y * su); + return float3(1.f - b.x - b.y, b.x, b.y); +} + +/** + * Sample from the von-Mises Fisher distribution. + * @param[in] u Uniform random numbers in [0,1)^2. + * @param[in] kappa VMF concentration parameter. + * @return Sampled direction in the local frame (+z axis up). + */ +[PreferRecompute] +float3 sampleVonMisesFisher(float2 u, float kappa) +{ + float sy = max(1.f - u.y, 1e-6f); + float phi = M_2PI * u.x; + float cosTheta = 1.f + log(exp(-2.f * kappa) * (1.f - sy) + sy) / kappa; + float sinTheta = sqrt(1.f - cosTheta * cosTheta); + float3 d = float3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta); + return d; +} + +/****************************************************************************** + + Motion vectors + +******************************************************************************/ + +/** + * Calculate screen-space motion vector. + * @param[in] pixelCrd Sample in current frame expressed in pixel coordinates with origin in the top-left corner. + * @param[in] prevPosH Sample in previous frame expressed in homogeneous clip space coordinates. Note that the definition differs between + * D3D12 and Vulkan. + * @param[in] renderTargetDim Render target dimension in pixels. + * @return Motion vector pointing from current to previous position expressed in sceen space [0,1] with origin in the top-left corner. + */ +float2 calcMotionVector(float2 pixelCrd, float4 prevPosH, float2 renderTargetDim) +{ + float2 prevCrd = prevPosH.xy / prevPosH.w; +#ifdef FALCOR_FLIP_Y + prevCrd *= float2(0.5, 0.5); +#else + prevCrd *= float2(0.5, -0.5); +#endif + prevCrd += 0.5f; + float2 normalizedCrd = pixelCrd / renderTargetDim; + return prevCrd - normalizedCrd; +} + +/****************************************************************************** + + Miscellaneous functions + +******************************************************************************/ + +/** + * Inverts a 2x2 matrix. + */ +float2x2 inverse(float2x2 M) +{ + float2x2 inv; + float invdet = 1.0f / determinant(M); + inv[0][0] = M[1][1] * invdet; + inv[1][1] = M[0][0] * invdet; + inv[0][1] = -M[0][1] * invdet; + inv[1][0] = -M[1][0] * invdet; + return inv; +} + +/** + * Inverts a 2x3 matrix. + */ +float2x3 inverse(float2x3 M) +{ + float2x2 N = float2x2(M._m00, M._m01, M._m10, M._m11); + float2x2 Ni = inverse(N); + float2 t = -mul(Ni, float2(M._m02, M._m12)); + float2x3 Mi = float2x3(Ni._m00, Ni._m01, t.x, Ni._m10, Ni._m11, t.y); + return Mi; +} + +/** + * Inverts a 3x3 matrix. + */ +float3x3 inverse(float3x3 M) +{ + float3x3 inv; + float invdet = 1.0f / determinant(M); + inv[0][0] = (M[1][1] * M[2][2] - M[2][1] * M[1][2]) * invdet; + inv[0][1] = (M[0][2] * M[2][1] - M[0][1] * M[2][2]) * invdet; + inv[0][2] = (M[0][1] * M[1][2] - M[0][2] * M[1][1]) * invdet; + inv[1][0] = (M[1][2] * M[2][0] - M[1][0] * M[2][2]) * invdet; + inv[1][1] = (M[0][0] * M[2][2] - M[0][2] * M[2][0]) * invdet; + inv[1][2] = (M[1][0] * M[0][2] - M[0][0] * M[1][2]) * invdet; + inv[2][0] = (M[1][0] * M[2][1] - M[2][0] * M[1][1]) * invdet; + inv[2][1] = (M[2][0] * M[0][1] - M[0][0] * M[2][1]) * invdet; + inv[2][2] = (M[0][0] * M[1][1] - M[1][0] * M[0][1]) * invdet; + return inv; +} + +/** + * Inverts a 4x4 matrix. + */ +float4x4 inverse(float4x4 m) +{ + float n11 = m[0][0], n12 = m[1][0], n13 = m[2][0], n14 = m[3][0]; + float n21 = m[0][1], n22 = m[1][1], n23 = m[2][1], n24 = m[3][1]; + float n31 = m[0][2], n32 = m[1][2], n33 = m[2][2], n34 = m[3][2]; + float n41 = m[0][3], n42 = m[1][3], n43 = m[2][3], n44 = m[3][3]; + + float t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44; + float t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44; + float t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44; + float t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34; + + float det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14; + float idet = 1.0f / det; + + float4x4 ret; + + ret[0][0] = t11 * idet; + ret[0][1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * idet; + ret[0][2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * idet; + ret[0][3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * idet; + + ret[1][0] = t12 * idet; + ret[1][1] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * idet; + ret[1][2] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * idet; + ret[1][3] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * idet; + + ret[2][0] = t13 * idet; + ret[2][1] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * idet; + ret[2][2] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * idet; + ret[2][3] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * idet; + + ret[3][0] = t14 * idet; + ret[3][1] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * idet; + ret[3][2] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * idet; + ret[3][3] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * idet; + + return ret; +} + +/** + * Generate a vector that is orthogonal to the input vector. + * This can be used to invent a tangent frame for meshes that don't have real tangents/bitangents. + * @param[in] u Unit vector. + * @return v Unit vector that is orthogonal to u. + */ +float3 perp_stark(float3 u) +{ + // TODO: Validate this and look at numerical precision etc. Are there better ways to do it? + float3 a = abs(u); + uint uyx = (a.x - a.y) < 0 ? 1 : 0; + uint uzx = (a.x - a.z) < 0 ? 1 : 0; + uint uzy = (a.y - a.z) < 0 ? 1 : 0; + uint xm = uyx & uzx; + uint ym = (1 ^ xm) & uzy; + uint zm = 1 ^ (xm | ym); // 1 ^ (xm & ym) + float3 v = normalize(cross(u, float3(xm, ym, zm))); + return v; +} + +/** + * @brief Generates full OrthoNormalBasis based on the normal, without branches or sqrt. + * + * From https://graphics.pixar.com/library/OrthonormalB/paper.pdf + */ +void branchlessONB(const float3 n, out float3 b1, out float3 b2) +{ + // can't use just `sign` because we need 0 to go into -1/+1, but not 0 + float sign = (n.z >= 0 ? 1 : -1); + const float a = -1.0f / (sign + n.z); + const float b = n.x * n.y * a; + b1 = float3(1.0f + sign * n.x * n.x * a, sign * b, -sign * n.x); + b2 = float3(b, sign + n.y * n.y * a, -n.y); +} + +// clang-format off +[Differentiable] float sqr(float v) { return v * v; } +[Differentiable] float2 sqr(float2 v) { return v * v; } +[Differentiable] float3 sqr(float3 v) { return v * v; } +[Differentiable] float4 sqr(float4 v) { return v * v; } +// clang-format on + +/** + * Error function. + */ +float erf(float x) +{ + // From "Numerical Recipes in C, The Art of Scientific Computing" + // (Second Edition) by Press et al. 1992. Page 221. + // Maxiumum error: 1.2 x 10^-7. + float t = 1.0f / (1.0f + 0.5f * abs(x)); + float p = 0.17087277f; + p = -0.82215223f + p * t; + p = 1.48851587f + p * t; + p = -1.13520398f + p * t; + p = 0.27886807f + p * t; + p = -0.18628806f + p * t; + p = 0.09678418f + p * t; + p = 0.37409196f + p * t; + p = 1.00002368f + p * t; + p = -1.26551223f + p * t; + float tau = t * exp(-x * x + p); + return x >= 0.0f ? 1.0f - tau : tau - 1.0f; +} + +/** + * Inverse error function. + */ +float erfinv(float x) +{ + // From "Approximating the erfinv function" by Mike Giles 2012. + // Maximum error: 7 x 10^-7. + if (x <= -1.0f) + { + return -1.0f / 0.0f; + } + else if (x >= 1.0f) + { + return 1.0f / 0.0f; + } + + float w = -log((1.0f - x) * (1.0f + x)); + float p; + if (w < 5.0f) + { + w = w - 2.5f; + p = 2.81022636e-08f; + p = 3.43273939e-07f + p * w; + p = -3.5233877e-06f + p * w; + p = -4.39150654e-06f + p * w; + p = 0.00021858087f + p * w; + p = -0.00125372503f + p * w; + p = -0.00417768164f + p * w; + p = 0.246640727f + p * w; + p = 1.50140941f + p * w; + } + else + { + w = sqrt(w) - 3.0f; + p = -0.000200214257f; + p = 0.000100950558f + p * w; + p = 0.00134934322f + p * w; + p = -0.00367342844f + p * w; + p = 0.00573950773f + p * w; + p = -0.0076224613f + p * w; + p = 0.00943887047f + p * w; + p = 1.00167406f + p * w; + p = 2.83297682f + p * w; + } + return p * x; +} + +/** + * Logarithm of the Gamma function. + */ +float lgamma(float x_) +{ + // Lanczos approximation from + // "Numerical Recipes in C, The Art of Scientific Computing" + // (Second Edition) by Press et al. 1992. Page 214. + // Maxiumum error: 2 x 10^-10. + const float g = 5.0; + const float coeffs[7] = { + 1.000000000190015, + 76.18009172947146, + -86.50532032941677, + 24.01409824083091, + -1.231739572450155, + 0.1208650973866179e-2, + -0.5395239384953e-5, + }; + + bool reflect = x_ < 0.5f; + float x = reflect ? -x_ : x_ - 1.0f; + float base = x + g + 0.5f; + + float s = 0.0f; + for (int i = 6; i >= 1; --i) + { + s += coeffs[i] / (x + (float)i); + } + s += coeffs[0]; + + float res = ((log(sqrt(2 * M_PI)) + log(s)) - base) + log(base) * (x + 0.5f); + if (reflect) + { + // Apply the Gamma reflection formula (in log-space). + res = log(abs(M_PI / sin(M_PI * x_))) - res; + } + return res; +} + +/** + * Gamma function. + */ +float gamma(float x) +{ + return exp(lgamma(x)); +} + +/** + * Beta function. + */ +float beta(float x, float y) +{ + return gamma(x) * gamma(y) / gamma(x + y); +} + +/** + * Given two vectors, will orthonormalized them, preserving v1 and v2. + * Vector v1 must be already normalized, v2 will be renormalized as part of the adjustment. + * Vector v2 is assumed to be non-zero and already somewhat orthogonal to v1, as this code does not handle v2=0 or v2=v1 + * + * @param[in] v1 A normalized vector to orthogonalize v2 to. + * @param[in,out] v2 Vector to be adjusted to be orthonormal to v2. + */ +void orthogonalizeVectors(const float3 v1, inout float3 v2) +{ + v2 = normalize(v2 - dot(v1, v2) * v1); +} + +/** + * Rotate a 3D vector counterclockwise around the X-axis. + * The rotation angle is positive for a rotation that is counterclockwise when looking along the x-axis towards the origin. + * @param[in] v Original vector. + * @param[in] angle Angle in radians. + * @return Transformed vector. + */ +[BackwardDifferentiable] +float3 rotate_x(const float3 v, const float angle) +{ + float c, s; + sincos(angle, s, c); + return float3(v.x, v.y * c - v.z * s, v.y * s + v.z * c); +} + +/** + * Rotate a 3D vector counterclockwise around the Y-axis. + * The rotation angle is positive for a rotation that is counterclockwise when looking along the y-axis towards the origin. + * @param[in] v Original vector. + * @param[in] angle Angle in radians. + * @return Transformed vector. + */ +[BackwardDifferentiable] +float3 rotate_y(const float3 v, const float angle) +{ + float c, s; + sincos(angle, s, c); + return float3(v.x * c + v.z * s, v.y, -v.x * s + v.z * c); +} + +/** + * Rotate a 3D vector counterclockwise around the Z-axis. + * The rotation angle is positive for a rotation that is counterclockwise when looking along the z-axis towards the origin. + * @param[in] v Original vector. + * @param[in] angle Angle in radians. + * @return Transformed vector. + */ +[BackwardDifferentiable] +float3 rotate_z(const float3 v, const float angle) +{ + float c, s; + sincos(angle, s, c); + return float3(v.x * c - v.y * s, v.x * s + v.y * c, v.z); +} + +/** + * Normalize a 3D vector, but return 0 if the vector is zero. + * @param[in] v Original vector. + * @return Normalized vector, or 0 if the vector is zero. + */ +[Differentiable] +[PreferRecompute] +float3 normalizeSafe(float3 v) +{ + float len = length(v); + return len > 0.f ? v / len : float3(0.f); +} diff --git a/Techniques/Denoising/SVGF/README.txt b/Techniques/Denoising/SVGF/README.txt new file mode 100644 index 00000000..a0d32ac0 --- /dev/null +++ b/Techniques/Denoising/SVGF/README.txt @@ -0,0 +1 @@ +This was adapted to Gigi from https://github.com/NVIDIAGameWorks/Falcor/tree/master/Source/RenderPasses/SVGFPass \ No newline at end of file diff --git a/Techniques/Denoising/SVGF/SVGF.gg b/Techniques/Denoising/SVGF/SVGF.gg new file mode 100644 index 00000000..519f1ad8 --- /dev/null +++ b/Techniques/Denoising/SVGF/SVGF.gg @@ -0,0 +1,1343 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "variables": [ + { + "name": "BuffersNeedClear", + "type": "Bool", + "dflt": "true" + }, + { + "name": "Alpha", + "type": "Float", + "dflt": "0.05f", + "visibility": "User" + }, + { + "name": "MomentsAlpha", + "type": "Float", + "dflt": "0.2f", + "visibility": "User" + }, + { + "name": "PhiColor", + "type": "Float", + "dflt": "10.0f", + "visibility": "User" + }, + { + "name": "PhiNormal", + "type": "Float", + "dflt": "128.0f", + "visibility": "User" + }, + { + "name": "FilterIterations", + "comment": "For atrous filtering", + "type": "Int", + "Const": true, + "dflt": "4", + "visibility": "User" + }, + { + "name": "FeedbackTap", + "comment": "When do to the feedback tap in the atrous loop. -1 to use the illumination.", + "type": "Int", + "dflt": "1", + "visibility": "User" + }, + { + "name": "FeedbackTapMax", + "type": "Int" + } + ], + "shaders": [ + { + "name": "ClearBuffersCS", + "fileName": "ClearBuffersCS.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "LinearZAndNormal", + "type": "Texture", + "access": "UAV" + }, + { + "name": "PrevLinearZAndNormal", + "type": "Texture", + "access": "UAV" + }, + { + "name": "FilteredPastFbo", + "type": "Texture", + "access": "UAV" + }, + { + "name": "PrevReprojFbo_0", + "type": "Texture", + "access": "UAV" + }, + { + "name": "PrevReprojFbo_1", + "type": "Texture", + "access": "UAV" + }, + { + "name": "PrevReprojFbo_2", + "type": "Texture", + "access": "UAV" + }, + { + "name": "CurReprojFbo_0", + "type": "Texture", + "access": "UAV" + }, + { + "name": "CurReprojFbo_1", + "type": "Texture", + "access": "UAV" + }, + { + "name": "CurReprojFbo_2", + "type": "Texture", + "access": "UAV" + }, + { + "name": "PingPongFbo_0", + "type": "Texture", + "access": "UAV" + }, + { + "name": "PingPongFbo_1", + "type": "Texture", + "access": "UAV" + }, + { + "name": "Final_Fbo", + "type": "Texture", + "access": "UAV" + } + ] + }, + { + "name": "ComputeLinearZAndNormal", + "fileName": "SVGFPackLinearZAndNormal.ps.slang", + "entryPoint": "csmain", + "slangOptions": { + "process": true + }, + "resources": [ + { + "name": "gLinearZ", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gNormal", + "type": "Texture", + "access": "SRV" + }, + { + "name": "LinearZAndNormalFbo", + "type": "Texture", + "access": "UAV" + } + ] + }, + { + "name": "ComputeReprojectionCS", + "fileName": "SVGFReproject.ps.slang", + "entryPoint": "csmain", + "slangOptions": { + "process": true + }, + "resources": [ + { + "name": "gMotion", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gColor", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gEmission", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gAlbedo", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gPositionNormalFwidth", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gLinearZAndNormal", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gPrevLinearZAndNormal", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gPrevIllum", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gPrevMoments", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gPrevHistoryLength", + "type": "Texture", + "access": "SRV" + }, + { + "name": "CurReprojFbo_0", + "type": "Texture", + "access": "UAV" + }, + { + "name": "CurReprojFbo_1", + "type": "Texture", + "access": "UAV", + "texture": { + "viewType": "Float2" + } + }, + { + "name": "CurReprojFbo_2", + "type": "Texture", + "access": "UAV", + "texture": { + "viewType": "Float" + } + } + ] + }, + { + "name": "ComputeFilteredMomentsCS", + "fileName": "SVGFFilterMoments.ps.slang", + "entryPoint": "csmain", + "slangOptions": { + "process": true + }, + "resources": [ + { + "name": "gLinearZAndNormal", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gIllumination", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gMoments", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gHistoryLength", + "type": "Texture", + "access": "SRV" + }, + { + "name": "PingPongFbo_0", + "type": "Texture", + "access": "UAV" + } + ] + }, + { + "name": "FinalModulateCS", + "fileName": "SVGFFinalModulate.ps.slang", + "entryPoint": "csmain", + "slangOptions": { + "process": true + }, + "resources": [ + { + "name": "gEmission", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gAlbedo", + "type": "Texture", + "access": "SRV" + }, + { + "name": "gIllumination", + "type": "Texture", + "access": "SRV" + }, + { + "name": "FinalFbo", + "type": "Texture", + "access": "UAV" + } + ] + } + ], + "fileCopies": [ + { + "fileName": "MathHelpers.slang", + "type": "Shader" + }, + { + "fileName": "MathConstants.slangh", + "type": "Shader" + }, + { + "fileName": "ColorHelpers.slang", + "type": "Shader" + }, + { + "fileName": "SVGFCommon.slang", + "type": "Shader" + } + ], + "nodes": [ + { + "actionComputeShader": { + "name": "ClearBuffers", + "editorPos": [ + -251.0, + -30.0 + ], + "condition": { + "variable1": "BuffersNeedClear", + "comparison": "IsTrue" + }, + "linkProperties": [ + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "LinearZAndNormal", + "dstNode": "Internal_LinearZAndNormalFbo", + "dstPin": "resource" + }, + { + "srcPin": "FilteredPastFbo", + "dstNode": "Internal_FilteredPastFbo", + "dstPin": "resource" + }, + { + "srcPin": "PrevReprojFbo_0", + "dstNode": "Internal_PrevReprojFbo_0", + "dstPin": "resource" + }, + { + "srcPin": "PrevReprojFbo_1", + "dstNode": "Internal_PrevReprojFbo_1", + "dstPin": "resource" + }, + { + "srcPin": "PrevReprojFbo_2", + "dstNode": "Internal_PrevReprojFbo_2", + "dstPin": "resource" + }, + { + "srcPin": "PrevReprojFbo_1" + }, + { + "srcPin": "PrevReprojFbo_0" + }, + { + "srcPin": "CurReprojFbo_1", + "dstNode": "Internal_CurReprojFbo_1", + "dstPin": "resource" + }, + { + "srcPin": "CurReprojFbo_2", + "dstNode": "Internal_CurReprojFbo_2", + "dstPin": "resource" + }, + { + "srcPin": "CurReprojFbo_0", + "dstNode": "Internal_CurReprojFbo_0", + "dstPin": "resource" + }, + { + "srcPin": "PrevLinearZAndNormal", + "dstNode": "Internal_PrevLinearZAndNormal", + "dstPin": "resource" + }, + { + "srcPin": "PingPongFbo_1", + "dstNode": "Internal_PingPongFbo_1", + "dstPin": "resource" + }, + { + "srcPin": "PingPongFbo_0", + "dstNode": "Internal_PingPongFbo_0", + "dstPin": "resource" + }, + { + "srcPin": "Final_Fbo", + "dstNode": "Internal_FinalFbo", + "dstPin": "resource" + } + ], + "shader": { + "name": "ClearBuffersCS" + }, + "dispatchSize": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "resourceTexture": { + "name": "Internal_LinearZAndNormalFbo", + "editorPos": [ + -575.0, + -158.0 + ], + "transient": false, + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "resourceTexture": { + "name": "LinearZ", + "editorPos": [ + -117.0, + -142.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "WorldNormal", + "editorPos": [ + -123.0, + -94.0 + ], + "visibility": "Imported" + } + }, + { + "actionComputeShader": { + "name": "ComputeLinearZAndNormal", + "editorPos": [ + 32.0, + -81.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "gLinearZ", + "dstNode": "LinearZ", + "dstPin": "resource" + }, + { + "srcPin": "gNormal", + "dstNode": "WorldNormal", + "dstPin": "resource" + }, + { + "srcPin": "LinearZAndNormalFbo", + "dstNode": "ClearBuffers", + "dstPin": "LinearZAndNormal" + } + ], + "shader": { + "name": "ComputeLinearZAndNormal" + }, + "dispatchSize": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "resourceTexture": { + "name": "Internal_CurReprojFbo_0", + "comment": "index 0 is illumination", + "editorPos": [ + -536.0, + 130.0 + ], + "transient": false, + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "resourceTexture": { + "name": "Internal_CurReprojFbo_1", + "comment": "index 1 is moments", + "editorPos": [ + -536.0, + 178.0 + ], + "transient": false, + "format": { + "format": "RG32_Float" + }, + "size": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "resourceTexture": { + "name": "Internal_CurReprojFbo_2", + "comment": "index 2 is history length", + "editorPos": [ + -536.0, + 226.0 + ], + "transient": false, + "format": { + "format": "R32_Float" + }, + "size": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "actionComputeShader": { + "name": "ComputeReprojection", + "editorPos": [ + 357.0, + -110.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "gEmission", + "dstNode": "Emission", + "dstPin": "resource" + }, + { + "srcPin": "gMotion", + "dstNode": "MotionVector", + "dstPin": "resource" + }, + { + "srcPin": "gColor", + "dstNode": "Color", + "dstPin": "resource" + }, + { + "srcPin": "gAlbedo", + "dstNode": "Albedo", + "dstPin": "resource" + }, + { + "srcPin": "gPrevMoments", + "dstNode": "ClearBuffers", + "dstPin": "PrevReprojFbo_1" + }, + { + "srcPin": "gPositionNormalFwidth", + "dstNode": "PosNormalFwidth", + "dstPin": "resource" + }, + { + "srcPin": "gPrevIllum", + "dstNode": "ClearBuffers", + "dstPin": "FilteredPastFbo" + }, + { + "srcPin": "gPrevHistoryLength", + "dstNode": "ClearBuffers", + "dstPin": "PrevReprojFbo_2" + }, + { + "srcPin": "gLinearZAndNormal", + "dstNode": "ComputeLinearZAndNormal", + "dstPin": "LinearZAndNormalFbo" + }, + { + "srcPin": "gPrevLinearZAndNormal", + "dstNode": "ClearBuffers", + "dstPin": "PrevLinearZAndNormal" + }, + { + "srcPin": "CurReprojFbo_2", + "dstNode": "ClearBuffers", + "dstPin": "CurReprojFbo_2" + }, + { + "srcPin": "CurReprojFbo_0", + "dstNode": "ClearBuffers", + "dstPin": "CurReprojFbo_0" + }, + { + "srcPin": "CurReprojFbo_1", + "dstNode": "ClearBuffers", + "dstPin": "CurReprojFbo_1" + } + ], + "shader": { + "name": "ComputeReprojectionCS" + }, + "dispatchSize": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "resourceTexture": { + "name": "MotionVector", + "editorPos": [ + 86.0, + -334.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "Color", + "editorPos": [ + 91.0, + -286.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "Emission", + "editorPos": [ + 91.0, + -238.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "Albedo", + "editorPos": [ + 91.0, + -190.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "PosNormalFwidth", + "editorPos": [ + 62.0, + -142.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "Internal_FilteredPastFbo", + "editorPos": [ + -536.0, + -62.0 + ], + "transient": false, + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "resourceTexture": { + "name": "Internal_PrevReprojFbo_0", + "comment": "index 0 is illumination", + "editorPos": [ + -542.0, + -14.0 + ], + "transient": false, + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "resourceTexture": { + "name": "Internal_PrevReprojFbo_1", + "comment": "index 1 is moments", + "editorPos": [ + -542.0, + 34.0 + ], + "transient": false, + "format": { + "format": "RG32_Float" + }, + "size": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "resourceTexture": { + "name": "Internal_PrevReprojFbo_2", + "comment": "index 2 is history length", + "editorPos": [ + -542.0, + 82.0 + ], + "transient": false, + "format": { + "format": "R32_Float" + }, + "size": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "resourceTexture": { + "name": "Internal_PrevLinearZAndNormal", + "editorPos": [ + -580.0, + -110.0 + ], + "transient": false, + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "actionComputeShader": { + "name": "ComputeFilteredMoments", + "editorPos": [ + 613.0, + 82.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "gIllumination", + "dstNode": "ComputeReprojection", + "dstPin": "CurReprojFbo_0" + }, + { + "srcPin": "gHistoryLength", + "dstNode": "ComputeReprojection", + "dstPin": "CurReprojFbo_2" + }, + { + "srcPin": "gLinearZAndNormal", + "dstNode": "ComputeReprojection", + "dstPin": "gLinearZAndNormal" + }, + { + "srcPin": "gMoments", + "dstNode": "ComputeReprojection", + "dstPin": "CurReprojFbo_1" + }, + { + "srcPin": "PingPongFbo_0", + "dstNode": "ClearBuffers", + "dstPin": "PingPongFbo_0" + } + ], + "shader": { + "name": "ComputeFilteredMomentsCS" + }, + "dispatchSize": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "resourceTexture": { + "name": "Internal_PingPongFbo_0", + "editorPos": [ + -531.0, + 274.0 + ], + "transient": false, + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "resourceTexture": { + "name": "Internal_PingPongFbo_1", + "editorPos": [ + -531.0, + 322.0 + ], + "transient": false, + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "actionSubGraph": { + "name": "ComputeAtrousDecomposition", + "editorPos": [ + 933.0, + -20.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Albedo", + "dstNode": "ComputeReprojection", + "dstPin": "gAlbedo" + }, + { + "srcPin": "LinearZAndNormal", + "dstNode": "ComputeFilteredMoments", + "dstPin": "gLinearZAndNormal" + }, + { + "srcPin": "HistoryLength", + "dstNode": "ComputeFilteredMoments", + "dstPin": "gHistoryLength" + }, + { + "srcPin": "PingPongFbo_0", + "dstNode": "ComputeFilteredMoments", + "dstPin": "PingPongFbo_0" + }, + { + "srcPin": "PingPongFbo_1 ", + "dstNode": "PingPongFbo_1_A", + "dstPin": "Pin 0" + }, + { + "srcPin": "FilteredPastFbo", + "dstNode": "ComputeReprojection", + "dstPin": "gPrevIllum" + } + ], + "fileName": "Atrous.gg", + "subGraphData": { + "importedResources": [ + "Albedo", + "LinearZAndNormal", + "HistoryLength", + "PingPongFbo_0", + "PingPongFbo_1 ", + "FilteredPastFbo" + ], + "variables": [ + { + "name": "PhiColor" + }, + { + "name": "PhiNormal", + "visibility": "User" + }, + { + "name": "LoopIndex", + "visibility": "Host" + }, + { + "name": "FeedbackTap", + "visibility": "User" + } + ] + }, + "variableSettings": [ + { + "name": "PhiColor", + "visibility": "User", + "replaceWithStr": "PhiColor" + }, + { + "name": "PhiNormal", + "visibility": "User", + "replaceWithStr": "PhiNormal" + }, + { + "name": "LoopIndex", + "isLoopIndex": true + }, + { + "name": "FeedbackTap", + "visibility": "User", + "replaceWithStr": "FeedbackTap" + } + ], + "loopCountVariable": { + "name": "FilterIterations" + } + } + }, + { + "actionBarrier": { + "name": "PingPongFbo_1_A", + "comment": "Just to route the lines more cleanly", + "editorPos": [ + 667.0, + 242.0 + ], + "linkProperties": [ + {}, + {} + ], + "connections": [ + { + "srcPin": "Pin 0", + "dstNode": "ClearBuffers", + "dstPin": "PingPongFbo_1" + }, + { + "srcPin": "Pin 1" + } + ] + } + }, + { + "actionCopyResource": { + "name": "FeedbackTapOuter", + "editorPos": [ + 1201.0, + 130.0 + ], + "condition": { + "variable1": "FeedbackTap", + "comparison": "LT", + "value2": "0" + }, + "linkProperties": [ + {}, + {} + ], + "source": { + "node": "ComputeFilteredMoments", + "pin": "gIllumination" + }, + "dest": { + "node": "ComputeAtrousDecomposition", + "pin": "FilteredPastFbo" + } + } + }, + { + "actionComputeShader": { + "name": "FinalModulate", + "editorPos": [ + 1419.0, + -74.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "gAlbedo", + "dstNode": "ComputeAtrousDecomposition", + "dstPin": "Albedo" + }, + { + "srcPin": "gEmission", + "dstNode": "ComputeReprojection", + "dstPin": "gEmission" + }, + { + "srcPin": "gIllumination", + "dstNode": "ComputeAtrousDecomposition", + "dstPin": "PingPongFbo_0" + }, + { + "srcPin": "FinalFbo", + "dstNode": "Final_Fbo_A", + "dstPin": "Pin 0" + } + ], + "shader": { + "name": "FinalModulateCS" + }, + "dispatchSize": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "resourceTexture": { + "name": "Internal_FinalFbo", + "editorPos": [ + -496.0, + 370.0 + ], + "transient": false, + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "actionBarrier": { + "name": "Final_Fbo_A", + "editorPos": [ + 661.0, + 322.0 + ], + "linkProperties": [ + {}, + {} + ], + "connections": [ + { + "srcPin": "Pin 0", + "dstNode": "ClearBuffers", + "dstPin": "Final_Fbo" + }, + { + "srcPin": "Pin 1" + } + ] + } + }, + { + "resourceTexture": { + "name": "Output", + "editorPos": [ + 1547.0, + 95.0 + ], + "visibility": "Exported", + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "LinearZ" + } + } + } + }, + { + "actionCopyResource": { + "name": "BlitToOutput", + "editorPos": [ + 1685.0, + -17.0 + ], + "linkProperties": [ + {}, + {} + ], + "source": { + "node": "FinalModulate", + "pin": "FinalFbo" + }, + "dest": { + "node": "Output", + "pin": "resource" + } + } + }, + { + "actionSubGraph": { + "name": "SwapReprojFbo_0", + "editorPos": [ + 1301.0, + -206.0 + ], + "linkProperties": [ + {}, + {} + ], + "connections": [ + { + "srcPin": "A", + "dstNode": "FeedbackTapOuter", + "dstPin": "source" + }, + { + "srcPin": "B", + "dstNode": "PrevReprojFbo_0_A", + "dstPin": "Pin 0" + } + ], + "fileName": "SwapTextures.gg", + "subGraphData": { + "importedResources": [ + "A", + "B" + ] + } + } + }, + { + "actionBarrier": { + "name": "PrevReprojFbo_0_A", + "editorPos": [ + 661.0, + 418.0 + ], + "linkProperties": [ + {}, + {} + ], + "connections": [ + { + "srcPin": "Pin 0", + "dstNode": "ClearBuffers", + "dstPin": "PrevReprojFbo_0" + }, + { + "srcPin": "Pin 1" + } + ] + } + }, + { + "actionSubGraph": { + "name": "SwapReprojFbo_1", + "editorPos": [ + 943.0, + -206.0 + ], + "linkProperties": [ + {}, + {} + ], + "connections": [ + { + "srcPin": "A", + "dstNode": "ComputeFilteredMoments", + "dstPin": "gMoments" + }, + { + "srcPin": "B", + "dstNode": "ComputeReprojection", + "dstPin": "gPrevMoments" + } + ], + "fileName": "SwapTextures.gg", + "subGraphData": { + "importedResources": [ + "A", + "B" + ] + } + } + }, + { + "actionSubGraph": { + "name": "SwapReprojFbo_2", + "editorPos": [ + 1125.0, + -206.0 + ], + "linkProperties": [ + {}, + {} + ], + "connections": [ + { + "srcPin": "A", + "dstNode": "ComputeAtrousDecomposition", + "dstPin": "HistoryLength" + }, + { + "srcPin": "B", + "dstNode": "ComputeReprojection", + "dstPin": "gPrevHistoryLength" + } + ], + "fileName": "SwapTextures.gg", + "subGraphData": { + "importedResources": [ + "A", + "B" + ] + } + } + }, + { + "actionCopyResource": { + "name": "CopyLinearZAndNormalFbo", + "editorPos": [ + 1509.0, + -206.0 + ], + "linkProperties": [ + {}, + {} + ], + "source": { + "node": "ComputeAtrousDecomposition", + "pin": "LinearZAndNormal" + }, + "dest": { + "node": "ComputeReprojection", + "pin": "gPrevLinearZAndNormal" + } + } + } + ], + "setVars": [ + { + "destination": { + "name": "BuffersNeedClear" + }, + "ALiteral": "false", + "op": "Noop", + "setBefore": false + }, + { + "destination": { + "name": "FeedbackTapMax" + }, + "AVar": { + "name": "FilterIterations" + }, + "op": "Subtract", + "BLiteral": "1" + }, + { + "destination": { + "name": "FeedbackTap" + }, + "AVar": { + "name": "FeedbackTap" + }, + "op": "Minimum", + "BVar": { + "name": "FeedbackTapMax" + } + }, + { + "destination": { + "name": "FeedbackTap" + }, + "AVar": { + "name": "FeedbackTap" + }, + "op": "Maximum", + "BLiteral": "-1" + } + ] +} \ No newline at end of file diff --git a/Techniques/Denoising/SVGF/SVGF.gguser b/Techniques/Denoising/SVGF/SVGF.gguser new file mode 100644 index 00000000..95c94920 --- /dev/null +++ b/Techniques/Denoising/SVGF/SVGF.gguser @@ -0,0 +1,172 @@ +{ + "version": "2.0", + "snapshot": { + "resourceViewNodeIndex": 41, + "resourceViewResourceIndex": 2, + "importedResources": [ + { + "nodeName": "Albedo", + "texture": { + "size": [ + 512, + 512, + 1 + ], + "color": [ + 0.501960813999176, + 1.0, + 0.501960813999176, + 1.0 + ] + } + }, + { + "nodeName": "Color", + "texture": { + "size": [ + 512, + 512, + 1 + ], + "color": [ + 1.0, + 0.501960813999176, + 0.501960813999176, + 1.0 + ] + } + }, + { + "nodeName": "Emission", + "texture": { + "size": [ + 512, + 512, + 1 + ], + "color": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "format": "RGBA32_Float" + } + }, + { + "nodeName": "LinearZ", + "texture": { + "size": [ + 512, + 512, + 1 + ], + "color": [ + 0.501960813999176, + 1.0, + 1.0, + 1.0 + ], + "format": "R32_Float" + } + }, + { + "nodeName": "MotionVector", + "texture": { + "size": [ + 512, + 512, + 1 + ], + "color": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "format": "RGBA32_Float" + } + }, + { + "nodeName": "PosNormalFwidth", + "texture": { + "size": [ + 512, + 512, + 1 + ], + "color": [ + 0.0, + 0.0, + 0.0, + 0.0 + ], + "format": "RGBA32_Float" + } + }, + { + "nodeName": "WorldNormal", + "texture": { + "size": [ + 512, + 512, + 1 + ], + "color": [ + 0.0, + 1.0, + 0.0, + 1.0 + ], + "format": "RGBA32_Float" + } + } + ], + "savedVariables": [ + { + "name": "BuffersNeedClear", + "value": "false" + }, + { + "name": "Alpha", + "value": "0.050000" + }, + { + "name": "MomentsAlpha", + "value": "0.200000" + }, + { + "name": "PhiColor", + "value": "10.000000" + }, + { + "name": "PhiNormal", + "value": "128.000000" + }, + { + "name": "FeedbackTap", + "value": "1" + }, + { + "name": "FeedbackTapMax", + "value": "3" + }, + { + "name": "ComputeAtrousDecomposition_Iteration_0_LoopIndex", + "value": "0" + }, + { + "name": "ComputeAtrousDecomposition_Iteration_1_LoopIndex", + "value": "0" + }, + { + "name": "ComputeAtrousDecomposition_Iteration_2_LoopIndex", + "value": "0" + }, + { + "name": "ComputeAtrousDecomposition_Iteration_3_LoopIndex", + "value": "0" + } + ] + } +} \ No newline at end of file diff --git a/Techniques/Denoising/SVGF/SVGFAtrous.ps.slang b/Techniques/Denoising/SVGF/SVGFAtrous.ps.slang new file mode 100644 index 00000000..c8747a37 --- /dev/null +++ b/Techniques/Denoising/SVGF/SVGFAtrous.ps.slang @@ -0,0 +1,154 @@ +/*************************************************************************** + # Copyright (c) 2015-23, NVIDIA CORPORATION. All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in the + # documentation and/or other materials provided with the distribution. + # * Neither the name of NVIDIA CORPORATION nor the names of its + # contributors may be used to endorse or promote products derived + # from this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY + # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **************************************************************************/ +import MathHelpers; +import ColorHelpers; +import SVGFCommon; + +/*$(ShaderResources)*/ +#define gStepSize (1 << /*$(Variable:LoopIndex)*/) +#define gPhiColor /*$(Variable:PhiColor)*/ +#define gPhiNormal /*$(Variable:PhiNormal)*/ +/* +cbuffer PerImageCB +{ + Texture2D gAlbedo; + Texture2D gHistoryLength; + Texture2D gIllumination; + Texture2D gLinearZAndNormal; + + int gStepSize; + float gPhiColor; + float gPhiNormal; +}; +*/ + +// computes a 3x3 gaussian blur of the variance, centered around +// the current pixel +float computeVarianceCenter(int2 ipos) +{ + float sum = 0.f; + + const float kernel[2][2] = { + { 1.0 / 4.0, 1.0 / 8.0 }, + { 1.0 / 8.0, 1.0 / 16.0 }, + }; + + const int radius = 1; + for (int yy = -radius; yy <= radius; yy++) + { + for (int xx = -radius; xx <= radius; xx++) + { + const int2 p = ipos + int2(xx, yy); + const float k = kernel[abs(xx)][abs(yy)]; + sum += gIllumination.Load(int3(p, 0)).a * k; + } + } + + return sum; +} + +//float4 main(FullScreenPassVsOut vsOut) : SV_TARGET0 +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + const int2 ipos = int2(DTid.xy); + const int2 screenSize = getTextureDims(gAlbedo, 0); + + const float epsVariance = 1e-10; + const float kernelWeights[3] = { 1.0, 2.0 / 3.0, 1.0 / 6.0 }; + + // constant samplers to prevent the compiler from generating code which + // fetches the sampler descriptor from memory for each texture access + const float4 illuminationCenter = gIllumination.Load(int3(ipos, 0)); + const float lIlluminationCenter = luminance(illuminationCenter.rgb); + + // variance, filtered using 3x3 gaussin blur + const float var = computeVarianceCenter(ipos); + + // number of temporally integrated pixels + const float historyLength = gHistoryLength[ipos].x; + + const float2 zCenter = gLinearZAndNormal[ipos].xy; + if (zCenter.x < 0) + { + // not a valid depth => must be envmap => do not filter + Output[ipos] = illuminationCenter; + return; + } + const float3 nCenter = oct_to_ndir_snorm(gLinearZAndNormal[ipos].zw); + + const float phiLIllumination = gPhiColor * sqrt(max(0.0, epsVariance + var.r)); + const float phiDepth = max(zCenter.y, 1e-8) * gStepSize; + + // explicitly store/accumulate center pixel with weight 1 to prevent issues + // with the edge-stopping functions + float sumWIllumination = 1.0; + float4 sumIllumination = illuminationCenter; + + for (int yy = -2; yy <= 2; yy++) + { + for (int xx = -2; xx <= 2; xx++) + { + const int2 p = ipos + int2(xx, yy) * gStepSize; + const bool inside = all(p >= int2(0, 0)) && all(p < screenSize); + + const float kernel = kernelWeights[abs(xx)] * kernelWeights[abs(yy)]; + + if (inside && (xx != 0 || yy != 0)) // skip center pixel, it is already accumulated + { + const float4 illuminationP = gIllumination.Load(int3(p, 0)); + const float lIlluminationP = luminance(illuminationP.rgb); + const float zP = gLinearZAndNormal[p].x; + const float3 nP = oct_to_ndir_snorm(gLinearZAndNormal[p].zw); + + // compute the edge-stopping functions + const float2 w = computeWeight( + zCenter.x, + zP, + phiDepth * length(float2(xx, yy)), + nCenter, + nP, + gPhiNormal, + lIlluminationCenter, + lIlluminationP, + phiLIllumination + ); + + const float wIllumination = w.x * kernel; + + // alpha channel contains the variance, therefore the weights need to be squared, see paper for the formula + sumWIllumination += wIllumination; + sumIllumination += float4(wIllumination.xxx, wIllumination * wIllumination) * illuminationP; + } + } + } + + // renormalization is different for variance, check paper for the formula + float4 filteredIllumination = float4(sumIllumination / float4(sumWIllumination.xxx, sumWIllumination * sumWIllumination)); + + Output[ipos] = filteredIllumination; +} diff --git a/Techniques/Denoising/SVGF/SVGFCommon.slang b/Techniques/Denoising/SVGF/SVGFCommon.slang new file mode 100644 index 00000000..b801b213 --- /dev/null +++ b/Techniques/Denoising/SVGF/SVGFCommon.slang @@ -0,0 +1,64 @@ +/*************************************************************************** + # Copyright (c) 2015-23, NVIDIA CORPORATION. All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in the + # documentation and/or other materials provided with the distribution. + # * Neither the name of NVIDIA CORPORATION nor the names of its + # contributors may be used to endorse or promote products derived + # from this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY + # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **************************************************************************/ +int2 getTextureDims(Texture2D tex, uint mip) +{ + uint w, h; + tex.GetDimensions(w, h); + return int2(w, h); +} + +float computeWeight( + float depthCenter, + float depthP, + float phiDepth, + float3 normalCenter, + float3 normalP, + float phiNormal, + float luminanceIllumCenter, + float luminanceIllumP, + float phiIllum +) +{ + const float weightNormal = pow(saturate(dot(normalCenter, normalP)), phiNormal); + const float weightZ = (phiDepth == 0) ? 0.0f : abs(depthCenter - depthP) / phiDepth; + const float weightLillum = abs(luminanceIllumCenter - luminanceIllumP) / phiIllum; + + const float weightIllum = exp(0.0 - max(weightLillum, 0.0) - max(weightZ, 0.0)) * weightNormal; + + return weightIllum; +} + +struct FullScreenPassVsOut +{ + float2 texC : TEXCOORD; +#ifndef _VIEWPORT_MASK + float4 posH : SV_POSITION; +#else + float4 posH : POSITION; +#endif +}; diff --git a/Techniques/Denoising/SVGF/SVGFFilterMoments.ps.slang b/Techniques/Denoising/SVGF/SVGFFilterMoments.ps.slang new file mode 100644 index 00000000..54249418 --- /dev/null +++ b/Techniques/Denoising/SVGF/SVGFFilterMoments.ps.slang @@ -0,0 +1,138 @@ +/*************************************************************************** + # Copyright (c) 2015-23, NVIDIA CORPORATION. All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in the + # documentation and/or other materials provided with the distribution. + # * Neither the name of NVIDIA CORPORATION nor the names of its + # contributors may be used to endorse or promote products derived + # from this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY + # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **************************************************************************/ +import MathHelpers; +import ColorHelpers; +import SVGFCommon; + +/*$(ShaderResources)*/ +#define gPhiColor /*$(Variable:PhiColor)*/ +#define gPhiNormal /*$(Variable:PhiNormal)*/ +/* +cbuffer PerImageCB +{ + Texture2D gIllumination; + Texture2D gMoments; + Texture2D gHistoryLength; + Texture2D gLinearZAndNormal; + + float gPhiColor; + float gPhiNormal; +}; +*/ + +//float4 main(FullScreenPassVsOut vsOut) : SV_TARGET0 +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + const float4 posH = float4(DTid.xy, 0.0f, 0.0f); + int2 ipos = int2(posH.xy); + + float h = gHistoryLength[ipos].x; + int2 screenSize = getTextureDims(gHistoryLength, 0); + + if (h < 4.0) // not enough temporal history available + { + float sumWIllumination = 0.0; + float3 sumIllumination = float3(0.0, 0.0, 0.0); + float2 sumMoments = float2(0.0, 0.0); + + const float4 illuminationCenter = gIllumination[ipos]; + const float lIlluminationCenter = luminance(illuminationCenter.rgb); + + const float2 zCenter = gLinearZAndNormal[ipos].xy; + if (zCenter.x < 0) + { + // current pixel does not a valid depth => must be envmap => do nothing + PingPongFbo_0[ipos] = illuminationCenter; + return; + } + const float3 nCenter = oct_to_ndir_snorm(gLinearZAndNormal[ipos].zw); + const float phiLIllumination = gPhiColor; + const float phiDepth = max(zCenter.y, 1e-8) * 3.0; + + // compute first and second moment spatially. This code also applies cross-bilateral + // filtering on the input illumination. + const int radius = 3; + + for (int yy = -radius; yy <= radius; yy++) + { + for (int xx = -radius; xx <= radius; xx++) + { + const int2 p = ipos + int2(xx, yy); + const bool inside = all(p >= int2(0, 0)) && all(p < screenSize); + const bool samePixel = (xx == 0 && yy == 0); + const float kernel = 1.0; + + if (inside) + { + const float3 illuminationP = gIllumination[p].rgb; + const float2 momentsP = gMoments[p].xy; + const float lIlluminationP = luminance(illuminationP.rgb); + const float zP = gLinearZAndNormal[p].x; + const float3 nP = oct_to_ndir_snorm(gLinearZAndNormal[p].zw); + + const float w = computeWeight( + zCenter.x, + zP, + phiDepth * length(float2(xx, yy)), + nCenter, + nP, + gPhiNormal, + lIlluminationCenter, + lIlluminationP, + phiLIllumination + ); + + sumWIllumination += w; + sumIllumination += illuminationP * w; + sumMoments += momentsP * w; + } + } + } + + // Clamp sum to >0 to avoid NaNs. + sumWIllumination = max(sumWIllumination, 1e-6f); + + sumIllumination /= sumWIllumination; + sumMoments /= sumWIllumination; + + // compute variance using the first and second moments + float variance = sumMoments.g - sumMoments.r * sumMoments.r; + + // give the variance a boost for the first frames + variance *= 4.0 / h; + + PingPongFbo_0[ipos] = float4(sumIllumination, variance.r); + return; + } + else + { + // do nothing, pass data unmodified + PingPongFbo_0[ipos] = gIllumination[ipos]; + return; + } +} diff --git a/Techniques/Denoising/SVGF/SVGFFinalModulate.ps.slang b/Techniques/Denoising/SVGF/SVGFFinalModulate.ps.slang new file mode 100644 index 00000000..5681cea1 --- /dev/null +++ b/Techniques/Denoising/SVGF/SVGFFinalModulate.ps.slang @@ -0,0 +1,46 @@ +/*************************************************************************** + # Copyright (c) 2015-23, NVIDIA CORPORATION. All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in the + # documentation and/or other materials provided with the distribution. + # * Neither the name of NVIDIA CORPORATION nor the names of its + # contributors may be used to endorse or promote products derived + # from this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY + # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **************************************************************************/ +import SVGFCommon; + +/*$(ShaderResources)*/ +/* +cbuffer PerImageCB +{ + Texture2D gAlbedo; + Texture2D gEmission; + Texture2D gIllumination; +}; +*/ + +//float4 main(FullScreenPassVsOut vsOut) : SV_TARGET0 +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + const int2 ipos = int2(DTid.xy); + + FinalFbo[ipos] = gAlbedo[ipos] * gIllumination[ipos] + gEmission[ipos]; +} diff --git a/Techniques/Denoising/SVGF/SVGFPackLinearZAndNormal.ps.slang b/Techniques/Denoising/SVGF/SVGFPackLinearZAndNormal.ps.slang new file mode 100644 index 00000000..65c47a17 --- /dev/null +++ b/Techniques/Denoising/SVGF/SVGFPackLinearZAndNormal.ps.slang @@ -0,0 +1,48 @@ +/*************************************************************************** + # Copyright (c) 2015-23, NVIDIA CORPORATION. All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in the + # documentation and/or other materials provided with the distribution. + # * Neither the name of NVIDIA CORPORATION nor the names of its + # contributors may be used to endorse or promote products derived + # from this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY + # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **************************************************************************/ +import MathHelpers; +import SVGFCommon; + +/*$(ShaderResources)*/ +/* +cbuffer PerImageCB +{ + Texture2D gLinearZ; + Texture2D gNormal; +}; +*/ + +//float4 main(FullScreenPassVsOut vsOut) : SV_TARGET0 +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + float2 fragCoord = DTid.xy; + const int2 ipos = int2(fragCoord.xy); + + const float2 nPacked = ndir_to_oct_snorm(gNormal[ipos].xyz); + LinearZAndNormalFbo[ipos] = float4(gLinearZ[ipos].xy, nPacked.x, nPacked.y); +} diff --git a/Techniques/Denoising/SVGF/SVGFReproject.ps.slang b/Techniques/Denoising/SVGF/SVGFReproject.ps.slang new file mode 100644 index 00000000..97398395 --- /dev/null +++ b/Techniques/Denoising/SVGF/SVGFReproject.ps.slang @@ -0,0 +1,255 @@ +/*************************************************************************** + # Copyright (c) 2015-23, NVIDIA CORPORATION. All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above copyright + # notice, this list of conditions and the following disclaimer in the + # documentation and/or other materials provided with the distribution. + # * Neither the name of NVIDIA CORPORATION nor the names of its + # contributors may be used to endorse or promote products derived + # from this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY + # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **************************************************************************/ +import MathHelpers; +import ColorHelpers; +import SVGFCommon; + +// Workaround for isnan() not working in slang. +bool isNaN(float f) +{ + uint u = asuint(f) & ~0x80000000u; // clear out the sign bit + return (u > 0x7F800000); // greater than Inf is NaN +} + +/*$(ShaderResources)*/ +#define gAlpha /*$(Variable:Alpha)*/ +#define gMomentsAlpha /*$(Variable:MomentsAlpha)*/ +/* +cbuffer PerImageCB +{ + Texture2D gMotion; + Texture2D gPositionNormalFwidth; + Texture2D gColor; + Texture2D gAlbedo; + Texture2D gEmission; + Texture2D gPrevIllum; + Texture2D gPrevMoments; + Texture2D gLinearZAndNormal; + Texture2D gPrevLinearZAndNormal; + Texture2D gPrevHistoryLength; + + float gAlpha; + float gMomentsAlpha; +}; +*/ + +float3 demodulate(float3 c, float3 albedo) +{ + return c / max(albedo, float3(0.001, 0.001, 0.001)); +} + +bool isReprjValid(int2 coord, float Z, float Zprev, float fwidthZ, float3 normal, float3 normalPrev, float fwidthNormal) +{ + const int2 imageDim = getTextureDims(gColor, 0); + + // check whether reprojected pixel is inside of the screen + if (any(coord < int2(1, 1)) || any(coord > imageDim - int2(1, 1))) + return false; + + // check if deviation of depths is acceptable + if (abs(Zprev - Z) / (fwidthZ + 1e-2f) > 10.f) + return false; + + // check normals for compatibility + if (distance(normal, normalPrev) / (fwidthNormal + 1e-2) > 16.0) + return false; + + return true; +} + +bool loadPrevData(float2 posH, out float4 prevIllum, out float2 prevMoments, out float historyLength) +{ + const int2 ipos = int2(posH); + const float2 imageDim = float2(getTextureDims(gColor, 0)); + + const float2 motion = gMotion[ipos].xy; + const float normalFwidth = gPositionNormalFwidth[ipos].y; + + // +0.5 to account for texel center offset + const int2 iposPrev = int2(float2(ipos) + motion.xy * imageDim + float2(0.5, 0.5)); + + float2 depth = gLinearZAndNormal[ipos].xy; + float3 normal = oct_to_ndir_snorm(gLinearZAndNormal[ipos].zw); + + prevIllum = float4(0, 0, 0, 0); + prevMoments = float2(0, 0); + + bool v[4]; + const float2 posPrev = floor(posH.xy) + motion.xy * imageDim; + const int2 offset[4] = { int2(0, 0), int2(1, 0), int2(0, 1), int2(1, 1) }; + + // check for all 4 taps of the bilinear filter for validity + bool valid = false; + for (int sampleIdx = 0; sampleIdx < 4; sampleIdx++) + { + int2 loc = int2(posPrev) + offset[sampleIdx]; + float2 depthPrev = gPrevLinearZAndNormal[loc].xy; + float3 normalPrev = oct_to_ndir_snorm(gPrevLinearZAndNormal[loc].zw); + + v[sampleIdx] = isReprjValid(iposPrev, depth.x, depthPrev.x, depth.y, normal, normalPrev, normalFwidth); + + valid = valid || v[sampleIdx]; + } + + if (valid) + { + float sumw = 0; + float x = frac(posPrev.x); + float y = frac(posPrev.y); + + // bilinear weights + const float w[4] = { (1 - x) * (1 - y), x * (1 - y), (1 - x) * y, x * y }; + + // perform the actual bilinear interpolation + for (int sampleIdx = 0; sampleIdx < 4; sampleIdx++) + { + const int2 loc = int2(posPrev) + offset[sampleIdx]; + if (v[sampleIdx]) + { + prevIllum += w[sampleIdx] * gPrevIllum[loc]; + prevMoments += w[sampleIdx] * gPrevMoments[loc].xy; + sumw += w[sampleIdx]; + } + } + + // redistribute weights in case not all taps were used + valid = (sumw >= 0.01); + prevIllum = valid ? prevIllum / sumw : float4(0, 0, 0, 0); + prevMoments = valid ? prevMoments / sumw : float2(0, 0); + } + + if (!valid) // perform cross-bilateral filter in the hope to find some suitable samples somewhere + { + float nValid = 0.0; + + // this code performs a binary descision for each tap of the cross-bilateral filter + const int radius = 1; + for (int yy = -radius; yy <= radius; yy++) + { + for (int xx = -radius; xx <= radius; xx++) + { + const int2 p = iposPrev + int2(xx, yy); + const float2 depthFilter = gPrevLinearZAndNormal[p].xy; + const float3 normalFilter = oct_to_ndir_snorm(gPrevLinearZAndNormal[p].zw); + + if (isReprjValid(iposPrev, depth.x, depthFilter.x, depth.y, normal, normalFilter, normalFwidth)) + { + prevIllum += gPrevIllum[p]; + prevMoments += gPrevMoments[p].xy; + nValid += 1.0; + } + } + } + if (nValid > 0) + { + valid = true; + prevIllum /= nValid; + prevMoments /= nValid; + } + } + + if (valid) + { + // crude, fixme + historyLength = gPrevHistoryLength[iposPrev].x; + } + else + { + prevIllum = float4(0, 0, 0, 0); + prevMoments = float2(0, 0); + historyLength = 0; + } + + return valid; +} + +// not used currently +float computeVarianceScale(float numSamples, float loopLength, float alpha) +{ + const float aa = (1.0 - alpha) * (1.0 - alpha); + return (1.0 - pow(aa, min(loopLength, numSamples))) / (1.0 - aa); +} + +struct PS_OUT +{ + float4 OutIllumination : SV_TARGET0; + float2 OutMoments : SV_TARGET1; + float OutHistoryLength : SV_TARGET2; +}; + +//PS_OUT main(FullScreenPassVsOut vsOut) +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + const float4 posH = float4(DTid.xy, 0.0f, 0.0f); + const int2 ipos = int2(posH.xy); + + float3 illumination = demodulate(gColor[ipos].rgb - gEmission[ipos].rgb, gAlbedo[ipos].rgb); + // Workaround path tracer bugs. TODO: remove this when we can. + if (isNaN(illumination.x) || isNaN(illumination.y) || isNaN(illumination.z)) + { + illumination = float3(0, 0, 0); + } + + float historyLength; + float4 prevIllumination; + float2 prevMoments; + bool success = loadPrevData(posH.xy, prevIllumination, prevMoments, historyLength); + historyLength = min(32.0f, success ? historyLength + 1.0f : 1.0f); + + // this adjusts the alpha for the case where insufficient history is available. + // It boosts the temporal accumulation to give the samples equal weights in + // the beginning. + const float alpha = success ? max(gAlpha, 1.0 / historyLength) : 1.0; + const float alphaMoments = success ? max(gMomentsAlpha, 1.0 / historyLength) : 1.0; + + // compute first two moments of luminance + float2 moments; + moments.r = luminance(illumination); + moments.g = moments.r * moments.r; + + float2 pm = moments; + + // temporal integration of the moments + moments = lerp(prevMoments, moments, alphaMoments); + + float variance = max(0.f, moments.g - moments.r * moments.r); + + // variance *= computeVarianceScale(16, 16, alpha); + + PS_OUT psOut; + // temporal integration of illumination + psOut.OutIllumination = lerp(prevIllumination, float4(illumination, 0), alpha); + // variance is propagated through the alpha channel + psOut.OutIllumination.a = variance; + psOut.OutMoments = moments; + psOut.OutHistoryLength = historyLength; + + CurReprojFbo_0[DTid.xy] = psOut.OutIllumination; + CurReprojFbo_1[DTid.xy] = psOut.OutMoments; + CurReprojFbo_2[DTid.xy] = psOut.OutHistoryLength; +} diff --git a/Techniques/Denoising/SVGF/SwapTextures.gg b/Techniques/Denoising/SVGF/SwapTextures.gg new file mode 100644 index 00000000..d1a3d753 --- /dev/null +++ b/Techniques/Denoising/SVGF/SwapTextures.gg @@ -0,0 +1,108 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "nodes": [ + { + "resourceTexture": { + "name": "A", + "editorPos": [ + 11.0, + 2.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "B", + "editorPos": [ + 171.0, + -30.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "Temp", + "editorPos": [ + 11.0, + 66.0 + ], + "format": { + "node": { + "name": "A" + } + }, + "size": { + "node": { + "name": "A" + } + } + } + }, + { + "actionCopyResource": { + "name": "Temp = A", + "editorPos": [ + 165.0, + 34.0 + ], + "linkProperties": [ + {}, + {} + ], + "source": { + "node": "A", + "pin": "resource" + }, + "dest": { + "node": "Temp", + "pin": "resource" + } + } + }, + { + "actionCopyResource": { + "name": "A = B", + "editorPos": [ + 309.0, + 2.0 + ], + "linkProperties": [ + {}, + {} + ], + "source": { + "node": "B", + "pin": "resource" + }, + "dest": { + "node": "Temp = A", + "pin": "source" + } + } + }, + { + "actionCopyResource": { + "name": "B = Temp", + "editorPos": [ + 453.0, + 34.0 + ], + "linkProperties": [ + {}, + {} + ], + "source": { + "node": "Temp = A", + "pin": "dest" + }, + "dest": { + "node": "A = B", + "pin": "dest" + } + } + } + ] +} \ No newline at end of file diff --git a/Techniques/PostProcessing/BoxBlur/BoxBlur.gg b/Techniques/PostProcessing/BoxBlur/BoxBlur.gg new file mode 100644 index 00000000..530656cd --- /dev/null +++ b/Techniques/PostProcessing/BoxBlur/BoxBlur.gg @@ -0,0 +1,221 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "variables": [ + { + "name": "Radius", + "comment": "The kernel size is Radius*2+1. Radius 1 is 3x3, Radius 2 is 5x5, etc.", + "type": "Int", + "visibility": "User" + }, + { + "name": "sRGB", + "comment": "set to true if input is an sRGB format texture", + "type": "Bool", + "dflt": "false", + "visibility": "User" + }, + { + "name": "Disable", + "type": "Bool", + "dflt": "false", + "visibility": "User" + } + ], + "shaders": [ + { + "name": "BoxBlurCS", + "fileName": "BoxBlurCS.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "Input", + "type": "Texture", + "access": "SRV" + }, + { + "name": "Output", + "type": "Texture", + "access": "UAV" + } + ] + } + ], + "nodes": [ + { + "actionComputeShader": { + "name": "DoBlurH", + "editorPos": [ + -31.0, + 1.0 + ], + "condition": { + "variable1": "Disable", + "comparison": "IsFalse" + }, + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Input", + "dstNode": "Input", + "dstPin": "resource" + }, + { + "srcPin": "Output", + "dstNode": "Temp", + "dstPin": "resource" + } + ], + "shader": { + "name": "BoxBlurCS" + }, + "dispatchSize": { + "node": { + "name": "Input" + } + }, + "defines": [ + { + "name": "BLURH", + "value": "1" + } + ] + } + }, + { + "resourceTexture": { + "name": "Input", + "editorPos": [ + -181.0, + -14.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "Output", + "editorPos": [ + 11.0, + 98.0 + ], + "visibility": "Exported", + "format": { + "node": { + "name": "Input" + } + }, + "size": { + "node": { + "name": "Input" + } + } + } + }, + { + "actionCopyResource": { + "name": "DontBlur", + "editorPos": [ + 324.0, + -1.0 + ], + "condition": { + "variable1": "Disable", + "comparison": "IsTrue" + }, + "linkProperties": [ + {}, + {} + ], + "source": { + "node": "DoBlurH", + "pin": "Input" + }, + "dest": { + "node": "DoBlurV", + "pin": "Output" + } + } + }, + { + "actionComputeShader": { + "name": "DoBlurV", + "editorPos": [ + 149.0, + 44.0 + ], + "condition": { + "variable1": "Disable", + "comparison": "IsFalse" + }, + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Input", + "dstNode": "DoBlurH", + "dstPin": "Output" + }, + { + "srcPin": "Output", + "dstNode": "Output", + "dstPin": "resource" + } + ], + "shader": { + "name": "BoxBlurCS" + }, + "dispatchSize": { + "node": { + "name": "Input" + } + }, + "defines": [ + { + "name": "BLURH", + "value": "0" + } + ] + } + }, + { + "resourceTexture": { + "name": "Temp", + "editorPos": [ + -181.0, + 50.0 + ], + "visibility": "Exported", + "format": { + "node": { + "name": "Input" + } + }, + "size": { + "node": { + "name": "Input" + } + } + } + } + ], + "setVars": [ + { + "destination": { + "name": "Radius" + }, + "AVar": { + "name": "Radius" + }, + "op": "Maximum", + "BLiteral": "0" + } + ] +} \ No newline at end of file diff --git a/Techniques/PostProcessing/BoxBlur/BoxBlur.gguser b/Techniques/PostProcessing/BoxBlur/BoxBlur.gguser new file mode 100644 index 00000000..58a4eba8 --- /dev/null +++ b/Techniques/PostProcessing/BoxBlur/BoxBlur.gguser @@ -0,0 +1,29 @@ +{ + "version": "2.0", + "snapshot": { + "resourceViewNodeIndex": 4, + "resourceViewResourceIndex": 3, + "importedResources": [ + { + "nodeName": "Input", + "texture": { + "fileName": "..\\..\\logo.png" + } + } + ], + "savedVariables": [ + { + "name": "Radius", + "value": "5" + }, + { + "name": "sRGB", + "value": "true" + }, + { + "name": "Disable", + "value": "false" + } + ] + } +} \ No newline at end of file diff --git a/Techniques/PostProcessing/BoxBlur/BoxBlurCS.hlsl b/Techniques/PostProcessing/BoxBlur/BoxBlurCS.hlsl new file mode 100644 index 00000000..8c626a6d --- /dev/null +++ b/Techniques/PostProcessing/BoxBlur/BoxBlurCS.hlsl @@ -0,0 +1,48 @@ +// Unnamed technique, shader GaussBlurCS +/*$(ShaderResources)*/ + +float3 LinearToSRGB(float3 linearCol) +{ + float3 sRGBLo = linearCol * 12.92; + float3 sRGBHi = (pow(abs(linearCol), float3(1.0 / 2.4, 1.0 / 2.4, 1.0 / 2.4)) * 1.055) - 0.055; + float3 sRGB; + sRGB.r = linearCol.r <= 0.0031308 ? sRGBLo.r : sRGBHi.r; + sRGB.g = linearCol.g <= 0.0031308 ? sRGBLo.g : sRGBHi.g; + sRGB.b = linearCol.b <= 0.0031308 ? sRGBLo.b : sRGBHi.b; + return sRGB; +} + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + int2 px = DTid.xy; + int2 maxPx; + Input.GetDimensions(maxPx.x, maxPx.y); + maxPx -= int2(1,1); + + // initialize values + float weight = 0.0f; + float3 color = float3(0.0f, 0.0f, 0.0f); + + // loop horizontally or vertically, as appropriate + for (int index = -/*$(Variable:Radius)*/; index <= /*$(Variable:Radius)*/; ++index) + { + int2 offset = (BLURH) ? int2(index, 0) : int2(0, index); + int2 readPx = clamp(px + offset, int2(0, 0), maxPx); + color += Input[readPx].rgb; + weight += 1.0f; + } + + // normalize blur + color /= weight; + + if (/*$(Variable:sRGB)*/) + color = LinearToSRGB(color); + + Output[px] = float4(color, 1.0f); +} + +/* +Shader Resources: + Texture Input (as SRV) + Texture Output (as UAV) +*/ diff --git a/Techniques/PostProcessing/DFT/DFT.gg b/Techniques/PostProcessing/DFT/DFT.gg new file mode 100644 index 00000000..50b7f019 --- /dev/null +++ b/Techniques/PostProcessing/DFT/DFT.gg @@ -0,0 +1,193 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "variables": [ + { + "name": "ChannelDotProduct", + "comment": "A DFT needs a scalar value. Pixel values are dotted against this vector to turn the vectors into a scalar.", + "type": "Float4", + "dflt": "0.25f, 0.25f, 0.25f, 0.25f", + "visibility": "User" + }, + { + "name": "RemoveDC", + "comment": "DC (0hz) is often a large spike that makes it hard to see the rest of the frequencies. Use this to set DC to zero.", + "type": "Bool", + "dflt": "false", + "visibility": "User" + }, + { + "name": "LogSpaceMagnitude", + "comment": "If true, show magnitude in log space", + "type": "Bool", + "dflt": "true", + "visibility": "User" + } + ], + "shaders": [ + { + "name": "DFTCS", + "fileName": "DFTCS.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "Input", + "type": "Texture", + "access": "SRV" + }, + { + "name": "Output", + "type": "Texture", + "access": "UAV", + "texture": { + "viewType": "Float2" + } + }, + { + "name": "MaxMagnitude", + "type": "Buffer", + "access": "UAV", + "buffer": { + "type": "Uint" + } + } + ] + }, + { + "name": "NormalizeCS", + "fileName": "NormalizeCS.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "DFTMagnitude", + "type": "Texture", + "access": "UAV" + }, + { + "name": "MaxMagnitude", + "type": "Buffer", + "access": "SRV", + "buffer": { + "type": "Uint" + } + } + ] + } + ], + "nodes": [ + { + "resourceTexture": { + "name": "Input", + "editorPos": [ + 11.0, + -14.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "DFTMagnitude", + "editorPos": [ + -5.0, + 50.0 + ], + "visibility": "Exported", + "format": { + "format": "R32_Float" + }, + "size": { + "node": { + "name": "Input" + } + } + } + }, + { + "actionComputeShader": { + "name": "DFT", + "editorPos": [ + 149.0, + 2.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Input", + "dstNode": "Input", + "dstPin": "resource" + }, + { + "srcPin": "Output", + "dstNode": "DFTMagnitude", + "dstPin": "resource" + }, + { + "srcPin": "MaxMagnitude", + "dstNode": "MaxMagnitude", + "dstPin": "resource" + } + ], + "shader": { + "name": "DFTCS" + }, + "dispatchSize": { + "node": { + "name": "Input" + } + } + } + }, + { + "resourceBuffer": { + "name": "MaxMagnitude", + "editorPos": [ + -22.0, + 114.0 + ], + "format": { + "type": "Uint" + } + } + }, + { + "actionComputeShader": { + "name": "Normalize", + "editorPos": [ + 341.0, + 18.0 + ], + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "DFTMagnitude", + "dstNode": "DFT", + "dstPin": "Output" + }, + { + "srcPin": "MaxMagnitude", + "dstNode": "DFT", + "dstPin": "MaxMagnitude" + } + ], + "shader": { + "name": "NormalizeCS" + }, + "dispatchSize": { + "node": { + "name": "DFTMagnitude" + } + } + } + } + ] +} \ No newline at end of file diff --git a/Techniques/PostProcessing/DFT/DFT.gguser b/Techniques/PostProcessing/DFT/DFT.gguser new file mode 100644 index 00000000..013ecafd --- /dev/null +++ b/Techniques/PostProcessing/DFT/DFT.gguser @@ -0,0 +1,27 @@ +{ + "version": "2.0", + "snapshot": { + "importedResources": [ + { + "nodeName": "Input", + "texture": { + "fileName": "..\\..\\logo.png" + } + } + ], + "savedVariables": [ + { + "name": "ChannelDotProduct", + "value": "0.250000,0.250000,0.250000,0.250000" + }, + { + "name": "RemoveDC", + "value": "false" + }, + { + "name": "LogSpaceMagnitude", + "value": "true" + } + ] + } +} \ No newline at end of file diff --git a/Techniques/PostProcessing/DFT/DFTCS.hlsl b/Techniques/PostProcessing/DFT/DFTCS.hlsl new file mode 100644 index 00000000..fcea78b2 --- /dev/null +++ b/Techniques/PostProcessing/DFT/DFTCS.hlsl @@ -0,0 +1,59 @@ +// Unnamed technique, shader DFTCS +/*$(ShaderResources)*/ + +static const float c_pi = 3.14159265359f; + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + uint2 px = DTid.xy; + float K = float(px.x); + float L = float(px.y); + + uint2 dims; + Input.GetDimensions(dims.x, dims.y); + + float2 dft = float2(0.0f, 0.0f); + + for (uint y = 0; y < dims.y; y++) + { + float vy = L * float(y) / float(dims.y); + for (uint x = 0; x < dims.x; x++) + { + float vx = K * float(x) / float(dims.x); + + float v = vx + vy; + + float theta = -2.0f * c_pi * v; + + float pixelValue = dot(Input[uint2(x,y)].xyzw, float4(/*$(Variable:ChannelDotProduct)*/)); + + dft.x += cos(theta) * pixelValue; + dft.y += sin(theta) * pixelValue; + } + } + + // 1/N in front of the DFT + dft *= 1.0f / float(dims.x*dims.y); + + // Zero out DC (0hz) if we should + if (/*$(Variable:RemoveDC)*/ && px.x == 0 && px.y == 0) + dft = float2(0.0f, 0.0f); + + // DFT shift + px = (px + uint2(dims.x, dims.y) / 2) % dims; + + // Write out magnitude + float magnitude = length(dft); + Output[px] = magnitude; + + // keep track of maximum magnitude + uint dummy; + InterlockedMax(MaxMagnitude[0], asuint(magnitude), dummy); +} + +/* +Shader Resources: + Texture Input (as SRV) + Texture Output (as UAV) + Buffer MaxMagnitude (as UAV) +*/ diff --git a/Techniques/PostProcessing/DFT/NormalizeCS.hlsl b/Techniques/PostProcessing/DFT/NormalizeCS.hlsl new file mode 100644 index 00000000..c2f98cd7 --- /dev/null +++ b/Techniques/PostProcessing/DFT/NormalizeCS.hlsl @@ -0,0 +1,19 @@ +// Unnamed technique, shader NormalizeCS +/*$(ShaderResources)*/ + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + float maxMagnitude = asfloat(MaxMagnitude[0]); + uint2 px = DTid.xy; + float value = DFTMagnitude[px]; + if (/*$(Variable:LogSpaceMagnitude)*/) + DFTMagnitude[px] = log(1.0f + value * 255.0f); + else + DFTMagnitude[px] = value / maxMagnitude; +} + +/* +Shader Resources: + Texture DFTMagnitude (as UAV) + Buffer MaxMagnitude (as SRV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/GatherDOF2018/BlurFarCS.hlsl b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/BlurFarCS.hlsl new file mode 100644 index 00000000..fe62ee3a --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/BlurFarCS.hlsl @@ -0,0 +1,71 @@ +// Unnamed technique, shader BlurFarCS +/*$(ShaderResources)*/ + +#include "Common.hlsli" + +#define BLUR_TAP_COUNT /*$(Variable:BlurTapCount)*/ + +// .x : size of the bokeh blur radius in texel space +// .y : rotation in radius to apply to the bokeh shape +// .z : Number of edge of the polygon (number of blades). 0: circle. 4: square, 6: hexagon... +#define KernelSize /*$(Variable:KernelSize)*/ + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + uint2 px = DTid.xy; + + uint2 FarFieldColorCoCSize; + FarFieldColorCoC.GetDimensions(FarFieldColorCoCSize.x, FarFieldColorCoCSize.y); + + float2 UVAndScreenPos = (float2(px) + float2(0.5f, 0.5f)) / float2(FarFieldColorCoCSize); + + float4 PixelColor = FarFieldColorCoC[px]; + float PixelCoC = PixelColor.w; + + float3 ResultColor = 0; + float Weight = 0; + + int TAP_COUNT = BLUR_TAP_COUNT; // Higher means less noise and make floodfilling easier after + + // Multiplying by PixelCoC guarantees a smooth evolution of the blur radius + // especially visible on plane (like the floor) where CoC slowly grows with the distance. + // This makes all the difference between a natural bokeh and some noticeable + // in-focus and out-of-focus layer blending + float radius = KernelSize.x * PixelCoC; + + if (PixelCoC > 0) { // Ignore any pixel not belonging to far field + + // Weighted average of the texture samples inside the bokeh pattern + // High radius and low sample count can create "gaps" which are fixed later (floodfill). + for (int u = 0; u < TAP_COUNT; ++u) + { + for (int v = 0; v < TAP_COUNT; ++v) + { + float2 uv = float2(u, v) / (TAP_COUNT - 1); // map to [0, 1] + uv = SquareToPolygonMapping( uv, KernelSize ) / float2(FarFieldColorCoCSize); // map to bokeh shape, then to texel size + uv = UVAndScreenPos.xy + radius * uv; + + float4 tapColor = FarFieldColorCoC.SampleLevel(linearClampSampler, uv, 0); //Texture2DSampleLevel(PostprocessInput0, PostprocessInput0Sampler, uv, 0); + + // Weighted by CoC. Gives more influence to taps with a CoC higher than us. + float TapWeight = tapColor.w * saturate(1.0f - (PixelCoC - tapColor.w)); + + ResultColor += tapColor.xyz * TapWeight; + Weight += TapWeight; + } + } + if (Weight > 0) ResultColor /= Weight; + Weight = Weight / TAP_COUNT / TAP_COUNT; + } + + Weight = saturate(Weight * 10); // From CoC 0.1, completely rely on the far field layer and stop lerping with in-focus layer + float4 OutColor = float4(ResultColor, Weight); + + BlurredFarFieldColorAlpha[px] = OutColor; +} + +/* +Shader Resources: + Texture FarFieldColorCoC (as SRV) + Texture BlurredFarFieldColorAlpha (as UAV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/GatherDOF2018/Common.hlsli b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/Common.hlsli new file mode 100644 index 00000000..d931bedb --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/Common.hlsli @@ -0,0 +1,84 @@ + +#define PI 3.14159265359f + +struct ViewStruct +{ + float DepthOfFieldFocalLength; + float DepthOfFieldFocalDistance; + float DepthOfFieldFocalRegion; + float DepthOfFieldNearTransitionRegion; + float DepthOfFieldFarTransitionRegion; + float DepthOfFieldScale; +}; + +float3 LinearToSRGB(float3 linearCol) +{ + float3 sRGBLo = linearCol * 12.92; + float3 sRGBHi = (pow(abs(linearCol), float3(1.0 / 2.4, 1.0 / 2.4, 1.0 / 2.4)) * 1.055) - 0.055; + float3 sRGB; + sRGB.r = linearCol.r <= 0.0031308 ? sRGBLo.r : sRGBHi.r; + sRGB.g = linearCol.g <= 0.0031308 ? sRGBLo.g : sRGBHi.g; + sRGB.b = linearCol.b <= 0.0031308 ? sRGBLo.b : sRGBHi.b; + return sRGB; +} + +// Maps a unit square in [0, 1] to a unit disk in [-1, 1] +// Returns polar coordinates (radius, angle) +// Shirley 97 "A Low Distortion Map Between Disk and Square" +float2 UnitSquareToUnitDiskPolar(float2 uv) +{ + float radius; + float angle; + const float PI_BY_2 = 1.5707963f; // PI / 2 + const float PI_BY_4 = 0.785398f; // PI / 4 + const float EPSILON = 0.000001f; + + // Remap [0, 1] to [-1, 1] centered + float a = (2.0f * uv.x) - 1.0f; + float b = (2.0f * uv.y) - 1.0f; + + // Morph to unit disk + if (abs(a) > abs(b)) + { + // First region (left and right quadrants of the disk) + radius = a; + angle = b / (a + EPSILON) * PI_BY_4; + } + else + { + // Second region (top and bottom quadrants of the disk) + radius = b; + angle = PI_BY_2 - (a / (b + EPSILON) * PI_BY_4); + } + if (radius < 0) + { + radius *= -1.0f; + angle += PI; + } + return float2(radius, angle); +} +// Maps a unit square in [0, 1] to a unit disk in [-1, 1] +// Returns new cartesian coordinates (u,v) +float2 SquareToDiskMapping(float2 uv) { + float2 PolarCoord = UnitSquareToUnitDiskPolar(uv); + return float2(PolarCoord.x * cos(PolarCoord.y), PolarCoord.x * sin(PolarCoord.y)); +} + +// Remap a unit square in [0, 1] to a unit polygon in [-1, 1] +// Returns new cartesian coordinates (u,v) +float2 SquareToPolygonMapping(float2 uv, in float4 KernelSize) { + const float N = KernelSize.z; // Edge count of the polygon. + float2 PolarCoord = UnitSquareToUnitDiskPolar(uv); // (radius, angle) + + if (N >= 3.0f) + { + // Re-scale radius to match a polygon shape + // http://www.crytek.com/download/Sousa_Graphics_Gems_CryENGINE3.pdf + PolarCoord.x *= ( cos(PI / N) / ( cos(PolarCoord.y - (2.0f * PI / N) * floor((N*PolarCoord.y + PI) / 2.0f / PI ) ))); + + // Apply a rotation to the polygon shape. + PolarCoord.y += KernelSize.y; + } + + return float2(PolarCoord.x * cos(PolarCoord.y), PolarCoord.x * sin(PolarCoord.y)); +} \ No newline at end of file diff --git a/Techniques/PostProcessing/DepthOfField/GatherDOF2018/DownscaleTileMap_1_4.hlsl b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/DownscaleTileMap_1_4.hlsl new file mode 100644 index 00000000..27262823 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/DownscaleTileMap_1_4.hlsl @@ -0,0 +1,22 @@ +// Unnamed technique, shader DownscaleTimeMapCS +/*$(ShaderResources)*/ + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + uint2 px = DTid.xy; + + float CoCs[4]; + + CoCs[0] = Source[px*2+uint2(0,0)]; + CoCs[1] = Source[px*2+uint2(1,0)]; + CoCs[2] = Source[px*2+uint2(0,1)]; + CoCs[3] = Source[px*2+uint2(1,1)]; + + Dest[px] = max( CoCs[0], max( CoCs[1], max( CoCs[2], CoCs[3] ) ) ); +} + +/* +Shader Resources: + Texture Source (as SRV) + Texture Dest (as UAV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/GatherDOF2018/FloodFillFarCS.hlsl b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/FloodFillFarCS.hlsl new file mode 100644 index 00000000..e8323e07 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/FloodFillFarCS.hlsl @@ -0,0 +1,88 @@ +// Unnamed technique, shader FloodFillFarCS +/*$(ShaderResources)*/ + +#include "Common.hlsli" + +#define FLOODFILL_TAP_COUNT /*$(Variable:FloodFillTapCount)*/ + +// .x : size of the bokeh blur radius in texel space +// .y : rotation in radius to apply to the bokeh shape +// .z : Number of edge of the polygon (number of blades). 0: circle. 4: square, 6: hexagon... +#define KernelSize /*$(Variable:KernelSize)*/ + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + uint2 px = DTid.xy; + + uint2 ColorCocSize; + ColorCoc.GetDimensions(ColorCocSize.x, ColorCocSize.y); + + float2 UVAndScreenPos = (float2(px) + float2(0.5f, 0.5f)) / float2(ColorCocSize); + + #if COC_TILEMAP + + // pass through if this is disabled + if (!/*$(Variable:DoNearFieldFloodFill)*/) + { + BlurredFieldColorAlpha[px] = ColorCoc[px]; + return; + } + + #else + + // pass through if this is disabled + if (!/*$(Variable:DoFarFieldFloodFill)*/) + { + BlurredFieldColorAlpha[px] = ColorCoc[px]; + return; + } + + #endif + + float4 PixelColor = ColorCoc[px]; + float PixelCoC = PixelColor.w; + +#if COC_TILEMAP + // Use max CoC tilemap instead of the original pixel CoC for near field + PixelCoC = MaxCoCTileMap[px/4].r; +#endif + + float4 ResultColor = PixelColor; + + float radius = PixelCoC * 1.75f * KernelSize.x / 15.0f; + + int TAP_COUNT = FLOODFILL_TAP_COUNT; // Higher count improves the floodfill + + if (PixelCoC > 0) { // Early out if we're outside the field + + // McIntosh12 http://ivizlab.sfu.ca/papers/cgf2012.pdf + // Keep the maximum of all the samples + for (int u = 0; u < TAP_COUNT; ++u) + { + for (int v = 0; v < TAP_COUNT; ++v) + { + float2 uv = float2(u, v) / (TAP_COUNT - 1); // map to [0, 1] + uv = SquareToPolygonMapping( uv, KernelSize ) / float2(ColorCocSize); // map to bokeh shape, then to texel size + uv = UVAndScreenPos.xy + radius * uv; + + float4 tapColor = ColorCoc.SampleLevel(linearClampSampler, uv, 0);//Texture2DSampleLevel(PostprocessInput0, PostprocessInput0Sampler, uv, 0); + ResultColor = max(ResultColor, tapColor); + } + } + } +#if COC_TILEMAP + float4 OutColor = ResultColor; +#else + // do not touch alpha of far field + float4 OutColor = float4(ResultColor.xyz, PixelCoC); +#endif + + BlurredFieldColorAlpha[px] = OutColor; +} + +/* +Shader Resources: + Texture ColorCoc (as SRV) + Texture MaxCoCTileMap (as SRV) + Texture BlurredFieldColorAlpha (as UAV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/GatherDOF2018/NearBlurCS.hlsl b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/NearBlurCS.hlsl new file mode 100644 index 00000000..069846d0 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/NearBlurCS.hlsl @@ -0,0 +1,61 @@ +// Unnamed technique, shader NearBlur +/*$(ShaderResources)*/ + +#include "Common.hlsli" + +#define BLUR_TAP_COUNT /*$(Variable:BlurTapCount)*/ + +// .x : size of the bokeh blur radius in texel space +// .y : rotation in radius to apply to the bokeh shape +// .z : Number of edge of the polygon (number of blades). 0: circle. 4: square, 6: hexagon... +#define KernelSize /*$(Variable:KernelSize)*/ + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + uint2 px = DTid.xy; + + uint2 NearFieldColorCoCBorderSize; + NearFieldColorCoCBorder.GetDimensions(NearFieldColorCoCBorderSize.x, NearFieldColorCoCBorderSize.y); + + float2 UVAndScreenPos = (float2(px) + float2(0.5f, 0.5f)) / float2(NearFieldColorCoCBorderSize); + + float4 PixelColor = NearFieldColorCoCBorder[px];// Texture2DSampleLevel(PostprocessInput0, PostprocessInput0Sampler, UVAndScreenPos.xy, 0); + float PixelCoC = NearmaxCoCTilemap_1_8_Halo[px/4];// Texture2DSampleLevel(PostprocessInput1, PostprocessInput1Sampler, UVAndScreenPos.xy, 0); + + float3 ResultColor = 0; + float Weight = 0; + int TAP_COUNT = BLUR_TAP_COUNT; // Higher means less noise and make floodfilling easier after + + float radius = KernelSize.x * 0.7f * PixelCoC; + + if (PixelCoC > 0) { // Early exit based on MaxCoC tilemap + for (int u = 0; u < TAP_COUNT; ++u) + { + for (int v = 0; v < TAP_COUNT; ++v) + { + float2 uv = float2(u, v) / (TAP_COUNT - 1); // map to [0, 1] + uv = SquareToPolygonMapping( uv, KernelSize ) / float2(NearFieldColorCoCBorderSize); // map to bokeh shape, then to texel size + uv = UVAndScreenPos.xy + radius * uv; + + float4 tapColor = NearFieldColorCoCBorder.SampleLevel(linearClampSampler, uv, 0);// Texture2DSampleLevel(PostprocessInput0, PostprocessInput0Sampler, uv, 0); + float TapWeight = saturate(tapColor.w * 10.0f); // From CoC 0.1 rely only on the near field and stop lerping with in-focus area + + ResultColor += tapColor.xyz * TapWeight; + Weight += TapWeight; + } + } + + ResultColor /= (Weight + 0.0000001f); + Weight /= (TAP_COUNT * TAP_COUNT); + } + float4 OutColor = float4(ResultColor, Weight); + + NearFieldColorCoCBorderBlurred[px] = OutColor; +} + +/* +Shader Resources: + Texture NearFieldColorCoCBorder (as SRV) + Count NearmaxCoCTilemap_1_8_Halo (as Count) + Texture NearFieldColorCoCBorderBlurred (as UAV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/GatherDOF2018/NearBorderCS.hlsl b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/NearBorderCS.hlsl new file mode 100644 index 00000000..7b62503e --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/NearBorderCS.hlsl @@ -0,0 +1,38 @@ +// Unnamed technique, shader NearBorderCS +/*$(ShaderResources)*/ + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + uint2 px = DTid.xy; + + float4 PixelColor = NearFieldColorCoC[px];// Texture2DSampleLevel(PostprocessInput0, PostprocessInput0Sampler, tapUV, 0); + + if (PixelColor.w == 0) // Only fill the empty areas around near field + { + PixelColor = 0; + float Weight = 0; + int RADIUS_TAPS = 1; + for (int u = -RADIUS_TAPS; u <= RADIUS_TAPS; ++u) + { + for (int v = -RADIUS_TAPS; v <= RADIUS_TAPS; ++v) + { + float4 tapValue = NearFieldColorCoC[px + int2(u,v)];//Texture2DSampleLevel(PostprocessInput0, PostprocessInput0Sampler, tapUV + float2(u,v) * PostprocessInput0Size.zw, 0); + float tapWeight = tapValue.w == 0.0f? 0.0f : 1.0f; + PixelColor += tapWeight * tapValue; + Weight += tapWeight; + } + } + PixelColor /= (Weight + 0.0000001f); + PixelColor.w = 0; + } + + float4 OutColor = PixelColor; + + NearFieldColorCoCBorder[px] = OutColor; +} + +/* +Shader Resources: + Texture NearFieldColorCoC (as SRV) + Texture NearFieldColorCoCBorder (as UAV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/GatherDOF2018/NearHaloCS.hlsl b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/NearHaloCS.hlsl new file mode 100644 index 00000000..6de37ecd --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/NearHaloCS.hlsl @@ -0,0 +1,37 @@ +// Unnamed technique, shader NearHaloCS +/*$(ShaderResources)*/ + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + uint2 px = DTid.xy; + + float PixelColor = NearMaxCocTilemap_1_8[px];//Texture2DSampleLevel(PostprocessInput0, PostprocessInput0Sampler, tapUV, 0); + + if (PixelColor == 0) // Only fill the empty areas around near field + { + PixelColor = 0; + float Weight = 0; + int RADIUS_TAPS = 4; // 8x8 taps, but shouldn't be heavy at such low resolution + for (int u = -RADIUS_TAPS; u <= RADIUS_TAPS; ++u) + { + for (int v = -RADIUS_TAPS; v <= RADIUS_TAPS; ++v) + { + float tapValue = NearMaxCocTilemap_1_8[int2(px) + int2(u, v)];//Texture2DSampleLevel(PostprocessInput0, PostprocessInput0Sampler, tapUV + float2(u,v) * PostprocessInput0Size.zw, 0); + float tapWeight = tapValue == 0.0f? 0.0f : 1.0f; + PixelColor += tapWeight * tapValue; + Weight += tapWeight; + } + } + PixelColor /= (Weight + 0.000001f); + } + + float4 OutColor = PixelColor; + + NearMaxCocTilemap_1_8_Halo[px] = OutColor; +} + +/* +Shader Resources: + Texture NearMaxCocTilemap_1_8 (as SRV) + Texture NearMaxCocTilemap_1_8_Halo (as UAV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/GatherDOF2018/RecombineCS.hlsl b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/RecombineCS.hlsl new file mode 100644 index 00000000..1b2900d3 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/RecombineCS.hlsl @@ -0,0 +1,135 @@ +// Unnamed technique, shader RecombineCS +/*$(ShaderResources)*/ + +#include "Common.hlsli" + +// Blend in-focus / far / near layers on the top of each others +float3 GetCombinedLayerColor(uint2 px, float2 uv, in ViewStruct View) +{ + // Set FadePower to 1.0f in the next line to be physically correct, + // but some in-focus silhouette might become visible at the border of the + // near field, where the gradient smoothly fades alpha to 0. [0 -> 0.5 -> 1] + // Limitation of screen-space effect: we don't have access to the actual color occluded by near field meshes. + // This makes the near-field fading gradient more aggressive [0 -> 1 -> 1] to hide any sharp silhouette. + float FadePower = 2.0f; +#if 1 // Optimized version using early-out to avoid unnecessary texture fetches -> ~25% speed-up in reference scene. + + float4 NearColor = /*$(Variable:DoNearField)*/ ? NearField.SampleLevel(linearClampSampler, uv, 0) : float4(0.0f, 0.0f, 0.0f, 0.0f);// Texture2DSampleLevel(PostprocessInput2, PostprocessInput2Sampler, uv, 0); + + NearColor.w = saturate(NearColor.w * FadePower); + + // Pure near field, early exit + if (NearColor.w == 1.0f) + { + return NearColor.rgb; + } + + float4 FarColor = /*$(Variable:DoFarField)*/ ? FarField.SampleLevel(linearClampSampler, uv, 0) : float4(0.0f, 0.0f, 0.0f, 0.0f);// Texture2DSampleLevel(PostprocessInput1, PostprocessInput1Sampler, uv, 0); + + // Original CoC to guarantee crisp edge of in-focus over far-field + //float2 PixelPosCenter = SvPosition.xy; + //float2 FullResUV = PixelPosCenter * PostprocessInput0Size.zw; + float SceneDepth = Depth[px];// CalcSceneDepth(FullResUV); + + bool isInFocus = (SceneDepth >= View.DepthOfFieldFocalDistance) && + (SceneDepth < View.DepthOfFieldFocalDistance + View.DepthOfFieldFocalRegion); + + if (!isInFocus) { + // Pure far field without any bleeding from near field, early exit + if (FarColor.w == 1.0f && NearColor.w == 0.0f ) + { + return FarColor.rgb; + } + + // Blending only between far and near + if (FarColor.w == 1.0f) { + return float3( NearColor.w * (NearColor.rgb) + (1.0f - NearColor.w) * FarColor.rgb ); + } + } else { + // Pixel was originally in focus, background should never bleed onto it + FarColor.w = 0; + } + + // Worst case: 3 layer merge + float3 FocusColor = Color[px].rgb;// Texture2DSample(PostprocessInput0, PostprocessInput0Sampler, uv).rgb; + + float3 Result = FarColor.w * FarColor.rgb + (1.0f - FarColor.w) * FocusColor; + Result = NearColor.w * (NearColor.rgb) + (1.0f - NearColor.w) * Result; + + return Result; + +#else // Original generic version + + float3 FocusColor = Texture2DSample(PostprocessInput0, PostprocessInput0Sampler, uv).rgb; + float4 FarColor = Texture2DSampleLevel(PostprocessInput1, PostprocessInput1Sampler, uv, 0); + float4 NearColor = Texture2DSampleLevel(PostprocessInput2, PostprocessInput2Sampler, uv, 0); + + // Original CoC to guarantee crisp edge of in-focus over far-field + float2 PixelPosCenter = SvPosition.xy; + float2 FullResUV = PixelPosCenter * PostprocessInput0Size.zw; + float SceneDepth = CalcSceneDepth(FullResUV); + + bool isInFocus = (SceneDepth >= View.DepthOfFieldFocalDistance) && + (SceneDepth < View.DepthOfFieldFocalDistance + View.DepthOfFieldFocalRegion); + if (isInFocus) FarColor.w = 0; + + // Alpha composite far field on the top of the original scene. + float3 Result = FarColor.w * FarColor.rgb + (1.0f - FarColor.w) * FocusColor; + + // Alpha composite on the near field + if (NearColor.w > 0) { + float blendFactor = saturate(NearColor.w * FadePower); + Result = blendFactor * (NearColor.rgb) + (1.0f - blendFactor) * Result; + } + + return Result; +#endif + +} + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + ViewStruct View = (ViewStruct)0; + View.DepthOfFieldFocalLength = /*$(Variable:FocalLength)*/; + View.DepthOfFieldFocalDistance = /*$(Variable:FocalDistance)*/; + View.DepthOfFieldFocalRegion = /*$(Variable:FocalRegion)*/; + View.DepthOfFieldNearTransitionRegion = /*$(Variable:NearTransitionRegion)*/; + View.DepthOfFieldFarTransitionRegion = /*$(Variable:FarTransitionRegion)*/; + View.DepthOfFieldScale = /*$(Variable:Scale)*/; + uint2 px = DTid.xy; + + uint2 OutputSize; + Output.GetDimensions(OutputSize.x, OutputSize.y); + float2 uv = (float2(px) + float2(0.5f, 0.5f)) / float2(OutputSize); + + /* +#if RECOMBINE_METHOD == 2 // Separate translucency + // SceneColor in full res + float2 PixelPosCenter = SvPosition.xy; + float2 FullResUV = PixelPosCenter * PostprocessInput0Size.zw; + float4 SeparateTranslucency = UpsampleSeparateTranslucency(SvPosition.xy, FullResUV, PostprocessInput3, PostprocessInput3Size.zw); +#endif +*/ + float3 RecombinedLayersColor = GetCombinedLayerColor(px, uv, View); + +/* +#if RECOMBINE_METHOD == 2 + // Separate translucency as premultiplied alpha + RecombinedLayersColor.rgb = RecombinedLayersColor.rgb * SeparateTranslucency.a + SeparateTranslucency.rgb; +#endif +*/ + + if (/*$(Variable:sRGB)*/) + RecombinedLayersColor = LinearToSRGB(RecombinedLayersColor); + + Output[px] = float4(RecombinedLayersColor, 1.0f); +} + +/* +Shader Resources: + Texture Color (as SRV) + Texture FarField (as SRV) + Texture NearField (as SRV) + Texture Depth (as SRV) + Texture Output (as UAV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/GatherDOF2018/SetupCS.hlsl b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/SetupCS.hlsl new file mode 100644 index 00000000..ffbfd0aa --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/SetupCS.hlsl @@ -0,0 +1,176 @@ +// Unnamed technique, shader SetupCS +/*$(ShaderResources)*/ + +// An implementation of GatherDOF2018: https://www.adriancourreges.com/blog/2018/12/02/ue4-optimized-post-effects/ + +#include "Common.hlsli" + +// Computed the "Circle Of Confusion" radius for "Depth of Field" +// Formula can be found in many places e.g. http://http.developer.nvidia.com/GPUGems/gpugems_ch23.html +// @param SceneDepth +// @return 0..1 0=in focus, 1:max blurry +float ComputeCircleOfConfusion(float SceneDepth, in ViewStruct View) +{ + // artificial area where all content is in focus (starting at FocalLength, ending at FocalLength+FocalRegion) + if(SceneDepth > View.DepthOfFieldFocalDistance) + { + SceneDepth = View.DepthOfFieldFocalDistance + max(0, SceneDepth - View.DepthOfFieldFocalDistance - View.DepthOfFieldFocalRegion); + } + + // depth of the pixel in unreal units + float D = SceneDepth; + // e.g. Focal length in mm (Camera property e.g. 75mm) + float F = View.DepthOfFieldFocalLength; + // Plane in Focus in unreal units + float P = View.DepthOfFieldFocalDistance; + // Camera property e.g. 0.5f, like aperture + float Aperture = View.DepthOfFieldScale; + + + // convert unreal units (100=1m) to mm + P *= 0.001f / 100.0f; + D *= 0.001f / 100.0f; +/* + float Div = abs(D * (P - F)); + // clamp crazy numbers +// Div = max(0.01f, Div); + float CoCRadiusFactor = Aperture * F * abs(P - D) / Div; + return saturate(CoCRadiusFactor); +*/ + // note: F has almost no effect + float CoCRadius = Aperture * F * (P - D) / (D * (P - F)); + + return saturate(abs(CoCRadius)); +} + +// TODO Taken from BokehDOF. Centralize! +// @return x:layer in front of focal plane, y: layer behind focal plane 1-x-y:layer in focus +float2 ComputeLayerContributions(float Depth, ViewStruct View) +{ + float Front = saturate((View.DepthOfFieldFocalDistance - Depth) / View.DepthOfFieldNearTransitionRegion); + float Back = saturate((Depth - View.DepthOfFieldFocalDistance - View.DepthOfFieldFocalRegion) / max(View.DepthOfFieldFarTransitionRegion, 0.0001f)); + return float2(Front, Back); +} + +// TODO Taken from BokehDOF. Centralize! +float4 CommonDOFSetup(/*in float2 CenterUV*/ in uint2 px, out bool bFrontLayer, out float4 Mask, ViewStruct View) +{ + /* + float2 Offset = PostprocessInput0Size.zw; + + float2 UV[4]; + + // no filtering (2x2 kernel) to get no leaking in Depth of Field + UV[0] = CenterUV + Offset * float2(-0.5f, -0.5f); + UV[1] = CenterUV + Offset * float2( 0.5f, -0.5f); + UV[2] = CenterUV + Offset * float2(-0.5f, 0.5f); + UV[3] = CenterUV + Offset * float2( 0.5f, 0.5f); + */ + uint2 samplePoints[4]; + samplePoints[0] = px*2 + uint2(0,0); + samplePoints[1] = px*2 + uint2(1,0); + samplePoints[2] = px*2 + uint2(0,1); + samplePoints[3] = px*2 + uint2(1,1); + + float4 ColorAndDepth[4]; + float2 Layer[4]; + + for(uint i = 0; i < 4; ++i) + { + // clamping to a small number fixes black dots appearing (denorms?, 0 doesn't fix it) + ColorAndDepth[i].rgb = max(float3(0.0001f, 0.0001f, 0.0001f), Color[samplePoints[i]].rgb /*Texture2DSample(PostprocessInput0, PostprocessInput0Sampler, UV[i]).rgb*/); + ColorAndDepth[i].a = Depth[samplePoints[i]]; + Layer[i] = ComputeLayerContributions(ColorAndDepth[i].a, View); + } + + float2 LayerSum = Layer[0] + Layer[1] + Layer[2] + Layer[3]; + bFrontLayer = LayerSum.x > LayerSum.y; + + Mask = bFrontLayer ? + float4(Layer[0].x, Layer[1].x, Layer[2].x, Layer[3].x) : + float4(Layer[0].y, Layer[1].y, Layer[2].y, Layer[3].y); + + float SumMask = dot(Mask, 1); + + float4 OutColor; + + if(SumMask > 0.001f) + { + OutColor = ( + ColorAndDepth[0] * Mask.x + + ColorAndDepth[1] * Mask.y + + ColorAndDepth[2] * Mask.z + + ColorAndDepth[3] * Mask.w ) / SumMask; + } + else + { + OutColor = ColorAndDepth[0]; + } + return OutColor; +} + + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + // ================================================ + // Our setup code + uint2 px = DTid.xy; + float4 OutColor0 = float4(0.0f, 0.0f, 0.0f, 0.0f); + float4 OutColor1 = float4(0.0f, 0.0f, 0.0f, 0.0f); + float4 OutColor2 = float4(0.0f, 0.0f, 0.0f, 0.0f); + + ViewStruct View = (ViewStruct)0; + View.DepthOfFieldFocalLength = /*$(Variable:FocalLength)*/; + View.DepthOfFieldFocalDistance = /*$(Variable:FocalDistance)*/; + View.DepthOfFieldFocalRegion = /*$(Variable:FocalRegion)*/; + View.DepthOfFieldNearTransitionRegion = /*$(Variable:NearTransitionRegion)*/; + View.DepthOfFieldFarTransitionRegion = /*$(Variable:FarTransitionRegion)*/; + View.DepthOfFieldScale = /*$(Variable:Scale)*/; + // ================================================ + + // unused for this pass + bool bFrontLayer = false; + float4 Mask = float4(0.0f, 0.0f, 0.0f, 0.0f); + + float4 SceneColorAndDepth = CommonDOFSetup(px, bFrontLayer, Mask, View); + + // clamp to avoid artifacts from exceeding fp16 through framebuffer blending of multiple very bright lights + SceneColorAndDepth.rgb = min(float3(256 * 256, 256 * 256, 256 * 256), SceneColorAndDepth.rgb); + + float SceneDepth = SceneColorAndDepth.a; + float CircleOfConfusion = ComputeCircleOfConfusion(SceneDepth, View); + + if (SceneDepth < View.DepthOfFieldFocalDistance) { + // Near + OutColor0 = float4(0, 0, 0, 0); + OutColor1 = float4(SceneColorAndDepth.rgb, CircleOfConfusion); + OutColor2 = CircleOfConfusion; // Separate CoC to build Max TileMap + } + else if (SceneDepth >= View.DepthOfFieldFocalDistance + View.DepthOfFieldFocalRegion) + { + // Far + OutColor0 = float4(SceneColorAndDepth.rgb, CircleOfConfusion); + OutColor1 = float4(0, 0, 0, 0); + OutColor2 = 0.0f; + } + else + { + // In-focus (inside focal region) + OutColor0 = float4(0, 0, 0, 0); + OutColor1 = float4(0, 0, 0, 0); + OutColor2 = 0.0f; + } + + FarFieldColorCoC[px] = OutColor0; + NearFieldColorCoC[px] = OutColor1; + NearMaxCocTilemap[px] = OutColor2; +} + +/* +Shader Resources: + Texture Color (as SRV) + Texture Depth (as SRV) + Texture FarFieldColorCoC (as UAV) + Texture NearFieldColorCoC (as UAV) + Texture NearMaxCocTilemap (as UAV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/GatherDOF2018/dof.gg b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/dof.gg new file mode 100644 index 00000000..de4e3cfc --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/dof.gg @@ -0,0 +1,1058 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "variables": [ + { + "name": "FocalDistance", + "comment": "Anything closer than this is considered near field", + "type": "Float", + "dflt": "500.0f", + "visibility": "User" + }, + { + "name": "FocalRegion", + "comment": "The size in world units of the middle range which is in focus", + "type": "Float", + "dflt": "100.0f", + "visibility": "User" + }, + { + "name": "FocalLength", + "comment": "Focal length in mm (Camera property e.g. 75mm)", + "type": "Float", + "dflt": "75.0f", + "visibility": "User" + }, + { + "name": "NearTransitionRegion", + "comment": "Fade distance in world units", + "type": "Float", + "dflt": "50", + "visibility": "User" + }, + { + "name": "FarTransitionRegion", + "comment": "Fade distance in world units", + "type": "Float", + "dflt": "200", + "visibility": "User" + }, + { + "name": "Scale", + "comment": "Camera property e.g. 0.5f, like aperture", + "type": "Float", + "dflt": "0.5f", + "visibility": "User" + }, + { + "name": "DoFarField", + "comment": "Whether or not to do the far field", + "type": "Bool", + "dflt": "true", + "visibility": "User" + }, + { + "name": "DoFarFieldFloodFill", + "comment": "Whether to do flood fill on the far field", + "type": "Bool", + "dflt": "true", + "visibility": "User" + }, + { + "name": "DoNearField", + "comment": "Whether or not to do the near field", + "type": "Bool", + "dflt": "true", + "visibility": "User" + }, + { + "name": "DoNearFieldFloodFill", + "comment": "Whether to do flood fill on the near field", + "type": "Bool", + "dflt": "true", + "visibility": "User" + }, + { + "name": "KernelSize", + "comment": "x = size of the bokeh blur radius in texel space. y = rotation in radius to apply to the bokeh shape. z = Number of edge of the polygon (number of blades). 0: circle. 4: square, 6: hexagon...", + "type": "Float4", + "dflt": "10.0f, 15.0f, 5.0f, 0.0f", + "visibility": "User" + }, + { + "name": "BlurTapCount", + "comment": "8 for high quality, 6 for low quality. Used in a double for loop, so it's this number squared.", + "type": "Uint", + "dflt": "8", + "visibility": "User" + }, + { + "name": "FloodFillTapCount", + "comment": "4 for high quality, 3 for low quality. Used in a double for loop, so it's this number squared.", + "type": "Uint", + "dflt": "4", + "visibility": "User" + }, + { + "name": "sRGB", + "comment": "Set to true if the input texture is an sRGB texture", + "type": "Bool", + "dflt": "true", + "visibility": "User" + } + ], + "shaders": [ + { + "name": "SetupCS", + "fileName": "SetupCS.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "Color", + "type": "Texture", + "access": "SRV" + }, + { + "name": "Depth", + "type": "Texture", + "access": "SRV", + "texture": { + "viewType": "Float" + } + }, + { + "name": "FarFieldColorCoC", + "type": "Texture", + "access": "UAV" + }, + { + "name": "NearFieldColorCoC", + "type": "Texture", + "access": "UAV" + }, + { + "name": "NearMaxCocTilemap", + "type": "Texture", + "access": "UAV" + } + ] + }, + { + "name": "BlurFarCS", + "fileName": "BlurFarCS.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "FarFieldColorCoC", + "type": "Texture", + "access": "SRV" + }, + { + "name": "BlurredFarFieldColorAlpha", + "type": "Texture", + "access": "UAV" + } + ], + "samplers": [ + { + "name": "linearClampSampler", + "addressMode": "Clamp" + } + ] + }, + { + "name": "FloodFillFarCS", + "fileName": "FloodFillFarCS.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "MaxCoCTileMap", + "type": "Texture", + "access": "SRV" + }, + { + "name": "ColorCoc", + "type": "Texture", + "access": "SRV" + }, + { + "name": "BlurredFieldColorAlpha", + "type": "Texture", + "access": "UAV" + } + ], + "samplers": [ + { + "name": "linearClampSampler", + "addressMode": "Clamp" + } + ] + }, + { + "name": "DownscaleTileMapCS", + "fileName": "DownscaleTileMap_1_4.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "Source", + "type": "Texture", + "access": "SRV", + "texture": { + "viewType": "Float" + } + }, + { + "name": "Dest", + "type": "Texture", + "access": "UAV", + "texture": { + "viewType": "Float" + } + } + ] + }, + { + "name": "NearHaloCS", + "fileName": "NearHaloCS.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "NearMaxCocTilemap_1_8", + "type": "Texture", + "access": "SRV", + "texture": { + "viewType": "Float" + } + }, + { + "name": "NearMaxCocTilemap_1_8_Halo", + "type": "Texture", + "access": "UAV", + "texture": { + "viewType": "Float" + } + } + ] + }, + { + "name": "NearBorderCS", + "fileName": "NearBorderCS.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "NearFieldColorCoC", + "type": "Texture", + "access": "SRV" + }, + { + "name": "NearFieldColorCoCBorder", + "type": "Texture", + "access": "UAV" + } + ] + }, + { + "name": "NearBlur", + "fileName": "NearBlurCS.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "NearFieldColorCoCBorder", + "type": "Texture", + "access": "SRV" + }, + { + "name": "NearmaxCoCTilemap_1_8_Halo", + "type": "Texture", + "access": "SRV", + "texture": { + "viewType": "Float" + } + }, + { + "name": "NearFieldColorCoCBorderBlurred", + "type": "Texture", + "access": "UAV" + } + ], + "samplers": [ + { + "name": "linearClampSampler", + "addressMode": "Clamp" + } + ] + }, + { + "name": "RecombineCS", + "fileName": "RecombineCS.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "NearField", + "type": "Texture", + "access": "SRV" + }, + { + "name": "Color", + "type": "Texture", + "access": "SRV" + }, + { + "name": "Depth", + "type": "Texture", + "access": "SRV", + "texture": { + "viewType": "Float" + } + }, + { + "name": "FarField", + "type": "Texture", + "access": "SRV" + }, + { + "name": "Output", + "type": "Texture", + "access": "UAV" + } + ], + "samplers": [ + { + "name": "linearClampSampler", + "addressMode": "Clamp" + } + ] + } + ], + "fileCopies": [ + { + "fileName": "Common.hlsli", + "type": "Shader" + } + ], + "nodes": [ + { + "resourceTexture": { + "name": "Color", + "editorPos": [ + -165.0, + -62.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "LinearDepth", + "editorPos": [ + -165.0, + -14.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "Output", + "editorPos": [ + 1595.0, + 66.0 + ], + "visibility": "Exported", + "format": { + "node": { + "name": "Color" + } + }, + "size": { + "node": { + "name": "Color" + } + } + } + }, + { + "actionComputeShader": { + "name": "Setup", + "editorPos": [ + 5.0, + -58.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Color", + "dstNode": "Color", + "dstPin": "resource" + }, + { + "srcPin": "Depth", + "dstNode": "LinearDepth", + "dstPin": "resource" + }, + { + "srcPin": "FarFieldColorCoC", + "dstNode": "FarFieldColorCoC", + "dstPin": "resource" + }, + { + "srcPin": "NearFieldColorCoC", + "dstNode": "NearFieldColorCoC", + "dstPin": "resource" + }, + { + "srcPin": "NearMaxCocTilemap", + "dstNode": "NearMaxCocTilemap", + "dstPin": "resource" + } + ], + "shader": { + "name": "SetupCS" + }, + "dispatchSize": { + "node": { + "name": "Color" + } + } + } + }, + { + "resourceTexture": { + "name": "FarFieldColorCoC", + "editorPos": [ + -191.0, + 34.0 + ], + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "Color" + }, + "divide": [ + 2, + 2, + 1 + ] + } + } + }, + { + "resourceTexture": { + "name": "NearFieldColorCoC", + "editorPos": [ + -201.0, + 82.0 + ], + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "Color" + }, + "divide": [ + 2, + 2, + 1 + ] + } + } + }, + { + "resourceTexture": { + "name": "NearMaxCocTilemap", + "editorPos": [ + -204.0, + 130.0 + ], + "format": { + "format": "R8_Unorm" + }, + "size": { + "node": { + "name": "Color" + }, + "divide": [ + 2, + 2, + 1 + ] + } + } + }, + { + "actionComputeShader": { + "name": "BlurFar", + "editorPos": [ + 277.0, + 172.0 + ], + "condition": { + "variable1": "DoFarField", + "comparison": "IsTrue" + }, + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "FarFieldColorCoC", + "dstNode": "Setup", + "dstPin": "FarFieldColorCoC" + }, + { + "srcPin": "BlurredFarFieldColorAlpha", + "dstNode": "BlurredFarFieldColorAlpha", + "dstPin": "resource" + } + ], + "shader": { + "name": "BlurFarCS" + }, + "dispatchSize": { + "node": { + "name": "FarFieldColorCoC" + } + } + } + }, + { + "resourceTexture": { + "name": "BlurredFarFieldColorAlpha", + "editorPos": [ + 27.0, + 290.0 + ], + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "Color" + }, + "divide": [ + 2, + 2, + 1 + ] + } + } + }, + { + "actionComputeShader": { + "name": "FloodFillFar", + "editorPos": [ + 597.0, + 114.0 + ], + "condition": { + "variable1": "DoFarField", + "comparison": "IsTrue" + }, + "linkProperties": [ + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "ColorCoc", + "dstNode": "BlurFar", + "dstPin": "BlurredFarFieldColorAlpha" + }, + { + "srcPin": "MaxCoCTileMap", + "dstNode": "Setup", + "dstPin": "NearMaxCocTilemap" + }, + { + "srcPin": "BlurredFieldColorAlpha", + "dstNode": "FloodFilledBlurredFarFieldColorAlpha", + "dstPin": "resource" + } + ], + "shader": { + "name": "FloodFillFarCS" + }, + "dispatchSize": { + "node": { + "name": "FarFieldColorCoC" + } + }, + "defines": [ + { + "name": "COC_TILEMAP", + "value": "0" + } + ] + } + }, + { + "resourceTexture": { + "name": "FloodFilledBlurredFarFieldColorAlpha", + "editorPos": [ + 268.0, + 274.0 + ], + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "Color" + }, + "divide": [ + 2, + 2, + 1 + ] + } + } + }, + { + "actionComputeShader": { + "name": "DownscaleTileMap_1_4", + "editorPos": [ + 863.0, + 229.0 + ], + "condition": { + "variable1": "DoNearField", + "comparison": "IsTrue" + }, + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Source", + "dstNode": "FloodFillFar", + "dstPin": "MaxCoCTileMap" + }, + { + "srcPin": "Dest", + "dstNode": "NearMaxCocTilemap_1_4", + "dstPin": "resource" + } + ], + "shader": { + "name": "DownscaleTileMapCS" + }, + "dispatchSize": { + "node": { + "name": "NearMaxCocTilemap_1_4" + } + } + } + }, + { + "resourceTexture": { + "name": "NearMaxCocTilemap_1_4", + "editorPos": [ + 632.0, + 341.0 + ], + "format": { + "format": "R8_Unorm" + }, + "size": { + "node": { + "name": "NearMaxCocTilemap" + }, + "divide": [ + 2, + 2, + 1 + ] + } + } + }, + { + "resourceTexture": { + "name": "NearMaxCocTilemap_1_8", + "editorPos": [ + 856.0, + 341.0 + ], + "format": { + "format": "R8_Unorm" + }, + "size": { + "node": { + "name": "NearMaxCocTilemap_1_4" + }, + "divide": [ + 2, + 2, + 1 + ] + } + } + }, + { + "actionComputeShader": { + "name": "DownscaleTileMap_1_8", + "editorPos": [ + 1077.0, + 229.0 + ], + "condition": { + "variable1": "DoNearField", + "comparison": "IsTrue" + }, + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Source", + "dstNode": "DownscaleTileMap_1_4", + "dstPin": "Dest" + }, + { + "srcPin": "Dest", + "dstNode": "NearMaxCocTilemap_1_8", + "dstPin": "resource" + } + ], + "shader": { + "name": "DownscaleTileMapCS" + }, + "dispatchSize": { + "node": { + "name": "NearMaxCocTilemap_1_8" + } + } + } + }, + { + "actionComputeShader": { + "name": "NearHalo", + "editorPos": [ + 1317.0, + 226.0 + ], + "condition": { + "variable1": "DoNearField", + "comparison": "IsTrue" + }, + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "NearMaxCocTilemap_1_8", + "dstNode": "DownscaleTileMap_1_8", + "dstPin": "Dest" + }, + { + "srcPin": "NearMaxCocTilemap_1_8_Halo", + "dstNode": "NearMaxCocTilemap_1_8_Halo", + "dstPin": "resource" + } + ], + "shader": { + "name": "NearHaloCS" + }, + "dispatchSize": { + "node": { + "name": "NearMaxCocTilemap_1_8" + } + } + } + }, + { + "resourceTexture": { + "name": "NearMaxCocTilemap_1_8_Halo", + "editorPos": [ + 1064.0, + 341.0 + ], + "format": { + "node": { + "name": "NearMaxCocTilemap_1_8" + } + }, + "size": { + "node": { + "name": "NearMaxCocTilemap_1_8" + } + } + } + }, + { + "actionComputeShader": { + "name": "NearBorder", + "editorPos": [ + 797.0, + -308.0 + ], + "condition": { + "variable1": "DoNearField", + "comparison": "IsTrue" + }, + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "NearFieldColorCoCBorder", + "dstNode": "NearFieldColorCoCBorder", + "dstPin": "resource" + }, + { + "srcPin": "NearFieldColorCoCBorder" + }, + { + "srcPin": "NearFieldColorCoC", + "dstNode": "Setup", + "dstPin": "NearFieldColorCoC" + } + ], + "shader": { + "name": "NearBorderCS" + }, + "dispatchSize": { + "node": { + "name": "NearFieldColorCoC" + } + } + } + }, + { + "resourceTexture": { + "name": "NearFieldColorCoCBorder", + "editorPos": [ + 576.0, + -193.0 + ], + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "Color" + }, + "divide": [ + 2, + 2, + 1 + ] + } + } + }, + { + "actionComputeShader": { + "name": "NearBlur", + "editorPos": [ + 1109.0, + -308.0 + ], + "condition": { + "variable1": "DoNearField", + "comparison": "IsTrue" + }, + "linkProperties": [ + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "NearFieldColorCoCBorderBlurred", + "dstNode": "NearFieldColorCoCBorderBlurred", + "dstPin": "resource" + }, + { + "srcPin": "NearmaxCoCTilemap_1_8_Halo", + "dstNode": "NearHalo", + "dstPin": "NearMaxCocTilemap_1_8_Halo" + }, + { + "srcPin": "NearFieldColorCoCBorderBlurred" + }, + { + "srcPin": "NearFieldColorCoCBorder", + "dstNode": "NearBorder", + "dstPin": "NearFieldColorCoCBorder" + } + ], + "shader": { + "name": "NearBlur" + }, + "dispatchSize": { + "node": { + "name": "NearFieldColorCoCBorder" + } + } + } + }, + { + "resourceTexture": { + "name": "NearFieldColorCoCBorderBlurred", + "editorPos": [ + 789.0, + -193.0 + ], + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "Color" + }, + "divide": [ + 2, + 2, + 1 + ] + } + } + }, + { + "actionComputeShader": { + "name": "FloodFillNear", + "editorPos": [ + 1434.0, + -289.0 + ], + "condition": { + "variable1": "DoNearField", + "comparison": "IsTrue" + }, + "linkProperties": [ + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "ColorCoc", + "dstNode": "NearBlur", + "dstPin": "NearFieldColorCoCBorderBlurred" + }, + { + "srcPin": "MaxCoCTileMap", + "dstNode": "NearBlur", + "dstPin": "NearmaxCoCTilemap_1_8_Halo" + }, + { + "srcPin": "BlurredFieldColorAlpha", + "dstNode": "FloodFilledBlurredNearFieldColorAlpha", + "dstPin": "resource" + } + ], + "shader": { + "name": "FloodFillFarCS" + }, + "dispatchSize": { + "node": { + "name": "FarFieldColorCoC" + } + }, + "defines": [ + { + "name": "COC_TILEMAP", + "value": "1" + } + ] + } + }, + { + "resourceTexture": { + "name": "FloodFilledBlurredNearFieldColorAlpha", + "editorPos": [ + 1112.0, + -177.0 + ], + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "Color" + }, + "divide": [ + 2, + 2, + 1 + ] + } + } + }, + { + "actionComputeShader": { + "name": "Recombine", + "editorPos": [ + 1781.0, + -87.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Color", + "dstNode": "Setup", + "dstPin": "Color" + }, + { + "srcPin": "FarField", + "dstNode": "FloodFillFar", + "dstPin": "BlurredFieldColorAlpha" + }, + { + "srcPin": "NearField", + "dstNode": "FloodFillNear", + "dstPin": "BlurredFieldColorAlpha" + }, + { + "srcPin": "Output", + "dstNode": "Output", + "dstPin": "resource" + }, + { + "srcPin": "Depth", + "dstNode": "Setup", + "dstPin": "Depth" + } + ], + "shader": { + "name": "RecombineCS" + }, + "dispatchSize": { + "node": { + "name": "Output" + } + } + } + } + ] +} \ No newline at end of file diff --git a/Techniques/PostProcessing/DepthOfField/GatherDOF2018/readme.txt b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/readme.txt new file mode 100644 index 00000000..35be8397 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/GatherDOF2018/readme.txt @@ -0,0 +1,3 @@ +Implementation of GatherDOF - the non TAA path +by Adrian Courrèges December 2018 +https://www.adriancourreges.com/blog/2018/12/02/ue4-optimized-post-effects/ \ No newline at end of file diff --git a/Techniques/PostProcessing/DepthOfField/Gustafsson2018/dof.gg b/Techniques/PostProcessing/DepthOfField/Gustafsson2018/dof.gg new file mode 100644 index 00000000..0d611f15 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/Gustafsson2018/dof.gg @@ -0,0 +1,147 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "variables": [ + { + "name": "MaxBlurSize", + "comment": "Maximum radius of the CoC", + "type": "Float", + "dflt": "20.0f", + "visibility": "User" + }, + { + "name": "FocalLength", + "comment": "How far from the camera should be in focus", + "type": "Float", + "dflt": "1.0f", + "visibility": "User" + }, + { + "name": "FocusScale", + "comment": "How quickly the CoC scales over distance", + "type": "Float", + "dflt": "100.0f", + "visibility": "User" + }, + { + "name": "RadiusScale", + "comment": "How fast the points spiral out. smaller = nicer. larger = faster.", + "type": "Float", + "dflt": "0.5f", + "visibility": "User" + }, + { + "name": "sRGB", + "comment": "Set to true if the input texture is an sRGB texture", + "type": "Bool", + "dflt": "true", + "visibility": "User" + } + ], + "shaders": [ + { + "name": "DOF", + "fileName": "dof.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "Color", + "type": "Texture", + "access": "SRV" + }, + { + "name": "LinearDepth", + "type": "Texture", + "access": "SRV" + }, + { + "name": "Output", + "type": "Texture", + "access": "UAV" + } + ] + } + ], + "nodes": [ + { + "actionComputeShader": { + "name": "DOF", + "editorPos": [ + 13.0, + -21.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Color", + "dstNode": "Color", + "dstPin": "resource" + }, + { + "srcPin": "LinearDepth", + "dstNode": "LinearDepth", + "dstPin": "resource" + }, + { + "srcPin": "Output", + "dstNode": "Output", + "dstPin": "resource" + } + ], + "shader": { + "name": "DOF" + }, + "dispatchSize": { + "node": { + "name": "Color" + } + } + } + }, + { + "resourceTexture": { + "name": "Color", + "editorPos": [ + -197.0, + -14.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "LinearDepth", + "editorPos": [ + -197.0, + 50.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "Output", + "editorPos": [ + -181.0, + 114.0 + ], + "visibility": "Exported", + "format": { + "node": { + "name": "Color" + } + }, + "size": { + "node": { + "name": "Color" + } + } + } + } + ] +} \ No newline at end of file diff --git a/Techniques/PostProcessing/DepthOfField/Gustafsson2018/dof.hlsl b/Techniques/PostProcessing/DepthOfField/Gustafsson2018/dof.hlsl new file mode 100644 index 00000000..65ae2052 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/Gustafsson2018/dof.hlsl @@ -0,0 +1,71 @@ +// Unnamed technique, shader DOF +/*$(ShaderResources)*/ + +// Implementation of "Bokeh depth of field in a single pass" +// https://blog.voxagon.se/2018/05/04/bokeh-depth-of-field-in-single-pass.html + +static const float GOLDEN_ANGLE = 2.39996323; + +float3 LinearToSRGB(float3 linearCol) +{ + float3 sRGBLo = linearCol * 12.92; + float3 sRGBHi = (pow(abs(linearCol), float3(1.0 / 2.4, 1.0 / 2.4, 1.0 / 2.4)) * 1.055) - 0.055; + float3 sRGB; + sRGB.r = linearCol.r <= 0.0031308 ? sRGBLo.r : sRGBHi.r; + sRGB.g = linearCol.g <= 0.0031308 ? sRGBLo.g : sRGBHi.g; + sRGB.b = linearCol.b <= 0.0031308 ? sRGBLo.b : sRGBHi.b; + return sRGB; +} + +float getBlurSize(float depth, float focusPoint, float focusScale) +{ + float coc = clamp((1.0 / focusPoint - 1.0 / depth)*focusScale, -1.0, 1.0); + return abs(coc) * /*$(Variable:MaxBlurSize)*/; +} + +float3 depthOfField(uint2 texCoord, float focusPoint, float focusScale) +{ + uint2 ColorSize; + Color.GetDimensions(ColorSize.x, ColorSize.y); + + float centerDepth = LinearDepth[texCoord].r; + float centerSize = getBlurSize(centerDepth, focusPoint, focusScale); + float3 color = Color[texCoord].rgb; + float tot = 1.0; + float radius = /*$(Variable:RadiusScale)*/; + for (float ang = 0.0; radius centerDepth) + sampleSize = clamp(sampleSize, 0.0, centerSize*2.0); + float m = smoothstep(radius-0.5, radius+0.5, sampleSize); + color += lerp(color/tot, sampleColor, m); + tot += 1.0; radius += /*$(Variable:RadiusScale)*//radius; + } + + return color /= tot; +} + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + uint2 px = uint2(DTid.xy); + + float3 output = depthOfField(px, /*$(Variable:FocalLength)*/, /*$(Variable:FocusScale)*/); + + if (/*$(Variable:sRGB)*/) + output = LinearToSRGB(output); + + Output[px] = float4(output, 1.0f); + +} + +/* +Shader Resources: + Texture Color (as SRV) + Texture LinearDepth (as SRV) + Texture output (as UAV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/Gustafsson2018/readme.txt b/Techniques/PostProcessing/DepthOfField/Gustafsson2018/readme.txt new file mode 100644 index 00000000..eeeda40b --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/Gustafsson2018/readme.txt @@ -0,0 +1,4 @@ +An implementation of "Bokeh depth of field in a single pass" +by Dennis Gustafsson +May 4, 2018 +https://blog.voxagon.se/2018/05/04/bokeh-depth-of-field-in-single-pass.html \ No newline at end of file diff --git a/Techniques/PostProcessing/DepthOfField/IW2007/dof.gg b/Techniques/PostProcessing/DepthOfField/IW2007/dof.gg new file mode 100644 index 00000000..c5bab3e6 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/IW2007/dof.gg @@ -0,0 +1,502 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "variables": [ + { + "name": "DepthScale", + "comment": "Divides EqNear and EqFar by this amount. Useful for large scenes to not work with very tiny numbers.", + "type": "Float", + "dflt": "1.0", + "visibility": "User" + }, + { + "name": "EqNear", + "comment": "CoC = (EqWorld.x * depth + EqWorld.y)", + "type": "Float2", + "visibility": "User" + }, + { + "name": "EqFar", + "comment": "CoC = (EqFar.x * depth + EqFar.y)", + "type": "Float2", + "visibility": "User" + }, + { + "name": "FarToNearRadiusRatio", + "type": "Float", + "dflt": "1.0", + "visibility": "User" + }, + { + "name": "fadeDistances", + "comment": "Let the unblurred sample to small blur fade happen over distance d0, the small to medium blur over distance d1, and the medium to large blur over distance d2, where d0 + d1 + d2 = 1.", + "type": "Float3", + "visibility": "User" + }, + { + "name": "sRGB", + "comment": "Set to true if the input texture is an sRGB texture", + "type": "Bool", + "dflt": "true", + "visibility": "User" + } + ], + "shaders": [ + { + "name": "DownSampleCoC", + "fileName": "dof_downsample_coc.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "Color", + "type": "Texture", + "access": "SRV" + }, + { + "name": "LinearDepth", + "type": "Texture", + "access": "SRV" + }, + { + "name": "DownsampledCoC", + "type": "Texture", + "access": "UAV" + } + ], + "samplers": [ + { + "name": "linearWrapSampler" + } + ] + }, + { + "name": "GaussBlur", + "fileName": "dof_gauss_blur.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "DownsampledCoC", + "type": "Texture", + "access": "SRV" + }, + { + "name": "BlurredDownsampledCoC", + "type": "Texture", + "access": "UAV" + } + ] + }, + { + "name": "CalculateNearCoC", + "fileName": "dof_calculate_near_coc.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "shrunkSampler", + "type": "Texture", + "access": "SRV" + }, + { + "name": "blurredSampler", + "type": "Texture", + "access": "SRV" + }, + { + "name": "Output", + "type": "Texture", + "access": "UAV" + } + ] + }, + { + "name": "BlurNearCoC", + "fileName": "dof_blur_near_coc.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "CalculatedNearCoC", + "type": "Texture", + "access": "SRV" + }, + { + "name": "Output", + "type": "Texture", + "access": "UAV" + } + ], + "samplers": [ + { + "name": "linearClampSampler", + "addressMode": "Clamp" + } + ] + }, + { + "name": "ApplyDOF", + "fileName": "dof_apply_dof.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "Color", + "type": "Texture", + "access": "SRV" + }, + { + "name": "LinearDepth", + "type": "Texture", + "access": "SRV" + }, + { + "name": "LargeBlur", + "type": "Texture", + "access": "SRV" + }, + { + "name": "SmallBlur", + "type": "Texture", + "access": "SRV" + }, + { + "name": "Output", + "type": "Texture", + "access": "UAV" + } + ], + "samplers": [ + { + "name": "linearWrapSampler" + } + ] + } + ], + "nodes": [ + { + "resourceTexture": { + "name": "Color", + "editorPos": [ + -36.0, + -4.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "LinearDepth", + "editorPos": [ + -37.0, + 50.0 + ], + "visibility": "Imported" + } + }, + { + "actionComputeShader": { + "name": "DownsampleCoC", + "editorPos": [ + 123.0, + 34.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Color", + "dstNode": "Color", + "dstPin": "resource" + }, + { + "srcPin": "LinearDepth", + "dstNode": "LinearDepth", + "dstPin": "resource" + }, + { + "srcPin": "DownsampledCoC", + "dstNode": "DownsampledCoC", + "dstPin": "resource" + } + ], + "shader": { + "name": "DownSampleCoC" + }, + "dispatchSize": { + "node": { + "name": "DownsampledCoC" + } + } + } + }, + { + "resourceTexture": { + "name": "DownsampledCoC", + "editorPos": [ + -36.0, + 162.0 + ], + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "Color" + }, + "divide": [ + 4, + 4, + 1 + ] + } + } + }, + { + "actionComputeShader": { + "name": "GaussBlur", + "editorPos": [ + 341.0, + 89.0 + ], + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "DownsampledCoC", + "dstNode": "DownsampleCoC", + "dstPin": "DownsampledCoC" + }, + { + "srcPin": "BlurredDownsampledCoC", + "dstNode": "BlurredDownsampledCoC", + "dstPin": "resource" + } + ], + "shader": { + "name": "GaussBlur" + }, + "dispatchSize": { + "node": { + "name": "DownsampledCoC" + } + } + } + }, + { + "resourceTexture": { + "name": "BlurredDownsampledCoC", + "editorPos": [ + 129.0, + 162.0 + ], + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "Color" + }, + "divide": [ + 4, + 4, + 1 + ] + } + } + }, + { + "actionComputeShader": { + "name": "CalculateNearCoC", + "editorPos": [ + 613.0, + 89.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "shrunkSampler", + "dstNode": "GaussBlur", + "dstPin": "DownsampledCoC" + }, + { + "srcPin": "blurredSampler", + "dstNode": "GaussBlur", + "dstPin": "BlurredDownsampledCoC" + }, + { + "srcPin": "Output", + "dstNode": "CalculatedNearCoC", + "dstPin": "resource" + } + ], + "shader": { + "name": "CalculateNearCoC" + }, + "dispatchSize": { + "node": { + "name": "DownsampledCoC" + } + } + } + }, + { + "resourceTexture": { + "name": "CalculatedNearCoC", + "editorPos": [ + 366.0, + 204.0 + ], + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "Color" + }, + "divide": [ + 4, + 4, + 1 + ] + } + } + }, + { + "actionComputeShader": { + "name": "BlurNearCoC", + "editorPos": [ + 821.0, + 143.0 + ], + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "CalculatedNearCoC", + "dstNode": "CalculateNearCoC", + "dstPin": "Output" + }, + { + "srcPin": "Output", + "dstNode": "BlurredNearCoC", + "dstPin": "resource" + } + ], + "shader": { + "name": "BlurNearCoC" + }, + "dispatchSize": { + "node": { + "name": "DownsampledCoC" + } + } + } + }, + { + "resourceTexture": { + "name": "BlurredNearCoC", + "editorPos": [ + 646.0, + 204.0 + ], + "format": { + "format": "RGBA32_Float" + }, + "size": { + "node": { + "name": "Color" + }, + "divide": [ + 4, + 4, + 1 + ] + } + } + }, + { + "actionComputeShader": { + "name": "ApplyDOF", + "editorPos": [ + 1093.0, + 28.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Color", + "dstNode": "DownsampleCoC", + "dstPin": "Color" + }, + { + "srcPin": "SmallBlur", + "dstNode": "BlurNearCoC", + "dstPin": "Output" + }, + { + "srcPin": "LargeBlur", + "dstNode": "CalculateNearCoC", + "dstPin": "blurredSampler" + }, + { + "srcPin": "Output", + "dstNode": "Output", + "dstPin": "resource" + }, + { + "srcPin": "LinearDepth", + "dstNode": "DownsampleCoC", + "dstPin": "LinearDepth" + } + ], + "shader": { + "name": "ApplyDOF" + }, + "dispatchSize": { + "node": { + "name": "Color" + } + } + } + }, + { + "resourceTexture": { + "name": "Output", + "editorPos": [ + 891.0, + 242.0 + ], + "visibility": "Exported", + "format": { + "node": { + "name": "Color" + } + }, + "size": { + "node": { + "name": "Color" + } + } + } + } + ] +} \ No newline at end of file diff --git a/Techniques/PostProcessing/DepthOfField/IW2007/dof_apply_dof.hlsl b/Techniques/PostProcessing/DepthOfField/IW2007/dof_apply_dof.hlsl new file mode 100644 index 00000000..19bff49a --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/IW2007/dof_apply_dof.hlsl @@ -0,0 +1,105 @@ +// Unnamed technique, shader ApplyDOF +/*$(ShaderResources)*/ + +#define dofEqFar float3(/*$(Variable:EqFar)*/ / /*$(Variable:DepthScale)*/, /*$(Variable:FarToNearRadiusRatio)*/) + +#define d0 /*$(Variable:fadeDistances)*/.x +#define d1 /*$(Variable:fadeDistances)*/.y +#define d2 /*$(Variable:fadeDistances)*/.z + +float3 LinearToSRGB(float3 linearCol) +{ + float3 sRGBLo = linearCol * 12.92; + float3 sRGBHi = (pow(abs(linearCol), float3(1.0 / 2.4, 1.0 / 2.4, 1.0 / 2.4)) * 1.055) - 0.055; + float3 sRGB; + sRGB.r = linearCol.r <= 0.0031308 ? sRGBLo.r : sRGBHi.r; + sRGB.g = linearCol.g <= 0.0031308 ? sRGBLo.g : sRGBHi.g; + sRGB.b = linearCol.b <= 0.0031308 ? sRGBLo.b : sRGBHi.b; + return sRGB; +} + +float3 GetSmallBlurSample(uint2 px) +{ + static const float weight = 4.0f / 17.0f; + float3 sum = float3(0.0f, 0.0f, 0.0f); + + uint2 dims; + Color.GetDimensions(dims.x, dims.y); + + // Unblurred sample done by alpha blending + float2 uv = (float2(px) + float2(0.5f, 0.5f) + float2(+0.5f, -1.5f)) / float2(dims); + sum += weight * Color.SampleLevel(linearWrapSampler, uv, 0); + + uv = (float2(px) + float2(0.5f, 0.5f) + float2(-1.5f, -0.5f)) / float2(dims); + sum += weight * Color.SampleLevel(linearWrapSampler, uv, 0); + + uv = (float2(px) + float2(0.5f, 0.5f) + float2(-0.5f, +1.5f)) / float2(dims); + sum += weight * Color.SampleLevel(linearWrapSampler, uv, 0); + + uv = (float2(px) + float2(0.5f, 0.5f) + float2(+1.5f, +0.5f)) / float2(dims); + sum += weight * Color.SampleLevel(linearWrapSampler, uv, 0); + + return sum; +} + +float4 InterpolateDof(float3 small, float3 med, float3 large, float t) +{ + // Efficiently calculate the cross-blend weights for each sample. + // Let the unblurred sample to small blur fade happen over distance + // d0, the small to medium blur over distance d1, and the medium to + // large blur over distance d2, where d0 + d1 + d2 = 1. + // dofLerpScale = float4( -1 / d0, -1 / d1, -1 / d2, 1 / d2 ); + // dofLerpBias = float4( 1, (1 – d2) / d1, 1 / d2, (d2 – 1) / d2 ); + + float4 dofLerpScale = float4( -1.0f / d0, -1.0f / d1, -1.0f / d2, 1.0f / d2 ); + float4 dofLerpBias = float4( 1.0f, (1.0f - d2) / d1, 1.0f / d2, (d2 - 1.0f) / d2 ); + + float4 weights = saturate(t * dofLerpScale + dofLerpBias); + weights.yz = min(weights.yz, 1 - weights.xy); + + // Unblurred sample with weight "weights.x" done by alpha blending + float3 color = weights.y * small + weights.z * med + weights.w * large; + float alpha = dot(weights.yzw, half3(16.0 / 17, 1.0, 1.0)); + return float4(color, alpha); +} + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + //28-4 + uint2 px = DTid.xy; + float3 small = GetSmallBlurSample(px); + float4 med = SmallBlur[px/4]; + float3 large = LargeBlur[px/4].rgb; + float nearCoc = med.a; + float depth = LinearDepth[px].r; + float coc = 0.0f; + if (depth == 0.0f) + { + coc = nearCoc; // We don't want to blur the sky + } + else + { + // dofEqFar.x and dofEqFar.y specify the linear ramp to convert + // to depth for the distant out-of-focus region. + // dofEqFar.z is the ratio of the far to the near blur radius. + float farCoc = saturate(dofEqFar.x * depth + dofEqFar.y); + coc = max(nearCoc, farCoc * dofEqFar.z); + } + float4 output = InterpolateDof(small, med.rgb, large, coc); + + if (/*$(Variable:sRGB)*/) + output.rgb = LinearToSRGB(output.rgb); + + Output[px] = float4(output.rgb, 1.0f); +} + +/* +Shader Resources: + Texture Color (as SRV) + Texture LinearDepth (as SRV) + Texture LargeBlur (as SRV) + Texture SmallBlur (as SRV) + Texture Output (as UAV) +Shader Samplers: + linearWrapSampler filter: MinMagMipLinear addressmode: Wrap +*/ diff --git a/Techniques/PostProcessing/DepthOfField/IW2007/dof_blur_near_coc.hlsl b/Techniques/PostProcessing/DepthOfField/IW2007/dof_blur_near_coc.hlsl new file mode 100644 index 00000000..5a53f37d --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/IW2007/dof_blur_near_coc.hlsl @@ -0,0 +1,32 @@ +// Unnamed technique, shader BlurNearCoC +/*$(ShaderResources)*/ + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + // 28-3 + uint2 px = DTid.xy; + + uint2 dims; + CalculatedNearCoC.GetDimensions(dims.x, dims.y); + + float4 texCoords = (float2(px) + float2(0.5f, 0.5f)).xxyy + float4(-0.5f, 0.5f, -0.5f, 0.5f); + texCoords /= float4(dims.xxyy); + + float4 color = float4(0.0f, 0.0f, 0.0f, 0.0f); + + color += CalculatedNearCoC.SampleLevel(linearClampSampler, texCoords.xz, 0); + color += CalculatedNearCoC.SampleLevel(linearClampSampler, texCoords.yz, 0); + color += CalculatedNearCoC.SampleLevel(linearClampSampler, texCoords.xw, 0); + color += CalculatedNearCoC.SampleLevel(linearClampSampler, texCoords.yw, 0); + + Output[px] = color / 4.0f; + + // TODO: maybe the input is the full sized color image, even though the output isnt? + // The instructions seem to contradict each other a bit +} + +/* +Shader Resources: + Texture CalculatedNearCoC (as SRV) + Texture Output (as UAV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/IW2007/dof_calculate_near_coc.hlsl b/Techniques/PostProcessing/DepthOfField/IW2007/dof_calculate_near_coc.hlsl new file mode 100644 index 00000000..be69982d --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/IW2007/dof_calculate_near_coc.hlsl @@ -0,0 +1,20 @@ +// Unnamed technique, shader CalculateNearCoC +/*$(ShaderResources)*/ + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + //28-2 + uint2 px = DTid.xy; + float4 shrunk = shrunkSampler[px]; + float4 blurred = blurredSampler[px]; + float3 color = shrunk.rgb; + float coc = 2.0f * max(blurred.a, shrunk.a) - shrunk.a; + Output[px] = float4(color, coc); +} + +/* +Shader Resources: + Texture shrunkSampler (as SRV) + Texture blurredSampler (as SRV) + Texture Output (as UAV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/IW2007/dof_downsample_coc.hlsl b/Techniques/PostProcessing/DepthOfField/IW2007/dof_downsample_coc.hlsl new file mode 100644 index 00000000..d25f71a3 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/IW2007/dof_downsample_coc.hlsl @@ -0,0 +1,83 @@ +// Unnamed technique, shader DownSampleCoC +/*$(ShaderResources)*/ + +#define dofEqWorld (/*$(Variable:EqNear)*/ / /*$(Variable:DepthScale)*/) + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + //28-1 + uint2 px = DTid.xy; + + uint2 dims; + Color.GetDimensions(dims.x, dims.y); + + /* + ___ ___ ___ ___ + | | | | | + |___|___|___|___| + | | | | | ___ + |___|___|___|___| => | | + | | | | | |___| + |___|___|___|___| + | | | | | + |___|___|___|___| + + */ + + // We want to average a 4x4 block of pixels from color. + // We could do 16 reads, but instead, we can do 4 bilinear taps at the center of each 4x4 cell. + // We add 0.5 when converting from integer pixel coordinates to UVs to get to the center of the cell, where the pixel data is. + // We add another 0.5 because we actually want to go the center of the 4x4 block + float2 uv00 = (float2(px * 4 + uint2(0, 0)) + float2(0.5f, 0.5f) + float2(0.5f, 0.5f)) / float2(dims); + float2 uv10 = (float2(px * 4 + uint2(2, 0)) + float2(0.5f, 0.5f) + float2(0.5f, 0.5f)) / float2(dims); + float2 uv01 = (float2(px * 4 + uint2(0, 2)) + float2(0.5f, 0.5f) + float2(0.5f, 0.5f)) / float2(dims); + float2 uv11 = (float2(px * 4 + uint2(2, 2)) + float2(0.5f, 0.5f) + float2(0.5f, 0.5f)) / float2(dims); + + float3 color = Color.SampleLevel(linearWrapSampler, uv00, 0).rgb + Color.SampleLevel(linearWrapSampler, uv10, 0).rgb + Color.SampleLevel(linearWrapSampler, uv01, 0).rgb + Color.SampleLevel(linearWrapSampler, uv11, 0).rgb; + color /= 4.0f; + + // We want to take the minimum CoC value of every depth value in the 4x4 block + float4 depth; + depth[0] = LinearDepth[px * 4 + uint2(0, 0)].r; + depth[1] = LinearDepth[px * 4 + uint2(1, 0)].r; + depth[2] = LinearDepth[px * 4 + uint2(2, 0)].r; + depth[3] = LinearDepth[px * 4 + uint2(3, 0)].r; + float4 sceneCoc = saturate(dofEqWorld.x * depth + dofEqWorld.y); + float4 curCoc = sceneCoc; + float4 coc = curCoc; + + depth[0] = LinearDepth[px * 4 + uint2(0, 1)].r; + depth[1] = LinearDepth[px * 4 + uint2(1, 1)].r; + depth[2] = LinearDepth[px * 4 + uint2(2, 1)].r; + depth[3] = LinearDepth[px * 4 + uint2(3, 1)].r; + sceneCoc = saturate(dofEqWorld.x * depth + dofEqWorld.y); + curCoc = sceneCoc; + coc = max(coc, curCoc); + + depth[0] = LinearDepth[px * 4 + uint2(0, 2)].r; + depth[1] = LinearDepth[px * 4 + uint2(1, 2)].r; + depth[2] = LinearDepth[px * 4 + uint2(2, 2)].r; + depth[3] = LinearDepth[px * 4 + uint2(3, 2)].r; + sceneCoc = saturate(dofEqWorld.x * depth + dofEqWorld.y); + curCoc = sceneCoc; + coc = max(coc, curCoc); + + depth[0] = LinearDepth[px * 4 + uint2(0, 3)].r; + depth[1] = LinearDepth[px * 4 + uint2(1, 3)].r; + depth[2] = LinearDepth[px * 4 + uint2(2, 3)].r; + depth[3] = LinearDepth[px * 4 + uint2(3, 3)].r; + sceneCoc = saturate(dofEqWorld.x * depth + dofEqWorld.y); + curCoc = sceneCoc; + coc = max(coc, curCoc); + + float maxCoc = max(max(coc[0], coc[1]), max(coc[2], coc[3])); + + DownsampledCoC[px] = float4(color, maxCoc); +} + +/* +Shader Resources: + Texture Color (as SRV) + Texture LinearDepth (as SRV) + Texture DownsampledCoC (as UAV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/IW2007/dof_gauss_blur.hlsl b/Techniques/PostProcessing/DepthOfField/IW2007/dof_gauss_blur.hlsl new file mode 100644 index 00000000..19b29f54 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/IW2007/dof_gauss_blur.hlsl @@ -0,0 +1,39 @@ +// Unnamed technique, shader GaussBlur +/*$(ShaderResources)*/ + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + // unlisted code from article + // Kernel calculated at http://demofox.org/gauss.html + // Sigma 1.0, Support 0.995 + static const int c_kernelSize = 5; + static const float c_kernel[c_kernelSize] = {0.3829f, 0.2417f, 0.0606f, 0.0060f, 0.0002f}; + + int2 px = int2(DTid.xy); + uint2 dims; + DownsampledCoC.GetDimensions(dims.x, dims.y); + + float4 sum = float4(0.0f, 0.0f, 0.0f, 0.0f); + float weight = 0.0f; + for (int iy = -c_kernelSize; iy <= c_kernelSize; ++iy) + { + for (int ix = -c_kernelSize; ix <= c_kernelSize; ++ix) + { + int2 readpx = px + int2(ix, iy); + if (readpx.x >= 0 && readpx.y >= 0 && readpx.x < dims.x && readpx.y < dims.y) + { + //uint2 readpx = uint2(px + int2(ix, iy) + int2(dims)) % dims; + sum += DownsampledCoC[readpx]; + weight += 1.0f; + } + } + } + + BlurredDownsampledCoC[px] = sum / weight; +} + +/* +Shader Resources: + Texture DownsampledCoC (as SRV) + Texture BlurredDownsampledCoC (as UAV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/IW2007/readme.txt b/Techniques/PostProcessing/DepthOfField/IW2007/readme.txt new file mode 100644 index 00000000..8692fe23 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/IW2007/readme.txt @@ -0,0 +1,3 @@ +implementation of gpu gems 3 chapter 28: Practical Post-Process Depth of Field +By Earl Hammon, Jr at Infinity Ward +https://developer.nvidia.com/gpugems/gpugems3/part-iv-image-effects/chapter-28-practical-post-process-depth-field \ No newline at end of file diff --git a/Techniques/PostProcessing/DepthOfField/dof_demo.gg b/Techniques/PostProcessing/DepthOfField/dof_demo.gg new file mode 100644 index 00000000..dcd15737 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/dof_demo.gg @@ -0,0 +1,959 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "variables": [ + { + "name": "RenderSize", + "type": "Uint2", + "dflt": "1024, 768", + "visibility": "User" + }, + { + "name": "sRGB", + "comment": "Set to true if the input texture is an sRGB texture", + "type": "Bool", + "dflt": "true", + "visibility": "User" + }, + { + "name": "ToneMapper", + "type": "Int", + "dflt": "ACES", + "visibility": "User", + "Enum": "ToneMappingOperation" + }, + { + "name": "ExposureFStops", + "type": "Float", + "dflt": "0.0f", + "visibility": "User" + }, + { + "name": "DepthNearPlane", + "type": "Float", + "dflt": "0.1f", + "visibility": "User" + }, + { + "name": "CameraPos", + "type": "Float3" + }, + { + "name": "InvViewProjMtx", + "type": "Float4x4" + }, + { + "name": "ViewProjMtx", + "type": "Float4x4" + }, + { + "name": "ViewMtx", + "type": "Float4x4" + }, + { + "name": "SpheresPositionStart", + "comment": "Where the spheres start. In world space.", + "type": "Float3", + "dflt": "-1300.000000,200.000000,-100.000000", + "visibility": "User" + }, + { + "name": "SpheresPositionEnd", + "comment": "Where the spheres end In world space.", + "type": "Float3", + "dflt": "-1300.000000,200.000000,-100.000000", + "visibility": "User" + }, + { + "name": "SphereCount", + "type": "Uint", + "dflt": "5", + "visibility": "User" + }, + { + "name": "SphereRadius", + "type": "Float", + "dflt": "10.0f", + "visibility": "User" + }, + { + "name": "SphereColor", + "type": "Float3", + "dflt": "1.0f, 1.0f, 1.0f", + "visibility": "User", + "UISettings": { + "UIHint": "Color" + } + }, + { + "name": "SphereBrightness", + "type": "Float", + "dflt": "10.0f", + "visibility": "User" + } + ], + "shaders": [ + { + "name": "VS", + "fileName": "dof_demo_vs.hlsl", + "type": "Vertex", + "entryPoint": "vsmain" + }, + { + "name": "PS", + "fileName": "dof_demo_ps.hlsl", + "type": "Pixel", + "entryPoint": "psmain", + "samplers": [ + { + "name": "linearWrapSampler" + } + ] + }, + { + "name": "Tonemap", + "fileName": "dof_demo_tonemap.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "HDR", + "type": "Texture", + "access": "SRV" + }, + { + "name": "SDR", + "type": "Texture", + "access": "UAV" + } + ] + }, + { + "name": "BrightLight", + "fileName": "dof_demo_brightlight.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "Color", + "type": "Texture", + "access": "UAV" + }, + { + "name": "LinearDepth", + "type": "Texture", + "access": "UAV", + "texture": { + "viewType": "Float" + } + } + ] + } + ], + "structs": [ + { + "name": "Vertex", + "fields": [ + { + "name": "Position", + "type": "Float3", + "semantic": "Position" + }, + { + "name": "Normal", + "type": "Float3", + "semantic": "Normal" + }, + { + "name": "UV", + "type": "Float2", + "semantic": "UV" + }, + { + "name": "MaterialID", + "type": "Int", + "semantic": "MaterialID" + } + ] + } + ], + "nodes": [ + { + "actionDrawCall": { + "name": "Draw Opaque", + "editorPos": [ + -57.0, + 4.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {} + ], + "vertexShader": { + "name": "VS" + }, + "pixelShader": { + "name": "PS" + }, + "depthTargetClear": true, + "depthTest": "Greater", + "colorTargetSettings": [ + { + "clear": true, + "writeChannels": [ + true, + true, + true, + false + ], + "srcBlend": "SrcAlpha", + "destBlend": "InvSrcAlpha" + }, + { + "clear": true, + "clearColor": [ + 0.0, + 1.0, + 1.0, + 1.0 + ] + }, + {}, + {}, + {}, + {}, + {}, + {} + ], + "defines": [ + { + "name": "OPAQUE_PASS", + "value": "1" + } + ], + "cullMode": "Back", + "frontIsCounterClockwise": false, + "vertexBuffer": { + "node": "VertexBuffer", + "pin": "resource" + }, + "colorTargets": [ + { + "node": "Color", + "pin": "resource" + }, + { + "node": "LinearDepth", + "pin": "resource" + }, + {}, + {}, + {}, + {}, + {}, + {} + ], + "depthTarget": { + "node": "Depth", + "pin": "resource" + } + } + }, + { + "resourceBuffer": { + "name": "VertexBuffer", + "editorPos": [ + -217.0, + 18.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "Color", + "editorPos": [ + -213.0, + 130.0 + ], + "format": { + "format": "RGBA32_Float" + }, + "size": { + "variable": { + "name": "RenderSize" + } + } + } + }, + { + "resourceTexture": { + "name": "Depth", + "editorPos": [ + -213.0, + 82.0 + ], + "format": { + "format": "D32_Float" + }, + "size": { + "variable": { + "name": "RenderSize" + } + } + } + }, + { + "resourceTexture": { + "name": "LinearDepth", + "editorPos": [ + -213.0, + 194.0 + ], + "format": { + "format": "R32_Float" + }, + "size": { + "variable": { + "name": "RenderSize" + } + } + } + }, + { + "actionDrawCall": { + "name": "Draw Transparent", + "editorPos": [ + 146.0, + 3.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {} + ], + "vertexShader": { + "name": "VS" + }, + "pixelShader": { + "name": "PS" + }, + "depthWrite": false, + "depthTest": "Greater", + "independentAlpha": true, + "colorTargetSettings": [ + { + "writeChannels": [ + true, + true, + true, + false + ], + "enableBlending": true, + "srcBlend": "SrcAlpha", + "destBlend": "InvSrcAlpha" + }, + { + "clearColor": [ + 0.0, + 1.0, + 1.0, + 1.0 + ], + "writeChannels": [ + false, + false, + false, + false + ] + }, + {}, + {}, + {}, + {}, + {}, + {} + ], + "defines": [ + { + "name": "OPAQUE_PASS", + "value": "0" + } + ], + "cullMode": "Back", + "frontIsCounterClockwise": false, + "vertexBuffer": { + "node": "Draw Opaque", + "pin": "vertexBuffer" + }, + "colorTargets": [ + { + "node": "Draw Opaque", + "pin": "colorTarget0" + }, + { + "node": "Draw Opaque", + "pin": "colorTarget1" + }, + {}, + {}, + {}, + {}, + {}, + {} + ], + "depthTarget": { + "node": "Draw Opaque", + "pin": "depthTarget" + } + } + }, + { + "actionSubGraph": { + "name": "IW2007", + "editorPos": [ + 609.0, + -52.0 + ], + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Color", + "dstNode": "BrightLight", + "dstPin": "Color" + }, + { + "srcPin": "LinearDepth", + "dstNode": "BrightLight", + "dstPin": "LinearDepth" + }, + { + "srcPin": "Output" + } + ], + "fileName": "IW2007\\dof.gg", + "subGraphData": { + "importedResources": [ + "Color", + "LinearDepth" + ], + "exportedResources": [ + "Output" + ], + "variables": [ + { + "name": "DepthScale", + "visibility": "User" + }, + { + "name": "EqNear", + "visibility": "User" + }, + { + "name": "EqFar", + "visibility": "User" + }, + { + "name": "FarToNearRadiusRatio", + "visibility": "User" + }, + { + "name": "fadeDistances", + "visibility": "User" + }, + { + "name": "sRGB", + "visibility": "User" + } + ] + }, + "variableSettings": [ + { + "name": "DepthScale", + "visibility": "User" + }, + { + "name": "EqNear", + "visibility": "User" + }, + { + "name": "EqFar", + "visibility": "User" + }, + { + "name": "FarToNearRadiusRatio", + "visibility": "User" + }, + { + "name": "fadeDistances", + "visibility": "User" + }, + { + "name": "sRGB", + "visibility": "User", + "replaceWithStr": "sRGB" + } + ] + } + }, + { + "actionSubGraph": { + "name": "Gustafsson2018", + "editorPos": [ + 608.0, + 98.0 + ], + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Color", + "dstNode": "BrightLight", + "dstPin": "Color" + }, + { + "srcPin": "LinearDepth", + "dstNode": "BrightLight", + "dstPin": "LinearDepth" + }, + { + "srcPin": "Output" + } + ], + "fileName": "Gustafsson2018\\dof.gg", + "subGraphData": { + "importedResources": [ + "Color", + "LinearDepth" + ], + "exportedResources": [ + "Output" + ], + "variables": [ + { + "name": "MaxBlurSize", + "visibility": "User" + }, + { + "name": "FocalLength", + "visibility": "User" + }, + { + "name": "FocusScale", + "visibility": "User" + }, + { + "name": "RadiusScale", + "visibility": "User" + }, + { + "name": "sRGB", + "visibility": "User" + } + ] + }, + "variableSettings": [ + { + "name": "MaxBlurSize", + "visibility": "User" + }, + { + "name": "FocalLength", + "visibility": "User" + }, + { + "name": "FocusScale", + "visibility": "User" + }, + { + "name": "RadiusScale", + "visibility": "User" + }, + { + "name": "sRGB", + "visibility": "User", + "replaceWithStr": "sRGB" + } + ] + } + }, + { + "actionComputeShader": { + "name": "IW2007Output", + "editorPos": [ + 757.0, + -14.0 + ], + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "HDR", + "dstNode": "IW2007", + "dstPin": "Output" + }, + { + "srcPin": "SDR", + "dstNode": "SDR1", + "dstPin": "resource" + } + ], + "shader": { + "name": "Tonemap" + }, + "dispatchSize": { + "node": { + "name": "Color" + } + } + } + }, + { + "actionComputeShader": { + "name": "Gustafsson2018Output", + "editorPos": [ + 757.0, + 140.0 + ], + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "HDR", + "dstNode": "Gustafsson2018", + "dstPin": "Output" + }, + { + "srcPin": "SDR", + "dstNode": "SDR2", + "dstPin": "resource" + } + ], + "shader": { + "name": "Tonemap" + }, + "dispatchSize": { + "node": { + "name": "Color" + } + } + } + }, + { + "resourceTexture": { + "name": "SDR1", + "editorPos": [ + 613.0, + 34.0 + ], + "format": { + "format": "RGBA8_Unorm_sRGB" + }, + "size": { + "node": { + "name": "Color" + } + } + } + }, + { + "resourceTexture": { + "name": "SDR2", + "editorPos": [ + 613.0, + 194.0 + ], + "format": { + "format": "RGBA8_Unorm_sRGB" + }, + "size": { + "node": { + "name": "Color" + } + } + } + }, + { + "actionComputeShader": { + "name": "BrightLight", + "editorPos": [ + 341.0, + 98.0 + ], + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "LinearDepth", + "dstNode": "Draw Transparent", + "dstPin": "colorTarget1" + }, + { + "srcPin": "Color", + "dstNode": "Draw Transparent", + "dstPin": "colorTarget0" + } + ], + "shader": { + "name": "BrightLight" + }, + "dispatchSize": { + "node": { + "name": "Color" + } + } + } + }, + { + "actionSubGraph": { + "name": "GatherDOF2018", + "editorPos": [ + 598.0, + 252.0 + ], + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Color", + "dstNode": "BrightLight", + "dstPin": "Color" + }, + { + "srcPin": "LinearDepth", + "dstNode": "BrightLight", + "dstPin": "LinearDepth" + }, + { + "srcPin": "Output" + } + ], + "fileName": "GatherDOF2018\\dof.gg", + "subGraphData": { + "importedResources": [ + "Color", + "LinearDepth" + ], + "exportedResources": [ + "Output" + ], + "variables": [ + { + "name": "FocalDistance", + "visibility": "User" + }, + { + "name": "FocalRegion", + "visibility": "User" + }, + { + "name": "FocalLength", + "visibility": "User" + }, + { + "name": "NearTransitionRegion", + "visibility": "User" + }, + { + "name": "FarTransitionRegion", + "visibility": "User" + }, + { + "name": "Scale", + "visibility": "User" + }, + { + "name": "DoFarField", + "visibility": "User" + }, + { + "name": "DoFarFieldFloodFill", + "visibility": "User" + }, + { + "name": "DoNearField", + "visibility": "User" + }, + { + "name": "DoNearFieldFloodFill", + "visibility": "User" + }, + { + "name": "KernelSize", + "visibility": "User" + }, + { + "name": "BlurTapCount", + "visibility": "User" + }, + { + "name": "FloodFillTapCount", + "visibility": "User" + }, + { + "name": "sRGB", + "visibility": "User" + } + ] + }, + "variableSettings": [ + { + "name": "FocalDistance", + "visibility": "User" + }, + { + "name": "FocalRegion", + "visibility": "User" + }, + { + "name": "FocalLength", + "visibility": "User" + }, + { + "name": "NearTransitionRegion", + "visibility": "User" + }, + { + "name": "FarTransitionRegion", + "visibility": "User" + }, + { + "name": "Scale", + "visibility": "User" + }, + { + "name": "DoFarField", + "visibility": "User" + }, + { + "name": "DoFarFieldFloodFill", + "visibility": "User" + }, + { + "name": "DoNearField", + "visibility": "User" + }, + { + "name": "DoNearFieldFloodFill", + "visibility": "User" + }, + { + "name": "KernelSize", + "visibility": "User" + }, + { + "name": "BlurTapCount", + "visibility": "User" + }, + { + "name": "FloodFillTapCount", + "visibility": "User" + }, + { + "name": "sRGB", + "visibility": "User", + "replaceWithStr": "sRGB" + } + ] + } + }, + { + "resourceTexture": { + "name": "SDR3", + "editorPos": [ + 619.0, + 354.0 + ], + "format": { + "format": "RGBA8_Unorm_sRGB" + }, + "size": { + "node": { + "name": "Color" + } + } + } + }, + { + "actionComputeShader": { + "name": "GatherDOF2018Output", + "editorPos": [ + 763.0, + 300.0 + ], + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "HDR", + "dstNode": "GatherDOF2018", + "dstPin": "Output" + }, + { + "srcPin": "SDR", + "dstNode": "SDR3", + "dstPin": "resource" + } + ], + "shader": { + "name": "Tonemap" + }, + "dispatchSize": { + "node": { + "name": "Color" + } + } + } + } + ], + "enums": [ + { + "name": "ToneMappingOperation", + "items": [ + { + "label": "None" + }, + { + "label": "Reinhard_Simple" + }, + { + "label": "ACES_Luminance" + }, + { + "label": "ACES" + } + ] + } + ] +} \ No newline at end of file diff --git a/Techniques/PostProcessing/DepthOfField/dof_demo.gguser b/Techniques/PostProcessing/DepthOfField/dof_demo.gguser new file mode 100644 index 00000000..805bcf44 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/dof_demo.gguser @@ -0,0 +1,1141 @@ +{ + "version": "2.0", + "systemVars": { + "camera": { + "farPlane": 10000.0, + "flySpeed": 10.0, + "startingCameraPos": [ + 725.8267211914063, + 152.89263916015626, + -64.2867660522461 + ], + "startingCameraAltitudeAzimuth": [ + 0.1963098794221878, + 1.832762360572815 + ] + }, + "ProjMtx_textureName": "Color" + }, + "snapshot": { + "resourceViewNodeIndex": 7, + "resourceViewResourceIndex": 3, + "cameraPos": [ + 725.8267211914063, + 152.89263916015626, + -64.2867660522461 + ], + "cameraAltitudeAzimuth": [ + 0.1963098794221878, + 1.832762360572815 + ], + "importedResources": [ + { + "nodeName": "VertexBuffer", + "isATexture": false, + "buffer": { + "fileName": "..\\..\\OBJAssets\\sponza\\sponza.obj", + "structIndex": 0, + "BLASOpaque": true + } + } + ], + "savedVariables": [ + { + "name": "RenderSize", + "value": "1024,768" + }, + { + "name": "sRGB", + "value": "false" + }, + { + "name": "ToneMapper", + "value": "0" + }, + { + "name": "ExposureFStops", + "value": "0.000000" + }, + { + "name": "DepthNearPlane", + "value": "0.100000" + }, + { + "name": "SpheresPositionStart", + "value": "-1300.000000,200.000000,0.000000" + }, + { + "name": "SpheresPositionEnd", + "value": "1300.000000,200.000000,100.000000" + }, + { + "name": "SphereCount", + "value": "5" + }, + { + "name": "SphereRadius", + "value": "5.000000" + }, + { + "name": "SphereColor", + "value": "1.000000,1.000000,1.000000" + }, + { + "name": "SphereBrightness", + "value": "2.000000" + }, + { + "name": "IW2007_DepthScale", + "value": "1000.000000" + }, + { + "name": "IW2007_EqNear", + "value": "-3.000000,1700.000000" + }, + { + "name": "IW2007_EqFar", + "value": "0.500000,-300.000000" + }, + { + "name": "IW2007_FarToNearRadiusRatio", + "value": "0.800000" + }, + { + "name": "IW2007_fadeDistances", + "value": "0.000000,0.500000,0.500000" + }, + { + "name": "Gustafsson2018_MaxBlurSize", + "value": "10.000000" + }, + { + "name": "Gustafsson2018_FocalLength", + "value": "500.000000" + }, + { + "name": "Gustafsson2018_FocusScale", + "value": "200.000000" + }, + { + "name": "Gustafsson2018_RadiusScale", + "value": "0.300000" + }, + { + "name": "GatherDOF2018_FocalDistance", + "value": "500.000000" + }, + { + "name": "GatherDOF2018_FocalRegion", + "value": "100.000000" + }, + { + "name": "GatherDOF2018_FocalLength", + "value": "75.000000" + }, + { + "name": "GatherDOF2018_NearTransitionRegion", + "value": "50.000000" + }, + { + "name": "GatherDOF2018_FarTransitionRegion", + "value": "200.000000" + }, + { + "name": "GatherDOF2018_Scale", + "value": "0.500000" + }, + { + "name": "GatherDOF2018_DoFarField", + "value": "true" + }, + { + "name": "GatherDOF2018_DoFarFieldFloodFill", + "value": "true" + }, + { + "name": "GatherDOF2018_DoNearField", + "value": "true" + }, + { + "name": "GatherDOF2018_DoNearFieldFloodFill", + "value": "true" + }, + { + "name": "GatherDOF2018_KernelSize", + "value": "10.000000,15.000000,5.000000,0.000000" + }, + { + "name": "GatherDOF2018_BlurTapCount", + "value": "8" + }, + { + "name": "GatherDOF2018_FloodFillTapCount", + "value": "4" + } + ] + }, + "snapshots": [ + { + "name": "IW2007", + "resourceViewNodeIndex": 6, + "resourceViewResourceIndex": 3, + "loadVars": false, + "loadCamera": false, + "loadResources": false, + "cameraPos": [ + 725.8267211914063, + 152.89263916015626, + -64.2867660522461 + ], + "cameraAltitudeAzimuth": [ + 0.1963098794221878, + 1.832762360572815 + ], + "importedResources": [ + { + "nodeName": "VertexBuffer", + "isATexture": false, + "buffer": { + "fileName": "..\\..\\OBJAssets\\sponza\\sponza.obj", + "structIndex": 0, + "BLASOpaque": true + } + } + ], + "savedVariables": [ + { + "name": "RenderSize", + "value": "1024,768" + }, + { + "name": "sRGB", + "value": "true" + }, + { + "name": "IW2007_DepthScale", + "value": "100.000000" + }, + { + "name": "IW2007_EqNear", + "value": "-2.000000,1700.000000" + }, + { + "name": "IW2007_EqFar", + "value": "1.000000,-500.000000" + }, + { + "name": "IW2007_FarToNearRadiusRatio", + "value": "1.000000" + }, + { + "name": "IW2007_fadeDistances", + "value": "0.000000,0.500000,0.500000" + }, + { + "name": "IW2007_sRGB", + "value": "true" + }, + { + "name": "Gustafsson2018_MaxBlurSize", + "value": "20.000000" + }, + { + "name": "Gustafsson2018_FocalLength", + "value": "500.000000" + }, + { + "name": "Gustafsson2018_FocusScale", + "value": "200.000000" + }, + { + "name": "Gustafsson2018_RadiusScale", + "value": "0.500000" + }, + { + "name": "Gustafsson2018_sRGB", + "value": "true" + }, + { + "name": "RenderSize", + "value": "1024,768" + }, + { + "name": "sRGB", + "value": "true" + }, + { + "name": "IW2007_DepthScale", + "value": "100.000000" + }, + { + "name": "IW2007_EqNear", + "value": "-2.000000,1700.000000" + }, + { + "name": "IW2007_EqFar", + "value": "1.000000,-500.000000" + }, + { + "name": "IW2007_FarToNearRadiusRatio", + "value": "1.000000" + }, + { + "name": "IW2007_fadeDistances", + "value": "0.000000,0.500000,0.500000" + }, + { + "name": "IW2007_sRGB", + "value": "true" + }, + { + "name": "Gustafsson2018_MaxBlurSize", + "value": "20.000000" + }, + { + "name": "Gustafsson2018_FocalLength", + "value": "500.000000" + }, + { + "name": "Gustafsson2018_FocusScale", + "value": "200.000000" + }, + { + "name": "Gustafsson2018_RadiusScale", + "value": "0.500000" + }, + { + "name": "Gustafsson2018_sRGB", + "value": "true" + }, + { + "name": "RenderSize", + "value": "1024,768" + }, + { + "name": "sRGB", + "value": "false" + }, + { + "name": "ToneMapper", + "value": "0" + }, + { + "name": "ExposureFStops", + "value": "0.000000" + }, + { + "name": "IW2007_DepthScale", + "value": "1000.000000" + }, + { + "name": "IW2007_EqNear", + "value": "-2.000000,1700.000000" + }, + { + "name": "IW2007_EqFar", + "value": "1.000000,-500.000000" + }, + { + "name": "IW2007_FarToNearRadiusRatio", + "value": "0.800000" + }, + { + "name": "IW2007_fadeDistances", + "value": "0.000000,0.500000,0.500000" + }, + { + "name": "Gustafsson2018_MaxBlurSize", + "value": "20.000000" + }, + { + "name": "Gustafsson2018_FocalLength", + "value": "500.000000" + }, + { + "name": "Gustafsson2018_FocusScale", + "value": "200.000000" + }, + { + "name": "Gustafsson2018_RadiusScale", + "value": "0.500000" + }, + { + "name": "RenderSize", + "value": "1024,768" + }, + { + "name": "sRGB", + "value": "false" + }, + { + "name": "ToneMapper", + "value": "0" + }, + { + "name": "ExposureFStops", + "value": "0.000000" + }, + { + "name": "DepthNearPlane", + "value": "0.100000" + }, + { + "name": "SpherePosition", + "value": "-1300.000000,200.000000,-100.000000" + }, + { + "name": "SphereRadius", + "value": "5.000000" + }, + { + "name": "SphereColor", + "value": "1.000000,1.000000,1.000000" + }, + { + "name": "SphereBrightness", + "value": "2.000000" + }, + { + "name": "IW2007_DepthScale", + "value": "1000.000000" + }, + { + "name": "IW2007_EqNear", + "value": "-2.000000,1700.000000" + }, + { + "name": "IW2007_EqFar", + "value": "1.000000,-500.000000" + }, + { + "name": "IW2007_FarToNearRadiusRatio", + "value": "0.800000" + }, + { + "name": "IW2007_fadeDistances", + "value": "0.000000,0.500000,0.500000" + }, + { + "name": "Gustafsson2018_MaxBlurSize", + "value": "20.000000" + }, + { + "name": "Gustafsson2018_FocalLength", + "value": "500.000000" + }, + { + "name": "Gustafsson2018_FocusScale", + "value": "200.000000" + }, + { + "name": "Gustafsson2018_RadiusScale", + "value": "0.100000" + }, + { + "name": "GatherDOF2018_FocalDistance", + "value": "500.000000" + }, + { + "name": "GatherDOF2018_FocalRegion", + "value": "100.000000" + }, + { + "name": "GatherDOF2018_FocalLength", + "value": "75.000000" + }, + { + "name": "GatherDOF2018_NearTransitionRegion", + "value": "50.000000" + }, + { + "name": "GatherDOF2018_FarTransitionRegion", + "value": "200.000000" + }, + { + "name": "GatherDOF2018_Scale", + "value": "0.500000" + }, + { + "name": "GatherDOF2018_DoFarField", + "value": "true" + }, + { + "name": "GatherDOF2018_DoFarFieldFloodFill", + "value": "true" + }, + { + "name": "GatherDOF2018_DoNearField", + "value": "true" + }, + { + "name": "GatherDOF2018_DoNearFieldFloodFill", + "value": "true" + }, + { + "name": "GatherDOF2018_MaxBokehSize", + "value": "10.000000" + }, + { + "name": "GatherDOF2018_KernelSize", + "value": "10.000000,15.000000,5.000000,0.000000" + } + ] + }, + { + "name": "Gustafsson2018", + "resourceViewNodeIndex": 7, + "resourceViewResourceIndex": 3, + "loadVars": false, + "loadCamera": false, + "loadResources": false, + "cameraPos": [ + 725.8267211914063, + 152.89263916015626, + -64.2867660522461 + ], + "cameraAltitudeAzimuth": [ + 0.1963098794221878, + 1.832762360572815 + ], + "importedResources": [ + { + "nodeName": "VertexBuffer", + "isATexture": false, + "buffer": { + "fileName": "..\\..\\OBJAssets\\sponza\\sponza.obj", + "structIndex": 0, + "BLASOpaque": true + } + } + ], + "savedVariables": [ + { + "name": "RenderSize", + "value": "1024,768" + }, + { + "name": "sRGB", + "value": "true" + }, + { + "name": "IW2007_DepthScale", + "value": "100.000000" + }, + { + "name": "IW2007_EqNear", + "value": "-2.000000,1700.000000" + }, + { + "name": "IW2007_EqFar", + "value": "1.000000,-500.000000" + }, + { + "name": "IW2007_FarToNearRadiusRatio", + "value": "1.000000" + }, + { + "name": "IW2007_fadeDistances", + "value": "0.000000,0.500000,0.500000" + }, + { + "name": "IW2007_sRGB", + "value": "true" + }, + { + "name": "Gustafsson2018_MaxBlurSize", + "value": "20.000000" + }, + { + "name": "Gustafsson2018_FocalLength", + "value": "500.000000" + }, + { + "name": "Gustafsson2018_FocusScale", + "value": "200.000000" + }, + { + "name": "Gustafsson2018_RadiusScale", + "value": "0.500000" + }, + { + "name": "Gustafsson2018_sRGB", + "value": "true" + }, + { + "name": "RenderSize", + "value": "1024,768" + }, + { + "name": "sRGB", + "value": "false" + }, + { + "name": "ToneMapper", + "value": "0" + }, + { + "name": "ExposureFStops", + "value": "0.000000" + }, + { + "name": "IW2007_DepthScale", + "value": "1000.000000" + }, + { + "name": "IW2007_EqNear", + "value": "-2.000000,1700.000000" + }, + { + "name": "IW2007_EqFar", + "value": "1.000000,-500.000000" + }, + { + "name": "IW2007_FarToNearRadiusRatio", + "value": "0.800000" + }, + { + "name": "IW2007_fadeDistances", + "value": "0.000000,0.500000,0.500000" + }, + { + "name": "Gustafsson2018_MaxBlurSize", + "value": "20.000000" + }, + { + "name": "Gustafsson2018_FocalLength", + "value": "500.000000" + }, + { + "name": "Gustafsson2018_FocusScale", + "value": "200.000000" + }, + { + "name": "Gustafsson2018_RadiusScale", + "value": "0.500000" + }, + { + "name": "RenderSize", + "value": "1024,768" + }, + { + "name": "sRGB", + "value": "false" + }, + { + "name": "ToneMapper", + "value": "0" + }, + { + "name": "ExposureFStops", + "value": "0.000000" + }, + { + "name": "DepthNearPlane", + "value": "0.100000" + }, + { + "name": "SpherePosition", + "value": "-1300.000000,200.000000,-100.000000" + }, + { + "name": "SphereRadius", + "value": "5.000000" + }, + { + "name": "SphereColor", + "value": "1.000000,1.000000,1.000000" + }, + { + "name": "SphereBrightness", + "value": "2.000000" + }, + { + "name": "IW2007_DepthScale", + "value": "1000.000000" + }, + { + "name": "IW2007_EqNear", + "value": "-2.000000,1700.000000" + }, + { + "name": "IW2007_EqFar", + "value": "1.000000,-500.000000" + }, + { + "name": "IW2007_FarToNearRadiusRatio", + "value": "0.800000" + }, + { + "name": "IW2007_fadeDistances", + "value": "0.000000,0.500000,0.500000" + }, + { + "name": "Gustafsson2018_MaxBlurSize", + "value": "20.000000" + }, + { + "name": "Gustafsson2018_FocalLength", + "value": "500.000000" + }, + { + "name": "Gustafsson2018_FocusScale", + "value": "200.000000" + }, + { + "name": "Gustafsson2018_RadiusScale", + "value": "0.100000" + }, + { + "name": "GatherDOF2018_FocalDistance", + "value": "500.000000" + }, + { + "name": "GatherDOF2018_FocalRegion", + "value": "100.000000" + }, + { + "name": "GatherDOF2018_FocalLength", + "value": "75.000000" + }, + { + "name": "GatherDOF2018_NearTransitionRegion", + "value": "50.000000" + }, + { + "name": "GatherDOF2018_FarTransitionRegion", + "value": "200.000000" + }, + { + "name": "GatherDOF2018_Scale", + "value": "0.500000" + }, + { + "name": "GatherDOF2018_DoFarField", + "value": "true" + }, + { + "name": "GatherDOF2018_DoFarFieldFloodFill", + "value": "true" + }, + { + "name": "GatherDOF2018_DoNearField", + "value": "true" + }, + { + "name": "GatherDOF2018_DoNearFieldFloodFill", + "value": "true" + }, + { + "name": "GatherDOF2018_MaxBokehSize", + "value": "10.000000" + }, + { + "name": "GatherDOF2018_KernelSize", + "value": "10.000000,15.000000,5.000000,0.000000" + } + ] + }, + { + "name": "GatherDOF2018", + "resourceViewNodeIndex": 12, + "resourceViewResourceIndex": 3, + "loadVars": false, + "loadCamera": false, + "loadResources": false, + "cameraPos": [ + 725.8267211914063, + 152.89263916015626, + -64.2867660522461 + ], + "cameraAltitudeAzimuth": [ + 0.1963098794221878, + 1.832762360572815 + ], + "importedResources": [ + { + "nodeName": "VertexBuffer", + "isATexture": false, + "buffer": { + "fileName": "..\\..\\OBJAssets\\sponza\\sponza.obj", + "structIndex": 0, + "BLASOpaque": true + } + } + ], + "savedVariables": [ + { + "name": "RenderSize", + "value": "1024,768" + }, + { + "name": "sRGB", + "value": "false" + }, + { + "name": "ToneMapper", + "value": "0" + }, + { + "name": "ExposureFStops", + "value": "0.000000" + }, + { + "name": "DepthNearPlane", + "value": "0.100000" + }, + { + "name": "SpherePosition", + "value": "-1300.000000,200.000000,-100.000000" + }, + { + "name": "SphereRadius", + "value": "5.000000" + }, + { + "name": "SphereColor", + "value": "1.000000,1.000000,1.000000" + }, + { + "name": "SphereBrightness", + "value": "2.000000" + }, + { + "name": "IW2007_DepthScale", + "value": "1000.000000" + }, + { + "name": "IW2007_EqNear", + "value": "-2.000000,1700.000000" + }, + { + "name": "IW2007_EqFar", + "value": "1.000000,-500.000000" + }, + { + "name": "IW2007_FarToNearRadiusRatio", + "value": "0.800000" + }, + { + "name": "IW2007_fadeDistances", + "value": "0.000000,0.500000,0.500000" + }, + { + "name": "Gustafsson2018_MaxBlurSize", + "value": "20.000000" + }, + { + "name": "Gustafsson2018_FocalLength", + "value": "500.000000" + }, + { + "name": "Gustafsson2018_FocusScale", + "value": "200.000000" + }, + { + "name": "Gustafsson2018_RadiusScale", + "value": "0.100000" + }, + { + "name": "GatherDOF2018_FocalDistance", + "value": "500.000000" + }, + { + "name": "GatherDOF2018_FocalRegion", + "value": "100.000000" + }, + { + "name": "GatherDOF2018_FocalLength", + "value": "100.000000" + }, + { + "name": "GatherDOF2018_NearTransitionRegion", + "value": "50.000000" + }, + { + "name": "GatherDOF2018_FarTransitionRegion", + "value": "200.000000" + }, + { + "name": "GatherDOF2018_Scale", + "value": "2.000000" + }, + { + "name": "GatherDOF2018_DoFarField", + "value": "true" + }, + { + "name": "GatherDOF2018_DoFarFieldFloodFill", + "value": "true" + }, + { + "name": "GatherDOF2018_DoNearField", + "value": "true" + }, + { + "name": "GatherDOF2018_DoNearFieldFloodFill", + "value": "true" + }, + { + "name": "GatherDOF2018_MaxBokehSize", + "value": "10.000000" + }, + { + "name": "GatherDOF2018_KernelSize", + "value": "10.000000,15.000000,5.000000,0.000000" + }, + { + "name": "RenderSize", + "value": "1024,768" + }, + { + "name": "sRGB", + "value": "false" + }, + { + "name": "ToneMapper", + "value": "0" + }, + { + "name": "ExposureFStops", + "value": "0.000000" + }, + { + "name": "DepthNearPlane", + "value": "0.100000" + }, + { + "name": "SpherePosition", + "value": "-1300.000000,200.000000,-100.000000" + }, + { + "name": "SphereRadius", + "value": "5.000000" + }, + { + "name": "SphereColor", + "value": "1.000000,1.000000,1.000000" + }, + { + "name": "SphereBrightness", + "value": "2.000000" + }, + { + "name": "IW2007_DepthScale", + "value": "1000.000000" + }, + { + "name": "IW2007_EqNear", + "value": "-2.000000,1700.000000" + }, + { + "name": "IW2007_EqFar", + "value": "1.000000,-500.000000" + }, + { + "name": "IW2007_FarToNearRadiusRatio", + "value": "0.800000" + }, + { + "name": "IW2007_fadeDistances", + "value": "0.000000,0.500000,0.500000" + }, + { + "name": "Gustafsson2018_MaxBlurSize", + "value": "20.000000" + }, + { + "name": "Gustafsson2018_FocalLength", + "value": "500.000000" + }, + { + "name": "Gustafsson2018_FocusScale", + "value": "200.000000" + }, + { + "name": "Gustafsson2018_RadiusScale", + "value": "0.100000" + }, + { + "name": "GatherDOF2018_FocalDistance", + "value": "500.000000" + }, + { + "name": "GatherDOF2018_FocalRegion", + "value": "100.000000" + }, + { + "name": "GatherDOF2018_FocalLength", + "value": "75.000000" + }, + { + "name": "GatherDOF2018_NearTransitionRegion", + "value": "50.000000" + }, + { + "name": "GatherDOF2018_FarTransitionRegion", + "value": "200.000000" + }, + { + "name": "GatherDOF2018_Scale", + "value": "0.500000" + }, + { + "name": "GatherDOF2018_DoFarField", + "value": "true" + }, + { + "name": "GatherDOF2018_DoFarFieldFloodFill", + "value": "true" + }, + { + "name": "GatherDOF2018_DoNearField", + "value": "true" + }, + { + "name": "GatherDOF2018_DoNearFieldFloodFill", + "value": "true" + }, + { + "name": "GatherDOF2018_MaxBokehSize", + "value": "10.000000" + }, + { + "name": "GatherDOF2018_KernelSize", + "value": "10.000000,15.000000,5.000000,0.000000" + }, + { + "name": "RenderSize", + "value": "1024,768" + }, + { + "name": "sRGB", + "value": "false" + }, + { + "name": "ToneMapper", + "value": "0" + }, + { + "name": "ExposureFStops", + "value": "0.000000" + }, + { + "name": "DepthNearPlane", + "value": "0.100000" + }, + { + "name": "SpheresPositionStart", + "value": "-1300.000000,200.000000,0.000000" + }, + { + "name": "SpheresPositionEnd", + "value": "1300.000000,200.000000,100.000000" + }, + { + "name": "SphereCount", + "value": "5" + }, + { + "name": "SphereRadius", + "value": "5.000000" + }, + { + "name": "SphereColor", + "value": "1.000000,1.000000,1.000000" + }, + { + "name": "SphereBrightness", + "value": "2.000000" + }, + { + "name": "IW2007_DepthScale", + "value": "1000.000000" + }, + { + "name": "IW2007_EqNear", + "value": "-2.000000,1700.000000" + }, + { + "name": "IW2007_EqFar", + "value": "1.000000,-500.000000" + }, + { + "name": "IW2007_FarToNearRadiusRatio", + "value": "0.800000" + }, + { + "name": "IW2007_fadeDistances", + "value": "0.000000,0.500000,0.500000" + }, + { + "name": "Gustafsson2018_MaxBlurSize", + "value": "20.000000" + }, + { + "name": "Gustafsson2018_FocalLength", + "value": "500.000000" + }, + { + "name": "Gustafsson2018_FocusScale", + "value": "200.000000" + }, + { + "name": "Gustafsson2018_RadiusScale", + "value": "0.100000" + }, + { + "name": "GatherDOF2018_FocalDistance", + "value": "500.000000" + }, + { + "name": "GatherDOF2018_FocalRegion", + "value": "100.000000" + }, + { + "name": "GatherDOF2018_FocalLength", + "value": "75.000000" + }, + { + "name": "GatherDOF2018_NearTransitionRegion", + "value": "50.000000" + }, + { + "name": "GatherDOF2018_FarTransitionRegion", + "value": "200.000000" + }, + { + "name": "GatherDOF2018_Scale", + "value": "0.500000" + }, + { + "name": "GatherDOF2018_DoFarField", + "value": "true" + }, + { + "name": "GatherDOF2018_DoFarFieldFloodFill", + "value": "true" + }, + { + "name": "GatherDOF2018_DoNearField", + "value": "true" + }, + { + "name": "GatherDOF2018_DoNearFieldFloodFill", + "value": "true" + }, + { + "name": "GatherDOF2018_KernelSize", + "value": "10.000000,15.000000,5.000000,0.000000" + }, + { + "name": "GatherDOF2018_BlurTapCount", + "value": "8" + }, + { + "name": "GatherDOF2018_FloodFillTapCount", + "value": "4" + } + ] + } + ] +} \ No newline at end of file diff --git a/Techniques/PostProcessing/DepthOfField/dof_demo_brightlight.hlsl b/Techniques/PostProcessing/DepthOfField/dof_demo_brightlight.hlsl new file mode 100644 index 00000000..c5b305df --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/dof_demo_brightlight.hlsl @@ -0,0 +1,86 @@ +// Unnamed technique, shader BrightLight +/*$(ShaderResources)*/ + +#define FLT_MAX 3.402823466e+38 + +// returns -1.0 on miss, else returns time to hit +float TestSphereTrace(in float3 rayPos, in float3 rayDir, in float4 sphere, out float3 normal) +{ + //get the vector from the center of this sphere to where the ray begins. + float3 m = rayPos - sphere.xyz; + + //get the dot product of the above vector and the ray's vector + float b = dot(m, rayDir); + + float c = dot(m, m) - sphere.w * sphere.w; + + //exit if r's origin outside s (c > 0) and r pointing away from s (b > 0) + if(c > 0.0 && b > 0.0) + return -1.0f; + + //calculate discriminant + float discr = b * b - c; + + //a negative discriminant corresponds to ray missing sphere + if(discr < 0.0) + return -1.0f; + + //ray now found to intersect sphere, compute smallest t value of intersection + bool fromInside = false; + float dist = -b - sqrt(discr); + if (dist < 0.0f) + { + fromInside = true; + dist = -b + sqrt(discr); + } + + normal = normalize((rayPos+rayDir*dist) - sphere.xyz) * (fromInside ? -1.0f : 1.0f); + + return dist; +} + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + uint2 px = DTid.xy; + + uint2 dims; + Color.GetDimensions(dims.x, dims.y); + + // Calculate a ray for this pixel + float2 screenPos = float2(px) / float2(dims) * 2.0 - 1.0; + screenPos.y = -screenPos.y; + + float4 world = mul(float4(screenPos, /*$(Variable:DepthNearPlane)*/, 1), /*$(Variable:InvViewProjMtx)*/); + world.xyz /= world.w; + + float3 rayPos = /*$(Variable:CameraPos)*/; + float3 rayDir = normalize(world.xyz - /*$(Variable:CameraPos)*/); + + // Shoot the ray at the spheres and compare hit time against depth buffer + float sphereHitT = FLT_MAX; + for (uint i = 0; i < /*$(Variable:SphereCount)*/; ++i) + { + float percent = (float(i) + 0.5f) / float(/*$(Variable:SphereCount)*/); + float3 spherePosition = lerp(/*$(Variable:SpheresPositionStart)*/, /*$(Variable:SpheresPositionEnd)*/, percent); + + float3 normal; + float hitT = TestSphereTrace(rayPos, rayDir, float4(spherePosition, /*$(Variable:SphereRadius)*/), normal); + if (hitT >= 0.0f) + sphereHitT = min(hitT, sphereHitT); + } + + // If no sphere hit, or none hit before the depth buffer value, nothing to do. + if (LinearDepth[px] < sphereHitT) + return; + + // draw the sphere hit to the color buffer and linear depth buffer + LinearDepth[px] = sphereHitT; + + Color[px] = float4(/*$(Variable:SphereColor)*/*/*$(Variable:SphereBrightness)*/, 1.0f); +} + +/* +Shader Resources: + Texture Color (as UAV) + Texture LinearDepth (as UAV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/dof_demo_ps.hlsl b/Techniques/PostProcessing/DepthOfField/dof_demo_ps.hlsl new file mode 100644 index 00000000..ca2d1a3b --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/dof_demo_ps.hlsl @@ -0,0 +1,165 @@ +// Unnamed technique, shader PS +/*$(ShaderResources)*/ + +struct PSInput // AKA VSOutput +{ + float4 position : SV_POSITION; + float2 UV : TEXCOORD0; + float3 normal : TEXCOORD1; + int materialID : TEXCOORD2; + float depth : TEXCOORD3; +}; + +struct PSOutput +{ + float4 colorTarget : SV_Target0; + float4 linearDepth : SV_Target1; +}; + +float4 ReadAlbedo(float2 UV, in Texture2D albedo, in Texture2D transparency) +{ + float4 ret; + ret.rgb = albedo.Sample(linearWrapSampler, UV).rgb; + ret.a = transparency.Sample(linearWrapSampler, UV); + return ret; +} + +float4 ReadAlbedo(float2 UV, in Texture2D albedo) +{ + float4 ret; + ret.rgb = albedo.Sample(linearWrapSampler, UV).rgb; + ret.a = 1.0f; + return ret; +} + + +PSOutput psmain(PSInput input) +{ + PSOutput ret = (PSOutput)0; + ret.linearDepth = input.depth; + + float4 albedo = float4(0.0f, 0.0f, 0.0f, 0.0f); + + // Textures should be in "..\..\OBJAssets\sponza\", but it doesn't copy them over correctly when doing that. + switch(input.materialID) + { + case 0: // leaf + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_thorn_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/, /*$(Image2D:textures\sponza_thorn_mask.png:R8_UNorm:float:false:true)*/); break; + + case 1: // vase_round + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\vase_round.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 2: // Material__57 + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\vase_plant.png:RGBA8_UNorm_SRGB:float4:true:true)*/, /*$(Image2D:textures\vase_plant_mask.png:R8_UNorm:float:false:true)*/); break; + + case 3: // Material__298 + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\background.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 4: // bricks + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\spnza_bricks_a_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 5: // arch + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_arch_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 6: // ceiling + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_ceiling_a_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 7: // column_a + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_column_a_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 8: // floor + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_floor_a_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 9: // column_c + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_column_c_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 10: // details + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_details_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 11: // column_b + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_column_b_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 12: // Material__47 + albedo = float4(0.0f, 0.0f, 0.0f, 0.0f); break; + + case 13: // flagpole + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_flagpole_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 14: // fabric_e + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_fabric_green_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 15: // fabric_d + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_fabric_blue_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 16: // fabric_a + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_fabric_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 17: // fabric_g + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_curtain_blue_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 18: // fabric_c + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_curtain_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 19: // fabric_f + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_curtain_green_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 20: // chain + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\chain_texture.png:RGBA8_UNorm_SRGB:float4:true:true)*/, /*$(Image2D:textures\chain_texture_mask.png:R8_UNorm:float:false:true)*/); break; + + case 21: // vase_hanging + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\vase_hanging.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 22: // vase + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\vase_dif.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 23: // Material__25 + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\lion.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + case 24: // roof + albedo = ReadAlbedo(input.UV, /*$(Image2D:textures\sponza_roof_diff.png:RGBA8_UNorm_SRGB:float4:true:true)*/); break; + + default: albedo = float4(1.0f, 0.0f, 1.0f, 1.0f); break; + } + + #if OPAQUE_PASS == 1 + if (albedo.a < 1.0f) + discard; + #else + if (albedo.a >= 1.0f) + discard; + #endif + + float3 lightDir = normalize(float3(0.2f, 1.0f, 0.3f)); + float3 lightColor = float3(1.0f, 1.0f, 1.0f); + float3 ambientLightColor = float3(0.1f, 0.1f, 0.1f); + + float3 color = albedo * (max(dot(input.normal, lightDir), 0.0f) * lightColor + ambientLightColor); + + ret.colorTarget = float4(color, albedo.a); + + return ret; +} + +/* +Info about obj format: https://paulbourke.net/dataformats/mtl/ + +Obj notes: +map_ka +map_kd +map_ks +map_ke +map_d +map_bump + +* bump (MASTER_Interior_01_Floor_Tile_Hexagonal_BLENDSHADER) +* d - transparency +* illum - illumination model +* ka - ambient color +* kd - diffuse color +* ks - specular color +* ke - emissive color +* Ni - refraction index +* Ns - specular exponent +* Tr - transparency (1-d) +* Tf - transmission color +*/ \ No newline at end of file diff --git a/Techniques/PostProcessing/DepthOfField/dof_demo_tonemap.hlsl b/Techniques/PostProcessing/DepthOfField/dof_demo_tonemap.hlsl new file mode 100644 index 00000000..fd37f9d2 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/dof_demo_tonemap.hlsl @@ -0,0 +1,124 @@ +// Unnamed technique, shader Tonemap +/*$(ShaderResources)*/ + +// https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ +float3 ACESFilm(float3 x) +{ + float a = 2.51f; + float b = 0.03f; + float c = 2.43f; + float d = 0.59f; + float e = 0.14f; + return saturate((x*(a*x+b))/(x*(c*x+d)+e)); +} + +// ============= ACES BEGIN +// https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl + +// The code in this file was originally written by Stephen Hill (@self_shadow), who deserves all +// credit for coming up with this fit and implementing it. Buy him a beer next time you see him. :) + +float3 LinearToSRGB(float3 linearCol) +{ + float3 sRGBLo = linearCol * 12.92; + float3 sRGBHi = (pow(abs(linearCol), float3(1.0 / 2.4, 1.0 / 2.4, 1.0 / 2.4)) * 1.055) - 0.055; + float3 sRGB; + sRGB.r = linearCol.r <= 0.0031308 ? sRGBLo.r : sRGBHi.r; + sRGB.g = linearCol.g <= 0.0031308 ? sRGBLo.g : sRGBHi.g; + sRGB.b = linearCol.b <= 0.0031308 ? sRGBLo.b : sRGBHi.b; + return sRGB; +} + +float3 SRGBToLinear(in float3 sRGBCol) +{ + float3 linearRGBLo = sRGBCol / 12.92; + float3 linearRGBHi = pow((sRGBCol + 0.055) / 1.055, float3(2.4, 2.4, 2.4)); + float3 linearRGB; + linearRGB.r = sRGBCol.r <= 0.04045 ? linearRGBLo.r : linearRGBHi.r; + linearRGB.g = sRGBCol.g <= 0.04045 ? linearRGBLo.g : linearRGBHi.g; + linearRGB.b = sRGBCol.b <= 0.04045 ? linearRGBLo.b : linearRGBHi.b; + return linearRGB; +} + +// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT +static const float3x3 ACESInputMat = +{ + {0.59719, 0.35458, 0.04823}, + {0.07600, 0.90834, 0.01566}, + {0.02840, 0.13383, 0.83777} +}; + +// ODT_SAT => XYZ => D60_2_D65 => sRGB +static const float3x3 ACESOutputMat = +{ + { 1.60475, -0.53108, -0.07367}, + {-0.10208, 1.10813, -0.00605}, + {-0.00327, -0.07276, 1.07602} +}; + +float3 RRTAndODTFit(float3 v) +{ + float3 a = v * (v + 0.0245786f) - 0.000090537f; + float3 b = v * (0.983729f * v + 0.4329510f) + 0.238081f; + return a / b; +} + +float3 ACESFitted(float3 color) +{ + color = mul(ACESInputMat, color); + + // Apply RRT and ODT + color = RRTAndODTFit(color); + + color = mul(ACESOutputMat, color); + + // Clamp to [0, 1] + color = saturate(color); + + return color; +} + +// ============= ACES END + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + uint2 px = DTid.xy; + + // convert exposure from FStops to a multiplier + float exposure = pow(2.0f, /*$(Variable:ExposureFStops)*/); + + float3 rgb = max(HDR[px].rgb * exposure, 0.0f); + + switch(/*$(Variable:ToneMapper)*/) + { + // Do nothing, only apply exposure + case ToneMappingOperation::None: break; + + // https://64.github.io/tonemapping/ + case ToneMappingOperation::Reinhard_Simple: + { + rgb = rgb / (1.0f + rgb); + break; + } + case ToneMappingOperation::ACES_Luminance: + { + // The * 0.6f is to undo the exposure baked in, per the author's instructions + rgb = ACESFilm(rgb * 0.6f); + break; + } + case ToneMappingOperation::ACES: + { + rgb = ACESFitted(rgb); + break; + } + } + + rgb = clamp(rgb, 0.0f, 1.0f); + SDR[px] = float4(LinearToSRGB(rgb), 1.0f); +} + +/* +Shader Resources: + Texture HDR (as SRV) + Texture SDR (as UAV) +*/ diff --git a/Techniques/PostProcessing/DepthOfField/dof_demo_vs.hlsl b/Techniques/PostProcessing/DepthOfField/dof_demo_vs.hlsl new file mode 100644 index 00000000..853957c5 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/dof_demo_vs.hlsl @@ -0,0 +1,33 @@ +// Unnamed technique, shader VS +/*$(ShaderResources)*/ + +struct VSInput +{ + float3 position : POSITION; + float3 normal : NORMAL; + float2 UV : TEXCOORD0; + int materialID : TEXCOORD1; +}; + +struct VSOutput // AKA PSInput +{ + float4 position : SV_POSITION; + float2 UV : TEXCOORD0; + float3 normal : TEXCOORD1; + int materialID : TEXCOORD2; + float depth : TEXCOORD3; +}; + +VSOutput vsmain(VSInput input) +{ + VSOutput ret = (VSOutput)0; + ret.position = mul(float4(input.position, 1.0f), /*$(Variable:ViewProjMtx)*/); + ret.UV = input.UV; + ret.normal = input.normal; + ret.materialID = input.materialID; + + float4 cameraPos = mul(float4(input.position, 1.0f), /*$(Variable:ViewMtx)*/); + ret.depth = cameraPos.z / cameraPos.w; + + return ret; +} diff --git a/Techniques/PostProcessing/DepthOfField/textures/background.png b/Techniques/PostProcessing/DepthOfField/textures/background.png new file mode 100644 index 00000000..e1695860 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/background.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21f5955648b003a0046ca16054aef2db07901d73662e8b8141e73ba551e06f87 +size 1279899 diff --git a/Techniques/PostProcessing/DepthOfField/textures/background_bump.png b/Techniques/PostProcessing/DepthOfField/textures/background_bump.png new file mode 100644 index 00000000..015e7413 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/background_bump.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c816df0108455787a9ffba973b01788d3cd2724dbfe1ff148dd1a51df37b2baa +size 211001 diff --git a/Techniques/PostProcessing/DepthOfField/textures/chain_texture.png b/Techniques/PostProcessing/DepthOfField/textures/chain_texture.png new file mode 100644 index 00000000..3a295b32 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/chain_texture.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5745cf634538333bcad860e5da4bd57d288166631aadc4b0268fc2103b152242 +size 374829 diff --git a/Techniques/PostProcessing/DepthOfField/textures/chain_texture_bump.png b/Techniques/PostProcessing/DepthOfField/textures/chain_texture_bump.png new file mode 100644 index 00000000..21e5ec96 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/chain_texture_bump.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2bcb283948533a96100cb90f1bffa4edb609c887b336ba21be12ec713430933e +size 37014 diff --git a/Techniques/PostProcessing/DepthOfField/textures/chain_texture_mask.png b/Techniques/PostProcessing/DepthOfField/textures/chain_texture_mask.png new file mode 100644 index 00000000..06d39d6d --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/chain_texture_mask.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:43c246a2de3b9bea28add7b188324765443e30223fcee13061719e2d357194e1 +size 1150 diff --git a/Techniques/PostProcessing/DepthOfField/textures/floor_gloss.png b/Techniques/PostProcessing/DepthOfField/textures/floor_gloss.png new file mode 100644 index 00000000..f1efd8bd --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/floor_gloss.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de0f989550e4cf7e0753c7480cd2b533ecb9d61b395033fbc3dbe71140aebaf2 +size 1419271 diff --git a/Techniques/PostProcessing/DepthOfField/textures/lion.png b/Techniques/PostProcessing/DepthOfField/textures/lion.png new file mode 100644 index 00000000..aa240202 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/lion.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13c763cb8d01e781121180a2f0c7ddc6c672d0a146ffc1359a5795dba99db5c2 +size 1685074 diff --git a/Techniques/PostProcessing/DepthOfField/textures/lion2_bump.png b/Techniques/PostProcessing/DepthOfField/textures/lion2_bump.png new file mode 100644 index 00000000..cbea1ad6 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/lion2_bump.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fcca6af06b7c7ca9b5ef0829db9ad7f2437ddaa2d6484d3811ad9a8b21a81ea3 +size 287706 diff --git a/Techniques/PostProcessing/DepthOfField/textures/lion_bump.png b/Techniques/PostProcessing/DepthOfField/textures/lion_bump.png new file mode 100644 index 00000000..cd778d30 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/lion_bump.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c9c6c4e42a9160f518f27af3755e8b45e0342882e422d3c6ecb397efcdc8acd +size 283932 diff --git a/Techniques/PostProcessing/DepthOfField/textures/spnza_bricks_a_bump.png b/Techniques/PostProcessing/DepthOfField/textures/spnza_bricks_a_bump.png new file mode 100644 index 00000000..e5b7083d --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/spnza_bricks_a_bump.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ce6e00a0d90f377b8f922f006b8078d72272259b1816e24d511302c0822dfd8 +size 613084 diff --git a/Techniques/PostProcessing/DepthOfField/textures/spnza_bricks_a_diff.png b/Techniques/PostProcessing/DepthOfField/textures/spnza_bricks_a_diff.png new file mode 100644 index 00000000..75e58a61 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/spnza_bricks_a_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6653d814e78df5b1d72bff0bc4f055b19f40c60125368c66f706862a77b11e19 +size 1850821 diff --git a/Techniques/PostProcessing/DepthOfField/textures/spnza_bricks_a_spec.png b/Techniques/PostProcessing/DepthOfField/textures/spnza_bricks_a_spec.png new file mode 100644 index 00000000..e22cd8c2 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/spnza_bricks_a_spec.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:07e6c0d154316dca9f06ac8f30e155786d1b4c9f4f75a5f57901f96338d452f7 +size 789292 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_arch_bump.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_arch_bump.png new file mode 100644 index 00000000..9292cf50 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_arch_bump.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ed13ea591ff9d0c4e950a372e59de8e95dd58af9d0f1fcc5794b87927e8d9ab +size 72484 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_arch_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_arch_diff.png new file mode 100644 index 00000000..b28417da --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_arch_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a2e127ce784d2d4f061eae58a780cdcc8daba6c0f254d06e5494e41d4874ff2 +size 1545689 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_arch_spec.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_arch_spec.png new file mode 100644 index 00000000..db24b7f4 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_arch_spec.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cff3751f78b5d8c59eb599477187c7ff2874a76140f442ed52a45e7def08e412 +size 519758 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_ceiling_a_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_ceiling_a_diff.png new file mode 100644 index 00000000..b1f55f83 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_ceiling_a_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d6ff12242bd2b0680c45b27d0234cb4fc636959a2575f29dd6eb02251348f4c +size 1748205 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_ceiling_a_spec.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_ceiling_a_spec.png new file mode 100644 index 00000000..6ebad647 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_ceiling_a_spec.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d8ae36a72774c51128a2810035377b08c7214b9fa1db6d0d4d2229162339828 +size 611209 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_column_a_bump.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_a_bump.png new file mode 100644 index 00000000..61c832e8 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_a_bump.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d88c0f98ac0d37a6c0759962bb797c3f1e9dbf976035308cde4cba92a1156b40 +size 314193 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_column_a_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_a_diff.png new file mode 100644 index 00000000..7d581544 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_a_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13c3511250c790ad260845ffd5d56f4622bb3760316831403c3cc182bcf40095 +size 1743092 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_column_a_spec.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_a_spec.png new file mode 100644 index 00000000..77581f96 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_a_spec.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66f596b9e37fdaf84b581bb671c40942d59f0dda3470f743b8cbe7928cbc4cab +size 624131 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_column_b_bump.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_b_bump.png new file mode 100644 index 00000000..d42366d0 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_b_bump.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a5f818c01f960fc43258e5be57c77b717209078a50758d43c6c61b89253c0395 +size 306062 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_column_b_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_b_diff.png new file mode 100644 index 00000000..99dc1c92 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_b_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e893c9f0a8ca1cb7b649476eaa6ce98ece4d82b447f2a9858dbf0be4ce05c8e1 +size 2127842 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_column_b_spec.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_b_spec.png new file mode 100644 index 00000000..130adfb9 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_b_spec.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6850e2de861b79d48722fd286f3726755d8d5f5f7c459e0600bc9f9f03c6f5fe +size 625709 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_column_c_bump.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_c_bump.png new file mode 100644 index 00000000..56c58ffc --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_c_bump.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25badc8f4f8ecb7f982265534d60fd0f0da961ee4f64abfafa8b31ec07534e27 +size 322713 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_column_c_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_c_diff.png new file mode 100644 index 00000000..7c7b0454 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_c_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eaf9050e0cb05bc5184b4fc7108085036e049ca6a3a93c0b11ed8e920831472d +size 2021589 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_column_c_spec.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_c_spec.png new file mode 100644 index 00000000..eb8bd90f --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_column_c_spec.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77641f66babf57ef10d36d4f4357d39b38c510779f87a3e63c0d797c40c425b7 +size 662176 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_curtain_blue_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_curtain_blue_diff.png new file mode 100644 index 00000000..0afcf9b9 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_curtain_blue_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:267f19cc7b95d665965f49117e6ef5cabc62ae65b5c921ca86c5f53ab5f55f97 +size 9202020 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_curtain_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_curtain_diff.png new file mode 100644 index 00000000..98d0d270 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_curtain_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dbe47dc0d50b3b5917d94f92c667a1068de776cf1b1af9f931358671a8e8a677 +size 8834304 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_curtain_green_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_curtain_green_diff.png new file mode 100644 index 00000000..3241c1df --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_curtain_green_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2a1141c908bbbcc66064ef0cd1888d26e4493560ca1a8add94ba96e4413ef0b5 +size 8325274 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_details_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_details_diff.png new file mode 100644 index 00000000..4b8f6202 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_details_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:01012e0e81c20b10856dd34476069aadf1270cedd47e13b2760ae7dec341a7ab +size 1342967 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_details_spec.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_details_spec.png new file mode 100644 index 00000000..da36d159 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_details_spec.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:405eb35e24f254a9ff4de6f8021f847e92af5d95ad91dfd5c88c239c0bbfeec0 +size 618549 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_blue_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_blue_diff.png new file mode 100644 index 00000000..9076f08c --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_blue_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7398d4f96ac101b92a42f8e093754fa239bb80e0038727e49574abed5473c20 +size 2097497 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_diff.png new file mode 100644 index 00000000..5d0dffb8 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1fe1ee45005ddcbcde414096c1018c9296e5dfed528ecc99f9ce7d82862fd963 +size 2208126 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_green_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_green_diff.png new file mode 100644 index 00000000..efcf8d11 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_green_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb009dd943c52da29e3d7dd4d30e12a912769ffc7659e97dba7a2483fa79c6c3 +size 2162350 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_purple.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_purple.png new file mode 100644 index 00000000..1b8b68d4 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_purple.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1de10bfe0c410f33e3a54aa4987bf7e7c209b3f00190779d1ce73001261bb294 +size 1104562 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_spec.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_spec.png new file mode 100644 index 00000000..ffbf88f6 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_fabric_spec.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f44c12f0749297ec5cfa73a6d867b8771cb366eb47233ff989c15f674e3573a0 +size 462762 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_flagpole_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_flagpole_diff.png new file mode 100644 index 00000000..74ada029 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_flagpole_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c65b8651f12a05063118a91bd2c1ebb37a403936bb2b79226cf842917ebfbcbe +size 1314735 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_flagpole_spec.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_flagpole_spec.png new file mode 100644 index 00000000..71e423ba --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_flagpole_spec.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e19367ea4099b185b86e9cbf932b54d2c7ec24ec4d7ed281adf8467d9be85af2 +size 597329 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_floor_a_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_floor_a_diff.png new file mode 100644 index 00000000..cfb4a235 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_floor_a_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ec677f8d95abc307a7551a501ed20c9cd79bbc38d41963a7d74a35d096d2f1c4 +size 1881715 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_floor_a_spec.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_floor_a_spec.png new file mode 100644 index 00000000..bd239723 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_floor_a_spec.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a46518c046ccb196bb25bc72c89546dca8625fc278de6a34256789e84d3cfdc +size 730796 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_roof_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_roof_diff.png new file mode 100644 index 00000000..3fda470d --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_roof_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be5c0e86671a709c5d2f87820f92414bf4c069c5041d2fb548f8bf130f7616dd +size 2280888 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_bump.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_bump.png new file mode 100644 index 00000000..98ba0b93 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_bump.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fddd9ab74a4ca2b63feba790102407aaeb1c3c675595f8836e9b97b783f7019c +size 35900 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_diff.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_diff.png new file mode 100644 index 00000000..a5f3256a --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_diff.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbe4564dcfbba7f225f6df00caa92365cf653d6bf496bb3da59b164fa1c84aac +size 450994 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_mask.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_mask.png new file mode 100644 index 00000000..f8797993 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_mask.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57f195177f3ff443e43eb7590859feb4c89164107ea69d6f26ee0a1deefa5c7b +size 68251 diff --git a/Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_spec.png b/Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_spec.png new file mode 100644 index 00000000..997cd52c --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/sponza_thorn_spec.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1576e5befee26cebb25be28626980e34d4cfd306968772b1359a8713c7d5cebc +size 360991 diff --git a/Techniques/PostProcessing/DepthOfField/textures/vase_bump.png b/Techniques/PostProcessing/DepthOfField/textures/vase_bump.png new file mode 100644 index 00000000..76e12c82 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/vase_bump.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e93b7ae479ffee85ea789c75cd4d12e96c813db73d914d13d3403ca379c0eb1f +size 431658 diff --git a/Techniques/PostProcessing/DepthOfField/textures/vase_dif.png b/Techniques/PostProcessing/DepthOfField/textures/vase_dif.png new file mode 100644 index 00000000..a4e2440a --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/vase_dif.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:141d957726bb80708e3210d481c82d4038016cc31e414c541eea76d61e600bd5 +size 1739865 diff --git a/Techniques/PostProcessing/DepthOfField/textures/vase_hanging.png b/Techniques/PostProcessing/DepthOfField/textures/vase_hanging.png new file mode 100644 index 00000000..9a5fb329 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/vase_hanging.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:310b171c5508c7f1df97cc87ebb2139141f4fbf6cd65d6cf1675e92ed64521b6 +size 1240906 diff --git a/Techniques/PostProcessing/DepthOfField/textures/vase_plant.png b/Techniques/PostProcessing/DepthOfField/textures/vase_plant.png new file mode 100644 index 00000000..ac8efb8a --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/vase_plant.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e3e7cdcc544beec19338b7e3f33e7814847b1e73294f4bae4c18d3740a7b1e1 +size 817124 diff --git a/Techniques/PostProcessing/DepthOfField/textures/vase_plant_mask.png b/Techniques/PostProcessing/DepthOfField/textures/vase_plant_mask.png new file mode 100644 index 00000000..89deb77a --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/vase_plant_mask.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d179d56d0750c9e64200bdc17b65c11ff8bda6a593f4d1453df05ade1a70927 +size 85746 diff --git a/Techniques/PostProcessing/DepthOfField/textures/vase_plant_spec.png b/Techniques/PostProcessing/DepthOfField/textures/vase_plant_spec.png new file mode 100644 index 00000000..ecfe3d11 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/vase_plant_spec.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b2332e35c817e17fe0185a6c246ac68bd38ad73c33372b86a887362a2e485402 +size 716987 diff --git a/Techniques/PostProcessing/DepthOfField/textures/vase_round.png b/Techniques/PostProcessing/DepthOfField/textures/vase_round.png new file mode 100644 index 00000000..95a252f9 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/vase_round.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ee2138dc016aff582e50c2725b7749cdf0681537147d3cd9034e0d10414fb7c +size 1798469 diff --git a/Techniques/PostProcessing/DepthOfField/textures/vase_round_bump.png b/Techniques/PostProcessing/DepthOfField/textures/vase_round_bump.png new file mode 100644 index 00000000..8473991e --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/vase_round_bump.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bf21985bf48a5392f7faba4e043b77582512cd88866c9b1cff4ec0939c19b1f +size 77501 diff --git a/Techniques/PostProcessing/DepthOfField/textures/vase_round_spec.png b/Techniques/PostProcessing/DepthOfField/textures/vase_round_spec.png new file mode 100644 index 00000000..81786d79 --- /dev/null +++ b/Techniques/PostProcessing/DepthOfField/textures/vase_round_spec.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dfe9e52cae7cf1fe654ca7088916e29405bde0150812ac419f0da74467c4db0a +size 1697907 diff --git a/Techniques/PostProcessing/GaussBlur/GaussBlur.gg b/Techniques/PostProcessing/GaussBlur/GaussBlur.gg new file mode 100644 index 00000000..c0e766ad --- /dev/null +++ b/Techniques/PostProcessing/GaussBlur/GaussBlur.gg @@ -0,0 +1,217 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "variables": [ + { + "name": "Sigma", + "comment": "Strength of blur. Standard deviation of gaussian distribution.", + "type": "Float", + "dflt": "1.0f", + "visibility": "User" + }, + { + "name": "Support", + "comment": "From 0 to 1. Controls the size of the filter by specifying how much of the Gaussian distribution to account for. 1 is infinitely large. 0.995 is more reasonable.", + "type": "Float", + "dflt": "0.995", + "visibility": "User" + }, + { + "name": "sRGB", + "comment": "set to true if input is an sRGB format texture", + "type": "Bool", + "dflt": "false", + "visibility": "User" + }, + { + "name": "Disable", + "type": "Bool", + "dflt": "false", + "visibility": "User" + } + ], + "shaders": [ + { + "name": "GaussBlurCS", + "fileName": "GaussBlurCS.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "Input", + "type": "Texture", + "access": "SRV" + }, + { + "name": "Output", + "type": "Texture", + "access": "UAV" + } + ] + } + ], + "nodes": [ + { + "actionComputeShader": { + "name": "DoBlurH", + "editorPos": [ + -31.0, + 1.0 + ], + "condition": { + "variable1": "Disable", + "comparison": "IsFalse" + }, + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Input", + "dstNode": "Input", + "dstPin": "resource" + }, + { + "srcPin": "Output", + "dstNode": "Temp", + "dstPin": "resource" + } + ], + "shader": { + "name": "GaussBlurCS" + }, + "dispatchSize": { + "node": { + "name": "Input" + } + }, + "defines": [ + { + "name": "BLURH", + "value": "1" + } + ] + } + }, + { + "resourceTexture": { + "name": "Input", + "editorPos": [ + -181.0, + -14.0 + ], + "visibility": "Imported" + } + }, + { + "resourceTexture": { + "name": "Output", + "editorPos": [ + 11.0, + 98.0 + ], + "visibility": "Exported", + "format": { + "node": { + "name": "Input" + } + }, + "size": { + "node": { + "name": "Input" + } + } + } + }, + { + "actionCopyResource": { + "name": "DontBlur", + "editorPos": [ + 324.0, + -1.0 + ], + "condition": { + "variable1": "Disable", + "comparison": "IsTrue" + }, + "linkProperties": [ + {}, + {} + ], + "source": { + "node": "DoBlurH", + "pin": "Input" + }, + "dest": { + "node": "DoBlurV", + "pin": "Output" + } + } + }, + { + "actionComputeShader": { + "name": "DoBlurV", + "editorPos": [ + 149.0, + 44.0 + ], + "condition": { + "variable1": "Disable", + "comparison": "IsFalse" + }, + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Input", + "dstNode": "DoBlurH", + "dstPin": "Output" + }, + { + "srcPin": "Output", + "dstNode": "Output", + "dstPin": "resource" + } + ], + "shader": { + "name": "GaussBlurCS" + }, + "dispatchSize": { + "node": { + "name": "Input" + } + }, + "defines": [ + { + "name": "BLURH", + "value": "0" + } + ] + } + }, + { + "resourceTexture": { + "name": "Temp", + "editorPos": [ + -181.0, + 50.0 + ], + "visibility": "Exported", + "format": { + "node": { + "name": "Input" + } + }, + "size": { + "node": { + "name": "Input" + } + } + } + } + ] +} \ No newline at end of file diff --git a/Techniques/PostProcessing/GaussBlur/GaussBlur.gguser b/Techniques/PostProcessing/GaussBlur/GaussBlur.gguser new file mode 100644 index 00000000..35ed5672 --- /dev/null +++ b/Techniques/PostProcessing/GaussBlur/GaussBlur.gguser @@ -0,0 +1,33 @@ +{ + "version": "2.0", + "snapshot": { + "resourceViewNodeIndex": 4, + "resourceViewResourceIndex": 3, + "importedResources": [ + { + "nodeName": "Input", + "texture": { + "fileName": "..\\..\\logo.png" + } + } + ], + "savedVariables": [ + { + "name": "Sigma", + "value": "2.000000" + }, + { + "name": "Support", + "value": "0.995000" + }, + { + "name": "sRGB", + "value": "true" + }, + { + "name": "Disable", + "value": "false" + } + ] + } +} \ No newline at end of file diff --git a/Techniques/PostProcessing/GaussBlur/GaussBlurCS.hlsl b/Techniques/PostProcessing/GaussBlur/GaussBlurCS.hlsl new file mode 100644 index 00000000..23986f1c --- /dev/null +++ b/Techniques/PostProcessing/GaussBlur/GaussBlurCS.hlsl @@ -0,0 +1,87 @@ +// Unnamed technique, shader GaussBlurCS +/*$(ShaderResources)*/ + +// Calculations adapted from http://demofox.org/gauss.html + +#define c_sigma /*$(Variable:Sigma)*/ +#define c_support /*$(Variable:Support)*/ + +float erf(float x) +{ + // save the sign of x + float sign = (x >= 0) ? 1 : -1; + x = abs(x); + + // constants + static const float a1 = 0.254829592; + static const float a2 = -0.284496736; + static const float a3 = 1.421413741; + static const float a4 = -1.453152027; + static const float a5 = 1.061405429; + static const float p = 0.3275911; + + // A&S formula 7.1.26 + float t = 1.0/(1.0 + p*x); + float y = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * exp(-x * x); + return sign * y; // erf(-x) = -erf(x); +} + +float IntegrateGaussian(float x, float sigma) +{ + float p1 = erf((x-0.5)/sigma*sqrt(0.5)); + float p2 = erf((x+0.5)/sigma*sqrt(0.5)); + return (p2-p1)/2.0; +} + +float3 LinearToSRGB(float3 linearCol) +{ + float3 sRGBLo = linearCol * 12.92; + float3 sRGBHi = (pow(abs(linearCol), float3(1.0 / 2.4, 1.0 / 2.4, 1.0 / 2.4)) * 1.055) - 0.055; + float3 sRGB; + sRGB.r = linearCol.r <= 0.0031308 ? sRGBLo.r : sRGBHi.r; + sRGB.g = linearCol.g <= 0.0031308 ? sRGBLo.g : sRGBHi.g; + sRGB.b = linearCol.b <= 0.0031308 ? sRGBLo.b : sRGBHi.b; + return sRGB; +} + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + int2 px = DTid.xy; + int2 maxPx; + Input.GetDimensions(maxPx.x, maxPx.y); + maxPx -= int2(1,1); + + // calculate radius of our blur based on sigma and support percentage + const int radius = int(ceil(sqrt(-2.0 * c_sigma * c_sigma * log(1.0 - c_support)))); + + // initialize values + float weight = 0.0f; + float3 color = float3(0.0f, 0.0f, 0.0f); + + // loop horizontally or vertically, as appropriate + for (int index = -radius; index <= radius; ++index) + { + float kernel = IntegrateGaussian(index, c_sigma); + + int2 offset = (BLURH) ? int2(index, 0) : int2(0, index); + + int2 readPx = clamp(px + offset, int2(0, 0), maxPx); + + color += Input[readPx].rgb * kernel; + weight += kernel; + } + + // normalize blur + color /= weight; + + if (/*$(Variable:sRGB)*/) + color = LinearToSRGB(color); + + Output[px] = float4(color, 1.0f); +} + +/* +Shader Resources: + Texture Input (as SRV) + Texture Output (as UAV) +*/ diff --git a/Techniques/PostProcessing/TemporalAccumulation/Accumulate.hlsl b/Techniques/PostProcessing/TemporalAccumulation/Accumulate.hlsl new file mode 100644 index 00000000..c1dd43fb --- /dev/null +++ b/Techniques/PostProcessing/TemporalAccumulation/Accumulate.hlsl @@ -0,0 +1,22 @@ +// Unnamed technique, shader TemporalAccum +/*$(ShaderResources)*/ + +/*$(_compute:csmain)*/(uint3 DTid : SV_DispatchThreadID) +{ + float alpha = (/*$(Variable:Reset)*/ || !/*$(Variable:Enabled)*/) + ? 1.0f + : /*$(Variable:Alpha)*/; + + uint2 px = DTid.xy; + + float4 oldValue = Accum[px]; + float4 newValue = Input[px]; + + Accum[px] = lerp(oldValue, newValue, alpha); +} + +/* +Shader Resources: + Texture Input (as SRV) + Texture Accum (as UAV) +*/ diff --git a/Techniques/PostProcessing/TemporalAccumulation/TemporalAccumulation.gg b/Techniques/PostProcessing/TemporalAccumulation/TemporalAccumulation.gg new file mode 100644 index 00000000..4952af9b --- /dev/null +++ b/Techniques/PostProcessing/TemporalAccumulation/TemporalAccumulation.gg @@ -0,0 +1,114 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "variables": [ + { + "name": "Alpha", + "comment": "For exponential moving average. From 0 to 1. TAA commonly uses 0.1.", + "type": "Float", + "dflt": "0.1f", + "visibility": "User" + }, + { + "name": "Enabled", + "type": "Bool", + "dflt": "true", + "visibility": "User" + }, + { + "name": "Reset", + "type": "Bool", + "dflt": "false", + "visibility": "User", + "UISettings": { + "UIHint": "Button" + } + } + ], + "shaders": [ + { + "name": "Accumulate", + "fileName": "Accumulate.hlsl", + "entryPoint": "csmain", + "resources": [ + { + "name": "Input", + "type": "Texture", + "access": "SRV" + }, + { + "name": "Accum", + "type": "Texture", + "access": "UAV" + } + ] + } + ], + "nodes": [ + { + "resourceTexture": { + "name": "Input", + "editorPos": [ + -37.0, + -14.0 + ], + "visibility": "Imported" + } + }, + { + "actionComputeShader": { + "name": "DoAccum", + "editorPos": [ + 75.0, + 2.0 + ], + "linkProperties": [ + {}, + {}, + {} + ], + "connections": [ + { + "srcPin": "Input", + "dstNode": "Input", + "dstPin": "resource" + }, + { + "srcPin": "Accum", + "dstNode": "Accum", + "dstPin": "resource" + } + ], + "shader": { + "name": "Accumulate" + }, + "dispatchSize": { + "node": { + "name": "Input" + } + } + } + }, + { + "resourceTexture": { + "name": "Accum", + "editorPos": [ + -37.0, + 50.0 + ], + "transient": false, + "visibility": "Exported", + "format": { + "node": { + "name": "Input" + } + }, + "size": { + "node": { + "name": "Input" + } + } + } + } + ] +} \ No newline at end of file diff --git a/Techniques/UnitTests/ShaderAssert/assertFormatting.gg b/Techniques/UnitTests/ShaderAssert/assertFormatting.gg new file mode 100644 index 00000000..f95a4f20 --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/assertFormatting.gg @@ -0,0 +1,28 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "shaders": [ + { + "name": "assertFormatting_CS", + "fileName": "assertFormatting_cs.hlsl", + "entryPoint": "main_cs" + } + ], + "nodes": [ + { + "actionComputeShader": { + "name": "Node 1", + "editorPos": [ + 492.0, + 1145.0 + ], + "linkProperties": [ + {} + ], + "shader": { + "name": "AssertFormatting_CS" + } + } + } + ] +} \ No newline at end of file diff --git a/Techniques/UnitTests/ShaderAssert/assertFormatting_cs.hlsl b/Techniques/UnitTests/ShaderAssert/assertFormatting_cs.hlsl new file mode 100644 index 00000000..de6f5405 --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/assertFormatting_cs.hlsl @@ -0,0 +1,13 @@ +// Unnamed technique, shader simpleAssertYES_cs +/*$(ShaderResources)*/ + +/*$(_compute:main_cs)*/(uint3 DTid : SV_DispatchThreadID) +{ + float v0 = 1.1; + float v1 = 1.2; + float v2 = 1.3; + float v3 = 1.4; + float v4 = 1.5; + float v5 = 1.6; + /*$(Assert: 1>4, "v0:%.1f v1:%.1f v2:%.1f v3:%.1f v4:%.1f v5:%.1f", v0, v1, v2, v3, v4, v5 )*/ +} diff --git a/Techniques/UnitTests/ShaderAssert/assertsTest.py b/Techniques/UnitTests/ShaderAssert/assertsTest.py new file mode 100644 index 00000000..e6129445 --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/assertsTest.py @@ -0,0 +1,175 @@ +import Host + +# don't save gguser files during this script execution +Host.DisableGGUserSave(True) + +class AssertInfo: + def __init__(self, assertId = -1): + if assertId >= 0: + self.fmtId = Host.GetShaderAssertFormatStrId(assertId) + self.msg = Host.GetShaderAssertMsg(assertId) + self.displayName = Host.GetShaderAssertDisplayName(assertId) + else: + self.fmtId = 0 + self.msg = '' + self.displayName = '' + + def __eq__(self, r): + return self.fmtId == r.fmtId and self.msg == r.msg and self.displayName == r.displayName + + @staticmethod + def construct(fmtId, msg, displayName): + a = AssertInfo() + a.fmtId = fmtId + a.msg = msg + a.displayName = displayName + return a + + def __str__(self) : + return f"\nAssert:{{\n DisplayName:{self.displayName}, \n msg:{self.msg}, \n fmtId:{self.fmtId}\n}}" + +def getCollectedAsserts(): + assertsCount = Host.GetCollectedShaderAssertsCount() + return [AssertInfo(assertId) for assertId in range(0, assertsCount)] + +def assertsToStr(asserts): + return '\n'.join([f"{a}" for a in asserts]) + +def runTechniques(): + #skip frame in flight + Host.RunTechnique() + Host.RunTechnique() + Host.RunTechnique() + +Tasks = [ + { + 'name' : "TEST BASIC ASSERT: VS:YES, PS:YES", + 'gg' : "Techniques/UnitTests/ShaderAssert/simpleAssertVsYesPsYes.gg", + 'expected' : { + 'asserts' : [ + AssertInfo.construct(0, "\"VS\"", "Node_1.__simpleAssertYES_VS__GigiAssertUAV"), + AssertInfo.construct(1, "\"PS\"", "Node_1.__simpleAssertYES_PS__GigiAssertUAV") + ], + } + }, + { + 'name' : "TEST BASIC ASSERT: VS:NO, PS:YES", + 'gg' : "Techniques/UnitTests/ShaderAssert/simpleAssertVsNoPsYes.gg", + 'expected' : { + 'asserts' : [ + AssertInfo.construct(1, "\"PS\"", "Node_1.__simpleAssertYES_PS__GigiAssertUAV") + ], + } + }, + { + 'name' : "TEST BASIC ASSERT: CS:YES", + 'gg' : "Techniques/UnitTests/ShaderAssert/simpleAssertCsYes.gg", + 'expected' : { + 'asserts' : [ + AssertInfo.construct(0, "\"CS\"", "Node_1.__simpleAssertYES_CS__GigiAssertUAV") + ], + } + }, + { + 'name' : "ASSERT FORMATTING: COMPLEX FMT", + 'gg' : "Techniques/UnitTests/ShaderAssert/assertFormatting.gg", + 'expected' : { + 'asserts' : [ + AssertInfo.construct(0, "\"v0:1.1 v1:1.2 v2:1.3 v3:1.4 v4:1.5 v5:1.6\"", "Node_1.__assertFormatting_CS__GigiAssertUAV") + ], + } + }, + { + 'name' : "ASSERT FORMATTING: NO FMT STRING", + 'gg' : "Techniques/UnitTests/ShaderAssert/noFmtStringAssert.gg", + 'expected' : { + 'asserts' : [ + AssertInfo.construct(0, "1>4", "Node_1.__noFmtStringAssert_CS__GigiAssertUAV") + ], + } + }, + { + 'name' : "SAME CS SHADER AND SUBGRAPH", + 'gg' : "Techniques/UnitTests/ShaderAssert/sameShaderWithSubgraphs.gg", + 'expected' : { + 'asserts' : [ + AssertInfo.construct(0, "1>4", "MainNode.__noFmtStringAssert_CS__GigiAssertUAV"), + AssertInfo.construct(0, "1>4", "SubGraphNode_InsideSubGraphNode.__SubGraphNode_noFmtStringAssert_CS__GigiAssertUAV") + ], + } + }, +] + +def DoTask(task, i): + name = task['name'] + + Host.Log("Info", f"Processing Assert test '{name} [{i+1}/{len(Tasks)}]'") + + if not Host.LoadGG(task['gg']): + return [False, f"Failed to load {task['gg']}"] + + runTechniques() + Host.WaitOnGPU() + + expected = task['expected'] + + collectedAsserts = getCollectedAsserts() + expectedAssertsCount = len(expected['asserts']) + + if not expectedAssertsCount == len(collectedAsserts): + return [False, f"Wrong fired asserts count expected:{expectedAssertsCount}," + + f"got:{len(collectedAsserts)}.\n\nFIRED ASSERTS: {assertsToStr(collectedAsserts)}" + + f"\n\nEXPECTED ASSERTS: {assertsToStr(expected['asserts'])}" + ] + + invalidAsserts = [] + for i in range(0, len(collectedAsserts)): + expectedAssert = expected['asserts'][i] + collectedAssert = collectedAsserts[i] + if not expectedAssert == collectedAssert: + invalidAsserts.append([i, expectedAssert, collectedAssert]) + + if len(invalidAsserts) != 0: + header = '\n------' + return [False, f"Unexpected asserts:\n" + + header + + header.join([f"\n i:{a[0]}\n EXPECTED:\n{a[1]}\n GOT:{a[2]}\n" for a in invalidAsserts])] + + + return [True, ''] + +def DoTasks(): + totalTasks = len(Tasks) + + failedTasks = [] + for i in range(0, totalTasks): + task = Tasks[i] + res = DoTask(task, i) + if res[0] == False: + failedTasks.append([task, res[1]]) + + failedTasksCount = len(failedTasks) + if failedTasksCount > 0: + header = '\n-----------------------' + resultStr = header + header.join( + [f"\nFAILED_ASSERT_TASK:\n name:{failedTasks[i][0]['name']}\n gg: {failedTasks[i][0]['gg']}\n msg: {failedTasks[i][1]}" for i in range(0, len(failedTasks))] + ) + Host.Log("Error", f"\nShader Asserts failed tasks [{len(failedTasks)}/{totalTasks}]\n {resultStr}") + return False + + return True + +def DoTest(): + Host.SetShaderAssertsLogging(False) + TestPassed = DoTasks() + Host.Log("Info", f"Finished processing of the {len(Tasks)} Shader Assert tests") + Host.SetShaderAssertsLogging(True) + + return TestPassed + +# This is so the test can be ran by itself directly +if __name__ == "builtins": + if DoTest(): + Host.Log("Info", "test Passed") + else: + Host.Log("Error", "Test Failed") diff --git a/Techniques/UnitTests/ShaderAssert/noFmtStringAssert.gg b/Techniques/UnitTests/ShaderAssert/noFmtStringAssert.gg new file mode 100644 index 00000000..6772bb93 --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/noFmtStringAssert.gg @@ -0,0 +1,28 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "shaders": [ + { + "name": "noFmtStringAssert_CS", + "fileName": "noFmtStringAssert_cs.hlsl", + "entryPoint": "main_cs" + } + ], + "nodes": [ + { + "actionComputeShader": { + "name": "Node 1", + "editorPos": [ + -101.0, + -30.0 + ], + "linkProperties": [ + {} + ], + "shader": { + "name": "noFmtStringAssert_CS" + } + } + } + ] +} \ No newline at end of file diff --git a/Techniques/UnitTests/ShaderAssert/noFmtStringAssertWithStub_cs.hlsl b/Techniques/UnitTests/ShaderAssert/noFmtStringAssertWithStub_cs.hlsl new file mode 100644 index 00000000..8775fcf9 --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/noFmtStringAssertWithStub_cs.hlsl @@ -0,0 +1,9 @@ +// Unnamed technique, shader simpleAssertYES_cs +/*$(ShaderResources)*/ + +/*$(_compute:main_cs)*/(uint3 DTid : SV_DispatchThreadID) +{ + /*$(Assert:1>4)*/ + uint dim, stride; + stub_uav.GetDimensions(dim, stride); +} diff --git a/Techniques/UnitTests/ShaderAssert/noFmtStringAssert_cs.hlsl b/Techniques/UnitTests/ShaderAssert/noFmtStringAssert_cs.hlsl new file mode 100644 index 00000000..ea93b1cd --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/noFmtStringAssert_cs.hlsl @@ -0,0 +1,7 @@ +// Unnamed technique, shader simpleAssertYES_cs +/*$(ShaderResources)*/ + +/*$(_compute:main_cs)*/(uint3 DTid : SV_DispatchThreadID) +{ + /*$(Assert:1>4)*/ +} diff --git a/Techniques/UnitTests/ShaderAssert/noFmtStringSubgraph.gg b/Techniques/UnitTests/ShaderAssert/noFmtStringSubgraph.gg new file mode 100644 index 00000000..7186a63d --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/noFmtStringSubgraph.gg @@ -0,0 +1,56 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "shaders": [ + { + "name": "noFmtStringAssert_CS", + "fileName": "noFmtStringAssertWithStub_cs.hlsl", + "entryPoint": "main_cs", + "resources": [ + { + "name": "stub_uav", + "type": "Buffer", + "access": "UAV", + "buffer": { + "type": "Float" + } + } + ] + } + ], + "nodes": [ + { + "actionComputeShader": { + "name": "InsideSubGraphNode", + "editorPos": [ + -37.0, + 18.0 + ], + "linkProperties": [ + {}, + {} + ], + "connections": [ + { + "srcPin": "stub_uav", + "dstNode": "stub_res_node", + "dstPin": "resource" + } + ], + "shader": { + "name": "noFmtStringAssert_CS" + } + } + }, + { + "resourceBuffer": { + "name": "stub_res_node", + "editorPos": [ + -165.0, + 18.0 + ], + "visibility": "Imported" + } + } + ] +} \ No newline at end of file diff --git a/Techniques/UnitTests/ShaderAssert/sameShaderWithSubgraphs.gg b/Techniques/UnitTests/ShaderAssert/sameShaderWithSubgraphs.gg new file mode 100644 index 00000000..54fa6a94 --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/sameShaderWithSubgraphs.gg @@ -0,0 +1,83 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "shaders": [ + { + "name": "noFmtStringAssert_CS", + "fileName": "noFmtStringAssertWithStub_cs.hlsl", + "entryPoint": "main_cs", + "resources": [ + { + "name": "stub_uav", + "type": "Buffer", + "access": "UAV", + "buffer": { + "type": "Float" + } + } + ] + } + ], + "nodes": [ + { + "actionComputeShader": { + "name": "MainNode", + "editorPos": [ + -91.0, + 18.0 + ], + "linkProperties": [ + {}, + {} + ], + "connections": [ + { + "srcPin": "stub_uav", + "dstNode": "Node 2", + "dstPin": "resource" + } + ], + "shader": { + "name": "noFmtStringAssert_CS" + } + } + }, + { + "resourceBuffer": { + "name": "Node 2", + "editorPos": [ + -245.0, + 82.0 + ], + "format": { + "type": "Float" + } + } + }, + { + "actionSubGraph": { + "name": "SubGraphNode", + "editorPos": [ + 132.0, + 2.0 + ], + "linkProperties": [ + {} + ], + "connections": [ + { + "srcPin": "stub_res_node", + "dstNode": "MainNode", + "dstPin": "stub_uav" + } + ], + "fileName": "noFmtStringSubgraph.gg", + "subGraphData": { + "importedResources": [ + "stub_res_node" + ] + } + } + } + ] +} \ No newline at end of file diff --git a/Techniques/UnitTests/ShaderAssert/sameShaderWithSubgraphs.gguser b/Techniques/UnitTests/ShaderAssert/sameShaderWithSubgraphs.gguser new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/sameShaderWithSubgraphs.gguser @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/Techniques/UnitTests/ShaderAssert/simpleAssertCsYes.gg b/Techniques/UnitTests/ShaderAssert/simpleAssertCsYes.gg new file mode 100644 index 00000000..392bb795 --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/simpleAssertCsYes.gg @@ -0,0 +1,28 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "shaders": [ + { + "name": "simpleAssertYES_CS", + "fileName": "simpleAssertYES_cs.hlsl", + "entryPoint": "main_cs" + } + ], + "nodes": [ + { + "actionComputeShader": { + "name": "Node 1", + "editorPos": [ + 534.0, + 1151.0 + ], + "linkProperties": [ + {} + ], + "shader": { + "name": "simpleAssertYES_CS" + } + } + } + ] +} \ No newline at end of file diff --git a/Techniques/UnitTests/ShaderAssert/simpleAssertNO_vs.hlsl b/Techniques/UnitTests/ShaderAssert/simpleAssertNO_vs.hlsl new file mode 100644 index 00000000..6fa06677 --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/simpleAssertNO_vs.hlsl @@ -0,0 +1,15 @@ +// Unnamed technique, shader simpleAssertYES_VS +/*$(ShaderResources)*/ + +struct VSOutput // AKA PSInput +{ + float4 position : SV_POSITION; +}; + +VSOutput main_vs() +{ + /*$(Assert: 1<2, "VS")*/ + + VSOutput ret = (VSOutput)0; + return ret; +} diff --git a/Techniques/UnitTests/ShaderAssert/simpleAssertVsNoPsYes.gg b/Techniques/UnitTests/ShaderAssert/simpleAssertVsNoPsYes.gg new file mode 100644 index 00000000..41d9ff20 --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/simpleAssertVsNoPsYes.gg @@ -0,0 +1,80 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "shaders": [ + { + "name": "simpleAssertNO_VS", + "fileName": "simpleAssertNO_vs.hlsl", + "type": "Vertex", + "entryPoint": "main_vs" + }, + { + "name": "simpleAssertYES_PS", + "fileName": "simpleAssertYES_ps.hlsl", + "type": "Pixel", + "entryPoint": "main_ps" + } + ], + "nodes": [ + { + "actionDrawCall": { + "name": "Node 1", + "editorPos": [ + 612.0, + 1063.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {}, + {}, + {}, + {} + ], + "vertexShader": { + "name": "simpleAssertNO_VS" + }, + "pixelShader": { + "name": "simpleAssertYES_PS" + }, + "countPerInstance": 4, + "depthWrite": false, + "colorTargets": [ + { + "node": "Node 2", + "pin": "resource" + }, + {}, + {}, + {}, + {}, + {}, + {}, + {} + ], + "geometryType": "PointList" + } + }, + { + "resourceTexture": { + "name": "Node 2", + "editorPos": [ + 443.0, + 1170.0 + ], + "visibility": "Exported", + "format": { + "format": "RGBA8_Unorm" + }, + "size": { + "multiply": [ + 256, + 256, + 1 + ] + } + } + } + ] +} \ No newline at end of file diff --git a/Techniques/UnitTests/ShaderAssert/simpleAssertVsNoPsYes.gguser b/Techniques/UnitTests/ShaderAssert/simpleAssertVsNoPsYes.gguser new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/simpleAssertVsNoPsYes.gguser @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/Techniques/UnitTests/ShaderAssert/simpleAssertVsYesPsYes.gg b/Techniques/UnitTests/ShaderAssert/simpleAssertVsYesPsYes.gg new file mode 100644 index 00000000..7ec38ab5 --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/simpleAssertVsYesPsYes.gg @@ -0,0 +1,80 @@ +{ + "$schema": "gigischema.json", + "version": "0.99b", + "shaders": [ + { + "name": "simpleAssertYES_VS", + "fileName": "simpleAssertYES_vs.hlsl", + "type": "Vertex", + "entryPoint": "main_vs" + }, + { + "name": "simpleAssertYES_PS", + "fileName": "simpleAssertYES_ps.hlsl", + "type": "Pixel", + "entryPoint": "main_ps" + } + ], + "nodes": [ + { + "actionDrawCall": { + "name": "Node 1", + "editorPos": [ + 612.0, + 1063.0 + ], + "linkProperties": [ + {}, + {}, + {}, + {}, + {}, + {}, + {} + ], + "vertexShader": { + "name": "simpleAssertYES_VS" + }, + "pixelShader": { + "name": "simpleAssertYES_PS" + }, + "countPerInstance": 4, + "depthWrite": false, + "colorTargets": [ + { + "node": "Node 2", + "pin": "resource" + }, + {}, + {}, + {}, + {}, + {}, + {}, + {} + ], + "geometryType": "PointList" + } + }, + { + "resourceTexture": { + "name": "Node 2", + "editorPos": [ + 443.0, + 1170.0 + ], + "visibility": "Exported", + "format": { + "format": "RGBA8_Unorm" + }, + "size": { + "multiply": [ + 256, + 256, + 1 + ] + } + } + } + ] +} \ No newline at end of file diff --git a/Techniques/UnitTests/ShaderAssert/simpleAssertVsYesPsYes.gguser b/Techniques/UnitTests/ShaderAssert/simpleAssertVsYesPsYes.gguser new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/simpleAssertVsYesPsYes.gguser @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/Techniques/UnitTests/ShaderAssert/simpleAssertYES_cs.hlsl b/Techniques/UnitTests/ShaderAssert/simpleAssertYES_cs.hlsl new file mode 100644 index 00000000..b72a95e4 --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/simpleAssertYES_cs.hlsl @@ -0,0 +1,7 @@ +// Unnamed technique, shader simpleAssertYES_cs +/*$(ShaderResources)*/ + +/*$(_compute:main_cs)*/(uint3 DTid : SV_DispatchThreadID) +{ + /*$(Assert: 1>4, "CS")*/ +} diff --git a/Techniques/UnitTests/ShaderAssert/simpleAssertYES_ps.hlsl b/Techniques/UnitTests/ShaderAssert/simpleAssertYES_ps.hlsl new file mode 100644 index 00000000..3e89f3f8 --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/simpleAssertYES_ps.hlsl @@ -0,0 +1,29 @@ +// Unnamed technique, shader simpleAssertYES_PS +/*$(ShaderResources)*/ + + +#line 2 + + +struct PSInput // AKA VSOutput +{ + float4 position : SV_POSITION; + //TODO: fill this out +}; + +struct PSOutput +{ + float4 colorTarget : SV_Target0; + //TODO: fill this out +}; + +PSOutput main_ps(PSInput input) +{ + /*$(Assert: 2>5, "PS" )*/ + + + + PSOutput ret = (PSOutput)0; + // TODO: fill this out + return ret; +} diff --git a/Techniques/UnitTests/ShaderAssert/simpleAssertYES_vs.hlsl b/Techniques/UnitTests/ShaderAssert/simpleAssertYES_vs.hlsl new file mode 100644 index 00000000..ea248d01 --- /dev/null +++ b/Techniques/UnitTests/ShaderAssert/simpleAssertYES_vs.hlsl @@ -0,0 +1,15 @@ +// Unnamed technique, shader simpleAssertYES_VS +/*$(ShaderResources)*/ + +struct VSOutput // AKA PSInput +{ + float4 position : SV_POSITION; +}; + +VSOutput main_vs() +{ + /*$(Assert: 5<2, "VS")*/ + + VSOutput ret = (VSOutput)0; + return ret; +} diff --git a/UserDocumentation/GigiShaders_Documentation.docx b/UserDocumentation/GigiShaders_Documentation.docx index 9fc037b7f00cc4f439f9d532f89c2a84f536793e..00ff466c6386b4bd67ae8012a305f6c28b0b6e8d 100644 GIT binary patch delta 12117 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 z zftePV6#}zjV0NGGF2MJHWD~rN{42$FW3#7%Tah*~5< zj?2o{W@l&BfhA;rkWjMk)C>rGAG*f+?jYb{2t~TVfgGIBjfi1{6cW-UIw>%0VJxR* zkzicjJT95_yZ7frD#c9R193?sqlsD^FZ zy2G%9Lg)j3H1dy)3UpP34TR&sK>o8vB}R-im&@hWLR<(DuV!825+O$Hq}D(HLH`Nk zlKsxO_!?>`Zll)xk#UIyNG#$EtxKr0F1~=NF)v&YnpK7iXhIC;^(FhN7WM@L6JxF5 zsx3^6khq52zhz?B9qiD4W@5YtP<`3PgnwdV!de@D6Mn(Q3`hOvMkdx9nOJXR;(umj zQW8X08yOfEpRTqtotcSi%uLLi8D=eqdqSujj6}t&P_3CkqSnm#l4>*4CG=(niCQzm z)}S{t0ZB-BGgApDLPBd{z$N-Ch>RF4EsU5?EQEWwl&H_yaIS<%K!}72-sBWwF(DQ+ zM16>V7_AGD!fSz8h{Oz*UjYhSAr?W(xfeg-Ud}iru1Lf7pn) z+s)Bvpj{nJ!Zn4}i3+gaZ@WA$v4{|hKFRfgABIL3)K2_=jB%$fFk3ulJa>i=OOe~cco@)GP? z1l0p)d3n4zm>;HsO%iNUBq2mnwMwmO$KhBHww1bKDD?BokQh`2JLBb-$+5+iNf0Ti z_R%n9xS5bNHZKuEBA6#OVGfSAB#p~|VCuMx1|&kytgI|rK){8kXO@wWkP7ktv~FO@ zh!&K<245ihWJDo}Kw)6Y3O)y4=mHc8FlOGGX&R)1@GK(%lEQ7OM%h#YP8M;J_B+?%G!Bz(sICs>43>=I;EltCZ1+N1*Rsbjw5fY}x>gBx9RDI~>%+vV2 z-7^Fpm2sM)`kq{C`w}SA**V@ zShH_N>#H>5PWqrE0lsh*=ObxHO0wh^e}N4x19;bv%a)q?;1@ zx#1lP_8c01ta#~EEQ4`NMTFGAcgT5B-0uQ*LOemt3x2rfJVVS<29Y1O1_tRS*Tpt? z{MmAqTqP9~QZW{wb3IJWh6^T-`{vIFy1wG=s>Wn5sqAIX+2iOL$Mir>n;f)8J23dRN2gcfh)BGxqgDm8wEF5hq@%t^=4f z*6%MKu&O-{FN!}VfXk5@RtGE6ZLS$?Ph5ozk+Pb7X&tYB!ypnL8;Q@{j;z}4$g16r zjCVW6B0?r2$!f==_d9}Wzhgon8TLEXjt8z3d>(&Q?Ra?4Bdhg1G78X0R%*Djkr0&3IW#o1B2*uLWVk#9)TAIun+z?IKkp(h&xk}uv{p+H zH2{pT-QbIY!s4>B;=;lLeI0`!mLajpjgm)fL7m8-J!?ekPNI?gb)>V*pzPrdtSC66 zW-2f(ersP`Qr!hUxhCf06_jNr;%%I;c4khzY<)k#0iRa!+f(5Lj$I%&g(xf-6wQW@K8A%1OCNMmhdu@i$Sx8|id`2=}iX?*!OCD1J zFBJA%#)8-#`~boI84FABNVR3v*D(4LnGDH{V-*>^Gn_%h6Lg7KE|%AmHs3|Iy;;VV{Hv`ny$6vni9@@^yNRw6~lkH z5`Xls2ac@rGl8^1O*Y(X;;=I_?C6Ap>Q|+`7vFiK_G*_p_s62`i^2wa-p$vf zBO(+5Q6u>;JNdb~DC}U8tfje;os#X!+9{pvx+on(AZZ6lr9R0f{4L|tms5XG&T5dg zAt>NaX^;s4`4Uot5V3cE=9^{2{E(hERvqZ`B);d!v3=v)4=XS}Il zy*b4S752gO0kg#M>9?FAzugXUc6oA(a*!X`~9Pf4>#J=e}H^S>p@YCehdH3O5i;9W9gHMYuoLnZ@PYL z&0yEbI|eR1WnEnKP%)}^yN3m<9tVf@f27%ZF5LS0xZyFKj%$XO(l<=VWZUjRw?;-w z7lyZ;`f~9Wi#MZxF1~ThEA3v?^JjVGspz70W+VkBvQC5IfJiiJ1}vMkq-Cr`$bgCq z1mJ|&W;oNBZb;Yfy{*ywZ#A38laa-P!mn*KJ{0yMoDIaq_2|BApByjNL)n3Cj~7I0 zW>dQ$UhxrQ@i(V@V)3(q(h(}LA=NWSi1uN<+1}M@mQ3%V?_$!V zNnh$BBK}W*WhbyQJZ3Y5s%VlWKC@p6YvaTRQ~D)r8Gn4;kDc9oI)?0axzTs#m_5Pk zQzkr}A6#C4aAhDX^V+{Cd$9dq2gMO;;z)dY(Z0?VFQ7Z?2DW?vwh-9+y9q zG<*{~EabcuXFe<7+utS8%8Ya10A6&{ulp>UayFe)ZKDq(Vs--B02 zwu>Fxnbr9{2VK$uC;#hy`JZ{fUyVojO&+;_H~-#8G2y*>;kLK^M?Fy&pFcjpck}v* zNzraUUFtf2PmblgcM+QV<`?IFRIg+nM=UsJ8(FW<$K*>}uEX^7MlPdsbwB z?P)(P;dJ}m-Q4e$xqIcBM+Tm1dbnAB(D2~+ijfCeDmvd9vSIzApv1hU+D>q@I(mO!v4fKTz;^%Zpi~I|v4c z7VK#^Xl0A0!`$vQu5TIRc&3p(H+n{Y-*uxS!xI-=X3sCOs`h~QfXHoDE)?tU?F|qO zT1XhUzc2csMl}uUleElILIm(1>2@VtSSfC4LSr%MtVxaS3s?&NspH`;zv+Kw?&GzC zhmR`izA$Uh)pN@&^8Z~A2YL%y3(BhZLR~u8+5e|J+#kqJU{hD&K`ZFgMQrMSd^UA% z4V;b?o0`gYukMOO4V8b`m0uq({*MfFa`g-7G$JB0Y{J-tj-wKySyfGQlI?71r)Wla z6ZkKi;?K+vBmDTS7ycCdWJm?*zx@$W^BtIuie|s_xv;>E6H0@9+fL1II6ZN{-zDox z@v3c_B^8~k+Sx8yWcuL#(ep=t7o5D;dGjx+`)^nhM=mYQt6I-ObxRSidGJ(|SQ+!qP`;JY35I zwrNe+sFY6^TPmVs!Yhi^3x{r7G&H0Caz+L_xqqSSi7G0cE@A|TlL+vs@I8HCRF=6`3?+QYKryo0d z(`atyiVjcryg1+b(%zv_?{gZ`Xrs-@@#p*c?z<)EzhuhWU;X>Onk4X@UQjH3Ip=vV zagou)doB7WTDR(QKAZ+p%$q=%}PGRI2J9P7XGsLhamNa6Om0w%(DC zhhDE;xFBeq=klSs&lBBKm>#Pin@+lYc4yECmnqNU&e*w*zSi><+1JSCqp)uifo)N< z(70CzCkz;<^f>Kf=R3_&v2&|wGofA1z1i!J_Siqfv?%IohkZ#G>$ND_WLuSzcDw7n z5D%XYLw;(1H|^KT9y?FYAw{b9#7)*!RPsw+Uvmm6sA#`71|U-;{XDB9bV# z9($xpR+KV$-&vWv`OvHxH%8h7j5)o$X_H|?e;84JWb*o_{>6FPm`Np9_m8xEvqoe3 zlGT_#ufa=ENU1Ts33=D*oJ~znLskKasNbJWH7H0ZtzJ$!98Wb!4Qy3V;0*e#7o9dx zLZL65L;Y^g6?S=QxivNEcGdCzs6j3jp1I4Rf4jVuy{T?CgO`xPu*&8Z$2={}>{vL< z!D$YEzbM&`$}UbJEX|SVRd(vnIjKc#>bbwgYTB}`b!Q2KKh|P!hVYvJ_oEnve^hvk zvK4EitJ*AZR2cqC8G!)-3bz2CZ=AY1x^!@}cj(eV=?I6>mTU{1AvUcQ85k8E(IFrq zEIL*Zp!*9j*&1Ut>_cC}3H)a52^@ur6lL>&J+B{mip>&*e!eM9`dc9AXGWPd`{IZ{ zJAW&cot0hjYU$43os~*`^8ef#{nL%@9wpcGLU}>qOMm+w;@Phqazf7LyzI~`!h80k z{8@#2f4usA`-tz)-5q+U(Gk-u-@5{J&b^jHcbLxUKjRnM!;dJ^e0f3h@3Z<9H8|gY z;_{hU&X>2G3gpKB=KU(#?#j6L-Qu}+VfRlw*>AD@W4i=Prwk>2k)NVEiPl}?1k=&qYJiwKRu=KUa({Rk4_c~_PH~XZ}Uc%Cbw@o{ZwFX9kM)h&;bZnWGS^EM#5Jheccy$nY?aXL)`{|r_OH(` ziW&5s`Th>8o*yrNS9+nIpeQy(>xzV1eg6OO<3Ufq+->=^x~_0w~2r85VG z_b#s*L@kvcyvfbo`u#J+?Y|*l%WB@a>~S-e-!lrWubjzkig|G@;OdJ>`{U+a>%4bUfu$pV`o3}TUElf+ z!azE*)%|BLhlxvPy4NrAwuwF)b#dBwwVC(6O$UC4LwFoGzk$_$^Wuz{%4+Qb2Fnulj_a=D_2eo$G1fY!9q%B4x;Ma|BM&E_P9u>*IqYLl0t8EJv8va5af zJ2AU^-CVHk%6K-om1dor(S;|kJyOpewF$Kw5b9n&z$4u*%`zcu7AR(r?itO%dYzf=k3d293Ce&-SO+Pv(Aq? zsejt|>c)t}IVe{lUXXaU@{snFddSd*E0Mt0x^K0odI&`B{^=3?i>~SG5xmY3Jexm) z<7xg6ox(*AGx`~S-7P3t+A}qd>b`2-n&vUPpKd68tvqsGaCh^k_rcMP*xkpDN1hse z`}L!;#KR{xt!{bm-J$1W0)v_M{WNOR4+jD=3txqr&YW1NQn{?SG1$Cn@VlYr4ohwN z_em)2B|o|SXi7m!x#PDXJ)4#4*Ea7RbN|G-H>al%F@0FI zjkWXn=hXVea|gCPwC^K*C-!^0-mO0dZSVAH--9{!2Zs+^{!6gx*O%v(MP_AIjUJwI z^LTIRyjFL+K5NuFE_~J0=Fxd8*R6GapYrYE(OHQbqA%WA`L0=|Q}M!A1?we?({m25 zZu|q?Yuf&Qz1#|GC&k{D4@NwD`|4t!=LH966I`@p?F+)z6&@r%2<=Hl_7dr`N7bBk`V+K+_~`+hJwI>h(aRhEsM zIvqNHKS0p2)F|7};d-gKb<@kclN~IXpRRZL<!w1#-G9~*Zki+ zR;+Cyf$52ag7(G~*_diTe6X9JFkzPZ#>pk^z6)+}joW2N&ll))4XBpV2 zKtPZJ;=vCYA*{89NzGZ%&fZbkIixy6$?7wI*h%1EY7U+>Qg#CGB+(1N-dqANB-zlI z1P?6Yuj`fTDr~=Y9ardL(453?oz%RAflsnzwuEJHGfK2Zv8MVOrDuOOWGXe4NdCuf z_JlYrM|0ra&ACnGRSS?cFQO2PbV+BST%RBx%lo-&$pX)L>%~k zGiaPK2(kk9fCGBoS<)&djs4YAxmEXmzMA-0zkcfHz2Wh*y#JlL+V=1I9|N?1dJZ(` z#pkHJAxWhq|IhxJTiT30gH$R5U+qY=(F;4wovFTUir=~Or^>zJ?mdf$5BnG5x~=_7 zu*;f7%Gcz#C`_8+9<;4-+llU2|Ly;SRyXqa1@PWhNHxqqzprJf_4`-xEv|Q8tLQK4 z_AK~sFxYPUw9@dNarr*xTONF?zA3tH{>SlaE8CVGz|Q+AvI|c% zu@n@|{&01Y`w5e$+`zB{01*0;O_#x$0d##+a3)O9?ibs(ZQHi3jcxPYByVinwylkA zCmY+g&i-}&yHlsC=dNqIYGy8`yB=Vq_3VMdrO|tVmVy&=^Dwt9c!8#ZfHCvvrRn*A zGNo0%fx@T3Wr4t^<@Y47i#RBcFp zph6&Nkp*C|X>Sl9gy8Hv++1ls{-Ck|t$At_Q~R!Pe+&c4e$@H`6TRU`cZM}v@GiNG z&sl#ipldTs>$lqZ9fdxqCx0E(^dS9Jqj{eunPbmDX zsc_U>S%kRl#PVl*>%V~`wk$s$TZg}{9RGPDKHJzEEvztXTJeJAlY>Cbwd6Gq08qR< zERcUWU_JM_i@Xd_torGD(+PV+{$A+5eO1GB+j`h?`$zly{ddbC$DUxXd$V`&j-A_3 z1Pj-#EJJD7g(EeoE45ntO~&zYUHcn3pZeytlaY zPx8-T+N!_bL^V4C+}|>nyx$w^NEAWjufGqQsc?*bt~;S#>iC-#-E#^-z?DIf$k&u0 zjdwjNIj@Y~W~mwo+v$v>sh_H2bPz^=qfgWmAwk}X(EVN^$xQJBL9XiSuagBF86hPcvOB7inS#C(# zKjp1h9aygs!>io<3I zX)#p=!;fo@z0UW>4ORn=^Z^5bH?tJZ-=E%6AK9=}KXfOr0urk5M?YByaCstUKZkGM zb&Mc899XQMA)im^l@+7J0;gg^xFSqLu-k3I6d9o)}`-MaQ7ME-)PM$!ScOs z8ZR@od_?rZen0O)0Zfgkb_6~*>a08ob`V?vlRP8l`XfgGB_I>Y^Nv6m5!!f)QV31mnT_;NYZe_Y;Kx0(T z_PBr5RZbHrn}UEHL2LN8FtB34T%X_az^6T_eVO<`5Mw&;XLmIt`?ZcU3ZuPk}x`LFA!9Tl)weA;+8?!goSoSfkrGfiFR39r~-BM>^7d2iEky|#Wy}pH3-y} z)GI5#NW<=!ySs!)kCD5uBv1EUO3wvS3Mbjzg4;$vcCI#UCkWIX+B^0;n!x`ADNR2Z zlo$jr%|93vhaWP#+xB#Ekii}$YRdi{t)#&yAcT%w0{j#c0|>FsKhK-XY@6*{rK}+i{vE5R?|~dG{=PA7|LGy_GC2 z3JA*ZuTlpPlm$>PQj!28Dfw~deLsbjfM$vW0cW`-ow7SZhh@)?NS3LMZc0F6kEQ?m>dq=N*FBRl$r(-4NzJ(o-nB-U6n4x1m+5?p6M0I6VwN4)~bK87uK!*9A zygYq;`EPO57*N>3uO`O|YN^#v(ayMQI<>fC@TI_46|oJIAfiwkX2}O;X$; zmk(m7LInVe$w9tIuRWfclB&9v5CeVW;DRA8 ztbP3>gtRX`N*zUE=_Gy?K6~rOoY;V~{}N3p!6FYsda( z0vzNlc^DdJaC0+oI~BTTZ^eXc zsv_VoDn+iMipGjGMZGzULyIPcs*kg_fv&`k@s#>yiIr~Co&luOM}PKbgozD(>gNsX^8p2PQ&Q4FTmytF06CfQN~ zi$|iyjApG!AKdkE|6Z1U8TY8PMQGF(zBa%l2!rVN=iGv4F$p`B0GpU|u?Ah{$2sg1YL(}NYX9u6>&?t=M5Nu z18xCNpl4BYN%$q!B)k%D!S`-}qcCwOgcSUuYcgKpx5RrO1J8k0p=D5oVBz*akpTlB zA5Gu=|u7D!4!?rN1 z$ebwG#CGJ}(ywfLHWMokFc;7#szEslB~8$BG$FHO)fDt3_)6OH+_9Zd&+C5OP3%z-@pXB`8-`4dw}m%@XlyH2?$D0a6EL{368$z(5A&=95{$ z;09&pld_{FCpYs^UtE_}H>ogEprZaeM0}D|;sQ4`>Mg-4ywF4#u?r40vU0%LTHPih+pK`(D({iR-J=DF<>yT&AQVO zE7hLngtX@{;4v`WeAAm@J*PH~IYy18XhylGrv2Y*n3KIl z=?2P+@*0DZ#O#u^!;AyfMPUtu`AeK2OK!P;Am_5@0 zDIgLI5%M-wx72IqE#n@+z-Dq@MzT8&&}{%*6qh6=UepOqA4ndQ^oy#TIwS=gLPRlM z1s0%)(-Bvnc8g;ieoOPeyC|ti3QD{JZ{dxx_GDy-`_Krf_$9Hb!(_pdBS{7@2X>&f zPyw~X`ifpbPEpVzvg0pQ0~tWWfioZnPzafq2BQrX6Qz^d2osqX`U{9FN>Gr<9I;EK zj{Ggn9qfct5Us38O_7Wo38My`1k(Z}6(tc7p`oXeCm(}W4FVD)lk&`>RKjS06KBiv zaLYp{Ig_Lyq9CFoB0r;j%e=-q5pAJd11SEAwP(!V$jn0Z*(; zLIn=WxpsZfPohgtu9f=(- zGYgi!LVLK=-tYN1ZKd|#^|4NZd;FqAd;0(0d=`LNIX$r(DlhaE@D0c*N=K3xFXb>nafsXqqXSOVFE>X1V}^VPjw3Pws8>j*nZl-S zIoV>G`famhp>FI2g}caV(-r|$n!X`&-3sE0?$PP~$4 z1mFeCDheanXGDFV6V1^91uzQc0ov92YZNt>WQt^pvKcuDSOg=50t&PcMKi`MNSG5& zmyxEDCuS-|QH7xaN9tDqNK>{$%YakyY>3pOk%I^RLE{E}ogJblkVGgV6cq^f`OjUb z^hijhPwWf*32iA(MM(4u`3Y?4g+*XT%pdECV5v+cPjoBfo%|fF93bV7|HQH+r9vb^ zAl?I~_NutVrwrA>fS%BY!ioAV`pPD8NIQ@MY=W^w!0rhbN_?3~(}@8!!j>y%`bV(s z#C!5yI#JG(@P{mNgK^-*ib|V{0o9|tdaINQKexUegDPeJ|<>YOdDEEY5r zZI)7{jnaeaek;Nk^@Rd<3+4kgO*jq|0}#83O0^sX6;!&pWV_!L(<3Q3dCDbd`qwo1 zw{ud$YTc?)%}ybf#retE%X!#SB7=`Z)OEntBCm0&L#{)G;@n03CDJK)u+hnM?XvBa zZk{IfgEd_H4}Zz=P5&`|^E>9eQc`#qf}5{bcVWKYGhts%j$m?p7C zS5f420jjlGXRPK&S3eC`>d3FaZf!x^EneyBY9tCy2q>UJ7Al?IxmeHT+6`7**gv#? zQtD&Jq;G0jSs9a(Q7@>F)|5ePDgZ;^6|;Yjs?idnN~Zx|dyu8kk6s%Lm)75Vmj9Az zBef~PcR?qDhHnzk{#iC1|KX{$+ox-C((v;x*NZ~zH=b^!<2HD9Yq)X${#?$EfYifIUxwKH@#L5;lrrkv+2`?POK&?HZTgYx0M^naLxV%V)@@Eb&0^8^OC;Qji@LZ;t=Mqgv zldd*W({3c9UmtP5pat<3!#4UtYXpIgyLwaJ5LmMmF1$1FMuVQ(D=sYBO?hhj2}yE$ ztUOF72lwrMwaHmS8ZLmQ`ecaFev@|Ohkey(!K1;HbR;TM!kj41R0i}ryt~RSZ}tg2 zW(Rs3t%BM0i-7qDr0?)Dk3HF+$e#CM>>p-LBuO9s&?mrXH{NEX#C^e_q$y#aL^jA| z*43JcRPoC}(fqHUXRjCIZ9ly2LEK|5&7Vf?2jJ-umjqK^)Dz$)O66D0SRa$IpAkNR zG1bfq!{rD5$PrHiM$`sfdG++c+PP*mfDE+*X%8(LGirTQ`~APT8x+sd7pD>W)En{h z+@VbWb|e3gge|zdgZVVCDMO_EBeZ?H@ zuMf2DKNY8+0G-N%;`Se*vDx1#+5s@GPH61H$j1ZD3rKHNcl{^>lOY1_RdB>%s?dK_ zm>*)N(xYO+Cq0wHZ#b3ihA4427O! zRy|2PoqJcq4DngP_{$G@n560=4r60vN_7`NE~D7VDW;@+SVvg!5+r$ua@A zuB!hoVZZhq51E!nq~^3-N@P~Hrk-X6!$gkN(s>JS4u5|xaaz_R?ds5o7+wlYtayrM z8M`>Zb}7OmOSVkq)D)42MdBg!WwPXS7FGK8;sK9sStW?1WFD6pycnchm_;X&uCZ~8 zSL88xeYnBhM-@Dc*+i76{z!MKL;p~ju?aSF2;WmyvpX9QE94edT56)o;>q*FU#Bqj z?A5rBG4Qcqp|b&aZa=iD7%E{cFIN4GCnxmcnz3S$y@c8( zY{?-^vspe%l3PFwg%B)RvtQCt+qa@vpsavtGI{eT&`gK#cY9tYL4Kqv!(GbASl?yh z5MQ^4XtGnupP8D&Q@vU*$!sqkY5!f#!y&-gs6F!{?J#rwYS6(mqHpS;*}ClbR>BC- zS!b9MnIfPG8co_y96v0&MqvxjTA@g@yi3tIQJ?NM zc`q0~#mk81IrYm^x|w>w-_UduHQoYXxPSVk7}BKBK3!VwP01x{Mz<08&H1+HwHkj} z2E+_zS1On8(oJOZjwy80O_*rXqIaV6_YOK*FF_2sj~*QD(=l>lAVqw$RvUJ?QeoMy z2>=l{AuIX{iFgs}@FFHTR@7#)v7;2?kG)m-39I|%6iKaP=xlhtQjcu2yu<*ixuZEb z`Jy|?=1wc!Iu&S}l}UqnUQLA$_;j(lI)AxYwklC_8FZJM%IC3im3WG@V#U*%9B;K^;6khp8Va0VO(?L^@Co zn0H|wF1=Wu4fHIR1LiM3Ze4(c7G9~0Au{aj4w_v2szd;# zU!Gx%hgh;?yK+%VH(i_WLZS&Gd`##%zNzM#+CpNXDYL_%Uf2uVjSQ<30U`8ziwv@@ zvu!hB%S1|bPnJ=n(g^K$NX@Uib|{`Iqbd&y8}`y6MYXhMI`=MRh9$u6z@iQ>)`$Es zACkb>n+Fn3=)PYEB__RJR-`jlxG^6QrFW#-4CekFI=V~p3}%O%6Re{Qx2=wdq+)e; zQwY{fT2^A@LeDy64Ne=itBXXyda}B}59ANZNk&>SW{gaQ+7?$iM05aPia_SB* zMP)wHDrA)4YGugAq`wCLaR1XrDU)v*d00Y%2mSJfV1c&~2VW??2T4)BOwN|7i^@1a zKvZjO%;s|^KPCk2P?iAmdgfpz9L0<_N5%crSS(wF zwnOdO^h2>09O3^Z!OqMVv)vave{H)pIEKZu<*>)=>$#&@U(#*H2BArwF z?s|OhIh?NG5p`r+Z_SWKyiq=pX*s=RZ_+Sfa{1ZBF%vLbiD_u~2M@o)L5b6lBktZu z3UQNk$uC~7BHF{OtoU%99W`SB+nfcs8nR`PrE97_N$v&Vyc2pvo1;1E#SySV?G!Sa_*l#?>OX)5AM9P{UtWHgwvw)YZx8ky|4 zcyo#skMq=$lI%|9OX`aqtwfLGQk>Z-qn2LJ*4>XtU_@>|K5fpH$pFYHsBSplp~C3- zJ@-?k=!S?F&d~xtgO%diMX{wP=O|K&iF|-{(f~U71@mGFe$sVd1~ZDyCu4egRz*~! z<(PnOR(JU#CPmm3e9cx8p9(?R63Qxt&MTSBuIb)rm1`Lj7u0Gr68b(`h?cbT8Ia5& zn+3B;q5d!xZs%k`uhMV!IT?K!H)P#P{Z=(blTI)EW%Q9;t5brq_E{!N%e!#GZono( z5m2Qyb-er!svfCFbOm zosq1(`UWF|Op^xt21rS+SlgVT06#B!2Zb(|(aX+m{Jb4{Q_c$XI;X?^(QREXJmx4rU-w^v8I++>nULYnQR*4&idL2dlro6OZ6R5M}nnePye& zmFBc&3{@ALvUhN^*i6SeQ%kq$!B*B)8DIrJtLc>43tEY%D>X&{r5kLq*6HQ0l38n5 zT~D#&6uE`oRh6`y`aajr7#t~VMGBWP0-qYj#x@#GhI*MbzeM%Fv(;>f_j@Q7C|-do zAXo&~0(}!1Itf6GiDJ=Xc7Hd?#CX*xNeXJSPWskIUJL)P0A*-M8gFCU{Zd|dbvM3W@f6#d|pBd~e( zJX{2&RRpzY1G`w=nH@y-sdcV6Rgt@r&T2hKapIPOho)xQo~91jB45f`j>v(ISt8Hd z*}~z!@%V}9Mv7E2NCXpS3h7e--%5Br$VYXEK0%(3f5-&5qcf0B-(ExzDqcT||+ zjT<9d%2^5E_+HTDNG-9=!i%kIzN=edaGa<&%fz$H zV6e#9PEWX2u{J4cu4r1pH*g;gb;V3AQ_59K$;{(#7{|)Vj`@hid&zMu*?PtI>qqIx zfC(}Sig!p#FDZpNE@$^!|Dw!Vik7V4w2fq#NVWi^jZmzPC@d;|eCxGD7|ik=SYwSe zv%7d1kK%d+{PcWkMH6?*KcmH^{Y8mO8)(z?ecdyl4Oz*}%gnT2hMk?oczn(_n-Zm% zrSZxkOH2S9Ta?p}cMy6i2I;o1#9zbrq32>`RWGEotNOJrIWdK*Y51hPw&-Q@C&obu zo$vxUUhSc{BwN*dZ`WB-T%8g10l-oE<&2DN6FK=rSILEJ9vfv0ii)gK+&e>pN2=E{ zd4_vl2HNm(b*kwM6@%(YhP*^RhP|JL7m8hb{Fk1lt~GNto^gNBzJLW=n;bZoa5hgydn%v$fGY%ImJ0s_fsPBh`txL`;C`FyBbFd=m zlD(wnIjOW&(?t&KH{X|De4>N1w5>td;jbxv>Go9|lO5Yxvw+10VD z9>$UdsoPMbjXf(5aoc1{6-PsF5Y0-k84TZpI(h-#uq?4pkji;a~t*IfZ6`Rcv2p z7d#q&#Y-u(?fb<%$P+pXVl||o;TCEhJdF@m`l3%TJ}BiY<*;*9_%k7->Ujs1<;0`M zFx|5XtTH~-?52I{uLSj zUdA2Xj+GT0jTge+6QxwO8=Y|b6~-Q$${hlSoU=Hu$1ILc=I21qt)$af!hprV2Bhu> z1Su!`4(I%JoxYdd1T)tI!*T>dd3x!U)gTM|(^t$3JyA-vnDrQ&zmPRrc+0H3lD?^( z0uIq!H*8%B1(`lGdw8DVt>^%Sh(+#akhgLuSlc>*BKZef$<&;A+GO2ei6Yib1InF4 z=`;_E#f`W*pY;s~%b!#6oPIs~1McJ5SK(@g%VY0e|DPOR#-moew<`rx0z!x~6Q26} zursQ3#Fb#r6syUR zY^`x1S%U7dgxu7H;{%RP&f=j}%o5F6-YEj)S8_?e<;#;|$c1C?*@!^kdnlyM>hK&&+dpUYZ8t+g0FJ5<)?iW9B-+Z3i`2*)aeoRLeCDF?e5$Yh@Y2 zmM`p!+eZl8hwe}9bUj%gP3?T9I%X7-a}LV#!IEeH2Ff{~GgS})+{^ad3EwK;+00C4 z>d&@Q*>e#`3F|bMgIeHMMk0Bx(P;^bQfpQk5gL8L}p$sse-E zCO9>W!CdP!RjkSPTz{{ZGHa5Qy{nlMYv^V3w2s9=F-mvdj~~cI1zSpD*07>ilk4Lc zyl!g2Pyor9*e3c)?bf?oSy(%;L9RGXdE|$l$8%^PTLthliaPKf#c;HhIf0S%2^ea> zdKQ|d)p6Gd9>r@G*}g7dpYicj_%pFcRFc_c3(A?xdrxiYwz|5sw5c8$#ank^npUlt zn%$JlOQGR@_H&ENO)&svx^#xk{8lnkrlA{atj)1)-yQs&xzF(HEcjHqTVNai%;9?7 zvh4%E1qv|y6>|3Ym{YJg=t2c(-~&UGw&hB|0u}85iuYqetcUm+F?Z<=DV|63*3VXRN7)b-9a_iMWJ84VB_Qf46x8*-e z`21@3HI6NXUdfg&!9E1>pn_(mcEVF;)+}xi;m1XCEaaP0OYE-2ZAz0skRWgoq7sf3 z-7-M9)fwWZip{a!x(q92lc#}nratsUP)1*v$j`EWO-j?;@O+wbcIuAmx_B;h;`_EY3R*@-IOtT*Hf3#Qm^6>m0 zdY;0zy+?aq0(uHcD(YsIkZsR{>j`c6{hR=u|GuE}ul^zaZ)nr=YioA-G`M&fN!^(N z1mi|I&X#|Ex#3hM(B*&I4Cb^~)_dQ#!p^}QpOBbw{f7myd7W?%YwNjow#t$%Tcl=F zX&-wWpSB~6-5paK$HPw<%ZV*E%@Wp8w5;j}??O1=crV24Ib@HiWOFnu*D+wktCq93E8AW;SEQ;m zmIm(&LcITjbi()h+}xaQNTtjfE^Gk!){I!${`28j-~pdIL`VZj5-FQSP;R{v9voV? zY&iO62S8fK=L8&~2x%T2#Q7|Yl-y@2VdYU?8;1_wxmVrENNR1Jh9JZw3d&sA@&!HB zIADB%m$6mU^u+W!rDU$Ax2)tU+qdf~)RYhT$3zAghF~n)>r^)rtMjQ zS)#gd>OE_tNc!It)698dnCeX1d;S;|2`Rnd{9{V~`w5jWm_Il{#?@2!=AK>@Zzb7= z^M!^gn#(VtxEuP-ur>k+1s+)beT}r@@6;s=F#ZTv8puO2TOdU&b6acea6jAb&fN{8 zj_j|#nYg~rP~Wsh|AUWFos9ZDbfdrXKp})^3HEaor=65 z=WaK;0muAq@Z-igd*_tW+#1+uT&c-}V~Ef8=K;7wgE)q5i<35X94>@vgXI>?RNSGs zt&l*AVG6WrDUefk*GFRWa%;?I&Zeo&BdW%wG!irItgD4TD}-ZeYH3CVLSSJQc3U0^h$`?p7#8gCK@Fv(85xG89_KKd7m6iH;IM~<%>=I3y05aT%a1*YL zm{LNqo<}*$sbgOCFgL|d%ekx0kx?2#k3f#4eXNa~iBpDS!%sk%_=Mi1c+Z^dH3{G+ z$g8Z13YTJDpGqh-c{s%=CxIj05qh^f%8`*t%!6Iq9m}?688Wu%{ja*^O+R7V$|7#` zG=jTMH7B7**@*wRsONcahwy7^8`G!bIh5p=n5@!&jSO{d=WYbP@6}A~f0=o4*_S(` zIXyW>vmnG=xyu2pko+s533|HEgmi>>{}|BUlEM$wg$NRJ*X_OY8)higm{pS@?3@=m z=U`Mh5H8goc}~YtJzUJs43w#9fLJo8^lb3%YUrq zzxRiBbPRkDFU^Y~y@KgZYvR^)&i5=IGvjCkzVla2+P`7? z%6r|>4ebPgq5X3ib%zLo}md4xLe>!^hNnp_;Nt&m_K7`Z2ZOI_H@(w>3*>E8b7P7XW!^+^GAn+v#Fwk zB!2inw;WB3x9zCHsz)r&178ODtMMy@ZzN&xDG5ZwkNnUtDzq z7iIsL6}UqUG>oqT*Irt~8}=R(7jL|tehVl$7+P)s3EeMa<93MP+L1ZfvJ&5A+*AuM zgjkwzTFSc9V6^2+)AB4q-;r?Ln1H^K*uH^64K$x@A39WJj;Gf4&Pg*z4eG44=&jcq zBD!tU_~?6qaq4+O*AA5+J$uzR$qfr_9pdUoi|Jv%94T`+bv3I~;i>8xMBgmSFcaLG zRIW7u{PW)1rXEs{!@{c9=0|LAhEJZzk8>_~O3%nbQ`hXX+iHKq7KdhkLDju_Moy-- zue#|YFG4{<*5>}`b*JYs;wLT1D{&zcEh#lTin)C~kRMrDk!k_>DVw#NXH&o1*I2!D zH~x(^GsxmhR$Pm(vUw2E3(dz`z4F1%`xyiXmU-yA{tn$eepG}TF1OF6bTq(j+$kem zu@M~W^hf^GSA~#km;E*wYmx~CsMvemdnrtCnYu!syBWM{fKPh)@Oi z9ZdHySg2!UYG;pBHOpKLirSi+eNgY&^Jhh5q!-2VQfdY}Cg4zNtqWJ;rZdWGHEX|; zFeyica~8+<&ZvgwWU_c`Utf>ZFgd+5)Rjj3MAtakrU=5tqdv3=oL~LXsdTmQ!Gp7T zhjqPR`CPk3qK-%we>17mQ854MrED9};uZSd0prq&T>hY2`8V|WyFE%(sn6NFa|0KV zyW8E6?^R2x%23NlYgw>sX~XTdwZ!yg>$Sj!{KRergy-YC=B9R-v2HX6(g$^z8jP&W z^>BfGg~nO*=k}~qCwtB_FP3gR%a<{6GU7(SJAf_gAdF!-UI02}H50ZA8XEvO<dt?}%3wZ4bIiQevYC6^sntV44W?JemCKc>%vxEXy~ue5Cg2-TSKn;V=8*p-P;g zD_dX7$)yji8425%Q6=+nJ=4}|o&N6MxGkKgb?51F!vkRsMuOkRXGq=vVzPX9ZUe@8 zp<-`{uo>2ykle0+6ld;d$AYj?f!}@iF46DkJxGn>Qh$Fv`0PC*k;rqp$20K9bt=|- zYW*cc&$CTv3-~A8t)&xUmmIUeEw+uToYMIaW7s5Wx+FM$W|v!u+ZW-DzH@4P+uzut zSJh^9e%|e;TaZs99ZmlV7(S{qye=*~#aRk@<`3Plw$v|Kt?DK&rFBUSpssDH#22#R zuCN6FyQ<{*nO7k`uk&E=^z@yz{eEN>VGX!x!0Q@z=WsPmSBzXhjv>>&5=IQ_qoMq_ zrdxDdA~i0OJ8Sn~c5Z6~5MQ>JGqPyvWCdzqIbbQXIM>iQ`!@RkU1TP%P*a>uE7i5O zw{-3rnmKcV%6NiK7cM*DIKF;YM_T1|i#H$|q|R`}h`*~4Zud0mYkk+a?0BvZUO8J@ zGJR@WcH`7+!iAKe5mUl;!0}LOWV&kS)@=<4`(#9PyfJ=FR~Vbl70v6m1Q;Q-3A3?F z&~XPnJ=EWaoFV-OSV{WL@pQoE)JajXv)FWIHA~u2ZI~R=HcW?@E~& zJ@XW+iV7GdbEiDg;k|`e@>toMTgfgdXPf@;0hH#LQ7ZSjVd3PJ6)6pf#B>id-022B z;`P0+EO&qaz?zTR*tGlN4tRX^Y%Q_Ws=}X^S2neE`%Y@wqK_SKX*9UD`vN}mC5K_V zOuy)wdj6SqRw(P)ZuKB-C;RM5hTSd1#r<^`t+_nE(LcT0h=wgOWZU4w#x^3zVu=0V z#rwdkamedpvw6|rYpxaEw11fi@O7&%>uVx7xW{=1WbdC`MzM$WP5$#!VrpO#$=b0Z zB3|Vv{(^6IB(eWA7)jr92dz zoDwowWQk+@D49k-ceK55B>Ud>=v`iV7Wk~B2)OUUi;c%qBBDRc#;b;M#N5PV!jP@o zyo<~NWV~M^3MKVE`mgNXYPGB^vRRiFG%b$)9hCx7D24;G2d7vu}TuTX5Zg`q=vYut5Kmk!sPWw1i9+#5?!vZ;6eS@H}E)|8AqY1fPC@ zSTL-H&XTQXL0cFtdz}hl^?Y>#mZ|)SL=-dbMB583_{hE*7^8> z^zFm$!<67hp3oACF|KbHSiY+1wB^e&rQgo+)OS4vssj$b*5_-kXScW=SYy`lPfreW?{B;}-U@p%eP_Z+E~dXq&bfzD{ch~WE;2ugivie){t!(v{3sq7 zyKc4KV@A2?Wwh}3v}lv9%-A0xtW4@fUDZ6-+EX|X^+|fy1@}sJ^f&a@_zm9WN_fMjW{9NS39nqf^(*NTrURr+7eJkfU)+P@e_m$wFv-9AO-4 z(9Dot^JdW1$l{cs9U5$ZctI@VV#F8`dk`PhQ|{<=NE@1bmN>=4%-@v1?`874B)Ki} zTjj}7cA62%wj_f*L}aH%wPf(S3;Y{C0U3$haJ5-52i zw9zB9&;xBm@3rh2x|f(-bs%_g06|KIiL7t}Rlq9gCh7Q%(j)Z6`79`UT);OWSY6ciU1FGRsK)qJF8+0>@oNli z76JvWveen++|@EFy0LAS{yO7H4c~QZZ@tO0S&rc&t zA*J8sGU%i%>%<0FbJTZ{0Q`h%a0tsbL-deF>H1+dtu}8Z@%s+yB_&iMT}nfsy(_8@ z8gW;6gS-q1gvMhU&fLQCjW>iWsPT>!F z>l3~GDROVEJaH{a6!>Cdvu4B{%{_wS?RsTkx@#O-b|QIhEpXjgW|2Lj89suB<-W}{ z?j-y|8G3|E-Rm}`B8v61buD!?tQ`xvc)44gKCN0?qs^wiBh(?qRx1PPmx8##P)|rU z9UR_AvP7e*r3|4AKwm>`{sk4okm5Kv`;o?mVr5mjJN(T$q1wlqrY+pVd#CW66SOenqd(7O;^3p`y=)5IccCuP;5do5&;FI)^v zMyPVr-n6H1o)y))?NE=rq^<;K&xbBu_GOBe(NX=81t)2lcB>J}6@!n6>^_CXWwqH0 z^Lz(!jo^K+=wAs2IgivY?Z>L_W-3&k!!bqyk;h~Kia<`Sx0<(0p+A^-&=ld<*lo?p z7g#0Q3bK3;0Q!U$ziIiT9^Zu5Qu2dkd$^~L33tNkE#=U8lXdSxe!|);!VP|~@uIry ztpUBptmvG3 zl93V)m1H-<_YedGx)NL}eDiV20uH#x(c&sFfUs}&+~B?GH(9Y@3&}}1`PqN{&}t*> zP$Gpe3j;kLdoS?OS!AD3;WLHJYT{ui?TqKF^5lQA$r5Y#xua)6&R|?(<+4lU<)V2A`Y3&;da9K!I6Y6f#=z9pTqTm1P2cP6<>wmLJ zCgBvKX&%wl1CF~j#?u|A$`1Uhji1Fp1(dik;-NsY;uv%GbgRO@nThliv(A8*2S~}x(_2n60aT>I= zalK_(9YhjSjY2e^`VfwX8444t+>*89U;s9su2}0K!c0cmG6WS8k35(r-wf01C>0p; z$Vx)bN?W3s{LAItik4K`W(6x`S^T*;ULPzg(#7<%@wW>JNGJM&1iUqE1Aw;rhy^dd z9bRDg(SW%-87w5$I0Y3{`E7%&1lD{_BD*3em4^ zR;4|P>X|<^VbqDPo?s(mCIRU3X3R2Rp}wUg%@2Wk5fZ|ZvDuD`JJX~=!2Ky#uo!Of z`#%8bKo-9~lLlA9*CN89+!{c5Qdk40Dq;7<-58l9*t(Po3ybMu9$Z?qaK4a+t4SD= zg5L?SYpSrCE|q}X!bzf)?4W=hI8v@4SC%k`@OIt7F&5X7r7-r-V=y<2=g17ee_+Q~ z(#e%F$&LflbT*k;gJ{^4K9>d838fpvKq(sz6s{$$7+2u@;0VQ1A)ORGRAxXNQ>L|x zAP`Ce7YGuZTnadp7IVk5nOtJA61{{76}TFx1Lnh(wNf7P!eR=miN~y@GWkkGAya`f zi^H)&(j;(J(hKPl&RDv65P2zwf5QihEI}O>77|5}HJ9DU9kLNZk}ssPk>ly3>3nK2 zorvTL%Te5l!pPgDEYkqyC2m220+YFNTD(#^`;IhX0+0AEhWU;h=!Btx;L1R%BXCzH zP7Gy5>eT6GuyKkcoIr1YAO*9)u>qOIu&`8sG>Ah4B6AsZ#ux)uU{RPZf8-V*{beyI z36i>HKf8V{ut14oF_%myuzx_DK@Q875@Lo;X8@THrdXk^Fel~i?=}#L7D;*(?Qq3$ zB=O?zGItA0?uMn8FK5!=ry_4mt01mjz<~r2)-a5ddwL1~P7y%zYoJhZg#;{+URcAy zTg07`mw<**P`sGJIXjn6e~T&hs-lVk4=lx?k&q@r9AC+;UPDJ525W^Z2$LcN7ITnP zi7a=dk|o)}HvJf!e=$u0uUB+&NMpxRWlL~2SHdA9X7{ud#-gW4mx?QRfmldYL~f!? z(E?^)EP*qn!9*KN(X{};@isOr%uSEX9~_t+7RKj1Q-c%xhsLKy zg}pFuY8qDhafn19IzKI7h7zgq;WFJaSc9jaPZ&M`4PkC8rTog z&l33tr)Lh$j*pJb3uDt0L&MOycNioa*gG*SvI3v&kb+NGBi9e0kr1u+L)+*m+>E^T1%|fx*^nzVpza@}Yr@&d!5_od*Xy4-S6s9vqM_;z#K6 z|AikXx))vPe;+Nq(T^znmj^54F9WXiZ%83%wG@n@-g&*_bviQsrUGI2{1;!6CSbil^kn#90HmqP01VGyWavxr9DH`=rE;LGc&^(nv zw^M5WACBEY8)`0N8d2Y^os_}mG6P640y0H2QnpHBmyGr;F5;PV~e^BnMb5%~Nw^J@w* zFH`t`e+^=-FvThDST#HsH_tEW~aPJ{rEe)idCNwqt3?%cC^PJuW@ z{>Tx`j-iwa%xWF2uX7CIm?IFe>+7@<(W>X3V;EY=KKS5+N*1^{yKi!WU@sGv-4j}; zGj`-O>Q>+516i19g{6|VPf2Gvixn5i^tRGu{;nWMKegH+Oq?D>;vRHij z>8GB;TJl#>nc{d+OBGM4c#hkyvx=is91NG0rnV{#BxI$bDk%-~*%L%*m4Z?cr6sK? zPO(*M6^FG3MR`fZt<5fAB+OeBVM^@>8YpA zJ)co4ky^NlsS=q_S`vMgLrLb{rHh3DCgF3A%rr=mX^-J zWnAwADo>p|fvK<=(F4?=04sqHe-Q8t;t3iU4mF}Rn2th0tNEFk2Om^%Ag4Ry#Q$Qi zs(9QAaxx~gMj>HB{lE6E1e&U@@88)S5gFqeQi^b{Ss6>oP-a5K?Phk3S7^Y!MMz49 zgo=!*Cry;3WVliyWJp4pN`q3;Aii@hNEcrf1vfC%MOK3W z>Mu@Lk46jM&1oGM9FLuvngwPSnQ*WVlRgA2i~u2nnT^kMFq}PEIk}sY2VFt~!D(n< zL)egfDkJ)S#wL6oHefaEe@PBD7@yr7YzQbAVGf($gM)z+xFBo8W5A&j+Z{Rs&LlKE zSTWsMi<#s?!H6i}4W}+HG>nM$2TOqv5xC(59!)V#ZB3u~AhE$fz{3dy$aH=-o;t91 zZ~_RE3e9~6Cn%1c{$@cgoY}T2f>vGEIJJX_gM)vOP(Z>~!6HBZ+U_`wmx8T=4L4t@j>NSxU2IqRC_^pUIweFi{G(`9Ok z3xyzkM-V~6%pyqSe}xklXmV-tXfN_1`>6YU)$!FtA^}b$LWVZq)Z8ko zImQM7gV%%UMN%TEV4#7}?1q6YCI+61eo}T7lApv3`HQNsiObn(8 zqA?8y5PEL(9P}6jHzt$_S@p*m?`qEXf_zWJb{}8&+4E&VGv^l2xj`V^cZKAdut1*` zl18q6-kf6~e|QXZ1<#>(oGT>Fs0`o#Z8_M?H_PBN_m^UFp5dIIR2aaL3dZ2%qSr@H zkl(_6U;eU+>f(52Cd!bLII%sR3S=o@OTx^14^u(e_nvBzxF2P!2%urlDH4YU`HJFx{sHcjs)tt`)ml5cV=^6 zw>Xf6>HZ=lCU-r{}}R=h;sOJ8dZpyF2kJ zX!jV32CtgzB3+qX!nQKEo0Un$24S< z+;sN-VOdeSGswL8#Ya7QYBABs(#T9_;AU!t$Yr}tygOx`JVoBo_Di6(eZG#4e0*4} ze;ifVRh7MYP1t#d`<=m0;6rT7vQ5x`@x zpoyc=Tu3A!4kdD<1W^l3&Waq_!#W*=e{kz`qCG6&zD|8j18kt|1*i>xX|6F~L{R|b zp#dTA%X}XY<3Lv*=+(Emzw6Af1WB4f+XGy;Qv`v9P;oRrNm)f%OHE5&Rb4|>Lk*CC zYF&&H1_UD)4oy1mDwl?B8VKB2@?MIuSb1plEMNx}kU*IO;El74vy7tG&h8YUe+Byd zw7tmR+Y?Gvn%$@qqy)AMv|-SKLF09Xj8_5BPyo~w!9sxJT+iWf)JDJzFqw-3h-lr} zTZDv!{OT62f&Z{>20(<`49d)D6asuk{5XG+kTvcY+-b=u3aZVyqPljYqT?ll?hSF? zm+kW+f?pDsmp{=-oTt8B#_DKOV z6!Fn3CakP~$MPjB-VGMWRZk!8D@%Ae?aKQ^BX6)Rsoen}8ec8SK;zm4UQ({NZn2v@ zu9h%#a$M(*qio7#l#C*uy(`}Xl=){1$@apIkOQw6D2vjBn#4mJDThWDe})^ied!bY z;P33%BoQfez*?l6qcU724T2dSeu18huy4Ev9yI`UWk3~} z;XSpPs2UXg+j;q)G2nCV?G|C~B{ltDaWJzJ$!90*JVp#Vn`$?ipU&H{o4)p1tJaar zx#UluTv-D`Er-4uW@4YYCN-|G-FI^jwqH@c&_G`J$|+M{V>537f3BY9ma15CK=Qqk z2-C~O*v^KSc5k8Nl}U|D^@8jXi@_QL~(O8izfz=CA8Ly3vb`L9k&$k5W)3w zn)_8GpPCt8{tYXqfARdTz5|5yA?;B{ZMm(m`>S#i&4l@JYEO*XJ4`2Sd=kpZ@zq2jbK#hRf|^XN!;2|;B=|{|~-DKE}7B#=(!HBSwkU_+Qw=X*HZ6q(Eo~m+OEczzCaGT{?cWl3&HaY1d z5G8b5OFzGZ`;yf1!MtqGcV+&DLRwQODa_9_a+Bz0*EtbJ5DktFnkcr6plO*D?34 z%JE+`qMEydqcZoi9qps4ZayX*iqBAZart$VY-`C@&(FDnD0qR4dr;E`^U@x)-O-&B z&#gAR4?&wpu{#NG6JD*xHIsJqFSZMnUaEfMf6j$?-y-pWs4gRwZHIE}6IGl8$oj=; zuJzK-R!c336H{<`s1a)rD<{a)LDf$7aIqR~H#(LTssCDl8KRrnXDuvhA+DK{L3UH& zm(>yq-LKxbvD*3KxQ>x^Y2V-@0#!$@Uo8eB_Z33vi50awuZ2SBs^o9X(uuKqj)k;Oa@(ax+P z-j;RfdC3IIyqFGNwKQIa07`+S_v0jlrxE1j#fnV|`>tMudL*+a4W z!^6dTuO9&n=Uq;ur~|553nTgdyw@sQe=JgTZi{!wpXT&WPaqTv4$Fw|>1k%4b=%+2 zC9!yw+AH`7=AEd`Emf=Xq{rui`M5=TQT` z&y?a%HFz*!U$(V$$?Inma*s9*$M1VAZ1vj1-};QJ0#Fs>Dw0erl+Ya!&~?q=F1HP@1yMI%yi*JXCBz> zoR(d3!)7(&x=hN(4Ykz8nT9!(f6uS?nycrTwH6@Ft#+JGr5+ZNGr_6lFUn@|y#-i& zufD;HM8YX7zQN){XG@(te{9(-(6qSi?g8z# zqI#Ripm%2P>B{ZCpH~G&%25aEMy?8{f0bj9HNPb5zffgF5WYs#EIn3_cab6w!ui&F z3Q&iYQcqvYr<Yfrdom+`+fo?yHu0pYbT#f-|dZB%eQ=@1ktzz4>d+H23C9 zQL6%C(herCOQo}me_zzI%#zOMUC|UyDqWZQ_1UXDzat|VH`QKt2xh5N4eUMm6r0w6 zV!@d~WNU@p;S=nGLC-Bt7Z@z+eXM!yo3vj9A|f=;jV;I^f4ovC)R+DwSQ!_*`~Hg? z60{$^QQFGQag@XF*6iB7Zc(j@hhr4o_Fwfz!SMq}?*~mxfBAQLqra*9XTAN4#SQGQ zM7V%z8a87kIzQGT*j$#{Av7wJw`|SCa97qKPmAD*o~OE7khbAR?hY+)H)z+SonNFb zP1`8leURo|s)6n5O9~K}F1r5-kVg?oN-ffO|-p&V^ey}g50GCBoZ65d}Gu5NiGX1agl|7 zuOC`>ybiexS4fS(lYd}_W>4P%3HTRQOaf2}iaG;ZC(W-}T3J=-*7u|BR_li<7R0EQnhv z`Eru~==kRd&tz|g4R2c>9>$9L@@lt-=?drC>OpGNjw`xu@=k9AtYuLY34=wVDdLSd z{)F9Bf571aV94{5!f#39l0xrIUazb-+_F_L6OJ~Q-Y~~hLm(ng z|Dgo`B{luO1ph&TXK^Gr)Xo1O70xvjV@Z0-?n~2S1|W5g=VVLyU3!ty}=4T2R%1CQBy+Y=t9&%WIz4R;Ue~JG|WfR%2w#7 z?Qs0G*S3hqwI+nbrBAh9ikJk@j_;D9S7+v&(*7K=C)Mk4XgFhZ3c&SlVWdf8sa@wS$bJ=XpTK&DDO|ZpD<@oyLZ5vsTz_Vw zCor7q?H6*IdA9&}R;&Ca`)()ea^OAj_gACf`-#9+fe(cML zv^+NwA&L}$eNjHb2tHugefy}~etUt3k*6QtKb6JY3os*d!~f=I*1S22M#B(j*x3;vLYE=AvL&k zpV~YgKa}2i^xPfP4dk=_H~q*RB$<6E*W7@5r}LL;Gv0324bWOF8X~Z(dByOU$uVIp z*FcZcuJGli;r*XS4HE##YwJH3@-e6ROIP)fPLQfX(P!`Fh1O8je@&K~y;xIZes;J` z+r0dv$msne1JOeMT_a~iQw%69Bni}zIF3~({ksCv>>h~x_+Ae5O*if`_Wrs>$wO;^XpDV!pJg)+T5`{SeFoyx=0Klw3 zNh0`iDsqApk2SqS%Z>-vep^R8t8GwuJtRQNS;VCUC}tlaFz zH8Myp>iIO1*sm0k@~*<(Io)*XPFwU;$0YF6a}HYcqTl3F{y;Auw3B>$zqQYU!OY&Q zFWq)*Z0Z4Auz%ocTUEK8QlFkC3)@p;5;#>j!KE}5JC^cAfA?w+Jj08%quivvAyIZn zA}w@$+6XXqqsOa^XD*B&$HS`D*;?Npjw`$3Rj=n6yltue)`!#ljU)2HQ+B?WRD(TRG8LZb-m${2H=HQlc-wubAQU2p5K z)s}PhIQm=-RiTu)#~}SyNT*PW-7tj;Y>?mk#Iy9Jd+f+3&~F@Uj|oOkj&TVqTZ928PwG^G^ET~Wx$SJC z(gOF}l5p;54612Bzl*pe-r#U{VZa-uU)dpldz#?zdFiF^*BHNXMoLhrwgrcy40<;4 z#mor0V8_mh?$dS@=Fjo5MTENar{6F(I9#H!$c83VO(oSr^CZsbREVhQ)n* z_aN@Ns_%Q?5;RwpS2j!yJ?lAOuiXL=6I@k3wqp9yxif(6I|dN6c|yHCZ_}Y+831ez)@p8@ z*U}E(75xA(w-WQ0wJus{DtpxRIl%RM0hDWIx1T-l_D{>V0xZ}A5E6Oz+@-V6P9NG1 zuwg8~3&-ZnYJZvORX=ziwx_}NisoQ~c6Z{d7{~S?bfphs$t2@AC5P^JldeC$7b@F5i#y?E&r!Wqb< ztf>P#Gy`Y_>{rBGQ946-40D1N>lOLfq>(7T0*?w13_@6tAWD)bNC&~@eHv0P#AZWy z+vDm@CVwyi9F=GcLAME36EH8&6Za@W`Ai{73Ozm=_A)N_TM!Gs(4^(CRvHcyPL-!n z!`ffko;<>>uvQTdV@_&MbG$tv<=3_SQ>N_0eye_;cBS&;?MN37Zd3d#l%1-M_$_FD zb$`1d=GWGh>yHN2FRoJzmx(Vx(<$?=#cOJSiGS+`$A8R37hERY0CAK zLeMKaA@ihk39RBiQ2*?BzlPDL+gE?vwQ!Nx2sNk53t9m+LBUX?45fT5TRW(35S(#3 zeSZjRAYS=2#D|1Hy!6t5a2v#*PJQLWr&n%JopE@=-*|E#ye&n{@wA|65RZFbe`5U; z=juzl$RB3k!FfM71}t;YsnW$a2DNj_GRjNfqJjOLG?sCvUb7!9KcFq)&B5)8xhJ2| z+!Xr_4i*ZsnJ$Gkrbj0+dRd8ig)J=}^qvp>BN=Al}J z#c&;J){m7Ff8-f@P@k8a{(bn=V}>#K{&bS$g0VkYZWB1g?@#^y({Iv!FkW~cpVz*E z3F0BBkeb0LesXdh?5_lM1ImSRqJI)l%_o&x2rl74NEA0iowyptiLXMc*a_25F}9(o zrKpLhdQ>)Q#?Owg^0dd7daCh>b{HWjz#!~^k%AkaM|!|4cuxJk!*A?47>64DTj~ls z!H#t;LObLL3$b1Y=!A12_r&t2UG7b z(o?_vdJrQaPE^4XF$NmM^I!>26RyMfay+}wh9%5RY5jd}z`W~x<-Q?`T38~i!S_{e zF#6m4t>X$`%J&__nY#2P2c;> zmoTIO6blxxfchD z)#6Af{Ot1Me|pkB%Kzx#N0)tc8Nf%YKNtbv`&O{=IGzUNWI5LC`<=UU`h7VQ7XJ8m zy7=sT`E?l|ns|ozXYoF%M1QG4y=%dez8Ln zOoN$BU|~$h5}1*tvx%&UO=WXg8|z?;*a~(9yNX@IHn5#+4||F|%bt@&Nn!^ig`|{% zq+lsTQn5^CW20Fys|6+dRvyc@Cw}J{#s%LuqzUlTMm6P`AaE{nRDYfi(#gLm>V#SO zO!WPpdZ~)wn=ACsmaGzZJ})cJ9=V{ug;l7FQRvH)y@F{2{DQF)Jo7X2`h!hul&{I3 zFe#nLSM&7SWwYtK%fvN{9^dvp1_pk^6JJZMPkh}?KJk$xlSE!Vg~V4JuUT0l|1_F~ zB<}$}I)3Hxt6>OK;ya1|CVB1~E2_pP-v1b%c%S2dU)5A+qEEc9Nj~v!{Hgb88mhr3z7r?= z#CPNr65o?}TFK&jQ~tJr>9j}j1e3+MZ~32S*A|K;Ab)3(82_zivq_Bm@@x|0 zg`d%@tq@H4ngLr7YzW3rO)8Uj-#iC-SmMM+U%CB=9-#p z9yhmOLd$@JX158Gst1>Go0{cfrokm0SaS9WB^^}K(O;73Ov7P#c9yBiY;y0bG@H6v zQ=JRLYkw=vjV5=G93Cf!C953KVk9{kYnZCy=2V*8tl3oMu3j{!v#Plg+v`%RD$EtL zRM}b3rBY*1jUjisxxI^}k7RN{NUtjG5+GR1yLF3}s+O7ViFK~3N_}#2qnrj6a$9a? zg*!-Y%XAJOGhAuv%G%R;RksdiG-qmNnrF70<$rREEm)~jtm^E%+#R0j&M;THGnO5U z!zs^lXPGOj+?i%&_RL1N(9Co8_;aG2JZF_Zr@wl$Ihik2RkQDB z(SMvc_o^AD>@4)Y{A0l%%s073Yx9iOIh-xCI?a`p${=5i{42`0V<=hVC8D!yv&s0ueUxB66s{q}q)fJQzJcT5E?inXfKHGgxqJE>Ve6ZhwAlS`lMb~K{<8qKa*jeM2N zI(Nna>@HdEQLcq^JE63{FrRslCD`N=^kO4lEle;~6uUb)~Pi{;m`-vgxePdEs+`$9d(qTgXn5ds09U7J91Aode zRn4j#Fu*~LDtrU;0^;&bD^me;qo-dtPPvHdwe_96akH;MFyR%1lYdrP$Fy8o98rLmW;LE}=IR!+NoT6=Z0Yu{n$g+i zaCEj;HP0#KZJ5W*>@?TAhU?|API9f#FXLTBKrO3nD9_Hqv!}ev%+}O(IoO)|Cf6<< z-WAp~xI6+ADw@k1yHYXFwabKOyPPWURG!EqCLZA}O~Od9TwcEmZ(pnATz^SUkmIf0 z4CJ(6e;R|@wlxr&E(6oym3xvb0fdFAO@Ebf0&z@ zM}k{0kL+TCQsY*cXO+9v=5n51#?#9vUCGmfaAU9-hR)$aDiXv~) z)a~^)xRUqjdm58*tDS{va(}r)GV$zJSkAz5qq&+fd9-^~YYQI-I9@s^vO-J7T3)TpL_Kx&A7QxK}m08#8&Qu5%jY?W}V{jky$;o!V4b zc}Mof&Iog!d~M>Tpt4-f5rSibdKabWF^Zivl9PfoIPz9AX0XX~Dyv>Z>uuTFK11vks%x?~SV}c$Z;2hA{d18WlN@jLe@QJBfIk~el zSbORUwDF3}OXt`C;NHe7#c4fsH5uAJ6PC6SWYvA0>&|;t(i?Br(g! zOmT>(I4Si>jNXOXffBuYFwvY=y-N-xnyN>&io>B;90pFY6n|NQEJhAR79k6f1;~7) z8JU7iMw-A0nIgXw&*QJ+2+G6QFicAobD;qx$e{vX>>HE>QDPcYq7I@&9CaF&p_GNF zOHntV_M^T*1>?|Du*CxGkzrjEmNsE&6Sio=8YZk^0;TYS$7o3E7QXiwGZEi;j9G|p z35N;aP~O)R`+th?CE*a^3&MY?WDntUO8kuQDd7{s$Ate7{!RE7;h@JDg7}DH9}@oQ zF+?B^cntA~4?G4t;(fwqy!W)Fw39k|M6J90!gYb94D}d+dPT+h=&Ld61Eby5FYR(<|6JV+(-59CEP=}n{XH5PQo2j z{dU4;!Y0CPgj)%>P}3U;8>sqv!p(#~6K*2hNcC>J!fL{$gg+53@#qT>7ZX+yRuV2EtRO5WTu4|(SV~wzSWH+%=pZa4 zEFjD$TtH|iw0RN=5$6-;5#|!kBb-Y(hcJh5Heohl7GWl#l`wNQm4pgH zIbjsRK`0}PB#a;oCk!K$5=uOAC5U3eP(l%*kWfI#C*%=w2{|%E=83am%ub0mLN+0b zkVzOq$RMN>(g;?9#S=RWkxDRoV)=$n@x+!Qk}1(dNFo>s20|i1Pe>rd6XFQ5gcw3J z^?wjWJw#Gs1RAx=;S<8gg#S=~|MtX~ z5&t3_^u*u>V;>Pd^u!b+{z*9CiK#$*;D3p!M7&RUkMOQ1rV8k4N0)iJpMC(-S=jafc_`fw-ND zY^EZcsK{+pObS z=sLt&DtQ&*N}Dsr)7 z8}d+CRnixsHAx3Fd}}QvEbxT$tu>!;0im7HMmV1^k1&^T9^qWV zaKbQ;j-!-NLMSE-B@__~2?d0FLY^m#@6%jD4k3aNPS6p;2%!Y62N$KAX$We9iV#8w zCIor3e5sX=Daik#dQhLEK7T`fiuweX^8?iTsP|CsqTWHhjd}~0tU6_?@`R5x2io?hk&=UaX$IcEuBF<}v*gHS;zCqIlLI0$8gk%SR6^?!w4^6?77a>6;DaC{VEa|maXTV@kx5oQuv2{Q;Sgl58Y!ZgBE z!dZkVgeF2G!9_TeFqz;aG!X0r8@W20kVVKO3?XC?(g|q zFkgTU7RHm4JAc%n)eCFpI~Q!3@08{j%om1zGoKxp&xD-$Y~uXp`2v>OK0h_RnwKt| zACpk6o1Zh^F<-o(rp?*DrOi2^t*vck+orZB+Y~F?*0l-SFeEtILbTQA*UWQ%Fpt4w zf){kCJ%ZOGs@ir7eZb%gq0ixE=b;16MMs=tJKH&D%YWI<*|wR^SzBg0lV+C96k2UF zoGrFy=XBdt=d>+TooCsaoKvuq(;Nn7fi6Kvz1 z<1u}lt=2hqORe(^Ta9zfmKx{88aCQi?W_`ulJH&vM*L|vt}-4nO6q1qyFq9-955U* zi0z4o5`Tr2dKQ+jGGSeU7=|wby~HQQuZ!Olzb#%7CI>`Kd&H^;p*?(6xR4X>2!AE~ zK)3|qo5O{$bzz&rwuOlk!ls9P5#|k(wuP~6p-+as94bx-ogUg2Du#vfxag?UIYMo@ z)nVEstz9b)w`uj5gGDD*i;pw@5B>^Z>>6mutnCi+PO5bWPn_arYuuK4{_3b} zax2%k!Pzv$)y3G=ja^KrXmCgIzh#%>tJkgtLwT*+Q19}Hn>QQE8*AOGc-Y~P!(JW+ zEPv9NIc-75f&~jR7i8iKYT5!!S=fO;G8n!hI~MYsg$n?SWDc+egMnohaCFE?3p%EE zU@Mq`$qVFU9-Af?$^5^;7W{mX|2boSWas~X8{k&v`+C8^jmS3x?$ZTv)A`3q0D^7< z=(`?{+r{|j7T5wi;Zb-Bo`+ZAYo>x`Sbq&q!bk8ae8oRxz=BvbOJo`FyIJ3#6!SnU z?g1sl0(g&jKk2*Q`w1Qpp#xH`$5^anJ)Yu?@b;XT)^~khci&4&HR$BJI^hLOJ;Zvv zM}#sS_ZIQEa5)dlH4X*c*0-&1)1cwB!+hv~C9o8h!G*8_E`pWtC%6nQhc$2o`hQ|2 zhOdOHU@cq?>);x=7OsQq;Rd)7Zh}9<&9ELez((}rt#BJ`^5yaPZTROVIhW_$0r$ZD zuoZbH+y!^Ty>K7KA3*PKg@-VWQYii)rfi1WG4&oy<)wJqHvHp;F7Uv1*nw+Caeu5E z_Q1pN2yz#$=5BZl9)~Az9rxhMK7TEz@f3gj$4k=dUtljh1JA;9@K^X7?u-}UMc4-~ z!OOoY=b8Q#9(x7;4*$TtwjW-D*WnF#3*LeE;R84TAL6e2{G|LhvBcY0<~?7je`2YB z!6#U<2TM{pD)X+K`?1`@eyn={4zgf4%mg?JUJUWoyGdT5_3}FM)#Iykmw)VMz8>2! z&R6K({9n2F!&c zijRdCvHd7KRl0udsjYYbqG7Z5dvAH)9lei<53>gLB6=hgytq>5GY4!|OoQ_j?cQ%$ ziuX&!Xz%CJ5%1?L*MIvBsKm|UY`hNsDUF5Y_#6m*3&eNu#1A~-0msNC#ad`8Mks<^a7Lt2~)X-Gu&KCK8n@|7a==$TUG(Z__3OI#yUl}oj1 zK@k#sYq~KyHGem8M6EVVs|eM{CL{(0hli?$)U@=jPq4(QRI!$XL7_*1gewF^?cAMa3yv9acE@5c@U4_P!?bDS1pSZIt@tum*mKr*v%v(#)VuQ?Lveczf#uVq~ml!qDnSBY9B(0$^(^e3r)Ub6*oq1&bu(SK=~)EgS9mXxtW%+m7kXtgM+V$@U-x1V+^GoQ-EbGa{ z$@P>ldrzLd2lr=03GPpQ*RN|OC$|x|v}8_Bv40kZ7Zl|uqeG(k9yf}tz$Tc@;e3Nf z9uG=I){3d^E64ZUmz-e9k5qKkPKGeEUo-+VIu3LZr1cjVU9f29RAld zj*!WGs=b-}d&>9=`fERKF#Th{vOaps5*11penCW05pEr2wC@_{SATSrQQ!{ZTT0T1 zN>xnRl#a^PuirG$b=!NZi)K12^(v((seeL4!faz^RgYWh%(9<(;kfGAW9(X$CRo}V zZ;p?MO-+uObmupB+|A&jrU-*oACYKHG!9A7m@~~~9rw(cfA8GF(}oz7rUoad_dKW`70R zHNv1>qZqJ9_Dp@~hpl}t$U9{0gJ0e~x$jWs^c$D1zGChTt+~PmPw(bh+6;A@KE3m- z+ZK*Gc1`gG_u;Cq^&SyhaYkwI2+gM}D6(6)!4ac1fYA_?9>&H6#c8x`Y>-Zk!AIGd z5a~ViFoq)|!E-z zCm(qnj(odT=ArExPL{SKC8fkZayPT%Jyhjebrnv`5mHhgC9irE|9ee`eX?)W`8B|g zRdOF*OFbCzZ<_y+Ui{u1bb%EO4ad`4zNyMS4(F%W@!PC~E(y_wXiJ+{yQbYdw{+OK zH#TKWwj7R#Qs9-xcIx6IRe#Z=n$JF`aO2?znws4|tZ(Q%yHc-_stiNoRjET#M=id0 zR@?paOQWJ#R(4UMHCC;TNs8+2HD)IyMyVR_|9Zow-mYn}$=1Yt+ON_|yo1_dpZ|=v z({8c&c1@~}Y9CcT0&)k^tl^&}iA_}_@b(rvWKyc^m(<;?6&#?!n}2W=kB4cJG=c_i zeS>ax@?9>IJC51+_vGp5cE?Tc2>G>5(Mjjqv;+4q9d6N>05?F$zvd50E49WvYg)cR z+n1;@(jL|t^Q~!lMh!ctHRPvR^NiY5l}@Ep;)|f}J?sxl&-z1s7WR%mOg?2dqEDkC z!|ziNZrJHi=_b)wnLUA@R@;C5@j>JDkBr@@^^YehkB{g0D313`y(uri6K6QQLA^QD z+MJwNyIp0Ai%aMhX6{JM)o4^0cmz_5>f$x(xZNxp-D&e4+MzQGV{>u4J4`$jtK+X) zdX2?v!=_A1uS;_F`yNy$ly5c_Tt)J8j|8`MSFTW#ez zCJl>|Sc*0&quA1=Pm3SmV#Cpc+HjSq;3rn%(U1DmFU~ItGnWiG)+@3hrKw?|SPOjD zQMV!jM!u>*|7lQOs;BEqb~*o<^riblsn8nrU4o2_^x zO%>12WE=k{9*2@{R(xNV;6qYLCLSs!$FCB5I62$%+ne-zm>g@hrkP`6qEB{jq*08` zw_1;HP^nv|w?wv^^E1=q`<_TFjTIzGt+%C`Z3(KO>1(Y88L5Af$6_+mtr1KVHHo&= z6kELNtXRCHLoH=_!qlP_!)n%z?VX~c8-q%^(r(up3)A}2GVALnrdQuwB}`Z8Gzx_V z_qiZ@Sj2sv2pMpZ@7|iK+$~%W;b0J+a)dy*MLsR?Njr19QmHX__dkTQ%pH#CI*tE! zCm+w;lk#z+fB1hF)$zo}t<; z@c;NVRM_arC<~WA&u7#5hpxjX=j{$h>c*pYu+7wf;u{L_&i!}s^dH?0!> z82+mo8E}=Ri8k>h=fuPsMc-3-Y-~&nE3l?nt$tsP3pSSK4aqZTq=nJxxsD-|{BFaC zuL=3(`td8yv?V*H4L9Uxr$^2UQ}sPqS{{|3z3BfC_Z`q}U1yrFqP+Led+!gug9O0} z76Bj#kQ9F@s#8=URV}L*%Ze=*$t8*7nw}F+$|f^=CW%B!q9ezd#F}K2*t1#3V^6XZ zCpqJDyv~Mu5>Gan*dny|z6XF1MbfgI-90!5cz{5>d;jk*-~ZqLUY%=M(_(hgG79LO zf8U>%u3q>y@OS@`Neg2Q9bj`rG)& zNDtDFJXiD9-Portx)bgMV}e-@!bG4iOCuB-zNAQlhqk>Yk@i_MoMpOAq<>V)DUlW~ zjb_Oj8-SJ;1f~{^%7L;$l~ckua~zG2{B?eHfn^Z2RGrW1BZBJt#WY`lf2?%>H+J+M zS>JzVqzSQ%k|u`_^v6m~=2&_A?(OB+s$*Z=5ZOH3sTPtLE|k!8EVnrw%my{lp~>Bo zgE92MouA#6(%PKHc*GVk(hi?P7wBX|UGZS7W9;ba@sE#3qI2@Z{eDt#%@#Ra-^`fG1Du6#{={O$O`8MlEk=pfstvl4@CL{BQK0bZHuLJd*zHOLCW2o317x%P>6}jy$oq+Z;qtQG>NvMXcNI$nxm1V zO2|ZDCXW&#Mj;{YhN(V5sb$xU_-_;%hRgL~=0$-ybP^$M@BhF>z0S+9l38r^WgQDX zp;%xq*_zT-Q<66glAgNTW~XiafF)__Zo{Y)G54+>l6fErwGy_ zZCg6tVy21i%FYfF)+xeqm5@dU1qyd((%a#Mr_y@>cxtmX4N6uc&~pK_5SLo z@n6TW193DS7kXglj(jpXi;B(*cOhMKT`(sYKQuRTs@d!Rq&0(bZE=Og3wL8FzHJ%~|=jl1;}ReJYxADiWGtU)$%Wqpf}|+S|URkZ?%d zEdC_xw)X5ScvoctjL6%y7QKJl60ys#XMv(XuK_!wj>LinvQ+vT%r8PKO7B?=3C4RDUyg7ck4)|b8ENL*FV*nDz|@l86hRWzv7Qs z%z9bh!!JGb@GFn?OLbOrJYiw=l*w+2Z@j0p@qtmV!D0|;{ZJzTibN|w5!M2{unO>H zt_pB3tOB613(`rD#K+H*JWADsf5jZWb@em<{CMRJ4uRIkUVf}t`IDn?bnCu->kpS% z%=yeu?{DLUoxSh-kK}(&Zb-~;3#~f?yZ5r#uCl8Tv2hlaUXruG zJOu{WIVPC|)}c5rsB6w4FtC?-zntLYiru6$E{CQewdVX$7>aQI`*5IGE4U;G@Km`E zT_uu=2|_FtRj!~9fRD&+CXbHd$1K*eW|Lb-y$LQ%Mvqopsfd4d9_XFU0nbW-(Yui3 zc@pq~FI+a$v;f|$oZ{AJID
$0) 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 delta 163221 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

eu|M6!=>yrF4# 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 D^ZvB( delta 15935 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 diff --git a/UserDocumentation/GigiViewerDX12_Documentation.pdf b/UserDocumentation/GigiViewerDX12_Documentation.pdf index 7c9d5dc7a7cb2566e84907313ccb5c956a18359b..e01a8ef8f3ec4668b4c2e4828b29fc73f93439ad 100644 GIT binary patch delta 133556 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ⅆipy29! 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

-am; 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 diff --git a/UserDocumentation/PythonTypes.txt b/UserDocumentation/PythonTypes.txt index 980ca65d..bd80e5bb 100644 --- a/UserDocumentation/PythonTypes.txt +++ b/UserDocumentation/PythonTypes.txt @@ -419,23 +419,24 @@ Host.GigiCompileResult_WrongVersion = 1 Host.GigiCompileResult_WrongParams = 2 Host.GigiCompileResult_CantLoadRenderGraph = 3 - Host.GigiCompileResult_ShaderReflection = 4 - Host.GigiCompileResult_Validation = 5 - Host.GigiCompileResult_ReferenceFixup = 6 - Host.GigiCompileResult_DepluralizeFileCopies = 7 - Host.GigiCompileResult_NoBackend = 8 - Host.GigiCompileResult_BackendData = 9 - Host.GigiCompileResult_Sanitize = 10 - Host.GigiCompileResult_NotCompiledYet = 11 - Host.GigiCompileResult_InterpreterError = 12 - Host.GigiCompileResult_InlineSubGraphs = 13 - Host.GigiCompileResult_ErrorCheck = 14 - Host.GigiCompileResult_ShaderFileDuplication = 15 - Host.GigiCompileResult_AddNodeInfoToShaders = 16 - Host.GigiCompileResult_DataFixup = 17 - Host.GigiCompileResult_DfltFixup = 18 - Host.GigiCompileResult_LAST = 18 - Host.GigiCompileResult_COUNT = 19 + Host.GigiCompileResult_ShaderAsserts = 4 + Host.GigiCompileResult_ShaderReflection = 5 + Host.GigiCompileResult_Validation = 6 + Host.GigiCompileResult_ReferenceFixup = 7 + Host.GigiCompileResult_DepluralizeFileCopies = 8 + Host.GigiCompileResult_NoBackend = 9 + Host.GigiCompileResult_BackendData = 10 + Host.GigiCompileResult_Sanitize = 11 + Host.GigiCompileResult_NotCompiledYet = 12 + Host.GigiCompileResult_InterpreterError = 13 + Host.GigiCompileResult_InlineSubGraphs = 14 + Host.GigiCompileResult_ErrorCheck = 15 + Host.GigiCompileResult_ShaderFileDuplication = 16 + Host.GigiCompileResult_AddNodeInfoToShaders = 17 + Host.GigiCompileResult_DataFixup = 18 + Host.GigiCompileResult_DfltFixup = 19 + Host.GigiCompileResult_LAST = 19 + Host.GigiCompileResult_COUNT = 20 GigiCompileWarning: Host.GigiCompileWarning_FIRST = 0 @@ -468,11 +469,13 @@ Host.SetVariableOperator_Divide = 3 Host.SetVariableOperator_Modulo = 4 Host.SetVariableOperator_PowerOf2GE = 5 - Host.SetVariableOperator_BitwiseOr = 6 - Host.SetVariableOperator_BitwiseAnd = 7 - Host.SetVariableOperator_BitwiseXor = 8 - Host.SetVariableOperator_BitwiseNot = 9 - Host.SetVariableOperator_Noop = 10 - Host.SetVariableOperator_LAST = 10 - Host.SetVariableOperator_COUNT = 11 + Host.SetVariableOperator_Minimum = 6 + Host.SetVariableOperator_Maximum = 7 + Host.SetVariableOperator_BitwiseOr = 8 + Host.SetVariableOperator_BitwiseAnd = 9 + Host.SetVariableOperator_BitwiseXor = 10 + Host.SetVariableOperator_BitwiseNot = 11 + Host.SetVariableOperator_Noop = 12 + Host.SetVariableOperator_LAST = 12 + Host.SetVariableOperator_COUNT = 13 diff --git a/external/df_serialize/Config.h b/external/df_serialize/Config.h index c368f06d..953cafda 100644 --- a/external/df_serialize/Config.h +++ b/external/df_serialize/Config.h @@ -34,6 +34,7 @@ #include #include #include +#include #include "GigiAssert.h" // flags used by struct fields @@ -42,6 +43,7 @@ #define SCHEMA_FLAG_UI_COLLAPSABLE ((size_t) (1 << 1)) // This field should have a collapsable header #define SCHEMA_FLAG_UI_ARRAY_FATITEMS ((size_t) (1 << 2)) // If true, puts all items on the same line. #define SCHEMA_FLAG_NO_SERIALIZE ((size_t) (1 << 3)) // Don't load / save. Also don't show in UI, and don't generate equality tests. -#define SCHEMA_FLAG_UI_MULTILINETEXT ((size_t) (1 << 4)) // if true, the text edit box is multiline -#define SCHEMA_FLAG_UI_ARRAY_HIDE_INDEX ((size_t) (1 << 5)) // If true, does not show the index of array items -#define SCHEMA_FLAG_UI_CONST ((size_t) (1 << 6)) // If true, does not allow field to be edited +#define SCHEMA_FLAG_SERIALIZE_DFLT ((size_t) (1 << 4)) // Write value, even if it's the default value +#define SCHEMA_FLAG_UI_MULTILINETEXT ((size_t) (1 << 5)) // if true, the text edit box is multiline +#define SCHEMA_FLAG_UI_ARRAY_HIDE_INDEX ((size_t) (1 << 6)) // If true, does not show the index of array items +#define SCHEMA_FLAG_UI_CONST ((size_t) (1 << 7)) // If true, does not allow field to be edited diff --git a/external/df_serialize/MakeJSONWriteHeader.h b/external/df_serialize/MakeJSONWriteHeader.h index ae416fd3..5a269ae6 100644 --- a/external/df_serialize/MakeJSONWriteHeader.h +++ b/external/df_serialize/MakeJSONWriteHeader.h @@ -62,7 +62,7 @@ enum class JSONWriteOverrideResult if (((_FLAGS) & SCHEMA_FLAG_NO_SERIALIZE) == 0) \ { \ static const _TYPE c_defaultValue = _DEFAULT; \ - if (value._NAME != c_defaultValue) \ + if (value._NAME != c_defaultValue || (((_FLAGS) & SCHEMA_FLAG_SERIALIZE_DFLT) != 0)) \ ret.AddMember(#_NAME, MakeJSONValue(value._NAME, allocator), allocator); \ } @@ -91,7 +91,7 @@ enum class JSONWriteOverrideResult break; \ } \ } \ - if (different) \ + if (different || (((_FLAGS) & SCHEMA_FLAG_SERIALIZE_DFLT) != 0)) \ { \ rapidjson::Value arr; \ arr.SetArray(); \ diff --git a/gigihelp.html b/gigihelp.html index 3952862e..559b12b6 100644 --- a/gigihelp.html +++ b/gigihelp.html @@ -359,6 +359,7 @@

Enums

WrongVersion WrongParams CantLoadRenderGraph +ShaderAsserts ShaderReflection Validation ReferenceFixup @@ -412,6 +413,8 @@

Enums

Divide/ Modulo% PowerOf2GEThe next power of two, greater or equal to the current value +Minimummin(A,B) +Maximummax(A,B) BitwiseOrA | B BitwiseAndA & B BitwiseXorA ^ B @@ -448,6 +451,14 @@

Structs


+VariableReferenceConstOnly : A reference to a variable. Only const variables allowed.

+ + + + +
VariableReferenceConstOnly
std::string name""The name of the variable.
int variableIndex-1Calculated for convenience.
+
+ StructReference : A reference to a struct

@@ -687,6 +698,14 @@

Structs

StructReference

+TokenReplacement : A shader token replacement

+ + + + +
TokenReplacement
std::string name""The token string.
std::string value""The replacement.
+
+ LoadedTextureReference : Information about a loaded texture referenced by this shader.

@@ -723,6 +742,7 @@

Structs

+ @@ -756,12 +776,13 @@

Structs

- + + @@ -993,6 +1014,7 @@

Structs

+
LoadedTextureReference
ShaderType typeShaderType::ComputeThe type of shader it is
std::string entryPoint""The shader entrypoint.
ShaderDefine defines[]The defines the shader is compiled with.
TokenReplacement tokenReplacements[]The token replacements specific for the shader.
int CSNumThreads[3]{ 8 , 8 , 1 }For compute shaders only, the number of threads each dispatch has. 61,1,1 suggested for 1d. 8,8,1 for 2d. 4,4,4 for 3d.
int NumThreads[3]{ 8 , 8 , 1 }The number of threads each dispatch has, for applicable shader types. 64,1,1 suggested for 1d. 8,8,1 for 2d. 4,4,4 for 3d.
bool copyFiletrueif false, will not copy the file over. A hackaround for when you have multiple raytracing shaders in the same file. TODO: resolve this better.
DataFieldType typeDataFieldType::CountThe type of the variable
bool ConstfalseIf true, the variable is declared const and cannot change at runtime
bool StaticfalseIf true, the variable has the same value for all instances of the technique
std::string dflt""The default value of the variable
std::string dflt""The default value of the variable. The default memory is zero initialized before this is parsed, so if you don't give it enough initializers, it will use zero for the unlisted fields.
VariableVisibility visibilityVariableVisibility::InternalWho can see and interact with this variable
std::string Enum""Integer types can specify an enum, which will then make symbols in both C++ and shader code.
BackendRestriction backends{}This variable can be limited to specific backends
bool transientfalseIf true, the variable should not be saved between runs of this technique. The Gigi viewer uses this to decide if it should save it in the gguser file or not, for example.
VariableUISettings UISettings{}UI Settings.
std::string UIGroup""Used to organize variables into folders in the viewer. separate folders with dots. For instance: settings.controls
int enumIndex-1Calculated for convenience.
std::string originalName""The name before renames and sanitization
std::string scope""The scope that the node lives in. A possibly nested list of subgraph node names, seperated by a dot.
std::string name""variable name
VariableVisibility visibilityVariableVisibility::InternalWho can see and interact with this variable
std::string replaceWithStr{}If set, the subgraph variable will be deleted and all references will use this parent graph variable instead.
std::string replaceWithValue{}Replace the variable with a literal value. At gigi compile time it makes an internal private variable of the correct type with this string as the default value.
bool isLoopIndexfalseIf true, this variable will recieve the loop index.
VariableReference replaceWith{}If set, the subgraph variable will be deleted and all references will use this parent graph variable instead.
@@ -1014,7 +1036,7 @@

Structs

float editorPos[2]{ 0.0f , 0.0f }The position of the node in the editor std::unordered_map inputPinIds{} std::unordered_map outputPinIds{} -int nodeIndex-1The index in the list of render graph nodes +int nodeIndex-1The index in the list of render graph nodes. This is filled in after loading by the ReferenceFixupVisitor and is in [0,N) with no gaps. std::string originalName""The name before renames and sanitization
@@ -1189,6 +1211,7 @@

Structs

SubGraphData subGraphData{}A cache of the interface of the other graph. SubGraphVariableSettings variableSettings[]Per variable settings for subgraph variables. int loopCount1Number of times to execute the technique. +VariableReferenceConstOnly loopCountVariable{}The variable to use for the loopCount. Only const variables supported currently. int loopIndex-1When unrolling subgraph loops, the loop index of the node is stored here.
@@ -1327,6 +1350,7 @@

Structs

std::string JitteredViewProjMtx_varName"JitteredViewProjMtx"ViewProjMtx with jitter. std::string InvJitteredViewProjMtx_varName"InvJitteredViewProjMtx"Inverted ViewProjMtx with jitter. std::string CameraPos_varName"CameraPos" +std::string CameraAltitudeAzimuth_varName"CameraAltitudeAzimuth" std::string CameraChanged_varName"CameraChanged" std::string CameraJitter_varName"CameraJitter" std::string ShadingRateImageTileSize_varName"ShadingRateImageTileSize" @@ -1342,35 +1366,53 @@

Structs


-GGUserFile_Bookmark : A bookmark for resources to show up in a short list, to be more quickly found.

- - - - -
GGUserFile_Bookmark
std::string name""
std::string viewableResourceDisplayName""
-
- -GGUserFile_ImportedResourcePreset : A preset of imported resource settings

+GGUserFileV1 : The contents of a .gguser file

- - + + + + + + + +
GGUserFile_ImportedResourcePreset
std::string name""
GGUserFileV1
std::string version"1.0"The version of the .gguser file
GGUserFile_SystemVars systemVars{}
int resourceViewType0The type of resource being viewed
int resourceViewNodeIndex-1The index of the node bieng viewed
int resourceViewResourceIndex-1The index of that resource within that node being used
int syncInterval1IDXGISwapChain::Present() parameter: Synchronize presentation after the nth vertical blank.
GGUserFile_ImportedResource importedResources[]
GGUserFile_SavedVariable savedVariables[]

-GGUserFile : The contents of a .gguser file

+GGUserFileV2Snapshot : The snapshot of a GGUserFileV2

- - - + + - + + + + + + - - +
GGUserFile
std::string version"1.0"The version of the .gguser file
GGUserFile_SystemVars systemVars{}
GGUserFileV2Snapshot
std::string name""The snapshot name
int resourceViewType0The type of resource being viewed
int resourceViewNodeIndex-1The index of the node bieng viewed
int resourceViewResourceIndex-1The index of that resource within that node being used
int syncIntervaltrueIDXGISwapChain::Present() parameter: Synchronize presentation after the nth vertical blank.
bool loadVarstrueWhether variables will be loaded from this snapshot
bool loadCameratrueWhether the camera will be loaded from this snapshot
bool loadResourcestrueWhether imported resources will be loaded from this snapshot
bool loadViewtrueWhether the resource viewed will be loaded from this snapshot
float cameraPos[3]{ 0.0f , 0.0f , - 10.0f }Used by snapshots to capture the camera position
float cameraAltitudeAzimuth[2]{ 0.0f , 0.0f }Used by snapshots to capture the camera orientation
GGUserFile_ImportedResource importedResources[]
GGUserFile_SavedVariable savedVariables[]
GGUserFile_Bookmark bookmarks[]
GGUserFile_ImportedResourcePreset importedResourcePresets[]
+
+ +GGUserFileV2 : The contents of a .gguser file

+ + + + + + + +
GGUserFileV2
std::string version"2.0"The version of the .gguser file
int syncInterval1IDXGISwapChain::Present() parameter: Synchronize presentation after the nth vertical blank.
GGUserFile_SystemVars systemVars{}
GGUserFileV2Snapshot snapshot{}
GGUserFileV2Snapshot snapshots[]
+
+ +GGUserFileVersionOnly : Only the version of the .gguser file

+ + +
GGUserFileVersionOnly
std::string version"1.0"The version of the .gguser file

@@ -1542,6 +1584,8 @@

Structs

std::string versionUpgradedMessage""Text to show about the version upgrade BackendTemplateConfig templateConfig{}Code generation template config bool generateGraphVizFlagfalseSet to true if the generating GraphViz. Should be set to true from a command line parameter +std::vector assertsFormatStrings{}The unique formatting strings of the asserts messages +std::unordered_set firedAssertsIdentifiers{}The identifiers of the fired asserts to ignore them later on
diff --git a/gigischema.json b/gigischema.json index dcecedb1..d7752686 100644 --- a/gigischema.json +++ b/gigischema.json @@ -43,7 +43,7 @@ "type": "boolean" }, "dflt": { - "description": "The default value of the variable", + "description": "The default value of the variable. The default memory is zero initialized before this is parsed, so if you don't give it enough initializers, it will use zero for the unlisted fields.", "type": "string" }, "visibility": { @@ -100,6 +100,10 @@ } } }, + "UIGroup": { + "description": "Used to organize variables into folders in the viewer. separate folders with dots. For instance: settings.controls", + "type": "string" + }, "UIHint": { "description": "Any hints for UI", "type": "string", @@ -2138,6 +2142,10 @@ "description": "If set, the subgraph variable will be deleted and all references will use this parent graph variable instead.", "type": "string" }, + "replaceWithValue": { + "description": "Replace the variable with a literal value. At gigi compile time it makes an internal private variable of the correct type with this string as the default value.", + "type": "string" + }, "isLoopIndex": { "description": "If true, this variable will recieve the loop index.", "type": "boolean" @@ -2158,6 +2166,16 @@ "loopCount": { "description": "Number of times to execute the technique.", "type": "integer" + }, + "loopCountVariable": { + "description": "The variable to use for the loopCount. Only const variables supported currently.", + "type": "object", + "properties": { + "name": { + "description": "The name of the variable.", + "type": "string" + } + } } } }, @@ -2369,7 +2387,7 @@ "op": { "description": "", "type": "string", - "enum": ["Add", "Subtract", "Multiply", "Divide", "Modulo", "PowerOf2GE", "BitwiseOr", "BitwiseAnd", "BitwiseXor", "BitwiseNot", "Noop"] + "enum": ["Add", "Subtract", "Multiply", "Divide", "Modulo", "PowerOf2GE", "Minimum", "Maximum", "BitwiseOr", "BitwiseAnd", "BitwiseXor", "BitwiseNot", "Noop"] }, "BVar": { "description": "The variable on the right side of the operator",