特殊効果のレンダリングエラーを回避する方法は？

今回の主な話題：特殊効果のレンダリングエラー、Monoメモリリーク、ネットゲーム通信暗号化スキームの設計、ゲームで描画されたマップグリッド線の実現方法など。

---
###レンダリング
Q1: 私たちのプロジェクトでは、黒の特殊効果がテクスチャにレンダリングされる方法が濾過されました。その理由は何ですか？ または、この問題を解決できるマテリアルはありますか？
![1 .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/604e34ab-9cbb-c81e-d87d-806a98c49db5.png)

①
>レンダリングカメラに背景色の問題があります。RenderTextureを使用してUIを背景として加法マテリアルを正しく描画するには、特別な方法が必要です。
一般的な考え方は、RenderTextureのユーザーが一つのBlendをOne OneMinusSrcAlphaのマテリアルとして使用します。
カメラの背景色はRGB黒で、Alphaは0です。
Additiveと不透明なものは直接描くことができます（Additive Alphaが0の場合には直接添付しますが、不透明が1の場合には直接カバーします）。元のAlphaBlendマテリアルであるブレンドカラーもOneOneMinusSrcAlphaに変更され、RGBにAlphaが乗算されます（Alphaは独自のAlphaであるため、RenderTexture側はDstの色を正しく減衰します）。

②
>パーティクルエフェクトで使用されるシェーダーでColorMaskRGBが使用されているかどうかを確認します。これにより、Alphaチャネルの情報が書き込まれなくなります。

>**補足：**
前のプロジェクトでも同じ問題が発生し、問題主は返信を続けませんでした。Additiveマテリアルの問題であると思われます。同様の問題が発生した人が参照できるために、プロジェクトで発生した問題と解決策を記録しました。
1）Additiveマテリアルを使用しました。効果は問題主と同じで、濾過されました。
2）特殊効果制作の一部では、パーティクルテクスチャと不透明テクスチャを使用しています。表示したい部分は黒を採用し、背景と重ね合わせて半透明効果を示しています。これをRenderTextureにレンダリングの結果は、正方形になり、テクスチャが黒い部分は背景の色で示しています。

>実際、この2つの状況では、RenderTextureの透明度チャネル情報に問題があります。1番目の状況では、組み込みのAdditiveでColorMask RGBを使用してAlphaチャネル情報を濾過することです。通常、背景はRGBブラックで、Alphaは0なので、RenderTextureのAlphaチャネル情報は0であり、背景と混合されると濾過されます。2番目の状況では、透明度情報はありません。

>RenderTexture効果にレンダリングされた情報は正しくない状況に遭った場合は、EditorのAlphaチャネルモードでRenderTextureのAlphaチャネル情報をチェックして、Alpha情報の書き込みエラーが原因であるかどうかを確認できます。

>Alpha情報が間違って書かれていることを知っている場合、それを変更する方法は？

>1）特殊効果がカスタマイズしたShaderを使用してAlphaチャネル情報を書き込みます。特殊効果が１層だけ、背景はPGB黒Alpha０の場合には問題ありません。しかし、複数層の特殊効果がある場合は、RenderTextureの最後記録は最後のレンダリングの特殊効果が混合されたAlpha値であり、この値をUIと混合した結果は間違っています。

>2）上にある月松さんが言った通りに、RenderTextureをUIと混合する場合、Blend One OneMinusSrcAlpha、こうすればRenderTextureがレンダリングするものが実際にUIの背景に重ねられるように、背景もある程度混合することができます。この方法にも、計算上の違いがあります。特殊効果をレンダリングする通常のブレンド方法とは異なるため、テクスチャの色を調整して正しく表示する必要があります。

>3）レンダリングする特殊効果の後にパッチを追加し、UI背景を貼り付けて、特殊効果が背景と正しく混合され、レンダリングされたRenderTextureがUIの背景をカバーできるようにします。これも、私が前のプロジェクトで最後に採用したソリューションであります。

---
###ロジックコード
Q2: フレームワークはC#+ Luaです。私たちのUnityゲームはAndroid端末でますますジャム状況になります。いくつ問題を聞きたいです。
1）Textureオブジェクトを作成しましたが、引用はしません。Destroy関数をコールしていませんが、GCはコールを取り戻すことができますか？
2）AssetBundleで生成されたテクスチャオブジェクトは、Resources.unLoadを使用して正常にクリーンアップできますか？
3）エディタモード。コード内に1000個の新しいテクスチャオブジェクトを周期的に生成し、listも存在しますのに、Profilerに何も変更されていませんのはなぜですか？（エディターのMonoは常に増加していますが、生成した時にも激しく増加したことはありません、ゆっくりと増加しています）
4）ジャムの原因は、メモリが高いではありません。たくさんのオブジェクトが廃棄されておらず、まだUnityに存在して実行されているようです。

①
>回答は以下になります。

>1）テクスチャはGCに行わず、必ず手動で破棄する必要があります。
2）AssetBundle.Unloadを使用してください。
https://docs.unity3d.com/Manual/AssetBundles-Native.html
3）感じだけでは信用できないので、廃棄されていないものが占用しているのもメモリです。

②

>答えは次のようです。

>1）リソース類はGCに行いません。
2）AssetBundle.Unload
3）Profilerが記録したデータはMonoにあるため、Monoが増加し続けるのは正常です。
4）ジャムの場合には、Profilerで実行に時間がかかりすぎる関数を確認できます。

---
###レンダリング
Q3: T4MのShaderに基づいてあるプロジェクトのバージョンを作成しましたが、元のShaderは問題ありませんでしたのに、自分で作成したShaderには、Lightmapが正しくないという問題がありました。

XCodeの実機Profilerで、新作成したShaderのtexcoord0はtexcoord1がbind VBOにあるoffsetと同じであることが見つけられました。つまり、入力されたUVとLightmapUVのデータソースが同じであります。これに影響を与えるのはappdataのみと感じていますが、自分が作成したappdataも簡単です。

```ruby:
struct appdata_t4m
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
float2 lightmapUV : TEXCOORD1;
};
```
そして、strideも正しくないでした。私のappdataによると、データstrideは40（pos + normal + uv0 + uv1 = 4×3 + 4×3 + 4×2 + 4×2 = 40）であるはずですが、見ましたstrideは32だけです。

元のSurfaceバージョンのT4Mに戻す限り、問題はないので、動的ローディングやMeshの問題ではないと感じています。理由はわかりません。

①
>T4MのShaderはSurface Shaderであるはずです。自分でSurface Shaderを作成する場合、LightmapはUnityによって自動的に処理されます。VF Shaderを作成したい場合、T4MのShaderでVF Shaderを生成することをお勧めします。生成されたコードを見れば原因がわかるはずです。Unityのデフォルトの静的LightmapにTEXCOORD1が存在し、動的LightmapにTEXCOORD2が存在します。

②
>UnityのネイティブShaderから直接コピーすれば、

>```ruby:
#ifndef LIGHTMAP_OFF
o.lmap.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
#ifndef DYNAMICLIGHTMAP_OFF
o.lmap.zw = v.texcoord2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
#endif
#endif
```

③
>unity_LightmapSTやunity_DynamicLightmapSTなどのパラメーターの未使用が原因である可能性があります。

---
###レンダリング
Q4：逆水寒庭園のグリッド線を下図のように実現したい。LineRendererで線とGameObjectを一対一描画すると、コストが非常に大きくかかるように感じます。代わりに、自己作成のMeshを使用し、Shaderを使用してグリッド線を描画します。しかし、これら2つのソリューションには、非常に深刻な効果の問題があります。つまり、視野内遠所の線ははっきりしなくなります。カメラの画角が回転するとより厳重です。Unityで次のグリッド効果を実現するには、どのような方法を使用して良好な結果と低コストを実現できますか？
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/da47246c-8701-b755-d49f-88d51ac1f535.png)
>MeshRendererで2番目のマテリアルを追加してみることができます。 マテリアルは、Repeatサンプリングされた正方形Outlineテクスチャを使用し、UV拡大縮小率を調整してそれを解決します。

---
###ロジックコード
Q5: 以前のプロジェクトは簡単なXOR暗号化でしたが、次の新しいプロジェクトではこの部分を統合したいです。インターネットで見つけたほとんどのやり方は一般的なネットワーク通信暗号化スキームの設計であり、特にネットゲーム向けのカスタマイズはありません。みなさんはどうやって実現しますか？ここでの暗号化には、ネットワークメッセージング層のみが含まれ、クライアントとサーバー自体のセキュリティは含まれません（つまり、それらは安全であると仮定します）。

私の疑問は以下になります。

1）皆さんは暗号化を行いましたか？ どうして？
私たちは暗号化を行いましたが、「少なくとも暗号化を行います、平文はまだ適切ではありません。probufferなどのバイナリシリアル化スキームでもvalueを解析できます」という考え方があります。暗号化以外には、「クライアントは信頼できない」の原則に守られます。具体的なビジネス通信プ​​ロトコルの設計では、クライアントがどのような情報を送信しても、サーバーがだまされないことを保証します（自分に損失はなく、相手にメリットもありません）。

2）機密性について、「自己開発の暗号化アルゴリズム」が使用されていますか、それとも標準アルゴリズムですか？ どうして？

3）完全性について、保証はありますか？ どの方法を使用しましたか？ーー私たちはそれをしませんでした。

4）アンチリプレイについて、保証はありますか？ どの方法を使用しましたか？ーー私たちはそれをしませんでした。

現在の暗号化システムで一般的に使用されている方法は、次の図に示すとおりです。この方法に従いましたか？ どのコンポーネントを選択しましたか？ どのようなカスタマイズをしましたか？ どうして？
![3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/11da4c40-0b6a-14b1-506c-97cd06188bb7.png)

①
>問題主は関する内容をもう十分に了解したと思います〜私たちのプロジェクトについて少しお話しましょうが、私は主にクライアントに関する仕事を働いているので、プロトコル暗号化については特に詳しくないので、参考用情報のみを提供します。

>1）暗号化はもちろん必要です…「クライアントは信頼できない」という原則はビジネス層が準拠するものでありますが、この層は最初に人の原因でいくつかの極端な状況の不適切な考慮がつながります。あとは設計上に不具合な場合もあります。
そして私は個人的に、プロトコルの暗号化は不正プラグインの制作の難しさを増すことだと思います。暗号化なしでは、プロトコルは人々にまる見られ、抜け穴が見やすくなります。ロジック的な抜け穴がなくても、直接利益を生まない補助プラグインを作りやすいです。 したがって、プロトコル暗号化を行うことは基本的な専門的な品質だと思います。そうしないと、仲間に笑われ、人前に顔が青くなりやすいです（冗談）。

>2）標準アルゴリズムをお勧めします。 自社開発アルゴリズムは業界で証明された標準アルゴリズムより優れていないでしょう。

>3）完全性とアンチリプレイについては、プロジェクトの時間と余力次第で決めます。余裕があればやる方がいいです。

>プロトコル暗号化は、クライアントのチート防止機能に似ており、チーターたちに要求を引き上げます。パッケージをキャプチャできるので、チーターに対して、プロトコルデータはクライアントリソースと同じように簡単に手に入られます。ですから、ある程度の暗号化が必要だと思います。
どの程度に行うについては、コストを考慮次第です。たとえば、基本的なAES暗号化は、実際に70〜80％のチーターを除外できます。ただし、貴方のゲームをチートする商業的な利益は十分に大きい場合、当然により強い上級チーターは参加します。この場合、一般的な暗号化では不十分です。

>誰でもチーターに直面したくありませんが、誰かが貴方のゲームをチートしたとき、それは貴方のゲームがお金を稼いでいることを意味するかもしれません。

②
>ロジックはゲームサーバー上で実行され、BUGはなく、暗号化も必要ありません。 また、他の人がゲームのために補助ツールを開発することは、推奨または許可できることです。または、自有の補助ツールを持参したりします。
たとえば、当社のMMOでは、戦闘部分がサーバー上で実行されています、他の機能も議論する必要はありません。基本的に問題はなく、もうリリースされています。 大事なのはサーバーを検証することです！

---
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、**パフォーマンス分析**と**最適化ソリューション**及び**コンサルティングサービス**を提供している会社でございます。

UWA公式サイト：https://jp.uwa4d.com
UWA公式ブログ：https://blog.jp.uwa4d.com