GradientSignalSamplerTests.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  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 <Tests/GradientSignalTestFixtures.h>
  9. #include <AzTest/AzTest.h>
  10. #include <AzCore/Asset/AssetManager.h>
  11. #include <AzCore/Memory/PoolAllocator.h>
  12. #include <AzCore/Math/Vector2.h>
  13. #include <AZTestShared/Math/MathTestHelpers.h>
  14. #include <GradientSignal/GradientSampler.h>
  15. namespace UnitTest
  16. {
  17. struct GradientSignalSamplerTestsFixture : public GradientSignalTest
  18. {
  19. void TestGradientSampler(
  20. GradientSignal::GradientSampler& gradientSampler,
  21. const AZStd::vector<float>& gradientInput,
  22. const AZStd::vector<float>& expectedOutput,
  23. int dataSize)
  24. {
  25. auto mockGradient = CreateEntity();
  26. const AZ::EntityId gradientId = mockGradient->GetId();
  27. MockGradientArrayRequestsBus mockGradientRequestsBus(gradientId, gradientInput, dataSize);
  28. gradientSampler.m_gradientId = gradientId;
  29. TestFixedDataSampler(expectedOutput, dataSize, gradientSampler);
  30. }
  31. };
  32. TEST_F(GradientSignalSamplerTestsFixture, DefaultSamplerReturnsExactGradientValues)
  33. {
  34. const int dataSize = 3; // 3x3 data
  35. // The default gradient sampler should return back the exact same set of values that our mock gradient defines.
  36. AZStd::vector<float> mockInputAndExpectedOutput =
  37. {
  38. 0.0f, 0.1f, 0.2f,
  39. 0.4f, 0.5f, 0.6f,
  40. 0.8f, 0.9f, 1.0f
  41. };
  42. GradientSignal::GradientSampler gradientSampler;
  43. TestGradientSampler(gradientSampler, mockInputAndExpectedOutput, mockInputAndExpectedOutput, dataSize);
  44. }
  45. TEST_F(GradientSignalSamplerTestsFixture, SamplerWithInvertReturnsInvertedGradientValues)
  46. {
  47. // If "invertInput" is set, the gradient sampler should return back values that are inverted from the mock gradient.
  48. const int dataSize = 3; // 3x3 data
  49. AZStd::vector<float> mockInput =
  50. {
  51. 0.0f, 0.1f, 0.2f,
  52. 0.4f, 0.5f, 0.6f,
  53. 0.8f, 0.9f, 1.0f
  54. };
  55. AZStd::vector<float> expectedOutput =
  56. {
  57. 1.0f, 0.9f, 0.8f,
  58. 0.6f, 0.5f, 0.4f,
  59. 0.2f, 0.1f, 0.0f
  60. };
  61. GradientSignal::GradientSampler gradientSampler;
  62. gradientSampler.m_invertInput = true;
  63. TestGradientSampler(gradientSampler, mockInput, expectedOutput, dataSize);
  64. }
  65. TEST_F(GradientSignalSamplerTestsFixture, SamplerWithOpacityReturnsGradientValuesAdjustedForOpacity)
  66. {
  67. // If "opacity" is set, the gradient sampler should return back values that match the mock gradient * opacity.
  68. const int dataSize = 3; // 3x3 data
  69. AZStd::vector<float> mockInput =
  70. {
  71. 0.0f, 0.1f, 0.2f,
  72. 0.4f, 0.5f, 0.6f,
  73. 0.8f, 0.9f, 1.0f
  74. };
  75. AZStd::vector<float> expectedOutput =
  76. {
  77. 0.0f, 0.05f, 0.1f,
  78. 0.2f, 0.25f, 0.3f,
  79. 0.4f, 0.45f, 0.5f
  80. };
  81. GradientSignal::GradientSampler gradientSampler;
  82. gradientSampler.m_opacity = 0.5f;
  83. TestGradientSampler(gradientSampler, mockInput, expectedOutput, dataSize);
  84. }
  85. TEST_F(GradientSignalSamplerTestsFixture, SamplerWithTranslateReturnsTranslatedGradientValues)
  86. {
  87. // If the transform is enabled, the gradient sampler should return back values that have been transformed.
  88. // In this test, we're setting the translation.
  89. const int dataSize = 3; // 3x3 data
  90. AZStd::vector<float> mockInput =
  91. {
  92. 0.0f, 0.1f, 0.2f,
  93. 0.4f, 0.5f, 0.6f,
  94. 0.8f, 0.9f, 1.0f
  95. };
  96. // We're translating one to the left in world space, which will translate one to the right in gradient lookup space,
  97. // which means each output value should be the one that's one position to the right in the input, with wrapping.
  98. // For example, the output for X=0 should match the input for X=1, the output for X=1 should match the input for X=2,
  99. // and the output for X=2 should match the input for X=0, because of the wrapping.
  100. AZStd::vector<float> expectedOutput =
  101. {
  102. 0.1f, 0.2f, 0.0f,
  103. 0.5f, 0.6f, 0.4f,
  104. 0.9f, 1.0f, 0.8f
  105. };
  106. GradientSignal::GradientSampler gradientSampler;
  107. gradientSampler.m_enableTransform = true;
  108. gradientSampler.m_translate = AZ::Vector3(-1.0f, 0.0f, 0.0f);
  109. TestGradientSampler(gradientSampler, mockInput, expectedOutput, dataSize);
  110. }
  111. TEST_F(GradientSignalSamplerTestsFixture, SamplerWithRotationReturnsRotatedGradientValues)
  112. {
  113. // If the transform is enabled, the gradient sampler should return back values that have been transformed.
  114. // In this test, we're setting the rotation.
  115. const int dataSize = 3; // 3x3 data
  116. AZStd::vector<float> mockInput =
  117. {
  118. 0.0f, 0.1f, 0.2f,
  119. 0.4f, 0.5f, 0.6f,
  120. 0.8f, 0.9f, 1.0f
  121. };
  122. // We're rotating 90 degrees to the right in world space, which should cause our output values to match the inputs
  123. // rotated 90 degrees to the left. This will cause our input lookups to be at:
  124. // (0,0) (0,1) (0,2) / (-1,0) (-1,1) (-1,2) / (-2,0) (-2,1) (-2,2)
  125. AZStd::vector<float> expectedOutput =
  126. {
  127. 0.0f, 0.4f, 0.8f,
  128. 0.2f, 0.6f, 1.0f,
  129. 0.1f, 0.5f, 0.9f
  130. };
  131. GradientSignal::GradientSampler gradientSampler;
  132. gradientSampler.m_enableTransform = true;
  133. gradientSampler.m_rotate = AZ::Vector3(0.0f, 0.0f, -90.0f);
  134. TestGradientSampler(gradientSampler, mockInput, expectedOutput, dataSize);
  135. }
  136. TEST_F(GradientSignalSamplerTestsFixture, SamplerWithScaleReturnsScaledGradientValues)
  137. {
  138. // If the transform is enabled, the gradient sampler should return back values that have been transformed.
  139. // In this test, we're setting the rotation.
  140. const int dataSize = 3; // 3x3 data
  141. AZStd::vector<float> mockInput =
  142. {
  143. 0.0f, 0.1f, 0.2f,
  144. 0.4f, 0.5f, 0.6f,
  145. 0.8f, 0.9f, 1.0f
  146. };
  147. // With a scale of 1/2, our output lookup will be every 2 points in input space.
  148. AZStd::vector<float> expectedOutput =
  149. {
  150. 0.0f, 0.2f, 0.1f,
  151. 0.8f, 1.0f, 0.9f,
  152. 0.4f, 0.6f, 0.5f
  153. };
  154. GradientSignal::GradientSampler gradientSampler;
  155. gradientSampler.m_enableTransform = true;
  156. gradientSampler.m_scale = AZ::Vector3(0.5f, 0.5f, 1.0f);
  157. TestGradientSampler(gradientSampler, mockInput, expectedOutput, dataSize);
  158. }
  159. TEST_F(GradientSignalSamplerTestsFixture, SamplerWithInputLevelsReturnsLeveledGradientValues)
  160. {
  161. // If levels are enabled, the gradient sampler should return back values that have been leveled.
  162. // Input levels are defined as ((x - min) / (max - min)) ^ (1 / mid), where the "((x - min) / (max - min))" term
  163. // is clamped to the 0 - 1 range.
  164. // In this test, we're leaving the output levels alone, and setting the input levels to min=0.5, max=1.0, mid=0.5, so
  165. // the results should be ((x - 0.5) / (1.0 - 0.5)) ^ (1 / 0.5), or (2x - 1) ^ 2.
  166. const int dataSize = 3; // 3x3 data
  167. AZStd::vector<float> mockInput =
  168. {
  169. 0.0f, 0.1f, 0.2f,
  170. 0.4f, 0.5f, 0.6f,
  171. 0.8f, 0.9f, 1.0f
  172. };
  173. AZStd::vector<float> expectedOutput =
  174. {
  175. 0.0f, 0.0f, 0.0f,
  176. 0.0f, 0.0f, 0.04f,
  177. 0.36f, 0.64f, 1.0f
  178. };
  179. GradientSignal::GradientSampler gradientSampler;
  180. gradientSampler.m_enableLevels = true;
  181. gradientSampler.m_inputMin = 0.5f;
  182. gradientSampler.m_inputMid = 0.5f;
  183. gradientSampler.m_inputMax = 1.0f;
  184. gradientSampler.m_outputMin = 0.0f;
  185. gradientSampler.m_outputMax = 1.0f;
  186. TestGradientSampler(gradientSampler, mockInput, expectedOutput, dataSize);
  187. }
  188. TEST_F(GradientSignalSamplerTestsFixture, SamplerWithOutputLevelsReturnsLeveledGradientValues)
  189. {
  190. // If levels are enabled, the gradient sampler should return back values that have been leveled.
  191. // In this test, we're leaving the input levels alone, and setting the output levels to 0.5 - 1.0, so
  192. // the results should be the input values mapped from 0.0 - 1.0 to 0.5 - 1.0, or (0.5 + input/2).
  193. const int dataSize = 3; // 3x3 data
  194. AZStd::vector<float> mockInput =
  195. {
  196. 0.0f, 0.1f, 0.2f,
  197. 0.4f, 0.5f, 0.6f,
  198. 0.8f, 0.9f, 1.0f
  199. };
  200. AZStd::vector<float> expectedOutput =
  201. {
  202. 0.5f, 0.55f, 0.6f,
  203. 0.7f, 0.75f, 0.8f,
  204. 0.9f, 0.95f, 1.0f
  205. };
  206. GradientSignal::GradientSampler gradientSampler;
  207. gradientSampler.m_enableLevels = true;
  208. gradientSampler.m_inputMin = 0.0f;
  209. gradientSampler.m_inputMid = 1.0f;
  210. gradientSampler.m_inputMax = 1.0f;
  211. gradientSampler.m_outputMin = 0.5f;
  212. gradientSampler.m_outputMax = 1.0f;
  213. TestGradientSampler(gradientSampler, mockInput, expectedOutput, dataSize);
  214. }
  215. }