merging from main

This commit is contained in:
greerdv
2021-04-15 08:18:11 +01:00
2503 changed files with 45147 additions and 527864 deletions
@@ -117,12 +117,10 @@ namespace AZ
}
else
{
const AZStd::string& cachePath = asset.GetHint();
AZ_Error("AssetUtils", false, "Could not load %s [Source='%s' Cache='%s' AssetID=%s] ",
AzTypeInfo<AssetDataT>::Name(),
sourcePathForDebug ? sourcePathForDebug : "<unknown>",
cachePath.empty() ? "<unknown>" : cachePath.c_str(),
asset.GetHint().empty() ? "<unknown>" : asset.GetHint().c_str(),
assetId.ToString<AZStd::string>().c_str());
return AZ::Failure();
@@ -197,26 +197,26 @@ namespace AZ
//! Selects an lod (based on size-in-screnspace) and adds the appropriate DrawPackets to the view.
uint32_t AddLodDataToView(const Vector3& pos, const Cullable::LodData& lodData, RPI::View& view);
//! Centralized manager for culling-related processing.
//! There is one CullingSystem owned by each Scene, so external systems (such as FeatureProcessors) should
//! access the CullingSystem via their parent Scene.
class CullingSystem
//! Centralized manager for culling-related processing for a given scene.
//! There is one CullingScene owned by each Scene, so external systems (such as FeatureProcessors) should
//! access the CullingScene via their parent Scene.
class CullingScene
{
public:
AZ_RTTI(CullingSystem, "{5B23B55B-8A1D-4B0D-9760-15E87FC8518A}");
AZ_CLASS_ALLOCATOR(CullingSystem, AZ::SystemAllocator, 0);
AZ_DISABLE_COPY_MOVE(CullingSystem);
AZ_RTTI(CullingScene, "{5B23B55B-8A1D-4B0D-9760-15E87FC8518A}");
AZ_CLASS_ALLOCATOR(CullingScene, AZ::SystemAllocator, 0);
AZ_DISABLE_COPY_MOVE(CullingScene);
CullingSystem() = default;
virtual ~CullingSystem() = default;
CullingScene() = default;
virtual ~CullingScene() = default;
void Activate(const class Scene* parentScene);
void Deactivate();
//! Notifies the CullingSystem that culling will begin for this frame.
//! Notifies the CullingScene that culling will begin for this frame.
void BeginCulling(const AZStd::vector<ViewPtr>& views);
//! Notifies the CullingSystem that the culling is done for this frame.
//! Notifies the CullingScene that the culling is done for this frame.
void EndCulling();
//! Performs render culling and lod selection for a View, then adds the visible renderpackets to that View.
@@ -235,7 +235,7 @@ namespace AZ
//! Is not threadsafe, so call this from the main thread outside of Begin/EndCulling()
void UnregisterCullable(Cullable& cullable);
//! Returns the number of cullables that have been added to the CullingSystem
//! Returns the number of cullables that have been added to the CullingScene
uint32_t GetNumCullables() const;
CullingDebugContext& GetDebugContext()
@@ -244,12 +244,13 @@ namespace AZ
}
static const size_t WorkListCapacity = 5;
using WorkListType = AZStd::fixed_vector<AzFramework::IVisibilitySystem::NodeData, WorkListCapacity>;
using WorkListType = AZStd::fixed_vector<AzFramework::IVisibilityScene::NodeData, WorkListCapacity>;
protected:
size_t CountObjectsInScene();
const Scene* m_parentScene = nullptr;
AzFramework::IVisibilityScene* m_visScene = nullptr;
CullingDebugContext m_debugCtx;
@@ -70,7 +70,7 @@ namespace AZ
//! Whether to run jobs in parallel or not (for debugging)
RHI::JobPolicy m_jobPolicy;
class CullingSystem* m_cullingSystem;
class CullingScene* m_cullingScene;
};
AZ_RTTI(FeatureProcessor, "{B8027170-C65C-4237-964D-B557FC9D7575}");
@@ -64,8 +64,9 @@ namespace AZ
//! @param rayStart position where the ray starts
//! @param dir direction where the ray ends (does not have to be unit length)
//! @param distanceFactor if an intersection is detected, this will be set such that distanceFactor * dir.length == distance to intersection
//! @param normal if an intersection is detected, this will be set to the normal at the point of intersection
//! @return true if the ray intersects the mesh
bool LocalRayIntersection(const AZ::Vector3& rayStart, const AZ::Vector3& dir, float& distanceFactor) const;
bool LocalRayIntersection(const AZ::Vector3& rayStart, const AZ::Vector3& dir, float& distanceFactor, AZ::Vector3& normal) const;
//! Checks a ray for intersection against this model, where the ray is in a different coordinate space.
//! Important: only to be used in the Editor, it may kick off a job to calculate spatial information.
@@ -76,9 +77,10 @@ namespace AZ
//! @param rayStart position where the ray starts
//! @param dir direction where the ray ends (does not have to be unit length)
//! @param distanceFactor if an intersection is detected, this will be set such that distanceFactor * dir.length == distance to intersection
//! @param normal if an intersection is detected, this will be set to the normal at the point of intersection
//! @return true if the ray intersects the mesh
bool RayIntersection(const AZ::Transform& modelTransform, const AZ::Vector3& nonUniformScale, const AZ::Vector3& rayStart,
const AZ::Vector3& dir, float& distanceFactor) const;
const AZ::Vector3& dir, float& distanceFactor, AZ::Vector3& normal) const;
//! Get available UV names from the model and its lods.
const AZStd::unordered_set<AZ::Name>& GetUvNames() const;
@@ -173,6 +173,16 @@ namespace AZ
void RemoveFromRenderTick();
~RenderPipeline();
enum class RenderMode : uint8_t
{
RenderEveryTick, // Render at each RPI system render tick
RenderOnce, // Render once in next RPI system render tick
NoRender // Render disabled.
};
//! Get current render mode
RenderMode GetRenderMode() const;
private:
RenderPipeline() = default;
@@ -204,12 +214,6 @@ namespace AZ
// End of functions accessed by Scene class
//////////////////////////////////////////////////
enum class RenderMode : uint8_t
{
RenderEveryTick, // Render at each RPI system render tick
RenderOnce, // Render once in next RPI system render tick
NoRender // Render disabled.
};
RenderMode m_renderMode = RenderMode::RenderEveryTick;
@@ -44,7 +44,7 @@ namespace AZ
class FeatureProcessor;
class ShaderResourceGroup;
class ShaderResourceGroupAsset;
class CullingSystem;
class CullingScene;
class DynamicDrawSystem;
// Callback function to modify values of a ShaderResourceGroup
@@ -162,9 +162,9 @@ namespace AZ
bool HasOutputForPipelineState(RHI::DrawListTag drawListTag) const;
AZ::RPI::CullingSystem* GetCullingSystem()
AZ::RPI::CullingScene* GetCullingScene()
{
return m_cullingSystem;
return m_cullingScene;
}
RenderPipelinePtr FindRenderPipelineForWindow(AzFramework::NativeWindowHandle windowHandle);
@@ -212,7 +212,7 @@ namespace AZ
// CPU simulation job completion for track all feature processors' simulation jobs
AZ::JobCompletion* m_simulationCompletion = nullptr;
AZ::RPI::CullingSystem* m_cullingSystem;
AZ::RPI::CullingScene* m_cullingScene;
// Cached views for current rendering frame. It gets re-built every frame.
AZ::RPI::FeatureProcessor::SimulatePacket m_simulatePacket;
@@ -139,6 +139,9 @@ namespace AZ
bool SetImageViewArray(RHI::ShaderInputNameIndex& inputIndex, AZStd::array_view<const RHI::ImageView*> imageViews, uint32_t arrayIndex = 0);
bool SetImageViewArray(RHI::ShaderInputImageIndex inputIndex, AZStd::array_view<const RHI::ImageView*> imageViews, uint32_t arrayIndex = 0);
/// Sets an unbounded array of image views for the given shader input index.
bool SetImageViewUnboundedArray(RHI::ShaderInputImageUnboundedArrayIndex inputIndex, AZStd::array_view<const RHI::ImageView*> imageViews);
/// Returns a single image view associated with the image shader input index and array offset.
const RHI::ConstPtr<RHI::ImageView>& GetImageView(RHI::ShaderInputNameIndex& inputIndex, uint32_t arrayIndex = 0) const;
const RHI::ConstPtr<RHI::ImageView>& GetImageView(RHI::ShaderInputImageIndex inputIndex, uint32_t arrayIndex = 0) const;
@@ -158,6 +161,9 @@ namespace AZ
bool SetBufferViewArray(RHI::ShaderInputNameIndex& inputIndex, AZStd::array_view<const RHI::BufferView*> bufferViews, uint32_t arrayIndex = 0);
bool SetBufferViewArray(RHI::ShaderInputBufferIndex inputIndex, AZStd::array_view<const RHI::BufferView*> bufferViews, uint32_t arrayIndex = 0);
/// Sets an unbounded array of buffer views for the given shader input index.
bool SetBufferViewUnboundedArray(RHI::ShaderInputBufferUnboundedArrayIndex inputIndex, AZStd::array_view<const RHI::BufferView*> bufferViews);
/// Returns a single buffer view associated with the buffer shader input index and array offset.
const RHI::ConstPtr<RHI::BufferView>& GetBufferView(RHI::ShaderInputNameIndex& inputIndex, uint32_t arrayIndex = 0) const;
const RHI::ConstPtr<RHI::BufferView>& GetBufferView(RHI::ShaderInputBufferIndex inputIndex, uint32_t arrayIndex = 0) const;
@@ -57,6 +57,9 @@ namespace AZ
//! Gets the name of the default, primary ViewportContext, for common single-viewport scenarios.
virtual AZ::Name GetDefaultViewportContextName() const = 0;
//! Get the ViewportConext which has default ViewportContext name
virtual ViewportContextPtr GetDefaultViewportContext() const = 0;
//! Creates a ViewportContext and registers it by name.
//! There may only be one context registered to a given name at any time.
//! The ViewportContext will be automatically assigned a View from the stack registered to this context name.
@@ -109,6 +112,9 @@ namespace AZ
virtual void OnViewportSizeChanged(AzFramework::WindowSize size){AZ_UNUSED(size);}
//! Called when the active view for a given viewport context name changes.
virtual void OnViewportDefaultViewChanged(AZ::RPI::ViewPtr view){AZ_UNUSED(view);}
//! Called when the viewport is to be rendered.
//! Add draws to this functions if they only need to be rendered to this viewport.
virtual void OnRenderTick(){};
protected:
~ViewportContextNotifications() = default;
@@ -44,6 +44,7 @@ namespace AZ
void PushView(const Name& contextName, ViewPtr view) override;
bool PopView(const Name& contextName, ViewPtr view) override;
ViewPtr GetCurrentView(const Name& contextName) const override;
ViewportContextPtr GetDefaultViewportContext() const override;
private:
void RegisterViewportContext(const Name& contextName, ViewportContextPtr viewportContext);
@@ -68,6 +69,8 @@ namespace AZ
mutable AZStd::recursive_mutex m_containerMutex;
AZStd::atomic<AzFramework::ViewportId> m_currentViewportId = StartingViewportId;
AZ::Name m_defaultViewportContextName;
friend class RPISystem;
friend class ViewportContext;
};
@@ -30,7 +30,7 @@ namespace AZ
//! Contains a set of RPI::ModelLodAsset objects.
//! Serialized to a .azmodel file.
//! Actual model data is stored in the BufferAssets referenced by ModelLodAssets.
class ModelAsset final
class ModelAsset
: public AZ::Data::AssetData
{
friend class ModelAssetCreator;
@@ -46,7 +46,7 @@ namespace AZ
static void Reflect(AZ::ReflectContext* context);
ModelAsset();
~ModelAsset();
virtual ~ModelAsset();
//! Returns the human readable name of the model
const Name& GetName() const;
@@ -66,8 +66,9 @@ namespace AZ
//! @param rayStart position where the ray starts
//! @param dir direction where the ray ends (does not have to be unit length)
//! @param distance if an intersection is detected, this will be set such that distanceFactor * dir.length == distance to intersection
//! @param normal if an intersection is detected, this will be set to the normal at the point of collision
//! @return true if the ray intersects the mesh
bool LocalRayIntersectionAgainstModel(const AZ::Vector3& rayStart, const AZ::Vector3& dir, float& distance) const;
virtual bool LocalRayIntersectionAgainstModel(const AZ::Vector3& rayStart, const AZ::Vector3& dir, float& distance, AZ::Vector3& normal) const;
private:
void SetReady();
@@ -78,9 +79,9 @@ namespace AZ
// mutable method
void BuildKdTree() const;
bool BruteForceRayIntersect(const AZ::Vector3& rayStart, const AZ::Vector3& dir, float& distance) const;
bool BruteForceRayIntersect(const AZ::Vector3& rayStart, const AZ::Vector3& dir, float& distance, AZ::Vector3& normal) const;
bool LocalRayIntersectionAgainstMesh(const ModelLodAsset::Mesh& mesh, const AZ::Vector3& rayStart, const AZ::Vector3& dir, float& distance) const;
bool LocalRayIntersectionAgainstMesh(const ModelLodAsset::Mesh& mesh, const AZ::Vector3& rayStart, const AZ::Vector3& dir, float& distance, AZ::Vector3& normal) const;
// Various model information used in raycasting
AZ::Name m_positionName{ "POSITION" };
@@ -35,7 +35,7 @@ namespace AZ
ModelKdTree() = default;
bool Build(const ModelAsset* model);
bool RayIntersection(const AZ::Vector3& raySrc, const AZ::Vector3& rayDir, float& distance) const;
bool RayIntersection(const AZ::Vector3& raySrc, const AZ::Vector3& rayDir, float& distance, AZ::Vector3& normal) const;
void GetPenetratedBoxes(const AZ::Vector3& raySrc, const AZ::Vector3& rayDir, AZStd::vector<AZ::Aabb>& outBoxes);
enum ESplitAxis
@@ -53,7 +53,7 @@ namespace AZ
private:
void BuildRecursively(ModelKdTreeNode* pNode, const AZ::Aabb& boundbox, AZStd::vector<ObjectIdTriangleIndices>& indices);
bool RayIntersectionRecursively(ModelKdTreeNode* pNode, const AZ::Vector3& raySrc, const AZ::Vector3& rayDir, float& distance) const;
bool RayIntersectionRecursively(ModelKdTreeNode* pNode, const AZ::Vector3& raySrc, const AZ::Vector3& rayDir, float& distance, AZ::Vector3& normal) const;
void GetPenetratedBoxesRecursively(ModelKdTreeNode* pNode, const AZ::Vector3& raySrc, const AZ::Vector3& rayDir, AZStd::vector<AZ::Aabb>& outBoxes);
void ConstructMeshList(const ModelAsset* model, const AZ::Transform& matParent);
@@ -100,6 +100,11 @@ namespace AZ
//! Returns a reference to the index buffer used by this mesh
const BufferAssetView& GetIndexBufferAssetView() const;
//! A helper method for returning this mesh's index buffer using a specific type for the elements.
//! @note It's the caller's responsibility to choose the right type for the buffer.
template<class T>
AZStd::array_view<T> GetIndexBufferTyped() const;
//! Return an array view of the list of all stream buffer info (not including the index buffer)
AZStd::array_view<StreamBufferInfo> GetStreamBufferInfoList() const;
@@ -109,12 +114,17 @@ namespace AZ
//! In perf loop, re-use AZ::Name instance.
const BufferAssetView* GetSemanticBufferAssetView(const AZ::Name& semantic) const;
//! A helper method for returning a specific mesh buffer.
//! For example, to get a position buffer for a mesh with AZ::Name("POSITION").
//! A helper method for returning this mesh's buffer using a specific type for the elements.
//! For example, to get a position buffer for a mesh with AZ::Name("POSITION") and T=float.
//! In perf loop, re-use AZ::Name instance.
AZStd::array_view<uint8_t> GetSemanticBuffer(const AZ::Name& semantic) const;
//! @note It's the caller's responsibility to choose the right type for the buffer.
template<class T>
AZStd::array_view<T> GetSemanticBufferTyped(const AZ::Name& semantic) const;
private:
template<class T>
AZStd::array_view<T> GetBufferTyped(const BufferAssetView& bufferAssetView) const;
AZ::Name m_name;
AZ::Aabb m_aabb = AZ::Aabb::CreateNull();
@@ -155,5 +165,41 @@ namespace AZ
};
using ModelLodAssetHandler = AssetHandler<ModelLodAsset>;
template<class T>
AZStd::array_view<T> ModelLodAsset::Mesh::GetIndexBufferTyped() const
{
return GetBufferTyped<T>(GetIndexBufferAssetView());
}
template<class T>
AZStd::array_view<T> ModelLodAsset::Mesh::GetSemanticBufferTyped(const AZ::Name& semantic) const
{
const BufferAssetView* bufferAssetView = GetSemanticBufferAssetView(semantic);
return bufferAssetView ? GetBufferTyped<T>(*bufferAssetView) : AZStd::array_view<T>{};
}
template<class T>
AZStd::array_view<T> ModelLodAsset::Mesh::GetBufferTyped(const BufferAssetView& bufferAssetView) const
{
if (const BufferAsset* bufferAsset = bufferAssetView.GetBufferAsset().Get())
{
const AZStd::array_view<uint8_t> rawBuffer = bufferAsset->GetBuffer();
if (!rawBuffer.empty())
{
const auto& bufferViewDescriptor = bufferAssetView.GetBufferViewDescriptor();
const uint8_t* beginMeshRawBuffer = rawBuffer.data() + (bufferViewDescriptor.m_elementOffset * bufferViewDescriptor.m_elementSize);
const uint8_t* endMeshRawBuffer = beginMeshRawBuffer + (bufferViewDescriptor.m_elementCount * bufferViewDescriptor.m_elementSize);
AZ_Assert((endMeshRawBuffer - beginMeshRawBuffer) % sizeof(T) == 0,
"Size of buffer (%d) is not a multiple of the type's size specified (%d)",
endMeshRawBuffer - beginMeshRawBuffer, sizeof(T));
return AZStd::array_view<T>(reinterpret_cast<const T*>(beginMeshRawBuffer), reinterpret_cast<const T*>(endMeshRawBuffer));
}
}
return {};
}
} // namespace RPI
} // namespace AZ
@@ -16,6 +16,23 @@
namespace AZ::RPI
{
namespace MorphTargetDeltaConstants
{
// Min/max values for compression should correspond to what is used in MorphTargetCompression.azsli
// A tangent/bitangent/normal will be between -1.0 and 1.0 on any given axis
// The largest a delta needs to be is 2.0 in either positive or negative direction
// to modify a value from 1 to -1 or from -1 to 1
constexpr float s_tangentSpaceDeltaMin = -2.0f;
constexpr float s_tangentSpaceDeltaMax = 2.0f;
// A color will be between 0.0 and 1.0 for any given channel
// The largest a delta needs to be is positive or negative 1.0
// to modify a value from 0 to 1 or from 1 to 0
constexpr float s_colorDeltaMin = -1.0f;
constexpr float s_colorDeltaMax = 1.0f;
}
//! This class represents the data that is passed to the morph target compute shader for an individual delta
//! See MorphTargetSRG.azsli for the corresponding shader struct
//! It is 16-byte aligned to work with structured buffers
@@ -32,8 +49,10 @@ namespace AZ::RPI
uint32_t m_normalZTangentXYZ;
// 8 bit padding plus 8 bits per component for bitangent deltas
uint32_t m_padBitangentXYZ;
// 8 bits per component for color deltas
uint32_t m_colorRGBA;
// Explicit padding so the struct is 16 byte aligned for structured buffers
uint32_t m_pad[3];
uint32_t m_pad[2];
};
//! A morph target delta that is compressed, but split into individual components
@@ -60,6 +79,12 @@ namespace AZ::RPI
uint8_t m_bitangentX;
uint8_t m_bitangentY;
uint8_t m_bitangentZ;
// 8 bits per channel for color deltas
uint8_t m_colorR;
uint8_t m_colorG;
uint8_t m_colorB;
uint8_t m_colorA;
};
PackedCompressedMorphTargetDelta PackMorphTargetDelta(const CompressedMorphTargetDelta& compressedDelta);
@@ -56,6 +56,9 @@ namespace AZ::RPI
float m_minPositionDelta;
float m_maxPositionDelta;
//! Boolean to indicate the presence or absence of color deltas
bool m_hasColorDeltas = false;
static void Reflect(AZ::ReflectContext* context);
};
@@ -48,6 +48,7 @@ namespace AZ
static void Reflect(ReflectContext* context);
AZStd::string m_shaderAssetFileName;
AZStd::vector<AZStd::string> m_platformIdentifiers;
AZStd::vector<AZStd::string> m_srgAssetFileNames;
AZStd::vector<AZStd::unique_ptr<RootShaderVariantAssetSourceData>> m_rootShaderVariantAssets;
};
@@ -48,6 +48,8 @@ namespace AZ
//! Adds a shader input to the ShaderResourceGroupLayout.
void AddShaderInput(const RHI::ShaderInputBufferDescriptor& shaderInputBuffer);
void AddShaderInput(const RHI::ShaderInputImageDescriptor& shaderInputImage);
void AddShaderInput(const RHI::ShaderInputBufferUnboundedArrayDescriptor& shaderInputBufferUnboundedArray);
void AddShaderInput(const RHI::ShaderInputImageUnboundedArrayDescriptor& shaderInputImageUnboundedArray);
void AddShaderInput(const RHI::ShaderInputSamplerDescriptor& shaderInputSampler);
void AddShaderInput(const RHI::ShaderInputConstantDescriptor& shaderInputConstant);
@@ -66,4 +68,4 @@ namespace AZ
RHI::Ptr<RHI::ShaderResourceGroupLayout> m_shaderResourceGroupLayout;
};
} // namespace RPI
} // namespace AZ
} // namespace AZ