今年もありがとうございました。

こんばんわ。Pocolです。
本年度、最後の更新です。今年一年を振り返ろうと思います。

まずは,自分がシステム構築など行ったゲームが無事に世に出て良かったです。
ほとんどやったのはシステム構築だけで最後まで関われなかったので,
製品まできちんと出来たのは自分以外の人の努力の結晶だと思います。
間接的ながら,少しだけ仕事に関わることが出来て良かったと思います。
また,ミリオンも達成できて良かったと非常に思います。
いつも,エンジンやらライブラリやらしか作っていないので,
製品のスタッフロールに載ることは殆ど無いのですが… 
(XXX Team やら XXX 株式会社なりでまとめられてしまうので,名前が載ることはないのです)
今回はスタッフロールに載せて頂けたので,非常に良い経験となりました。

10月には,皆様に大変お待たせしましたが,ようやく執筆していた本を発売することができました。
レビューアの皆様ならび,編集担当の落合様には大変互助力をしていただきました。
この場で,再度お礼を申し上げます。ありがとうございました。
来年には,皆で打ち上げやりましょう!

後は最近うちのホームページなんか見ている人これっぽっちもいないだろうと思っていて,そろそろpublicなホームページは辞めたいなって思っています。
privateなページにして,のほほんとやっていきたい。自由に書きたい。
Githubに人知れずこっそりと記事をあげたりとか,今あんまり使っていないSlackとかで投稿するのも良いかもしれないなぁって感じています。
…ということで,そのうちページ閉じるかもという予告でした。

来年はどんな一年になるんでしょうか?
楽しい1年にしたいな。
それでは,皆様良いお年を!

お、遅かったじゃないか…。

こんにちわ。Pocolです。
「お、遅かったじゃないか…。」

そう言われても仕方ありませんね。
Direct3D 12 ゲームグラフィックス実践ガイドの正式な発売が決定しました!
10月15日発売です!
三宅さんのAI本の一日後なので,三宅さんの本を買う人は一日遅らせて一緒に買いましょう。

本日より,先行販売している書店さんもあるようです。一日でも早く手に入れたいという方は,先行販売している書店さんに行ってみると良いかもしれません。

また,本日の先行販売に合わせて,書籍のサンプルプログラムのダウンロードページが公開されました。
下記ページの「本書のサポートページ」にアクセスするとzipファイルでサンプルプログラムがダウンロードできる状態になっています。
書籍のページ上の都合で,本にはプログラムコードがフルで書かれていませんので,こちらのサンプルを見ながら,本と照らし合わせて見て頂けると良いかと思います!

あと,ページレイアウト決まった後で,サンプルプログラムで未使用変数があるというビルド警告が出る箇所を見つけてしまったのですが,プログラムが実行できないなどの致命的な問題ではないのと,諸所の事情で修正できませんでした。
該当の箇所は,

Chapter9/Tonemap/Sample/res/TonemapPS.hlsl
107行目のL0
108行目のL1

です。
こちらはプログラム上で使っておりませんので,削除あるいはコメントアウトして頂けるとビルド警告が表示されなくなりますので,お手数ですが各自で修正をお願い致します。

…というわけで,来週発売になりますのでよろしくお願い致します!

私的メモ:モーションブラー

A Fast and Stable Feature-Aware Motion Blur Filterの疑似コード。

float cone(float dist, float r) {
	return saturate(1.0f - abs(dist) / r);
}

float cylinder(float dist, float r) {
		return sign(r - abs(dist)) * 0.5f + 0.5f;
}

// linear depth.
float zCompare(float za, float zb) {
		const float SOFT_Z_EXTENT = 0.1f;
		return saturate(1.0 - (za - ab) / SOFT_Z_EXTENT);
}

float3 MotionBlur(float2 p)
{
	// parameter setting (see. 5. Implementation and Results).
	const auto N		= 35;	// sample count.
	const auto eta		= 0.95; // a larger maximum jitter value (in pixel units). (see p.6)
	const auto phi		= 27;	// user-determined constant which affects the "baseline2 jitter level. (see p.6)
	const auto kappa	= 40;	// use-parameter to bais its importance. (see p.6)
	const auto r		= 40;	// a maximum image-space blur radius. (see p.2)
	const auto gamma	= 1.5;	// minimum user threshold (see p.4)

	auto j = Halton(-1, 1);

	// sOffset jitters a tile lookup (but never into a diagonal tile).
	auto vmax = FetchNeighborMax(p/r + sOffset(p, j));
	auto mag_vmax = length(vmax);
	if (mag_vmax <= 0.5f)
	{
		return FetchColor(p);
	}

	auto wn = vmax / mag_vmax;
	auto vc = FetchVelocity(p);
	auto wp = (-wn.y, wn.x); // vmax⊥.

	if (dot(wp, vc) < 0.0)
	{
		wp = -wp;
	}

	auto mag_vc = length(vc);
	auto wc = normalize(lerp(normalize(vc), wp, (mag_vc - 0.5) / gamma); // Eq. (1).

	// First integration samples: p with center weight
	auto totalWeight = N / (kappa * mag_vc);
	auto result = FetchColor(p) * totalWeight;
	auto j_dash = j * eta * phi / N;

	auto z_p = FetchDepth(p);

	for(int i=0; i<N; ++i)
	{
		auto t = lerp(-1.0, 1.0, (i+j_dash + 1)/(N+1)); // jitter sampler

		// Compute point S; split samples between {vmax, vc}
		auto d = (i & 0x1) ? vc : vmax; // iが奇数なら vc, iが偶数なら vmax.
		auto T = t * mag_vmax;
		auto S = int2(t * d) + p;

		// Compute S's velocity and color
		auto vs = FetchVelocity(S);
		auto colorSmaple = FetchColor(S);

		auto z_S = FetchDepth(S);

		// Fore-vs. background classification Y w.r.t p
		auto f = zCompare(z_p, z_S);
		auto b = zCompare(z_S, z_p);

		// Sample weight and velocity-aware factors (Sec.4.1)
		// The length of v_s is clamped to 0.5 minimum during normalization
		auto weight = 0;
		auto wA = dot(wc, d);
		auto wB = dot(normalize(vs), d);

		auto mag_vs = length(vs);

		// 3 phenomenological cases (Sec. 3, 4.1): Object
		// moving over p, p's blurred motion, & their blending.
		weight += dot(f, cone(T, 1 / mag_vs)) * wB;
		weight += dot(b, cone(T, 1 / mag_vc)) * wA;
		weight += cylinder(T, min(mag_vs, mag_vc)) * max(wA, wB) * 2;

		totalWeight += weight; // For normalization
		result += colorSample * weight;
	}

	return result / totalWeight;
}

McGuireのG3Dエンジンでは論文実装よりも変更がある。以下のように内積計算部分がガッツリなくなっている。
https://sourceforge.net/p/g3d/code/HEAD/tree/G3D10/data-files/shader/MotionBlur/MotionBlur_gather.pix

auto f = zCompare(z_p, z_S);
auto b = zCompare(z_S, z_p);

auto weight = 0.0f;
weight += b * cone(T, 1 / mag_vs);
weight += f * cone(T, 1 / mag_vc);
weight += cylinder(T, min(mag_vs, mag_vc)) * 2.0f;

totalWeight += weight;
result += colorSample * weight;

順調です。

こんばんわ、Pocolです。
アレですが,順調に進んでおります。機が熟したら書きますので、もう少しお待ちください。

超雑訳 Separable Subsurface Scattering Supplementary Materials

こんにちわ。Pocolです。
今日は前に読んだ,Separable Subsurface Scatteringの補足資料を読んでみようと思います。
資料は
[Jimenez 2015] Jorge Jimenez, Karoly Zsolnai, Adrian Jarabo, Christain Freude, Thomas Auzinger, Xian-Chun Wu, Javier von der Pahlen, Michael Wimmer, Diego Gutierrez, “Separable Subsurface Scattering”, Compute Graphics Forum 2015.
のプロジェクトページhttp://www.iryoku.com/separable-sss/にあります。
いつものように誤字・誤訳があるかと思いますので,ご指摘いただける場合は正しい翻訳例と共に指摘していただけると幸いです。

(さらに…)

もうすこし待たれよ!

こんにちわ、Pocolです。
執筆している本ですが…,順調に進んでいます。

企画から5年。そして無名ということで企画が通るまでの,半年近くはほぼ何もできず。
担当さんの地道な根回しがあって,ようやく執筆までたどり着いた本です。

折角企画も通り,発売に向けて動き出したので…
発売後にマサカリ投げられるのは,嫌なので説明部分に関してはあらかじめ豪華メンバーに査読していただきました。
説明については丁寧にレビューしていただきました。
本当にこの場を借りて,感謝を述べさせていただきたいと思います。
「本業がありタイトル開発などお忙しい中,レビューアーの皆様本当にありがとうございました!」

実をいうと,レビューで心が折れました。
やっぱり,色々と見てもらうと自分がいかに愚か者であるかということをヒシヒシと感じますね。
説明の仕方もそうですが,言葉の選び方や言い回しなんかもそうです。
独りよがりはやっぱりいかんなと改めて思いました。
また、レビューしていただいて本当によかったなと心の底から感じています(本当最初の状態は酷かった)。
レビュー無しで,国会図書館なんかに寄贈されて,ダメダメな説明とかが自分が死んだ後も一生記録されてしまうと思うと,ゾッとしますね。
レビューが無かったら,そうした恥をさらしながら生きていかなければならないのですが,レビューをしてもらうことで,少しでも回避することができて本当によかったなと思います。
やはり,レビューをしてもらって感じたのですが,きちんとした議論があってこそ,良いものが生まれてくるんだろうなと… そう感じました。
自分が見ていて「これは良いな!」と思う書籍は共著だったり,きちんと監修が付いていたりしますしね。

自分は筆不精でして,期待されて待っている方には本当に申し訳ないのですが,
実はとある競合書籍が発売されていなければ,今頃は既に発売済みだったんですね。
何もせずに,当初通りそのまま発売というのもありだったのですが,単なる2番煎じになるもの,流石にどうかなと思いまして…。
(まぁ、だったら先越される前に早く書けよっていうのはごもっともです。)

やはり,先手を打ち出されてしまうと,後手側は何かしらの対策を練らねければなりません。
何も対策を練らないというのは愚の骨頂ではないかと思いましたし,何かしら付加価値を付けて提供したいと思いました。
また,何もせずにそのまま発売にもっていってしまうのは,色々な方の力を借りている分,自分として申し訳なかったですし,待っている方にも申し訳が立たないです。
担当さんは,「こちらのほうが先にやっているのに…後からを先越されて…」と,がっくし来ていたみたいです。
自分もさらに,その本の内容を見てガックシきました。ちなみに,その本の内容は,細かい所は違えど目指す方向性としては,自分が一番最初に出版社に企画を出してボツになった内容ほぼそのものでした。こっちの出版社だったら,すんなり受け入れられていたかもしれないな…って。
まぁ、いずれこういう先に越されることは目に見えていたので,筆不精な自分が悪い以外のなにものでもないんですけどもね。

ただ,今書いている内容はボツになったものとは方向性が違います。
…というか,出版社側のダメ出しだったり,他社に先越されるのとか想定して,じゃぁちょっと変えましょうと,企画段階で変更したんですよね。
だから,そのまま予定に沿って発売に向けて動いても問題はなかったのですが,何か悔しいなと思って…。
何かしら手は打たねばならないと思いました。
そこで,1章分を新たに追加執筆し,さらに開発に役立つと思われる付録もちょっとしょぼい内容ですが一応付けました。

具体的な内容については,もう少し言える状況になったらお伝えしたいと思います。
(内容を書いて競合他社にパクられて,差別化をするためにまた発売を延期するのは流石に勘弁したいので…)
皆さん,完成まで着々と進んでいます。もうしばらくお待ちください!!

明けましておめでとうございます。

新年あけましておめでとうございます!
本年度もどうぞProjectASURAをよろしくお願い致します。

今年は執筆していた本も発売されるので,本発売まで更新停止していたホームページもぼちぼち更新頻度を高められたらなぁと思っています。
色々とノウハウも徐々についてきたので,どこかで文章化出来たらいいなと思っています。

あとは昨年から息抜きとしてゲームっぽいものも作り始めました。こちらについてもある程度形になってきたらホームページの方で記事化出来たらと思ってます。

書籍進捗状況。

こんるる~、Pocolです。

皆さん、気になっている書籍進捗状況について。
手元に最初のレイアウト見本が届きました。


当然ながら完成していないのとネタバレ回避のため全部をお見せすることはできませんが…
コロナの影響もあり,ゆっくりですが順調に進んでおります。

詳細なご案内ができるまで,今しばらくお待ちくださいませ。