Unityで加算合成とかしたい


前提

  • unityでマテリアルとシェーダーの基本的な利用方法はここでは説明しません。
  • シェーダーのソースが利用できる必要があります。
  • この記事は、執筆時点での私の理解に留まり、必ずしも真実ではありません。

目的

  • 既存のシェーダーのブレンドモードを変更したい。
    • 例えば、もやっとした画像をPhotoshopの「覆い焼き(リニア)」みたいに被せて、光ってるみたいに見せたい。

手っ取り早い解決

  • 対象のオブジェクトに割り当てられたマテリアルを確認し、マテリアルが使用しているシェーダーを特定します。
    • 例えば、対象がuGUIのImageでマテリアルが明示されていないなら、Default UI Materialが割り当てられ、UI/Defaultシェーダーが使われています。
  • シェーダーのソースを用意します。
  • ソースのファイル名を変更します。
    • 例えば、UI-Default.shaderUI-Default-Add.shaderに変更します。
  • ソースをプロジェクトに取り込みます。
  • ソースを開いて、冒頭のシェーダー名を変更します。
    • 例えば、以下のように変更します。
UI-Default-Add.shader
Shader "UI/Default"
{

UI-Default-Add.shader
Shader "UI/Add"
{
  • キーワードBlendを探し、後に続くふたつのキーワードを変更します。
    • 例えば、以下のように変更します。
UI-Default-Add.shader
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha /////// 発見
ColorMask [_ColorMask]

UI-Default-Add.shader
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend One One /////// 加算合成
ColorMask [_ColorMask]
  • 新しいマテリアルを作り、書き換えたシェーダーを割り当てます。
  • 対象のオブジェクトに、マテリアルを割り当てます。

以上で、UI-Default.shaderの加算合成版ができました。

Blendの引数と効果

命令 上作用 下作用 効果 意味*
Blend SrcAlpha OneMinusSrcAlpha アルファブレンド 下画像を上画像の透明度を補うように薄くしたものと上画像をその透明度で薄くしたものを合成
Blend OneMinusDstColor Zero 反転 上画像に下画像の補色を乗算
Blend One One 加算 / 覆い焼き(リニア) 下画像に上画像を加算
Blend SrcAlpha One 加算+アルファ / スクリーン 下画像に上画像を透明度で薄くして加算
Blend OneMinusDstColor One スクリーン / 比較(明) 上画像に下画像の補色を乗算した上で下画像を加算
Blend Zero SrcColor 乗算 下画像に上画像を乗算

*私の理解

Blend 《第1引数》 《第2引数》は、「上画像に第1引数を作用させたものと、下画像に第2引数を作用させたものを合成する」というルールを定めるみたいだけど、この「作用」がどういうものかは、フラグメントシェーダーでプログラムされていて、たいていは「乗算」になっているようです。
つまり、多くの場合、Blend = 上画像 × 第1引数 + 下画像 × 第2引数となるものと受け取りました。
例えば、単純な乗算ならBlend = 上画像 × 0 + 下画像 × 上画像、加算なら、Blend = 上画像 × 1 + 下画像 × 1で実現できるわけです。

※私の勝手な解釈ですので、「そうじゃない」とかあれば、是非ご指摘ください。

技術情報

キーワード 意味
Zero (0, 0, 0, 0) 0%
One (1, 1, 1, 1) 100%
SrcColor (Sr/Kr, Sg/Kg, Sb/Kb, Sa/Ka) 新しい色
OneMinusSrcColor (1, 1, 1, 1) - (Sr/Kr, Sg/Kg, Sb/Kb, Sa/Ka) 新しい色の補色
DstColor (Dr/Kr, Dg/Kg, Db/Kb, Da/Ka) 現在の色
OneMinusDstColor (1, 1, 1, 1) - (Dr/Kr, Dg/Kg, Db/Kb, Da/Ka) 現在の色の補色
SrcAlpha (Sa/Ka, Sa/Ka, Sa/Ka, Sa/Ka) 新しいα
OneMinusSrcAlpha (1, 1, 1, 1) - (Sa/Ka, Sa/Ka, Sa/Ka, Sa/Ka) 新しいαの補色
DstAlpha (Da/Ka, Da/Ka, Da/Ka, Da/Ka) 現在のα
OneMinusDstAlpha (1, 1, 1, 1) - (Da/Ka, Da/Ka, Da/Ka, Da/Ka) 現在のαの補色
SrcAlphaSaturate (i, i, i, 1)
{i = Min (Sa / Ka, 1 - Da / Ka)}
「新しいα」と「現在のαの補色」の暗い方を不透明にしたもの
S (r, g, b, a) (0, 0, 0, 0)~(Kr, Kg, Kb, Ka) 新色(絶対値)
D (r, g, b, a) (0, 0, 0, 0)~(Kr, Kg, Kb, Ka) 現色(絶対値)

参考にしたページ

以下のページを参考にさせていただきました。
どうもありがとうございました。