MaterialScreenshotTests.bv.lua 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. ----------------------------------------------------------------------------------------------------
  2. --
  3. -- Copyright (c) Contributors to the Open 3D Engine Project.
  4. -- For complete copyright and license terms please see the LICENSE at the root of this distribution.
  5. --
  6. -- SPDX-License-Identifier: Apache-2.0 OR MIT
  7. --
  8. --
  9. --
  10. ----------------------------------------------------------------------------------------------------
  11. RunScript("scripts/TestEnvironment.luac")
  12. g_shaderballModel = 'materialeditor/viewportmodels/shaderball.azmodel'
  13. g_cubeModel = 'materialeditor/viewportmodels/cube.azmodel'
  14. g_beveledCubeModel = 'materialeditor/viewportmodels/beveledcube.azmodel'
  15. g_modelWithoutLayerMask = 'objects/bunny.azmodel'
  16. g_modelWithLayerMask = 'testdata/objects/paintedplane.azmodel'
  17. g_modelHermanubis = 'materialeditor/viewportmodels/hermanubis.azmodel'
  18. g_modelTube = 'testdata/objects/tube.azmodel'
  19. g_modelGrass = 'objects/grass_tile_large.azmodel'
  20. function GenerateMaterialScreenshot(imageComparisonThresholdLevel, materialName, options)
  21. if options == nil then options = {} end
  22. if not (type(options.model) == "string") then
  23. options.model = g_shaderballModel
  24. end
  25. if not (type(options.cameraPitch) == "number") then
  26. options.cameraPitch = 20
  27. end
  28. if not (type(options.cameraHeading) == "number") then
  29. options.cameraHeading = -30
  30. end
  31. if not (type(options.cameraDistance) == "number") then
  32. options.cameraDistance = 2.0
  33. end
  34. if not (type(options.cameraZ) == "number") then
  35. options.cameraZ = 0.0
  36. end
  37. if not (type(options.screenshotFilename) == "string") then
  38. options.screenshotFilename = materialName
  39. end
  40. if not (type(options.showGroundPlane) == "boolean") then
  41. options.showGroundPlane = false
  42. end
  43. Print("Generating material screenshot for " .. materialName)
  44. Print("MODEL: " .. options.model)
  45. materialName = string.lower(materialName)
  46. SetImguiValue('Models/##Available', options.model)
  47. SetImguiValue('Materials/##Available', g_testMaterialsFolder .. materialName .. '.azmaterial')
  48. if (options.lighting ~= nil) then
  49. SetImguiValue('Lighting Preset##SampleBase/' .. options.lighting, true)
  50. else
  51. SetImguiValue('Lighting Preset##SampleBase/Neutral Urban (Alt)', true)
  52. end
  53. SetImguiValue('Show Ground Plane', options.showGroundPlane)
  54. -- The sample resets the camera position after loading the model and we need to
  55. -- make sure that happens before moving the camera below
  56. IdleFrames(1)
  57. ArcBallCameraController_SetHeading(DegToRad(options.cameraHeading))
  58. ArcBallCameraController_SetPitch(DegToRad(-options.cameraPitch))
  59. ArcBallCameraController_SetDistance(options.cameraDistance)
  60. ArcBallCameraController_SetPan(Vector3(0.0, 0.0, options.cameraZ))
  61. -- Give some extra frames for the textures to finish streaming in.
  62. IdleFrames(10)
  63. options.screenshotFilename = string.lower(options.screenshotFilename)
  64. if type(options.uniqueSuffix) == "string" then
  65. filename = g_testCaseFolder .. '/' .. options.screenshotFilename .. '.' .. options.uniqueSuffix .. '.png'
  66. else
  67. filename = g_testCaseFolder .. '/' .. options.screenshotFilename .. '.png'
  68. end
  69. SelectImageComparisonToleranceLevel(imageComparisonThresholdLevel)
  70. CaptureScreenshot(filename)
  71. end
  72. OpenSample('RPI/Mesh')
  73. ResizeViewport(999, 999)
  74. -- This is just quick regression test for a crash that happened when turning on the ground plane with no model
  75. SetImguiValue('Show Ground Plane', true)
  76. IdleFrames(1)
  77. SetImguiValue('Show Ground Plane', false)
  78. ----------------------------------------------------------------------
  79. -- StandardPBR Materials...
  80. g_testMaterialsFolder = 'testdata/materials/standardpbrtestcases/'
  81. g_testCaseFolder = 'StandardPBR'
  82. Print('Saving screenshots to ' .. NormalizePath(g_screenshotOutputFolder .. g_testCaseFolder))
  83. GenerateMaterialScreenshot('Level C', '001_DefaultWhite')
  84. GenerateMaterialScreenshot('Level G', '002_BaseColorLerp')
  85. GenerateMaterialScreenshot('Level H', '002_BaseColorLinearLight')
  86. GenerateMaterialScreenshot('Level G', '002_BaseColorMultiply')
  87. GenerateMaterialScreenshot('Level E', '003_MetalMatte')
  88. GenerateMaterialScreenshot('Level F', '003_MetalPolished')
  89. GenerateMaterialScreenshot('Level E', '004_MetalMap')
  90. GenerateMaterialScreenshot('Level E', '005_RoughnessMap')
  91. GenerateMaterialScreenshot('Level E', '006_SpecularF0Map')
  92. GenerateMaterialScreenshot('Level D', '007_MultiscatteringCompensationOff')
  93. GenerateMaterialScreenshot('Level D', '007_MultiscatteringCompensationOn')
  94. GenerateMaterialScreenshot('Level H', '008_NormalMap')
  95. GenerateMaterialScreenshot('Level E', '008_NormalMap_Bevels')
  96. GenerateMaterialScreenshot('Level F', '009_Opacity_Blended', {lighting="Neutral Urban", model=g_beveledCubeModel})
  97. GenerateMaterialScreenshot('Level F', '009_Opacity_Blended_Alpha_Affects_Specular', {lighting="Neutral Urban", model=g_beveledCubeModel})
  98. GenerateMaterialScreenshot('Level H', '009_Opacity_Cutout_PackedAlpha_DoubleSided', {lighting="Neutral Urban", model=g_beveledCubeModel})
  99. GenerateMaterialScreenshot('Level H', '009_Opacity_Cutout_SplitAlpha_DoubleSided', {lighting="Neutral Urban", model=g_beveledCubeModel})
  100. GenerateMaterialScreenshot('Level G', '009_Opacity_Cutout_SplitAlpha_SingleSided', {lighting="Neutral Urban", model=g_beveledCubeModel})
  101. GenerateMaterialScreenshot('Level F', '009_Opacity_Opaque_DoubleSided', {lighting="Neutral Urban", model=g_modelTube, cameraDistance=4.0, cameraPitch=45.0})
  102. GenerateMaterialScreenshot('Level F', '009_Opacity_TintedTransparent', {lighting="Neutral Urban", model=g_beveledCubeModel})
  103. GenerateMaterialScreenshot('Level H', '010_AmbientOcclusion', {lighting="Palermo Sidewalk (Alt)"})
  104. GenerateMaterialScreenshot('Level G', '010_SpecularOcclusion', {lighting="Palermo Sidewalk (Alt)"})
  105. GenerateMaterialScreenshot('Level G', '010_BothOcclusion', {lighting="Palermo Sidewalk (Alt)"})
  106. GenerateMaterialScreenshot('Level G', '011_Emissive')
  107. GenerateMaterialScreenshot('Level I', '012_Parallax_POM', {model=g_cubeModel, cameraHeading=-35.0, cameraPitch=35.0})
  108. GenerateMaterialScreenshot('Level I', '012_Parallax_POM_Cutout', {model=g_cubeModel, cameraHeading=-130.0, cameraPitch=35.0, cameraDistance=3.5, lighting="Goegap (Alt)", showGroundPlane=true})
  109. GenerateMaterialScreenshot('Level I', '013_SpecularAA_Off', {lighting="Test"})
  110. GenerateMaterialScreenshot('Level J', '013_SpecularAA_On', {lighting="Test"})
  111. GenerateMaterialScreenshot('Level G', '014_ClearCoat', {lighting="Neutral Urban"})
  112. GenerateMaterialScreenshot('Level H', '014_ClearCoat_NormalMap', {lighting="Neutral Urban"})
  113. GenerateMaterialScreenshot('Level H', '014_ClearCoat_NormalMap_2ndUv', {lighting="Neutral Urban"})
  114. GenerateMaterialScreenshot('Level F', '014_ClearCoat_RoughnessMap', {lighting="Neutral Urban"})
  115. GenerateMaterialScreenshot('Level F', '015_SubsurfaceScattering', {lighting="Test", cameraHeading = 45.0, cameraPitch=30.0, cameraDistance=1.5})
  116. GenerateMaterialScreenshot('Level D', '015_SubsurfaceScattering_Transmission', {lighting="Test", cameraHeading = 45.0, cameraPitch=-30.0, cameraDistance=1.5})
  117. GenerateMaterialScreenshot('Level E', '015_SubsurfaceScattering_Transmission_Thin', {model=g_modelGrass, lighting="Goegap (Alt)", cameraHeading = -150.0, cameraPitch=5.0, cameraDistance=1.5})
  118. GenerateMaterialScreenshot('Level I', '100_UvTiling_AmbientOcclusion')
  119. GenerateMaterialScreenshot('Level I', '100_UvTiling_BaseColor')
  120. GenerateMaterialScreenshot('Level I', '100_UvTiling_Emissive')
  121. GenerateMaterialScreenshot('Level H', '100_UvTiling_Metallic')
  122. GenerateMaterialScreenshot('Level I', '100_UvTiling_Normal')
  123. GenerateMaterialScreenshot('Level G', '100_UvTiling_Normal_Dome_Rotate20', {model=g_cubeModel, lighting="Test", cameraHeading=225.0})
  124. GenerateMaterialScreenshot('Level G', '100_UvTiling_Normal_Dome_Rotate90', {model=g_cubeModel, lighting="Test", cameraHeading=225.0})
  125. GenerateMaterialScreenshot('Level G', '100_UvTiling_Normal_Dome_ScaleOnlyU', {model=g_cubeModel, lighting="Test", cameraHeading=225.0})
  126. GenerateMaterialScreenshot('Level G', '100_UvTiling_Normal_Dome_ScaleOnlyV', {model=g_cubeModel, lighting="Test", cameraHeading=225.0})
  127. GenerateMaterialScreenshot('Level G', '100_UvTiling_Normal_Dome_ScaleUniform', {model=g_cubeModel, lighting="Test", cameraHeading=225.0})
  128. GenerateMaterialScreenshot('Level G', '100_UvTiling_Normal_Dome_TransformAll', {model=g_cubeModel, lighting="Test", cameraHeading=225.0})
  129. GenerateMaterialScreenshot('Level M', '100_UvTiling_Opacity', { lighting="Neutral Urban" })
  130. GenerateMaterialScreenshot('Level L', '100_UvTiling_Parallax_A', { uniqueSuffix="Angle1", model=g_cubeModel, cameraHeading=35.0, cameraPitch=35.0 })
  131. GenerateMaterialScreenshot('Level M', '100_UvTiling_Parallax_A', { uniqueSuffix="Angle2", model=g_cubeModel, cameraHeading=125.0, cameraPitch=35.0 })
  132. GenerateMaterialScreenshot('Level L', '100_UvTiling_Parallax_B', { uniqueSuffix="Angle1", model=g_cubeModel, cameraHeading=0.0, cameraPitch=45.0 })
  133. GenerateMaterialScreenshot('Level L', '100_UvTiling_Parallax_B', { uniqueSuffix="Angle2", model=g_cubeModel, cameraHeading=90.0, cameraPitch=45.0 })
  134. GenerateMaterialScreenshot('Level H', '100_UvTiling_Roughness')
  135. GenerateMaterialScreenshot('Level F', '100_UvTiling_SpecularF0')
  136. GenerateMaterialScreenshot('Level F', '101_DetailMaps_BaseNoDetailMaps', {model=g_modelHermanubis, lighting="Blouberg Sunrise 1 (Alt)", cameraHeading=175.0, cameraPitch=5.0, cameraDistance=0.75, cameraZ=0.5})
  137. GenerateMaterialScreenshot('Level H', '102_DetailMaps_All', {model=g_modelHermanubis, lighting="Blouberg Sunrise 1 (Alt)", cameraHeading=175.0, cameraPitch=5.0, cameraDistance=0.75, cameraZ=0.5})
  138. GenerateMaterialScreenshot('Level G', '103_DetailMaps_BaseColor', {model=g_modelHermanubis, lighting="Blouberg Sunrise 1 (Alt)", cameraHeading=175.0, cameraPitch=5.0, cameraDistance=0.75, cameraZ=0.5})
  139. GenerateMaterialScreenshot('Level G', '103_DetailMaps_BaseColorWithMask', {model=g_modelHermanubis, lighting="Blouberg Sunrise 1 (Alt)", cameraHeading=175.0, cameraPitch=5.0, cameraDistance=0.75, cameraZ=0.5})
  140. GenerateMaterialScreenshot('Level H', '104_DetailMaps_Normal', {model=g_modelHermanubis, lighting="Blouberg Sunrise 1 (Alt)", cameraHeading=175.0, cameraPitch=5.0, cameraDistance=0.75, cameraZ=0.5})
  141. GenerateMaterialScreenshot('Level H', '104_DetailMaps_NormalWithMask', {model=g_modelHermanubis, lighting="Blouberg Sunrise 1 (Alt)", cameraHeading=175.0, cameraPitch=5.0, cameraDistance=0.75, cameraZ=0.5})
  142. GenerateMaterialScreenshot('Level H', '105_DetailMaps_BlendMaskUsingDetailUVs', {model=g_modelHermanubis, lighting="Blouberg Sunrise 1 (Alt)", cameraHeading=175.0, cameraPitch=5.0, cameraDistance=0.75, cameraZ=0.5})
  143. ----------------------------------------------------------------------
  144. -- StandardMultilayerPBR Materials...
  145. g_testMaterialsFolder = 'testdata/materials/standardmultilayerpbrtestcases/'
  146. g_testCaseFolder = 'StandardMultilayerPBR'
  147. Print('Saving screenshots to ' .. NormalizePath(g_screenshotOutputFolder .. g_testCaseFolder))
  148. GenerateMaterialScreenshot('Level I', '001_ManyFeatures', {model=g_cubeModel, cameraHeading=-125.0, cameraPitch=-16.0, cameraZ=0.12})
  149. GenerateMaterialScreenshot('Level I', '001_ManyFeatures_Layer2Off', {model=g_cubeModel, cameraHeading=-125.0, cameraPitch=-16.0, cameraZ=0.12})
  150. GenerateMaterialScreenshot('Level I', '001_ManyFeatures_Layer3Off', {model=g_cubeModel, cameraHeading=-125.0, cameraPitch=-16.0, cameraZ=0.12})
  151. GenerateMaterialScreenshot('Level J', '002_ParallaxPdo', {model=g_cubeModel, cameraHeading=15.0, cameraPitch=28.0, lighting="Goegap (Alt)"})
  152. GenerateMaterialScreenshot('Level G', '003_Debug_BlendMask', {model=g_cubeModel})
  153. GenerateMaterialScreenshot('Level G', '003_Debug_Displacement', {model=g_cubeModel})
  154. GenerateMaterialScreenshot('Level G', '003_Debug_BlendWeights', {model=g_cubeModel})
  155. GenerateMaterialScreenshot('Level I', '004_UseVertexColors', {model=g_modelWithLayerMask, cameraHeading=0.0, cameraPitch=45.0, cameraDistance=30.0})
  156. GenerateMaterialScreenshot('Level I', '004_UseVertexColors', {model=g_modelWithoutLayerMask, cameraHeading=145.0, cameraPitch=7.0, cameraZ=-0.1, cameraDistance=3.0, screenshotFilename="004_UseVertexColors_modelHasNoVertexColors"})
  157. GenerateMaterialScreenshot('Level I', '005_UseDisplacement', {lighting="Blouberg Sunrise 1 (Alt)", model=g_modelWithLayerMask, cameraHeading=-35.0, cameraPitch=33.0, cameraDistance=9.0, cameraZ=0.9})
  158. GenerateMaterialScreenshot('Level I', '005_UseDisplacement_Layer2Off', {lighting="Blouberg Sunrise 1 (Alt)", model=g_modelWithLayerMask, cameraHeading=-35.0, cameraPitch=33.0, cameraDistance=9.0, cameraZ=0.9})
  159. GenerateMaterialScreenshot('Level I', '005_UseDisplacement_Layer3Off', {lighting="Blouberg Sunrise 1 (Alt)", model=g_modelWithLayerMask, cameraHeading=-35.0, cameraPitch=33.0, cameraDistance=9.0, cameraZ=0.9})
  160. GenerateMaterialScreenshot('Level I', '005_UseDisplacement_With_BlendMaskVertexColors', {lighting="Blouberg Sunrise 1 (Alt)", model=g_modelWithLayerMask, cameraHeading=0.0, cameraPitch=80.0, cameraDistance=27.0})
  161. GenerateMaterialScreenshot('Level I', '005_UseDisplacement_With_BlendMaskTexture', {lighting="Blouberg Sunrise 1 (Alt)", model=g_modelWithLayerMask, cameraHeading=180.0, cameraPitch=45.0, cameraDistance=20.0, cameraZ=-0.5})
  162. GenerateMaterialScreenshot('Level I', '005_UseDisplacement_With_BlendMaskTexture_NoHeightmaps', {lighting="Blouberg Sunrise 1 (Alt)", model=g_modelWithLayerMask, cameraHeading=180.0, cameraPitch=45.0, cameraDistance=20.0, cameraZ=-0.5})
  163. GenerateMaterialScreenshot('Level I', '005_UseDisplacement_With_BlendMaskTexture_AllSameHeight', {lighting="Blouberg Sunrise 1 (Alt)", model=g_modelWithLayerMask, cameraHeading=180.0, cameraPitch=45.0, cameraDistance=20.0, cameraZ=-0.5})
  164. ----------------------------------------------------------------------
  165. -- Skin Materials...
  166. g_testMaterialsFolder = 'testdata/materials/skintestcases/'
  167. g_testCaseFolder = 'Skin'
  168. Print('Saving screenshots to ' .. NormalizePath(g_screenshotOutputFolder .. g_testCaseFolder))
  169. -- We should eventually replace this with realistic skin test cases, these are just placeholders for regression testing
  170. GenerateMaterialScreenshot('Level D', '001_hermanubis_regression_test', {model=g_modelHermanubis, cameraHeading=-26.0, cameraPitch=15.0, cameraDistance=2.0, cameraZ=0.7})
  171. GenerateMaterialScreenshot('Level G', '002_wrinkle_regression_test', {model=g_modelWithLayerMask, cameraHeading=0.0, cameraPitch=45.0, cameraDistance=30.0})
  172. ----------------------------------------------------------------------
  173. -- MinimalPBR Materials...
  174. g_testMaterialsFolder = 'materials/minimalpbr/'
  175. g_testCaseFolder = 'MinimalPBR'
  176. Print('Saving screenshots to ' .. NormalizePath(g_screenshotOutputFolder .. g_testCaseFolder))
  177. GenerateMaterialScreenshot('Level C', 'MinimalPbr_Default')
  178. GenerateMaterialScreenshot('Level F', 'MinimalPbr_BlueMetal')
  179. GenerateMaterialScreenshot('Level D', 'MinimalPbr_RedDielectric')
  180. ----------------------------------------------------------------------
  181. -- MinimalMultilayerPBR Materials...
  182. -- This test is here only temporarily for regression testing until StandardMultilayerPBR is refactored to use reused nested property groups.
  183. g_testMaterialsFolder = 'materials/types/'
  184. g_testCaseFolder = 'MinimalPBR'
  185. Print('Saving screenshots to ' .. NormalizePath(g_screenshotOutputFolder .. g_testCaseFolder))
  186. GenerateMaterialScreenshot('Level G', 'MinimalMultilayerExample')
  187. ----------------------------------------------------------------------
  188. -- AutoBrick Materials...
  189. g_testCaseFolder = 'AutoBrick'
  190. Print('Saving screenshots to ' .. NormalizePath(g_screenshotOutputFolder .. g_testCaseFolder))
  191. g_testMaterialsFolder = 'testdata/materials/autobrick/'
  192. GenerateMaterialScreenshot('Level C', 'Brick', {model=g_cubeModel})
  193. GenerateMaterialScreenshot('Level E', 'Tile', {model=g_cubeModel})
  194. ----------------------------------------------------------------------
  195. -- Low End Pipeline...
  196. SetImguiValue('Use Low End Pipeline', true)
  197. -- Toggle a couple extra times to test a specific issue where the render pipelines would become disabled.
  198. IdleFrames(2)
  199. SetImguiValue('Use Low End Pipeline', false)
  200. IdleFrames(2)
  201. SetImguiValue('Use Low End Pipeline', true)
  202. IdleFrames(2)
  203. g_testMaterialsFolder = 'testdata/materials/standardpbrtestcases/'
  204. g_testCaseFolder = 'LowEndPipeline'
  205. Print('Saving screenshots to ' .. NormalizePath(g_screenshotOutputFolder .. g_testCaseFolder))
  206. -- We're not really getting full coverage here, but just some cursory regression tests to make sure the low-end pipeline doesn't break.
  207. GenerateMaterialScreenshot('Level E', '004_MetalMap')
  208. GenerateMaterialScreenshot('Level F', '009_Opacity_Blended', {lighting="Neutral Urban", model=g_beveledCubeModel})
  209. SetImguiValue('Use Low End Pipeline', false)
  210. ----------------------------------------------------------------------
  211. -- Material Pipeline Abstraction...
  212. -- These test materials are temporary, specifically for regression testing the new material pipeline system while it is in development.
  213. -- Once the core material types like StandardPBR are ported to use material pipelines, we can switch these over to use core material
  214. -- types, and maybe remove some cases if they end up being redundant.
  215. g_testMaterialsFolder = 'materials/materialpipelinetest/'
  216. g_testCaseFolder = 'MaterialPipelineSystem'
  217. Print('Saving screenshots to ' .. NormalizePath(g_screenshotOutputFolder .. g_testCaseFolder))
  218. SetImguiValue('Use Low End Pipeline', false)
  219. SetImguiValue('Use Deferred Pipeline', false)
  220. GenerateMaterialScreenshot('Level G', 'MaterialPipelineTest_Basic', {screenshotFilename="MaterialPipelineTest_Basic_MainPipeline"})
  221. GenerateMaterialScreenshot('Level G', 'MaterialPipelineTest_Standard', {screenshotFilename="MaterialPipelineTest_Standard_MainPipeline"})
  222. GenerateMaterialScreenshot('Level G', 'MaterialPipelineTest_Enhanced', {screenshotFilename="MaterialPipelineTest_Enhanced_MainPipeline", lighting="Test"})
  223. SetImguiValue('Use Low End Pipeline', true)
  224. GenerateMaterialScreenshot('Level G', 'MaterialPipelineTest_Basic', {screenshotFilename="MaterialPipelineTest_Basic_LowEndPipeline"})
  225. GenerateMaterialScreenshot('Level G', 'MaterialPipelineTest_Standard', {screenshotFilename="MaterialPipelineTest_Standard_LowEndPipeline"})
  226. GenerateMaterialScreenshot('Level G', 'MaterialPipelineTest_Enhanced', {screenshotFilename="MaterialPipelineTest_Enhanced_LowEndPipeline", lighting="Test"})
  227. SetImguiValue('Use Low End Pipeline', false)
  228. SetImguiValue('Use Deferred Pipeline', true)
  229. GenerateMaterialScreenshot('Level G', 'MaterialPipelineTest_Basic', {screenshotFilename="MaterialPipelineTest_Basic_DeferredPipeline"})
  230. GenerateMaterialScreenshot('Level G', 'MaterialPipelineTest_Standard', {screenshotFilename="MaterialPipelineTest_Standard_DeferredPipeline"})
  231. GenerateMaterialScreenshot('Level G', 'MaterialPipelineTest_Enhanced', {screenshotFilename="MaterialPipelineTest_Enhanced_DeferredPipeline", lighting="Test"})
  232. SetImguiValue('Use Deferred Pipeline', false)