ムラサメ研究ブログ

主にゲームやプログラミングのログ

RenderTextureを使いレンダリング結果をTextureに保存する

レンダリング結果をテクスチャでほしい事ってありますよね

例えばレンダリング結果を鏡にうつしたり G-Bufferをファイルに保存したり

ってことで、RenderTextureを作り カメラにAttachし、レンダリング結果を取得します

まず RenderTextureをCreateします MultiRenderTarget機能があるので、最大8個まで取得できます

newでRenderTextureを作成しますが、幅、高さをピクセルサイズで指定し、ビット深度を指定します 幅、高さは2のn乗にしておきましょう

そして カメラにたいして SetTargetBuffersでアタッチします

なんとこれだけ。簡単ですね

    private RenderTexture[] _rt;
    public Camera cam;


    // Use this for initialization
    void Start() {
        _rt = new RenderTexture[8];
        for (int i=0; i< _rt.Length; i++)
        {
            _rt[i] = new RenderTexture(2048, 2048, 32);
        }

        cam.SetTargetBuffers(new RenderBuffer[8] { _rt[0].colorBuffer, _rt[1].colorBuffer, _rt[2].colorBuffer, _rt[3].colorBuffer
            , _rt[4].colorBuffer, _rt[5].colorBuffer , _rt[6].colorBuffer, _rt[7].colorBuffer}
            , _rt[0].depthBuffer);      
    }

2年前に開発したC++のリアルタイムゲームサーバ

はじめに

2年半ほどまえに、リアルタイム対戦ゲームの ソーシャルサーバとリアルタイムサーバの作成案件をもらった ソーシャルサーバは何度か作ったし余裕 リアルタイムサーバは、いわゆるMO的なゲームでロビーサーバを作ったり、レートでマッチングしたり、プレイヤーが落ちた時、復帰 と、考えることがいっぱいあったので 悩んだが 私なら何でも出来ると請けた

ソーシャルサーバはJavaPlayframeworkを使って問題なく設計したが リアルタイムサーバは C++で! という要望だった C++のりゆうは 速度が速い事と、運用会社が得意だからと

Windowsソケットとマルチスレッドを使った マルチスレッドパターンのライブラリをもらい 自由に使ってください との依頼だった

会社の資産をもらえ、それに沿って作れば簡単だし、責任もなすりつけられるので それでいこうと思ったが やはり 大量接続を考えると 非同期で行うほうが効率は良い それに もらったライブラリは、当然ながらデータアクセス部がMutexで同期をとり、明らかなボトルネックがあった そのため、ライブラリの提供は丁寧にお断りし Boost.ASIOで1から作る事にした

非同期I/Oを使うため、Mutexも不要。 明らかに高速で動く

現在の状況

半年ほどで私は開発を終わり、その後少し機能追加はしたものの、ゲーム側の不具合だらけで サーバを先にリリースして抜けた その後2年の歳月がながれ、いよいよクライアントの不具合も解消され リリースされた iphone無料ゲーム 最高20位と好調な滑り出しで そこそこアクセスがきているが ソーシャルサーバは Javaだけに速く、ほとんどスケールアウトもせず 安定稼働 リアルタイムサーバは なんと あまりにも速すぎて、MAXのピークがきても 負荷が0.0のままで変わらず 非常に安定しているとのこと

やはり C++で作ってよかった。予想では nodeで作った場合の100倍以上。PHPの5000倍ぐらいはパフォーマンス出ると思う

正直いうと、元から速かったので、最終的なチューニングも行ってないので、チューニングすれば3割以上は速くなると思うし 今作ると チューニングなしで3割速く作れると思う

設計

設計は リアルタイムサーバは余裕だった。 問題点は事前調査しきれないので、トライ&エラーだ ソーシャルサーバのほうはDB構成などあまり得意じゃないので 友達に作ってもらい、それを修正した

C10K問題というのがバズってたので、あくまで 非同期I/Oで処理することを考えた

非同期にはboost.asioを使用し、File I/Oや Redis その他のI/Oも非同期にした また、勉強もかねて C++11やboostを積極的に取り入れた

ルームへの復帰も簡単にできるよう、ルームの検索も高速になるよう、ルームリストとユーザーリスト作ってキャッシュさせる もちろん お互いの参照もあるのでWeakPtr使いつつ

非同期処理はコールバック地獄になるので、coroutineを使い簡略化した

当時 Earlangも気になっていたので、例外が起きたら例外を処理せず死ぬように作ったため、例外はシンプルになる もちろん 死ぬ前にルーム退出やAIへ自動的に変わるなど 後処理はあるけど 基本的に 何かエラーがあれば、コルーチンが死ぬという簡単な作りにした

その他、関数型言語ならい、参照透過性を意識して作った

苦労ポイント

ルーム

一番開発時に不具合が出た・・ 理由は shared_ptrを使い管理していたのだが 参照カウントが残ることが多かった プログラムのミスなんだけど、高速化のための List等に残っていたり・・ 逆にいえば Listからの消し忘れなどが shared_ptrを使っているために、簡単に発見できたといえる もし生ポインタ使っていれば、Listに無効なポインタが残って メモリリークをしていたかもしれない

タイムアウト

ASIOのタイムアウト処理が面倒だし、油断すると 無限に待ったりする タイムアウトの簡略化が課題

ほかプレイヤーの同期

例えば ゲームの開始など、全プレイヤーのOKの帰りを待つ必要があるが、そのあたりのSyncが難しい それに 麻雀ゲームという性質上、牌を切るごとに 全員の反応を待つ Syncが入る ので、それをライブラリ化したら 楽になった ただし 上記のタイムアウトと併用するので ややこしく・・ だが、このプロジェクトで最も頭を悩ませた問題だった・・・ 2週間ほど この部分で悩み、リアルに血を吐きかけた 逆に言えば ここをクリアしたらあとは力で勝負できたので楽だった

C#コードの移植

お客さんのC#コードの移植という作業があった が、お客さんのコードが Staticおじさんで、そのままでは複数プレイヤーに対応できないとか コードがあまりにも原始的だったり C#C++の違いだったり いろいろと苦労はしたけど 基本的には力業だった 逆に もっと苦労すると思っていたのだが、C++STLが予想以上に 高性能で、移植は楽だった

さいごに

WebサーバもC++で作ったし、C++は慣れた人が書くと、JavaC#で書くのと何も変わらない それでいて速度が100倍とか差が出るので 高速サーバには絶対おすすめ!

金額でいうとサーバコストが数十倍の単位で違ってくる

阿里山vs梨山

阿里山梨山。どちらも日本人には人気の 高級高山茶です 今回は2つの山の 青心烏龍種のお茶の飲み比べ

左 X-005阿里山  右 X-007 梨山 どちらも原価 100g1000円。日本だと30-50gで2500円ぐらい。 とっても高級なお茶です

見た目で違いがあります 阿里山のほうが少し焙煎が強いですね 茶葉の大きさは大体同じそう

淹れたときも一目瞭然 阿里山のほうが焙煎が強いため濃い水色です

味も当然 阿里山のほうが焙煎が強く香ばしい味 梨山のほうは 甘み旨みが強く緑茶に近い味わいです

どちらが好きかはお好みですが 梨山のほうがアイスには合いそうですね 7杯ぐらいまではおいしく飲めます

阿里山はだいたい標高1500メートルあたりでお茶が作られます 梨山はもう少し高く 1700メートル付近

梨山台中市の福壽のものです。梨山でも人気の茶園ですね 阿里山は嘉儀懸の樟樹湖。これも阿里山のなかでは最も有名な茶園ですね

青心烏龍、金萱茶 飲み比べ

はじめに

お茶好きです お抹茶、グリーンティー、紅茶なども好きですが 特に 中国茶が好きです その中でも特に、台湾ウーロン茶とプーアル茶が好き

原価屋

よく台湾や香港、中国でお土産にお茶を買ってきたり、日本のお茶屋さんで茶葉を買いますが 少量だと割高だし、もっと飲みたいときに飲めない 300g~とかで買うと、いろんな種類を飲みたいので飲みきれない ので、個人販売をしたいと思いました 飲みきれないぶんを個人販売したいなと。

ふつうは販売するときは利益率で計算します たとえば100g原価500円のお茶を原価率20%で販売したばあい 2500円です 原価5000円のお茶は 25000円 茶葉が高級になればなるほど 線形で金額が高くなるため 主に安い茶葉 あるいは、高級茶葉は少量ロットの販売になります

私は、お茶の葉の販売業をしたいわけではなく 自分で飲みたいお茶を飲んで、飲みきれないぶんを分けたいので 基本的には、珍しいお茶や高いお茶を出したい

ので、原価率では販売せず 原価+固定の手数料 という形にすれば たとえば原価500円の茶葉は2500円 原価5000円だと7000円 と、高い茶葉が割安で買えるはず

ってことで、茶葉の比較を

金萱烏龍茶(J-001)vs青心ウーロン茶(X-004)

どちらも100gあたり500円程度の同じランクのお茶

左が金萱、右が青心 茶葉の見た目は似ています

同じ量、同じ湯量、同じ温度で淹れたけど、見た目みても水色の違いがあります 青心のほうが明らかに濃い色をしています 焙煎も少し青心のほうが強いです

味のほうも明らかに違い 青心のほうが濃い、うまみの強い味です。一般的にナッツ臭といわれる香り うまみと強い甘み(中国では甜といいます)があります

金萱はさわやかな香り。ほんのり甘さ(甜)があります よくミルクの香りと言われます

OverwatchというかFPS初心者の夏休みの研究

最近のゲーム FPSなどが極端に下手なので練習開始してます

Overwatch

1年ほど前に発売されたFPSで今もそこそこ人数がいる 出来は素晴らしいらしい FPSというよりMOBAであるため、単純なプレイヤースキルではなく頭を使った戦術でも戦える ため、FPS初心者でも考えれば勝てるはず また、ヒーローごとのアンチがある

Splatoon

これも日本では人気だし練習に買ってもよかったと思うけどまだ手を出してない

実力

超下手なので練習

練習方針として、FPSの標準操作キャラのソルジャーをしばらく使ったが いまいちなので方針変更してみる

方針

苦手意識を持ったキャラを使ってみる 苦手キャラのアンチも使ってみる そういえば苦手キャラ=使い方のわからないキャラ である 今のとこ

以下苦手キャラ

ゲンジ

木の葉返しがうざい エイムできない ULT怖い

アンチ シンメトラ、ゴリラ、ザリア、トールビョン、メイ、ロードホッグ

ジャンクラット

跳弾する弾にあたってしまう つい近距離で殺して爆風に巻き込まれる 威力でかい ULT怖い

アンチ ファラ、ザリア

ハンゾー

スナイプ怖い ULT怖い

アンチ ゴリラ D.va

ウィドーメイカー

スナイプ怖い

アンチ ゴリラ

積みゲーム

社会人といえば積みゲーム!!

昔から積みゲーム多いよほんと! とりあえず Steamのサマーセールで3本買った。どうせ全部積みゲーになるんだろうね・・

ゲーム実況で食えるまでは 仕事がメインで積みゲー消化できないよ・・

f:id:murasame-labo:20170704195220p:plain

私は あまり積みゲー作らないようにしてる。あまりプレイする時間ないのわかってるし 仕事として必要な有名ゲームや、変わったものをプレイしてる

今積んでるゲームで有名なのだけ紹介

Age of Empires Collection

AoE 1,2,3,RoN,AoM と色々なものが入ってる。昔AoEにはお世話になったので 感謝の意味もこめて 買った RoNとか さすがCivチームが作っただけあって 酷いしおもろい AoMとかもいいね メインのAoCは文明も増えてるし あと何年遊べるんだ?このゲーム

Skyrim

昔はお前のようなゲーマーだったんだが、膝に矢をうけてしまってな・・・ これはマジでやると半永久的に遊べるから危険だ!!

AlanWake

あれ?ミスクリで買っちゃった

Assasin’s Creed

これ すっごくやりたかったんだ!

CS-GO

FPS練習に買ったけど難しいよ!!

DarkSouls III

早くプレイしたい

Dota2

この手のゲーム好きなんだけど、どっぷり時間かけて集中して勉強する必要あって 全然できない

Dungeons&Dragons

昔好きだったので 感謝の気持ち込めて

MetalGearSolid

はやくプレイしたい!!

Civilization V

いつも買っては プレイに困る奴。やっぱ買った

今回のサマーセールで買ったやつ

Potal2

凄い安いんだよ・・

Deathsmiles

ゴシックシューティング!! はよープレイしたい

Fallout4

有名だし、プレイしたい

UNITYのライト消したいの巻

まずデフォルト

UNITY-Chanと中野シスターズを表示してみる ライトはディレクショナルライトいれて ドーン

f:id:murasame-labo:20170704191808p:plain

ここからライトを消していきます

Directional Light OFF

f:id:murasame-labo:20170704191856p:plain

UNITYちゃんは真っ黒になったけど、中野シスターズも背景も光があります これは UNITYはデフォルトで少しAmbientが入っているからです

UNITYちゃんが真っ暗なのは、UNITYちゃんは DirectionalLight以外効かないからです

Ambient OFF

f:id:murasame-labo:20170704192036p:plain メニューの Window->Lighting->Setting

f:id:murasame-labo:20170704192102p:plain Intensity Multiple を0に

f:id:murasame-labo:20170704192425p:plain

キャラは真っ暗になった 背景がまだ明るいけど・・

完全に暗く

先ほどのLight Settingの

Skybox Materialをnoneにすると空がなくなる AmbientColorを黒にする EmvironmentReflections の Intensity Multipleも黒にする f:id:murasame-labo:20170704193308p:plain

カメラのBackgroundColorも黒にする

f:id:murasame-labo:20170704193316p:plain

漆黒が手に入りました!

テストでSpotLightつける

f:id:murasame-labo:20170704193542p:plain

ちゃんとライトも反映されてます UNITYちゃんは ディレクショナルライト以外反応しないのはきっと シェーダーのせいでしょう