Andre Ahmed
Andre Ahmed

Reputation: 1889

Green Chrome Key Shader using depth

I have written a shader which converts an RGB Camera Value to HSV and then apply some filtering for green chrome. Current Problem

  1. If the object at foreground (player) has green pixels, it will be cut out.

  2. I have already depth camera, how can I use that property for making a better cut out chrome key ?

    frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv);

                 if (_ShowBackground)
                 {
                     fixed4 col2 = tex2D(_TexReplacer, i.uv);
                     col = col2;
                 }
                 else if (!_ShowOriginal)
                 {
                     fixed4 col2 = tex2D(_TexReplacer, i.uv);
    
                     float maskY = 0.2989 * _GreenColor.r + 0.5866 * _GreenColor.g + 0.1145 * _GreenColor.b;
                     float maskCr = 0.7132 * (_GreenColor.r - maskY);
                     float maskCb = 0.5647 * (_GreenColor.b - maskY);
    
                     float Y = 0.2989 * col.r + 0.5866 * col.g + 0.1145 * col.b;
                     float Cr = 0.7132 * (col.r - Y);
                     float Cb = 0.5647 * (col.b - Y);
    
                     float alpha = smoothstep(_Sensitivity, _Sensitivity + _Smooth, distance(float2(Cr, Cb), float2(maskCr, maskCb)));
    
                     col = (alpha * col) + ((1 - alpha) * col2);
                 }
                 return col;
             }
    

Upvotes: 1

Views: 140

Answers (1)

Thomas
Thomas

Reputation: 1265

Unity's UnityObjectToClipPos(float3 pos) let's you transform a vertex into clip space. This means 0 to 1 on all axes, z axis is the distance from the rendering camera (from near to far clipping plane, I believe).

You can use this distance to simply to only apply your keying to vertices further than a given threshold.

If you do not want to use normalized coordinates you can also convert your vertex to world space using mul(unity_ObjectToWorld, vertex.position) and afterwards to camera space, by multiplying the world position with the camera's world to local matrix (which you have to pass into your shader).

To access the camera's depth texture in shader you can use _CameraDepthTexture (see documentation https://docs.unity3d.com/Manual/SL-CameraDepthTexture.html section Shader variables). You can sample it like any other texture using tex2D(_CameraDepthTexture, i.uv);

Upvotes: 0

Related Questions