Search Unity

Problem with Graphic.Blit() and Cubemaps

Discussion in 'General Graphics' started by kapuxino, Jul 14, 2017.

  1. kapuxino

    kapuxino

    Joined:
    Jul 14, 2017
    Posts:
    3
    Hi all,

    I've been stuck with this one for the las few days. :( I hope someone with more experience than me can help me with this one.

    I'm trying to modify/write a cubemap texture in realtime. I'm trying to avoid SetPixels() + Apply(), so I'm working with Blit and a custom shader.

    I'm calling Graphics.Blit() on an Update() loop to update a cube map render texture using a material with a custom shader that would do some image processing stuff and then update the cubemap. I'll be using that cubemap texture on multiple places afterwards.

    I expect the shader to be able to write the whole cube map texture (all sides), but it appears as only one of the sides/faces is being drawn (face +X).

    Here is the simplified example I'm using to debug. Right now the shader only writes red pixels (it's meant for more complex stuff, this is just for debugging). You can see how only one of the faces is painted red, while the others have garbage.

    Maybe Blit is not supposed to be used with cube maps? Maybe there is a problem with the shader?

    Thanks a lot for anyone willing to help me out. :)


    Code (CSharp):
    1. void Update () {
    2.  
    3.     mat.SetTeture("_videoFrameTex", frameTexture);
    4.     Graphics.Blit(null, cubeRenderTexture, mat);
    5.  
    6. }
    Code (CSharp):
    1. Shader "Custom/CubemapDebugger" {
    2. Properties {
    3.     _videoFrameTex ("_videoFrameTex", 2D) = "white" {}
    4. }
    5.  
    6. SubShader {
    7.  
    8.     Cull Back ZWrite Off
    9.  
    10.     Pass {
    11.         CGPROGRAM
    12.         #pragma vertex vert
    13.         #pragma fragment frag
    14.         #pragma target 2.0
    15.         #include "UnityCG.cginc"
    16.  
    17.         sampler2D _VideoFrameTex;
    18.  
    19.  
    20.         struct v2f {
    21.                half4 pos : SV_Position;
    22.                half3 uv : TEXCOORD0;
    23.         };
    24.  
    25.         v2f vert (appdata_img v) {
    26.                 v2f o;
    27.                 o.pos = UnityObjectToClipPos(v.vertex);
    28.                 o.uv = v.vertex.xyz * half3(-1,1,1);
    29.                 return o;
    30.         }
    31.  
    32.         fixed4 frag (v2f IN) : SV_Target {
    33.                     return float4(1,0,0,1);
    34.         }
    35.         ENDCG
    36.     }
    37. }  
    38. Fallback Off
    39. }

    (I'm using a sphere with a skybox material to visualise it, that's why it looks weird, but as you can see, the face +X is red while the other ones are garbage)
     
  2. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    Yes, try Camera.RenderToCubemap. And then use layers to limit what is rendered.
     
  3. kapuxino

    kapuxino

    Joined:
    Jul 14, 2017
    Posts:
    3
    As fas as I know, RenderToCubemap() renders the current scene to a cubemap. That's not exactly what I'm trying to achieve. I'm trying to write to the cubemap texture from a shader.

    I'm thinking about using multiple Graphics.Blit(), one for each cubemap face. But I'm not sure about the performance of a Blit per face vs. the SetPixels() + Apply() method.

    Other option is to write something in GL, but I'm not familiar with it.

    Do you guys hace any suggestion?
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
  5. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Same issue here... I can't Blit into a Cubemap, even while using SetRenderTarget (which is supposed to be able to take a CubemapFace parameter). It always write on the same face of the cubemap.

    CopyTexture doesn't work too.

    ConvertTexture spits "called with a RenderTexture as destination, please use Blit"

    This is dumb! How do you write to a cubemap at runtime?!?
     
    Last edited: Mar 2, 2018
  6. Shadowmage45

    Shadowmage45

    Joined:
    Apr 28, 2016
    Posts:
    6
    Was wondering if you ever manged to get this resolved? I've been banging my head against the exact same problem for ages now...
     
  7. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Managed to make it work:
    Code (CSharp):
    1. Graphics.CopyTexture(source, 0, 0, cubemap, face, 0);
    From what I figured out, it really is that both the source and cubemap only works with some specific texture settings:

    Code (CSharp):
    1. cubemap = new RenderTexture(resolution, resolution, 16, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
    2. cubemap.dimension = TextureDimension.Cube;
    3. cubemap.useMipMap = true;
    4. cubemap.autoGenerateMips = false;
    5. cubemap.Create();
    Code (CSharp):
    1. RenderTexture render = new RenderTexture(resolution, resolution, 16, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
    2. render.useMipMap = false;
    3. render.Create();
    Now... Other settings might work. But also noticed that a LOT of settings make it fail.
     
    Shadowmage45 likes this.