代码改变世界

Adreno 505 角色不显示问题

2020-04-18 17:02  kk20161206  阅读(407)  评论(0编辑  收藏  举报

We are currently testing our project on our dev-kits, one of which is Adreno 505.

And it confuses us a lot that whenever we use unity_ObjectToWorld in our fragment shader, there comes an error and the fragment would not be rendered.

We use snapdragon profiler to test our shader, and the glsl is like this:

This is vertex shader converted to glsl:

  1. #version 300 es
  2. uniform vec4 hlslcc_mtx4x4unity_ObjectToWorld[4];
  3. uniform vec4 hlslcc_mtx4x4unity_MatrixVP[4];
  4. in highp vec4 in_POSITION0;
  5. in highp vec2 in_TEXCOORD0;
  6. out highp vec2 vs_TEXCOORD0;
  7. vec4 u_xlat0;
  8. vec4 u_xlat1;
  9. void main()
  10. {
  11. u_xlat0 = in_POSITION0.yyyy * hlslcc_mtx4x4unity_ObjectToWorld[1];
  12. u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[0] * in_POSITION0.xxxx + u_xlat0;
  13. u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[2] * in_POSITION0.zzzz + u_xlat0;
  14. u_xlat0 = u_xlat0 + hlslcc_mtx4x4unity_ObjectToWorld[3];
  15. u_xlat1 = u_xlat0.yyyy * hlslcc_mtx4x4unity_MatrixVP[1];
  16. u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[0] * u_xlat0.xxxx + u_xlat1;
  17. u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[2] * u_xlat0.zzzz + u_xlat1;
  18. gl_Position = hlslcc_mtx4x4unity_MatrixVP[3] * u_xlat0.wwww + u_xlat1;
  19. vs_TEXCOORD0.xy = in_TEXCOORD0.xy;
  20. return;
  21. }

This is the fragment shader:

  1. #version 300 es
  2. precision highp float;
  3. precision highp int;
  4. uniform vec4 hlslcc_mtx4x4unity_ObjectToWorld[4];
  5. layout(location = 0) out mediump vec4 SV_Target0;
  6. void main()
  7. {
  8. /////
  9. // Red: works fine.
  10. // Not render: something wrong about hlslcc_mtx4x4unity_ObjectToWorld
  11. SV_Target0 = hlslcc_mtx4x4unity_ObjectToWorld[2];
  12. SV_Target0 = vec4(1,0,0,1);
  13. return;
  14. //////////
  15. }

It works fine on Mali GPUs, but it failes to render when it comes to Adreno 505.

How to handle that please?

 

参考:https://answers.unity.com/questions/1364928/cannot-use-unity-objecttoworld-on-the-gpu-adreno-5.html

就是说这个unity_ObjectToWorld在顶点着色器使用没有问题,但是在片元着色器使用会有问题。

修改:

使用

UnityObjectToWorldNormal函数替换我们的法线变换就好了。
// Transforms normal from object to world space
inline float3 UnityObjectToWorldNormal( in float3 norm )
{
#ifdef UNITY_ASSUME_UNIFORM_SCALING
    return UnityObjectToWorldDir(norm);
#else
    // mul(IT_M, norm) => mul(norm, I_M) => {dot(norm, I_M.col0), dot(norm, I_M.col1), dot(norm, I_M.col2)}
    return normalize(mul(norm, (float3x3)unity_WorldToObject));
#endif
}

顶点是float4,没法儿转,但是顶点着色器里不需要。