Files
Adi Bar-Lev 9786d63596 Hair - Hair Gem introduction to O3DE from Atom/barlev/AtomTressFX_DevRebase (#4439)
* Hair
- First introduction of Hair gem to Atom and O3DE
- The hair technology is based off TressFX 4.1
- These are some of the areas we enhanced the original TressFX implementation:
   - Lighting model was replaced and we now use a modified Marschner model
   - Blending is done directly with the back buffer removing the silhouette of the original implementation
   - Hair depth / thickness is now calculated to remove incorrect back lighting (TT lobe in the Marschner model)
   - Thickness corrected to handle hair gaps hence introducing better light passage for the TT
   - The hair is fully integrated into the Atom pipeline and structure design
   - Usage of single shared buffer for the computer buffers reduces barriers sync overhead

Remarks:
- Collisions via SDF compute are to be introduced soon
- Improved shortcut rendering method ala Eidos Montreal to be introduced soon

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - code clean pass

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - EMFX Actor visibility implementation

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - COnnecting hair passes to Atom's MainPipeline.pass

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - adding dedicated thumbnail pipeline that does not include the hair gem

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - changed Atom shader files to allow hooking the hair to the lighting data structures

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - fixed a few headers to have the latest O3DE license + verification fixes

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - enabling editor component only when tool pipline is built + default texture add

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - fixing Linux and Android compilation builds

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - another files change to make Linux compile

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - more Linux and Android build fixes

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair

- Adding usage of fallback white texture
- Removing invalid null assignments into vectors
- Removing redundant mutex preventing deletion on some platforms

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair

- Shame: removed forgoten #pragma optimize
- Adding header complained by Android

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - removing the Hair Gem connection in the active project.

- This submission removes the connection to the active project hence allowing to run without the Gem.  Enable the passes in MainPipeline.pass and declare them again when you want to use the Gem.

Remark: the gem file PassTemplates.azasset was renamed and will be connected via code in the future to avoid the need to declare in the global pass template.
Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - registrating gem pass templates through the gem templates file (#198)

* Hair - registrating gem pass templates through the gem templates file

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - adding handler disconnect for the pass template registration.

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - PPLLIndexCounter buffer going data driven via the pass declarations (#202)

* Hair - PPLLIndexCounter buffer going data driven via the pass declaration
- Moving PPLLIndexCounter from code allocation and attachment to be data driven
- Fixed RPI typo bug that can prevent using buffers like that

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - fixing UI Editor (LYShine) crash (#209)

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* [Hair - resolved the multi pipeline mismatches and crashes + cleaned initialization & leftovers (#222)

* [Hair] - multiple render pipelines handling

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* [Hair] - Shut down order is handle to allow hair feature processor be deregistered only after the bootstrap component has disabled it

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* [Hair] - minor cleanups

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* [Hair] - followups from review nits

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - code fixes based on the CR remarks for the Hair merge to Dev (#248)

* Hair
- First introduction of Hair gem to Atom and O3DE
- The hair technology is based off TressFX 4.1
- These are some of the areas we enhanced the original TressFX implementation:
   - Lighting model was replaced and we now use a modified Marschner model
   - Blending is done directly with the back buffer removing the silhouette of the original implementation
   - Hair depth / thickness is now calculated to remove incorrect back lighting (TT lobe in the Marschner model)
   - Thickness corrected to handle hair gaps hence introducing better light passage for the TT
   - The hair is fully integrated into the Atom pipeline and structure design
   - Usage of single shared buffer for the computer buffers reduces barriers sync overhead

Remarks:
- Collisions via SDF compute are to be introduced soon
- Improved shortcut rendering method ala Eidos Montreal to be introduced soon

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - code clean pass

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - EMFX Actor visibility implementation

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - COnnecting hair passes to Atom's MainPipeline.pass

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - adding dedicated thumbnail pipeline that does not include the hair gem

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - changed Atom shader files to allow hooking the hair to the lighting data structures

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - fixed a few headers to have the latest O3DE license + verification fixes

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - enabling editor component only when tool pipline is built + default texture add

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - fixing Linux and Android compilation builds

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - another files change to make Linux compile

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - more Linux and Android build fixes

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair

- Adding usage of fallback white texture
- Removing invalid null assignments into vectors
- Removing redundant mutex preventing deletion on some platforms

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair

- Shame: removed forgoten #pragma optimize
- Adding header complained by Android

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - removing the Hair Gem connection in the active project.

- This submission removes the connection to the active project hence allowing to run without the Gem.  Enable the passes in MainPipeline.pass and declare them again when you want to use the Gem.

Remark: the gem file PassTemplates.azasset was renamed and will be connected via code in the future to avoid the need to declare in the global pass template.
Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - registrating gem pass templates through the gem templates file (#198)

* Hair - registrating gem pass templates through the gem templates file

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - adding handler disconnect for the pass template registration.

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - PPLLIndexCounter buffer going data driven via the pass declarations (#202)

* Hair - PPLLIndexCounter buffer going data driven via the pass declaration
- Moving PPLLIndexCounter from code allocation and attachment to be data driven
- Fixed RPI typo bug that can prevent using buffers like that

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - fixing UI Editor (LYShine) crash (#209)

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* [Hair - resolved the multi pipeline mismatches and crashes + cleaned initialization & leftovers (#222)

* [Hair] - multiple render pipelines handling

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* [Hair] - Shut down order is handle to allow hair feature processor be deregistered only after the bootstrap component has disabled it

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* [Hair] - minor cleanups

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* [Hair] - followups from review nits

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - last fixes based on CR remarks

Signed-off-by: Adi-Amazon <barlev@amazon.com>

* Hair - fixing AR

Signed-off-by: Adi-Amazon <barlev@amazon.com>
2021-10-04 10:46:31 -04:00

148 lines
6.7 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Component/TickBus.h>
#include <AzCore/Name/Name.h>
#include <Atom/RHI/FreeListAllocator.h>
#include <Atom/RHI.Reflect/Format.h>
#include <Atom/RHI/BufferPool.h>
#include <Atom/RPI.Public/Shader/ShaderResourceGroup.h>
// Hair specific
#include <Rendering/HairSharedBufferInterface.h>
namespace AZ
{
namespace RPI
{
class BufferAsset;
class Buffer;
}
namespace Render
{
//! This structure contains information regarding the naming of the buffer on both the CPU
//! and the GPU
//! This structure is also used to determine the maximum alignment required for the buffer
//! when allocating sub-buffers
struct SrgBufferDescriptor
{
//! Pool type to determine how a resource pool should be generated.
RPI::CommonBufferPoolType m_poolType;
//! The format used for the buffer
//! Should be Unknown for structured buffers, or R32 for raw buffers.
RHI::Format m_elementFormat;
//! The size in bytes of each element in the stream
uint32_t m_elementSize;
//! Amount of elements required to create the buffer
uint32_t m_elementCount;
//! The name used for the buffer view
Name m_bufferName;
//! The name used by the shader Srg in the GPU for this shader parameter
Name m_paramNameInSrg;
//! The assigned SRG slot in the CPU / GPU for this shader resource
uint32_t m_resourceShaderIndex;
//! If using a buffer view within a shared buffer, this represents
//! the view offset from the shared buffer origin in bytes.
uint32_t m_viewOffsetInBytes;
SrgBufferDescriptor() = default;
SrgBufferDescriptor(
RPI::CommonBufferPoolType poolType,
RHI::Format elementFormat,
uint32_t elementSize,
uint32_t elementCount,
Name bufferName,
Name paramNameInSrg,
uint32_t resourceShaderIndex,
uint32_t viewOffsetInBytes
) : m_poolType(poolType), m_elementFormat(elementFormat),
m_elementSize(elementSize), m_elementCount(elementCount),
m_bufferName(bufferName), m_paramNameInSrg(paramNameInSrg),
m_resourceShaderIndex(resourceShaderIndex), m_viewOffsetInBytes(viewOffsetInBytes)
{};
};
//! This class represents a single RPI::Buffer used to allocate sub-buffers from the
//! existing buffer that can then be used per draw. In a way, this buffer is used as a memory
//! pool from which sub-buffers are being created.
//! This is very useful when we want to synchronize the use of these buffers via barriers
//! so we declare and pass the entire buffer between passes and therefore we are creating
//! a dependency and barrier for this single buffer, yet as a result all sub-buffers are
//! now getting synced between passes.
//!
// Adopted from SkinnedMeshOutputStreamManager in order to make it more generic and context free usage
class SharedBuffer
: public HairSharedBufferInterface
, private SystemTickBus::Handler
{
public:
SharedBuffer();
SharedBuffer(AZStd::string bufferName, AZStd::vector<SrgBufferDescriptor>& buffersDescriptors);
AZ_RTTI(AZ::Render::SharedBuffer, "{D910C301-99F7-41B6-A2A6-D566F3B2C030}", AZ::Render::HairSharedBufferInterface);
~SharedBuffer();
void Init(AZStd::string bufferName, AZStd::vector<SrgBufferDescriptor>& buffersDescriptors);
// SharedBufferInterface
AZStd::intrusive_ptr<HairSharedBufferAllocation> Allocate(size_t byteCount) override;
void DeAllocate(RHI::VirtualAddress allocation) override;
void DeAllocateNoSignal(RHI::VirtualAddress allocation) override;
Data::Asset<RPI::BufferAsset> GetBufferAsset() const override;
Data::Instance<RPI::Buffer> GetBuffer() override;
//! Update buffer's content with sourceData at an offset of bufferByteOffset
bool UpdateData(const void* sourceData, uint64_t sourceDataSizeInBytes, uint64_t bufferByteOffset = 0) override;
//! Utility function to create a resource view of different type than the shared buffer data.
//! Since this class is sub-buffer container, this method should be used after creating
//! a new allocation to be used as a sub-buffer.
static RHI::BufferViewDescriptor CreateResourceViewWithDifferentFormat(
uint32_t offsetInBytes, uint32_t elementCount, uint32_t elementSize,
RHI::Format format, RHI::BufferBindFlags overrideBindFlags);
private:
// SystemTickBus
void OnSystemTick() override;
void GarbageCollect();
void CalculateAlignment(AZStd::vector<SrgBufferDescriptor>& buffersDescriptors);
void InitAllocator();
void CreateBufferAsset();
void CreateBuffer();
AZStd::string m_bufferName = "GenericSharedBuffer";
Data::Asset<AZ::RPI::ResourcePoolAsset> m_bufferPoolAsset;
Data::Instance<RPI::Buffer> m_buffer = nullptr;
Data::Asset<RPI::BufferAsset> m_bufferAsset = {};
RHI::FreeListAllocator m_freeListAllocator;
AZStd::mutex m_allocatorMutex;
uint64_t m_alignment = 16; // This will be overridden by the size of the largest allocated element
//! Currently the shared buffer size is fixed. Going towards dynamic size can be a better
//! solution but requires using re-allocations and proper synchronizing between all existing buffers.
//! This amount of memory should be enough for 2-3 very details cinematic hair or for 4-6 high
//! fidelity hair objects.
//! Additional attention should be given to the fact that because the buffers in Atom are NOT triple
//! buffered but instead they are delayed via garbage collection mechanism, during reallocation
//! the amount of memory required might reach close to double of the run-time.
size_t m_sizeInBytes = 256u * (1024u * 1024u);
bool m_memoryWasFreed = false;
bool m_broadcastMemoryAvailableEvent = false;
};
} // namespace Render
} // namespace AZ