I am trying to take a screenshot and then place it on a quad. I have it working - sort of. Here’s what I have so far:
var quad = EntityManager.Instantiate(SystemAPI.GetSingleton<Config>().QuadPrefab);
var hybridRenderer = World.GetExistingSystemManaged<EntitiesGraphicsSystem>();
var screenShotMaterial = new Material(Shader.Find("HDRP/Unlit"));
//_squareImage simply makes the 16:9 screenshot square
var squareTexture = _squareImage(UnityEngine.ScreenCapture.CaptureScreenshotAsTexture());
squareTexture.Apply();
screenShotMaterial.mainTexture = squareTexture;
var materialID = hybridRenderer.RegisterMaterial(screenShotMaterial);
var mmi = EntityManager.GetComponentData<MaterialMeshInfo>(quad);
mmi.MaterialID = materialID;
var quadRma = EntityManager.GetSharedComponentManaged<RenderMeshArray>(quad);
var rmaMatList = quadRma.Materials.ToList();
rmaMatList.Add(screenShotMaterial);
var rma = new RenderMeshArray(rmaMatList.ToArray(), quadRma.Meshes);
var rmd = new RenderMeshDescription(UnityEngine.Rendering.ShadowCastingMode.Off, false);
RenderMeshUtility.AddComponents(quad, EntityManager, rmd, rma, mmi);
And even then, I have to run it twice as the first time through it doesn’t work.
So two problems:
why doesn’t ScreenCapture.CaptureScreenshotAsTexture() work without saving a copy to the disk?
Why do I get no result the first time I hit run but then it works the second? (I think this is due to the texture being on the CPU but not the GPU but I thought the Apply() method would copy it over.)
That was probably my issue with it as I can’t do that while in an ECS system.
I have come up with a solution that works though.
I’m no longer using the ScreenCapture function, I set up a second camera and a rendertexture, I’m then copying the texture from the rendertexture into a new material. I got the idea from this post:
So I set up everything according to the what mingwai did in that post and then I used this code to make the copy and place it on the texture
var quad = EntityManager.Instantiate(SystemAPI.GetSingleton<Config>().QuadPrefab);
var hybridRenderer = World.GetExistingSystemManaged<EntitiesGraphicsSystem>();
var mat = new Material(Shader.Find("HDRP/Unlit"));
var texture = new Texture2D(2048, 2048, TextureFormat.RGBA32, 1, false, false);
Graphics.CopyTexture(_material.mainTexture, texture);
mat.mainTexture = texture;
mat.name = "mat";// some unique name
var materialID = hybridRenderer.RegisterMaterial(mat);
var mmi = EntityManager.GetComponentData<MaterialMeshInfo>(quad);
mmi.MaterialID = materialID;
var quadRma = EntityManager.GetSharedComponentManaged<RenderMeshArray>(rawDataEntity); // this is one of my singleton entities that I put a quad on so I could get the RMA from it
var rmaMatList = quadRma.Materials.ToList();
maMatList.Add(mat);
var rma = new RenderMeshArray(rmaMatList.ToArray(), quadRma.Meshes);
var rmd = new RenderMeshDescription(UnityEngine.Rendering.ShadowCastingMode.Off, false);
RenderMeshUtility.AddComponents(quad, EntityManager, rmd, rma, mmi);
enderMeshUtility.AddComponents(rawDataEntity, EntityManager, rmd, rma, mmi);
the _material property is straight from what Mingwai did: