c # - Er der en billig måde at overføre farve data fra en RenderTarget2D på per frame basis?

Indlæg af Hanne Mølgaard Plasc

Problem



Indtil for nylig har vores spil kontrolleret kollisioner ved at få farvedataene fra en del af baggrundsstrukturens tekstur. Dette fungerede meget godt, men da designet blev ændret, havde vi brug for at kontrollere mod flere teksturer, og det blev besluttet at gøre disse alle til en enkelt RenderTarget2D og kontrollere kollisioner herom.


public bool TouchingBlackPixel(GameObject p)
    {
        /*
        Calculate rectangle under the player...
        SourceX,SourceY: Position of top left corner of rectangle
        SizeX,SizeY: Aproximated (cast to int from float) size of box
        */

        Rectangle sourceRectangle = new Rectangle(sourceX, sourceY,
                                                   (int)sizeX, (int)sizeY);

        Color[] retrievedColor = new Color[(int)(sizeX * sizeY)];

        p.tileCurrentlyOn.collisionLayer.GetData(0, sourceRectangle, retrievedColor,
                                                     0, retrievedColor.Count());

        /*
        Check collisions
        */
    }


Problemet, som vi har haft, er, at vi, siden vi flyttede til render-målet, oplever massive reduktioner i FPS.


Fra det vi har læst, ser det ud som om problemet er at for at få data fra RenderTarget2D, skal du overføre data fra GPU'en til CPU'en, og at dette er langsom. Dette forværres af os, der skal køre samme funktion to gange (en gang for hver spiller) og ikke at kunne holde de samme data (de kan ikke være på samme flise).


Vi har forsøgt at flytte GetData-opkald til flisens tegnefunktion og lagre dataene i et medlemskort, men det ser ikke ud til at have løst problemet (da vi stadig kalder GetData på en flise ret regelmæssigt - ned fra to gange hver opdatering til en gang hver træk).


Enhver hjælp, som du kunne give os, ville være fantastisk, da den kraft, som dette kollisionssystem giver os, er ganske fantastisk, men det overhead, som giver mål, har introduceret, gør det umuligt at beholde.

Bedste reference


Det enkle svar er: Gør det ikke .


Det lyder som at aflæse sammensætningen af ​​dine kollisionsdata til GPU'en var en præstationsoptimering, der ikke fungerede - så det rette handlingsforløb ville være at vende om forandringen.


Du skal blot gøre din kollisionskontrol alt på CPU'en. Og jeg vil endvidere foreslå, at det nok er hurtigere at køre din kollisionsalgoritme flere gange og bestemme et kollisionsrespons ved at kombinere resultaterne i stedet for at sammensætte hele scenen på et enkelt lag og køre kollisionsdetektion en gang.


Dette er især tilfældet, hvis du bruger render-målet til at understøtte transformationer, inden du kolliderer.


(For simpel 2D pixel kollisionsdetektering, se denne prøve. Hvis du har brug for support til transformationer, se også denne prøve.) [2] [3]

Andre referencer 1


Jeg antager, at flisens kollisionslag ikke ændres eller i det mindste ændrer sig ikke så ofte, så du kan gemme farverne for hver flise i en matrix eller anden struktur. Dette ville reducere mængden af ​​data, der overføres fra GPU'en til CPU, men kræver, at de ekstra data, der er gemt i RAM'et, ikke er for store.