2010年12月24日

GLSLによるトゥーンシェーディング

輪郭線表示するならトゥーンシェーディングも試してみようということで試してみました。

今回はジオメトリシェーダは殆ど関係ないですね。頂点シェーダからピクセルシェーダにデータを受け渡してあげるぐらいです。

ほぼ参考サイトそのままなので特に書くこともないです。

参考サイト:
http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20080218
http://www.arakin.dyndns.org/glsl_cartoon.php

使用したテクスチャは下記のようなものです。手抜きでプログラム内で値を設定しました。

toon.png

実行結果



一応おまけでフォンシェーディングのハイライトを入れていますが、トゥーンシェーディングするなら入れては駄目な気もしますね。

web拍手 by FC2
posted by シンドラー at 18:12 | Comment(2) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2010年12月22日

ジオメトリシェーダで輪郭線表示

あまりジオメトリシェーダの使い道が思いつかないのですが、インクと呼ばれる輪郭線表示辺りなら簡単にできそうだったので試してみました。

MMDでも同じ方法を使っているんでしょうかね。


処理の流れは以下の通りです。

頂点シェーダ
1.頂点の位置と法線ベクトルをジオメトリシェーダに渡す

ジオメトリシェーダ
1. 元の面をそのまま表示
2.法線方向に頂点を移動
3.黒色、裏面にしてポリゴンを描画

面を裏返す方法は頂点の順番を逆にするだけですしとても簡単ですね。

通常のプログラムの方で陰面消去を有効にしておく必要があります。

glEnable(GL_CULL_FACE);

実行結果

glsl_gs_002.png

ソースコード

GLSL_GPU_1.zip

以下シェーダのソース
続きを読む
web拍手 by FC2
posted by シンドラー at 16:30 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2010年12月13日

GLSLでジオメトリシェーダのテスト

GLSLでジオメトリシェーダを試してみました。あまり日本語の情報ないですね。

参考サイト:http://cirl.missouri.edu/gpu/glsl_lessons/glsl_geometry_shader/index.html

上記のサイトのソースコードを改変しました。

ジオメトリシェーダを使用するための準備は、バーテックスシェーダとフラグメントシェーダの場合とほぼ一緒です。

glCreateProgram
↓              glCreateShader
glAttachShader ←         ↓
↓              glShaderSource
glLinkProgram            ↓
↓              glCompileShader
glUseProgram

変更点としては、追加で最大頂点数とジオメトリシェーダへの入力と出力を指定する必要があるということです。

 // 三角形を入力して三角形を出力する
 glProgramParameteriEXT(program, GL_GEOMETRY_INPUT_TYPE_EXT, GL_TRIANGLES);
 glProgramParameteriEXT(program, GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_TRIANGLES);

 // ジオメトリシェーダで出力する最大頂点数の取得と設定
 int temp;
 glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &temp);
 glProgramParameteriEXT(program, GL_GEOMETRY_VERTICES_OUT_EXT, temp);

後はジオメトリシェーダのソースコードを記入します。#version 120ですので、もしかしたら情報が古いかもしれません。

#version 120 
#extension GL_EXT_geometry_shader4 : enable

void main(void)
{
// 何もせずそのまま出力
for (int i=0; i<gl_VerticesIn; i++)
{
gl_Position = gl_PositionIn[i];
EmitVertex();
}
EndPrimitive();
}

ここで、EmitVertex()とEndPrimitive()が重要で、以下のような決まりがあります。

 EmitVertex()で頂点の設定を完了
 (1個の頂点を設定後呼び出す必要有り)

 EndPrimitive()でプリミティブの設定を完了し次のプリミティブを開始
 (GL_POINTSなら1個の頂点をEmitVertex()した後に呼び出し、
  GL_TRIANGLESなら3個の頂点をEmitVertex()した後に呼び出す)

その他詰まった点として、バーテックスシェーダ→フラグメントシェーダのプログラムを改変した場合、バーテックスシェーダ→ジオメトリシェーダ→フラグメントシェーダと間にジオメトリシェーダが入ることになるため、varying変数でバーテックスシェーダからフラグメントシェーダにデータを直接渡すことができなくなるところでした。

実行結果

glsl_gs_001.JPG

ジオメトリシェーダで各ポリゴンを四面体に変更したティーポットです。
その他詳しいところはソースコードでということで。

以下ソース
GLSL_GPU_0.zip
web拍手 by FC2
posted by シンドラー at 23:39 | Comment(0) | TrackBack(0) | OpenGL & Metasequoia | このブログの読者になる | 更新情報をチェックする

2010年12月08日

c-means法と距離フィールドによるカラー画像の拡大

続きです。カラー画像でも距離フィールドで拡大してみたかったので、c-means法でクラスタリング(減色)して、各クラスの距離フィールドを計算して、拡大→統合してみました。

テクスチャとして考えた場合は、距離フィールドの画像がクラスの数だけできてしまうので、意味がない気がします。

処理の流れは以下のようになります。

カラー画像の距離フィールド作成方法

1.原画像読み込み
2.c-means法で指定したクラス数に分割(減色処理)
3.各クラスの画像を2値化→距離フィールドを計算→縮小
4.各クラスの縮小した距離フィールド画像と色情報を保存

拡大方法

1.4.の画像と色情報を読み込み
2.全てのクラスの距離フィールドを拡大
3.閾値以上の領域は各クラスの色に設定
4.閾値以下の場合は値に応じてスケールを調整
 (閾値128で値が64の場合は0.5倍の色)
5.各クラスの拡大画像を加算して、複数クラスが重なった画素はスケールの値で割る
 (ある画素がクラス1の1倍の色+クラス2の0.5倍の色の場合、1.5で画素値を割る)

実行結果

ネットで拾ったゆっくり画像です。元画像とか良く分からないので問題があれば教えてください。

原画像(629x350)

yukkuri.jpg

拡大(1258x700)して64クラスに領域分けした結果

c_means191.bmp

距離フィールド画像の一例(157x87、1/8倍、64枚)

df061.bmp

距離フィールド画像と色情報から拡大(2516x1400)した結果

scaleUp_result.png

細かく見ると微妙ですが、距離フィールド画像から16倍していることを考えるとそれなりの結果が得られているのではないかと思います。

ただ、64色に減色していますので、自然画像などには厳しいのではないかと思います。

対策としては、メモリがたくさんあればクラス数を増やす、またはクラスの統合・分割を行い最適化する等が考えられます。
(色だけでクラスタリングしているので、1点だけ孤立していたりキザキザだったり改善点は色々あります)

別の方法として、領域分割後に輪郭を基本形状や曲線でベクトル化した方がきれいになる気がします。

web拍手 by FC2
posted by シンドラー at 17:11 | Comment(0) | TrackBack(0) | Image Processing | このブログの読者になる | 更新情報をチェックする

2010年12月04日

c-means法によるクラスタリング

領域分割の方法のひとつとして、k-meansやc-meansと呼ばれる教師なしで指定したk個のクラスに分類する手法があります。

OpenCVにもk-means法とかSVMとか色々ありますが、今回は下記参考文献を参考に、hard c-means法とfuzzy c-means法を実装してみました。

参考文献(2章):http://www.risk.tsukuba.ac.jp/riskhp08/educ/thesis/master/2008/200720815.pdf

分類するデータとしては、画素の位置情報やRGB色情報、近傍画素との平均や分散など、色々なものが考えられると思います。今回は位置と色を使ってみました。

実行結果

出展元がよくわからないはちゅね画像(512x512)を使わせていただいております。
原画像を256x256に縮小し、クラスタリングを行いました。

c-means法


位置情報、1024クラスに分類。なんとなく枠が外に逃げている感じ。

c_means167.bmp 
色情報、24クラスに分類。ほぼ原画像ですね。


色と位置情報の併用、1024クラスに分類。あまりきれいではないですが。

fuzzy c-means法


位置情報、1024クラスに分類。ファジーなので少し色が混ざっているのと、外に広がる感じ。
左上の緑色は恐らくバグです。


web拍手 by FC2
posted by シンドラー at 03:38 | Comment(0) | TrackBack(0) | Image Processing | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。