Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG REPORT: When there are multiple hair objects, ConstBuffer(ConstBuffer_SDF) always uses the data of the last hair object #46

Open
KondeU opened this issue Apr 14, 2022 · 0 comments

Comments

@KondeU
Copy link

KondeU commented Apr 14, 2022

Hi there,

In the v4.1.0 sample, there are two hair objects, the NumHairVerticesPerStrand is 32 for one and 8 for the other. In other physical pass, the NumHairVerticesPerStrand of these two hair objects is correct.

AMD::sint4 m_Counts;
// int m_NumOfStrandsPerThreadGroup;
// int m_NumFollowHairsPerGuideHair;
// int m_NumVerticesPerStrand; // should be 2^n (n is integer and greater than 2) and less than
// or equal to TRESSFX_SIM_THREAD_GROUP_SIZE. i.e. 8, 16, 32 or 64

Figure.1

Figure.2

But the last physical pass CollideWithHair, both are 8. For all hair objects, it use the data value of the last hair object!
As we can clearly see from the following figure, both hair objects use the same ConstBuffer (Buffer 895):

Figure.3

Figure.4

The process of delivering the ConstBuffer is described in the TressFXSDFCollision::CollideWithHair:

TressFXSDFCollisionParams m_ConstBuffer;

void TressFXSDFCollision::CollideWithHair(EI_CommandContext& commandContext,
TressFXSDFCollisionSystem& system,
TressFXHairObject& hairObject)
{
if (!m_pInputCollisionMesh)
return;
EI_Marker marker(commandContext, "CollideWithHair");
int numTotalHairVertices = hairObject.GetNumTotalHairVertices();
// Get vertex buffers from the hair object.
TressFXDynamicState& state = hairObject.GetDynamicState();
// Set the constant buffer parameters
m_ConstBuffer.m_Origin.x = m_Origin.x;
m_ConstBuffer.m_Origin.y = m_Origin.y;
m_ConstBuffer.m_Origin.z = m_Origin.z;
m_ConstBuffer.m_Origin.w = 0;
m_ConstBuffer.m_CellSize = m_CellSize;
m_ConstBuffer.m_NumCellsX = m_NumCellsX;
m_ConstBuffer.m_NumCellsY = m_NumCellsY;
m_ConstBuffer.m_NumCellsZ = m_NumCellsZ;
m_ConstBuffer.m_CollisionMargin = m_CollisionMargin * m_CellSize;
m_ConstBuffer.m_NumTotalHairVertices = hairObject.GetNumTotalHairVertices();
m_ConstBuffer.m_NumHairVerticesPerStrand = hairObject.GetNumVerticesPerStrand();
commandContext.UpdateBuffer(m_pConstantBufferResource.get(), &m_ConstBuffer);

For each model that collides with the hair object, there is a TressFXSDFCollision instance, but only one TressFXSDFCollisionParams structure instance and one ConstantBufferResource in this TressFXSDFCollision instance.

So, when there are multiple hair objects, there is only one ConstBuffer in the TressFXSDFCollision!

Therefore, the same ConstBuffer is updated after each hair object calls the CollideWithHair function. Regardless of which hair object, the same data from the last hair object is used.


Language: CN

[缺陷报告] 头发的碰撞矫正处理中,当有多个头发对象时,ConstBuffer(ConstBuffer_SDF)始终使用了最后一个头发对象的数据

在v4.1.0版本的示例程序中,有两个头发对象,其中一个头发对象的NumHairVerticesPerStrand为32,另一个为8。在其他的物理计算的pass中,这两个头发对象的NumHairVerticesPerStrand是对的。

AMD::sint4 m_Counts;
// int m_NumOfStrandsPerThreadGroup;
// int m_NumFollowHairsPerGuideHair;
// int m_NumVerticesPerStrand; // should be 2^n (n is integer and greater than 2) and less than
// or equal to TRESSFX_SIM_THREAD_GROUP_SIZE. i.e. 8, 16, 32 or 64

图1

图2

而在最后一个处理碰撞矫正的物理pass中,两个都变成了8。该pass针对所有的头发对象,仅使用了最后一次更新的数据值!

图3

图4

该ConstBuffer的下发逻辑在TressFXSDFCollision中:

TressFXSDFCollisionParams m_ConstBuffer;

void TressFXSDFCollision::CollideWithHair(EI_CommandContext& commandContext,
TressFXSDFCollisionSystem& system,
TressFXHairObject& hairObject)
{
if (!m_pInputCollisionMesh)
return;
EI_Marker marker(commandContext, "CollideWithHair");
int numTotalHairVertices = hairObject.GetNumTotalHairVertices();
// Get vertex buffers from the hair object.
TressFXDynamicState& state = hairObject.GetDynamicState();
// Set the constant buffer parameters
m_ConstBuffer.m_Origin.x = m_Origin.x;
m_ConstBuffer.m_Origin.y = m_Origin.y;
m_ConstBuffer.m_Origin.z = m_Origin.z;
m_ConstBuffer.m_Origin.w = 0;
m_ConstBuffer.m_CellSize = m_CellSize;
m_ConstBuffer.m_NumCellsX = m_NumCellsX;
m_ConstBuffer.m_NumCellsY = m_NumCellsY;
m_ConstBuffer.m_NumCellsZ = m_NumCellsZ;
m_ConstBuffer.m_CollisionMargin = m_CollisionMargin * m_CellSize;
m_ConstBuffer.m_NumTotalHairVertices = hairObject.GetNumTotalHairVertices();
m_ConstBuffer.m_NumHairVerticesPerStrand = hairObject.GetNumVerticesPerStrand();
commandContext.UpdateBuffer(m_pConstantBufferResource.get(), &m_ConstBuffer);

对于每一个会和头发对象产生碰撞的物体模型,都有一个TressFXSDFCollision实例,但该实例中仅存了一个TressFXSDFCollisionParams结构体实例和一个对应的ConstantBufferResource。

当有多个头发对象时,由于该ConstBuffer只有一个,因此每个头发对象都调用CollideWithHair函数后,都是更新的同一块ConstBuffer,因此不管哪个头发对象,都使用了最后一个头发对象的数据!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant