LoginSignup
2
3

More than 5 years have passed since last update.

[Unity5.4]Unityでクロマキー合成シェーダーを作成

Posted at

ViveでのVRコンテンツを製作している際にクロマキー合成を行うシェーダーを作成することになったのですがなかなか綺麗に抜ける
クロマキー合成のソースコードが見当たらなかったので自分で関係する記事を探して作成しました。
※Unityのシェーダーはこれが初めてなので至らないとこが多々あると思います…。

↓参考記事
クロマキー合成 + 立体視が可能な Ovrvision SDK v0.6 を試してみた
RGBからHSVへの変換と復元

ソースコード

Chromakey.shader
Shader "Custom/Chromakey" {
        Properties{
            _MainTex("Base ( RGB ) Trans ( A )", 2D) = "white" { }
            _MaxHue("Max Hue", Range(0, 1)) = 1
            _MinHue("Min Hue", Range(0, 1)) = 1
            _MaxSaturation("Max Saturation", Range(0, 1)) = 1
            _MinSaturation("Min Saturation", Range(0, 1)) = 1
            _MaxValue("Max Value", Range(0, 1)) = 1
            _MinValue("Min Value", Range(0, 1)) = 1

        }
        SubShader{
                Tags{ "Queue" = "Overlay+1" "RenderType" = "Overlay" }
                LOD 200
                Pass{
                    Lighting Off
                    ZWrite Off
                    Ztest Always
                    Blend SrcAlpha OneMinusSrcAlpha

                    CGPROGRAM
                    #pragma vertex vert
                    #pragma fragment frag
                    #include "UnityCG.cginc"

                    sampler2D _MainTex;
                    float _MaxHue;
                    float _MinHue;
                    float _MaxSaturation;
                    float _MinSaturation;
                    float _MaxValue;
                    float _MinValue;

                    struct v2f {
                        float4 pos : SV_POSITION;
                        half2 uv : TEXCOORD0;
                        float2 uv_MainTex : TEXCOORD0;
                    };

                    //  RGB値をHSV値に変換
                    float3 RGBtoHSV( float3 rgb) {
                        float hue = 0;
                        float minValue = min(rgb.r, min(rgb.g, rgb.b));
                        float maxValue = max(rgb.r, max(rgb.g, rgb.b));
                        if (minValue == maxValue) {
                            hue = 0;
                        }
                        else if (minValue == rgb.b) {
                            hue = 60 * (rgb.g - rgb.r) / (maxValue - minValue) + 60;
                        }
                        else if (minValue == rgb.r) {
                            hue = 60 * (rgb.b - rgb.g) / (maxValue - minValue) + 180;
                        }
                        else if (minValue == rgb.g) {
                            hue = 60 * (rgb.r - rgb.b) / (maxValue - minValue) + 300;
                        }
                        hue /= 360;
                        float value = maxValue;
                        float saturation = maxValue - minValue;
                        float3 hsv = float3( hue, saturation, value ); 
                        return hsv;
                    }

                    v2f vert( appdata_img v ) {
                        v2f o;
                        o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                        o.uv = v.texcoord;
                        return o;
                    }

                    //  HSV値で判定
                    float4 frag( v2f i ) : COLOR0 {
                        float3 colors = tex2D( _MainTex, i.uv_MainTex ).rgb;
                        float3 hsvcolor = RGBtoHSV(colors);
                        if (hsvcolor.r >= _MinHue && hsvcolor.r <= _MaxHue) {
                            if (hsvcolor.g >= _MinSaturation && hsvcolor.g <= _MaxSaturation) {
                                if (hsvcolor.b >= _MinValue && hsvcolor.b <= _MaxValue) {
                                    discard;
                                }
                            }
                        }

                        return float4(colors, 1.0);
                    }
                    ENDCG
            }
    }
    FallBack "Tranparent/Diffuse"
}

使用感

個人的には綺麗に抜けているとは思いますがちょっと抜けているとろろがジャギってしてしまっているので対象の輪郭を綺麗に抜けるような工夫が必要だなと思っています。
chromakey.PNG
↑試しに黄緑色のグリーンバックを抜いてみた

あと抜く色の指定も少しコツがいるので改善点だと考えています。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3