1
\$\begingroup\$

I'm writing my own shader in mobile, but was wondering if it uses default GPU or CPU skinning feature in Unity3D?

I'd like to use GPU skinning and already enabled GPU skinning. Is there any way to determine which (GPU or CPU) was actually used?

My shader is as below:

 Shader "Mobile Custom/Specular Map" {
 Properties {
     _ShininessColor("Shininess Color", Color) = (1,1,1,1)
     _Shininess ("Shininess", Range (0.03, 1)) = 0.078125
     _MainTex ("Base (RGB)", 2D) = "white" {}
     _SpecMap ("Specular Map", 2D) = "white" {}
 }
 SubShader {
     Tags { "RenderType"="Opaque" }
     LOD 250
     Cull Back

     CGPROGRAM
     #pragma surface surf MobileBlinnPhong exclude_path:prepass nolightmap halfasview interpolateview noshadow nofog nometa nolppv noshadowmask

     inline fixed4 LightingMobileBlinnPhong (SurfaceOutput s, fixed3 lightDir, fixed3 halfDir, fixed atten) {
         fixed diff = max (0, dot (s.Normal, lightDir));
         fixed nh = max (0, dot (s.Normal, halfDir));
         fixed spec = pow (nh, s.Specular * 128) * s.Gloss;

         fixed4 c;
         c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * spec) * atten;
         UNITY_OPAQUE_ALPHA(c.a);
         return c;
     }

     sampler2D _MainTex;
     sampler2D _SpecMap;
     uniform float4 _ShininessColor;
     half _Shininess;

     struct Input {
         float2 uv_MainTex;
     };

     void surf (Input IN, inout SurfaceOutput o) {
         fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
         o.Albedo = tex.rgb;
         o.Gloss = tex2D(_SpecMap, IN.uv_MainTex) * _ShininessColor;
         o.Alpha = tex.a;
         o.Specular = _Shininess;
     }
     ENDCG
 }

 FallBack "Mobile/VertexLit"
 }
\$\endgroup\$
  • \$\begingroup\$ Did you try applying your shader on a skinned mesh to test it? \$\endgroup\$ – DMGregory Jan 27 at 14:05
  • \$\begingroup\$ yes~ tried it and it worked. But i'm not sure it's using CPU skinning or GPU skinning. Is there any way we can check this? \$\endgroup\$ – kkl Jan 27 at 14:08
  • \$\begingroup\$ If that's what you need to know, then that sounds like a good way to phrase your question. You can use the edit link at the bottom of the question to revise it. \$\endgroup\$ – DMGregory Jan 27 at 14:13
  • \$\begingroup\$ Done edit~ Do u have any clue, @DMGregory? \$\endgroup\$ – kkl Jan 27 at 14:44
1
\$\begingroup\$

The closest I was able to come to tracking this down was a comment I noticed in an official Unity tutorial called Mobile Considerations (for version: 2017.4):

GPU Skinning

Although GPU Skinning is a selectable option in Build Settings for all platforms, it is not supported by any mobile platform. This option will be removed in upcoming Unity releases.

Taken from your own finding about Android settings on version 2018.3, it appears that Unity now limits GPU skinning to VR:

GPU Skinning

Enable this option to use OpenGL ES 3 GPU skinning. To learn more about GPU skinning, see the Wikipedia page on skeletal animation.

Note: This property only supports VR apps, and only works if the Virtual Reality Supported checkbox is ticked.

Regarding their motivation for this, the best I could find is this piece (from version 2018.3) on mobile optimization:

Focus on CPUs

It is often the case that games are limited by the GPU on pixel processing. So they end up having unused CPU power, especially on multicore mobile CPUs. So it is often sensible to pull some work off the GPU and put it onto the CPU instead (Unity does all of these): mesh skinning , batching of small objects, particle geometry updates.

My best guess is that Unity eventually decided that either in general the performance trade offs were such that CPU skinning gave better results than GPU skinning or that the there were some other complications with support this feature. Based on some much older forum discussions, it seems that GPU skinning is only available on certain version of DirectX & OpenGL. It's also possible that rather than deal with a lot of user confusion about when & where a minor feature was & was not taking effect, that they simply removed it from the options.

Regarding the comment about CPU skinning hurting performance (in mobile apps), the only way to know that for certain would be to profile. It's fine to have hunches, but if you are serious about improving performance, should always start & end with profiling. Use profiling at the beginning to find the problem spots (instead of guessing & wasting time on things that aren't relevant) & use it after changes in development strategy to make sure you're moving the right things in the right direction.

\$\endgroup\$
  • \$\begingroup\$ That's a good finding~ I also found this docs.unity3d.com/Manual/…. It mentions GPU skinning will only be enabled for VR apps only. But why? If i have high polygon count model, it would slow down the performance in mobile apps \$\endgroup\$ – kkl Jan 30 at 2:09
  • \$\begingroup\$ @kkl I've updated my answer with some info that attempts to address this. I also added your info (good find) since it might help others. Ultimately, the only one who can explain why Unity did Z is Unity & in the absence of an official rationale, this is my best educated guess on the matter. \$\endgroup\$ – Pikalek Jan 30 at 17:12
  • \$\begingroup\$ it's so much clearer now. Thanks @Pikalek. I mean for game, it totally makes sense to use both CPU and GPU at the fullest. But for my case, I'm building a 3D live wallpaper, and battery is a big concern. Using CPU skinning takes more battery than GPU, as far as I've tested. Well i guess I'll need to implement my own GPU skinning instead \$\endgroup\$ – kkl Jan 31 at 14:41

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.