Search Unity

Render texture to png ARBG32 no opaque pixels

Discussion in 'General Graphics' started by rayfigs, Apr 8, 2015.

  1. rayfigs

    rayfigs

    Joined:
    Feb 8, 2009
    Posts:
    41
    I've been wanting to render the camera view to a png so that I could use the images in my marketing.
    I found http://answers.unity3d.com/questions/37134/is-it-possible-to-save-rendertextures-into-png-fil.html that showed me how to get render textures to png.

    At first it looked like it worked correctly, but upon inspecting I noticed that there were no alphas in the image.

    I went ahead and changed the encoding of the image to include the alpha and got this



    I don't know why the opaque objects are being rendered transparent. I introduced a default sphere and deleted lights in the scene but I keep getting the same treatment. I've tried different texture format combinations and still no luck. I just don't understand well enough what's going on under the hood. I've included the script I'm using below. The script is being run by ab editor script with a button to execute.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class renderPNG : MonoBehaviour {
    5.     public int imgX = 512;
    6.     public int imgY = 512;
    7.     public Camera virtuCamera;
    8.     public string imageName = "myRenderTexture";
    9.  
    10.     public void renderTex()
    11.     {
    12.         // capture the virtuCam and save it as a square PNG.
    13.  
    14.  
    15.        
    16.         //virtuCamera.camera.aspect = 1.0f;
    17.         // recall that the height is now the "actual" size from now on
    18.        
    19.         RenderTexture tempRT = new RenderTexture(imgX,imgY,24, RenderTextureFormat.ARGB32 );
    20.         // the 24 can be 0,16,24, formats like
    21.         // RenderTextureFormat.Default, ARGB32 etc.
    22.        
    23.         virtuCamera.camera.targetTexture = tempRT;
    24.         virtuCamera.camera.Render();
    25.        
    26.         RenderTexture.active = tempRT;
    27.         Texture2D virtualPhoto =
    28.             new Texture2D(imgX,imgY, TextureFormat.ARGB32, false);
    29.         // false, meaning no need for mipmaps
    30.         virtualPhoto.ReadPixels( new Rect(0, 0, imgX,imgY), 0, 0);
    31.        
    32.         RenderTexture.active = null; //can help avoid errors
    33.         virtuCamera.camera.targetTexture = null;
    34.         // consider ... Destroy(tempRT);
    35.        
    36.         byte[] bytes;
    37.         bytes = virtualPhoto.EncodeToPNG();
    38.        
    39.         System.IO.File.WriteAllBytes(
    40.             OurTempSquareImageLocation(), bytes );
    41.         // virtualCam.SetActive(false); ... no great need for this.
    42.         Debug.Log ("Saved image in this location " + OurTempSquareImageLocation());
    43.         // now use the image,
    44.         //UseFileImageAt( OurTempSquareImageLocation() );
    45.     }
    46.    
    47.     private string OurTempSquareImageLocation()
    48.     {
    49.         string r = Application.dataPath +"/"+imageName+".png";
    50.         return r;
    51.     }
    52.  
    53. }
    54.  
    If anyone can kindly direct me to the right information to help me get a transparent background with opaque objects I would be forever grateful! :)

    Many thanks,
    Reinaldo
     

    Attached Files:

  2. rayfigs

    rayfigs

    Joined:
    Feb 8, 2009
    Posts:
    41
    I thought that this might be the correct forum to post this question in. Was I mistaken, should it belong somewhere else?
     
  3. rayfigs

    rayfigs

    Joined:
    Feb 8, 2009
    Posts:
    41
    I found this fantastic script which makes taking screenshots very easily and with transparencies. For some reason I get the same issue. It looks ok in the preview but if you open the image in photoshop it shows that the cube is transparent.

    I've tried on both mac and pc and get the same result.
    There is certainly something that I am overlooking or there is a defect somewhere. Anyone have any ideas?

    Many thanks,
    Reinaldo
     

    Attached Files:

  4. invadererik

    invadererik

    Joined:
    Oct 31, 2010
    Posts:
    148
    You need to make sure of three things:
    1. Your second camera needs to use a clear colour with the alpha value you want in empty spaces.
    2. The objects rendered by your second camera need to use shaders that write appropriate alpha values
    3. The material for your plane needs to support blending so that the alpha values from the render texture are used appropriately as transparency.
    also if you are using unity 4.x , you need pro for render texture output to be correct.
     
    theANMATOR2b likes this.
  5. rayfigs

    rayfigs

    Joined:
    Feb 8, 2009
    Posts:
    41
    Hi invadererik, thank you for your feedback. If you could kindly clarify points 1 and 2 for me, that would help me out greatly.
    1. Your second camera needs to use a clear colour with the alpha value you want in empty spaces.
    When you say second camera, do you mean the camera creating the render texture? I only ask since I'm doing this in the editor for marketing images, so it's not run time.

    2. The objects rendered by your second camera need to use shaders that write appropriate alpha values​

    I dioremember seeing this mentioned somewhere but I don't know how to confirm that the shaders are writing to the correct channels. In this case I would assume that they should only be writing to RGB channels since I want them to be opaque. Hw would I make sure they are? Would default shader on a cube meet these requirements?
     
  6. ANTARES_XXI

    ANTARES_XXI

    Joined:
    Dec 23, 2014
    Posts:
    141
    Can you send the project? I think I can help you.
     
  7. rayfigs

    rayfigs

    Joined:
    Feb 8, 2009
    Posts:
    41
    Oh that would be great if you can!
    Here is a project with the scripts attached.

    I just tried in unity 5 and it seems that I can't reproduce there, so maybe the shaders change or something else all together.
     

    Attached Files:

  8. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Did you set the camera's clear flag to solid color and modify the color's alpha to 0?
     
  9. ANTARES_XXI

    ANTARES_XXI

    Joined:
    Dec 23, 2014
    Posts:
    141
    Okay, I had a look at your project. I suppose you're taking screenshots this way:

    1.png

    So,

    1) Please make sure you always check Transparent Background:

    2.png

    2) Like invadererik and Dantus said, you need to set the main camera color's alpha to 0, because in your project it wasn't 0.

    Well, I've changed the alpha and now it works perfect for me. Please see the project with fix in the attachments.
     

    Attached Files:

  10. invadererik

    invadererik

    Joined:
    Oct 31, 2010
    Posts:
    148
    Try an unlit shader or vertex lit , basically make sure the shader is explicitly writing 1 to the alpha channel.

    Basic Diffuse shader modified to explicitly set the alpha channel to 1 :

    Code (CSharp):
    1. Shader "custom/myDiffuse" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1,1,1,1)
    4.     _MainTex ("Base (RGB)", 2D) = "white" {}
    5. }
    6. SubShader {
    7.     Tags { "RenderType"="Opaque" }
    8.     LOD 200
    9.  
    10. CGPROGRAM
    11. #pragma surface surf Lambert
    12.  
    13. sampler2D _MainTex;
    14. fixed4 _Color;
    15.  
    16. struct Input {
    17.     float2 uv_MainTex;
    18. };
    19.  
    20. void surf (Input IN, inout SurfaceOutput o) {
    21.     fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    22.     o.Albedo = c.rgb;
    23.     o.Alpha = 1;
    24. }
    25. ENDCG
    26. }
    27.  
    28. Fallback "VertexLit"
    29. }
    example screenshot ( back two spheres using default diffuse, while front one is using the above shader)


    you could probably report this behavior as a bug to unity possibly.
     
    Last edited: Apr 11, 2015