ブレンドタイプの提案

17 views
Skip to first unread message

zebla

unread,
Nov 6, 2008, 4:57:22 AM11/6/08
to Star Ruby
どうも、zeblaです。

少し個人的な要望で恐縮なんですけど、あると便利と思った、テクスチャのブレンド方式のアイデアがあるので、提案してみます。


1.ネガポジ反転
2.転送先のアルファ値を保持する
(3.パレットを持つテクスチャの描画において、パレットの先頭ないしは任意のインデクスの色を「抜き色」とし、抜き色に関してはアルファ値0、その他
の色はアルファ値255として下地を考慮せず、ブレンドする側のアルファ値も考慮しないブレンドを行う)
(4.RGB各要素を、同ピクセルのアルファ値に置き換えてブレンドを行う。このときアルファ値255だとするとRGB255となり、ピクセルが透明な
ほど黒く、不透明なほど白くなる)


2.は、 dst.render_texture(src,x,y) とした時に dst の持っていた各点のアルファ値が、src の持つそれに影響
されることなく保持されるという意味です。色調を変更するのと同じような感覚で、画像を合成することができます。

3.に関しては、アルファ値の計算が省ければ、若干描画を高速化できるのではあるまいか? と考えての提案となります。予想なので果たして有用かどう
か、さっぱりわからないのですが。(パレットの要素に、255以下のアルファ値を持つカラーを代入しても、ちゃんと反映されるので、現時点で下地は考慮
するようになってるんだなとは分かりました。この現行の仕様も有用でしょうから、オプションとして提案する次第です)

4.に関しては、思いついてみたものの「これ本当に使えるのか」といった感じで、果たしてライブラリ側で提供する価値が十分にあるのか、よくわからない
です。マスク用画像をリアルタイムに生成するとかを想定しています。「ブレンド時にRGBA各要素を自由に置き換えながらブレンドする」、という風にし
てもいけますが。


以上です。一考いただければ幸いです。

Hajime Hoshi

unread,
Nov 6, 2008, 6:47:11 AM11/6/08
to star...@googlegroups.com
星です。

> 少し個人的な要望で恐縮なんですけど、あると便利と思った、テクスチャのブレンド方式のアイデアがあるので、提案してみます。

ありがとございます。

> 1.ネガポジ反転

実装は簡単ですが、はて必要でしょうか?
(まああってもいいかなとは思いますけど :-)

> 2.転送先のアルファ値を保持する
> (3.パレットを持つテクスチャの描画において、パレットの先頭ないしは任意のインデクスの色を「抜き色」とし、抜き色に関してはアルファ値0、その他
> の色はアルファ値255として下地を考慮せず、ブレンドする側のアルファ値も考慮しないブレンドを行う)
> (4.RGB各要素を、同ピクセルのアルファ値に置き換えてブレンドを行う。このときアルファ値255だとするとRGB255となり、ピクセルが透明な
> ほど黒く、不透明なほど白くなる)

> 2.は、 dst.render_texture(src,x,y) とした時に dst の持っていた各点のアルファ値が、src の持つそれに影響
> されることなく保持されるという意味です。色調を変更するのと同じような感覚で、画像を合成することができます。

実は昔「特定の色成分から特定の色成分へコピーする」という機能を実装しかけたのですが、
ひょっとしたらそれで出来るかも。
(いまでも dump/undump で出来たりします。)

さらに言うと、それをやるなら汎用的なフィルターメソッドがほしくなりますが、
それについては後述。

> 3.に関しては、アルファ値の計算が省ければ、若干描画を高速化できるのではあるまいか? と考えての提案となります。予想なので果たして有用かどう
> か、さっぱりわからないのですが。(パレットの要素に、255以下のアルファ値を持つカラーを代入しても、ちゃんと反映されるので、現時点で下地は考慮
> するようになってるんだなとは分かりました。この現行の仕様も有用でしょうから、オプションとして提案する次第です)

速度はほとんどかわらないと思います。
合成結果の dst の RGB は結局 src と dst の RGBA で計算するからです。
ちなみに今の計算方法の疑似コードは以下の通りです:

if (dst.a == 0) {
dst.r = (1 - src.a / 255) * dst.r + (src.a / 255) * src.r
dst.g = (1 - src.a / 255) * dst.g + (src.a / 255) * src.g
dst.b = (1 - src.a / 255) * dst.b + (src.a / 255) * src.b
dst.a = max(dst.a, src.a) # (1)
} else {
dst = src
}

提案手法では、 (1) がなくなるだけのように思えますが。

> 4.に関しては、思いついてみたものの「これ本当に使えるのか」といった感じで、果たしてライブラリ側で提供する価値が十分にあるのか、よくわからない
> です。マスク用画像をリアルタイムに生成するとかを想定しています。「ブレンド時にRGBA各要素を自由に置き換えながらブレンドする」、という風にし
> てもいけますが。

これも、上で述べた「特定の色成分から特定の色成分へコピー」ですみそうですね。


話は変わるのですが、こういうフィルター的なものは DSL
でかけたらいいなと思っています。

Ruby スクリプトでフィルターを実装する場合、
Color オブジェクトがばんばん生成されるなど
速度的にきついものになります。
(ちなみに色は 32 bit 整数なので 32bit マシンでは Fixnum でも収まりません。)

そこで、フィルターのための独自言語 (DSL) を作り、
それを文字列 (もしくはコンパイル済みのバイト列など) として
与えるというのを考えております。
DirectX や OpenGL のシェーダーのようなものです。

やるとしたら 0.4.x やその先の話になりそうです。
(1.0 には全然たどり着きませんね :)

--
Hajime Hoshi <hajim...@gmail.com>

zebla

unread,
Nov 6, 2008, 10:39:45 AM11/6/08
to Star Ruby
> > 1.ネガポジ反転
>
> 実装は簡単ですが、はて必要でしょうか?
> (まああってもいいかなとは思いますけど :-)

んまあ、「個人的な意見」ですんで。DSLが実装されるなら、今無理に実装しなくてもいいかなとは思います。ただ有効な使い道はそれなりにあるんでない
かと。あくまでも個人的に。

> > 2.転送先のアルファ値を保持する
> > (3.パレットを持つテクスチャの描画において、パレットの先頭ないしは任意のインデクスの色を「抜き色」とし、抜き色に関してはアルファ値0、その他
> > の色はアルファ値255として下地を考慮せず、ブレンドする側のアルファ値も考慮しないブレンドを行う)
> > (4.RGB各要素を、同ピクセルのアルファ値に置き換えてブレンドを行う。このときアルファ値255だとするとRGB255となり、ピクセルが透明な
> > ほど黒く、不透明なほど白くなる)
> > 2.は、 dst.render_texture(src,x,y) とした時に dst の持っていた各点のアルファ値が、src の持つそれに影響
> > されることなく保持されるという意味です。色調を変更するのと同じような感覚で、画像を合成することができます。
>
> 実は昔「特定の色成分から特定の色成分へコピーする」という機能を実装しかけたのですが、
> ひょっとしたらそれで出来るかも。
> (いまでも dump/undump で出来たりします。)
>
> さらに言うと、それをやるなら汎用的なフィルターメソッドがほしくなりますが、
> それについては後述。

「あるテクスチャから任意のテクスチャへ」任意の色成分をコピーできる機能、ということですか。そうすれば、私の案で言うところの dst に当たるも
ののアルファ値を、src に持っていき、その上で dst に対して src をブレンドすれば同等の結果が得られそうだ、という解釈でよろしいので
しょうか。

> > 3.に関しては、アルファ値の計算が省ければ、若干描画を高速化できるのではあるまいか? と考えての提案となります。予想なので果たして有用かどう
> > か、さっぱりわからないのですが。(パレットの要素に、255以下のアルファ値を持つカラーを代入しても、ちゃんと反映されるので、現時点で下地は考慮
> > するようになってるんだなとは分かりました。この現行の仕様も有用でしょうから、オプションとして提案する次第です)
>
> 速度はほとんどかわらないと思います。
> 合成結果の dst の RGB は結局 src と dst の RGBA で計算するからです。
> ちなみに今の計算方法の疑似コードは以下の通りです:
>
> if (dst.a == 0) {
> dst.r = (1 - src.a / 255) * dst.r + (src.a / 255) * src.r
> dst.g = (1 - src.a / 255) * dst.g + (src.a / 255) * src.g
> dst.b = (1 - src.a / 255) * dst.b + (src.a / 255) * src.b
> dst.a = max(dst.a, src.a) # (1)
>
> } else {
> dst = src
> }
>
> 提案手法では、 (1) がなくなるだけのように思えますが。


もしかして、正しくはこうですか?:

if (dst.a == 0) {
dst = src

} else {
dst.r = (1 - src.a / 255) * dst.r + (src.a / 255) * src.r
dst.g = (1 - src.a / 255) * dst.g + (src.a / 255) * src.g
dst.b = (1 - src.a / 255) * dst.b + (src.a / 255) * src.b
dst.a = max(dst.a, src.a) # (1)
}

ふーむ。ブレンドタイプ :non が結構早くなるので、これはと思ったんですが。src をまるっと dst に持っていくわけではないですしね...


> > 4.に関しては、思いついてみたものの「これ本当に使えるのか」といった感じで、果たしてライブラリ側で提供する価値が十分にあるのか、よくわからない
> > です。マスク用画像をリアルタイムに生成するとかを想定しています。「ブレンド時にRGBA各要素を自由に置き換えながらブレンドする」、という風にし
> > てもいけますが。
>
> これも、上で述べた「特定の色成分から特定の色成分へコピー」ですみそうですね。
>
> 話は変わるのですが、こういうフィルター的なものは DSL
> でかけたらいいなと思っています。
>
> Ruby スクリプトでフィルターを実装する場合、
> Color オブジェクトがばんばん生成されるなど
> 速度的にきついものになります。
> (ちなみに色は 32 bit 整数なので 32bit マシンでは Fixnum でも収まりません。)
>
> そこで、フィルターのための独自言語 (DSL) を作り、
> それを文字列 (もしくはコンパイル済みのバイト列など) として
> 与えるというのを考えております。
> DirectX や OpenGL のシェーダーのようなものです。

非常に有用だと思います。マニアックなフィルタが利用できるのはもちろん、ある程度の最適化(こーいう言い回しは果たして適切なのか)にも応用できるか
もしれません。

> やるとしたら 0.4.x やその先の話になりそうです。
> (1.0 には全然たどり着きませんね :)

僕は気長に見守らせていただくとします。たまに勝手な意見を吐いたりしながら←

Hajime Hoshi

unread,
Nov 6, 2008, 11:32:04 AM11/6/08
to star...@googlegroups.com
星です。

>> > 1.ネガポジ反転
>>
>> 実装は簡単ですが、はて必要でしょうか?
>> (まああってもいいかなとは思いますけど :-)
>
> んまあ、「個人的な意見」ですんで。DSLが実装されるなら、今無理に実装しなくてもいいかなとは思います。ただ有効な使い道はそれなりにあるんでない
> かと。あくまでも個人的に。

そうですね。
強い要望でらっしゃらないようですので保留にします。

>> > 2.転送先のアルファ値を保持する
>> > (3.パレットを持つテクスチャの描画において、パレットの先頭ないしは任意のインデクスの色を「抜き色」とし、抜き色に関してはアルファ値0、その他
>> > の色はアルファ値255として下地を考慮せず、ブレンドする側のアルファ値も考慮しないブレンドを行う)
>> > (4.RGB各要素を、同ピクセルのアルファ値に置き換えてブレンドを行う。このときアルファ値255だとするとRGB255となり、ピクセルが透明な
>> > ほど黒く、不透明なほど白くなる)
>> > 2.は、 dst.render_texture(src,x,y) とした時に dst の持っていた各点のアルファ値が、src の持つそれに影響
>> > されることなく保持されるという意味です。色調を変更するのと同じような感覚で、画像を合成することができます。
>>
>> 実は昔「特定の色成分から特定の色成分へコピーする」という機能を実装しかけたのですが、
>> ひょっとしたらそれで出来るかも。
>> (いまでも dump/undump で出来たりします。)
>>
>> さらに言うと、それをやるなら汎用的なフィルターメソッドがほしくなりますが、
>> それについては後述。
>
> 「あるテクスチャから任意のテクスチャへ」任意の色成分をコピーできる機能、ということですか。そうすれば、私の案で言うところの dst に当たるも
> ののアルファ値を、src に持っていき、その上で dst に対して src をブレンドすれば同等の結果が得られそうだ、という解釈でよろしいので
> しょうか。

その通りです。説明足らずですみません。

>> > 3.に関しては、アルファ値の計算が省ければ、若干描画を高速化できるのではあるまいか? と考えての提案となります。予想なので果たして有用かどう
>> > か、さっぱりわからないのですが。(パレットの要素に、255以下のアルファ値を持つカラーを代入しても、ちゃんと反映されるので、現時点で下地は考慮
>> > するようになってるんだなとは分かりました。この現行の仕様も有用でしょうから、オプションとして提案する次第です)
>>
>> 速度はほとんどかわらないと思います。
>> 合成結果の dst の RGB は結局 src と dst の RGBA で計算するからです。
>> ちなみに今の計算方法の疑似コードは以下の通りです:
>>
>> if (dst.a == 0) {
>> dst.r = (1 - src.a / 255) * dst.r + (src.a / 255) * src.r
>> dst.g = (1 - src.a / 255) * dst.g + (src.a / 255) * src.g
>> dst.b = (1 - src.a / 255) * dst.b + (src.a / 255) * src.b
>> dst.a = max(dst.a, src.a) # (1)
>>
>> } else {
>> dst = src
>> }
>>
>> 提案手法では、 (1) がなくなるだけのように思えますが。
>
>
> もしかして、正しくはこうですか?:
>
> if (dst.a == 0) {
> dst = src
>
> } else {
> dst.r = (1 - src.a / 255) * dst.r + (src.a / 255) * src.r
> dst.g = (1 - src.a / 255) * dst.g + (src.a / 255) * src.g
> dst.b = (1 - src.a / 255) * dst.b + (src.a / 255) * src.b
> dst.a = max(dst.a, src.a) # (1)
> }
>
> ふーむ。ブレンドタイプ :non が結構早くなるので、これはと思ったんですが。src をまるっと dst に持っていくわけではないですしね...

おーっとその通りでした。
:none は dst を完全無視しますからねえ。

>> > 4.に関しては、思いついてみたものの「これ本当に使えるのか」といった感じで、果たしてライブラリ側で提供する価値が十分にあるのか、よくわからない
>> > です。マスク用画像をリアルタイムに生成するとかを想定しています。「ブレンド時にRGBA各要素を自由に置き換えながらブレンドする」、という風にし
>> > てもいけますが。
>>
>> これも、上で述べた「特定の色成分から特定の色成分へコピー」ですみそうですね。
>>
>> 話は変わるのですが、こういうフィルター的なものは DSL
>> でかけたらいいなと思っています。
>>
>> Ruby スクリプトでフィルターを実装する場合、
>> Color オブジェクトがばんばん生成されるなど
>> 速度的にきついものになります。
>> (ちなみに色は 32 bit 整数なので 32bit マシンでは Fixnum でも収まりません。)
>>
>> そこで、フィルターのための独自言語 (DSL) を作り、
>> それを文字列 (もしくはコンパイル済みのバイト列など) として
>> 与えるというのを考えております。
>> DirectX や OpenGL のシェーダーのようなものです。
>
> 非常に有用だと思います。マニアックなフィルタが利用できるのはもちろん、ある程度の最適化(こーいう言い回しは果たして適切なのか)にも応用できるか
> もしれません。
>
>> やるとしたら 0.4.x やその先の話になりそうです。
>> (1.0 には全然たどり着きませんね :)
>
> 僕は気長に見守らせていただくとします。たまに勝手な意見を吐いたりしながら←

はーい。

--
Hajime Hoshi <hajim...@gmail.com>

Reply all
Reply to author
Forward
0 new messages