Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

How can I render into a cubemap face?

Discussion in 'General Graphics' started by guodongrong, Jan 23, 2020.

  1. guodongrong

    guodongrong

    Joined:
    Dec 4, 2019
    Posts:
    13
    I have a RenderTexture whose dimension is TextureDimension.Cube. I can use Camera.RenderToCubemap to render into all six faces of this cube map, or render into specific faces with the help of face mask.

    However, the problem is, that internal implementation always use WORLD +z as "Front". What I want is to use CAMERA +z as "Front". So, I can only render Front/Left/Right faces in each frame.

    To be able to achieve this, I want to create three cameras, and call Camera.Render for each camera, and let each camera render into a specific face of my cube map. However, it seems I cannot set a specific face of my cube map as the render target for each of my three cameras:
    * If I use "camera.targetTexture = xxx", I cannot specify the face of the cube map;
    * If I use "camera.SetTargetBuffers", I cannot get color buffer and depth buffer of a specific face of the cube map;
    * There is another function "Graphics.SetRenderTarget" which allows me to specify the face of the cube map, but it seems having no effect on the render target of my three cameras.

    So, in summary, how can I use "Camera.Render" to directly render into a specific face of a cube map RenderTexture?

    Some related questions:
    * What are the differences between "Graphics.SetRenderTarget" and "Camera.SetTargetBuffers"?
    * I see RenderTexture has properties like "colorBuffer" and "depthBuffer". If a RenderTexture is a cube map (i.e. dimension = TextureDimension.Cube), what will these buffers be? Will they be the buffers of the Front surface? Is so, how can I get the buffers of other faces?
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,243
    The difference between Graphics.SetRenderTarget and Camera.SetTargetBuffers is the later sets what a camera renders to when it renders normally or manually via cam.Render() and Graphics.SetRenderTarget sets the currently active render target used by things like Graphics.DrawMeshNow or GL immediate rendering calls.

    So to directly answer your question of:
    You can't. It's not that it's impossible to do what you want, just Unity doesn't support that setup.

    However you can work around this by rendering to a temporary 2D render texture of the same dimensions and format of the cubemap face, and then use Graphics.CopyTexture() to copy the results into the cubemap.
    https://docs.unity3d.com/ScriptReference/Graphics.CopyTexture.html

    Note, CopyTexture is a direct GPU side memory copy and is very, very fast. It is not a "blit". So while not as fast as directly rendering to the face, it's not significantly slower.
     
  3. guodongrong

    guodongrong

    Joined:
    Dec 4, 2019
    Posts:
    13
    Thanks bgolus for your suggestion!

    I found another way to get the cube map oriented with camera (not world) by calling once Camera.RenderToCubemap instead of calling six times of Camera.Render. As Hypertectonic pointed out in the reply of this post, if I use Stereoscopic mode, Camera.RenderToCubemap will generate a cubemap aligned with camera orientation. :)
     
    bgolus likes this.