Files
o3de/Gems/AtomTressFX/Assets/Shaders/HairSimulationComputeSrgs.azsli
Adi Bar-Lev 64bbc700fa Hair - ShortCut rendering technique and pipeline with Marschner lighting model (#4871)
- This rendering technique reduces the memory required per pipeline by 750MB compared to the PPLL technique!!
- Using 3 screen buffers representing the closest 3 hair gragments depths.
- Going through second geometry pass that disqualify any fragment further than the third depth, the technique blends the three closes shaders hair fragments.
- Supports the Marschner lighting model (big change from the original TressFX 4.1 implementation)
- The current technique is almost twice the performance of the PPLL but not quite as advacned when come to final visual quality.

Remarks:
Unlike the PPLL, this technique is still lacking some of the advanced features added to the PPLL such as
1. Back lobe (TT) conseal by depth comparison
2. Thickness dependency in light transfer (mainly TT)
3. Allowing TT transfer for thin separated hair strands (might be supported by default with no distinction)

Signed-off-by: Adi-Amazon <Adi Bar-Lev 82479970+Adi-Amazon@users.noreply.github.com>
Signed-off-by: Adi-Amazon <Adi Bar-Lev barlev@amazon.com>
Signed-off-by: Adi-Amazon <Adi Bar-Lev 82479970+Adi-Amazon@users.noreply.github.com>
Signed-off-by: Adi-Amazon <Adi Bar-Lev barlev@amazon.com>

Co-authored-by: Adi-Amazon <Adi Bar-Lev 82479970+Adi-Amazon@users.noreply.github.com>
2021-10-21 14:29:53 -04:00

180 lines
7.3 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: HairSimulationComputeSrgs.azsli
//
// Declarations of SRGs used by the hair shaders.
//------------------------------------------------------------------------------
#pragma once
#include <HairComputeSrgs.azsli>
//!-----------------------------------------------------------------------------
//!
//! Skinning / Simulation Render Usage
//! Per Objects Space 0 - Static Buffers for Hair Generation
//!
//! ----------------------------------------------------------------------------
struct TressFXSimulationParams
{
float4 m_Wind;
float4 m_Wind1;
float4 m_Wind2;
float4 m_Wind3;
float4 m_Shape; // damping, local stiffness, global stiffness, global range.
float4 m_GravTimeTip; // gravity maginitude (assumed to be in negative y direction.)
int4 m_SimInts; // Length iterations, local iterations, collision flag.
int4 m_Counts; // num strands per thread group, num follow hairs per guid hair, num verts per strand.
float4 m_VSP; // VSP parameters - controls how Velocity Shock Propogation will dictate how
// fast velocities are handled and can be compensated using the hair root velocity
float m_ResetPositions;
float m_ClampPositionDelta;
float m_pad1;
float m_pad2;
#if TRESSFX_DQ // this option is currently not functional
float4 m_BoneSkinningDQ[AMD_TRESSFX_MAX_NUM_BONES * 2];
#else
row_major float4x4 m_BoneSkinningMatrix[AMD_TRESSFX_MAX_NUM_BONES];
#endif
};
struct BoneSkinningData
{
float4 boneIndex; // x, y, z and w component are four bone indices per strand
float4 boneWeight; // x, y, z and w component are four bone weights per strand
};
//!------------------------------ SRG Structure --------------------------------
//! This is the static Srg required for the hair genration per hair object draw.
//! The data is used only for skinning / simulation and doesn't change between
//! the object's passes.
//! To match to the original TressFX naming follow the global defines bellow.
ShaderResourceGroup HairGenerationSrg : SRG_PerDraw
{
// Buffers containing hair generation properties.
Buffer<float4> m_initialHairPositions;
Buffer<float> m_hairRestLengthSRV;
Buffer<float> m_hairStrandType;
Buffer<float4> m_followHairRootOffset;
StructuredBuffer<BoneSkinningData> m_boneSkinningData;
// Constant buffer structure reflected in code as 'TressFXSimulationParams'
TressFXSimulationParams m_tressfxSimParameters;
};
//------------------------------------------------------------------------------
// Allow for the code to run with minimal changes - compute passes usage
#define g_InitialHairPositions HairGenerationSrg::m_initialHairPositions
#define g_HairRestLengthSRV HairGenerationSrg::m_hairRestLengthSRV
#define g_HairStrandType HairGenerationSrg::m_hairStrandType
#define g_FollowHairRootOffset HairGenerationSrg::m_followHairRootOffset
#define g_BoneSkinningData HairGenerationSrg::m_boneSkinningData
#define g_NumOfStrandsPerThreadGroup HairGenerationSrg::m_tressfxSimParameters.m_Counts.x
#define g_NumFollowHairsPerGuideHair HairGenerationSrg::m_tressfxSimParameters.m_Counts.y
#define g_NumVerticesPerStrand HairGenerationSrg::m_tressfxSimParameters.m_Counts.z
#define g_NumLocalShapeMatchingIterations HairGenerationSrg::m_tressfxSimParameters.m_SimInts.y
#define g_GravityMagnitude HairGenerationSrg::m_tressfxSimParameters.m_GravTimeTip.x
#define g_TimeStep HairGenerationSrg::m_tressfxSimParameters.m_GravTimeTip.y
#define g_TipSeparationFactor HairGenerationSrg::m_tressfxSimParameters.m_GravTimeTip.z
#define g_Wind HairGenerationSrg::m_tressfxSimParameters.m_Wind
#define g_Wind1 HairGenerationSrg::m_tressfxSimParameters.m_Wind1
#define g_Wind2 HairGenerationSrg::m_tressfxSimParameters.m_Wind2
#define g_Wind3 HairGenerationSrg::m_tressfxSimParameters.m_Wind3
#define g_ResetPositions HairGenerationSrg::m_tressfxSimParameters.m_ResetPositions
#define g_ClampPositionDelta HairGenerationSrg::m_tressfxSimParameters.m_ClampPositionDelta
#define g_BoneSkinningDQ HairGenerationSrg::m_tressfxSimParameters.m_BoneSkinningDQ
#define g_BoneSkinningMatrix HairGenerationSrg::m_tressfxSimParameters.m_BoneSkinningMatrix
// We no longer support groups (indirection).
int GetStrandType(int globalThreadIndex)
{
return 0;
}
float GetDamping(int strandType)
{
// strand type unused.
// In the future, we may create an array and use indirection.
return HairGenerationSrg::m_tressfxSimParameters.m_Shape.x;
}
float GetLocalStiffness(int strandType)
{
// strand type unused.
// In the future, we may create an array and use indirection.
return HairGenerationSrg::m_tressfxSimParameters.m_Shape.y;
}
float GetGlobalStiffness(int strandType)
{
// strand type unused.
// In the future, we may create an array and use indirection.
return HairGenerationSrg::m_tressfxSimParameters.m_Shape.z;
}
float GetGlobalRange(int strandType)
{
// strand type unused.
// In the future, we may create an array and use indirection.
return HairGenerationSrg::m_tressfxSimParameters.m_Shape.w;
}
float GetVelocityShockPropogation()
{
return HairGenerationSrg::m_tressfxSimParameters.m_VSP.x;
}
float GetVSPAccelThreshold()
{
return HairGenerationSrg::m_tressfxSimParameters.m_VSP.y;
}
int GetLocalConstraintIterations()
{
return (int)HairGenerationSrg::m_tressfxSimParameters.m_SimInts.y;
}
int GetLengthConstraintIterations()
{
return (int)HairGenerationSrg::m_tressfxSimParameters.m_SimInts.x;
}
//------------------------------------------------------------------------------