Search Unity

Bug LinearBlendSkinning has a render bug

Discussion in 'Graphics for ECS' started by zhangdong304, May 4, 2023.

  1. zhangdong304

    zhangdong304

    Joined:
    Mar 21, 2018
    Posts:
    23
    I wrote a shader manually like this:

    Code (CSharp):
    1.  
    2. uniform ByteAddressBuffer _SkinMatrices;
    3.  
    4. half3x4 LoadSkinMatrix(int index)
    5. {
    6.     int offset = index * 48;
    7.     half4 p1 = asfloat(_SkinMatrices.Load4(offset + 0 * 16));
    8.     half4 p2 = asfloat(_SkinMatrices.Load4(offset + 1 * 16));
    9.     half4 p3 = asfloat(_SkinMatrices.Load4(offset + 2 * 16));
    10.     return half3x4(p1.x, p1.w, p2.z, p3.y,p1.y, p2.x, p2.w, p3.z,p1.z, p2.y, p3.x, p3.w);
    11. }
    12.  
    13. void Unity_LinearBlendSkinning_float(int4 indices, half4 weights, half3 positionIn, half3 normalIn, out half3 positionOut, out half3 normalOut)
    14. {
    15.     positionOut = 0;
    16.     normalOut = 0;
    17.     for (int i = 0; i < 4; ++i)
    18.     {
    19.       int skinMatrixIndex = indices[i] + UNITY_ACCESS_HYBRID_INSTANCED_PROP(_SkinMatrixIndex, int);
    20.       half3x4 skinMatrix = LoadSkinMatrix(skinMatrixIndex);
    21.       half3 vtransformed = mul(skinMatrix, half4(positionIn, 1));
    22.       half3 ntransformed = mul(skinMatrix, half4(normalIn, 0));
    23.  
    24.       positionOut += vtransformed * weights[i];
    25.       normalOut += ntransformed * weights[i];
    26.    }
    27. }
    28.  
    And the fragment shader like this:
    Code (CSharp):
    1.  
    2. half4 frag(Varyings input) : SV_Target
    3. {
    4.     UNITY_SETUP_INSTANCE_ID(input);
    5.  
    6.     half3 worldSpaceNormal = input.normalWS.xyz;
    7.  
    8.     half3 mainTexColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.texCoord0.xy).rgb;
    9.     mainTexColor = saturate(mainTexColor);
    10.  
    11.     half3 mainLightDir = half3(0.5h, 0.5h, 0.0h);
    12.  
    13.     half dotProduct = dot(mainLightDir, worldSpaceNormal);
    14.     half3 diffuse = saturate(dotProduct * mainTexColor);
    15.  
    16.     half3 ambient = mainTexColor * 0.4h;
    17.  
    18.     half3 color = diffuse + ambient;
    19.  
    20.     half3 finalColor = lerp(color, _BaseColor, _ColorLerp);
    21.  
    22.     return half4(finalColor, 1.0h);
    23. }
    24.  
    And the vertex shader like this:
    Code (CSharp):
    1.  
    2. Varyings vert(Attributes input)
    3. {
    4.     Varyings output = (Varyings)0;
    5.  
    6.     UNITY_SETUP_INSTANCE_ID(input);
    7.     UNITY_TRANSFER_INSTANCE_ID(input, output);
    8.  
    9.     half3 linearBlendSkinnedPosition = 0;
    10.     half3 linearBlendSkinnedNormal = 0;
    11.     Unity_LinearBlendSkinning_float(input.indices, input.weights, input.positionOS, input.normalOS,
    12.         linearBlendSkinnedPosition, linearBlendSkinnedNormal);
    13.  
    14.     half3 positionWS = TransformObjectToWorld(linearBlendSkinnedPosition);
    15.     half3 normalWS = TransformObjectToWorldNormal(linearBlendSkinnedNormal);
    16.  
    17.     output.normalWS = normalWS;
    18.     output.positionCS = TransformWorldToHClip(positionWS);
    19.     output.texCoord0 = input.uv0;
    20.     return output;
    21. }
    22.  
    This shader, on the Redmi Note3 and other phones, renders objects completely black. However, I changed the shader code as below and the render color was correct.
    Code (CSharp):
    1.  
    2. Varyings vert(Attributes input)
    3. {
    4.     Varyings output = (Varyings)0;
    5.  
    6.     UNITY_SETUP_INSTANCE_ID(input);
    7.     UNITY_TRANSFER_INSTANCE_ID(input, output);
    8.  
    9.     half3 linearBlendSkinnedPosition = input.positionOS;
    10.     half3 linearBlendSkinnedNormal = input.normalOS;
    11.  
    12.     half3 positionWS = TransformObjectToWorld(linearBlendSkinnedPosition);
    13.     half3 normalWS = TransformObjectToWorldNormal(linearBlendSkinnedNormal);
    14.  
    15.     output.normalWS = normalWS;
    16.     output.positionCS = TransformWorldToHClip(positionWS);
    17.     output.texCoord0 = input.uv0;
    18.     return output;
    19. }
    20.  
    My Unity editor version is 2022.2.15, and DOTS version is 1.0.pre65.
    LinearBlendSkinning node of ShaderGraph is used to write the same shader as above, with the same problem.
     
    Last edited: May 5, 2023
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,271
    Are the positions in the correct locations? And it is just the normals that are wrong? Is ambience being added correctly?
     
  3. zhangdong304

    zhangdong304

    Joined:
    Mar 21, 2018
    Posts:
    23
    Positions are in the correct locations.
    mainTexColor * 0.4h
    looks like 0. The ambience looks like black. Strangely,
    mainTexColor * 0.9h
    also looks like 0, but
    mainTexColor * 1.0h
    looks like correct.
    It's fine not to use
    LinearBlendSkinning
    , but whenever you use it, you get an error.
     
    Last edited: May 5, 2023
  4. zhangdong304

    zhangdong304

    Joined:
    Mar 21, 2018
    Posts:
    23
    I have three phones. Two of them are wrong.