GPUOpen-Effects / TressFX

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

BUG REPORT and SOLUTION: Wind calculation #47

Open KondeU opened 2 years ago

KondeU commented 2 years ago

Hi there,

In the v4.1.0, there is a serious bug in the wind calculation. In fact, the wind does not work currently. The bug and its fix method are as follows.

1: In the sample, where the wind magnitude is not set at all, m_windMagnitude is only be set to 0.0f during initialization, however m_clampPositionDelta is not used at all, but it can be configured in the ImGUI.

https://github.com/GPUOpen-Effects/TressFX/blob/ba0bdacdfb964e38522fda812bf23169bc5fa603/src/TressFX/TressFXSettings.h#L82-L86

https://github.com/GPUOpen-Effects/TressFX/blob/ba0bdacdfb964e38522fda812bf23169bc5fa603/src/TressFX/TressFXSettings.h#L49

https://github.com/GPUOpen-Effects/TressFX/blob/ba0bdacdfb964e38522fda812bf23169bc5fa603/src/TressFXSample.cpp#L596

So we can modify the above code to these.

image

2: When calculating the displacement caused by wind, the effect is a vector with magnitude. The shader directly calculates the cross product of the unnormalized v and w, where v is the hair strand vector (with magnitude and direction), and w is wind vector (with magnitude and direction).

https://github.com/GPUOpen-Effects/TressFX/blob/ba0bdacdfb964e38522fda812bf23169bc5fa603/src/Shaders/TressFXSimulation.hlsl#L904-L911

The vector cross product result is the displacement direction, but the value of each component in the vector has no practical significance. So we need to split into two parts to calculate separately in here, as shown below.

image

After modifying the code as shown above, the wind calculation will be correct and affect the hair strands.

3: The wind calculation and length constraints use the same pass, the length constraints will be iteratively calculated(dispatch multiple times), but the wind calculation does not need iterate, so we need to separate this pass to the wind calculation pass and the length constraints pass.