今年も大晦日になりました。今まで一年を振り返るというのをやったことが無かったのですが(振り返れるものが無かったともいう)今年はいろいろあったので、RIZINを見ながら軽く振り返ります。2018年まで2018年は就職して3年目でした。基本的には仕事以外でプログラムを書くようなことは無かった上に、この時は、スマートフォンゲームにハマっており、twitterは課金の報告用になっていました。2018に向けてメガデモを製作するための技術を勉強し始めました。これを起点に情報発信や作品の制作を行うようになって、2019年に繋がったと思います。2019年シェーダー芸の投稿2018年の12月から今年の9月までコンスタントに月一個以上はShadertoyやNEORTにシェーダー芸を投稿しました。本当は12月までの一年間続けたかったんですが、仕事やその他のイベントなどで作る時間を捻出できなくなってしまいできませんでした。三日坊主で有名な僕が10か月以上も継続できたことが自分でも驚きなので、ポジティブにとらえていきたいです。NEORTに投稿していた作品の一つが渋谷駅に展示されました。継続的に投稿を行っていないとこのような素晴らしい機会を得ることは絶対にできなかったと思います。登壇等2件やりました。6月に「UnityエンジニアによるShader勉強会!登壇」でなぜかライブコーディングに関する発表を行い、終了後の懇親会では20分のライブコーディングの実演を行い場を盛り上げることができたと思います。11月にWebGL総本山のdoxas氏が主宰する「GLSLスクール2019」でレイマーチングによるシェーダーアートの制作例とテクニックについて1時間の講義を行いました。Twitterを今のように活用する前からこのスクールを知っていたので、呼んでいただいて本当に光栄でした。記事の投稿Unityやシェーダーに関する記事をいくつか書きました。いろんな人に見てもらいたいものはQiita、雑なメモや個人的なものはブログに書くように使い分けていました。いずれもたくさんの方に見て頂けて嬉しかったです。これから今年は自分の情報を外に出すようにしたからか、新しい出会いがたくさんありました。仕事でもいい方向にいろいろと環境が変わった年でもありました。来年からもマイペースに作りたいものを作って、やりたいことを勉強する年にしていきたいです。メガデモサムネ用はじめに毎月やっている月毎に制作したシェーダーの紹介第8回目です。今月はShadertoyで一つシェーダーを作ったので簡単な解説をします。2019インスピレーション9月頭あたりにこのシェーダーを見て、金色のケージっぽいオブジェクトかっこいいなと思ったので今回登場させました。www.shadertoy.comまた以前からパイプをエネルギーが伝っているようなシーンを作ってみたかったので合わせて今回のシェーダーになりました。形状ケージの形状はトーラスをpmodで二重に複製しています。MAT_CAGE);}ステージのモデリングには例に漏れず、Mercuryのhg_sdfを活用させていただいています。使用して、元のステージとboxを組み合わせて這うパイプを表現しています。kbデモを意識してコンパクトでそれなりの見た目になる物を用意して使っています。Diffuseに正規化Lambert、Specularに正規化BlinPhongを使用したもので、反射率はフレネルを考慮した方が良い結果になりますが、マテリアル毎に一定としています。(len*len);}今まで、複数回のリフレクションに対応するシェーダーを書いたことが無かったので、今回はそれに対応しました。シェーダー内では再帰関数を利用できないので、依存関係にならないように処理を小さい粒度で関数化して、レンダリングの後方でトレースをループすることで実現しました。(ACES)さいごに来月はGLSLスクールがあるので頑張って資料作ります!10月は何を作るかまだ未定ですが、もし何か作ったら紹介します。06:022019年9月のシェーダーを紹介するTweet広告を非表示にするコメントを書くもっと読む2019-08-312019年8月の成果物を紹介するサムネ用はじめに毎月やっている月毎に制作したシェーダーの紹介第7回目です。今月はShadertoyでシェーダーを書きませんでしたが、最近触り始めたUnityのさらにHDRPで色々やっていたので紹介します!新幹線でライブコーディング会社の出張で大阪に向かった時にライブコーディングをやりました。2019以前Shadertoyでトンネルを二つ組み合わせた面白い表現を見たので、ボリュームライトと組み合わせてライブコーディングでやってみました。20198月上旬から中旬はずっとこれをやっていました。凄い人が作ったであろうHDRPを実際に触って改造してみることで色々な知見を得られるのではないかという作戦で進めました。実際に今まで知らなかった手法やテクニックがたくさん使われており大変勉強になっております!HDRPのキャッチアップまず手始めにHDRPを改造できる環境を整えました。以下にその時のメモが残っています。nanka.hateblo.jpまた改造の練習にHDRPにレンダリングパスを追加してアウトラインを描画するということもやりました。2019レイマーチングHDRPでレイマーチングをするというのが今月の目標でした。HDRPの改造方法も大体わかってきたのでこの辺りから詩作を始めました。2019レンダリングパスを追加できるようにしておく等入念に準備していましたが、意外とHDRP側の修正は少なく済みました。2019この辺りからはHDRPの素敵なライティングでスクショを取るのが楽しすぎて、作業よりもスクショを取ってる時間の方が長かったです。2019そして完成したものがこちらです。2019この時に得た知見等はこちらの記事で解説しています。HDRPを触っていろいろやりたいなと考えています。10月に@h_doxas氏主催のGLSLスクールでプラスワン講義を担当することになったので、来月はそちらの資料作りに時間を取りたいとも考えています!webgl.souhonzan.org来月ももし何か作ったら紹介します。6.9.0-preview今回作ったプロジェクトはこちらのリポジトリで公開しています!もしかしたらHDRPでカスタムシェーダーを作るときに何かの足しになるかもしれないです!!github.com仕組みまずどうやってUnityの世界にレイマーチングオブジェクトを表示するのかの仕組みを簡単に説明します。3Dではフォワードやディファードレンダリングという言葉をよく聞くと思います。HDRPではディファードをさらに発展させたものをハイブリットに使用してレンダリングしています。ディファードレンダリングでは、GBufferと呼ばれるライティングに必要な情報を収集するパスと、そのGBufferを利用して実際にライティングを行うパスに分かれて世界を表現します。今回はこのGBufferを生成するパスにレイマーチングによる情報で上書きすることで、ライティングをHDRPの強力なライティングソリューションにお任せするということをしています。Unityでレイマーチングをするのは偉大な先駆者の方々がいらっしゃるので、詳しくはそちらの方々の解説を参照してください。この記事ではHDRPでレイマーチングするにあたっての知識にフォーカスします。i-saint.hatenablog.comtips.hecomi.comgam0022.netレイマーチング用シェーダーファイルの構成レイマーチングオブジェクトのマテリアルは、以下の6つのユーザーシェーダーで構成されます。GBufferパスHDRPではマテリアルタイプ毎にGBufferに格納する内容が異なるっぽい(GBuffer0.aとGBuffer2が異なるみたい)ですが、今回のレイマーチングはHDRPのStandardマテリアルのみで描画しています。(今後別マテリアルにも対応したいです)シェーダー内のコメントによると、特に追加設定の無いStandardマテリアルのGBufferの内容は以下のようになっています。(バージョンアップで変わる可能性もあります)最終的にこのフォーマットでレンダリングすればHDRPの強力なライティングソリューションで描画してくれます!既存のLit.shaderで使用されているShaderPassGBuffer.hlslのGBufferパスを覗いてみると、こちらの一行でGBufferに情報を書き込んでいました。outGBuffer);このインターフェースに乗っ取って、SurfaceDataとBuiltinDataをレイマーチングで生成できれば上手くGBufferに情報を書き込むことが出来そうです。GBufferパスでレイマーチングを行うように改造するこのプロジェクトでは3つのレイマーチングオブジェクトがありますが、その中のMengerEmitを例に解説します。GBufferパスのフラグメントシェーダーでレイマーチングを行いたいので、該当の処理を見てみます。HDRPのシェーダーは各処理毎にシェーダーファイルが分かれていて、includeを差し替えることでいろいろなパスに切り替えれるようになっています。GBufferのフラグメントシェーダーも実際は.shaderファイルには無くて、ShaderPassGBuffer.hlslに切り出されています。このhlslファイルを丸々コピーしてレイマーチング用のGBufferパスにカスタマイズしていきます。GBufferパス改造の本質と言える部分は以下の箇所です。outGBuffer);上記のコードを一つずつ解説していきます。今回は球を描画する際にレイマーチングを行うので、本来ならばカメラのワールド座標をRayOriginに、カメラ位置からフラグメントの位置へのベクトルをRayDirectionにするはずです。私は今回以下のように実装しました。GetRayOrigin(input.positionRWS);RayOriginが原点...?なんだこれは?と思いますよね...実はHDRPではカメラの平行移動による座標値の精度低下を抑えるために、MVP行列のMに当たるモデル変換行列の位置成分から既にカメラ座標が差し引かれています。カメラ空間レンダリングというらしいです。normalizeするだけで求めることができます。カメラ空間レンダリングを行わないとどうなるのかと言ったことはこちらの記事で詳しく解説してくれています。(こちらはレイトレーサーの話なので少し文脈が異なりそうですが...)pharr.org実際にHDRPではどういう理由で採用されて、どう動いているかはこちらのHDRPのマニュアルに記載されています。outGBuffer);座標変換等少し特殊なことをしていますが、いつものようにスフィアトレーシングをしてサーフェースデータを計算します。HDRPのライティングに必要なデータに変換します。関数の中身はこのようになっています。必要で、既存のGBufferパスもこの二つを計算する処理が書かれています。GI等HDRPの仕組みに依存したデータが必要です。等の情報を使って取得してくれるのでそちらにお任せします。Emissiveのみ取得後に上書きする必要があるので注意です。この関数を拡張すれば、SSSマテリアル等にも対応できるのではないかと思っているので今後検証していきたいです。用いてGBufferに書き込みます。レイマーチングオブジェクトの深度で上書きするこのままだとポリゴンの形状のままの深度値で計算されてしまうので、レイマーチングによって計算された深度で上書きします。今回レイマーチングをHDRPで動かすにあたってHDRP本体に二行ほどの修正を行いました。cullingResults);具体的に言うとGBufferパスの後にD(ecal)Bufferパスを描画するようにしました。このような変更を加えたかというと、デプステクスチャのコピーのタイミングに関係があります。HDRenderPipeline.csを除くとデプステクスチャーがコピーされる可能性があるタイミングが以下の二か所にあります。DBufferパスの直前GBufferパスの直後Decalは設定によってON/OFFを切り替えれるため、DBufferパスを実行する場合はその直前に、しなかった場合はGBufferパスの直後にデプステクスチャーがコピーされるという実装になっているようです。このままだと何が問題かというと、Decalが有効の場合、GBufferパスの前に既にデプステクスチャがコピーされてしまっているので、レイマーチングで上書きした深度がその後のパスに反映されないという状態になります。カスタム無しカスタム有りこのように前後関係がめちゃくちゃになります。そのため、GBufferによる深度をコピー前に上書きするために、このような変更を加えました。この時3つの解決策を思いつきましたが、結局GとDBufferの順番を入れ替えるという方法で解決することにしました。Passでもレイマーチングを行って正しい深度を計算するメリットHDRP本体に変更を加える必要がないためクリーンに解決できるデメリット追加のレイマーチングが必要なため負荷が非常に高い➂DBuffer前とGBuffer後、どちらもデプスをコピーするように変更するメリット追加のレイマーチングをするのに比べてテクスチャのコピーなので負荷が少ないデメリットHDRP側の変更が入れ替えるものより少し多い入れ替えるものに比べて少し負荷が高い今回は1の入れ替える方法を採用しましたが、個人的には負荷や正確性を考えて➂が良いのかなと思います。さいごに筆が遅すぎて、このプロジェクトを作ってから結構時間が空いてしまいましたが、ここまでの情報でHDRP上でレイマーチングできます!HDRPのカスタムシェーダーを手書きするのはあまり賢い手段ではないのですが、何かの足しになれば幸いです。影とモーションベクターのパスの解説ができていないので、来月ぐらいにはそちらも書きたいです。unityHDRPを弄れる環境はこちらで既に整えましたnanka.hateblo.jp今回は実際にカスタマイズして周作に最適なアウトラインパスを追加してみます。6.9.0-preview今回のプロジェクトはこちらです。github.comLit.shaderをカスタマイズしてアウトラインパスを追加する大元となるのはHDRPのLit.shaderなので丸々コピーしてきてアウトラインパスを追加しましょう。いくつかのパスが既に記述されているので、それを参考にアウトラインを描画するパスを追加します。記述されていそうな感じがします。少なくともパスを追加して呼び出すということがしたいだけであれば、ここを起点に読み進めればできそうです!https://github.com/Unity-Technologies/ScriptableRenderPipeline/blob/6.9.0-preview/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDRenderPipeline.csというわけでOutlineを呼び出す処理を書いていきます。今回はアウトラインということなので、DefferdやForwardのライティング処理が終わってから実行したいです。空描画の次あたりに差し込んでみます。cmd);RenderOutlineを実装する差し込みましたが実装がまだないのでその他のRender関数を参考に作ります。}}CustomSamplerIdとHDShaderPassNamesにOutlineを追加RenderOutlineで使用する変数等を追加します。パス名の文字列とIDを追加します。ShaderTagId(s_DepthOnlyStr);動作確認これでアウトラインパスが動作するHDRPとシェーダーの準備ができたので、作成したシェーダーをアサインしたマテリアルをメッシュに割り当てて動作確認します。問題なく動作していそうです!単純なパスなら意外とさっくりと追加できました、もっと良い方法や考慮すべきことが残っていそうな気がするので何か情報をお持ちの方は是非教えていただきたいです。unityカスタマイズするか不明ですが、UPMでインストールしたパッケージはカスタマイズしずらいので、公式リポジトリをforkした物を使うプロジェクトを準備しておく。フォークする後で使うのでHDRPが含まれているこちらのSRP公式リポジトリをforkする。github.comHDRPプロジェクト作る今回は最近正式リリースされたUnity2019.2.0f1を使用してHDRPプロジェクトを作る。Hub等でインストールしておく)この後forkしたSRPをサブモジュール設定するために、作ったプロジェクトは適当にgit管理しておく。覗いて使用しているHDRPのバージョンを確認しておく。プロジェクトでforkしたSRPを使用するためにサブモジュール設定をする。プロジェクトのディレクトリに移動して以下のコマンドで設定(kaneta1992の部分はそれぞれのユーザー名に合わせる。サブモジュール設定したディレクトリを設定する。シェーダーライブコーディングサムネ用はじめに毎月やっている月毎に制作したシェーダーの紹介第6回目です。今月は先月までと比べて忙しい時期だった(後先月頑張りすぎて燃え尽きていた...)ので、あまり活動できませんでしたがいくつかシェーダーを作ったので紹介します。7/3仕事から帰ってきて友人と通話している間にのんびりシェーダーライブコーディングの練習をしていてできたものです。Travelerに登場した物体と似たようなものを出そうという意思と、bloom表現をボリューメトリックにしようと考えてできました。一度のマーチングループで衝突判定とボリューム累積を行っているので、結構いい加減な見た目になっていますが、これはこれでありだと思ってます。会社の同僚にこちらのページを教えてもらい、インスパイアされて作り始めました。www.reddit.comGlow表現レイマーチングでGlow表現をする時はボリューム累積を行うのが一般的なので、今回も例に漏れずそのようにしています。自分が今までやっていたボリューム累積と異なるところとしてマーチ数は変更せずにシーンの深度を見てマーチ距離を決定するディザパターンを使用して見た目の情報量を増やすを取り入れてみました。ピクセル毎にマーチ距離が一定の特に工夫なしのボリューム累積ディザパターンあり深度からマーチ距離を決定する深度を見てマーチ距離を決定することで、距離が近い箇所のボリューム累積が正確になり何もしないよりかは良い見た目になったと思います。ディザパターンはこちらのShadertoyで実装されていたベイヤー配列というパターンを使わせていただきました。関する情報はiq氏のページがとても有名ですが、MERCURYというデモグループのこちらのページにもとても有益な距離関数の情報が載っています(こちらは主に距離関数同士の合成に関するメソッドが多数あります)mercury.sexyminによる合成fOpUnionStairsによる合成スパイクブラーブラーこのブラーをスパイクブラーと呼ぶか知りませんが、トゲトゲになるので僕はそのように読んでいます。実は全然特殊なことをしていなくて、スクリーン中央から放射状にノイズを作成してアニメーション変数iTimeのオフセットとして利用しています。帰宅直前、玄関の前あたりでブタジエン氏に誘われて2度目のVRChatライブコーディングをやりました!今回はなんと坪倉氏制作の4人ライブコーディングバトル特化の闘技場風のワールドで、私含めて4名のライブコーダーで二時間弱で同時にコーディングを実現できました!!世界初!VR内でライブコーディングバトルを行いました!マジでとんでもない空間だった...。当日の様子はこちらにアーカイブされています。www.youtube.com私はアイデアが思いつかないときは過去に見た映像などを再現しようと頑張る傾向にあります。コーディングが終わった後に、「元ネタを忘れてしまったがTwitterで見た映像を再現しようとした」という話をしたら、観覧者の一人だったfotfla氏が元ネタを知っていて、まさかの裏ライブコーディングで同じネタで作っていました...!先に言い訳をしておくと、これを書こうとしたら(大元ネタはKeijiroさんのやつ)まさかかねたさんとかぶった。2019年7月17日こんなこともあるのかと盛り上がっていました。さいごに7月も何とかシェーダーを作ることができました。3日坊主で有名な僕が、7ヵ月も続けられていることが今でも驚きです...(それだけシェーダーで遊ぶのは楽しい)最近はGLSLやシェーダーライブコーディングを始める人が多くて、TLを眺めるだけでもとても楽しいですし、VRChatというプラットフォームでみんなでワイワイシェーダーを書いてボイチャするという空間が楽しすぎました!8月は何を作るかまだ未定ですが、もし何か作ったら紹介します。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。