ホーム > お知らせ > コラム

CANDERA開発者コラム
第11回 VBAテクスチャ描画システムを拡張する(2)
~アルファブレンド(前編)~

 

はじめに


前回までの内容で、不透明の描画を高速化する処理を実装しました。これにより、かなり効率的な描画が行えるようになったと思います。
ところで、これまでの実装は、不透明の描画に最適化されたものでした。では、ここに半透明の画像が登場するとどうなるでしょうか?
半透明の画像を正しく描画するためには、そのためのシステムの拡張が必要になってきます。今回は、そのための準備として、前提知識について見ていきたいと思います。

 

半透明な画像を取り扱う


ここでは、まずは、現状の仕組み上で半透明の画像がどのように見えるかを確認した後に、どうすれば意図した結果を得られるかについて考えてみたいと思います。

 

半透明な画像は現状のシステムでどう見えるか

前回までで実装した描画システムに、半透明の画像を描画させてみましょう。図1のような半透明の画像を、図2にような設定で読み込むことになります。

 

図1. 半透明の画像(200x120)
図1. 半透明の画像(200x120)

 

図2. 読み込み設定
図2. 読み込み設定

 

そうすると、図3のような出力が得られます。半透明の画像なのだから、後ろの内容が透けて描画されることを期待していると思いますが、実際はいかがでしょうか?
現状は、後から描画される画像が必ず優先され、それまでの描画内容と合成されることなく、上書きされてしまいます。

 

図3. 現状の仕組みだとこれが限界
図3. 現状の仕組みだとこれが限界

 

どうなることが理想か

では、どうなることが理想なのでしょうか?言葉で表現するとなると、「後ろが透けるいい感じで…」なのですが、少し具体的なところに落とし込むと、「半透明の画像をこれから描画する場合は、それまで描画されている内容を考慮して、色を混ぜ合わせてほしい」ということになります。
では、どう混ぜ合わせるべきなのでしょうか?ここで「アルファブレンド」というキーワードが登場します。
今回のゴールは、アルファブレンドとは大体こういうものだというのを理解するところになります。

 

アルファブレンドとは

アルファブレンドとは、文字通り、アルファチャネルを使ってこれから描画しようとしている色とすでに描画されている色を混ぜ合わせる手法になります。
どのような描画システムであるかによらず、半透明を含んだデータを半透明の状態で描画したい場合は必ず考慮しなければならないものになります。
例えば図4のような描画を考えてみます。

図4. 想定描画シーケンス
図4. 想定描画シーケンス

 

ここでは、フレームバッファに不透明の矩形が描画され、その上に半透明の画像を描画しています。描画順が図形の重なりの順番であると仮定すると、まずは、フレームバッファをクリア、次に不透明の矩形を描画、そこに一部重なるような形で半透明の画像を描画することになります。

この描画において、最初の矩形の描画についてはこれまでの仕組みで対応することはできます。アルファブレンドについて考えなければならないのは、不透明描画が行われたフレームバッファと、半透明の画像を合成するタイミング、つまり、2回目の描画をする時になります。

では、アルファブレンドはどのように行うのでしょうか?アルファ値を使って、これまで描画された内容とこれから描画する内容を混ぜ合わせていくわけですが、その計算方法について見ていきましょう。

 

アルファブレンドの式

アルファ値を使って描画元と描画先の色を混ぜ合わせる方法についてですが、数式を使って考えていきましょう。今回登場する数式には表1の記号を用います。一部の記号は、添え字として利用します。

表1. アルファブレンドの数式で用いる記号

記号 意味
C カラー値
A アルファ値
F 係数
Result 描画結果
Src これから描画しようとしているもの
Dst 描画先

 

それでは上記を前提にアルファブレンドの式を考えていきます。
アルファ値を使って描画元と描画先の色を混ぜ合わせるということは、基準となるアルファ値が必要になります。このため、アルファブレンドは、描画結果のアルファ値を計算するところからスタートします。
計算結果のアルファ値 $A_{Result}$ は、描画元のアルファ値にかかる係数、$F_{ASrc}$ と、描画先のアルファ値にかかる係数、$F_{ADst}$を用いて、
$$ A_{Result} = F_{ASrc} * A_{Src} + F_{ADst} * A_{Dst} \tag{1} $$ と表現できます。つまり、描画元のアルファ値と、描画先のアルファ値に何らかの値を掛け算し、それを足し合わせたものが描画結果のアルファ値ということになります。

次に、色を見ていきましょう。
計算結果の色の値 $C_{Result}$ は、描画元の色の値にかかる係数、$F_{CSrc}$ と、描画先の色の値にかかる係数、$F_{CDst}$ を用いて、
$$ C_{Result} = ( A_{Src} * C_{Src} * F_{CSrc} + A_{Dst} * C_{Dst} * F_{CDst} ) / A_{Result} \tag{2} $$ と表現できます。一見ややこしく見えますが、描画元、描画先のアルファ値が全体のアルファ値においてどの程度占めるかを計算し、その割合で色を混ぜ合わせているというのが分かると思います。

ところで、アルファブレンドの式の基本形は理解できたものの、それぞれの係数はどのようにして決まるのでしょうか?ここに関係してくるのが、次の「ブレンドモード」になります。

 

ブレンドモード

式1と2において、$F_{ASrc}$ 、$F_{ADst}$ 、$F_{CSrc}$ 、$F_{CDst}$ の4つの係数が登場しました。これらを決定するのが、ブレンドモードという考え方です。反対に言うと、これらの値を上手く設定すると、いろいろな描画ができてしまいます。今回は、図4の描画を正しく行う、つまり、不透明な場所に、半透明なものを重ねて背景が透けて見えるような状況を想定としていますので、そのような結果となるブレンドモードを使用します。このブレンドモードは、Source Over( ソースオーバー )と呼ばれるもので、Src over Dstのように表現します。Dstの上にSrcを重ねるていますので、大抵の演算はこの形式になると考えてもよいと思います。その場合、各係数は、 $$ \begin{align} F_{ASrc} &= F_{CSrc} = 1.0 \ F_{ADst} &= F_{CDst} = 1.0 - A_{Src} \end{align} $$ となり、これにより式1は、 $$ A_{Result} = 1.0 * A_{Src} + ( 1.0 - A_{Src} ) * A_{Dst} \tag{3} $$ 式2は、 $$ C_{Result} = ( A_{Src} * C_{Src} * 1.0 + A_{Dst} * C_{Dst} * ( 1.0 - A_{Src} ) ) / A_{Result} \tag{4} $$ のように変形させることができます。

 

おわりに


いかがでしたでしょうか?今回は、半透明の画像を描画するための下準備としてアルファブレンドの考え方をご紹介しました。言葉で説明すると、アルファ値を使用してこれから描画しようとしている色と、既に描画されている色を混ぜ合わせて新しい色を作成するということでした。その計算方法はいくつかあり、式1および2の係数に設定する値次第では様々なブレンドが実装できるものの、今回行いたい合成はSrc over Dstであるため、式3および4の形となるというのが結論となります。これで、半透明の実装はできる…と考えがちですが、アルファブレンドを考える上でもう一つ大事な考え方があります。そちらについては次回にお届けしたいと思います。

 

◆CANDERA(カンデラ)とは?

加賀FEI株式会社では、CGI StudioとUI Conductorという2つの組み込み向けHMIオーサリングツールを開発~販売しており、車載向けメータークラスター、ヘッドアップディスプレイ、ナビゲーション、周辺監視システム、車載以外にもプリンター、デジタルカメラ、建設機械など、多くの機器で広くご採用頂いております。

 

◆バックナンバー

第1回  身の回りにあるHMI
第2回  OpenGL ESを用いた簡単な図形の描画
第3回  OpenGL ESを用いた簡単な図形の描画 実践編(前編)
第4回  OpenGL ESを用いた簡単な図形の描画 実践編(後編)
第5回  OpenVGを用いた簡単な図形の描画
第6回  ソフトウェアレンダリングを実装してみる(設計編)
第7回  ソフトウェアレンダリングを実装してみる(実装編)
第8回  VBAでテクスチャを描画してみる(前編)
第9回  VBAでテクスチャを描画してみる(後編)
第10回  VBAのテクスチャ描画システムを拡張する(1)