瀏覽代碼

ATOM-15434 "Decal + POM (Grey outline issue)"

Added new 012_Parallax_POM_Cutout screenshot test for a specific bug that was discovered.
Added a "ground plane" feature to the "RPI/Mesh" sample which can be used to view shadows, which is relevant to the bug being addressed.
Chris Santora 4 年之前
父節點
當前提交
5a8acf46f3

+ 52 - 1
Gem/Code/Source/MeshExampleComponent.cpp

@@ -75,6 +75,8 @@ namespace AtomSampleViewer
                 // This handler will be connected to the feature processor so that when the model is updated, the camera
                 // controller will reset. This ensures the camera is a reasonable distance from the model when it resizes.
                 ResetCameraController();
+
+                UpdateGroundPlane();
             }
         };
     }
@@ -111,6 +113,10 @@ namespace AtomSampleViewer
 
         InitLightingPresets(true);
 
+        AZ::Data::Asset<AZ::RPI::MaterialAsset> groundPlaneMaterialAsset = AZ::RPI::AssetUtils::LoadAssetByProductPath<AZ::RPI::MaterialAsset>(DefaultPbrMaterialPath, AZ::RPI::AssetUtils::TraceLevel::Error);
+        m_groundPlaneMaterial = AZ::RPI::Material::FindOrCreate(groundPlaneMaterialAsset);
+        m_groundPlaneModelAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::ModelAsset>("objects/plane.azmodel", AZ::RPI::AssetUtils::TraceLevel::Assert);
+
         AZ::TickBus::Handler::BusConnect();
     }
 
@@ -124,10 +130,12 @@ namespace AtomSampleViewer
         m_modelBrowser.Deactivate();
 
         RemoveController();
-
+        
         GetMeshFeatureProcessor()->ReleaseMesh(m_meshHandle);
+        GetMeshFeatureProcessor()->ReleaseMesh(m_groundPlandMeshHandle);
 
         m_modelAsset = {};
+        m_groundPlaneModelAsset = {};
 
         m_materialOverrideInstance = nullptr;
 
@@ -146,6 +154,19 @@ namespace AtomSampleViewer
 
             modelNeedsUpdate |= ScriptableImGui::Checkbox("Enable Material Override", &m_enableMaterialOverride);
            
+            if (ScriptableImGui::Checkbox("Show Ground Plane", &m_showGroundPlane))
+            {
+                if (m_showGroundPlane)
+                {
+                    CreateGroundPlane();
+                    UpdateGroundPlane();
+                }
+                else
+                {
+                    RemoveGroundPlane();
+                }
+            }
+
             if (ScriptableImGui::Checkbox("Show Model Materials", &m_showModelMaterials))
             {
                 modelNeedsUpdate = true;
@@ -285,6 +306,36 @@ namespace AtomSampleViewer
             GetMeshFeatureProcessor()->SetMaterialAssignmentMap(m_meshHandle, m_materialOverrideInstance);
         }
     }
+    
+    void MeshExampleComponent::CreateGroundPlane()
+    {
+        m_groundPlandMeshHandle = GetMeshFeatureProcessor()->AcquireMesh(m_groundPlaneModelAsset, m_groundPlaneMaterial);
+    }
+
+    void MeshExampleComponent::UpdateGroundPlane()
+    {
+        if (m_groundPlandMeshHandle.IsValid())
+        {
+            AZ::Transform groundPlaneTransform = AZ::Transform::CreateIdentity();
+
+            AZ::Vector3 modelCenter;
+            float modelRadius;
+            m_modelAsset->GetAabb().GetAsSphere(modelCenter, modelRadius);
+
+            static const float GroundPlaneRelativeScale = 4.0f;
+            static const float GroundPlaneOffset = 0.01f;
+
+            groundPlaneTransform.SetScale(AZ::Vector3(GroundPlaneRelativeScale * modelRadius));
+            groundPlaneTransform.SetTranslation(AZ::Vector3(0.0f, 0.0f, m_modelAsset->GetAabb().GetMin().GetZ() - GroundPlaneOffset));
+
+            GetMeshFeatureProcessor()->SetTransform(m_groundPlandMeshHandle, groundPlaneTransform);
+        }
+    }
+
+    void MeshExampleComponent::RemoveGroundPlane()
+    {
+        GetMeshFeatureProcessor()->ReleaseMesh(m_groundPlandMeshHandle);
+    }
 
     void MeshExampleComponent::OnEntityDestruction(const AZ::EntityId& entityId)
     {

+ 10 - 0
Gem/Code/Source/MeshExampleComponent.h

@@ -52,6 +52,10 @@ namespace AtomSampleViewer
 
         void ModelChange();
 
+        void CreateGroundPlane();
+        void UpdateGroundPlane();
+        void RemoveGroundPlane();
+
         void UseArcBallCameraController();
         void UseNoClipCameraController();
         void RemoveController();
@@ -87,12 +91,18 @@ namespace AtomSampleViewer
         // be shown in the material list.
         bool m_showModelMaterials = false;
 
+        bool m_showGroundPlane = false;
+
         bool m_cameraControllerDisabled = false;
 
         AZ::Data::Instance<AZ::RPI::Material> m_materialOverrideInstance; //< Holds a copy of the material instance being used when m_enableMaterialOverride is true.
         AZ::Render::MeshFeatureProcessorInterface::MeshHandle m_meshHandle;
         AZ::Data::Asset<AZ::RPI::ModelAsset> m_modelAsset;
 
+        AZ::Data::Asset<AZ::RPI::ModelAsset> m_groundPlaneModelAsset;
+        AZ::Render::MeshFeatureProcessorInterface::MeshHandle m_groundPlandMeshHandle;
+        AZ::Data::Instance<AZ::RPI::Material> m_groundPlaneMaterial;
+
         ImGuiSidebar m_imguiSidebar;
         ImGuiMaterialDetails m_imguiMaterialDetails;
         ImGuiAssetBrowser m_materialBrowser;

+ 7 - 1
Scripts/MaterialScreenshotTests.bv.lua

@@ -40,6 +40,9 @@ function GenerateMaterialScreenshot(imageComparisonThresholdLevel, materialName,
     if not (type(options.screenshotFilename) == "string") then
         options.screenshotFilename = materialName
     end
+    if not (type(options.showGroundPlane) == "boolean") then
+        options.showGroundPlane = false
+    end
 
     Print("MODEL: " .. options.model)
 
@@ -52,6 +55,8 @@ function GenerateMaterialScreenshot(imageComparisonThresholdLevel, materialName,
     else
         SetImguiValue('Lighting Preset##SampleBase/Neutral Urban (Alt)', true)
     end
+    
+    SetImguiValue('Show Ground Plane', options.showGroundPlane)
 
     -- The sample resets the camera position after loading the model and we need to
     -- make sure that happens before moving the camera below
@@ -109,6 +114,7 @@ GenerateMaterialScreenshot('Level G', '010_SpecularOcclusion', {lighting="Palerm
 GenerateMaterialScreenshot('Level G', '010_BothOcclusion', {lighting="Palermo Sidewalk (Alt)"})
 GenerateMaterialScreenshot('Level G', '011_Emissive')
 GenerateMaterialScreenshot('Level I', '012_Parallax_POM', {model=g_cubeModel, cameraHeading=-35.0, cameraPitch=35.0})
+GenerateMaterialScreenshot('Level I', '012_Parallax_POM_Cutout', {model=g_cubeModel, cameraHeading=-130.0, cameraPitch=35.0, cameraDistance=3.5, lighting="Goegap (Alt)", showGroundPlane=true})
 GenerateMaterialScreenshot('Level I', '013_SpecularAA_Off', {lighting="Dark Test Lighting"})
 GenerateMaterialScreenshot('Level J', '013_SpecularAA_On', {lighting="Dark Test Lighting"})
 GenerateMaterialScreenshot('Level G', '014_ClearCoat', {lighting="Neutral Urban"})
@@ -167,7 +173,7 @@ Print('Saving screenshots to ' .. NormalizePath(g_screenshotOutputFolder))
 
 -- We should eventually replace this with realistic skin test cases, these are just placeholders for regression testing
 GenerateMaterialScreenshot('Level D', '001_lucy_regression_test',    {model=g_modelLucy, cameraHeading=-26.0, cameraPitch=15.0, cameraDistance=2.0, cameraZ=0.7})
-GenerateMaterialScreenshot('Level E', '002_wrinkle_regression_test', {model=g_modelWithLayerMask, cameraHeading=-135.0, cameraPitch=15.0, cameraZ=-0.3, cameraDistance=3.5})
+GenerateMaterialScreenshot('Level G', '002_wrinkle_regression_test', {model=g_modelWithLayerMask, cameraHeading=-135.0, cameraPitch=15.0, cameraZ=-0.3, cameraDistance=3.5})
 
 ----------------------------------------------------------------------
 -- MinimalPBR Materials...