[Reading Notes] cp7-Mobile Shader Adjustment(모바일 플랫폼의 shader)

앞에 쓰다


다음 두 장에서 Shader가 서로 다른 플랫폼에서 좋은 모습을 보일 수 있도록 하는 방법을 배울 것이다.우리는 특정한 플랫폼에 대해 토론하지 않고 Shader에서 우리가 조정할 수 있는 각 부분을 분해하고 일반적인 상황에서 모바일 플랫폼의 최적화를 토론한다.Unity 내장 변수에 대한 설명, Shader 메모리를 줄이는 방법 등이 수록되어 있습니다. +Cheap shader + 당신의 shader 분석 + 모바일 플랫폼을 위한 shader 수정

Introdudction


shader의 최적화는 거의 모든 게임 항목에서 볼 수 있다.예를 들어 업데이트된 무늬로 같은 효과를 실현하는 등 항상 주목할 점이 있다.기술 미술, shader 프로그래머로서 shader 최적화의 기본 원리를 이해해야만 성능이 향상되는 동시에 비교적 좋은 효과를 유지할 수 있다.이런 지식을 갖게 되면 shader를 작성하는 데도 도움이 될 것입니다.예를 들어, 당신들의 게임은 모바일 기기 위에서 실행되는 것을 알고 있습니다. 우리는 모든 조명 함수를 직접 반사 벡터를 계산하는 것이 아니라, Half vector 근사 시뮬레이션을 사용할 수 있습니다.

저렴한 shader 소개


이것은 대답하기 어렵다. shader에 대해 최적화를 할 수 있는 방면이 있다.메모리 무늬, 무늬 수량 문제일 수도 있고 shader 자체가 좋은 작업일 수도 있지만 우리는 더 적은 데이터, 코드를 사용하여 같은 효과를 실현할 수 있다.PC든 모바일 기기든 상관없이, 이러한 관련 기술을 어떻게 조합해야 당신의 shader가 어느 정도의 고품질 효과를 유지할 수 있는지 탐색해야 한다.
몇 가지 최적화 사항: + ### 데이터 유형 + Float: 32비트, 부동점수, 정밀도는 높지만 3에서 부동점수 중 가장 느리다.Half: 16자리, 부동점수, [-60000, 60000], 소수점 이하 3자리까지 정확하고 UV값을 저장하기에 적합하며 색상값은float보다 빠르다.Fixed: 보통 11자리, 정점수?범위는 [-2,2] 정밀도 1/256이며, 이 정밀도 설정은 색 연산에 매우 적합하다.
  • #### noforwardadd: Unity가 shader를 바꾸는 물체를 사용하여 한 방향의 벡터만 픽셀로 처리한다(pre-pixel). 그 어떠한 빛도 Spherical Harmonic(SH)라는 매우 간단하고 효율적인 빛모형으로 유닛에 내장된다.우리가 계속 장면에 점광원을 놓으면 점광원에 대한 계산은NormalMap의 요철 정보가 없다는 것을 알 수 있다. 왜냐하면 우리의 Shader가 법상 스티커에 대한 계산은 픽셀마다 있기 때문이다.

  • 그렇다면 주광원으로서 픽셀별 계산을 컨트롤하고 싶을 때가 많다.이렇게 하면 라이트의 Inspector 패널에 있는 RenderMode와 제어할 수 있으며, 3가지 옵션 + Auto가 Unity에 의해 최적의 동작을 결정합니다. +Important는 가능한 한 픽셀별 처리를 하고 +Not Important는 정점별 처리를 한다. 이 옵션을 통해 유니티에게 그 광원은 픽셀별 처리가 필요한 광원으로 여겨져야 하며, 반대로 픽셀별 처리를 해서는 안 된다는 것을 알려줄 수 있다.
  • ### exclude_pass: 이 shader는 deffered rendererer에서 유래한 것을 받아들이지 않는다는 것을 설명합니다.

  • shader code
    Shader "CookbookShaders/self/OptimizeShader001" {
        Properties {
            _MainTex ("Base (RBG)", 2D)="white"{}
            _NormalMap("Normal Map", 2D)="bump"{}
        }
        SubShader {
            Tags { "RenderType"="Opaque" }
            LOD 200
    
            CGPROGRAM
            //define light function ourself, noforwardadd?
            //excluce_path:prepass 
            #pragma surface surf SimpleLambert excluce_path:prepass  noforwardadd
    
            sampler2D _MainTex;
            sampler2D _NormalMap;
    
            struct Input {
                half2 uv_MainTex; //float2 to half2 ,save data
                //half2 uv_NormalMap; remove uv of normalmap ,because same as uv maintex
            };
    
            inline float4 LightingSimpleLambert(SurfaceOutput s, float3 lightDir, float atten)
            {
                //float to fixed save data
                fixed diff = max(0, dot(s.Normal, lightDir));
    
                fixed4 c;
                c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2);
                c.a = s.Alpha;
                return c;
            }
    
            void surf (Input IN, inout SurfaceOutput o) {
                fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
                o.Albedo = c.rgb;
                o.Alpha = c.a;
                o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex));
            }
            ENDCG
        }
        FallBack "Diffuse"
    }
    

    Profiling you shader 너의 Shader 분석


    Unity가 제공하는 Prefiling은 운행 과정에서 모든 대상이 각종 자원에 대한 소모를 실시간으로 파악할 수 있습니다.자세한 내용은 공식 문서를 참조하십시오.https://docs.unity3d.com/Manual/MobileProfiling.html

    모바일 장치의 Shader 수정


    지금까지 우리는 Shader의 최적화 기교를 실천한 적이 있다. 이제 모바일 플랫폼에 예쁘고 질 좋은 Shader를 어떻게 쓰는지 살펴보자.
    Shader "CookbookShaders/self/mobilespeclar" {
        Properties{
            _Diffuse("Base (RGB) Specular Amount (A)", 2D) = "white" {}
        _SpecIntensity("Specular Width", Range(0.01, 1)) = 0.5
            _NormalMap("Normal Map", 2D) = "bump" {}
        }
            SubShader{
            Tags{ "RenderType" = "Opaque" }
            LOD 200
    
            CGPROGRAM
            //define light function ourself, noforwardadd only one direct light should per-pixel
            //excluce_path:prepass 
            //halfasview
    #pragma surface surf MobileBlinnPhong  nolightmap noforwardadd halfasview
    
            sampler2D _Diffuse;
            sampler2D _NormalMap;
            fixed _SpecIntensity;
    
        struct Input {
            half2 uv_Diffuse;
        };
    
        inline float4 LightingMobileBlinnPhong(SurfaceOutput s, fixed3 lightDir, fixed 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 * 2);
            c.a = 0.0;
            return c;
        }
    
        void surf(Input IN, inout SurfaceOutput o) {
            fixed4 c = tex2D(_Diffuse, IN.uv_Diffuse);
            o.Albedo = c.rgb;
            o.Alpha = 0.0;
            o.Specular = _SpecIntensity;
            o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_Diffuse));
        }
        ENDCG
        }
            FallBack "Diffuse"
    }
    
  • nolightmap:lightmap check 닫기
  • noforwawrdadd: 앞에서 말한 바와 같이
  • halfasview: 고광을 계산하는 것은viewDir와lightDir의 중간 벡터를 반사 벡터로 대체하는 것이다.

  • 마지막으로 당신이 진정으로 필요로 하는 데이터만 사용할 수 있도록 하고 게임이 목표 플랫폼에서의 효과에 대해 균형을 잡아야 한다는 것을 알아야 한다.

    좋은 웹페이지 즐겨찾기