Search Unity

Render to texture forcing aspect ratio change on camera?

Discussion in 'Shaders' started by tz, Nov 4, 2007.

  1. tz

    tz

    Joined:
    Oct 13, 2007
    Posts:
    91
    This is an unexpected behavior for me... I have two cameras in identical spots, one renders to a texture, while the second one renders the scene, and then uses the rendered texture as a full-screen overlay to do some special effects.

    I noticed that the elements in the render to texture camera would move normally at run time on the vertical axis of the framebuffer, but that as I change the viewport aspect ratio of the rendering window, the elements move at a rate of change about equal to the aspect ratio of the horizontal to vertical axis. (i.e. with a square render target and a square viewport, they match up pretty closely... if I then double the viewport width, the elements move about twice as fast across the horizontal axis as they should).

    When I changed the render to texture size, it actually changed the aspect ratio of the resultant image!

    This implies to me that the render to target texture is actually forcing an aspect ratio change on the camera that is writing to it. Please tell me this is overrideable... I know from experience that you often want powers of 2 in your textures, but this certainly shouldn't be affecting the aspect ratio of the camera that is writing to the texture (in actuality, I presume it's just writing each pixel and rendering the appropriate vector from the eye with a 1:1 correlation, but this still destroys the functionality for me in a lot of cases I had hoped to use rendered textures for)

    Thanks!

    Tz
     
  2. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    The trick here is to create your render texture from code - then you can match your screen resolution exactly, rather than having to scale up to the next power-of-two....
     
  3. tz

    tz

    Joined:
    Oct 13, 2007
    Posts:
    91
    Ah, thank you Nicholas, I'll try that.

    Is there ever a time where you want your rendertexture to have a different aspect ratio than the camera you used to shoot it?

    In all the examples of this in the past that I've used, I've never run into a case of this... however, I do often write 1280 x 720 aspect ratio images to targets that are powers of two...

    Curious on this one, because the details seem inverted to me.

    thanks for the tip!

    Tz
     
  4. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    Basically, there are 2 use cases for rendertextures:

    * Image Effects - those you typically do by implementing OnRenderImage (take a look in the Pro Standard Assets for source code). Here you do everything from code.

    * Textures in-game. Think of a video surveillance camera - a camera rendering into a texture, putting that on geometry. Here, the rendertexture screen aspect can be completely different
     
  5. tz

    tz

    Joined:
    Oct 13, 2007
    Posts:
    91
    Ok, so I have my camera creating a rendertexture at start.

    Wierdly, it doesn't work, until I go into the debug parameters for the object that references the rendertexture (and draws it to the screen during the overlay pass), and click on the "_mainTex" field.

    Then it picks up the reference and starts drawing it.

    I'm assuming that I need to connect the object to this texture at start, but the following doesn't seem to take care of it:

    (This script is attached to the fullscreen rect object).


    Code (csharp):
    1. function Start () {
    2.  
    3. var blobtexture : RenderTexture = GameObject.Find("FXCamera").camera.targetTexture;
    4. renderer.material.SetTexture("_MainTex", blobtexture);
    5.  
    6. }
    7.  
    8.  

    I also tried pushing it onto the screenrect from the camera initialization (this script being attached to the FXcamera object):

    Code (csharp):
    1.  
    2. function Start()
    3. {
    4.       renderTexture = RenderTexture(Screen.width / 2, Screen.height / 2, 0);
    5.       renderTexture.isPowerOfTwo = false;
    6.       camera.targetTexture = renderTexture;
    7.       camera.depth = -10; // force draw earlier than main camera
    8.       GameObject.Find("ScreenRect").renderer.material.mainTexture = renderTexture;
    9. }
    I'm doing something wrong... still wrapping my head around how these classes talk to each other.

    Tz
     
  6. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    As a side note, you can override camera's aspect variable if you want something else than the pixel aspect.
     
  7. TWObitEDD

    TWObitEDD

    Joined:
    Sep 13, 2012
    Posts:
    3
    I found that I could set the resolution in my RenderTexture to match the intended aspect ratio of my camera by switching the editor to Debug mode, setting the variables, and then switching back to normal mode.

    Hope this idea helps; and please tell me if you know of future problems which await from this solution.

    Thanks for the thread guys, wouldn't have tried such a thing if I hadn't seen you could get the same results by creating the RenderTexture from code :)

    #DFTBA
    -EDD
     
  8. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    I guess there are some parts of Unity that haven't changed in more than six years.
     
    Freznosis likes this.
  9. Glurth

    Glurth

    Joined:
    Dec 29, 2014
    Posts:
    109
    since it took me a while to figure out what Aras meant, figured I'd spell it out for anyone else who find this. First I set the camera ratio to 1, because my objects were being skewed for non-square RenderTextures. This had no effect. Then I tried the opposite, setting the camera.aspect to the render texture's output aspect ratio, this worked: my objects no longer looked skewed in the output.
    Code (CSharp):
    1.  
    2. snapShot = new RenderTexture((int)size.x, (int)size.y, 16, RenderTextureFormat.ARGB32);
    3. cam.targetTexture = snapShot;
    4. cam.aspect = size.x/size.y;
     
    Albazcythe likes this.
  10. DavidMiranda

    DavidMiranda

    Joined:
    Nov 30, 2012
    Posts:
    617
    YES YES YES
     
  11. Stiffbreeze

    Stiffbreeze

    Joined:
    Apr 7, 2017
    Posts:
    1
    Oh man thank you guys.

    To add light to this, it appears that setting `camera.targetTexture` to a render texture was automatically changing the aspect ratio of the camera under the hood.

    If you need to maintain your aspect ratio for a camera you're dumping to a texture, you can do this:

    Code (CSharp):
    1. float cachedCameraAspect = camera.aspect;
    2. camera.targetTexture = renderTexture;
    3. camera.aspect = cachedCameraAspect;
     
  12. mlongtin

    mlongtin

    Joined:
    Jul 12, 2016
    Posts:
    1
    Thank you, thank you, thank you! This solved my issue. It's one of those undocumented subtleties that ends up costing developers time. You saved me a lot of aggravation.
     
  13. naviln

    naviln

    Joined:
    Oct 18, 2016
    Posts:
    32
    Whoa thanks. I have been struggling with getting my camera to see objects in their shape. Initial tests look promising. Going to play with this some more. Huge thanks!! (I wonder why you can't do this in the Editor?? As in, resize the aspect using the mouse and click/dragging)
     
  14. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    I just used ProBuilder, just set the scale you need when you create the New Shape.... It will be scaled to one in unity, at your custom proportions!
     
  15. ademord

    ademord

    Joined:
    Mar 22, 2021
    Posts:
    49
    omg thank you so much. i had a predefined rendertexture and @NicholasFrancis reply helped me think that maybe i should do it dynamically and also just in case overwrite the aspect ratio of the camera. i wonder if my solution is dirty or not, but idk it works :D
     
  16. K0ST4S

    K0ST4S

    Joined:
    Feb 2, 2017
    Posts:
    35
    How to do opposite? How to force camera to resize to its target texture after assigning texture from code?