Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We’re making changes to the Unity Runtime Fee pricing policy that we announced on September 12th. Access our latest thread for more information!
    Dismiss Notice
  3. Dismiss Notice

Bug Ortographic camera screenshot with RenderTexture using URP camera and DOTS fails.

Discussion in 'Graphics for ECS' started by muntes, May 8, 2023.

  1. muntes


    Nov 24, 2021
    When I try to generate an image using camera.Render() on a RenderTexture I get:

    "InvalidOperationException: The previously scheduled job LocalToWorldSystem:ComputeChildLocalToWorldJob writes to the ComponentTypeHandle<Unity.Collections.NativeText.ReadOnly> ComputeChildLocalToWorldJob.JobData.LocalToWorldTypeHandleRW. You are trying to schedule a new job EmitDrawCommandsJob, which reads from the same ComponentTypeHandle<Unity.Collections.NativeText.ReadOnly> (via EmitDrawCommandsJob.LocalToWorld). To guarantee safety, you must include LocalToWorldSystem:ComputeChildLocalToWorldJob as a dependency of the newly scheduled job.
    Unity.Jobs.LowLevel.Unsafe.JobsUtility.ScheduleParallelForDeferArraySize (Unity.Jobs.LowLevel.Unsafe.JobsUtility+JobScheduleParameters& parameters, System.Int32 innerloopBatchCount, System.Void* listData, System.Void* listDataAtomicSafetyHandle) (at <07b4fb2b5af74e479c2c24afaabbcaa4>:0)"

    Considering the fact I call this function from WithStructuralChanges().Run(). What should I add to it?

    PS: The image generation is not in entities context is old mono behavior logic which should work for DOTS and non-dots calls.

    Am I missing something? Does in the background camera.Render() from URP cameras work with DOTS jobs?

    The elements in the camera are only entities.
    URP camera set as orthographic

    protected override void OnUpdate()
    var deltaTime = World.Time.DeltaTime;
    Entities.ForEach((ref Entity entity, ref HolderVersion hv, ref MeshLODGroupComponent mlgc, in WaitingForLOD toGenerateLod) =>
    toGenerateLod.CreationDate = deltaTime + toGenerateLod.CreationDate;
    if (!(toGenerateLod.CreationDate >= _interval)) return; // I want a delay between instantiation and LOD generation.

    var element = LodCreator.GetEntityViaId(hv.Id);
    if (!element.isSome) return;

    element.value.GetComponent<RenderingHolder>().CreateLod1(entity); //This calls RenderToTexture which should add the texture to a mesh quad.


    private static Disposable<RenderTexture> RenderToTexture(Camera camera, int width, int height, Vector3 position, Quaternion rotation)
    var renderTexture = RenderTexture.GetTemporary(width, height, 24, DEFAULT_RENDER_TEXTURE_FORMAT);
    renderTexture.antiAliasing = 1;
    var transform = camera.transform;
    transform.position = position;
    transform.rotation = rotation;
    camera.targetTexture = renderTexture;

    camera.Render(); // THIS IS WHERE THE ISSUE OCCURS

    camera.targetTexture = null;

    string savePath = "Screenshot"; // THIS IS ONLY FOR DEBUG PURPOSES. The texture is blank.
    if (!Directory.Exists(savePath))

    string fileName = $"{System.DateTime.Now:yyyy-MM-dd_HH-mm-ss}{Random.Range(0, 1000000).ToString()}.png";
    string filePath = Path.Combine(savePath, fileName);
    byte[] bytes = renderTexture.ToTexture2D(false).EncodeToPNG();
    File.WriteAllBytes(filePath, bytes);

    return Disposable<RenderTexture>.Borrow(renderTexture, RenderTexture.ReleaseTemporary);

    Thanks for your attention.