Más contenido relacionado
La actualidad más candente (20)
Similar a Shadow gunのサンプルから学べるモバイル最適化 (20)
Más de Katsutoshi Makino (9)
Shadow gunのサンプルから学べるモバイル最適化
- 4. • 基本的に多くの情報はすでに英語で
Unity の Web サイトに出ています
– http://blogs.unity3d.com/2012/03/23/shad
owgun-optimizing-for-mobile-sample-level/
– http://blogs.unity3d.com/2011/08/18/fast-
mobile-shaders-talk-at-siggraph/
- 10. テクスチャ枚数
• 64 × 1枚
• 128 × 1枚
• 256 × 7枚
• 512 × 10枚
• 1024 × 10枚
• 2048 × 3枚
- 11. テクスチャ用途
• 64、128
– 光の表現、God Ray、BRDF LookUpTexture
• 256
– 遠景(月、山)、煙、床、水面
• 512
– 彫像、床、旗、空、NormalMap
• 1024
– 敵、シャトル、壁、窓
• 2048
– 壁、オブジェクト用アトラス
- 12. テクスチャフォーマット
• 64、128
– RGBA 32、RGB 16
• 256
– RGBA 32、RGB 16、Compressed
• 512、1024、2048
– Compressed
- 13. ポリゴン数
• ポリゴン数
– 毎フレーム : 20k 〜 30k 描画
– 敵1体 : 約2k
– Draw-call : 30 〜 50
– Batched : 120 〜 150
- 16. 処理時間
• physx: 0.3
• animation: 0.3
• culling 0.0
• skinning: 2.6
• batching: 0.7
• render: 1.8
• fixed-update-count: 1 .. 4
• update: 0.2
• fixedUpdate: 0.4
• coroutines: 0.0
- 17. 処理時間
• physx: 0.3
• animation: 0.3
• culling 0.0
• skinning: 2.6 結構重い!
• batching: 0.7
• render: 1.8
• fixed-update-count: 1 .. 4
• update: 0.2
• fixedUpdate: 0.4
• coroutines: 0.0
- 19. Case 1
v2f vert (appdata_full v) {
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord;
float3 worldNormal = mul((float3x3)_Object2World, v.normal);
float3 viewNormal = mul((float3x3)UNITY_MATRIX_MV, v.normal);
頂点シェーダ
float4 viewPos = mul(UNITY_MATRIX_MV, v.vertex);
float3 viewDir = float3(0,0,1);
float3 viewLightPos = _SpecOffset * float3(1,1,-1);
float3 dirToLight = viewPos.xyz - viewLightPos;
float3 h = (viewDir + normalize(-dirToLight)) * 0.5;
float atten = 1.0 - saturate(length(dirToLight) / _SpecRange);
o.spec = _SpecColor * pow(saturate(dot(viewNormal, normalize(h))), _Shininess * 128) * 2 * atten;
o.SHLighting = ShadeSH9(float4(worldNormal,1)) * _SHLightingScale;
return o;
}
fixed4 frag (v2f i) : COLOR {
fixed4 c = tex2D (_MainTex, i.uv);
c.rgb *= i.SHLighting;
}
c.rgb += i.spec.rgb * c.a;
return c; フラグメントシェーダ
- 20. Case 2
v2f vert (appdata_full v) {
v2f o;
float3 viewPos = mul(UNITY_MATRIX_MV,v.vertex);
float dist = length(viewPos);
float nfadeout = saturate(dist / _FadeOutDistNear);
float ffadeout = 1 - saturate(max(dist - _FadeOutDistFar,0) * 0.2);
ffadeout *= ffadeout;
nfadeout *= nfadeout;
頂点シェーダ
nfadeout *= nfadeout;
nfadeout *= ffadeout;
float4 vpos = v.vertex;
vpos.xyz -= v.normal * saturate(1 - nfadeout) * v.color.a * _ContractionAmount;
o.uv = v.texcoord.xy;
o.pos = mul(UNITY_MATRIX_MVP, vpos);
o.color = nfadeout * v.color * _Multiplier;
return o;
}
fixed4 frag (v2f i) : COLOR {
フラグメントシェーダ
return tex2D (_MainTex, i.uv.xy) * i.color;
}
- 24. • Virtual Gloss Per-Vertex Additive
(Supports Lightmap)
–壁とか床
–一番使用量が多い
- 25. Pass {
CGPROGRAM
pragma vertex vert
#pragma fragment frag
#pragma fragmentoption
ARB_precision_hint_faste
fixed4 frag (v2f i) : COLOR
{
・・・
- 26. Pass {
CGPROGRAM
pragma vertex vert
#pragma fragment frag
#pragma fragmentoption
ARB_precision_hint_faste
精度を可能な限り落して
fixed4 frag (v2f i) : COLOR
{ 実行時間を短くす
る ・・・
- 27. fixed4 frag (v2f i) : COLOR {
fixed4 c = tex2D (_MainTex, i.uv);
fixed3 spec = i.spec.rgb * c.a;
c.rgb += spec;
fixed3 lm = DecodeLightmap(tex2D(
unity_Lightmap, i.lmap));
c.rgb *= lm;
return c;
}
- 28. fixed4 frag (v2f i) : COLOR {
fixed4 c = tex2D (_MainTex, i.uv);
fixed3 spec = 明示的に精度を落とす
i.spec.rgb * c.a;
c.rgb += spec;
fixed3 lm = DecodeLightmap(tex2D(
unity_Lightmap, i.lmap));
c.rgb *= lm;
return c;
}
- 29. 精度
• fixed
– 通常 11 bit
– -2.0 〜 +2.0
– 精度 1 / 256
• half
– 通常 16 bit
– -60000 〜 +60000
– 精度おおよそ 3 桁
• float
– 32 bit
- 30. 精度
• fixed
– 通常 11 bit 速い
– -2.0 〜 +2.0
– 精度 1 / 256
• half
– 通常 16 bit
– -60000 〜 +60000
– 精度おおよそ 3 桁
• float 遅い
– 32 bit
- 31. 精度
• fixed
– 色、単位ベクトル
• half
– その他
• float
– half で精度が足りないとき
- 40. Per Vertex Specular Maps
1. テクスチャの α に鏡面反射強度を格
納しておく
2. 頂点シェーダでスペキュラ計算
3. フラグメントシェーダで上記計算結
果と強度を掛けて足す
- 41. コード
v2f vert (appdata_full v) {
・・・
o.spec = _SpecColor *
pow(saturate(dot(viewNormal,
normalize(h))), _Shininess * 128)
* 2 * atten;
・・・
}
- 42. コード
half4 frag (v2f i) : COLOR {
half4 c = tex2D (_MainTex, i.uv);
half3 spec = i.spec.rgb * c.a;
}
- 47. コード
void surf (Input IN, inout MySurfaceOutput o) {
fixed4 tex =
tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = tex.rgb;
o.Gloss = tex.a;
o.Alpha = tex.a;
o.Normal = tex2D(_BumpMap,
IN.uv_BumpMap).rgb * 2.0 - 1.0;
}
- 48. コード
ixed4 LightingPseudoBRDF (MySurfaceOutput s, fixed3
lightDir, fixed3 viewDir, fixed atten)
{
fixed3 halfDir = normalize (lightDir + viewDir);
// N.L
fixed NdotL = dot (s.Normal, lightDir);
// N.H
fixed NdotH = dot (s.Normal, halfDir);
// remap N.L from [-1..1] to [0..1]
fixed biasNdotL = NdotL * 0.5 + 0.5;
・・・
- 49. コード
・・・
fixed4 l = tex2D (_BRDFTex,
fixed2(biasNdotL, NdotH));
fixed4 c;
c.rgb = s.Albedo * (l.rgb + s.Gloss * l.a) * 2;
c.a = 0;
return c;
}
s.Gloss(= tex.a)
- 54. コード
v2f vert (appdata_full v) {
v2f o;
float3 viewPos = mul(UNITY_MATRIX_MV,v.vertex);
float dist = length(viewPos);
float nfadeout = saturate(dist / _FadeOutDistNear);
float ffadeout = 1 - saturate(max(dist - _FadeOutDistFar,0)
* 0.2);
距離に応じての減衰率を出す
ffadeout *= ffadeout;
・・・
- 55. コード
・・・
float4 vpos = v.vertex;
vpos.xyz -= v.normal * saturate(1 - nfadeout) * v.color.a
* _ContractionAmount;
頂点を法線方向に移動
o.uv = v.texcoord.xy;
o.pos = mul(UNITY_MATRIX_MVP, vpos);
o.color = nfadeout * v.color * _Multiplier;
return o;
}
- 57. 旗
• 頂点カラーの α に風の影響を受ける
かを格納してある
• 上記と各種パラメータを使って頂点
シェーダで計算して直接頂点の位置
を変更
- 61. コード
v2f vert (appdata_full v) {
v2f o;
テクスチャ座標移動
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv.xy = TRANSFORM_TEX(v.texcoord.xy,_MainTex) +
frac(float2(_ScrollX, _ScrollY) * _Time);
o.uv.zw = TRANSFORM_TEX(v.texcoord.xy,_DetailTex) +
frac(float2(_Scroll2X, _Scroll2Y) * _Time);
・・・
- 62. コード
・・・
o.uv.x += sin(_Time * _SineFreqX) * _SineAmplX;
o.uv.y += sin(_Time * _SineFreqY) * _SineAmplY;
o.uv.z += sin(_Time * _SineFreqX2) * _SineAmplX2;
o.uv.w += sin(_Time * _SineFreqY2) * _SineAmplY2;
o.color = _MMultiplier * _Color * v.color;
return o;
}
- 67. void surf (Input IN, inout SurfaceOutput o) {fixed4 tex =
tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = tex.rgb;
o.Alpha = tex.a;
half3 t = _Center.xyz - IN.worldPos.xyz;
half d = 1 / (t.x * t.x + t.y * t.y + t.z * t.z);
o.Gloss = (_Radius * _Radius * d);
WorldNormalVector(IN, o.Normal);
}
- 68. コード
fixed4 LightingSimpleLambertAO (SurfaceOutput s, fixed3
lightDir, fixed atten) {
fixed NdotL = dot (s.Normal, lightDir);
fixed bl = NdotL * s.Gloss;
fixed4 c; 光のブロック率を出す
c.rgb = s.Albedo * _LightColor0.rgb *
(NdotL * atten * 2) * (1 - bl);
c.a = s.Alpha;
return c;
}