倍率色収差の実装

倍率色収差

今回は簡単に出来そうな倍率色収差を実装してみます。 収差とは,レンズを通る光の波長の違いによるズレによる現象のことですが,倍率色収差は画面の周辺部にかけて色がズレていく現象のことだそうです。

http://cweb.canon.jp/eos/special/dlo/factor/index02.html
https://docs.unity3d.com/jp/540/Manual/script-VignettingAndChromaticAberration.html

実装

基本的な実装は,元となるテクスチャに対して幾つかのチャンネルでマスクをかけたものをそれぞれ拡大して加算合成すれば実現できます。

f:id:hikita12312:20171005235956p:plain:w600

#define CHROMATIC_ABERRATION_ARRAY_NUM 5
static const float3 s_aChoromaticAberrationFilter[CHROMATIC_ABERRATION_ARRAY_NUM] =
{
    float3(0.0f, 0.0f, 0.5f),
    float3(0.0f, 0.25f, 0.5f),
    float3(0.0f, 0.5f, 0.0f),
    float3(0.5f, 0.25f, 0.0f),
    float3(0.5f, 0.0f, 0.0f)
};

float4 PS_ChromaticAberration(PPFX_OUT In) : SV_TARGET0
{
    const float2 uv = In.UV.xy;
    float4 outputColor = float4(0.0f, 0.0f, 0.0f, 1.0f);

    float2 screenPos = TexCoordToScreenSpace(uv);
    for (uint i = 0; i < CHROMATIC_ABERRATION_ARRAY_NUM; ++i)
    {
        const float2 tempUV = ScreenSpaceToTexCoord(screenPos * (1.0f - CRHOMATIC_ABERRATION_SCALE * (i + 1) / CHROMATIC_ABERRATION_ARRAY_NUM));
        const float3 mask = s_aChoromaticAberrationFilter[i];
        const float3 srcColor = SampleLod0(g_SrcTexture, g_LinearSampler, tempUV).rgb;
        outputColor.rgb += srcColor * mask;
    }

    return outputColor;
}

以下が実装結果です。

f:id:hikita12312:20171006000516p:plain:w300
倍率色収差無し
f:id:hikita12312:20171006000534p:plain:w300
倍率色収差有り

f:id:hikita12312:20171006000534p:plain:w600

倍率色収差をかけると,画面の端の方ほど,色がズレていることが分かるかと思います。