123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- /*
- * Modifications 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
- *
- */
-
- //-----------------------------------------------------------------------------------------------------------
- //
- // Copyright (c) 2019 Advanced Micro Devices, Inc. All rights reserved.
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- //
- //------------------------------------------------------------------------------
- // File: HairComputeSrgs.azsli
- //
- // Declarations of SRGs used by the hair shaders.
- //------------------------------------------------------------------------------
- #pragma once
- #include <Atom/Features/SrgSemantics.azsli>
- // Whether bones are specified by dual quaternion.
- // This option is not currently functional.
- #define TRESSFX_DQ 0
- //! notice - the following constants need to match what appears in AMD_TressFX.h
- #define AMD_TRESSFX_MAX_HAIR_GROUP_RENDER 16
- #define AMD_TRESSFX_MAX_NUM_BONES 512
- #define CM_TO_METERS 1.0
- #define METERS_TO_CM 1.0
- //#define CM_TO_METERS 0.01
- //#define METERS_TO_CM 100.0
- // The following macro is not being used yet due to limitation of the C preprocessor
- // mcpp that creates a shader compilation fault not being able to extend the macro.
- #define BYTE_OFFSET(index,baseOffset) ((baseOffset >> 2) + (index << 2))
- //!------------------------------ SRG Structure --------------------------------
- //! Per pass SRG the holds the dynamic read-write buffer shared across all
- //! dispatches and draw calls and used as the memory pool for all the dynamic
- //! buffer that can change between passes due to the application of skinning,
- //! simulation and physics affect and read by the rendering shaders.
- ShaderResourceGroup PassSrg : SRG_PerPass
- {
- RWStructuredBuffer<int> m_skinnedHairSharedBuffer;
- }
- //!=============================================================================
- //!
- //! Per Instance Space 1 - Dynamic Buffers for Hair Skinning and Simulation
- //!
- //! ----------------------------------------------------------------------------
- struct StrandLevelData
- {
- float4 skinningQuat;
- float4 vspQuat;
- float4 vspTranslation;
- };
- //!------------------------------ SRG Structure --------------------------------
- //! Per instance/draw SRG representing dynamic read-write set of buffers
- //! that are unique per instance and are shared and changed between passes due
- //! to the application of skinning, simulation and physics affect.
- //! It is then also read by the rendering shaders.
- //! This Srg is NOT shared by the passes since it requires having barriers between
- //! both passes and draw calls, instead, all buffers are allocated from a single
- //! shared buffer (through BufferViews) and that buffer is then shared between
- //! the passes via the PerPass Srg frequency.
- ShaderResourceGroup HairDynamicDataSrg : SRG_PerObject // space 1 - per instance / object
- {
- RWBuffer<float4> m_hairVertexPositions;
- RWBuffer<float4> m_hairVertexPositionsPrev;
- RWBuffer<float4> m_hairVertexPositionsPrevPrev;
- RWBuffer<float4> m_hairVertexTangents;
- RWStructuredBuffer<StrandLevelData> m_strandLevelData;
- //! Per hair object offset to the start location of each buffer within
- //! 'm_skinnedHairSharedBuffer'. The offset is in bytes!
- uint m_positionBufferOffset;
- uint m_positionPrevBufferOffset;
- uint m_positionPrevPrevBufferOffset;
- uint m_tangentBufferOffset;
- uint m_strandLevelDataOffset;
- };
- //------------------------------------------------------------------------------
- // Allow for the code to run with minimal changes - skinning / simulation compute passes
- // Usage of per-instance buffer
- #define g_HairVertexPositions HairDynamicDataSrg::m_hairVertexPositions
- #define g_HairVertexPositionsPrev HairDynamicDataSrg::m_hairVertexPositionsPrev
- #define g_HairVertexPositionsPrevPrev HairDynamicDataSrg::m_hairVertexPositionsPrevPrev
- #define g_HairVertexTangents HairDynamicDataSrg::m_hairVertexTangents
- #define g_StrandLevelData HairDynamicDataSrg::m_strandLevelData
- //------------------------------------------------------------------------------
- float3 GetSharedVector3(int offset)
- {
- return float3(
- asfloat(PassSrg::m_skinnedHairSharedBuffer[offset]),
- asfloat(PassSrg::m_skinnedHairSharedBuffer[offset + 1]),
- asfloat(PassSrg::m_skinnedHairSharedBuffer[offset + 2])
- );// *CM_TO_METERS; // convert to meters when using
- }
- void SetSharedVector3(int offset, float3 pos)
- {
- // pos.xyz *= METERS_TO_CM; // convert to cm when storing
- PassSrg::m_skinnedHairSharedBuffer[offset] = asint(pos.x);
- PassSrg::m_skinnedHairSharedBuffer[offset+1] = asint(pos.y);
- PassSrg::m_skinnedHairSharedBuffer[offset+2] = asint(pos.z);
- }
- float4 GetSharedVector4(int offset)
- {
- return float4(
- float3(
- asfloat(PassSrg::m_skinnedHairSharedBuffer[offset]),
- asfloat(PassSrg::m_skinnedHairSharedBuffer[offset + 1]),
- asfloat(PassSrg::m_skinnedHairSharedBuffer[offset + 2])
- ),// * CM_TO_METERS, // convert to meters when using
- asfloat(PassSrg::m_skinnedHairSharedBuffer[offset + 3])
- );
- }
- void SetSharedVector4(int offset, float4 pos)
- {
- // pos.xyz *= METERS_TO_CM; // convert to cm when storing
- PassSrg::m_skinnedHairSharedBuffer[offset] = asint(pos.x);
- PassSrg::m_skinnedHairSharedBuffer[offset+1] = asint(pos.y);
- PassSrg::m_skinnedHairSharedBuffer[offset+2] = asint(pos.z);
- PassSrg::m_skinnedHairSharedBuffer[offset+3] = asint(pos.w);
- }
- //------------------------------------------------------------------------------
- //! Getter/setter of position / tangent in the global shared buffer based on the
- //! per-instance offset of the instance positions buffer within the global shared buffer
- void SetSharedPosition3(int vertexIndex, float3 position)
- {
- int vertexOffset = (HairDynamicDataSrg::m_positionBufferOffset >> 2) + (vertexIndex << 2);
- SetSharedVector3(vertexOffset, position);
- }
- void SetSharedPosition(int vertexIndex, float4 position)
- {
- int vertexOffset = (HairDynamicDataSrg::m_positionBufferOffset >> 2) + (vertexIndex << 2);
- SetSharedVector4(vertexOffset, position);
- }
- float4 GetSharedPosition(int vertexIndex)
- {
- int vertexOffset = (HairDynamicDataSrg::m_positionBufferOffset >> 2) + (vertexIndex << 2);
- return GetSharedVector4(vertexOffset);
- }
- void SetSharedPrevPosition(int vertexIndex, float4 position)
- {
- int vertexOffset = (HairDynamicDataSrg::m_positionPrevBufferOffset >> 2) + (vertexIndex << 2);
- SetSharedVector4(vertexOffset, position);
- }
- float4 GetSharedPrevPosition(int vertexIndex)
- {
- int vertexOffset = (HairDynamicDataSrg::m_positionPrevBufferOffset >> 2) + (vertexIndex << 2);
- return GetSharedVector4(vertexOffset);
- }
- void SetSharedPrevPrevPosition(int vertexIndex, float4 position)
- {
- int vertexOffset = (HairDynamicDataSrg::m_positionPrevPrevBufferOffset >> 2) + (vertexIndex << 2);
- SetSharedVector4(vertexOffset, position);
- }
- float4 GetSharedPrevPrevPosition(int vertexIndex)
- {
- int vertexOffset = (HairDynamicDataSrg::m_positionPrevPrevBufferOffset >> 2) + (vertexIndex << 2);
- return GetSharedVector4(vertexOffset);
- }
- void SetSharedTangent(int tangentIndex, float3 currentTangent)
- {
- int tangentOffset = (HairDynamicDataSrg::m_tangentBufferOffset >> 2) + (tangentIndex << 2);
- PassSrg::m_skinnedHairSharedBuffer[tangentOffset] = asint(currentTangent.x);
- PassSrg::m_skinnedHairSharedBuffer[tangentOffset+1] = asint(currentTangent.y);
- PassSrg::m_skinnedHairSharedBuffer[tangentOffset+2] = asint(currentTangent.z);
- }
- float3 GetSharedTangent(int tangentIndex)
- {
- int tangentOffset = (HairDynamicDataSrg::m_tangentBufferOffset >> 2) + (tangentIndex << 2);
- return float3(
- asfloat(PassSrg::m_skinnedHairSharedBuffer[tangentOffset]),
- asfloat(PassSrg::m_skinnedHairSharedBuffer[tangentOffset + 1]),
- asfloat(PassSrg::m_skinnedHairSharedBuffer[tangentOffset + 2])
- );
- }
|