[SOLVED] Immediate drawing GL.[command] isn't working up until 1 update frame in, normal behavior?

I’m trying to set up some custom light data, in the start() function, before the game start. I capture a cubemap then transfer it’s content 256 times using immediate drawing commands to an atlas.

Problem: The immediate fonction don’t seem to work in start() nor in the first frame, if I artificially hold one frame, then it start rendering to the atlas. However, the cubemap camera DO render, which mean the GPU is not on hold…
Tested in unity 2017.1.1f1 and 2019.3.0b4

Is this a normal behavior?

I have attached a scene that show the issue:

  • The relevant part is in MagicSetup.cs
  • The relevant fonctions are renderProbe() and updatingAtlas()

A. When renderprobe() fire in Start() nothing happen for the atlas texture, but the cubemap is rendered
B. When renderprobe() fire in Upate() the cubemap and atlas are rendered
C. When I constrain the frame with

int f=0;
    void Update(){
        if (f==1)
        {
            renderProbe();
        }
        ++f;
    }

For f = 0 (first frame not complete) the atlas do not render (cubemap is rendered)
For f < 0 (first frame has been complete) The atlas is rendered and so is the cubemap.

  • You can inspect the cubemap in MAGIC/render texture/SceneCaptureCube
  • You can inspect the atlas in MAGIC/ custom render texture/IndirectionProbeAtlas
void renderProbe(){
        GameObject probe;
        UVCapture.enabled = true;

        for (int i = 0; i<ProbeArray.Length;i++){
            //render at position on grid
            probe = ProbeArray[i];
            Capture.transform.position = probe.transform.position;
            Capture.transform.rotation = Quaternion.identity;
            UVCapture.RenderToCubemap(SceneCapture);
            //update zone
            updating[0] = zones[i];
            IndirectionProbeAtlas.SetUpdateZones(updating);
       
            //float size = IndirectionProbeAtlas.width / updating[0].updateZoneSize.x;
            float size = updating[0].updateZoneSize.x;
            Vector2 position = updating[0].updateZoneCenter;
       
            //IndirectionProbeAtlas.Update();
            updatingAtlas(size, position);
            //Graphics.Blit(null,IndirectionProbeAtlas, atlasTransfer,-1);
        }
        UVCapture.enabled = false;
    }
    //don't work at start for some reason
    void updatingAtlas(float size, Vector2 offset){
        //could probably do teh UV selection in shader
        //at each point
        //hash the offset using the size
        //if offset ! of input uniform, add 0
        //else add transfered color using remap UV
   
        offset        = new Vector2 (offset.x - (size/2),offset.y - (size/2));
        Vector2 s    = new Vector2 (size + offset.x,size + offset.y);
   
        offset    /=IndirectionProbeAtlas.width;
        s        /=IndirectionProbeAtlas.width;
   
        Graphics.SetRenderTarget(IndirectionProbeAtlas);
   
        GL.PushMatrix();
        GL.LoadOrtho();
        atlasTransfer.SetPass(0);

        GL.Begin(GL.TRIANGLE_STRIP);
   
         //0,0
        GL.TexCoord(new Vector3(0f,                0f,            0f));
        GL.Vertex3(                offset.x,        offset.y,    1f);
   
         //0,1
        GL.TexCoord(new Vector3(0f,                1f,            0f));
        GL.Vertex3(                offset.x,        s.y,        1f);
   
         //1,0
        GL.TexCoord(new Vector3(1f,                0f,            0f));
        GL.Vertex3(                s.x,            offset.y,    1f);
   
         //1,1
        GL.TexCoord(new Vector3(1f,                1f,            0f));
        GL.Vertex3(                s.x,            s.y,        1f);
   
        GL.End();
        GL.PopMatrix();

    }

5148467–509819–MAGICwip.unitypackage (35.3 KB)

Which platform, which graphics api?

I figure it out after many days, right after posting this thread …

Custom Render Texture probably initialize after one update() cycle, If I replace by a plain render texture it work as expected. They aren’t alike.

For completion (and ticking the alert) It’s on editor, windows, no specific API, on GT 705.

I started by trying to use the functionality of custom render texture, BUT the manual say update only happen after rendering lifecycle of the engine. I had to reimplement that fonction using immediate mode (also because I can’t manually update zones one after another in the same frame), but then as I posted this very thread, I realized under the hood it must have a different path than a typical render texture (taking hints from that manual quote) so I switch to that and it worked.

I guess you can only confirm, or precise, that deduction, unless it’s another happy accident.

Checked the code, any changes to custom render textures happen in PostLateUpdate. So you’re correct, that’s after Update() :slight_smile:

1 Like