SMAAFeatureProcessor.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <PostProcessing/SMAAConfigurationDescriptor.h>
  9. #include <PostProcessing/SMAAFeatureProcessor.h>
  10. #include <PostProcessing/SMAAEdgeDetectionPass.h>
  11. #include <PostProcessing/SMAABlendingWeightCalculationPass.h>
  12. #include <PostProcessing/SMAANeighborhoodBlendingPass.h>
  13. #include <Atom/RHI/Factory.h>
  14. #include <Atom/RPI.Public/Pass/PassFilter.h>
  15. #include <Atom/RPI.Public/Pass/PassSystemInterface.h>
  16. #include <Atom/RPI.Public/RPISystemInterface.h>
  17. #include <Atom/RPI.Public/Scene.h>
  18. #include <Atom/RPI.Public/View.h>
  19. #include <Atom/RPI.Reflect/Asset/AssetUtils.h>
  20. namespace AZ
  21. {
  22. namespace Render
  23. {
  24. void SMAAFeatureProcessor::Reflect(ReflectContext* context)
  25. {
  26. if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
  27. {
  28. serializeContext
  29. ->Class<SMAAFeatureProcessor, FeatureProcessor>()
  30. ->Version(0);
  31. }
  32. SMAAConfigurationDescriptor::Reflect(context);
  33. }
  34. SMAAFeatureProcessor::SMAAFeatureProcessor()
  35. : SMAAFeatureProcessorInterface()
  36. , m_convertToPerceptualColorPassTemplateNameId(SMAAConvertToPerceptualColorPassTemplateName)
  37. , m_edgeDetectioPassTemplateNameId(SMAAEdgeDetectionPassTemplateName)
  38. , m_blendingWeightCalculationPassTemplateNameId(SMAABlendingWeightCalculationPassTemplateName)
  39. , m_neighborhoodBlendingPassTemplateNameId(SMAANeighborhoodBlendingPassTemplateName)
  40. {
  41. }
  42. void SMAAFeatureProcessor::Activate()
  43. {
  44. Data::Asset<RPI::AnyAsset> smaaAsset = RPI::AssetUtils::LoadAssetByProductPath<RPI::AnyAsset>("passes/SMAAConfiguration.azasset", RPI::AssetUtils::TraceLevel::Error);
  45. const SMAAConfigurationDescriptor* smaaConfigurationDescriptor = RPI::GetDataFromAnyAsset<SMAAConfigurationDescriptor>(smaaAsset);
  46. m_data.m_enable = smaaConfigurationDescriptor->m_enable != 0;
  47. SetQualityByPreset(static_cast<SMAAQualityPreset>(smaaConfigurationDescriptor->m_quality));
  48. m_data.m_edgeDetectionMode = static_cast<SMAAEdgeDetectionMode>(smaaConfigurationDescriptor->m_edgeDetectionMode);
  49. m_data.m_outputMode = static_cast<SMAAOutputMode>(smaaConfigurationDescriptor->m_outputMode);
  50. smaaAsset.Release();
  51. }
  52. void SMAAFeatureProcessor::Deactivate()
  53. {
  54. m_data = {};
  55. }
  56. void SMAAFeatureProcessor::Simulate(const FeatureProcessor::SimulatePacket& packet)
  57. {
  58. AZ_PROFILE_FUNCTION(AzRender);
  59. AZ_UNUSED(packet);
  60. }
  61. void SMAAFeatureProcessor::UpdateConvertToPerceptualPass()
  62. {
  63. RPI::PassFilter passFilter = RPI::PassFilter::CreateWithTemplateName(m_convertToPerceptualColorPassTemplateNameId, GetParentScene());
  64. RPI::PassSystemInterface::Get()->ForEachPass(passFilter, [this](RPI::Pass* pass) -> RPI::PassFilterExecutionFlow
  65. {
  66. pass->SetEnabled(m_data.m_enable);
  67. return RPI::PassFilterExecutionFlow::ContinueVisitingPasses;
  68. });
  69. }
  70. void SMAAFeatureProcessor::UpdateEdgeDetectionPass()
  71. {
  72. RPI::PassFilter passFilter = RPI::PassFilter::CreateWithTemplateName(m_edgeDetectioPassTemplateNameId, GetParentScene());
  73. RPI::PassSystemInterface::Get()->ForEachPass(passFilter, [this](RPI::Pass* pass) -> RPI::PassFilterExecutionFlow
  74. {
  75. auto* edgeDetectionPass = azrtti_cast<AZ::Render::SMAAEdgeDetectionPass*>(pass);
  76. edgeDetectionPass->SetEnabled(m_data.m_enable);
  77. if (m_data.m_enable)
  78. {
  79. edgeDetectionPass->SetEdgeDetectionMode(m_data.m_edgeDetectionMode);
  80. edgeDetectionPass->SetChromaThreshold(m_data.m_chromaThreshold);
  81. edgeDetectionPass->SetDepthThreshold(m_data.m_depthThreshold);
  82. edgeDetectionPass->SetLocalContrastAdaptationFactor(m_data.m_localContrastAdaptationFactor);
  83. edgeDetectionPass->SetPredicationEnable(m_data.m_predicationEnable);
  84. edgeDetectionPass->SetPredicationThreshold(m_data.m_predicationThreshold);
  85. edgeDetectionPass->SetPredicationScale(m_data.m_predicationScale);
  86. edgeDetectionPass->SetPredicationStrength(m_data.m_predicationStrength);
  87. }
  88. return RPI::PassFilterExecutionFlow::ContinueVisitingPasses;
  89. });
  90. }
  91. void SMAAFeatureProcessor::UpdateBlendingWeightCalculationPass()
  92. {
  93. RPI::PassFilter passFilter = RPI::PassFilter::CreateWithTemplateName(m_blendingWeightCalculationPassTemplateNameId, GetParentScene());
  94. RPI::PassSystemInterface::Get()->ForEachPass(passFilter, [this](RPI::Pass* pass) -> RPI::PassFilterExecutionFlow
  95. {
  96. auto* blendingWeightCalculationPass = azrtti_cast<AZ::Render::SMAABlendingWeightCalculationPass*>(pass);
  97. blendingWeightCalculationPass->SetEnabled(m_data.m_enable);
  98. if (m_data.m_enable)
  99. {
  100. blendingWeightCalculationPass->SetMaxSearchSteps(m_data.m_maxSearchSteps);
  101. blendingWeightCalculationPass->SetMaxSearchStepsDiagonal(m_data.m_maxSearchStepsDiagonal);
  102. blendingWeightCalculationPass->SetCornerRounding(m_data.m_cornerRounding);
  103. blendingWeightCalculationPass->SetDiagonalDetectionEnable(m_data.m_enableDiagonalDetection);
  104. blendingWeightCalculationPass->SetCornerDetectionEnable(m_data.m_enableCornerDetection);
  105. }
  106. return RPI::PassFilterExecutionFlow::ContinueVisitingPasses;
  107. });
  108. }
  109. void SMAAFeatureProcessor::UpdateNeighborhoodBlendingPass()
  110. {
  111. RPI::PassFilter passFilter = RPI::PassFilter::CreateWithTemplateName(m_neighborhoodBlendingPassTemplateNameId, GetParentScene());
  112. RPI::PassSystemInterface::Get()->ForEachPass(passFilter, [this](RPI::Pass* pass) -> RPI::PassFilterExecutionFlow
  113. {
  114. auto* neighborhoodBlendingPass = azrtti_cast<AZ::Render::SMAANeighborhoodBlendingPass*>(pass);
  115. if (m_data.m_enable)
  116. {
  117. neighborhoodBlendingPass->SetOutputMode(m_data.m_outputMode);
  118. }
  119. else
  120. {
  121. neighborhoodBlendingPass->SetOutputMode(SMAAOutputMode::PassThrough);
  122. }
  123. return RPI::PassFilterExecutionFlow::ContinueVisitingPasses;
  124. });
  125. }
  126. void SMAAFeatureProcessor::Render([[maybe_unused]] const SMAAFeatureProcessor::RenderPacket& packet)
  127. {
  128. AZ_PROFILE_SCOPE(RPI, "SMAAFeatureProcessor: Render");
  129. UpdateConvertToPerceptualPass();
  130. UpdateEdgeDetectionPass();
  131. UpdateBlendingWeightCalculationPass();
  132. UpdateNeighborhoodBlendingPass();
  133. }
  134. void SMAAFeatureProcessor::SetEnable(bool enable)
  135. {
  136. m_data.m_enable = enable;
  137. }
  138. void SMAAFeatureProcessor::SetQualityByPreset(SMAAQualityPreset preset)
  139. {
  140. switch (preset)
  141. {
  142. case SMAAQualityPreset::Low:
  143. // SMAA_PRESET_LOW
  144. SetChromaThreshold(0.15f);
  145. SetMaxSearchSteps(4);
  146. SetDiagonalDetectionEnable(false);
  147. SetCornerDetectionEnable(false);
  148. break;
  149. case SMAAQualityPreset::Middle:
  150. // SMAA_PRESET_MEDIUM
  151. SetChromaThreshold(0.1f);
  152. SetMaxSearchSteps(8);
  153. SetDiagonalDetectionEnable(false);
  154. SetCornerDetectionEnable(false);
  155. break;
  156. case SMAAQualityPreset::High:
  157. // SMAA_PRESET_HIGH
  158. SetChromaThreshold(0.1f);
  159. SetMaxSearchSteps(16);
  160. SetMaxSearchStepsDiagonal(8);
  161. SetCornerRounding(25);
  162. SetDiagonalDetectionEnable(true);
  163. SetCornerDetectionEnable(true);
  164. break;
  165. case SMAAQualityPreset::Ultra:
  166. // SMAA_PRESET_ULTRA
  167. SetChromaThreshold(0.05f);
  168. SetMaxSearchSteps(32);
  169. SetMaxSearchStepsDiagonal(16);
  170. SetCornerRounding(25);
  171. SetDiagonalDetectionEnable(true);
  172. SetCornerDetectionEnable(true);
  173. break;
  174. }
  175. }
  176. void SMAAFeatureProcessor::SetEdgeDetectionMode(SMAAEdgeDetectionMode mode)
  177. {
  178. m_data.m_edgeDetectionMode = mode;
  179. }
  180. void SMAAFeatureProcessor::SetChromaThreshold(float threshold)
  181. {
  182. m_data.m_chromaThreshold = threshold;
  183. }
  184. void SMAAFeatureProcessor::SetDepthThreshold(float threshold)
  185. {
  186. m_data.m_depthThreshold = threshold;
  187. }
  188. void SMAAFeatureProcessor::SetLocalContrastAdaptationFactor(float factor)
  189. {
  190. m_data.m_localContrastAdaptationFactor = factor;
  191. }
  192. void SMAAFeatureProcessor::SetPredicationEnable(bool enable)
  193. {
  194. m_data.m_predicationEnable = enable;
  195. }
  196. void SMAAFeatureProcessor::SetPredicationThreshold(float threshold)
  197. {
  198. m_data.m_predicationThreshold = threshold;
  199. }
  200. void SMAAFeatureProcessor::SetPredicationScale(float scale)
  201. {
  202. m_data.m_predicationScale = scale;
  203. }
  204. void SMAAFeatureProcessor::SetPredicationStrength(float strength)
  205. {
  206. m_data.m_predicationStrength = strength;
  207. }
  208. void SMAAFeatureProcessor::SetMaxSearchSteps(int steps)
  209. {
  210. m_data.m_maxSearchSteps = steps;
  211. }
  212. void SMAAFeatureProcessor::SetMaxSearchStepsDiagonal(int steps)
  213. {
  214. m_data.m_maxSearchStepsDiagonal = steps;
  215. }
  216. void SMAAFeatureProcessor::SetCornerRounding(int cornerRounding)
  217. {
  218. m_data.m_cornerRounding = cornerRounding;
  219. }
  220. void SMAAFeatureProcessor::SetDiagonalDetectionEnable(bool enable)
  221. {
  222. m_data.m_enableDiagonalDetection = enable;
  223. }
  224. void SMAAFeatureProcessor::SetCornerDetectionEnable(bool enable)
  225. {
  226. m_data.m_enableCornerDetection = enable;
  227. }
  228. void SMAAFeatureProcessor::SetOutputMode(SMAAOutputMode mode)
  229. {
  230. m_data.m_outputMode = mode;
  231. }
  232. const SMAAData& SMAAFeatureProcessor::GetSettings() const
  233. {
  234. return m_data;
  235. }
  236. } // namespace Render
  237. } // namespace AZ