Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Chroma Key in Unity 5

Discussion in 'Community Learning & Teaching' started by BabilinApps, Oct 4, 2015.

  1. BabilinApps

    BabilinApps

    Joined:
    Dec 28, 2014
    Posts:
    40


    Download the code here: http://babilinapps.com/wp-content/uploads/2015/10/Shader.zip
    or check the bottom for the full script.

    Chroma Key in unity 3d. I’m surprised to see so many chroma key shaders on the unity asset store. The chroma key shader isn’t anything revolutionary, and there are plenty of resources online to use when creating your shader. Most notably, : http://pilcrowpipe.blogspot.jp/2013/03/chroma-keying-transparent-background.html . This is going to be the first written tutorial that I did so please don’t judge too harshly. The Unity Shader code can be found on : https://unexpectedend.wordpress.com/2014/11/04/unity3d-chroma-key-shader/ but I wanted to describe the translation between Open GL shaders to Unity. The screen grabs below are from the Open Gl Shader in the first linked blog. This shader also works in Unity 5 . There are some assets offer Chroma Key for Unity 5 but this one is probably the simplest and it's free.

    Code (CSharp):
    1. static const char videoPlaybackFragmentShader[] =
    2. "#extension GL_OES_EGL_image_external : require \n"
    3. "precision mediump float; \n"
    4. "uniform samplerExternalOES texSamplerOES; \n"
    5. " varying vec2 texCoord;\n"
    6. " varying vec2 texdim0;\n"
    7. " void main()\n\n"
    8. " {\n"
    9. " vec3 keying_color = vec3(%f, %f, %f);\n"
    10. " float thresh = 0.8; // [0, 1.732]\n"
    11. " float slope = 0.2; // [0, 1]\n"
    12. " vec3 input_color = texture2D(texSamplerOES, texCoord).rgb;\n"
    13. " float d = abs(length(abs(keying_color.rgb - input_color.rgb)));\n"
    14. " float edge0 = thresh * (1.0 - slope);\n"
    15. " float alpha = smoothstep(edge0, thresh, d);\n"
    16. " gl_FragColor = vec4(input_color, alpha);\n"
    17. }";
    *Update from the author

    Code (CSharp):
    1. static const char* videoPlaybackVertexShader =
    2. "attribute vec4 vertexPosition; \n"
    3. "attribute vec4 vertexNormal; \n"
    4. "attribute vec2 vertexTexCoord; \n"
    5. "varying vec2 texCoord; \n"
    6. "varying vec4 normal; \n"
    7. "uniform mat4 modelViewProjectionMatrix; \n"
    8. "void main() \n"
    9. "{ \n"
    10. " gl_Position = modelViewProjectionMatrix * vertexPosition; \n"
    11. " normal = vertexNormal; \n"
    12. " texCoord = vertexTexCoord; \n"
    13. "} \n";
    So now lets take the time to translate this code into Unity’s shader language.

    First lets get a better understanding shader code.

    Start off by writing shader and then a path with a name.


    Shader "Custom/ChromaKey" {

    This allows are shader to exist. The path name is where the shader will appear.

    Next we have to give our shader some properties. The properties are just translated from the Open GL code to Unities shader code:

    Open GL:
    Code (CSharp):
    1.  
    2.  
    3. vec3 keying_color = vec3(%f, %f, %f);\n"
    4. " float thresh = 0.8; // [0, 1.732]\n"
    5. " float slope = 0.2; // [0, 1]\n"
    6.  
    7. Unity:
    8.  
    9.  
    10. Properties {
    11.  
    12. _MainTex ("Base (RGB)", 2D) = "white" {}
    13. _thresh ("Threshold", Range (0, 16))
    14. _slope ("Slope", Range (0, 1))
    15. _keyingColor ("Key Colour", Color) = (1,1,1,1)
    16. }
    We also included a MainText so that we could pass the original image into the texture. Now we start with the SubShader. This is where all the code is going to go. The tags are the rendering type of the material. These Properties are written in strings so you will have to use the double quotation. The tags that we are going to use in this demonstration are exactly the same as in the Unlit Transparent texture .


    Code (CSharp):
    1. SubShader {
    2.  
    3. Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    We are going to use CG for this shader because it is the most common shader language , There are other languages such as GLSL and Open GL. So you have to declare that it is a CG shader program. What you need to do for CG programing is that you tell the graphics card that this is a shader program but you have to follow it up by writing ENDCG.

    A Pragma is telling unity that we are using a shader type in our shader. In this case we are going to try to create a low GPU shader so we will specify the following pragmas.

    Lastly we are going to tell the shader that we want to use the variables that we specified earlier . And we have to define their type.

    A float is a float and a float3 has 3 perimeters and a float 4 has 4 float perimeters.


    Code (CSharp):
    1. Lighting Off
    2. ZWrite Off
    3. AlphaTest Off
    4. Blend SrcAlpha OneMinusSrcAlpha
    5.  
    6. Pass {
    7. CGPROGRAM
    8. #pragma vertex vert_img
    9. #pragma fragment frag
    10. #pragma fragmentoption ARB_precision_hint_fastest
    11.  
    12. sampler2D _MainTex;
    13. float3 _keyingColor;
    14. float _thresh;
    15. float _slope;
    Next we want to say that we are going to include unities native functions and predefined shader variables. This is achieved by writing #include “UnityCG.cginc"

    Then we are going to do the same functions as the open Gl shader did.

    Original

    Code (CSharp):
    1.  
    2. float d =[URL='http://unity3d.com/support/documentation/ScriptReference/30_search.html?q=length']length[/URL](_keyingColor.rgb- input_color.rgb);"
    3. " float edge0 = thresh * (1.0 - slope);"
    4. " float alpha = smoothstep(edge0, thresh, d);"
    5. " gl_FragColor = vec4(input_color, alpha);"
    Unity


    Code (CSharp):
    1. #include "UnityCG.cginc"
    2.  
    3. float4 frag(v2f_img i) : COLOR{
    4. float3 input_color = tex2D(_MainTex,i.uv).rgb * _Color;
    5. float d = abs(length(abs(_keyingColor.rgb - input_color.rgb)));
    6. float edge0 = _thresh*(1 - _slope);
    7. float alpha = smoothstep(edge0,_thresh,d);
    8. return float4(input_color,alpha);

    Here is the complete code :

    Code (CSharp):
    1.  
    2. Shader"Custom/ChromaKey" {
    3.  
    4. Properties {
    5. _MainTex ("Base (RGB)", 2D) = "white" {}
    6. _thresh ("Threshold", Range (0, 16)) = 0.65
    7. _slope ("Slope", Range (0, 1)) = 0.63
    8. _keyingColor ("KeyColour", Color) = (1,1,1,1)
    9. }
    10.  
    11. SubShader {
    12. Tags {"Queue"="Transparent""IgnoreProjector"="True""RenderType"="Transparent"}
    13. LOD100
    14.  
    15. LightingOff
    16. ZWriteOff
    17. AlphaTestOff
    18. BlendSrcAlphaOneMinusSrcAlpha
    19.  
    20. Pass {
    21. CGPROGRAM
    22. #pragmavertexvert_img
    23. #pragmafragmentfrag
    24. #pragmafragmentoptionARB_precision_hint_fastest
    25.  
    26. sampler2D_MainTex;
    27. float3_keyingColor;
    28. float_thresh; //0.8
    29. float_slope; //0.2
    30.  
    31. #include "UnityCG.cginc"
    32.  
    33. float4frag(v2f_imgi) : COLOR{
    34. float3input_color = tex2D(_MainTex,i.uv).rgb;
    35. floatd = abs(length(abs(_keyingColor.rgb - input_color.rgb)));
    36. floatedge0 = _thresh*(1 - _slope);
    37. floatalpha = smoothstep(edge0,_thresh,d);
    38. returnfloat4(input_color,alpha);
    39.  
    40.  
    41. }
    42.  
    43. ENDCG
    44. }
    45. }
    46.  
    47. FallBack"Unlit/Texture"
    48. }
    49.  
    This is the most simple Chroma Key Unity 5 shader and it's free !

    As seen on: http://babilinapps.com/2015/06/chroma-key-unity-5/
     
    Last edited: Oct 13, 2015
    Rodolinc, Jochem, Iday and 5 others like this.
  2. Adam-Buckner

    Adam-Buckner

    Joined:
    Jun 27, 2007
    Posts:
    5,670
  3. BabilinApps

    BabilinApps

    Joined:
    Dec 28, 2014
    Posts:
    40
  4. jhocking

    jhocking

    Joined:
    Nov 21, 2009
    Posts:
    777
    thanks for explaining this!
     
  5. BabilinApps

    BabilinApps

    Joined:
    Dec 28, 2014
    Posts:
    40
    If you like it, make sure to give it a like please. :D
     
  6. NGC6543

    NGC6543

    Joined:
    Jun 3, 2015
    Posts:
    213
    Thank you for your work!!! works like a magic!!
     
  7. jtrim1

    jtrim1

    Joined:
    Sep 27, 2014
    Posts:
    11
    Hi! I know this is drudging this up from the past a bit, but I'm attempting to use this chroma key shader, and it works to replace the key color just like I wanted, but it seems that the "Tiling" and "Offset" values don't work. The input boxes are there to set the tiling and offset options, but they don't change anything about the video. I am needing to use these as I am trying to chroma key out a side by side 3d video.

    Is there a quick way to fix this on this particular shader?

    Thank you!
     
  8. Rodolinc

    Rodolinc

    Joined:
    Sep 23, 2013
    Posts:
    63
    After correcting some formatting issues (dunno if it was because of the browser or the post) it worked perfectly! thanks!
     
  9. Simon_says

    Simon_says

    Joined:
    Oct 19, 2013
    Posts:
    141
    How to make it work with sprite texture instead of usual material texture?
     
  10. ssuresh1295

    ssuresh1295

    Joined:
    Jul 13, 2017
    Posts:
    20
    This code not working for me added this shader file and added to the video player. but it's not getting transparent what is the mistake I don't know my video background color is RGB = 0, 100, 0. please tell me how to do thanks.
     
  11. freedom667

    freedom667

    Joined:
    Sep 6, 2015
    Posts:
    393
    is this working on white color? I have a draw tool and it drawing only white color, so ı have to remove the white color from background and it will work only other colors
     
  12. BradleyHean1

    BradleyHean1

    Joined:
    Apr 27, 2015
    Posts:
    3
    Cant get this to work with the VideoPlayer. can you please explain a bit about the setup? I have a quad which is using the shader with the specific green color set and I have a VideoPlayer on the quad that is set to "override material". The video has a guy dancing with green behind them, but it just will not remove the green, in fact it overlays green over the whole video.
     
unityunity