Unreal fur hair groom rendering or shading issues

Hi guys, I’m using Unreal 5.5.3. to do the groom stands

The issue: when the light direction is parallel to the fur direction, will cause that part of the root look dark. However, it is supposed to be a bright highlight at that part because the light will scatter and bounce in each stand of hair. But the Unreal Engine’s default Hair shading model calculates light based on **Tangents

  1. i have try using consolve but not work
  2. The shader also cannot be fixed unless using emission, but emission is not a good solution cuz it looks fake**

is anyone face this issues ?
Thanks for your time - hope to hear soon from any Unreal Engine Deities that might be listening in

Here is the solution that i fix

(before fix just save a copy as a backup)

1.go to folder in Program Files\Epic Games\UE_5.5\Engine\Shaders\Private\HairStrands\HairStrandsDeepTransmittanceDualScattering.ush"

  1. open HairStrandsDeepTransmittanceDualScattering.ush

  2. in line around 137-140 the original script is
    // Compute the transmittance based on precompute Hair transmittance LUT
    const float3 T = GBuffer.WorldNormal;
    const float SinLightAngle = dot(L, T);
    const FHairAverageScattering AverageScattering = SampleHairLUT(HairLUTTexture, HairLUTSampler, GBuffer.BaseColor, Roughness, SinLightAngle);

  3. replace it to this
    const float3 T = GBuffer.WorldNormal;
    const float RawDot = dot(L, T);

const float SinLightAngle = saturate(-RawDot);

5.restart/recomplie your UE the is done

the reason i use this method is because i found out in r.hairstrands.component.local scattering have the black void,here is the example:

as we can see the they using {const float3 T = GBuffer.WorldNormal;
const float SinLightAngle = dot(L, T);} which mean calculate light direction and fur direction.
if the paraller to the light direction ,then is 1
if is opposite paraller then is -1
if is 90 degree then is 0

so 1 or -1 is dark ,but 0 is bright.thatsway we can see that black void at front and back

So {const float SinLightAngle = saturate(-RawDot)} is force the 1 and 0 to 0 value and -1 is 1 value to avoid the specular become black void


before


after

this might not a smart solution but is work

If anyone improve the solution, I would be very grateful.Thank you