標準体重達成!

こんにちわ、Pocolです。
相変わらずダイエットを頑張ってやっています。

本日の体重は58.9kgで,ついに58kgに突入しました!
上記の体重で分かるように標準体重以下になりました。
内臓脂肪レベルは6.5で,体脂肪率は15.3%,BMIは21.8です。筋肉量が前回よりもちょっと減り気味なのが,気になる点です。

まだ,ダイエット始めて2カ月は立っていないのですが,1カ月ちょっとでここまで削れたのは自分でも驚きですね。
基本的に,ダイエットの仕方はほとんど変わっていないですが,最近停滞期気味なので,仕方なくFitboxingでの運動量を増やしました。
朝・昼・晩と3回Dailyをこなす感じにしました。

血液検査の結果は次回の診察時に教えてもらえるそうで,次回の診察で,薬物治療をやめるかどうか判断しましょうかという話になりました。
今のところは,あまり体の方も問題なく調子いい感じです。夜中に突然目が覚めるのも無くなって,ぐっすり眠れています。

会社もそろそろリアル出社に切り替わるようで,飲み会等も増える気がしているので,何とかそれまでには治ってほしいなぁと思っています。

Bilateral Upsampling

こんにちわ,Pocolです。
今日はバイラテラルアップサンプリングについてメモをしておこうと思います。
パフォーマンスを稼ぐために,低解像度で描画しておき,それを元解像度に戻したいという場面が,ゲームグラフィックスでは多々出てきます。具体的には,SSAOやSSRなどの計算です。
ただ単にバイリニア補間で元解像度に戻してしまうとエッジ部分などでアーティファクトが発生してしまうことがあります。
こうしたアーティファクトを避けるために使われる手法の中の一つとして,Bilateral Upsamplingがあります。

通常のバイリニア補間は4点から計算を行います。

バイラテラルアップサンプリングは,法線と深度によってバイリニアウェイトを修正します。サンプルは以下のように,バイリニアの重み,法線の類似度による重み,深度の類似度による重みの3つによって重みづけされます。

バイリニアの重みは以下です。

法線の重みは次のように求めます。

深度の重みは次のように求めます。

以上から求められた重みを使ってサンプルを重みづけします。下図の通りです。

実装例ですが,もんしょさんが「DirectXの話 第121回 Bilateral Upsampling」の記事にてサンプルコードをアップしてくださっています。有難いです。
シェーダコードを抜粋すると下記の通りです。

float4 RenderUpsamplingPS( OutputVS inPixel ) : SV_TARGET
{
	const float2 kScreenSize = g_ScreenParam.xy * 2.0;
	const float2 kScreenHalfSize = g_ScreenParam.xy;
	const float4 kBilinearWeights[4] =
	{
		float4( 9.0/16.0, 3.0/16.0, 3.0/16.0, 1.0/16.0 ),
		float4( 3.0/16.0, 9.0/16.0, 1.0/16.0, 3.0/16.0 ),
		float4( 3.0/16.0, 1.0/16.0, 9.0/16.0, 3.0/16.0 ),
		float4( 1.0/16.0, 3.0/16.0, 3.0/16.0, 9.0/16.0 )
	};

	// Hi-Resピクセルのインデックスを求める
	int2 hiResUV = (int2)(inPixel.texCoord0 * kScreenSize + float2(0.1, 0.1));
	int hiResIndex = (1 - (hiResUV.y & 0x01)) * 2 + (1 - (hiResUV.x & 0x01));
	float4 hiResND = texNormalDepth.Load( int3(hiResUV, 0), int2(0, 0) );

	// Low-Resから4ピクセルの法線・深度を求める
	int2 lowResUV = (int2)(inPixel.texCoord0 * kScreenHalfSize.xy + float2(0.1, 0.1));
	float4 lowResND[4];
	float lowResAO[4];
	switch (hiResIndex)
	{
	case 0:
		lowResND[0] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, 0) );
		lowResND[1] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(1, 0) );
		lowResND[2] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, 1) );
		lowResND[3] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(1, 1) );
		lowResAO[0] = texHDAO.Load( int3(lowResUV, 0), int2(0, 0) ).r;
		lowResAO[1] = texHDAO.Load( int3(lowResUV, 0), int2(1, 0) ).r;
		lowResAO[2] = texHDAO.Load( int3(lowResUV, 0), int2(0, 1) ).r;
		lowResAO[3] = texHDAO.Load( int3(lowResUV, 0), int2(1, 1) ).r;
		break;
	case 1:
		lowResND[0] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(-1, 0) );
		lowResND[1] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, 0) );
		lowResND[2] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(-1, 1) );
		lowResND[3] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, 1) );
		lowResAO[0] = texHDAO.Load( int3(lowResUV, 0), int2(-1, 0) ).r;
		lowResAO[1] = texHDAO.Load( int3(lowResUV, 0), int2(0, 0) ).r;
		lowResAO[2] = texHDAO.Load( int3(lowResUV, 0), int2(-1, 1) ).r;
		lowResAO[3] = texHDAO.Load( int3(lowResUV, 0), int2(0, 1) ).r;
		break;
	case 2:
		lowResND[0] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, -1) );
		lowResND[1] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(1, -1) );
		lowResND[2] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, 0) );
		lowResND[3] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(1, 0) );
		lowResAO[0] = texHDAO.Load( int3(lowResUV, 0), int2(0, -1) ).r;
		lowResAO[1] = texHDAO.Load( int3(lowResUV, 0), int2(1, -1) ).r;
		lowResAO[2] = texHDAO.Load( int3(lowResUV, 0), int2(0, 0) ).r;
		lowResAO[3] = texHDAO.Load( int3(lowResUV, 0), int2(1, 0) ).r;
		break;
	case 3:
		lowResND[0] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(-1, -1) );
		lowResND[1] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, -1) );
		lowResND[2] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(-1, 0) );
		lowResND[3] = texHalfNormalDepth.Load( int3(lowResUV, 0), int2(0, 0) );
		lowResAO[0] = texHDAO.Load( int3(lowResUV, 0), int2(-1, -1) ).r;
		lowResAO[1] = texHDAO.Load( int3(lowResUV, 0), int2(0, -1) ).r;
		lowResAO[2] = texHDAO.Load( int3(lowResUV, 0), int2(-1, 0) ).r;
		lowResAO[3] = texHDAO.Load( int3(lowResUV, 0), int2(0, 0) ).r;
		break;
	}

	// 法線のウェイトを求める
	float totalWeight = 0.0;
	float ao = 0.0;
	for( int i = 0; i < 4; ++i )
	{
		// 法線のウェイトを求める
		float normalWeight = dot( lowResND[i].xyz, hiResND.xyz );
		normalWeight = pow( saturate(normalWeight), 32.0 );

		// 深度のウェイトを求める
		float depthDiff = hiResND.w - lowResND[i].w;
		float depthWeight = 1.0 / (1.0 + abs(depthDiff));

		// 総合する
		float weight = normalWeight * depthWeight * kBilinearWeights[hiResIndex][i];
		totalWeight += weight;
		ao += lowResAO[i] * weight;
	}

	ao /= totalWeight;

	return float4(ao, ao, ao, 1);
}

…ということで,Bilateral Upsamplingの話でした。
もしかしたら,Quad系のWaveIntrinsics使って実装した方がナウいかもしれないですね(※試してないので,出来なかったらごめんなさい)。

※追記
Quad Intrinsics使って実装できました。
WaveGetLaneIndex() % 4でhiResIndexを算出します。一度現在位置での,lowResNDとlowResAOを先頭の方でサンプリングしておき,あとはループでQuadReadLaneAt(lowResND, i)と QuadReadLaneAt(lowResAO, i)で,処理対象を持ってきます。これでswitchケース分が丸っとなくせるのと,テクスチャフェッチ回数が減らせます。

減量継続中。

こんにちわ,Pocolです。

引き続き頑張って内臓脂肪を減らすためにダイエット中です。
今日体重を測ったら,62.4kgでした。前回投稿時が64.5kgなので10日で2kg減量したことになります。
これで,ダイエット始めてから1カ月以内に6kgの減量に成功したことになります。

2kgやせるのも5日ほど短縮しています。
ここ最近変化したことといえば,Fitboxingでの運動量を増やして,平均590kcal程度になるようにしたこと。8時間ダイエット法を取り入れるようにしたことですかね。
8時間ダイエット法のほうはあんまり効いている感じしないのですが,食事をとる時間が圧縮されて,自由に使える時間が増えるというメリットがあるので,効果は出なくとも減量中は一応続けていこうかと思います。

タニタの体組成計で,体重や基礎代謝等を毎日図っているのですが,今のところ筋力量も基礎代謝量も減らずに体重減っているので,いい感じです。
内臓脂肪レベルも8.5まで減り,ようやく標準の範囲に入ってきました。体脂肪率も減ってきて,18%とかそのあたりの数値になってきて,ギリギリ肥満ではないレベルに入りました。

数日後に病院に診察してもらいに行こうかなって思っているので,どういう結果になっているか,期待半分不安半分という感じです。

GDC 2023関連

こんにちわ、Pocolです。
GDC 2023関連の情報をまとめていなかったので,(FreeContentsで)興味ある資料をまとめておこうと思います。

成果が出てきた!

こんにちわ。
Pocolです。

引き続き,減量を頑張っています。
今日入浴前に体重を測ったら64.5kgでした。
前回投稿が4/21なので,15日経過で 66.8kg – 64.5kg = 2.3kg 減量しています。
着実にですが,効果が出ています。
今のところ1週間で1kgぐらいのペースですね。

前回投稿から気づいた点としては,無理に食事制限するとマジでヤバいということを体験しました。
まず,朝起きたら手足が何か痺れるのと,手などの皮膚が異様にボロボロになるという状態で,流石にダイエット完了する前に死んでしまう!と感じました。
で,ネットでも色々と調べてみるとあまりに食事制限してしまうと,体がヤバいと感じてしまいエネルギーを蓄えてしまう体になってしまい,痩せずらい身体になってしまうそうです。
あとは皮膚がボロボロになるのも必要な栄養素が不足している現象の様です。

…ということで,まずは栄養素の偏りを是正するために,ドラッグストアに駆け込みマルチビタミンとマルチミネラルを購入してきました。
これで最低限必要なビタミンとミネラルは補給できるはず。
次に,痩せずらい身体になってしまうのを回避するために,1週間に1回食事制限をしない普通の食生活にするということを行いました。
いつもよりも数百kcal多いですが,それでも多分一般的なの人がダイエットで摂取するぐらいで,十分少ないです。
後は,無理な食事制限はツライということも分かったので,野菜中心の食生活にしました。コンビニのサラダでちょっと頑張ろうかと思ったのですが,調べてみると意外とカロリーが高い。ご飯1杯ぐらいあるものも存在する(しかも,これまで好んで食べていたやつがそうだった)ので,季節感に全然合わないですが,鍋料理を昼夜と食べています。
意外と満腹感がありますが,ほとんど体重には悪い影響は出ていないというのも良い点です。今のところは,赤からの鍋と,バズレシピの脂肪燃焼塩スープを作って食べています。
これで,大分安心した生活が出来るようになりました。

また,Fitboxingも減量のために開始したのですが,1日の消費カロリーを300kcalを目安に動くようにしています。
これが,結構いい感じに効いていて,食事制限のみだと体重が減らない状態だったのですが,また順調に減るようになってきています。
35分のデイリーをやった後に,フリーで300kcalになるように調整という感じです。
普段運動を全くしない状態で,全部ぶっ通しでやるとツラいので,休憩を挟みながらやっています。
GWで実家に帰っていたのですが,昼と夜にそれぞれFitboxingやるようにすれば,意外と大変な思いをせずに続けられそうということが分かりました。

何とかこの調子で,残り5kgを頑張って減量していきたいです。

減量開始。

こんにちわ、Pocolです。
みなさん、元気にお過ごしですか?

私は,つい2日前に健康診断の2次検診で脂質異常症の検査にひっかかってしまい。
「脂肪肝ですね。」とお医者に言われてしまいました。
「このままだと肝硬変になります。血管中にプラークがたまり心筋梗塞になる恐れもあります。」

我が家は,父親が脳梗塞と心筋梗塞のどちらもなったことがあり,どうなってしまうのかというのは間近で見ていたので,『マジでこのままだと死ぬ』という生命の危機感を覚えて,本格的に減量を開始することにしました。
主に不健康の原因は内臓脂肪がついてしまっていることにあるそうで,減量をして内臓脂肪を減らさないと数値は正常にならないと診察で教えてもらいました。
正月の時点で,72.4kg程度体重がありました。流石にヤバいと思い,少しずつ食事量を減らして診察時点の朝の体重が,68kg。
4kgはダイエットに成功しているのですが,残念ながらこれは最初の健康診断時(昨年の10月時点)の体重に戻ったに過ぎません。
ここから標準体重の59.8kgを目指して,9kg削る必要があります。
なんともハードですが,削らないと死ぬだけなので,やらないという選択肢は既に消滅している。

ここ2週間ほど前から断酒を初めて,1週間ほど前からカロリー制限と糖質制限を始めました。
徐々に効果が表れ始めていて,今日お風呂上りに測ったら66.8kgでようやく66kg台に突入して,残り7kgです。

減量し始めて気づいたのですが,プロファイルして大きく削れそうなところから削っていくというやり方が,どことなくプログラムの最適化に似ています。
そんなわけで,ちょこちょこダイエット日記を書いていこうかなって思っています。

道徳の授業

こんにちわ、Pocolです。
今日は私が最近取り組んでいる内容の一つをご紹介しようと思います。

私が小学生ぐらいの頃に,学校の授業で「道徳」という科目があったのですが,自分は結構話の内容が面白くて好きだったなーとふと思い出しまして,こういうのってあんまり会社では教育してくれないよなって思って,実験的にちょっとやってみようかと思って最近新人さんを捕まえて勝手にやってます。
当然、自分の昔話しても単なる「老害」になってしまうし,全く意味が無いし,自分だったら「お前の話聞いても面白くないよ」と思ってしまうので,これはダメ。
また,よく社会人になりたての頃にやる研修とかでやるような内容をやっても,対して業務に役に立たないことが多いので,違う内容をやろうと思いました。
…で,色々と考えて面白く学べる内容かつ業務内容にも効きそうな内容をやると良いんじゃないかと。毎年CEDECとかで基調講演とかやってますけど,自分はああいうのが結構面白くて好きな人間でして,ガイアの夜明けとかカンブリア宮殿,がっちりマンデーとかが好きなので,そういうテイストの動画を見てもらって,実績ある人から開発で心がけたこととか,作る際に気を付けたこと,どうやってアイデアが出てきたか?などを知ってほしいなと思って,最近色々と動画を漁って,その動画を見て気づきを得てもらう。
…というようなことをやっています。

初回にやったのは,任天堂の山内溥さんの話を見てもらいました。
NHKアーカイブス あの人に会いたい File.494 山内溥

結構色々と面白い話があって,その中の一つに

今まで過去に売れた そういうゲームのいいところだけを取ってきてね
面白い箇所だけ寄せ集めてきてね
それでまとめてしまう
ということをやる人もいますけど
そんなことをしてもユーザーは知っているわけですよ
ユーザーが求めているのは独創的な楽しさ面白さをもとめているわけです 絶えず

という言葉があって,「確かになぁ!」と自分は思いました。
自分がユーザーだとしたら一度見せられたものを見ても新鮮さは無いわけです。もっと言えば,飽きちゃう。飽きちゃうから面白くない。

あと面白いと思ったのは,次のような話もありました。

大衆が買える価格でないと広がらないんですよ
16であろうと32ビットであろうと64ビットであろうとユーザーは関係がないんです ユーザーは
ゲームというのはインタラクティブで遊んで楽しい面白いものなんです
映像がすごい 音声がすごいと言ったって
遊んだら全然面白くも楽しくもなかったら
ユーザーはどうするんですか こんなもん

買いません ユーザーは絶対に。

…まぁ、ものすごく当たり前のことを言っていますよね。
でも,正直なところ開発する際に,こういう当たり前のことを忘れてしまっているな,と自分は気づかされました。

こういう動画を見て感じることは人それぞれ違うと思うんです。
それを動画を見た後に感想会みたいな感じで言い合って,共有するということをやっています。
ただ,動画見るだけども面白いですけども,人それぞれ解釈の仕方のも違うので,色々な新しい考え方も取り込めて面白いんじゃないかと思ってやっています。

この「道徳の授業」がどういう効果をもたらすかは未知ですが…
少なくとも,人が何を面白いと思って開発しているのか,どういう思いを持って開発しているのかについては「知らない」よりは「知っていた方がよいことがある」という信念をもってやっていますし,単純に自分が面白いというものを推し活しているだけなのですが,今後何かいいことがあるといいなとワクワクしながら取り組んでいます。
何か良いことが起こったら,皆さんにも共有したいと思います。

Character Rendering 研究メモ

私的な研究メモです。

以前からどうも眼球がリアルに見えなくて困っています。
特に困っている点としては,

  • 眼球としての丸みが分かるライティングが出来ていない
  • 透明感のあるライティングが出来ていない

という2点です。

透明感のあるライティングについては,一応アイデアがあって下記の画像を参照。上側が元絵で,下側が加工画になっています。

何が変わったかというとGimpでガウスブラーがかかっているだけです。
このことから,テクスチャがはっきり見えすぎてしまうとCGっぽくなることが分かるので,虹彩部分に対してもSSSブラーを適用した方がよさそうな感じ。
過去試したことはあるのですが,皮膚と同じSSSプロファイルを適用してしまうと赤味がかってしまうので,SSSプロファイルのパラメータは別途設定した方がよさそう。
ゼリー状っぽいパラメータを設定するのが感覚的にはよさそう。

次に,皮膚のライティングについて。
上記の実写をみると,鼻の頭のあたりや頬骨,あごのあたりや下唇のスペキュラーハイライトの出方が特徴的で,CG側だとうまくそれが再現できていない。
鼻のあたりは,実写の方は結構鋭く光っているが,CG側は結構鈍い感じに出ている。一方,下唇やあごの部分は実写側は柔らかく出ているのに対して,CG側はきつく出すぎているので,スペキュラーのBRDFは見直しした方がよさそう。
ライティングはももう少しGI的な要素が載らないと実写に近づかない気がする。下あご側面からエラにかけての光の出方に違いが見て取る。


このラフネスに対して,Toksvigで法線から作成したラフネスを加えている。

眼球中心だが,人間は非対称で中心に寄りやすいという統計結果がでているらしく,それを再現するためかKappa angleというものが実装されている。

噂によるととあるステルスアクションゲームでもそうなるようにモデリングされていたとかされていないとか。

今年のGDCでCallist ProtocolのCharacter Renderingについてのプレゼンがあるようなので,あとで要チェック。
https://schedule.gdconf.com/session/the-character-rendering-art-of-the-callisto-protocol/893232