投稿者 tel | 2013年7月24日

Distance Fieldでフォントの描画する

WebGLで「Improved Alpha-Tested Magnification for Vector Textures and Special Effects」を実装してみた。

http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf
https://www.cct.lsu.edu/~fharhad/ganbatte/siggraph2007/CD1/content/courses/c28/c28.pdf

Distance Fieldとよばれるエッジからの距離を格納したテクスチャを使ってベクターデータのようにエッジを滑らかにレンダリングする手法。64×64くらいの小さなテクスチャでも拡大しても耐えられるような見た目になる。

オライリーの「iPhone 3Dプログラミング」にDistance Fieldテクスチャの生成アルゴリズムとシェーダが載っていたので試してみたが、うまくいかなかった。

Distance Fieldのテクスチャ生成は、とりあえずでかい解像度で作ってから縮小したらそれなりに見れるようになった。(そのままのサイズだとモアレが発生してレンダリングした時にエッジがガタガタになってしまった)

df_cat_3

シェーダの方はちゃんとコピペしてきてもアウトラインとかが全然うまく表示されなかったのでいろいろ修正した。fwidthの拡張機能を使うのでシェーダの最初の方で有効にしている。(WebGLで拡張機能を有効にする方法)

#extension GL_OES_standard_derivatives : enable
precision highp float;

varying vec2 textureCoord;
uniform sampler2D distanceField;
uniform float alphaTest;
uniform vec3 glyphColor;
uniform vec3 outlineColor;
uniform vec3 glowColor;

uniform bool outline;
uniform bool glow;

uniform float smoothCenter;	//=0.5
uniform float outlineCenter; //=0.4

void main() {;
	vec4 color = texture2D(distanceField, textureCoord);
	float alpha = color.a;
	float d = color.a;

	if(alpha < alphaTest) {
		discard;
	}

	vec3 rgb = glyphColor;
	float smoothWidth = fwidth(alpha);

	alpha = smoothstep(smoothCenter - smoothWidth, smoothCenter + smoothWidth, alpha);

	if(outline) {
		rgb = mix(outlineColor, rgb, alpha);
		alpha = smoothstep(outlineCenter - smoothWidth, outlineCenter + smoothWidth, color.a);
	}

	gl_FragColor = vec4(rgb, alpha);
}

df_result

実際にレンダリングしてみた結果。大きくしてもエッジがそこそこなめらかになっている。

outline_0

outline_1

アウトライン表示。アウトラインの太さはシェーダのパラメータで変えられる。

iPhone 3Dプログラミング ―OpenGL ESによるアプリケーション開発
Philip Rideout
オライリージャパン
売り上げランキング: 129,813

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

カテゴリー

%d人のブロガーが「いいね」をつけました。