//tips
//読みやすいコードについて
読みやすいコードは、判断と処理のロジックをメソッドで分離している、という記述に感心したので例を下記に記載する。
オブジェクト指向の考え方では、関連するデータとロジックはクラスでまとめ、コードの塊はメソッドとして抽出して独立させるのだが、その中でも大事な手法。
両方とも子供料金計算を行なっている。
悪い例
if(customerType.equals(“child”))
{
fee = baseFee * 0.5;
}
良い例
if(isChild())
{
fee = childFee();
}
private Boolean isChild() //子供であるかどうかの判断ロジック
{
return customerType.equals(“child”) ;
}
Private int childFee() //子供料金の計算ロジック
{
return baseFee * 0.5;
}
少しコードの記述量は多くなってしまうが、それ以上に視認性が増し、メンテナンス効率がよくなる。また、エラー部分の特定もしやすく、修正時の修正箇所も少なく抑えられる。
//バッチ処理について
描画の負荷を抑える手法として、バッチ処理がある。
バッチ処理とは、同じマテリアルを共有しているゲームオブジェクトをバッチとしてグループ化し、GPUが描画する際にある同じマテリアルのものを一度に描画する。
その際、オブジェクトのメッシュはOpenGLのVBO(vertex buffer object)へコンパイルされている。
このバッチ処理には静的なものと動的なものの2種類ある。
「Static Batching」の方は、シーン内の動かないオブジェクトに適応され、オブジェクトに対し「Static」のチェックを入れると、バッチングが有効な時はMesh Filterが「Combined Mesh」となり、まとめられたものがMeshとして利用される。
組み合わせたMeshを最初に作成し、それを毎フレーム表示する。
動的バッチ処理は、静的バッチ処理より負荷がかかり、オブジェクトを描画する際に
オブジェクト個別描画コスト > 動的バッチ処理のコスト + バッチ化されたドローコール処理コスト
が成り立つ場合に採用される。処理負荷が高いグラフィックス APIが組み込まれている場合に使われる。
これらのバッチング処理により、複数のテクスチャを一つのマクロテクスチャファイルやTextureAtlasとして保存し、UV座標系を使ってテクスチャをマッピングするUVマッピングを行う。
https://entry.cgworld.jp/terms/UV%E3%83%9E%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0.html
レンダリングの最終目標は、ディスプレイデバイスの全てのピクセルを適切な色で埋めることだが、一つのピクセルに複数回描画を行なってしまうと非効率となる。
通常、Unityは実際のディスプレイよりも大きいフレームバッファーメモリーに対して描画し、視覚的歪みの補正、色の分離などの後処理を行った上でディスプレイにデータが渡される。
後処理は複数のオーバーレイバッファーを合成して行う。
フレームバッファは、画面に表示するための文字やイメージを記録しておくためのメモリで、通常はメインメモリの一部として割り付けられており、直接、あるいはグラフィックス回路の描画機能等を使って、画面イメージが書き込まれる。
書き込まれたイメージは、DAC(Digital to Analog Converter)によって、ディスプレイのタイミングに合せたビデオ信号に変換され画面に表示される
バッファは多数のデータを処理する際にデータを一時的に保管する記憶装置や領域のことで、これにより、処理するスピードと転送するスピードを補っている。処理が早いCPUと遅いディスプレイを調整するものと考える。
印刷を例にとるとわかりやすい。
パソコンの処理速度・情報転送速度が早いため、プリンタの印字スピードが追いつかなく、ミスが起きてしまう。
これを補うためにプリントに内蔵されたメモリがパソコンから送られてきたデータを一時保管し、印刷のスピードに合わせて順次データを読み出すことになる。
このプリンタに保管された一時的なデータ領域がバッファである。
高度な描画を行う際には、マルチパスレンダリングが使われるが、その仕組みは、デフォルトで使用しているバッファの描画先の格納場所を複数作って、複数描画デザインの生成を一度に行うことで、描画のパフォーマンスを上げるものとなっている。
http://marupeke296.sakura.ne.jp/DXG_No50_MultiPassRendering.html
//iosシミュレータの使用準備
フォルダのリンク切れ先を辿り、フォルダのパスとして出てきた.xcpdeprojに紐づけたが、これでは再生できないよう。
ターミナルを使用して.appの格納場所をきちんと突き止めることにする。
https://qiita.com/coa00/items/6ae2766a2991424fd144
https://stackoverflow.com/questions/1984727/how-to-get-app-file-of-a-xcode-application
//360度球体映像メディア作成
球体の映像メディアを作成する。
まずは球にテクスチャを貼り付け、回転させた。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Rotator : MonoBehaviour
{
public Vector3 rate;
void Update()
{
transform.Rotate(rate * Time.deltaTime);
}
}
次は画像を球の内面に貼り付けて、内側から球体を覗いてみる。
Sphere colliderのチェックボックスを外し、透過できるようにし、Albedoに画像をアタッチする。
さらに球体の内面にレンダリングする必要があるためにカスタムシェーダーでシェーダーを加工していく。
Shader "Custom/InwardShader"
{
Properties
{
_MainTex ("Albedo (RGB)", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
Cull Front
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard vertex:vert
void vert(inout appdata_full v)
{
v.normal.xyz = v.normal * -1;
}
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
}
ENDCG
}
FallBack "Diffuse"
}
Cull Frontとv.normal.xyz = v.normal * -1;とすることでAlbedoの画像を表裏反転させて、内側から画像を見れるようにしている。
Shaderを作成シェーダに切り替えると内側から除ける球体が作成できる。外面が透けてしまって内側が見えてしまうので子要素に普通の球体を作成すれば、外側も簡単に隠すことができる。