グラデーションアルゴリズム
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
NGNG0003デフォルトの名無しさん
NGNG弟子にして下さい。
0004ボログラマー
NGNGベベルを知らない俺に対するイジメですか。(滅
悔しいので検索。
http://www.jade.dti.ne.jp/~yam/jf11baveb.html
タイプミスで、こっちかとも思ったんですが、
http://www.forest.impress.co.jp/article/2000/04/19/nvrbordermania.html
こっちっすな。>ベベル
>>1
以下、コード。(コンパイルも通してません)
// buff は24bitBITMAP@` n は明るく(暗く)するレベル
void white(unsigned char *buff@` int n)
{
for( int i = 0; i < 3; i++) {
if(buff[i] + n < 0xff ) buff[i] += n;
else buff[i] = 0xff;
}
}
void black(unsigned char *buff@` int n)
{
for( int i = 0; i < 3; i++) {
if(buff[i] - n >= 0 ) buff[i] -= n;
else buff[i] = 0;
}
}
// buff は24bitBITMAP@` (x@` y)はBITMAPのサイズ@` b は縁取りするドット数
void beberu(unsigned char *buff@` int xsize@` int ysize@` int b)
{
int x@` y;
int alx = (xsize * 3 + 3) & 0x7ffffffc; // BITMAPのアライン対策
for( y = 0; y < b; y++) {
for( x = y; x < xsize - y; x++) {
white(buff[x*3 + alx*y]@` 0x60);
black(buff[x*3 + alx*(ysize-y-1)]@` 0x60);
}
}
for( x = 0; x < b; x++) {
for( y = x; y < ysize - x; y++) {
white(buff[x*3 + alx*y]@` 0x80);
black(buff[x*3 + alx*(ysize-y-1)]@` 0x80);
}
}
}
00051
NGNGいくつかのアルゴリズムを組み合わせたもののようです。
ボロプログラマーさんありがとうございます。
グラデーションは塗りも含めて汎用的なものがあれば
いいなぁといったレベルです。
0006名無しさんi486
NGNG00081
NGNG斜めのアルゴリズムになるととたんにわからなくなります。
>>6
ディザ処理というかアンチエイリアスの処理なんではないかなと私は踏んでます。
確かにレベルや、ぼかしの量などではディザを使うような気もしますが…。
グラフィック系のアルゴリズムは初めてで本やネットを検索したんですが、
なかなかこれといったものにたどり着けないありさまです。
0009>7@`8
NGNG特定の色だと、たとえRGB24bitであっても1bitの違いの色も目で見て分かるからな
フォトショップをみてごらん
確かに、水平・垂直方向以外のグラデーションはメンドイけど、ディザらない
のなら、厨房のレベルだろ。
色の開始点〜終了点の距離に着目して考えてごらん。
0010ボログラマー
NGNGそういう意味か。
普段ゲームで使うリアルタイムな処理しか考えんから思い当たらなかった。
でもまぁ、サイズと頂点の色差に寄るけど24bitなら2〜3ドット同色
続いても、見分けつかなくない?
0011デフォルトの名無しさん
NGNG>垂直、水平のグラデーションは頭をひねればそこそこ作れるのですが、
>斜めのアルゴリズムになるととたんにわからなくなります。
それなら水平・垂直のグラデーションを斜めに傾ければよいのでは。
0012デフォルトの名無しさん
NGNG用途が書いてないから、まあしょうがないが、ゲームならミドルウェアが
勝手にやってくれるから、ゲームの話じゃないと思ったわけだよ。
ビデオ系は結構問題になるよ。16〜235の範囲だし、10bitだし。
00131
NGNG確かにその方法は考えたのですが、二度手間になるかなと思って、
他に良い方法を探していると言った感じです。
最悪の場合はそれがいいのかなとも思っています。
やっぱりグラデーションの汎用的なアルゴリズムは存在しなんでしょうか?
00141
NGNGこれといった特定の用途があるわけではなく、勉強に近いものです。
機種依存で良いのならハードウェアレベルや、ミドルウェアが処理して
くれるので、こういったことも問題にならなんですが、なるべく機種依存の
ないライブラリを独自のノウハウとして持っておきたいなということです。
0015デフォルトの名無しさん
NGNG自動的に勝手に斜め方向にもグラデーションされる。
0016デフォルトの名無しさん
NGNG逆アフィン変換でグラデーションを描画すれば
いいはずだよ。
0017デフォルトの名無しさん
NGNGアフィン変換が
http://www-ai1.csis.oita-u.ac.jp/~mikiko/Cgzemi/file6-4.html
この事だとすれば、何か勘違いしてるであろう
16の自分用語の可能性は残っているが
0018ボログラマー
NGNGhttp://www.ascii.co.jp/ghelp/57/005763.html
通常、テクスチャ貼るときに使う。>逆アフィン
テクスチャをグラデパターンにして描画しろ、ってことだろ。
俺はそんなことしないぞ?
0019デフォルトの名無しさん
NGNGグラデにディザってマッハバンド対策でしょ。
どっちかっていうと同色が多く続く場合のほうが問題なわけです。
0020デフォルトの名無しさん
NGNGその交点の位置で色決めます。
DDA使えば整数だけでできるよ。
0021デフォルトの名無しさん
NGNGDelphiだとこんなかんじ(長くてすまんこ)
procedure MakeMatrix(aAngle: Integer);
var
x@` y: Integer;
xx@` yy: Integer;
dx@` dy: Integer;
th: Extended;
ml: Extended;
cc@` ss: Extended;
icc@` iss: Integer;
col: Integer;
const
GradLevelMax = 256; //グラデのレベルの最大
GradMatrixSize = 256; //グラデの配列のサイズ
begin
SinCos(DegToRad(aAngle)@` cc@` ss);
ml := Max(Abs(cc)@` Abs(ss)) * GradLevelMax/2 * 65536;
cc := cc * ml; ss := ss * ml;
icc := Round(cc); iss := Round(ss - (GradLevelMax div 2) * 65536);
dx := Round(2 * ss / (GradMatrixSize-1)); dy := Round(2 * cc / (GradMatrixSize-1));
yy := -icc;
for y := 0 to GradMatrixSize-1 do begin
xx := yy - iss;
for x := 0 to GradMatrixSize-1 do begin
GradationMatrix[y@` x] := Max(Min(xx div 65536@` GradLevelMax-1)@` 0);
Inc(xx@` dx);
end;
Inc(yy@` dy);
end;
end;
わたしもコンパイル非チェックです(ぉ
0022デフォルトの名無しさん
NGNG少しずつずらしながら転送するってのもいいかも
00231
NGNGなるほど、なんとなくわかってきました。
この例ですと、65536色の場合、
256x256のMatrixの中に指定されたAngle分のグラデーションを描画(配列に保存)し
それアフィン変換を使って拡大縮小で補間すると言ったかんじでしょうか?
ただ、行っていることはなんとなく理解できるんですが、
どういう理屈で動いているかがわかりません。
色の指定jはどこで行っているのでしょうか?
002421
NGNG// 正方形の中心(cx@` cy)
cx := (GradMatrixSize-1) / 2.0; cy := cx;
SinCos(th@` ss@` cc);
// 中心から斜めった角までの長さ
ml := cx / Max(Abs(cc)@` Abs(ss));
for y := 0 to GradMatrixSize-1 do begin
yy := y - cy;
for x := 0 to GradMatrixSize-1 do begin
xx := x - cx;
v := yy * cc - xx * ss;
//ここでvは-ml <= v <= mlの範囲でグラデる
end;
end;
こんなメモが出てきました
これがどーしてあーなったのか忘れたけど(ぉ
>色の指定jはどこで行っているのでしょうか?
そうですね、これだけだと正方形に角度指定して0から
だんだん大きな値にするだけのルーチンですね
別のところで、ColorTable[0..GradLevelMax-1] of TColorとかで
色の配列を作って、それをGradationMatrix[]の値で参照して
BitmapにPlotしていきます
色の配列は、指定された最初と最後の色のRGB各値を
ちょっとずつ変えて入れています
白黒だけならRGBにそれぞれ0〜$ffを入れるだけなんだけど…
00251
NGNGこの方法でいけるかもと思ったのですが、この場合ある2点を指定された
グラデーションで塗る(いわゆる、PhotoShopのグラデーションで塗るときの動作)
ということを行おうとした場合、うまくいかないのではないかと思ったのですが、
実際はどうなのでしょう?
002621
NGNGうまくいかないでしょう
っていうか、Photoshopって使ったこと無いので、どんなんか
わからないというのが本音
すまんこ>1
想像だけど、2点を結ぶ線に垂直にグラデりそうな気が
するんだけど(始点から終点の色で)
線分を対角線に持つ矩形を塗り潰すのかな
斜め->角度がもらえると思ったおれはドキュソ
欝だ仕事に戻ろう
0027ボログラマー
NGNG角度ならatan2()で取れる。>C/C++
>>19
2〜3ドット連続してる画像テスト。24bitか32bitカラー環境で見てくれ。
http://members.jcom.home.ne.jp/3225906101/bin/test.bmp
ホントにこれ見て解る?正直俺はわかんねぇが。
もっと連続してくれば*見える*が、
2〜3ドットならば人間には判別出来ないと思うが。どうか?
002821
NGNGぐらひっく屋さんって、わかるらしいですよ
わたしはわかんないけど
あと、白黒でRGBが(81@`81@`81)から(82@`82@`82)までを分割するさい
ふつうだと(81@`81@`81)と(82@`82@`82)の2分割しかできないけど
(81@`81@`81)@`(81@`81@`82)@`(81@`82@`82)@`(82@`82@`82)
とか、むりやり間を取る(散らす)こともあるって噂
002916
NGNGそのとおり、グラデーションのテクスチャを貼り付けるという考え方です。
グラデーションしか描けないアルゴリズムよりも,
1に汎用的な方法を知ってもらった方がよいと思ったんですよ。
0030デフォルトの名無しさん
NGNG俺は分かった。なんか縦筋がうっすらと見えるんだよな。
それでなくとも汚いグラデーションだと感じた。
00311
NGNGそんなことはないです。ありがとうございます。
確か20さんが言っていたように、開始点と終了点を結ぶ垂線に
そって描画すれば、グラデーションを描けると思います。
この場合、縦、横は矩形を色を変化させながら連続して描画を行えば、
きれいなグラデーションになっていくと考えられるのですが、斜めになった場合、
矩形と矩形の間に隙間ができてしまうのではないかと想像がつきます。
この方法も工夫次第ではきれいなグラデーションを描画できそうなんですが、
どうしても、もっとスマートなアルゴリズムがあるのではないかということを
思った次第です。
>>27
私が見た感じでは、十分使用に耐えうるグラデーションになっていると思います。
確かに良く見るとうっすらと筋が見えたりしますが、
この程度なら市販のアプリケーションでもあることですし…。
>>28
参考までに、FireWorks(グラフィックソフト)で
#FFFFFF〜#FEFEFEへのグラデーションを描画
してみたところ、この2色の2分割になっていました。
>>29
ありがとうございます。
確かにグラデパターンをテクスチャで貼るという考え方は思いつきませんでした。
これは21でかかれている方法と同じだと考えてよいのでしょうか?
0032デフォルトの名無しさん
NGNG対象領域を水平線分割する処理を書くというか これは必須だよね
対象領域の水平線の始点と終点の色を決定する
この決定は多少重くても問題ない。
水平線の始点と終点を与えてDDA使って塗ればOK
003321
NGNGもし、テクスチャを回転してきれいに貼れるのであれば
縦か横のグラデだけ作れれば済むと思いますよ
■ このスレッドは過去ログ倉庫に格納されています