Search Unity

Warping gameview using matrix and Graphics.blit

Discussion in 'Shaders' started by MGijs, Feb 11, 2016.

  1. MGijs

    MGijs

    Joined:
    Oct 29, 2015
    Posts:
    10
    Hello,

    I have a question about Graphics.Blit and if it is even possible to achieve what im trying to do here.
    Im trying to render out my game on a belt by projecting this game on a belt which is 3m x 1m,

    Currently I have a shader which wraps my game view nicely using a matrix4x4. All of this is working properly and as intended. (Picture 0,0 to 1,1) this will result into a scaled render on the belt (1m x 1m).

    Im using Graphics.Blit to achieve this effect and if im understanding it correctly it is warping the source (render of gameview) from 0,0 - 1,1 using the matrix to position it at the correct part of the projection.

    Code (CSharp):
    1.   void OnRenderImage(RenderTexture source, RenderTexture destination)
    2.     {
    3.         Graphics.Blit(source, destination, mat);
    4.     }
    What iam trying to achieve here is that it renders the whole belt (3m x 1m) by grabbing a "wider" view of the camera and use it to map it correctly onto the belt. The shader should get as input a 3m x 1m "game view".



    Am I on the right track or won't I be able to get this result using a matrix and Graphics.blit?

    Thanks,
     
  2. Teravisor

    Teravisor

    Joined:
    Dec 29, 2014
    Posts:
    654
    To be precise, it doesn't use matrix. It just renders texture onto quad (0,0)-(1,1) using material and renders result into RenderTexture output. You need to make it use matrix on your own by making uniform matrix4x4 in shader and setting it in code before you Blit.

    Just apply scaling matrix to vertexes in vertex shader. It should work. Don't forget to set matrix using mat.SetMatrix call.
     
  3. MGijs

    MGijs

    Joined:
    Oct 29, 2015
    Posts:
    10
    Yes but the problem with that is that if i create a matrix of that size and blit the rendertexture onto it it is all streched and i want to maintain the correct size of all objects
     
  4. Teravisor

    Teravisor

    Joined:
    Dec 29, 2014
    Posts:
    654
    From my guess either you are trying to render texture to different sized one (like 256x256 into 768x256) or you are trying to make texture "tile" inside it 3 times by compressing it over X axis. In both cases you should scale texture down(not up) 3 times(so scaling matrix will have 1/3rd as X scaling) and then Blit it onto target (up to 3 times, depending on source).
    If resulting texture is same size (256->256) then you will get 3 textures will be streched by Y axis. So by itself it won't look good(and it needs not to) because then the real object being rendered should be wider 3 times in order to compensate - that the only use I see for that trick.

    If you are trying to just draw tiled texture on one mesh, there's much simpler way: just set UVs to larger than 1. For example, UV set to draw from (0,0) to (10,10) will make texture tile 10 times by X and 10 times by Y on object you're drawing.
     
    MGijs likes this.
  5. MGijs

    MGijs

    Joined:
    Oct 29, 2015
    Posts:
    10
    Thanks for your help Teravisor, I got it working now by making the objects "wider". It feels a bit clumsy this way but atleast it is working. Do you know any tricks to turn the rest of the screen black (except the newly rendered texture in the matrix). Should I add an extra pass to me shader?
     
  6. Teravisor

    Teravisor

    Joined:
    Dec 29, 2014
    Posts:
    654
    Why not just set clear color of camera to black? Or if you need that in Blit call together with creating that texture, then something like
    Code (CSharp):
    1.  Pass {
    2.             Color (0, 0, 0, 1)
    3.         }
    4.  
    in shader before rendering texture.