• OPTIMIZATION
BASICS
• BATCHING
• LIGHTING
• SHADERS
WORDS TO
SAY
BASICS BATCHING LIGHTING
SHADERS
«В предыдущей серии»
Рендер, шейдеры, пост-процессинг,
etc.
<DevGamm! Minsk 2014>
• Mobile engine/tools developer в Vizor
Intreractive.
• В прошлом – программист графики
Unity3D в Steel Monkeys.
• 3 года опыта работы с графикой (Adobe
flash, DirectX, OpenGL, Metal)
• Работал с большим количеством open-
source игровых движков
Профилирован
ие
Анализ
результатов
Проектирован
ие
Реализац
ия
Играбельная
версия
Финальный билд
Оптимизация -
циклический процесс
увеличения
производительности
BASICS BATCHING LIGHTING
SHADERS
КОГДА ОПТИМИЗИРОВАТЬ ГРАФИКУ
• «Не сейчас» (с) Сначала получите приемлемый результат.
• Когда производительность приложения на целевых
устройствах Вас не устраивает.
• Вместе с гейм-дизайнером – для решения вопросов об
игровой стилистике.
• Вместе с 2D/3D художником – для быстрой переделки
игровых ресурсов.
BASICS BATCHING LIGHTING
SHADERS
ФОРМАЛИЗАЦИЯ
• Что визуально изменится для игрока?
• Каковы преимущества и недостатки оптимизации?
• Какие игровые ресурсы нужно будет переделывать?
• Какой код нужно переписывать (и кто будет это делать)?
• Сколько времени займет оптимизация?
• Энтропия (Что может не заработать?).
В процессе формализации, Вы отвечаете на вопросы: «Что именно я
делаю?» и «Сколько времени это займет?»
BASICS BATCHING LIGHTING
SHADERS
ПРОФИЛИРОВАНИЕ
• Не считайте попугаев (FPS, draw calls), замеряйте время.
• Не замеряйте производительность в сферическом вакууме.
• Создавайте тесты для быстрого получения результатов.
• Записывайте render time, а не frame time (это исключит из
результата swap buffer delay и vSync).
• Обязательно оценивайте «до/после» только по достижении
планируемого результата.
• Получив массив результатов времени, берите медиану, а не
среднее арифметическое, иначе рискуете получить «среднюю
температуру по больнице».
BASICS BATCHING LIGHTING
SHADERS
ПРОФИЛИРОВАНИЕ UNITY-ПРОФАЙЛЕРОМ
• Время Camera.Render() в профайлере – это именно то, что Вам
нужно.
• Напишите простенький MonoBehaviour:
• OnPreCull() – начало фрейма
• OnPostRender() – конец фрейма
• OnGUI() – для вывода результата
BASICS BATCHING LIGHTING
SHADERS
General-purpose tools
• Unity profiler
• GDebugger (OpenGL
desktop)
• Microsoft PiX (DirectX 9)
• ADB GL tracer (android)
• xCode instruments (iOS)
Platform-specific tools:
• Adreno profiler (Qualcomm
Adreno)
• PerfHUD ES (NVidia Tegra)
• Mali profiler (ARM Mali)
• PVRTune (Imagination tec
PowerVR)
На личном опыте:
• Mali – самая проблемная
• Tegra – самая медленная
• PowerVR – самая
производительная
BASICS BATCHING LIGHTING
SHADERS
БАЗОВЫЙ ПОДХОД:
• Упрощайте шейдеры
• Упрощайте пост-процессинг
• Используйте меньше transparent-объектов
• Подключайте LOD’ы
• Используйте Material ID
• Запекайте цвет и свойства материалов в vertexColor и uv2
• Используйте native-текстуры
• Снижайте Fillrate
• Включайте оптимизацию Mesh’ей
BASICS BATCHING LIGHTING
SHADERS
Static batching:
(+)
• Не нужно постоянно перезаписывать VBO.
• Меньше нагрузка на CPU, так как не нужно
трансформировать вершины в runtime.
• Немного меньше matrix multiplications в runtime.
(-)
• Рендер создает физическую копию забатченной геометрии.
• Нет возможности перемещать статически забатченные
объекты.
• Для работы frustum и occlusion culling’a требуется
динамическая перезапись index buffer.
BASICS BATCHING LIGHTING
SHADERS
model matrix position world position
_Object2World – model matrix
_World2Object – inverse model matrix
UNITY_MATRIX_MVP – model-view-projection matrix
BASICS BATCHING LIGHTING
SHADERS
BASICS BATCHING LIGHTING
SHADERS
BASICS BATCHING LIGHTING
SHADERS
BASICS BATCHING LIGHTING
SHADERS
[0] [1] [2] [3] [4]
BASICS BATCHING LIGHTING
SHADERS
BASICS BATCHING LIGHTING
SHADERS
• Используйте как можно меньше
динамических источников
освещения на сцене
• Уменьшайте количество «per-
pixel lights в Quality Settings.
• Помечайте второстепенные
источники света как «non-
important»
• При огромном количестве
источников освещения –
подключайте Deferred shading
• Не слишком полагайтесь на
Surface шейдеры.
LIGHTING
BASICS BATCHING LIGHTING
SHADERS
• SubShader:
• Forward base
• GLES
• Base
• KEYWORD_A
• KEYWORD_B
...
• Shadow caster
• Shadow collector
• DX9
• WP8
• Playstation 3
…
• Forward add
• Prepass base
• Prepass final
Shader "Custom/NewShader" {
Properties {
_MainTex("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
Варианты Вашего
шейдера:
BASICS BATCHING LIGHTING
SHADERS
• 12K triangles
• 24K vertices
• 5X Blend “One
One”
BASICS BATCHING LIGHTING
SHADERS
BASICS BATCHING LIGHTING
SHADERS
https://github.com/RChehowski/devgamm_expo
• 2K triangles
• 4K vertices
• 1 проход
BASICS BATCHING LIGHTING
SHADERS
ОПТИМИЗАЦИЯ ШЕЙДЕРНОГО КОДА
• Используйте апроксимации.
• Упрощайте математику.
• Переносите код из пиксельного шейдера в вершинный
• Не пренебрегайте интринсиками и векторизацией
• По возможности, избегайте ветвления в шейдере
• Используйте ARB_precision_hint
• При необходимости – редактируйте сгенерировнный Unity код
BASICS BATCHING LIGHTING
SHADERS
float x = (v1 * merge) + (v2 * (1.0 – merge));
float x = lerp(v1, v2, merge);
• Не изобретайте велосипед. Почти все уже реализовано в языке
HLSL.
• Иногда удобно использовать интринсики не по прямому
назначению.
ИНТРИНСИКИ
float4 result = dot(float4(0.3, 0.59, 0.11, 1.0), myColor);
• Не забывайте про min(), max(), abs(), mad(), и т.д.
BASICS BATCHING LIGHTING
SHADERS
ВЕКТОРИЗАЦИ
Я
return a.yzx * b.zxy - a.zxy * b.yzx;
return float3(
a.y * b.z - a.z * b.y,
a.z * b.x - a.x * b.z,
a.z * b.y - a.y * b.z
);
• В HLSL скаляры это одномерные векторы, поэтому:
return float3(var, var, var);
• Вы можете делать swizzle в любом, удобном Вам порядке
return var.xxx;
(а вообще, это cross(a,
b))
BASICS BATCHING LIGHTING
SHADERS
if(x == 0)
return a;
else if(x == 1)
return b;
return lerp(a, b, floor(x));
• Постарайтесь избегать ветвления для тривиальных
случаев
• В некоторых случаях, ветвление все-таки лучше:
if(x == 0)
очень
много
кода
else if(x == 1)
clip(-1)
BRANCHING
BASICS BATCHING LIGHTING
SHADERS
struct VertexData {
float a : TEXCOORD0;
float b : TEXCOORD1;
float c : TEXCOORD2;
float d : TEXCOORD3;
};
myMaterial.SetFloat(„a”, 1.0f);
myMaterial.SetFloat(„b”, 2.0f);
myMaterial.SetFloat(„c”, 3.0f);
myMaterial.SetFloat(„d”, 4.0f);
struct VertexData {
float4 abcd : TEXCOORD0;
};
myMaterial.SetVector(
„abcd”,
new Vector4(1.0f, 2.0f, 3.0f, 4.0f
);
• Позволяет заменить 4 вызова glUniform1fv одним вызовом
glUniform4fv
УПАКОВКА
BASICS BATCHING LIGHTING
SHADERS
Вставьте этот код вместо исходного кода Вашего
шейдера
BASICS BATCHING LIGHTING
SHADERS
ВЫВОДЫ
• Процесс оптимизации должен быть достаточно детерминирован
• Оптимизировать можно только финальную версию игры или
модуля
• Во время оптимизации Вы снова возвращаетесь к задаче и в
процессе можете решить проблему, которая казалась
неразрешимой или была оставлена на «и так сойдет…»
СПАСИБО ЗА ВНИМАНИЕ
– Вопросы…?
roman.chehowski@vizor-
interactive.by
inangwis

Unity_ Handmade graphics optimizations by Roman Chehowski

  • 2.
    • OPTIMIZATION BASICS • BATCHING •LIGHTING • SHADERS WORDS TO SAY
  • 3.
    BASICS BATCHING LIGHTING SHADERS «Впредыдущей серии» Рендер, шейдеры, пост-процессинг, etc. <DevGamm! Minsk 2014> • Mobile engine/tools developer в Vizor Intreractive. • В прошлом – программист графики Unity3D в Steel Monkeys. • 3 года опыта работы с графикой (Adobe flash, DirectX, OpenGL, Metal) • Работал с большим количеством open- source игровых движков
  • 4.
  • 5.
    КОГДА ОПТИМИЗИРОВАТЬ ГРАФИКУ •«Не сейчас» (с) Сначала получите приемлемый результат. • Когда производительность приложения на целевых устройствах Вас не устраивает. • Вместе с гейм-дизайнером – для решения вопросов об игровой стилистике. • Вместе с 2D/3D художником – для быстрой переделки игровых ресурсов. BASICS BATCHING LIGHTING SHADERS
  • 6.
    ФОРМАЛИЗАЦИЯ • Что визуальноизменится для игрока? • Каковы преимущества и недостатки оптимизации? • Какие игровые ресурсы нужно будет переделывать? • Какой код нужно переписывать (и кто будет это делать)? • Сколько времени займет оптимизация? • Энтропия (Что может не заработать?). В процессе формализации, Вы отвечаете на вопросы: «Что именно я делаю?» и «Сколько времени это займет?» BASICS BATCHING LIGHTING SHADERS
  • 7.
    ПРОФИЛИРОВАНИЕ • Не считайтепопугаев (FPS, draw calls), замеряйте время. • Не замеряйте производительность в сферическом вакууме. • Создавайте тесты для быстрого получения результатов. • Записывайте render time, а не frame time (это исключит из результата swap buffer delay и vSync). • Обязательно оценивайте «до/после» только по достижении планируемого результата. • Получив массив результатов времени, берите медиану, а не среднее арифметическое, иначе рискуете получить «среднюю температуру по больнице». BASICS BATCHING LIGHTING SHADERS
  • 8.
    ПРОФИЛИРОВАНИЕ UNITY-ПРОФАЙЛЕРОМ • ВремяCamera.Render() в профайлере – это именно то, что Вам нужно. • Напишите простенький MonoBehaviour: • OnPreCull() – начало фрейма • OnPostRender() – конец фрейма • OnGUI() – для вывода результата BASICS BATCHING LIGHTING SHADERS
  • 9.
    General-purpose tools • Unityprofiler • GDebugger (OpenGL desktop) • Microsoft PiX (DirectX 9) • ADB GL tracer (android) • xCode instruments (iOS) Platform-specific tools: • Adreno profiler (Qualcomm Adreno) • PerfHUD ES (NVidia Tegra) • Mali profiler (ARM Mali) • PVRTune (Imagination tec PowerVR) На личном опыте: • Mali – самая проблемная • Tegra – самая медленная • PowerVR – самая производительная BASICS BATCHING LIGHTING SHADERS
  • 10.
    БАЗОВЫЙ ПОДХОД: • Упрощайтешейдеры • Упрощайте пост-процессинг • Используйте меньше transparent-объектов • Подключайте LOD’ы • Используйте Material ID • Запекайте цвет и свойства материалов в vertexColor и uv2 • Используйте native-текстуры • Снижайте Fillrate • Включайте оптимизацию Mesh’ей BASICS BATCHING LIGHTING SHADERS
  • 11.
    Static batching: (+) • Ненужно постоянно перезаписывать VBO. • Меньше нагрузка на CPU, так как не нужно трансформировать вершины в runtime. • Немного меньше matrix multiplications в runtime. (-) • Рендер создает физическую копию забатченной геометрии. • Нет возможности перемещать статически забатченные объекты. • Для работы frustum и occlusion culling’a требуется динамическая перезапись index buffer. BASICS BATCHING LIGHTING SHADERS
  • 12.
    model matrix positionworld position _Object2World – model matrix _World2Object – inverse model matrix UNITY_MATRIX_MVP – model-view-projection matrix BASICS BATCHING LIGHTING SHADERS
  • 13.
  • 14.
  • 15.
  • 16.
    [0] [1] [2][3] [4] BASICS BATCHING LIGHTING SHADERS
  • 17.
  • 18.
    • Используйте какможно меньше динамических источников освещения на сцене • Уменьшайте количество «per- pixel lights в Quality Settings. • Помечайте второстепенные источники света как «non- important» • При огромном количестве источников освещения – подключайте Deferred shading • Не слишком полагайтесь на Surface шейдеры. LIGHTING BASICS BATCHING LIGHTING SHADERS
  • 19.
    • SubShader: • Forwardbase • GLES • Base • KEYWORD_A • KEYWORD_B ... • Shadow caster • Shadow collector • DX9 • WP8 • Playstation 3 … • Forward add • Prepass base • Prepass final Shader "Custom/NewShader" { Properties { _MainTex("Base (RGB)", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert sampler2D _MainTex; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { half4 c = tex2D(_MainTex, IN.uv_MainTex); o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" } Варианты Вашего шейдера: BASICS BATCHING LIGHTING SHADERS
  • 20.
    • 12K triangles •24K vertices • 5X Blend “One One” BASICS BATCHING LIGHTING SHADERS
  • 21.
  • 22.
    • 2K triangles •4K vertices • 1 проход BASICS BATCHING LIGHTING SHADERS
  • 23.
    ОПТИМИЗАЦИЯ ШЕЙДЕРНОГО КОДА •Используйте апроксимации. • Упрощайте математику. • Переносите код из пиксельного шейдера в вершинный • Не пренебрегайте интринсиками и векторизацией • По возможности, избегайте ветвления в шейдере • Используйте ARB_precision_hint • При необходимости – редактируйте сгенерировнный Unity код BASICS BATCHING LIGHTING SHADERS
  • 24.
    float x =(v1 * merge) + (v2 * (1.0 – merge)); float x = lerp(v1, v2, merge); • Не изобретайте велосипед. Почти все уже реализовано в языке HLSL. • Иногда удобно использовать интринсики не по прямому назначению. ИНТРИНСИКИ float4 result = dot(float4(0.3, 0.59, 0.11, 1.0), myColor); • Не забывайте про min(), max(), abs(), mad(), и т.д. BASICS BATCHING LIGHTING SHADERS
  • 25.
    ВЕКТОРИЗАЦИ Я return a.yzx *b.zxy - a.zxy * b.yzx; return float3( a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.z * b.y - a.y * b.z ); • В HLSL скаляры это одномерные векторы, поэтому: return float3(var, var, var); • Вы можете делать swizzle в любом, удобном Вам порядке return var.xxx; (а вообще, это cross(a, b)) BASICS BATCHING LIGHTING SHADERS
  • 26.
    if(x == 0) returna; else if(x == 1) return b; return lerp(a, b, floor(x)); • Постарайтесь избегать ветвления для тривиальных случаев • В некоторых случаях, ветвление все-таки лучше: if(x == 0) очень много кода else if(x == 1) clip(-1) BRANCHING BASICS BATCHING LIGHTING SHADERS
  • 27.
    struct VertexData { floata : TEXCOORD0; float b : TEXCOORD1; float c : TEXCOORD2; float d : TEXCOORD3; }; myMaterial.SetFloat(„a”, 1.0f); myMaterial.SetFloat(„b”, 2.0f); myMaterial.SetFloat(„c”, 3.0f); myMaterial.SetFloat(„d”, 4.0f); struct VertexData { float4 abcd : TEXCOORD0; }; myMaterial.SetVector( „abcd”, new Vector4(1.0f, 2.0f, 3.0f, 4.0f ); • Позволяет заменить 4 вызова glUniform1fv одним вызовом glUniform4fv УПАКОВКА BASICS BATCHING LIGHTING SHADERS
  • 28.
    Вставьте этот кодвместо исходного кода Вашего шейдера BASICS BATCHING LIGHTING SHADERS
  • 29.
    ВЫВОДЫ • Процесс оптимизациидолжен быть достаточно детерминирован • Оптимизировать можно только финальную версию игры или модуля • Во время оптимизации Вы снова возвращаетесь к задаче и в процессе можете решить проблему, которая казалась неразрешимой или была оставлена на «и так сойдет…»
  • 30.
    СПАСИБО ЗА ВНИМАНИЕ –Вопросы…? roman.chehowski@vizor- interactive.by inangwis