GPUOpen-Effects / TressFX

DirectX 12 and Vulkan libraries that provide convenient access to realistically rendered and simulated hair and fur
MIT License
789 stars 131 forks source link

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

Open KondeU opened 2 years ago

KondeU commented 2 years ago

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.

https://github.com/GPUOpen-Effects/TressFX/blob/ba0bdacdfb964e38522fda812bf23169bc5fa603/src/TressFX/TressFXConstantBuffers.h#L66-L70

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:

https://github.com/GPUOpen-Effects/TressFX/blob/ba0bdacdfb964e38522fda812bf23169bc5fa603/src/TressFX/TressFXSDFCollision.h#L95

https://github.com/GPUOpen-Effects/TressFX/blob/ba0bdacdfb964e38522fda812bf23169bc5fa603/src/TressFX/TressFXSDFCollision.cpp#L171-L198

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是对的。

https://github.com/GPUOpen-Effects/TressFX/blob/ba0bdacdfb964e38522fda812bf23169bc5fa603/src/TressFX/TressFXConstantBuffers.h#L66-L70

图1

图2

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

图3

图4

该ConstBuffer的下发逻辑在TressFXSDFCollision中:

https://github.com/GPUOpen-Effects/TressFX/blob/ba0bdacdfb964e38522fda812bf23169bc5fa603/src/TressFX/TressFXSDFCollision.h#L95

https://github.com/GPUOpen-Effects/TressFX/blob/ba0bdacdfb964e38522fda812bf23169bc5fa603/src/TressFX/TressFXSDFCollision.cpp#L171-L198

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

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