You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
9.0 KiB
Plaintext
217 lines
9.0 KiB
Plaintext
/*
|
|
* 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) AND 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])
|
|
);
|
|
} |