Search Unity

Chroma Key in Unity 5

Discussion in 'Shaders' started by BabilinApps, Oct 8, 2015.

  1. BabilinApps

    BabilinApps

    Joined:
    Dec 28, 2014
    Posts:
    40


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

    Code (CSharp):
    Code (CSharp):
    1. static const char* videoPlaybackVertexShader =
    2. "attribute vec4 vertexPosition;"
    3. "attribute vec4 vertexNormal; "
    4. "attribute vec2 vertexTexCoord; "
    5. "varying vec2 texCoord; "
    6. "varying vec4 normal; "
    7. "uniform mat4 modelViewProjectionMatrix; "
    8. "void main() "
    9. "{ "
    10. " gl_Position = modelViewProjectionMatrix * vertexPosition; "
    11. " normal = vertexNormal; "
    12. " texCoord = vertexTexCoord; "
    13. "} ";
    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):
    Code (CSharp):
    1.  
    2.  
    3. vec3 keying_color = vec3(%f, %f, %f);"
    4. " float thresh = 0.8; // [0, 1.732]"
    5. " float slope = 0.2; // [0, 1]"
    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):
    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):
    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):
    Code (CSharp):
    1.  
    2. float d = abs(length(abs(keying_color.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):
    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 =[URL='http://unity3d.com/support/documentation/ScriptReference/30_search.html?q=length']length[/URL](_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):
    Code (CSharp):
    1. Shader "Custom/ChromaKey" {
    2.  
    3. Properties {
    4. _Color ("Main Color", Color) = (1,1,1,1)
    5. _MainTex ("Base (RGB)", 2D) = "white" {}
    6. _thresh ("Threshold", Range (0, 16)) = 0.8
    7. _slope ("Slope", Range (0, 1)) = 0.2
    8. _keyingColor ("Key Colour", Color) = (1,1,1,1)
    9. }
    10.  
    11. SubShader {
    12.  
    13. Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    14. LOD 100
    15.  
    16. Lighting Off
    17. ZWrite Off
    18. AlphaTest Off
    19. Blend SrcAlpha OneMinusSrcAlpha
    20.  
    21. Pass {
    22. CGPROGRAM
    23. #pragma vertex vert_img
    24. #pragma fragment frag
    25. #pragma fragmentoption ARB_precision_hint_fastest
    26. float4 _Color;
    27. sampler2D _MainTex;
    28. float3 _keyingColor;
    29. float _thresh; // 0.8
    30. float _slope; // 0.2
    31.  
    32. #include "UnityCG.cginc"
    33.  
    34. float4 frag(v2f_img i) : COLOR{
    35. float3 input_color = tex2D(_MainTex,i.uv).rgb* _Color.rgb;
    36. float d = (_keyingColor.rgb- input_color.rgb);
    37. float edge0 = _thresh*(1 - _slope);
    38. float alpha = smoothstep(edge0,_thresh,d);
    39. return float4(input_color,alpha);
    40.  
    41. }
    42.  
    43. ENDCG
    44. }
    45.  
    46. }
    47.  
    48. FallBack "Unlit"
    49. }
    This is the most simple Chroma Key Unity 5 shader and it's free !

    As seen on: http://babilinapps.com/2015/06/chro...preview_nonce=b35d2b5b8d&post_format=standard
     
    Last edited: Oct 13, 2015
  2. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    You can change:
    Code (csharp):
    1. float d = abs(length(abs(_keyingColor.rgb - input_color.rgb)));
    Into:
    Code (csharp):
    1. float d = length(_keyingColor.rgb - input_color.rgb);
    It comes down to the same thing.
     
    BabilinApps likes this.
  3. BabilinApps

    BabilinApps

    Joined:
    Dec 28, 2014
    Posts:
    40
    Thank you! Just updated it.
     
  4. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    That update was not 100% successful. Besides that, this might give an implicit vector truncation warning:
    Code (csharp):
    1. float3 input_color = tex2D(_MainTex,i.uv).rgb * _Color;
    Can be removed by changing it to:
    Code (csharp):
    1. float3 input_color = tex2D(_MainTex,i.uv).rgb * _Color.rgb;