Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Render Texture Alpha

Discussion in 'Editor & General Support' started by antenna-tree, Jun 18, 2006.

  1. antenna-tree

    antenna-tree

    Joined:
    Oct 30, 2005
    Posts:
    5,325
    I noticed the Render To Texture automatically builds an alpha channel from the grayscale. Is there a way to turn this off? And is there a way to get a "true" alpha of the rendered scene?

    Another thing I'm curios about is how hard it would be to script/create a grayscale Zbuffer or depthmap image from the rendered scene. This seems like it would be hard, but could be really cool for manipulating image effects down the road.
     
  2. DocSWAB

    DocSWAB

    Joined:
    Aug 28, 2006
    Posts:
    615
    I'm wondering the same thing -- I want the view in the Render to Texture to be 100% opaque and not have any transparency (otherwise, it doesn't really do the whole "arena cam" thing properly).

    Thanks,
    Steve
     
  3. Aras

    Aras

    Graphics Plumber Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,528
    Does it? There's no code in Unity to do that; and in all cases I've seen the alpha of a render texture is whatever is rendered into alpha.
    Right now you could render several camera-facing planes, with depth test on and blending the results. More planes = better accuracy, but slower. Or wait until we add depth texture support to Unity (but that will require hardware that can actually do this of course).
    Render texture alpha contains whatever is rendered into alpha. So if you make sure all your objects render "white" into alpha, then you get white. Alternatively, you could render a full-screen quad with a shader that writes only to alpha channel. Sort of an image effect that doesn't do anything interesting, just sets alpha to white everywhere.

    ...or you don't actually need having 100% opaque alpha in your render texture :) If you're just putting that texture onto some object, just use a shader that does not do alpha blending!
     
  4. DocSWAB

    DocSWAB

    Joined:
    Aug 28, 2006
    Posts:
    615
     
  5. Aras

    Aras

    Graphics Plumber Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,528
    In that case the best is probably to render a fullscreen quad that would write only to alpha, and keep the RGB untouched.
     
  6. Aras

    Aras

    Graphics Plumber Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,528
    In other words, just attach this javascript to your camera. It will set alpha channel to the specified value.
    Code (csharp):
    1. var alpha = 1.0;
    2. private var mat : Material;
    3.  
    4. function Start ()
    5. {
    6.     mat = new Material(
    7.         "Shader \"Hidden/Clear Alpha\" {" +
    8.         "Properties { _Alpha(\"Alpha\", Float)=1.0 } " +
    9.         "SubShader {" +
    10.         "    Pass {" +
    11.         "        ZTest Always Cull Off ZWrite Off" +
    12.         "        ColorMask A" +
    13.         "        SetTexture [_Dummy] {" +
    14.         "            constantColor(0,0,0,[_Alpha]) combine constant }" +
    15.         "    }" +
    16.         "}" +
    17.         "}"
    18.     );
    19. }
    20.  
    21. function OnPostRender()
    22. {
    23.     GL.PushMatrix();
    24.     GL.LoadOrtho();
    25.     mat.SetFloat( "_Alpha", alpha );
    26.     mat.SetPass(0);
    27.     GL.Begin( GL.QUADS );
    28.     GL.Vertex3( 0, 0, 0.1 );
    29.     GL.Vertex3( 1, 0, 0.1 );
    30.     GL.Vertex3( 1, 1, 0.1 );
    31.     GL.Vertex3( 0, 1, 0.1 );
    32.     GL.End();
    33.     GL.PopMatrix();
    34. }
     
  7. freyr

    freyr

    Joined:
    Apr 7, 2005
    Posts:
    1,148
    Another solution is not to use a render texture nor a GUITexture at all. Just render it as a normal, but set the camera viewport rect and layer, so it is rendered into a square above the main camera.
     
  8. DocSWAB

    DocSWAB

    Joined:
    Aug 28, 2006
    Posts:
    615
    Thanks everybody for all this help. I observed the Render Texture camera images being transparent on a GUITexture in the FPS tutorial project. When I tried the same technique with our actual project, for whatever reason, I didn't get the partial alpha.

    I appreciate knowing there's a back-door way to assign a material to a GUITexture, though.

    I had tried the simple viewport thing, but really wanted a fixed pixel size and position for the camera's view, since it's a GUI element and needs to be layered with other GUITextures.

    Cheers,
    Steve
     
  9. Neodrop

    Neodrop

    Joined:
    Oct 24, 2008
    Posts:
    1,358
    A want to render object only in Alpha channel. Can I do this? And how?
     
  10. Aras

    Aras

    Graphics Plumber Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,528
    In the shader, use "ColorMask A". This will make it only render into alpha channel.

    Hey, my shader above (that draws the quad to clear alpha) uses that as well!
     
  11. Neodrop

    Neodrop

    Joined:
    Oct 24, 2008
    Posts:
    1,358
    Aras, look at my problem again, please. I want to render my character for produsing "real" projector shadow.
    I can't change original instantiated materials on my character. How can I render him only in alpha chanel?
    Or may be other trick?
    May be recolor Diffuse to black? But how?
     

    Attached Files:

  12. Aras

    Aras

    Graphics Plumber Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,528
    From what you said, CharacterShadow on the wiki should do exactly what you need.
     
  13. Neodrop

    Neodrop

    Joined:
    Oct 24, 2008
    Posts:
    1,358
    Thanks a lot, Aras!
     
  14. JasonMo

    JasonMo

    Joined:
    Dec 14, 2011
    Posts:
    3
    Hi, I have a camera with a target renderTexture. It works perfectly until I have a transparent/diffuse shader on any objects it sees. They won't show up at all in the renderTexture. The material that displays the camera on a plane is also set to transparent/diffuse, could this be the problem?
     
  15. tgraupmann

    tgraupmann

    Joined:
    Sep 14, 2007
    Posts:
    828
    Thanks for the info. I ended up using a RenderTexture camera with a black background with this custom shader on a plane, to act as though the background of the camera was transparent.

    No need for any scripts attached to the camera. Recap.

    Camera with black background.
    Camera points to render texture.
    Mask texture: white for showing, transparent for hidden.
    Material points to the custom shader.
    Material has _MainTex as the RenderTexture.
    Material has _Mask as the mask
    Plane uses the Material to display the RenderTexture with a mask

    Code (csharp):
    1. Shader "Transparent/RenderTexture" {
    2.     Properties {
    3.         _MainTex ("Black (RGB)", 2D) = "black" {}
    4.     }
    5.  
    6.     SubShader {
    7.         Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    8.  
    9.         Blend SrcAlpha SrcAlpha
    10.         ZWrite off
    11.  
    12.         Pass {  
    13.             CGPROGRAM
    14.                 #pragma vertex vert
    15.                 #pragma fragment frag
    16.            
    17.                 #include "UnityCG.cginc"
    18.  
    19.                 struct appdata_t {
    20.                     float4 vertex : POSITION;
    21.                     float2 texcoord : TEXCOORD0;
    22.                 };
    23.  
    24.                 struct v2f {
    25.                     float4 vertex : POSITION;
    26.                     float2 texcoord : TEXCOORD0;
    27.                 };
    28.  
    29.                 sampler2D _MainTex;
    30.            
    31.                 v2f vert (appdata_t v)
    32.                 {
    33.                     v2f o;
    34.                     o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    35.                     o.texcoord = v.texcoord;
    36.                     return o;
    37.                 }
    38.            
    39.                 half4 frag (v2f i) : COLOR
    40.                 {
    41.                     float4 black = tex2D(_MainTex, i.texcoord);
    42.                     return float4(black.r, black.g, black.b, 1);
    43.                 }
    44.             ENDCG
    45.         }
    46.     }
    47. }
     
    Last edited: Mar 13, 2012
  16. Fordeka

    Fordeka

    Joined:
    Aug 18, 2011
    Posts:
    78
    I may be mistaken but this approach will not work if you have alpha in your textures that is greater than 0 and less than 1. Is there still no way to make the Camera render alpha into a RenderTexture?
     
    Last edited: Sep 16, 2012
  17. 3Nu

    3Nu

    Joined:
    Feb 13, 2011
    Posts:
    18
    And ... it doesn't work for me. Everything shows being very bright.
    Plus, your steps are out of data, since the "_Mask" doesn't exist for this shader :(
     
  18. turdann

    turdann

    Joined:
    Dec 29, 2012
    Posts:
    18
    Hi, I had a similar problem and I used Aras approach.
    I need a texture with a runtime generated RGB (using render to texture) and an Alpha channel with specular information.
    So I make the render to texture and then on post render I draw a quad just in alpha channel using a specular texture.

    It is working in my computer, but it doesn't work in my Android!!
    Any idea about what is happening?
    The result texture is used with a Mobile/BumpedSpecular material, in the computer it works but in the Android device it seems a full white specular.
    I'm pretty sure the problem is in the shader used to render the alpha quad because I've seen that tga textures with alpha are well interpreted by the bumpedSpecular shader also in Android.

    This is the shader that I'm using to render the alpha quad

    Shader "Custom/writeInAlpha" {
    Properties {
    _MainTex ("Texture (RGBA)", 2D) = "white" {}
    }
    SubShader {
    Pass {
    ZTest Always
    Cull Off
    ZWrite Off
    ColorMask A
    SetTexture [_MainTex] {
    constantColor (1,1,1,1)
    combine constant, texture
    }
    }
    }
    FallBack "Diffuse"
    }


    Just in case we can't find how to fix it... do you know a mobile shader similar to Mobile/BumpedSpecular that gets specular from a separated texture?


    Thanks!
     
  19. reallypeople

    reallypeople

    Joined:
    Jul 11, 2013
    Posts:
    21
    Hi,
    I'm having a similar problem in that I had a camera rendering to a texture in my project. The character (an on-screen guide) used to only have a diffuse material and the render texture worked perfectly (i.e. in the alpha channel it was white where the character was, and black where they weren't) which enabled me to overlay it on the GUI. I've since added a specular shader to the character, but that has now changed the alpha of the render texture to show the specular values of the character (so his shiny stuff is opaque, but matt parts are transparent). I tried Aras's 1st script above, but that has made the entire render texture opaque. Is there a way of keeping the specular material on my character, but getting the render texture to be a more traditional alpha channel (i.e. white where there is geometry and black where there isn't)?

    Any help appreciated!
     
  20. reallypeople

    reallypeople

    Joined:
    Jul 11, 2013
    Posts:
    21
    Attached pic of what I'm trying to achieve. specular-alpha.jpg
     
  21. Draco18s

    Draco18s

    Joined:
    Aug 15, 2011
    Posts:
    107
    I have this same problem.

    Because I was rendering a bunch of semi-transparent textures into a render texture, so I could display that on a single plane to place in front of the main camera (making a gui for the oculus rift is not easy, you're told to place it as objects in front of the camera, because no other camera will render on top of the oculus cameras and they won't take gui layers).

    The alpha chanel that is rendered to the texture is the raw alpha value of the object closest to the camera (ignoring all other objects behind it, ignoring what alpha means for that object, e.g. cutout). I was able to fix this by writing a custom shader for the object the rendered texture is applied to. As I had a fixed gui alpha I wanted, I simply took the rendered texture as the base texture and overwrote its alpha channel with a mask texture (I used a duplicate of the original gui texture, but I had to resize it to be square).

    Only oddity appears that if I directly write the mask alpha to the output, I get its RGB as well, but mask.a+0.0001 fixes that.

    In theory you could use a rendered texture as the alpha channel as well (solving reallypeople's problem: render the target twice, once with diffuse shaders, once with specular, combine the two textures as desired; I believe there is a way to replace an object's shader with another shader via code for a specific render pass). Likely not fast, but should work.

    Code (CSharp):
    1. Shader "Unlit/AlphaMask" {
    2.     Properties {
    3.         _MainTex ("Base (RGB)", 2D) = "white" {}
    4.         _Alpha ("Base (RGB)", 2D) = "white" {}
    5.     }
    6.     SubShader {
    7.         Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
    8.         Blend SrcAlpha OneMinusSrcAlpha
    9.         LOD 100
    10.    
    11.         Lighting Off
    12.    
    13.         Pass {
    14.             CGPROGRAM
    15.                 #pragma vertex vert
    16.                 #pragma fragment frag
    17.                
    18.                 #include "UnityCG.cginc"
    19.    
    20.                 struct appdata_t {
    21.                     float4 vertex : POSITION;
    22.                     float2 texcoord : TEXCOORD0;
    23.                 };
    24.    
    25.                 struct v2f {
    26.                     float4 vertex : SV_POSITION;
    27.                     half2 texcoord : TEXCOORD0;
    28.                 };
    29.    
    30.                 sampler2D _MainTex;
    31.                 sampler2D _Alpha;
    32.                 float4 _MainTex_ST;
    33.    
    34.                 v2f vert (appdata_t v)
    35.                 {
    36.                     v2f o;
    37.                     o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    38.                     o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
    39.                     return o;
    40.                 }
    41.                
    42.                 fixed4 frag (v2f i) : COLOR
    43.                 {
    44.                     fixed4 col = tex2D(_MainTex, i.texcoord);
    45.                     fixed4 col2 = tex2D(_Alpha, i.texcoord);
    46.                     col.a = col2.a + 0.0001;
    47.                     return col;
    48.                 }
    49.             ENDCG
    50.         }
    51.     }
    52. }
     
  22. gaiastellar

    gaiastellar

    Joined:
    Nov 8, 2013
    Posts:
    44
    Hi,
    I think this is exactly what I need but can you please put into c# pleeease!! - I have a smoke particle effect that I am trying to capture to a render texture, but the clouds completely white out the render texture. I use anim/alpha blend on the clouds, but on the render texture they completely overload into white.

    Thanks
    Paul uk



     
  23. Precache

    Precache

    Joined:
    Jul 30, 2015
    Posts:
    17
    I ran into this issue after updating to 2018.3, as the post processing stack used to clear the alpha.

    Here's a c# version of the code:
    (just add the script to the camera in question)
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class ClearAlpha : MonoBehaviour
    5. {
    6.     private float alpha = 1.0f;
    7.     private Material mat;
    8.     private Shader shader;
    9.  
    10.     void Start()
    11.     {
    12.         shader = Shader.Find("Hidden/ClearAlpha");
    13.         mat = new Material(shader);
    14.     }
    15.  
    16.     private void OnPostRender()
    17.     {
    18.         GL.PushMatrix();
    19.         GL.LoadOrtho();
    20.         mat.SetFloat("_Alpha", alpha);
    21.         mat.SetPass(0);
    22.         GL.Begin(GL.QUADS);
    23.         GL.Vertex3(0, 0, 0.1f);
    24.         GL.Vertex3(1, 0, 0.1f);
    25.         GL.Vertex3(1, 1, 0.1f);
    26.         GL.Vertex3(0, 1, 0.1f);
    27.         GL.End();
    28.         GL.PopMatrix();
    29.     }
    30. }
    31.  
    And here's the code for the shader:
    Code (Shader):
    1.  
    2. Shader "Hidden/ClearAlpha"
    3. {
    4.     Properties
    5.     {
    6.        _Alpha("Alpha", Float) = 1.0
    7.     }
    8.  
    9.    SubShader
    10.    {
    11.        Pass
    12.        {
    13.            ZTest Always Cull Off ZWrite Off
    14.                ColorMask A
    15.                SetTexture [_Dummy]
    16.                {
    17.                    constantColor(0,0,0,[_Alpha]) combine constant
    18.                }
    19.        }
    20.    }
    21. }
    22.