Dela via


Hologramstabilisering – MRTK2

Prestanda

För att den underliggande plattformen och enheten för mixad verklighet ska kunna ge bästa resultat är det viktigt att uppnå prestanda för bildfrekvenser. Målramhastigheten (t.ex. 60 FPS eller 90 FPS) varierar mellan plattformar och enheter. Mötesramhastigheten för program med mixad verklighet kommer dock att ha stabila hologram samt effektiv huvudspårning, handspårning med mera.

Miljöspårning

Stabil holografisk återgivning är starkt beroende av huvudpositionsspårning av plattformen och enheten. Unity renderar scenen varje bildruta från kameraställningen som uppskattas och tillhandahålls av den underliggande plattformen. Om den här spårningen inte följer den faktiska huvudförflyttningen korrekt visas hologram som visuellt felaktiga. Detta är särskilt tydligt och viktigt för AR-enheter som HoloLens där användare kan relatera virtuella hologram till den verkliga världen. Prestanda är betydande för tillförlitlig huvudspårning, men det kan också finnas andra viktiga funktioner. Vilka typer av miljöelement som påverkar användarupplevelsen beror på målplattformens specifika egenskaper.

Windows Mixed Reality

Windows Mixed Reality-plattformen innehåller ett visst referensmaterial för att stabilisera hologram på plattformen. Det finns dock en handfull viktiga verktyg som utvecklare kan använda för att förbättra den visuella hologramupplevelsen för användare.

Delning av djupbuffert

Unity-utvecklare har möjlighet att dela programmets djupbuffert med plattformen. Detta ger information, där hologram finns för en aktuell ram, som plattformen kan använda för att stabilisera hologram via en maskinvaruassisterad process som kallas Late-Stage Reprojection.

Omprojektion i sen fas

I slutet av återgivningen av en ram tar Windows Mixed Reality-plattformen mål för färg- och djupåtergivning som skapats av programmet och omvandlar slutskärmens utdata för att ta hänsyn till eventuella små huvudrörelser sedan den senaste förutsägelsen av huvudställningen. Ett programs spelslinga tar tid att köra. Vid 60 FPS innebär det till exempel att programmet tar ~16,667 ms för att återge en ram. Även om detta kan verka som en minimal tid, kommer användarens position och orientering av huvudet att ändras vilket resulterar i nya projektion matriser för kameran i rendering. Omprojektion i sen fas transformerar bildpunkterna i den slutliga bilden för att ta hänsyn till det nya perspektivet.

LSR per pixel jämfört med stabiliseringsplan

Beroende på vilken enhetsslutpunkt och os-version som körs på en Windows Mixed Reality-enhet utförs algoritmen för reprojection i sen fas antingen per pixel eller via ett stabiliseringsplan.

Djupbaserad per bildpunkt

Per pixel djupbaserad reprojection innebär att använda djupbufferten för att ändra bildens utdata per pixel och därmed stabilisera hologram på olika avstånd. Till exempel kan en sfär 1m bort vara framför en pelare som är 10m bort. Bildpunkterna som representerar sfären har en annan transformering än de bortre bildpunkterna som representerar pelaren om användaren har lutat huvudet något. Reprojection per pixel tar hänsyn till den här avståndsskillnaden vid varje pixel för mer exakt reprojection.

Stabiliseringsplan

Om det inte går att skapa en korrekt djupbuffert att dela med plattformen använder en annan form av LSR ett stabiliseringsplan. Alla hologram i en scen får viss stabilisering, men hologram som ligger i det önskade planet får maximal maskinvarustabilisering. Punkten och det normala för planet kan levereras till plattformen via Api:et HolographicSettings.SetFocusPointForFrame som tillhandahålls av Unity.

Djupbuffertformat

Om du riktar in dig på HoloLens för utveckling rekommenderar vi starkt att du använder 16-bitars djupbuffertformatet jämfört med 24-bitars. Detta kan spara enormt på prestanda även om djupvärden har mindre precision. För att kompensera för den lägre precisionen och undvika z-fighting rekommenderar vi att du minskar det avlägsna klippplanet från standardvärdet på 1 000 meter som angetts av Unity.

Kommentar

Om du använder 16-bitars djupformat fungerar inte de nödvändiga effekterna av stencilbufferten eftersom Unity inte skapar en stencilbuffert i den här inställningen. Om du väljer 24-bitars djupformat omvänt skapas vanligtvis en 8-bitars stencilbuffert, om tillämpligt på slutpunktsgrafikplattformen.

Djupbuffertdelning i Unity

För att kunna använda djupbaserad LSR finns det två viktiga steg som utvecklare måste vidta.

  1. Under Redigera>projektinställningar>aktiverar Player>XR Settings>Virtual Reality SDK:er> djupbuffertdelning
    1. Om du riktar in dig på HoloLens rekommenderar vi att du även väljer 16-bitars djupformat .
  2. När du återger färg på skärmen återger du även djup

Ogenomskinliga GameObjects i Unity skriver vanligtvis till djupet automatiskt. Transparenta och textobjekt skrivs dock vanligtvis inte på djupet som standard. Om du använder MRTK Standard Shader eller Text Mesh Pro kan detta enkelt åtgärdas.

Kommentar

För att snabbt avgöra vilka objekt i en scen som inte skriver till djupbufferten visuellt kan man använda verktyget Rendera djupbuffert under Redigeringsinställningarna i MRTK-konfigurationsprofilen.

Transparent MRTK Standard-skuggning

För transparent material som använder MRTK Standard-skuggning väljer du det material som ska visas i fönstret Kontroll . Klicka sedan på knappen Åtgärda nu för att konvertera materialet för att skriva till djupet (d.v.s. Z-Write On).

Före

Djupbuffert före korrigering av MRTK Standard Shader

Efter

Djupbuffert fast MRTK Standard Shader

Text Mesh Pro

För Text Mesh Pro-objekt väljer du TMP GameObject för att visa det i inspektören. Under materialkomponenten byter du skuggning för det tilldelade materialet för att använda MRTK TextMeshPro-skuggningen.

Korrigering av djupbuffert för Text Mesh Pro

Anpassad skuggning

Om du skriver en anpassad skuggning lägger du till ZWrite-flaggan överst i definitionen för passblock för att konfigurera skuggningen att skriva till djupbufferten.

Shader "Custom/MyShader"
{
    SubShader
    {
        Pass
        {
            ...
            ZWrite On
            ...
        }
    }
}
Ogenomskinliga stöd

Om ovanstående metoder inte fungerar för ett visst scenario (dvs. med unity-användargränssnittet) kan ett annat objekt skrivas till djupbufferten. Ett vanligt exempel är att använda Unity UI Text på en flytande panel i en scen. Genom att göra panelen ogenomskinlig eller åtminstone skriva på djupet, kommer både texten och panelen att stabiliseras av plattformen eftersom deras z-värden är så nära varandra.

WorldAnchors (HoloLens)

Förutom att säkerställa att rätt konfigurationer uppfylls för att säkerställa visuell stabilitet är det viktigt att se till att hologram förblir stabila på rätt fysiska platser. För att informera plattformen om viktiga platser i ett fysiskt utrymme kan utvecklare använda WorldAnchors på GameObjects som behöver stanna på ett ställe. En WorldAnchor är en komponent som läggs till i ett GameObject som tar absolut kontroll över objektets transformering.

Enheter som HoloLens genomsöker och lär sig hela tiden om miljön. Eftersom HoloLens spårar rörelse och position i rymden uppdateras dess uppskattningar och Unity-koordinatsystemet justeras. Om till exempel en GameObject placeras 1 m från kameran från början, när HoloLens spårar miljön, kan den inse att den fysiska punkten där GameObject ligger faktiskt är 1,1 m bort. Detta skulle leda till att hologrammet driver. Om du tillämpar en WorldAnchor på en GameObject kan fästpunkten styra objektets transformering så att objektet förblir på rätt fysisk plats (d.v.s. uppdatera till 1,1 m bort i stället för 1 m vid körning). För att bevara WorldAnchors mellan appsessioner kan utvecklare använda WorldAnchorStore för att spara och läsa in WorldAnchors.

Kommentar

När en WorldAnchor-komponent har lagts till i en GameObject går det inte att ändra gameobjects transformering (dvs transform.position = x). En utvecklare måste ta bort WorldAnchor för att kunna redigera transformeringen.

WorldAnchor m_anchor;

public void AddAnchor()
{
    this.m_anchor = this.gameObject.AddComponent<WorldAnchor>();
}

public void RemoveAnchor()
{
    DestroyImmediate(m_anchor);
}

Om du vill ha ett alternativ till att arbeta manuellt med Anchors kan du läsa Microsoft World Locking Tools.

Se även