Search Unity

ECS/Job system way of doing Texture2D.SetPixel()?

Discussion in 'Entity Component System' started by MD_Reptile, Dec 10, 2018.

  1. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Hello, I have been checking out the samples for ECS and the Job system, and they are pretty cool and seem very powerful - but I had been scratching my head about some basic stuff, and haven't got a strong enough understanding of the new features to really figure it out.

    Forgive me if I just haven't dug deep enough yet to "get it" about how everything works now.

    With Mono scripts I could just have a reference to a Texture2D then call Texture2D.SetPixel() or Texture2D.SetPixels() followed with Texture2D.Apply() to make changes to a texture at runtime - but of course that was also pretty slow, and in the past I had much better performance using a compute shader to do heavy texture manipulation rather than using the Texture2D class at all, and perhaps now with ECS and Jobs it would make more sense to instead do something completely different than either of those things.

    Anybody have any idea about how to do an "ECS way" of texture changes? An example of a use case might be a game like "Worms" - to give you an idea what I'd be trying to do.
     
  2. Spy-Shifty

    Spy-Shifty

    Joined:
    May 5, 2011
    Posts:
    546
    You can get the Colordata as a NativeArray and process that in a job.

    Here is an example:
    Code (CSharp):
    1.  
    2.   struct HoloPanelData {
    3.         [ReadOnly] public SharedComponentDataArray<HoloPanel> holoPanel;
    4.         public readonly int Length;
    5.         public bool Any => Length > 0;
    6.     }
    7.  
    8. struct ResetHoloJob : IJobParallelFor {
    9.         [WriteOnly] public NativeArray<Color32> Texture;
    10.         public Color32 Color;
    11.  
    12.         public void Execute(int index) {
    13.             Texture[index] = Color;
    14.         }
    15.     }
    16.  
    17.  
    18.     [Inject] HoloPanelData holoPanelData;
    19. protected override JobHandle OnUpdate(JobHandle inputDeps) {
    20.         if (!holoPanelData.Any) {
    21.             return inputDeps;
    22.         }
    23.  
    24.         NativeArray<Color32> texture = holoPanelData.holoPanel[0].BaseTexture.GetRawTextureData<Color32>();
    25.         Color defaultColor = holoPanelData.holoPanel[0].Default;
    26.  
    27.         var resetHoloJob = new ResetHoloJob {
    28.             Texture = texture,
    29.             Color = defaultColor,
    30.         };
    31.         inputDeps = resetHoloJob.Schedule(texture.Length, 64, inputDeps);
    32.  
    33.         inputDeps.Complete();
    34.         holoPanelData.holoPanel[0].BaseTexture.Apply();
    35.         return inputDeps; // job.Schedule(this, inputDeps);
    36.     }
     
    Aratow and MD_Reptile like this.
  3. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    OK cool, I'm going to give that a try and see if I can figure it out! Thanks for the info.

    @Spy-Shifty one more thing, could I ask where that example came from? Was that out of an example project (where I could see the rest of the code that worked with that) or was that something else?
     
  4. Spy-Shifty

    Spy-Shifty

    Joined:
    May 5, 2011
    Posts:
    546
    It's from one of my projects.

    I've deleted some specific code...
     
  5. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Ah ok, fair enough.
     
  6. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    So something occured to me while testing this idea - once you have edited the NativeArray then your left using the SetPixels() method and Apply() to actually write that data back to a texture?

    Wouldn't that mean your basically still stuck crossing that GPU <> CPU bridge which is where the performance dies doing it "the old way"? If you are indeed stuck with that to push changes - that means that using a compute shader would still outrun this technique by some magnitude...

    @Spy-Shifty is that something you found a way around?
     
  7. Spy-Shifty

    Spy-Shifty

    Joined:
    May 5, 2011
    Posts:
    546
    Yep that is correct and no there is no other way around. So basically a shader would be better....
     
    MD_Reptile likes this.
  8. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Alrighty, thanks for all the help!
     
    Spy-Shifty likes this.