אנו מפתחים מערכות חלקיקים ו-VFX למשחקי מובייל שנראות משכנעות גם במכשירים תקציביים. בניסיון שלנו, אפקט שולחני עם 50,000 חלקיקים באייפון 11 הוביל להתחממות יתר ול-20 FPS. מצאנו את הגבול: האפקט נראה איכותי עם 10,000 חלקיקים או פחות תוך שמירה על יציבות תרמית. עם ניסיון מצטבר של למעלה מ-5 שנים, אנו בוחרים את הערימה והטכניקה האופטימליים לכל פלטפורמה. מערכת חלקיקים נכונה מגדילה את שימור השחקנים ב-15% לפי הנתונים שלנו, ללא צורך במכשירים יקרים.
בחירת כלי: Unity לעומת SpriteKit לעומת Metal
רוב משחקי המובייל משתמשים באחד משלושה: מערכת החלקיקים המובנית של Unity (Shuriken), Apple SpriteKit SKEmitterNode, או מערכת מותאמת אישית על Metal/OpenGL ES/Vulkan לדרישות מיוחדות. השוו ביניהם בטבלה.
| כלי | פלטפורמה | ביצועים | גמישות | מתי להשתמש |
|---|---|---|---|---|
| Unity Shuriken | חוצה-פלטפורמות | גבוהים (GPU Instancing) | בינונית | משחקי 2D/3D על Unity |
| SpriteKit SKEmitterNode | iOS | גבוהים מאוד (ילידיים) | נמוכה | משחקי 2D בלבד ל-iOS |
| Metal Compute Shaders | iOS | מקסימליים | גבוהה | אפקטים מותאמים אישית מורכבים |
ה-Shuriken של Unity הוא התקן דה-פקטו. עורך ויזואלי, תמיכה ב-Sub Emitters, GPU Instancing, מהדר Burst לסימולציית CPU. VFX Graph (סימולציית GPU דרך Compute Shaders) עובד על מובייל החל מ-Metal (iOS 12+) ו-Vulkan (Android API 24+). במכשירים ישנים יותר VFX Graph אינו זמין — יש צורך בחזרה ל-Shuriken.
SpriteKit SKEmitterNode מיועד למשחקי 2D באופן ילידי על iOS. פשוט, מהיר, ללא תקורה של Unity. אבל מוגבל: אין Sub Emitters, אין shaders מותאמים אישית ללא Metal. לאפקטים פשוטים (אש, גשם, קונפטי) זה מספיק.
באיזה כלי לבחור ל-VFX במשחק מובייל?
אם הפרויקט חוצה-פלטפורמות, קחו את מערכת החלקיקים של Unity. למשחקי 2D בלבד ל-iOS, SpriteKit מספיק. אם אתם צריכים אפקטים ייחודיים עם שליטה מלאה, כתבו shaders מותאמים אישית על Metal. הצוות שלנו מבטיח שהערימה שנבחרה לא תפגע במגבלות ה-GPU במכשירי היעד.
תקציב חלקיקים ומגבלות GPU
ב-GPUs למובייל (סדרת Apple A, Adreno, Mali) צוואר הבקבוק הוא לעיתים קרובות לא מספר החלקיקים, אלא overdraw — מספר הפעמים שפיקסל בודד על המסך נצבע מחדש בכל פריים. מקור: Apple Developer Documentation
חלקיקים שקופים עם מיזוג אדיטיבי נותנים overdraw המוכפל במספר השכבות. פיצוץ של 5000 חלקיקים במרכז המסך יכול להיות בעל overdraw אמיתי של 50–100x. זה הורג את קצב המילוי אפילו ב-A15.
אסטרטגיות להפחתה:
- Texture Atlasing: כל ספרייטי החלקיקים לאטלס אחד של 512×512 או 1024×1024. מפחית קריאות ציור בשינוי טקסטורה.
- Billboard imposters: לאפקטים נפחיים (ענן פיצוץ) — מרובע עם טקסטורה אפויה במקום מאות כדורים.
- Particle LOD: במרחק/FPS נמוך — הפחתת maxParticles בחצי דרך QualitySettings.particleRaycastBudget או מנהל LOD מותאם אישית.
כיצד לייעל overdraw של חלקיקים צעד אחר צעד:
- זיהוי ה-overdraw הגרוע ביותר באמצעות פרופילר GPU (לדוגמה, Xcode Metal Debugger).
- הפחתת מספר השכבות השקופות על ידי שימוש במיזוג אדיטיבי רק לחלקים הזוהרים.
- החלת texture atlasing על כל ספרייטי החלקיקים.
- הגדרת מערכת LOD להפחתת מספר החלקיקים בחצי מתחת ל-45 FPS.
- בדיקה על מכשיר היעד החלש ביותר (לדוגמה, iPhone SE 2016) לאישור 60 FPS.
// Unity: динамический LOD системы частиц по FPS
public class ParticleLODManager : MonoBehaviour
{
[SerializeField] private ParticleSystem targetSystem;
private ParticleSystem.MainModule _main;
private float _fpsTimer;
void Start()
{
_main = targetSystem.main;
}
void Update()
{
_fpsTimer += Time.deltaTime;
if (_fpsTimer < 1f) return;
_fpsTimer = 0;
float fps = 1f / Time.smoothDeltaTime;
if (fps < 45f)
{
_main.maxParticles = Mathf.Max(100, _main.maxParticles / 2);
}
else if (fps > 58f && _main.maxParticles < originalMax)
{
_main.maxParticles = Mathf.Min(originalMax, _main.maxParticles * 2);
}
}
} מדוע overdraw הוא אויב הביצועים העיקרי?
סימולציית GPU דרך VFX Graph רצה פי 4 מהר יותר מסימולציית CPU ב-A14 Bionic, אבל overdraw אוכל את הרווח הזה. עם מיזוג אדיטיבי, כל פיקסל יכול להיצבע מחדש עשרות פעמים. כדי להימנע מכך, אנו מיישמים texture atlasing ומפחיתים את מספר החלקיקים עם חפיפת אלפא גבוהה.
Shaders מותאמים אישית ל-VFX למובייל
ה-shaders המובנים של Unity לחלקיקים (Particles/Standard Unlit) בטוחים אך מוגבלים. לאפקט dissolve, עיוות חום, מגן אנרגיה — יש צורך ב-shader מותאם אישית.
במובייל החוקים מחמירים: אין discard ב-shader (שובר early Z-test, קצב המילוי יורד), מינימום דגימות טקסטורה, הימנעות מקריאות טקסטורה תלויות. Shader Model 2.0 כבסיס לכיסוי רחב.
דוגמה לאפקט עיוות פשוט לפיצוץ (Unity HLSL):
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _NoiseTex;
float _DistortionStrength;
float _FadeEdges;
fixed4 frag (v2f i) : SV_Target
{
float2 noise = tex2D(_NoiseTex, i.uv + _Time.y * 0.3).rg * 2 - 1;
float2 distortedUV = i.uv + noise * _DistortionStrength * i.color.a;
float edge = 1 - saturate(distance(distortedUV, float2(0.5, 0.5)) * _FadeEdges);
fixed4 col = tex2D(_MainTex, distortedUV) * i.color;
col.a *= edge;
return col;
}
ENDCGi.color.a הוא אלפא החלקיק ממערכת החלקיקים של Unity, מסונכרן עם אורך החיים. העיוות דועך עם החלקיק אוטומטית.
אפקטים ב-SpriteKit: אש וקונפטי
ניתן להגדיר SKEmitterNode בעורך Xcode (קובץ .sks) או פרוגרמטית. פרוגרמטית עדיפה לפרמטרים דינמיים:
func makeFireEmitter() -> SKEmitterNode {
let emitter = SKEmitterNode()
emitter.particleTexture = SKTexture(imageNamed: "spark")
emitter.particleBirthRate = 120
emitter.particleLifetime = 1.2
emitter.particleLifetimeRange = 0.4
emitter.particleSpeed = 80
emitter.particleSpeedRange = 40
emitter.emissionAngle = .pi / 2 // вверх
emitter.emissionAngleRange = .pi / 8
emitter.particleScale = 0.15
emitter.particleScaleSpeed = -0.1
emitter.particleAlphaSpeed = -0.8
emitter.particleColorSequence = SKKeyframeSequence(
keyframeValues: [SKColor.yellow, SKColor.orange, SKColor.red, SKColor.clear],
times: [0, 0.3, 0.7, 1.0]
)
emitter.particleBlendMode = .add
return emitter
}// Unity: динамический LOD системы частиц по FPS public class ParticleLODManager : MonoBehaviour { [SerializeField] private ParticleSystem targetSystem; private ParticleSystem.MainModule _main; private float _fpsTimer; void Start() { _main = targetSystem.main; } void Update() { _fpsTimer += Time.deltaTime; if (_fpsTimer < 1f) return; _fpsTimer = 0; float fps = 1f / Time.smoothDeltaTime; if (fps < 45f) { _main.maxParticles = Mathf.Max(100, _main.maxParticles / 2); } else if (fps > 58f && _main.maxParticles < originalMax) { _main.maxParticles = Mathf.Min(originalMax, _main.maxParticles * 2); } } } מיזוג — מיזוג אדיטיבי. אש וניצוצות נראים זוהרים. לא בשימוש לעשן ואבק — שם יש צורך ב-CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _NoiseTex; float _DistortionStrength; float _FadeEdges; fixed4 frag (v2f i) : SV_Target { float2 noise = tex2D(_NoiseTex, i.uv + _Time.y * 0.3).rg * 2 - 1; float2 distortedUV = i.uv + noise * _DistortionStrength * i.color.a; float edge = 1 - saturate(distance(distortedUV, float2(0.5, 0.5)) * _FadeEdges); fixed4 col = tex2D(_MainTex, distortedUV) * i.color; col.a *= edge; return col; } ENDCG .
כלי פרופיל GPU
Xcode Metal Debugger — לכידת פריים למשחקי Metal. ראו כל קריאת ציור, טקסטורות, ויזואליזציה של overdraw. ל-Unity על iOS: דרך Xcode GPU Frame Debugger כשמחוברים באמצעות USB.
Android GPU Inspector (AGI) — מגוגל עבור Adreno ו-Mali. Frame Profiler מראה את שלבי הצינור שבהם ה-GPU ממתין.
Unity Profiler — מובנה, מראה זמן CPU/GPU לכל רינדור אפקט. Rendering → ParticleSystem.Update לוקח יותר מ-2ms — בדקו סימולציית CPU והפחיתו maxParticles או עברו למצב GPU.
מה כלול בעבודה
- פיתוח shader מותאם אישית לפלטפורמת היעד
- אופטימיזציה של מערכות חלקיקים קיימות (LOD, atlasing, overdraw)
- אינטגרציה למנוע המשחק (Unity, SpriteKit, מותאם אישית)
- פרופיל וכוונון למכשירים חלשים (לדוגמה, iPhone SE 2016)
- תיעוד פרמטרים ותמיכה
- הדרכה לצוות שלכם כיצד להשתמש ולהרחיב את ה-VFX
- תמיכה שוטפת בחודש הראשון לאחר המסירה
תהליך העבודה
ניהול אמנותי טכני: אילו אפקטים נדרשים, תדירותם על המסך בו-זמנית, מכשירי יעד. פיתוח shaders ומערכות חלקיקים בעורך עם פרופיל על מכשיר Android חלש. הגדרת מערכת LOD. אינטגרציה למנוע המשחק, בדיקת חנק תרמי (סשן משחק של 10 דקות עם ניתוח טמפרטורה).
הערכות זמן
3–5 ימי עבודה לסט VFX בסיסי (3–5 סוגי אפקטים) החל מ-$500. מערכת מותאמת אישית מורכבת על Metal Compute Shaders — משבועיים, החל מ-$2000. העלות המדויקת מחושבת באופן אישי לאחר ניתוח הדרישות שלכם. אנו נעריך את הפרויקט שלכם: צרו קשר לניתוח מקדים. קבלו ייעוץ לבחירת כלים לאפקטים שלכם.
טבלת השוואת טכניקות להפחתת overdraw
| טכניקה | הפחתת overdraw | מורכבות | זמן יישום |
|---|---|---|---|
| Texture atlasing | הפחתה של פי 2-3 | נמוכה | יום אחד |
| Billboard imposters | פי 10 לאפקטים נפחיים | בינונית | 2-3 ימים |
| Particle LOD | פי 2 בעת הצורך | נמוכה | יום אחד |
| הפחתת max particles | פי 5 אם מופחת בחצי | נמוכה | שעה אחת |







