Izpētiet revolucionāro WebGL Mesh Shader pipeline. Uzziniet, kā Task Amplification nodrošina masveida ģeometrijas ģenerēšanu lidojumā un uzlabotu apcirpšanu nākamās paaudzes tīmekļa grafikai.
Ģeometrijas atbrīvošana: Dziļš ieskats WebGL Mesh Shader Task Amplification Pipeline
Tīmeklis vairs nav statisks, divdimensiju medijs. Tas ir attīstījies par dinamisku platformu bagātīgai, ieskaujošai 3D pieredzei, sākot no elpu aizraujošiem produktu konfiguratoriem un arhitektūras vizualizācijām līdz sarežģītiem datu modeļiem un pilnvērtīgām spēlēm. Tomēr šī evolūcija rada nepieredzētas prasības grafikas apstrādes vienībai (GPU). Gadiem ilgi standarta reāllaika grafikas pipeline, lai arī jaudīgs, ir parādījis savu vecumu, bieži vien darbojoties kā šķērslis ģeometriskās sarežģītības veidam, ko pieprasa mūsdienu lietojumprogrammas.
Iepazīstinām ar Mesh Shader pipeline, kas ir paradigma maiņas funkcija, kas tagad ir pieejama tīmeklī, izmantojot WEBGL_mesh_shader paplašinājumu. Šis jaunais modelis fundamentāli maina to, kā mēs domājam par ģeometriju GPU un kā to apstrādājam. Tās pamatā ir spēcīgs jēdziens: Task Amplification. Tas nav tikai pakāpenisks atjauninājums; tas ir revolucionārs lēciens, kas pārvieto plānošanas un ģeometrijas ģenerēšanas loģiku no CPU tieši uz GPU ļoti paralēlo arhitektūru, paverot iespējas, kas iepriekš bija nepraktiskas vai neiespējamas tīmekļa pārlūkprogrammā.
Šī visaptverošā rokasgrāmata aizvedīs jūs dziļā ceļojumā mesh shader ģeometrijas pipeline. Mēs izpētīsim tā arhitektūru, izpratīsim Task un Mesh shader atšķirīgās lomas un atklāsim, kā task amplification var izmantot, lai izveidotu nākamās paaudzes vizuāli satriecošas un veiktspējīgas tīmekļa lietojumprogrammas.
Ātrs atskats: Tradicionālās ģeometrijas pipeline ierobežojumi
Lai patiesi novērtētu mesh shader inovāciju, mums vispirms jāsaprot pipeline, ko tie aizstāj. Gadu desmitiem reāllaika grafikā ir dominējis salīdzinoši fiksētas funkcijas pipeline:
- Vertex Shader: Apstrādā atsevišķas virsotnes, pārveidojot tās ekrāna telpā.
- (Neobligāti) Tessellation Shaders: Sadala ģeometrijas ielāpus, lai izveidotu smalkākas detaļas.
- (Neobligāti) Geometry Shader: Var izveidot vai iznīcināt primitīvus (punktus, līnijas, trīsstūrus) lidojumā.
- Rasterizer: Pārvērš primitīvus pikseļos.
- Fragment Shader: Aprēķina katra pikseļa galīgo krāsu.
Šis modelis mums labi kalpoja, taču tam ir raksturīgi ierobežojumi, īpaši, kad skati kļūst sarežģītāki:
- CPU-saistīti zīmēšanas izsaukumi: CPU ir milzīgs uzdevums noskaidrot, kas tieši ir jāzīmē. Tas ietver frustum culling (objektu noņemšana ārpus kameras skata), occlusion culling (objektu noņemšana, ko slēpj citi objekti) un level-of-detail (LOD) sistēmu pārvaldību. Attiecībā uz skatu ar miljoniem objektu tas var izraisīt CPU kļūšanu par galveno šķērsli, nespējot pietiekami ātri pabarot izsalkušo GPU.
- Stingra ievades struktūra: Pipeline ir veidots ap stingru ievades apstrādes modeli. Input Assembler padevē virsotnes pa vienai, un shader apstrādā tās salīdzinoši ierobežotā veidā. Tas nav ideāli piemērots modernām GPU arhitektūrām, kas izceļas ar saskaņotu, paralēlu datu apstrādi.
- Neefektīva amplification: Lai gan Geometry Shaders atļāva ģeometrijas amplification (jaunu trīsstūru izveide no ievades primitīva), tie bija bēdīgi neefektīvi. To izvades uzvedība aparatūrai bieži bija neparedzama, izraisot veiktspējas problēmas, kas padarīja tos par ne-starter daudzām liela mēroga lietojumprogrammām.
- Izniekots darbs: Tradicionālajā pipeline, ja jūs nosūtāt trīsstūri renderēšanai, vertex shader darbosies trīs reizes, pat ja šis trīsstūris galu galā tiek apcirpts vai ir pretēji vērsts pikseļu plāns šķērsgriezums. Liels apstrādes jaudas daudzums tiek tērēts ģeometrijai, kas neko neveicina galīgajam attēlam.
Paradigma maiņa: Iepazīstinām ar Mesh Shader Pipeline
Mesh Shader pipeline aizstāj Vertex, Tessellation un Geometry shader posmus ar jaunu, elastīgāku divu posmu modeli:
- Task Shader (Neobligāti): Augsta līmeņa vadības posms, kas nosaka, cik daudz darba ir jāpaveic. Pazīstams arī kā Amplification Shader.
- Mesh Shader: Darba zirga posms, kas darbojas ar datu paketēm, lai ģenerētu mazas, pašpietiekamas ģeometrijas paketes, ko sauc par "meshlets".
Šī jaunā pieeja fundamentāli maina renderēšanas filozofiju. Tā vietā, lai CPU mikropārvaldītu katru zīmēšanas izsaukumu katram objektam, tas tagad var izdot vienu, spēcīgu zīmēšanas komandu, kas būtībā pasaka GPU: "Šeit ir augsta līmeņa sarežģīta skata apraksts; jūs izdomājat detaļas."
GPU, izmantojot Task un Mesh shader, var veikt apcirpšanu, LOD atlasi un procedūru ģenerēšanu ļoti paralēlā veidā, palaižot tikai nepieciešamo darbu, lai ģenerētu ģeometriju, kas patiesībā būs redzama. Šī ir GPU vadīta renderēšanas pipeline būtība, un tā maina spēli veiktspējai un mērogojamībai.
Diriģents: Task (Amplification) Shader izpratne
Task Shader ir jaunā pipeline smadzenes un atslēga uz tā neticamo spēku. Tas ir neobligāts posms, bet tajā notiek "amplification". Tās galvenā loma nav virsotņu vai trīsstūru ģenerēšana, bet gan darba dispečera loma.
Kas ir Task Shader?
Iedomājieties Task Shader kā projektu vadītāju milzīgam būvniecības projektam. CPU dod vadītājam augsta līmeņa mērķi, piemēram, "uzbūvēt pilsētas rajonu". Projektu vadītājs (Task Shader) pats neklāj ķieģeļus. Tā vietā tas novērtē kopējo uzdevumu, pārbauda rasējumus un nosaka, kuras būvniecības komandas (Mesh Shader darba grupas) ir nepieciešamas un cik daudz. Tas var nolemt, ka noteikta ēka nav nepieciešama (apcirpšana) vai ka noteiktai vietai ir nepieciešamas desmit komandas, bet citai - tikai divas.
Tehniski runājot, Task Shader darbojas kā compute-like darba grupa. Tas var piekļūt atmiņai, veikt sarežģītus aprēķinus un, pats galvenais, izlemt, cik daudz Mesh Shader darba grupu palaist. Šis lēmums ir tā spēka pamatā.
Amplification spēks
Termins "amplification" nāk no Task Shader spējas ņemt vienu savu darba grupu un palaist nulli, vienu vai daudzas Mesh Shader darba grupas. Šī spēja ir transformējoša:
- Palaist nulli: Ja Task Shader nosaka, ka objekts vai skata daļa nav redzama (piemēram, ārpus kameras frustum), tas var vienkārši izvēlēties palaist nulli Mesh Shader darba grupu. Viss potenciālais darbs, kas saistīts ar šo objektu, pazūd, nekad netiekot apstrādāts tālāk. Šī ir neticami efektīva apcirpšana, kas tiek veikta pilnībā GPU.
- Palaist vienu: Šī ir tieša caurlaide. Task Shader darba grupa nolemj, ka ir nepieciešama viena Mesh Shader darba grupa.
- Palaist daudzas: Šeit notiek maģija procedūru ģenerēšanai. Viena Task Shader darba grupa var analizēt dažus ievades parametrus un nolemt palaist tūkstošiem Mesh Shader darba grupu. Piemēram, tā varētu palaist darba grupu katram zāles stiebram laukā vai katram asteroīdam blīvā kopā, un tas viss no vienas CPU nosūtīšanas komandas.
Konceptuāls skatījums uz Task Shader GLSL
Lai gan specifika var kļūt sarežģīta, galvenais amplification mehānisms GLSL (WebGL paplašinājumam) ir pārsteidzoši vienkāršs. Tas griežas ap `EmitMeshTasksEXT()` funkciju.
Piezīme: Šis ir vienkāršots, konceptuāls piemērs.
#version 310 es
#extension GL_EXT_mesh_shader : require
layout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;
// Uniforms, kas nodoti no CPU
uniform mat4 u_viewProjectionMatrix;
uniform uint u_totalObjectCount;
// Buferis, kas satur ierobežojošas sfēras daudziem objektiem
struct BoundingSphere {
vec4 centerAndRadius;
};
layout(std430, binding = 0) readonly buffer ObjectBounds {
BoundingSphere bounds[];
} objectBounds;
void main() {
// Katrs pavediens darba grupā var pārbaudīt citu objektu
uint objectIndex = gl_GlobalInvocationID.x;
if (objectIndex >= u_totalObjectCount) {
return;
}
// Veikt frustum culling GPU šī objekta ierobežojošai sfērai
BoundingSphere sphere = objectBounds.bounds[objectIndex];
bool isVisible = isSphereInFrustum(sphere.centerAndRadius, u_viewProjectionMatrix);
// Ja tas ir redzams, palaidiet vienu Mesh Shader darba grupu, lai to uzzīmētu.
// Piezīme: Šī loģika varētu būt sarežģītāka, izmantojot atomics, lai saskaitītu redzamus
// objektus un lai vienam pavedienam būtu nosūtīšana visiem.
if (isVisible) {
// Tas liek GPU palaist mesh uzdevumu. Parametrus var izmantot
// lai nodotu informāciju Mesh Shader darba grupai.
// Vienkāršības labad mēs iedomājamies, ka katrs uzdevumu shader izsaukums var tieši kartēt uz mesh uzdevumu.
// Reālistiskāks scenārijs ietver grupēšanu un nosūtīšanu no viena pavediena.
// Vienkāršots konceptuāls nosūtīšana:
// Mēs izliksimies, ka katrs redzamais objekts saņem savu uzdevumu, lai gan patiesībā
// viens uzdevumu shader izsaukums pārvaldītu vairāku mesh shader nosūtīšanu.
EmitMeshTasksEXT(1u, 0u, 0u); // Šī ir galvenā amplification funkcija
}
// Ja nav redzams, mēs neko nedarām! Objekts tiek apcirpts ar nulles GPU izmaksām ārpus šīs pārbaudes.
}
Reālajā scenārijā jums varētu būt viens pavediens darba grupā, kas apkopo rezultātus un veic vienu `EmitMeshTasksEXT` zvanu visiem redzamajiem objektiem, par kuriem ir atbildīga darba grupa.
Darbaspēks: Mesh Shader loma ģeometrijas ģenerēšanā
Tiklīdz Task Shader ir nosūtījis vienu vai vairākas darba grupas, Mesh Shader pārņem vadību. Ja Task Shader ir projektu vadītājs, Mesh Shader ir kvalificēta būvniecības komanda, kas faktiski būvē ģeometriju.No darba grupām līdz meshlets
Līdzīgi kā Task Shader, Mesh Shader izpildās kā sadarbības pavedienu darba grupa. Visas šīs darba grupas kolektīvais mērķis ir izveidot vienu, nelielu ģeometrijas paketi, ko sauc par meshlet. Meshlet ir vienkārši virsotņu un primitīvu (trīsstūru) kolekcija, kas tos savieno. Parasti meshlet satur nelielu virsotņu skaitu (piemēram, līdz 128) un trīsstūrus (piemēram, līdz 256), izmērs, kas ir ļoti draudzīgs moderniem GPU kešatmiņām un apstrādes modeļiem.
Šī ir fundamentāla atkāpe no vertex shader, kuram nebija jēdziena par saviem kaimiņiem. Mesh Shader visiem pavedieniem darba grupā var būt kopīga atmiņa un koordinēt savus centienus, lai efektīvi izveidotu meshlet.
Virsotņu un primitīvu ģenerēšana
Tā vietā, lai atgrieztu vienu `gl_Position`, Mesh Shader darba grupa aizpilda izvades masīvus ar pilnīgiem datiem savam meshlet. Pavedieni strādā kopā, lai šajos masīvos ierakstītu virsotņu pozīcijas, normas, UV koordinātas un citus atribūtus. Viņi arī definē primitīvus, norādot, kuras virsotnes veido katru trīsstūri.
Pēdējais solis Mesh Shader ir izsaukt funkciju, piemēram, `SetMeshOutputsEXT()`, lai deklarētu, cik daudz virsotņu un primitīvu tā ir ģenerējis. Pēc tam aparatūra ņem šo meshlet un nodod to tieši rasterizatoram.
Konceptuāls skatījums uz Mesh Shader GLSL
Šeit ir konceptuāls piemērs Mesh Shader, kas ģenerē vienkāršu quad. Ievērojiet, kā pavedieni sadarbojas, pamatojoties uz savu `gl_LocalInvocationID`.
#version 310 es
#extension GL_EXT_mesh_shader : require
// Definējiet maksimālās izvades mūsu meshlet
layout(max_vertices = 4, max_primitives = 2) out;
layout(triangles) out;
layout(local_size_x = 4, local_size_y = 1, local_size_z = 1) in;
// Mēs rakstām virsotņu datus šajos iebūvētajos izvades masīvos
out gl_MeshVerticesEXT {
vec4 position;
vec2 uv;
} vertices[];
// Mēs rakstām trīsstūra indeksus šajā masīvā
out uint gl_MeshPrimitivesEXT[];
uniform mat4 u_modelViewProjectionMatrix;
void main() {
// Kopējais virsotņu un primitīvu skaits, kas jāģenerē šim meshlet
const uint vertexCount = 4;
const uint primitiveCount = 2;
// Pasakiet aparatūrai, cik daudz virsotņu un primitīvu mēs faktiski izvadām
SetMeshOutputsEXT(vertexCount, primitiveCount);
// Definējiet virsotņu pozīcijas un UV quad
vec4 positions[4] = vec4[4](
vec4(-0.5, 0.5, 0.0, 1.0),
vec4(-0.5, -0.5, 0.0, 1.0),
vec4(0.5, 0.5, 0.0, 1.0),
vec4(0.5, -0.5, 0.0, 1.0)
);
vec2 uvs[4] = vec2[4](
vec2(0.0, 1.0),
vec2(0.0, 0.0),
vec2(1.0, 1.0),
vec2(1.0, 0.0)
);
// Ļaujiet katram pavedienam darba grupā ģenerēt vienu virsotni
uint id = gl_LocalInvocationID.x;
if (id < vertexCount) {
vertices[id].position = u_modelViewProjectionMatrix * positions[id];
vertices[id].uv = uvs[id];
}
// Ļaujiet pirmajiem diviem pavedieniem ģenerēt divus trīsstūrus quad
if (id == 0) {
// Pirmais trīsstūris: 0, 1, 2
gl_MeshPrimitivesEXT[0] = 0u;
gl_MeshPrimitivesEXT[1] = 1u;
gl_MeshPrimitivesEXT[2] = 2u;
}
if (id == 1) {
// Otrais trīsstūris: 1, 3, 2
gl_MeshPrimitivesEXT[3] = 1u;
gl_MeshPrimitivesEXT[4] = 3u;
gl_MeshPrimitivesEXT[5] = 2u;
}
}
Praktiskā maģija: Task Amplification lietošanas gadījumi
Šī pipeline patiesais spēks tiek atklāts, kad mēs to pielietojam sarežģītiem, reāliem renderēšanas izaicinājumiem.
1. lietošanas gadījums: Masveida procedūru ģeometrijas ģenerēšana
Iedomājieties, ka tiek renderēts blīvs asteroīdu lauks ar simtiem tūkstošu unikālu asteroīdu. Izmantojot veco pipeline, CPU būtu jāģenerē katra asteroīda virsotņu dati un jāizdod atsevišķs zīmēšanas izsaukums katram, kas ir pilnīgi neiespējama pieeja.
Mesh Shader Workflow:
- CPU izdod vienu zīmēšanas izsaukumu: `drawMeshTasksEXT(1, 1)`. Tā arī nodod dažus augsta līmeņa parametrus, piemēram, lauka rādiusu un asteroīdu blīvumu, uniform buferī.
- Tiek izpildīta viena Task Shader darba grupa. Tā nolasa parametrus un aprēķina, ka, teiksim, ir nepieciešami 50 000 asteroīdu. Pēc tam tā izsauc `EmitMeshTasksEXT(50000, 0, 0)`.
- GPU paralēli palaiž 50 000 Mesh Shader darba grupu.
- Katra Mesh Shader darba grupa izmanto savu unikālo ID (`gl_WorkGroupID`) kā sēklu, lai procedūru ģenerētu virsotnes un trīsstūrus vienam unikālam asteroīdam.
Rezultāts ir milzīgs, sarežģīts skats, kas tiek ģenerēts gandrīz pilnībā GPU, atbrīvojot CPU, lai apstrādātu citus uzdevumus, piemēram, fiziku un AI.
2. lietošanas gadījums: GPU vadīta apcirpšana lielā mērogā
Apsveriet detalizētu pilsētas skatu ar miljoniem atsevišķu objektu. CPU vienkārši nevar pārbaudīt katra objekta redzamību katrā kadrā.
Mesh Shader Workflow:
- CPU augšupielādē lielu buferi, kas satur ierobežojošos tilpumus (piemēram, sfēras vai kastes) katram atsevišķam objektam skatā. Tas notiek vienreiz vai tikai tad, kad objekti pārvietojas.
- CPU izdod vienu zīmēšanas izsaukumu, palaižot pietiekami daudz Task Shader darba grupu, lai paralēli apstrādātu visu ierobežojošo tilpumu sarakstu.
- Katra Task Shader darba grupa tiek piešķirta ierobežojošo tilpumu saraksta daļai. Tā atkārto savus piešķirtos objektus, veic frustum culling (un potenciāli occlusion culling) katram no tiem un saskaita, cik daudz ir redzami.
- Visbeidzot, tā palaiž tieši tik daudz Mesh Shader darba grupu, nododot redzamo objektu ID.
- Katra Mesh Shader darba grupa saņem objekta ID, meklē tā mesh datus no bufera un ģenerē atbilstošos meshlets renderēšanai.
Tas pārvieto visu apcirpšanas procesu uz GPU, ļaujot skatiem ar sarežģītību, kas uzreiz sagrautu CPU balstītu pieeju.
3. lietošanas gadījums: Dinamisks un efektīvs detalizācijas līmenis (LOD)
LOD sistēmas ir būtiskas veiktspējai, pārslēdzoties uz vienkāršākiem modeļiem objektiem, kas atrodas tālu. Mesh shaders padara šo procesu detalizētāku un efektīvāku.
Mesh Shader Workflow:
- Objekta dati tiek iepriekš apstrādāti meshlets hierarhijā. Rupjāki LOD izmanto mazāk, lielākus meshlets.
- Šī objekta Task Shader aprēķina tā attālumu no kameras.
- Pamatojoties uz attālumu, tas nolemj, kurš LOD līmenis ir atbilstošs. Pēc tam tas var veikt apcirpšanu katram meshlet atsevišķi šim LOD. Piemēram, lielam objektam tas var apcirpt meshlets objekta aizmugurē, kas nav redzami.
- Tas palaiž tikai Mesh Shader darba grupas redzamajiem atlasītā LOD meshlets.
Tas ļauj veikt smalku, lidojumā LOD atlasi un apcirpšanu, kas ir daudz efektīvāka nekā CPU apmainīt visu modeli.
Darba sākšana: Izmantojot `WEBGL_mesh_shader` paplašinājumu
Vai esat gatavs eksperimentēt? Šeit ir praktiski soļi, lai sāktu darbu ar mesh shaders WebGL.
Atbalsta pārbaude
Pirmkārt un galvenokārt, šī ir moderna funkcija. Jums ir jāpārliecinās, vai lietotāja pārlūkprogramma un aparatūra to atbalsta.
const gl = canvas.getContext('webgl2');
const meshShaderExtension = gl.getExtension('WEBGL_mesh_shader');
if (!meshShaderExtension) {
console.error("Jūsu pārlūkprogramma vai GPU neatbalsta WEBGL_mesh_shader.");
// Atgriezties pie tradicionālā renderēšanas ceļa
}
Jaunais zīmēšanas izsaukums
Aizmirstiet `drawArrays` un `drawElements`. Jaunā pipeline tiek izsaukta ar jaunu komandu. Paplašinājuma objekts, ko saņemat no `getExtension`, saturēs jaunās funkcijas.
// Palaidiet 10 Task Shader darba grupas.
// Katrai darba grupai būs shader definēts local_size.
meshShaderExtension.drawMeshTasksEXT(0, 10);
Arguments `count` norāda, cik daudz Task Shader lokālo darba grupu palaist. Ja jūs neizmantojat Task Shader, tas tieši palaiž Mesh Shader darba grupas.
Shader kompilācija un saistīšana
Process ir līdzīgs tradicionālajam GLSL, bet jūs veidosiet shader veidus `meshShaderExtension.MESH_SHADER_EXT` un `meshShaderExtension.TASK_SHADER_EXT`. Jūs saistāt tos kopā programmā tāpat kā vertex un fragment shader.
Būtiski, ka jūsu GLSL pirmkodam abiem shader ir jāsākas ar direktīvu, lai iespējotu paplašinājumu:
#extension GL_EXT_mesh_shader : require
Veiktspējas apsvērumi un labākā prakse
- Izvēlieties pareizo darba grupas lielumu: `layout(local_size_x = N)` jūsu shader ir kritisks. 32 vai 64 lielums bieži vien ir labs sākumpunkts, jo tas labi atbilst pamatā esošajām aparatūras arhitektūrām, bet vienmēr profilējiet, lai atrastu optimālo lielumu jūsu konkrētajai darba slodzei.
- Uzturiet savu Task Shader liesu: Task Shader ir spēcīgs rīks, bet tas ir arī potenciāls šķērslis. Apcirpšanai un loģikai, ko veicat šeit, jābūt pēc iespējas efektīvākai. Izvairieties no lēniem, sarežģītiem aprēķiniem, ja tos var iepriekš aprēķināt.
- Optimizējiet Meshlet izmēru: Ir no aparatūras atkarīgs piemērots skaits virsotņu un primitīvu vienā meshlet. Rūpīgi jāizvēlas deklarētie `max_vertices` un `max_primitives`. Pārāk mazs, un darba grupu palaišanas izmaksas dominē. Pārāk liels, un jūs zaudējat paralēlismu un kešatmiņas efektivitāti.
- Datu saskaņotība ir svarīga: Veicot apcirpšanu Task Shader, sakārtojiet savus ierobežojošos tilpumu datus atmiņā, lai veicinātu saskaņotus piekļuves modeļus. Tas palīdz GPU kešatmiņām efektīvi darboties.
- Ziniet, kad no tiem izvairīties: Mesh shaders nav burvju lode. Lai renderētu nelielu skaitu vienkāršu objektu, mesh pipeline izmaksas var būt lēnākas nekā tradicionālā vertex pipeline. Izmantojiet tos tur, kur spīd to stiprās puses: milzīgs objektu skaits, sarežģīta procedūru ģenerēšana un GPU vadītas darba slodzes.
Secinājums: Reāllaika grafikas nākotne tīmeklī ir tagad
Mesh Shader pipeline ar Task Amplification ir viens no nozīmīgākajiem reāllaika grafikas sasniegumiem pēdējā desmitgadē. Pārvietojot paradigmu no stingra, CPU pārvaldīta procesa uz elastīgu, GPU vadītu, tas sagrauj iepriekšējos šķēršļus ģeometriskai sarežģītībai un skata mērogam.
Šī tehnoloģija, kas ir saskaņota ar modernu grafikas API, piemēram, Vulkan, DirectX 12 Ultimate un Metal virzienu, vairs nav jāaprobežojas ar augstas klases vietējām lietojumprogrammām. Tās ierašanās WebGL paver durvis jaunai tīmekļa pieredzes ērai, kas ir detalizētāka, dinamiskāka un ieskaujošāka nekā jebkad agrāk. Izstrādātājiem, kas vēlas pieņemt šo jauno modeli, radošās iespējas ir praktiski neierobežotas. Spēja ģenerēt veselas pasaules lidojumā pirmo reizi ir burtiski jūsu rokai rokas stiepiena attālumā tieši tīmekļa pārlūkprogrammā.