Search Unity

Graphics.Blit() not rendering.

Discussion in 'Scripting' started by DaveHoskins, May 5, 2014.

  1. DaveHoskins

    DaveHoskins

    Joined:
    Sep 9, 2013
    Posts:
    190
    Hi, I want to draw a full screen background in my game using a script.
    According to the docs, I can simply call Graphics.Blit() in the Update function, like this:-
    https://docs.unity3d.com/Documentation/ScriptReference/Graphics.Blit.html

    But I can't get anything to show, is this code correct? Does it have to have a camera component as well? Thanks.

    Please note that I want to render the full screen texture BEFORE anything else is rendered, this is not GUI related.
    Can anyone help?

    Cheers,
    Dave
     
  2. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Do you use Unity Pro?
     
  3. DaveHoskins

    DaveHoskins

    Joined:
    Sep 9, 2013
    Posts:
    190
    Yep. Has anyone actually used this method?
     
  4. Trexug

    Trexug

    Joined:
    Dec 2, 2013
    Posts:
    88
    We had some trouble using Graphics.Blit() in the Update loop as well. For our purposes we could switch to OnGUI/OnRenderImage because it wasn't a background. Perhaps OnPreRender will work in your case?
     
  5. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Update() is before rendering starts, so how are your clear flags set on your camera? Perhaps whatever you're blitting is being cleared by the upcoming frame?
     
  6. Trexug

    Trexug

    Joined:
    Dec 2, 2013
    Posts:
    88
    I just realised this was the source of our trouble with Graphics.Blit() so thanks for clearing that up :)
     
  7. DaveHoskins

    DaveHoskins

    Joined:
    Sep 9, 2013
    Posts:
    190
    After spending a few hours with it, I'm amazed it can't be done.

    Graphics.Blit only seems to work when attached to a camera.
    I can't set a sort order for it to render first, because of this.
    Blit always obliterates everything on screen, no matter where you put the call.

    I've tried using the polygon draw out of the image effects stuff with this, but it still didn't work, I suspect that this is correct way of doing this though, I'm just not understanding it correctly I guess.

    Code (csharp):
    1.     void CustomGraphicsBlit(Material fxMaterial)
    2.     {
    3.  
    4.         GL.PushMatrix();
    5.         GL.LoadOrtho();
    6.  
    7.   // Tried this with many z values, it never appears behind the game objects...
    8.         float z = 100.0f;
    9.  
    10.         fxMaterial.SetPass(0);
    11.  
    12.         GL.MultiTexCoord2(0, 0.0f, 1.0f);
    13.         GL.Vertex3(0.0f, 0.0f, z); // BL
    14.  
    15.         GL.MultiTexCoord2(0, 1.0f, 1.0f);
    16.         GL.Vertex3(1.0f, 0.0f, z); // BR
    17.  
    18.         GL.MultiTexCoord2(0, 1.0f, 1.0f);
    19.         GL.Vertex3(1.0f, 1.0f, z); // TR
    20.  
    21.         GL.MultiTexCoord2(0, 0.0f, 1.0f);
    22.         GL.Vertex3(0.0f, 1.0f, z); // TL
    23.    
    24.         GL.End();
    25.  
    26.         GL.PopMatrix();
    27.     }

    I can't believe I'm in this apparently simple, yet impossible to achieve situation!
     
  8. Trexug

    Trexug

    Joined:
    Dec 2, 2013
    Posts:
    88
    You could use two cameras and set the depth to specify which should render first. Then use one camera for rendering your background and the other for rendering the rest of the scene. I'm unsure how efficient it would be, though.
     
  9. DaveHoskins

    DaveHoskins

    Joined:
    Sep 9, 2013
    Posts:
    190
    I only wanted to draw one quad in a 3D background.
    Too much to ask for? :(
     
  10. DaveHoskins

    DaveHoskins

    Joined:
    Sep 9, 2013
    Posts:
    190
    OK I went with sticking a quad as a child of the camera at the Z distance I wanted, and used the camera stuff to calculate how big it needs to be to render it exactly full screen. It seems to rotate perfectly.
    Someone may find it useful, so here it is:-

    In the quad script...

    Code (csharp):
    1.     void Update()
    2.     {
    3.         GameObject obj = GameObject.FindGameObjectWithTag("MainCamera");
    4.         Camera cam = obj.GetComponent<Camera>();
    5.  
    6.         float size = Mathf.Tan(cam.fieldOfView * Mathf.PI / 360.0f) * 2.0f * transform.localPosition.z;
    7.         transform.localScale = new Vector3(size * cam.aspect, size, 1.0f);
    8.     }
    Dave.