これを読んだお前はCyberpunkに到達し、ナイトシティに火をつける。

はじめに

『2077年の犯罪の定義とは、捕まる事さ。』

キアヌ・リーブスが悪びれもせずにこう言い放つ。

その瞬間、死んで冷たくなっていた<FLAT-LINED>俺の心臓は、AEDによるインパクトをもらった時のように飛び起きた。

そう、去る2.0.2.0.・・・

サイバーパンクの歴史を塗り替える伝説のサイバーパンク「Cyberpunk2077」がとうとう発売されたこの年、世界中の千葉シティが歓喜の渦に包まれたという。

www.spike-chunsoft.co.jp

(うろ覚えで内容不正確かもしれないが、)確か2.0.1.3.にティーザームービーが発表され、2.0.1.8.に発売するつもりが延期になり、2年後の9月に発売するつもりが延期になり、その顛末が散々インターネットでいじられ倒された後、ようやくローンチを迎えたこの作品を心待ちにしていたコンピュータ・カウボーイは数知れない。少なくとも両手では数えきれないほどはいたはずだ。

俺も当然そんな中の一人で、このような自家製のサイバーパンクを作っては、満たされない心のキアヌを慰めていた。

しかし、Cyberpunk2077の発売は成し遂げられ、全世界が熱狂した・・・

そして俺が勤める弊コーポ、つまりカヤック・・・

そこの後輩FUJISAWAは、喜びのあまり古都鎌倉をロボットレストランみたいにギラギラさせるなどして、爆発寸前の感情をインターネットにぶつけていたらしい。

ならばこの俺も、この記念的な瞬間に、祝杯としてのサイバーパンクを捧げる必要がある・・・

だからここにウェブ=ログを残す事にした、というわけだ。

自己紹介

...おっと、自己紹介が遅れたな。

私、クライアントワーク事業部でUnityエンジニアとして働かせて頂いております、井上宗汰と申します。弊社では社員を紹介するサイトがありますが、ここでの情報を元に所在地を特定されると電脳を灼かれる危険性がある為載せておりません。

あ、この記事は Tech KAYAC Advent Calendar 2020 23日目の記事です。

さて。

俺は何者にも縛られないアウトローになりたいし、硬派なハードボイルドでありたいと常に考えているが、だからと言ってほんとに前科者になるのはとても良くないことも知っている。

そこで、逮捕された時の写真っぽい映像が取れるARアプリの試作品を試作した。

実装はARFoundationのPeopleOcclusionを用いてUnityで行った。

こういうのはマグショットっていうらしい。

アメリカで捕まったらマグショットを撮る、ということをユージュアルサスペクツのDVDジャケで学び、最高にクールだと感じたので、コンソールを叩いてプログラミングした。(ちなみに背景画像は「いらすとや」さんでお借りした。いらすとやさんはなんでもあってとてもすごい。)

しかし、今のままだといささかサイバーパンクと呼ぶには物足りない。

そもそもサイバーパンクというものは、技術の発展は人類を明るい未来へ導くことはなく、

むしろ人間の退廃性を加速させ...

超絶圧倒的格差社会の闇が深まり...

そして何より必要なのは、赤とか青とかのライトで紫色に光る人間が鉄砲とか刀とかを持って大暴れする...

そういう合成調味料のようなアクの強さが、サイバーパンクと呼ばれるような作品に求められるのだ。

つまり、このアプリは『サイバーパンク色』に輝いていない...

今回のヤマは、この逮捕体験を赤とか青とかに光らせて、このコンテンツが持つサイバーパンク性を高める事に他ならない。

俺はコンソールを開き、プログラミングを頑張る事にした。

実装について

Unityを触ったことがある人なら恐らく知っていると思うが、UnityにはPostProcessingStackという、お手軽にブルームエフェクトや色調調整をかけることができるライブラリが存在している。大抵のことはデフォルトのColorGradingで事足りると思うが、今回はせっかくなので自作のエフェクトを作って使えるような手順を踏んで、実際に使ってみる。

PPSそのものの基本的な使い方に関してはスコープ外とするので割愛する。マニュアルで紹介されてるGrayscale.csとGrayscale.shaderを踏襲しつつ、

docs.unity3d.com

作成した用意したのはこの2つのファイル。

//Cyberpunk.cs(PostProcessEffectSettingsを継承している方の名前を使わないといけないので注意!!)

using System;
using UnityEngine;
using UnityEngine.Rendering.PostProcessing;


[Serializable]
[PostProcess(typeof(CyberpunkRenderer), PostProcessEvent.AfterStack, "Custom/Cyberpunk")]
public sealed class Cyberpunk : PostProcessEffectSettings
{
    [Range(1f, 10f), Tooltip("Cyberpunk Effect Intensity")]
    public FloatParameter speed = new FloatParameter { value = 1f };
}

public sealed class CyberpunkRenderer : PostProcessEffectRenderer<Cyberpunk>
{
    public override void Render(PostProcessRenderContext context)
    {
        var sheet = context.propertySheets.Get(Shader.Find("Hidden/Custom/Cyberpunk"));
        sheet.properties.SetFloat("_Speed", settings.speed);
        context.command.BlitFullscreenTriangle(context.source, context.destination, sheet, 0);
    }
}
//Cyberpunk.shader

Shader "Hidden/Custom/Cyberpunk"
{
    HLSLINCLUDE

        #include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"

        TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
        float _Speed;

        float4 Frag(VaryingsDefault i) : SV_Target
        {
            float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord);

            float displacementAmount = _SinTime.x * _CosTime.y * 0.3;
            color.rgb = color.rgb * float3(i.texcoord.x + displacementAmount, 0, i.texcoord.y + displacementAmount) * 1.2;
            return color;   
        }

    ENDHLSL

    SubShader
    {
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            HLSLPROGRAM

                #pragma vertex VertDefault
                #pragma fragment Frag

            ENDHLSL
        }
    }
}

Cyberpunk.csはPPSで自作シェーダーを使う為に必要なやつで、Cyberpunk.shaderは実際に赤とか青とかに光らせる為に必要な自作シェーダーだ。とりあえず、uv座標をRGBのRとBにぶち込むと画面がサイバーパンクになる事を俺は知っていたので、適当にゆらゆら揺れそうな変数(displacementAmount)を混ぜて適用してみた。

ここで注意点が2つある。

(参考にさせて頂いたのはこの記事様です。ありがとうございます。)

ssr-maguro.hatenablog.com

1つは、PPSの設定用csファイルを作成する時にはPostProcessEffectSettingsを継承した方のクラス名を使う必要があるという事。なんかマニュアルにそう書いてたので、俺はそうした。パンクな姿勢そのものはクールかもしれないが、無意味な逆張りは時間をいたずらに浪費するだけの愚策だ。

f:id:xabutoon:20201223082941p:plain

もう一つの注意点は、自作シェーダーをPlayerSettings/Graphics/AlwaysIncludedShaderに含めないと、ビルド時に反映されない、という事だ。もしくはResourcesフォルダを作ってそこに入れておく、という方法もあるが、俺は今回使ってないので実際動作がどうなるかはわからない。

f:id:xabutoon:20201223083336p:plain

以上の点を踏まえてファイルを作成すれば、

f:id:xabutoon:20201223083609p:plain

f:id:xabutoon:20201223083631p:plain

このようにPost-process Volumeコンポーネントから自作エフェクトを追加できるようになる。

ビルドしてみた結果が、これだ。

2077年のアメリカで逮捕されたような、ギラついた危なっかしさが演出され、俺はまさにサイバネティックなアウトローへと変貌を遂げた。昔ビューティコロシアムという番組があったが、俺はこのBefore/Afterをもって出場資格があると言えるだろう...

エピローグ

...2077年。資本主義の傀儡と化した警察に捕まった俺は、謎の人物が提供した莫大な保釈金によって留置所から放り出された。

呆け顔で空を見上げる俺の寸分先、ダダ漏れ縦ノリミュージックと共に、一台の車が停車した。

ドアが開き、現れたのは伝説のサイバーパンク、キアヌ・リーブスその人だった。

そう、例の保釈金を払ったのはこの男だ。俺をデカいヤマに誘う/もしくは捨て駒にする為に。

無法者としてのキャリアをスタートしたばかりの俺は、導かれるまま車の後部座席に乗り、ネオン煌びやかな闇の中へ溶けて消えた。

おしまい

え?UnityのWebGL書き出しでもリッチな表現を?

f:id:hara-makoto:20201221094641j:plain

できらぁっ!

この記事は Tech KAYAC Advent Calendar 2020 の22日目の記事です。

こんにちは、原です。 普段はクライアントワークチームでunityを使って色々インタラクティブなものを作ってる、2児の父です。

unityroom、いいよね

普段の仕事ではVRとかARとか、未来志向なものに近いことをやっているのですが

2児の父にもなりますと、もっと身近に体験できるジャンルのものづくりにも興味が湧いてきますね。

ということで、身近に体験できると言えばunityroom。

unityroom.com

ご存知の方も多いと思いますが、UnityからWebGL書き出しをしたファイルをアップロードすることで、即自分の作ったゲームを公開できる素晴らしいWebサービスです。 これを使えば、簡単に子供と一緒に自作ゲームで遊べる!

やれんのか!UnityWebGL

でも、unityのWebGL。錆びついた私の記憶の中では、unityのwebgl書き出しって、pcやモバイルのネイティブ書き出しに比べるとかなり表現が貧弱で、私が思い描く理想のゲーム世界を描けないんじゃないだろうか? 私は結構ぱっと見の表現にはこだわるタイプだよ?

そう思って試してみました。

こちらは、クリスマスツリーを育てるサンプルゲームです。

unityroom.com

池から水を汲んでツリーに与えると、育っていきます。ぜひ遊んでみてください。

ゲームの内容はともかくとして、見てくださいこの表現。明るいところにはブルームが効いてほわっとしていて、水のところはさざなみ立つような水面シェーダー。また、生える木が距離によってぼやけたりくっきりしたりしていますが、こちらはデプスオブフィールドが効いています。

f:id:hara-makoto:20201221095312j:plain

こういったポストエフェクトや特殊なシェーダーって、てっきりwebgl書き出しだとできないものだと思っていましたが、ばっちりできています。やるじゃんunity !!

webglでもリッチな表現ができるための機能「URP」

ただ、これをやるためには一つ条件があります。それはレンダリングパイプラインを「URP」にすること。スポットライト的な光にはこちらの有料アセットを使っていますが、これはURPに対応したエフェクトアセットです。 もともと私はamplify shader editorを使っていたんですが(昨年記事参照) こちらを使ってスタンダードなレンダリングでwebgl書き出しを試したところ、このシェーダーで作った箇所が真っピンク、つまりいつもの壊れ方をしてしまい、大変なことになりました。

ユニバーサルなレンダリングの時代がやってくる

ちなみに今回作ったこのミニゲームを試しにiOS向けに書き出ししてみたのですが、なんとこちらも全く同じ見た目が再現できました。(厳密にはちょっとバージョンが違うものの動画ですが)

URPとはユニバーサルレンダリングパイプラインの略称なんですが、まさにユニバーサル!どんなプラットフォームでも同じ見た目を再現できるすごい機能ですね。 こちらのURPは、将来的にはデフォルトのパイプラインに置き換わると言われています。つまり、本デモのように、web、モバイル、pcとプラットフォームを跨いでも見た目のクオリティが統一される時代がやってくるのです。

リッチな表現が技術的に可能でも、準備はそれなりにかかる

今回言いたかったことがもう終わってしまって尺が余ったので、今回デモを作成するにあたって踏んだプロセスについて書いておきます。

1. エモいシーンを思い浮かべる

エモいシーンって色々あると思います。自分の中で今回思い浮かんだのは、「暗闇の中で光が差し込んでいて、そこだけ植物とか生えてる」でした。

2. ざっくり下描きする

1で思い浮かべたシーンをざっくりと下描きします。自分はそんなに絵が描けないので、この段階ではそんなに詰めません。

f:id:hara-makoto:20201220074706j:plain
ざっくりすぎてやばい

3. 3Dに起こす

下描きをもとに3Dを起こします。この段階ではまだセットアップやUV展開はしません。 f:id:hara-makoto:20201220075227j:plain

4. 起こした3Dをスクショして、procreateで色検討する

3Dを一旦全部Unityに取り込んで、なんとなくライト配置だけします。 f:id:hara-makoto:20201220073728j:plain

で、それをスクリーンショットして、procreateに取り込んで色をつけます。 f:id:hara-makoto:20201220074150j:plain

この工程を踏んでおかないと、Unity上の色調整で迷子になってしまいます。

5. 3DをUV展開してテクスチャを塗る・Unityシーンのライティング、ポストエフェクト、色を調整する

ビジュアルの方向性が決まったので、あとは一気に仕上げの作業を進めます。 今回は島のまわりの水面がそうですが、単純に色を調整するだけではなくてシェーダーの実装も必要になるとここの工程がより大変になりますね。 また、3DモデルのUV展開・テクスチャ作成は手間がかかりつつ省略できない作業で、ひたすら地道に進めていく感じです。

6. 完成

5が全部終わったら完成です。 といってもこの工程はビジュアル面の工程だけ書いていますが、今回のサンプルはわずかながらもゲーム要素を入れています。 今回はビジュアル重視のサンプルなのでゲーム要素はボリュームは少ないですが、上記のビジュアルプロセスと並行してゲーム部分の検討・実装を進める感じだったので結構大変でした。

まとめ

UnityのWebGL書き出しでもリッチな表現は、、できる!

以上です。