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:
#version 300 es
uniform vec4 hlslcc_mtx4x4unity_ObjectToWorld[4];
uniform vec4 hlslcc_mtx4x4unity_MatrixVP[4];
in highp vec4 in_POSITION0;
in highp vec2 in_TEXCOORD0;
out highp vec2 vs_TEXCOORD0;
vec4 u_xlat0;
vec4 u_xlat1;
void main()
{
u_xlat0 = in_POSITION0.yyyy * hlslcc_mtx4x4unity_ObjectToWorld[1];
u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[0] * in_POSITION0.xxxx + u_xlat0;
u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[2] * in_POSITION0.zzzz + u_xlat0;
u_xlat0 = u_xlat0 + hlslcc_mtx4x4unity_ObjectToWorld[3];
u_xlat1 = u_xlat0.yyyy * hlslcc_mtx4x4unity_MatrixVP[1];
u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[0] * u_xlat0.xxxx + u_xlat1;
u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[2] * u_xlat0.zzzz + u_xlat1;
gl_Position = hlslcc_mtx4x4unity_MatrixVP[3] * u_xlat0.wwww + u_xlat1;
vs_TEXCOORD0.xy = in_TEXCOORD0.xy;
return;
}
This is the fragment shader:
#version 300 es
precision highp float;
precision highp int;
uniform vec4 hlslcc_mtx4x4unity_ObjectToWorld[4];
layout(location = 0) out mediump vec4 SV_Target0;
void main()
{
/////
// Red: works fine.
// Not render: something wrong about hlslcc_mtx4x4unity_ObjectToWorld
SV_Target0 = hlslcc_mtx4x4unity_ObjectToWorld[2];
SV_Target0 = vec4(1,0,0,1);
return;
//////////
}
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,没法儿转,但是顶点着色器里不需要。