1. We've introduced thread tags, search within a thread and similar thread search. Read more here.
    Dismiss Notice
  2. Learn how you'll soon be able to publish your games to China in four simple steps with Xiaomi. Sign up now for early access.
    Dismiss Notice
  3. Get further faster with the Unity Plus Accelerator Pack, free for new Unity Plus subscribers for a limited time. Click here for more details.
    Dismiss Notice
  4. We've released our first Timeline Experimental Preview, our new tool for creating cutscenes and more! To check it out click here.
    Dismiss Notice
  5. Unity 5.5 is now released.
    Dismiss Notice
  6. Check out all the fixes for 5.5 in patch releases 1 & 2.
    Dismiss Notice
  7. Unity 5.6 beta is now available for download.
    Dismiss Notice

@ chroma key shader with any colours

Discussion in 'Shaders' started by PSpiroz, Mar 17, 2017.

  1. PSpiroz

    PSpiroz

    Joined:
    Feb 15, 2015
    Posts:
    12
    Two things into one:
    1) Can there be a chroma key shader that I choose what solid colour (even under restrictions) will turn to transparent by entering key code values from inspector? Example not green but also custom pink, yellow, etc.
    2) Can there be a chroma key shader that can "key" two different colours to transparent? example. Green and Blue?
    3) Can there be a shader that combines two two above (example picture)?



    Please anyone have a shader script of any, or instructions will help because I don;t understand how to write shader code.
    Thanx.
     

    Attached Files:

  2. goal2112

    goal2112

    Joined:
    May 8, 2013
    Posts:
    4
    1) Yes. You can set chroma keying to be done for any color. I've personally used even a full texture for keying rather than a particular color. If your camera is fixed you can have it take a picture of the set without your subject, and then use each pixel of that as your key.

    2) If you wanna key out 2 particular colors per pixel then the cost grows, but yes, it's doable.

    3) I think your example kind of asks more for what I described in 1, unless your camera has to move. Either way, yes.


    The way to perform keying accurately is to convert each RGB color space pixel into "Lab" color space values, and then find the "distance" between the values. You can find more specifics here: http://www.brucelindbloom.com/index.html?Equations.html

    The steps you'd need to run through are as follows:
    1. Convert your destination color (key color) to XYZ, and then to Lab.
    2. Do the same with your source color (texture you want parts of keyed out).
    3. Use Delta E (CIE 1994) to calculate the overall difference in the color to determine how transparent the pixel should be. Lower values approaching 0 should be more transparent, higher values more opaque. There are other Delta E that improve on accuracy at the cost of performance. It's up to you to choose which one you can afford to use.
    4. Return your source color with the newly calculated alpha.

    Done! :)
     
    PSpiroz likes this.
  3. PSpiroz

    PSpiroz

    Joined:
    Feb 15, 2015
    Posts:
    12
    Thank you very much.
    Very interesting what your (Goal2112) replying. These are concepts I have never though I should take under consideration.
    Still I don't get it, and moreover, I don't get how to apply the above in unity.
    I also found this tool: http://colormine.org/delta-e-calculator/cie94
    Never-mind. I think I'll get it as soon as I manage to understand all the previous steps and the mechanism behind it.


    In a more simple version that I don't really understand what I did and need further assistance, I have modified this standard shader chroma key script for green screen:
    Code (CSharp):
    1. Shader "Custom/ChromaKey" {
    2. Properties {
    3.   _MainTex ("Base (RGB)", 2D) = "white" {}
    4.   _AlphaValue ("Alpha Value", Range(0.0,1.0)) = 1.0
    5. }
    6. SubShader {
    7.   Tags { "Queue"="Transparent" "RenderType"="Transparent" }
    8.   LOD 200
    9.  
    10.   CGPROGRAM
    11.   #pragma surface surf Lambert alpha
    12.   sampler2D _MainTex;
    13.   float _AlphaValue;
    14.   struct Input {
    15.    float2 uv_MainTex;
    16.   };
    17.   void surf (Input IN, inout SurfaceOutput o) {
    18.    half4 c = tex2D (_MainTex, IN.uv_MainTex);
    19.    o.Emission = c.rgb;
    20.  
    21.    // Green screen level - leaves minor green glow
    22.    if (c.g >= 0.67f && c.r <= 0.65f && c.b <= 0.65f && _AlphaValue == 0.0)
    23.          {
    24.           o.Alpha = 0.0;
    25.          }
    26.          else
    27.          {
    28.           o.Alpha = c.a;
    29.          }
    30.   }
    31.   ENDCG
    32. }
    33. FallBack "Diffuse"
    34. }
    by changing the "if" statement to:

    Code (CSharp):
    1. if ((c.g <= 0.65f && c.r >= 0.67f && c.b <= 0.65f && _AlphaValue == 0.0)|| (c.g >= 0.67f && c.r <= 0.65f && c.b <= 0.65f && _AlphaValue == 0.0))
    that made unity to set alpha == 0 for green and red colour.
    I can assume that c.g / c.r / c.b stands for rgb green / red / blue values in a range of [0,1] instead of [0,255].

    My question are
    1) How to set / calculate these equations lets say for pink colour.
    2) What is the memory cost? Is it just almost the same with the original script or it is double the cost?
    3) The author of the original script refers that his equation "..leaves a minor green glow" . How can we control / omit this glow, as well as other colour attributes?