Search Unity

Graphics blitting

Discussion in 'Scripting' started by Jagwire, May 21, 2015.

  1. Jagwire

    Jagwire

    Joined:
    Dec 5, 2013
    Posts:
    59
    I'm trying to do some computation on the GPU.

    I was suggested to use http://docs.unity3d.com/ScriptReference/Graphics.Blit.html which takes a Texture and a RenderTexture, with the Texture data being put into the _MainTexture uniform within the Material's shader...outputting the data into the RenderTexture.

    How do I then pass the RenderTexture into a second blit call as input?

    thanks!
     
  2. krougeau

    krougeau

    Joined:
    Jul 1, 2012
    Posts:
    456
    I assume I'm misunderstanding something... The code from the example accepts the first texture (aTexture) as the source and the render texture (rTex) as the destination:

    Code (CSharp):
    1.     void Update() {
    2.         Graphics.Blit(aTexture, rTex);
    3.     }
    You're wanting to create yet another blit with the render texture as the source? And, what, a second render texture as another destination? If that is actually what you're trying to do, then I suppose you could do something like this:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class ExampleClass : MonoBehaviour {
    5.     public Texture aTexture;
    6.     public RenderTexture rTex;
    7.     public RenderTexture rTex2;
    8.     void Start() {
    9.         if (!aTexture || !rTex)
    10.             Debug.LogError("A texture or a render texture are missing, assign them.");
    11.      
    12.     }
    13.     void Update() {
    14.         Graphics.Blit(aTexture, rTex);
    15.         Graphics.Blit(rTex, rTex2);
    16.     }
    17. }
    Granted, I haven't tested this, and you'll likely have some issues because a Texture and a RenderTexture aren't the same animals in Unity's eyes... But then again, I'm really not clear on what you're trying to achieve either, so more information to that end would help immensely.
     
  3. Jagwire

    Jagwire

    Joined:
    Dec 5, 2013
    Posts:
    59
    Thank you for the response!

    I have a water simulation that I'd like to translate to the GPU, and I'm tripping all over the place trying to figure out how to do so. I don't believe I'm able to use compute shaders, because we're not targeting windows platforms for our solution and as per the documentation, compute shaders require DirectX.

    My next thought is maybe I could use a single shader program with multiple passes. This would only work if there is a way to communicate outputs from each pass to the next pass. I speculate I would need a total of 3 passes. So in essence

    if A is the output of pass1, I would I want to pass A as input to pass2 to get B as output, and then pass that as input to pass3. I have yet to find an example of someone doing this in Unity to learn from.

    That said, I was suggested that Graphics.Blit() could be a good approach. Does any of this make sense?
     
    krougeau likes this.
  4. krougeau

    krougeau

    Joined:
    Jul 1, 2012
    Posts:
    456
    Yeah, it makes sense, however it's a bit outside of my wheelhouse. I'm also about brain-dead from a 36 hour programming sprint, haha :p If no one else steps up to help, I'll be happy to assist with some general trial and error later. May as well learn something new, right? :)
     
  5. krougeau

    krougeau

    Joined:
    Jul 1, 2012
    Posts:
    456
    I haven't had anywhere near as much free time as I'd hoped, but I did make a quick pass at testing the following code, and it seems to function without errors. That said, I don't know the specifics of the setup you're using, so your mileage may vary. Feel free to provide example code or even a demo scene for me to toy with, and I'll be happy to assist however I can. In the meantime, give this a shot and see where you get...

    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class BlitTest : MonoBehaviour {
    7.  
    8.     public Texture aTexture;
    9.     public RenderTexture rTex;
    10.     public RenderTexture rTex2;
    11.     private Renderer rend;
    12.  
    13.     void Start()
    14.     {
    15.         rend = GetComponent<Renderer>();
    16.         if (!aTexture || !rTex || !rTex2)
    17.         {
    18.             Debug.LogError("A texture or a render texture are missing, assign them.");
    19.         }      
    20.     }
    21.  
    22.     void Update()
    23.     {
    24.         Graphics.Blit(aTexture, rTex);
    25.         Graphics.Blit(rTex, rTex2);
    26.         rend.material.mainTexture = rTex2;
    27.     }
    28. }
    In my scene, I have the above script set on a Plane with a new material I named Test. Render textures 1 & 2 are each applied to a second and third camera in the scene. Again, this may not help you at all...
     
    Jagwire likes this.
  6. Jagwire

    Jagwire

    Joined:
    Dec 5, 2013
    Posts:
    59
    Validation that a RenderTexture can be used as the first parameter to Graphics.Blit() is definitely forward progress. The next step would be using RenderTextures that are not attached to cameras. Thanks again for the rapid prototype!
     
    krougeau likes this.
  7. krougeau

    krougeau

    Joined:
    Jul 1, 2012
    Posts:
    456
    You're most certainly welcome. I only wish I were able to be of more assistance. Best of luck & have fun!
     
    Jagwire likes this.