Unity グラフィック メモ3
メモしたのを書きなぐります
・Compile and show code
Compile and show codeは選択したグラフィックス API に対するすべてのシェーダーバリアントを手動でコンパイルを行う。
シェーダーはビルド時まですべてのグラフィックス API 用のすべてのシェーダーバリアントをコンパイルしません。エラーを確認するために、これを手動で強制的におこなうことができます。
以下のシェーダーバリアントを実装したシェーダーで試してみる。
Shader "Sample/MultiCompile"
{
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ RED GREEN BLUE
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
{
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
#ifdef RED
return fixed4(1, 0, 0, 1);
#elif GREEN
return fixed4(0, 1, 0, 1);
#elif BLUE
return fixed4(0, 0, 1, 0);
#endif
return fixed4(0, 0, 0, 1);
}
ENDCG
}
}
}
Compile and show codeの▼をクリックすると、現在使用しているPCのグラフィックAPIか、ビルドターゲットのグラフィックAPIか、すべてのプラットフォームのグラフィックAPIか、カスタムでグラフィックAPIを選べる。
今回は、MetalのグラフィックAPIを選択してみたの下記である。
// Compiled shader for custom platforms
//////////////////////////////////////////////////////////////////////////
//
// NOTE: This is *not* a valid shader file, the contents are provided just
// for information and for debugging purposes only.
//
//////////////////////////////////////////////////////////////////////////
Shader "Sample/MultiCompile" {
SubShader {
Pass {
//////////////////////////////////
// //
// Compiled programs //
// //
//////////////////////////////////
//////////////////////////////////////////////////////
Keywords: <none>
-- Hardware tier variant: Tier 1
-- Vertex shader for "metal":
Uses vertex data channel "Vertex"
Constant Buffer "VGlobals" (128 bytes) on slot 0 {
Matrix4x4 unity_ObjectToWorld at 0
Matrix4x4 unity_MatrixVP at 64
}
Shader Disassembly:
#include <metal_stdlib>
#include <metal_texture>
using namespace metal;
struct VGlobals_Type
{
float4 hlslcc_mtx4x4unity_ObjectToWorld[4];
float4 hlslcc_mtx4x4unity_MatrixVP[4];
};
struct Mtl_VertexIn
{
float4 POSITION0 [[ attribute(0) ]] ;
};
struct Mtl_VertexOut
{
float4 mtl_Position [[ position ]];
};
vertex Mtl_VertexOut xlatMtlMain(
constant VGlobals_Type& VGlobals [[ buffer(0) ]],
Mtl_VertexIn input [[ stage_in ]])
{
Mtl_VertexOut output;
float4 u_xlat0;
float4 u_xlat1;
u_xlat0 = input.POSITION0.yyyy * VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[1];
u_xlat0 = fma(VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[0], input.POSITION0.xxxx, u_xlat0);
u_xlat0 = fma(VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[2], input.POSITION0.zzzz, u_xlat0);
u_xlat0 = u_xlat0 + VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[3];
u_xlat1 = u_xlat0.yyyy * VGlobals.hlslcc_mtx4x4unity_MatrixVP[1];
u_xlat1 = fma(VGlobals.hlslcc_mtx4x4unity_MatrixVP[0], u_xlat0.xxxx, u_xlat1);
u_xlat1 = fma(VGlobals.hlslcc_mtx4x4unity_MatrixVP[2], u_xlat0.zzzz, u_xlat1);
output.mtl_Position = fma(VGlobals.hlslcc_mtx4x4unity_MatrixVP[3], u_xlat0.wwww, u_xlat1);
return output;
}
-- Hardware tier variant: Tier 1
-- Fragment shader for "metal":
Shader Disassembly:
#include <metal_stdlib>
#include <metal_texture>
using namespace metal;
#ifndef XLT_REMAP_O
#define XLT_REMAP_O {0, 1, 2, 3, 4, 5, 6, 7}
#endif
constexpr constant uint xlt_remap_o[] = XLT_REMAP_O;
struct Mtl_FragmentOut
{
float4 SV_Target0 [[ color(xlt_remap_o[0]) ]];
};
fragment Mtl_FragmentOut xlatMtlMain(
)
{
Mtl_FragmentOut output;
output.SV_Target0 = float4(0.0, 0.0, 0.0, 1.0);
return output;
}
//////////////////////////////////////////////////////
Keywords: RED
-- Hardware tier variant: Tier 1
-- Vertex shader for "metal":
Uses vertex data channel "Vertex"
Constant Buffer "VGlobals" (128 bytes) on slot 0 {
Matrix4x4 unity_ObjectToWorld at 0
Matrix4x4 unity_MatrixVP at 64
}
Shader Disassembly:
#include <metal_stdlib>
#include <metal_texture>
using namespace metal;
struct VGlobals_Type
{
float4 hlslcc_mtx4x4unity_ObjectToWorld[4];
float4 hlslcc_mtx4x4unity_MatrixVP[4];
};
struct Mtl_VertexIn
{
float4 POSITION0 [[ attribute(0) ]] ;
};
struct Mtl_VertexOut
{
float4 mtl_Position [[ position ]];
};
vertex Mtl_VertexOut xlatMtlMain(
constant VGlobals_Type& VGlobals [[ buffer(0) ]],
Mtl_VertexIn input [[ stage_in ]])
{
Mtl_VertexOut output;
float4 u_xlat0;
float4 u_xlat1;
u_xlat0 = input.POSITION0.yyyy * VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[1];
u_xlat0 = fma(VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[0], input.POSITION0.xxxx, u_xlat0);
u_xlat0 = fma(VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[2], input.POSITION0.zzzz, u_xlat0);
u_xlat0 = u_xlat0 + VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[3];
u_xlat1 = u_xlat0.yyyy * VGlobals.hlslcc_mtx4x4unity_MatrixVP[1];
u_xlat1 = fma(VGlobals.hlslcc_mtx4x4unity_MatrixVP[0], u_xlat0.xxxx, u_xlat1);
u_xlat1 = fma(VGlobals.hlslcc_mtx4x4unity_MatrixVP[2], u_xlat0.zzzz, u_xlat1);
output.mtl_Position = fma(VGlobals.hlslcc_mtx4x4unity_MatrixVP[3], u_xlat0.wwww, u_xlat1);
return output;
}
-- Hardware tier variant: Tier 1
-- Fragment shader for "metal":
Shader Disassembly:
#include <metal_stdlib>
#include <metal_texture>
using namespace metal;
#ifndef XLT_REMAP_O
#define XLT_REMAP_O {0, 1, 2, 3, 4, 5, 6, 7}
#endif
constexpr constant uint xlt_remap_o[] = XLT_REMAP_O;
struct Mtl_FragmentOut
{
float4 SV_Target0 [[ color(xlt_remap_o[0]) ]];
};
fragment Mtl_FragmentOut xlatMtlMain(
)
{
Mtl_FragmentOut output;
output.SV_Target0 = float4(1.0, 0.0, 0.0, 1.0);
return output;
}
//////////////////////////////////////////////////////
Keywords: GREEN
-- Hardware tier variant: Tier 1
-- Vertex shader for "metal":
Uses vertex data channel "Vertex"
Constant Buffer "VGlobals" (128 bytes) on slot 0 {
Matrix4x4 unity_ObjectToWorld at 0
Matrix4x4 unity_MatrixVP at 64
}
Shader Disassembly:
#include <metal_stdlib>
#include <metal_texture>
using namespace metal;
struct VGlobals_Type
{
float4 hlslcc_mtx4x4unity_ObjectToWorld[4];
float4 hlslcc_mtx4x4unity_MatrixVP[4];
};
struct Mtl_VertexIn
{
float4 POSITION0 [[ attribute(0) ]] ;
};
struct Mtl_VertexOut
{
float4 mtl_Position [[ position ]];
};
vertex Mtl_VertexOut xlatMtlMain(
constant VGlobals_Type& VGlobals [[ buffer(0) ]],
Mtl_VertexIn input [[ stage_in ]])
{
Mtl_VertexOut output;
float4 u_xlat0;
float4 u_xlat1;
u_xlat0 = input.POSITION0.yyyy * VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[1];
u_xlat0 = fma(VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[0], input.POSITION0.xxxx, u_xlat0);
u_xlat0 = fma(VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[2], input.POSITION0.zzzz, u_xlat0);
u_xlat0 = u_xlat0 + VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[3];
u_xlat1 = u_xlat0.yyyy * VGlobals.hlslcc_mtx4x4unity_MatrixVP[1];
u_xlat1 = fma(VGlobals.hlslcc_mtx4x4unity_MatrixVP[0], u_xlat0.xxxx, u_xlat1);
u_xlat1 = fma(VGlobals.hlslcc_mtx4x4unity_MatrixVP[2], u_xlat0.zzzz, u_xlat1);
output.mtl_Position = fma(VGlobals.hlslcc_mtx4x4unity_MatrixVP[3], u_xlat0.wwww, u_xlat1);
return output;
}
-- Hardware tier variant: Tier 1
-- Fragment shader for "metal":
Shader Disassembly:
#include <metal_stdlib>
#include <metal_texture>
using namespace metal;
#ifndef XLT_REMAP_O
#define XLT_REMAP_O {0, 1, 2, 3, 4, 5, 6, 7}
#endif
constexpr constant uint xlt_remap_o[] = XLT_REMAP_O;
struct Mtl_FragmentOut
{
float4 SV_Target0 [[ color(xlt_remap_o[0]) ]];
};
fragment Mtl_FragmentOut xlatMtlMain(
)
{
Mtl_FragmentOut output;
output.SV_Target0 = float4(0.0, 1.0, 0.0, 1.0);
return output;
}
//////////////////////////////////////////////////////
Keywords: BLUE
-- Hardware tier variant: Tier 1
-- Vertex shader for "metal":
Uses vertex data channel "Vertex"
Constant Buffer "VGlobals" (128 bytes) on slot 0 {
Matrix4x4 unity_ObjectToWorld at 0
Matrix4x4 unity_MatrixVP at 64
}
Shader Disassembly:
#include <metal_stdlib>
#include <metal_texture>
using namespace metal;
struct VGlobals_Type
{
float4 hlslcc_mtx4x4unity_ObjectToWorld[4];
float4 hlslcc_mtx4x4unity_MatrixVP[4];
};
struct Mtl_VertexIn
{
float4 POSITION0 [[ attribute(0) ]] ;
};
struct Mtl_VertexOut
{
float4 mtl_Position [[ position ]];
};
vertex Mtl_VertexOut xlatMtlMain(
constant VGlobals_Type& VGlobals [[ buffer(0) ]],
Mtl_VertexIn input [[ stage_in ]])
{
Mtl_VertexOut output;
float4 u_xlat0;
float4 u_xlat1;
u_xlat0 = input.POSITION0.yyyy * VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[1];
u_xlat0 = fma(VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[0], input.POSITION0.xxxx, u_xlat0);
u_xlat0 = fma(VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[2], input.POSITION0.zzzz, u_xlat0);
u_xlat0 = u_xlat0 + VGlobals.hlslcc_mtx4x4unity_ObjectToWorld[3];
u_xlat1 = u_xlat0.yyyy * VGlobals.hlslcc_mtx4x4unity_MatrixVP[1];
u_xlat1 = fma(VGlobals.hlslcc_mtx4x4unity_MatrixVP[0], u_xlat0.xxxx, u_xlat1);
u_xlat1 = fma(VGlobals.hlslcc_mtx4x4unity_MatrixVP[2], u_xlat0.zzzz, u_xlat1);
output.mtl_Position = fma(VGlobals.hlslcc_mtx4x4unity_MatrixVP[3], u_xlat0.wwww, u_xlat1);
return output;
}
-- Hardware tier variant: Tier 1
-- Fragment shader for "metal":
Shader Disassembly:
#include <metal_stdlib>
#include <metal_texture>
using namespace metal;
#ifndef XLT_REMAP_O
#define XLT_REMAP_O {0, 1, 2, 3, 4, 5, 6, 7}
#endif
constexpr constant uint xlt_remap_o[] = XLT_REMAP_O;
struct Mtl_FragmentOut
{
float4 SV_Target0 [[ color(xlt_remap_o[0]) ]];
};
fragment Mtl_FragmentOut xlatMtlMain(
)
{
Mtl_FragmentOut output;
output.SV_Target0 = float4(0.0, 0.0, 1.0, 0.0);
return output;
}
}
}
}
確かに、グラフィックAPIはmetal、シェーダーバリアントは定義したRED、GREEN、BLUEがソース上に記載されているのが分かる。このコンパイルしたシェーダーコードは最適化する際に役に立ち、生成されたコードを GPU シェーダーパフォーマンス分析ツール (AMD GPU ShaderAnalyzer や PVRShaderEditorなど)に貼り付けることでパフォーマンスなどの情報を確認することができる。
また、Showボタンを押下することで、ビルドに含まれるシェーダーバリアントやビルドの際削除されるシェーダーバリアントを見ることができる。
今回は、SurfaceShaderをShowボタンで押下していたのが以下である。
// Total snippets: 11
// -----------------------------------------
// Snippet #0 platforms ffffffff:
Keywords stripped away when not used: STEREO_CUBEMAP_RENDER_ON STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON UNITY_SINGLE_PASS_STEREO
Keywords always included into build: INSTANCING_ON FOG_LINEAR FOG_EXP FOG_EXP2
Builtin keywords used: DIRECTIONAL LIGHTPROBE_SH SHADOWS_SHADOWMASK DYNAMICLIGHTMAP_ON LIGHTMAP_ON LIGHTMAP_SHADOW_MIXING DIRLIGHTMAP_COMBINED SHADOWS_SCREEN VERTEXLIGHT_ON
8 keyword variants used in scene:
DIRECTIONAL
DIRECTIONAL LIGHTPROBE_SH
DIRECTIONAL SHADOWS_SCREEN
DIRECTIONAL LIGHTPROBE_SH SHADOWS_SCREEN
DIRECTIONAL VERTEXLIGHT_ON
DIRECTIONAL LIGHTPROBE_SH VERTEXLIGHT_ON
DIRECTIONAL SHADOWS_SCREEN VERTEXLIGHT_ON
DIRECTIONAL LIGHTPROBE_SH SHADOWS_SCREEN VERTEXLIGHT_ON
// -----------------------------------------
// Snippet #1 platforms ffffffff:
Keywords stripped away when not used: STEREO_CUBEMAP_RENDER_ON STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON UNITY_SINGLE_PASS_STEREO
Keywords always included into build: FOG_LINEAR FOG_EXP FOG_EXP2
1 keyword variants used in scene:
<no keywords defined>
// -----------------------------------------
// Snippet #2 platforms ffffffff:
Keywords stripped away when not used: STEREO_CUBEMAP_RENDER_ON STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON UNITY_SINGLE_PASS_STEREO
Keywords always included into build: INSTANCING_ON FOG_LINEAR FOG_EXP FOG_EXP2
Builtin keywords used: DIRECTIONAL LIGHTPROBE_SH SHADOWS_SHADOWMASK DYNAMICLIGHTMAP_ON LIGHTMAP_ON LIGHTMAP_SHADOW_MIXING DIRLIGHTMAP_COMBINED SHADOWS_SCREEN VERTEXLIGHT_ON
8 keyword variants used in scene:
DIRECTIONAL
DIRECTIONAL LIGHTPROBE_SH
DIRECTIONAL SHADOWS_SCREEN
DIRECTIONAL LIGHTPROBE_SH SHADOWS_SCREEN
DIRECTIONAL VERTEXLIGHT_ON
DIRECTIONAL LIGHTPROBE_SH VERTEXLIGHT_ON
DIRECTIONAL SHADOWS_SCREEN VERTEXLIGHT_ON
DIRECTIONAL LIGHTPROBE_SH SHADOWS_SCREEN VERTEXLIGHT_ON
// -----------------------------------------
// Snippet #3 platforms ffffffff:
Keywords stripped away when not used: STEREO_CUBEMAP_RENDER_ON STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON UNITY_SINGLE_PASS_STEREO
Keywords always included into build: INSTANCING_ON
Builtin keywords used: SHADOWS_DEPTH SHADOWS_CUBE
2 keyword variants used in scene:
SHADOWS_DEPTH
SHADOWS_CUBE
// -----------------------------------------
// Snippet #4 platforms ffffffff:
Keywords stripped away when not used: STEREO_CUBEMAP_RENDER_ON STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON UNITY_SINGLE_PASS_STEREO
Keywords always included into build: INSTANCING_ON FOG_LINEAR FOG_EXP FOG_EXP2
Builtin keywords used: POINT DIRECTIONAL SPOT POINT_COOKIE DIRECTIONAL_COOKIE
5 keyword variants used in scene:
POINT
DIRECTIONAL
SPOT
POINT_COOKIE
DIRECTIONAL_COOKIE
// -----------------------------------------
// Snippet #5 platforms ffffffff:
Keywords stripped away when not used: STEREO_CUBEMAP_RENDER_ON STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON UNITY_SINGLE_PASS_STEREO
Keywords always included into build: INSTANCING_ON FOG_LINEAR FOG_EXP FOG_EXP2
Builtin keywords used: POINT DIRECTIONAL SPOT POINT_COOKIE DIRECTIONAL_COOKIE SHADOWS_SHADOWMASK LIGHTMAP_SHADOW_MIXING SHADOWS_DEPTH SHADOWS_SOFT SHADOWS_SCREEN SHADOWS_CUBE
13 keyword variants used in scene:
POINT
DIRECTIONAL
SPOT
POINT_COOKIE
DIRECTIONAL_COOKIE
SHADOWS_DEPTH SPOT
SHADOWS_DEPTH SHADOWS_SOFT SPOT
DIRECTIONAL SHADOWS_SCREEN
DIRECTIONAL_COOKIE SHADOWS_SCREEN
POINT SHADOWS_CUBE
POINT SHADOWS_CUBE SHADOWS_SOFT
POINT_COOKIE SHADOWS_CUBE
POINT_COOKIE SHADOWS_CUBE SHADOWS_SOFT
// -----------------------------------------
// Snippet #6 platforms fffffbff:
Keywords stripped away when not used: STEREO_CUBEMAP_RENDER_ON STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON UNITY_SINGLE_PASS_STEREO
Keywords always included into build: INSTANCING_ON
Builtin keywords used: LIGHTPROBE_SH DYNAMICLIGHTMAP_ON SHADOWS_SHADOWMASK LIGHTMAP_ON DIRLIGHTMAP_COMBINED UNITY_HDR_ON
4 keyword variants used in scene:
<no keywords defined>
LIGHTPROBE_SH
UNITY_HDR_ON
LIGHTPROBE_SH UNITY_HDR_ON
// -----------------------------------------
// Snippet #7 platforms ffffffff:
Keywords stripped away when not used: STEREO_CUBEMAP_RENDER_ON STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON UNITY_SINGLE_PASS_STEREO
Keywords always included into build: FOG_LINEAR FOG_EXP FOG_EXP2 POINT SPOT
3 keyword variants used in scene:
<no keywords defined>
POINT
SPOT
// -----------------------------------------
// Snippet #8 platforms fffffbff:
Keywords stripped away when not used: STEREO_CUBEMAP_RENDER_ON STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON UNITY_SINGLE_PASS_STEREO
Keywords always included into build: INSTANCING_ON
Builtin keywords used: LIGHTPROBE_SH DYNAMICLIGHTMAP_ON SHADOWS_SHADOWMASK LIGHTMAP_ON DIRLIGHTMAP_COMBINED UNITY_HDR_ON
4 keyword variants used in scene:
<no keywords defined>
LIGHTPROBE_SH
UNITY_HDR_ON
LIGHTPROBE_SH UNITY_HDR_ON
// -----------------------------------------
// Snippet #9 platforms ffffffff:
Keywords stripped away when not used: EDITOR_VISUALIZATION STEREO_CUBEMAP_RENDER_ON STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON UNITY_SINGLE_PASS_STEREO
Keywords always included into build: INSTANCING_ON
1 keyword variants used in scene:
<no keywords defined>
// -----------------------------------------
// Snippet #10 platforms ffffffff:
Keywords stripped away when not used: EDITOR_VISUALIZATION STEREO_CUBEMAP_RENDER_ON STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON UNITY_SINGLE_PASS_STEREO
Keywords always included into build: INSTANCING_ON
1 keyword variants used in scene:
<no keywords defined>
Keywords stripped away when not usedはビルドの際削除されるシェーダーバリアント、
Keywords always included into buildはビルドの際削除されないシェーダーバリアント、
Builtin keywords usedはおそらくビルドの際削除されないシェーダーバリアント。
また、Skip unused shader_featuresは、
オンだとUnityが自動でシェーダーバリアント省いた後の場合で
オフだと全てのシェーダーバリアントを含めた場合である。
参照サイト
・コンピュードシェーダー
コンピュードシェーダー(GPGPU)は、本来CPUでやるような処理をGPUにやらせるシェーダーのことである。
特徴としては以下である。
主にはこういう処理で使用する。
大量に同じような処理を行うときに向いているといえる。
対応しているプラットフォームは以下である。
・DirectX 11 または DirectX 12 グラフィックス API と Shader Model 5.0 GPU を伴う Windows と Windows ストア
・Metal グラフィックス API を使用する macOS と iOS
・Vulkan API を伴う Android、Linux、Windows プラットフォーム
・現段階で一般的に使用されている OpenGL プラットフォーム (Linux または Windows の OpenGL 4.3、Android の OpenGL ES 3.1)。Mac OS X は OpenGL 4.3 をサポートしません。
・Modern consoles
いつか自前でやろうと思うが時間がかかりそうなので今回はここまで。
詳しい内容は、参照サイトを参照
参照サイト、参照動画
・エラーシェーダーとローディングシェーダー
■エラーシェーダー
シェーダーに問題がある場合、Unity はデフォルトのエラーシェーダーでオブジェクトをレンダリングします。例えば、マテリアルが割り当てられていない場合や、シェーダーがコンパイリングしない場合、シェーダーがサポートされていない場合などです。
BatchRendererGroup API を使用する場合、Unity はデフォルトのエラーシェーダーを表示しません。BatchRendererGroup.SetErrorMaterial を使って、代わりに使用するマテリアルを設定してください。
■ローディングシェーダー
非同期シェーダーがコンパイルされているときは以下のような見た目になる。
参照サイト
・オブジェクトが金属非金属、粗さによって反射が変わる。
上の画像で、球のオブジェクトが上から下にいくにつれて金属っぽくかつ滑らかになっていく。
それにともなって、反射光の範囲が狭くなり周囲の景色などがより反射されて見え、ハイライトも小さくなっていることが分かる。
参照サイト
・Visual StudioまたはPIXでシェーダーデバッグ
やり方は参照サイトを参照
参照サイト、参照サイト
・PBRが正しいのがエディタ上で確認
Validate Albedo と Validate Metal Specularを使用してPBRが正しいのか確認できるが、ビルトインのみ。
参照サイト
・C#のSetColor、SetFloat、SetInteger、SetTextureでシェーダー内の値を変える。
各々のやれることは以下である。
SetColor マテリアルの色を変えます
SetFloat 浮動小数点の値を設定します
SetInteger マテリアルに整数値を設定します
SetTexture マテリアルに新しいテクスチャを指定します
実際に使用してみる。
まずはC#のコード
using UnityEngine;
public class Test : MonoBehaviour
{
public GameObject oj;
public Texture2D tex;
private Renderer gameObjectRenderer;
void Start()
{
gameObjectRenderer = oj.GetComponent<Renderer>();
}
void Update()
{
if (Input.GetKey(KeyCode.A)) {
gameObjectRenderer.material.SetColor("_BaseColor",Color.red);
}
if (Input.GetKey(KeyCode.B))
{
gameObjectRenderer.material.SetTexture("_BaseMap", tex);
}
if (Input.GetKey(KeyCode.C))
{
gameObjectRenderer.material.SetInteger("_Integer", 0);
}
if (Input.GetKey(KeyCode.D))
{
gameObjectRenderer.material.SetFloat("_Float", 0.2f);
}
}
}
次にシェーダー
Shader "Test"
{
Properties
{
_BaseMap("Base Map", 2D) = "white" {}
_BaseColor("Base Color", Color) = (1, 1, 1, 1)
_Integer("Integer", Int) = 1
_Float("Float", Float) = 1.0
}
SubShader
{
Tags
{
"RenderPipeline" = "UniversalPipeline"
}
Pass
{
Tags
{
"LightMode" = "UniversalForward"
}
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _BaseMap;
float4 _BaseMap_ST;
half4 _BaseColor;
int _Integer;
float _Float;
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap);
return OUT;
}
half4 frag(Varyings IN) : SV_Target
{
return tex2D(_BaseMap, IN.uv) * _BaseColor * _Integer * _Float;
}
ENDHLSL
}
}
}
A押下すると
Bを押下すると
Cを押下すると
Dを押下すると
正しく反映されているのが分かる。
(C押下の時は何故かエラー出たが見た目が正しいので今回は気にしない)
参照サイト
・マテリアルバリアント
マテリアルバリアントは、複製したマテリアルをパラメータを部分的に変えたり、共通で変えたりできる。
実際にやったほうが早い。
なお、ShaderGraphでも可能。
類似しているプレハブバリアントの違いは、以下である
①マテリアルバリアントは親を変更できます。
②マテリアルバリアントのプロパティはロック (固定) できます。
参照サイト、参照動画
・Shuriken(ビルトインパーティクルシステム)とVisual Effect Graphの違い
・Particle SystemのCustom Vertex Streams
Custom Vertex Streamsとは、Particle Systemの項目でParticle Systemで設定しているモジュール内の値をシェーダーに渡せる機能である。
これを利用することで、Particle Systemの回転・速さ・大きさなどの値に応じてシェーダー内の動的に変更できる。
以下のような値をシェーダーに渡せる。
実際にやってみる。
以下のシェーダーを使用する。
colorSourceがParticle Systemから渡される値である。
Shader "Test"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType" = "Transform" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 uv : TEXCOORD0;
// TEXCOORD1でcolorSourceを受け取るようにする
float3 colorSource : TEXCOORD1;
};
struct v2f
{
float4 vertex : SV_POSITION;
float4 color : Color;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.color = v.color;
o.color.rgb =+ v.colorSource;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv) * i.color;
return col;
}
ENDCG
}
}
}
Particle Systemでは以下のような値をシェーダー(colorSource)に渡す。
赤枠のNoiseモジュールの値を渡す。
実際の結果がこちらである。
確かに色が変わっていることが分かる。
参照サイト、参照サイト
・Particle SystemのSimulate Layers、Resimulate、Show Bounds、Show Only Selected
■Simulate Layers
Particle Systemを描画させるレイヤーを指定。
選択したParticle Systemはもちろん描画させるが、選択していないParticle Systemを描画するのかをレイヤーで指定できる。
■Resimulate
変更したParticle Systemをすぐに反映させる。
■Show Bounds
Particle Systemの描画できる範囲を視覚化する
■Show Only Selected
検証してみたがSimulate Layersと違いが分からない。
参照サイト
・Particle System Force Fieldコンポーネント
Particle Systemに色んな力を加えて動きをつけれるコンポーネント
実際にやってみた
参照サイト、参照サイト
・Visual Effect Graph
いつかやる
一応参照サイトだけ貼っておく
参照サイト
・デカール
デカールは、
ビルトインだとProjector コンポーネント
URPだとDecal Renderer Feature
HDRPだとDecal Projector
を使用する
今回はURPでやってみる。
URPでデカールを実現するには、Decal Renderer FeatureとDecal Projectorコンポーネントが必要である。
実際に試してみた下記動画である。
■Draw DistanceとMax Draw Distanceで最適化
Draw DistanceとMax Draw Distanceはともにデカールが描画される距離を調整できる機能である。
Max Draw DistanceはDecal Renderer Feature にある設定項目である。
Draw DistanceはURP Decal Projectorの設定項目である。
Max Draw Distance < Draw Distanceの場合は、Max Draw Distanceの値が反映される。
Max Draw Distance > Draw Distanceの場合は、Draw Distanceの値が反映される。
本題であるが、Draw DistanceとMax Draw Distanceの数値大きいとその分描画される距離が長くなるのでなるべく小さくしたほうが良い。
①Draw Distanceが1000
②Draw Distanceが1
デカールが見えているDraw Distanceが1000のほうが、ドローコールや頂点の数が多いことが分かるように、あまりDraw DistanceとMax Draw Distanceの値が多きすぎると負荷がかかるので注意。
■Enable GPU Instancingを有効で最適化
SetPassCallsがオンの方が少ないことが分かる。
なので、なるべくEnable GPU Instancingを使用したほうが最適化できるので良い。
Enable GPU Instancingオフ
Enable GPU Instancingオン
■Technique
Techniqueはデカールのレンダリング方法を選択する
①Automatic
ビルドプラットフォームに基づいて自動的にレンダリング手法が選択されます。
②DBuffer
DBufferを選択すると、デカールの情報はDBufferという一時テクスチャに書き込まれ、不透明描画の際に合成される。
DBufferを選択するとSurface Dataが出てくる。
これはデカールに適用する要素決めるものである。以下の設定項目がある。
Albedo: デカールは通常色と発光色に影響します。
Albedo Normal: デカールは通常色、発光色、および法線に影響します。
Albedo Normal MAOS: デカールは、通常色、発光色、法線、メタリック値、スムースネス値、およびアンビエントオクルージョン値に影響します。
実際にやってみる
Albedo
Albedo Normal
Albedo Normal MAOS
デカールのマテリアルは、BaseMapとNormalMapをついてるマテリアルである。
Albedoの方は色だけしか反映されていないが、Albedo NormalとAlbedo Normal MAOSはNormalMapが反映されているのが分かる。
ただ、Albedo→Albedo Normal→Albedo Normal MAOSにいくにつれて、DBufferTextureが生成されるのでメモリ容量的に注意が必要
また、 DepthNormal プレパスが必要なので、タイルベースのレンダリングを実装する GPU では、この手法の効率が低下する。
③Screen Space
これは、深度テクスチャから再構築した法線を使用して、不透明なオブジェクトの後にデカールをレンダリングします。不透明なメッシュの上にデカールをメッシュとしてレンダリングします。
Normal Blendで、法線の品質(Low、Medium、High)を設定できるが品質が高いほど負荷がかかるるので注意
参照サイト、参照サイト、参照サイト
・SkyBoxのシーンごとにSkyBoxを設定する方法と、カメラごとに設定する方法
■SkyBoxのシーンごとにSkyBoxを設定する方法
EnvironmentのSkybox Materialをシーンごとに設定する。
シーンA
シーンB
確かにシーンごとにSkyboxが変わっていることが分かる。
■カメラごとに設定する方法
カメラにSkybox コンポーネントをアタッチする。
カメラA
カメラB(Skybox コンポーネントアタッチ)
参照サイト
・HDRとトーンマッピングについて
HDRを使用することで、現実と同じ光度を再現できる。
ただ、SDRディスプレイで、HDR画像を描画すると白飛び(または極端に暗くなる)してしまう。
そこでHDR画像をSDRディスプレイでも正しく描画される変換が必要になるが、その変換がトーンマッピングである。
実際にSDRのディスプレイでやってみる。
そもそも前提としてHDRレンダリングを可能にするには、URPの場合はRenderPipelineAssetのQualityのHDRをオンにし、Color SpaceをLinearにしないといけない。
今、HDR画像のSkyBoxとBloom(Emissionつけたオブジェクト)のシーンを用意した。
空とBloomが白飛びしているのが分かる。
これにトーンマッピングを適用させたのが以下である。
白飛びしない結果となっている。
(ただ、Game画面だとトーンマッピングしていなくてもトーンマッピングしてそうな結果になったのは何故だ?)
■HDR画像をHDRディスプレイで出力方法
なお、上の例はHDR画像をSDRディスプレイで出力したパターンであるが、HDR画像をHDRディスプレイで表示するにも互換性(HDR画像をSDRディスプレイで出力)含めて別途対応対応が必要である。
Playerの、Allow HDR Display OutputとUse HDR Display Outputを有効にすれば可能である。
なお、Allow HDR Display OutputとUse HDR Display Outputを有効にするとトーンマッピングの項目に以下の項目が追加で現れるのでこれを調整していく。
現在HDRのディスプレイを持っていないので下記の項目の検証は未実施とする。
一方で、HDR画像をHDRディスプレイでの出力は
Unity 2023.2.0a18(および 2023.2 ベータ版)前は、デスクトップPCとコンソールをサポートしており、
Unity 2023.2.0a18(および 2023.2 ベータ版)以降は、これに加えてiOS(iOS 16 以降、iPadOS 16 以降)とVulkan および GLES を使用している Android(Android 9 以降、デバイスの機能によって異なる)がサポートに加えられた。
一般的なモバイルデバイスで、HDR ディスプレイのサポートを提供しているものとしては、iPhone X 以降、Samsung Galaxy S10 以降、Galaxy Note 10 以降、Galaxy Tab S6 以降などがあります。
もし、Unity 2023.2.0a18(および 2023.2 ベータ版)前のVesionで開発していて、モバイルでもHDR画像をHDRディスプレイで出力するには以下のいずれかの対応が公式ドキュメントでは必要であると記載されている。
・独自のトーンマッピングソリューションを作成し、表示のために、HDR 画像バッファを互換性のある HDR フォーマットに直接変換します。
・Unity のトーンマッピングポストプロセスエフェクトを使用して、HDR バッファを SDR 画像に変換し (上記のように)、その後、Unity の自動出力トーンマッピングを使用して、その SDR 画像を適切な出力形式に変換します。Unity の自動出力トーンマッピングの詳細については、HDROutputSettings.automaticHDRTonemapping のドキュメントを参照してください。
と記載されている。
HDROutputSettings.automaticHDRTonemappingをtrueにすると自動でやってくれるようだが、一部のプラットフォームでは自動でやってくれないっぽい。
なお、もし自動でできるプラットフォームの場合、デフォルトで自動でやってくれる。
■HDRのメリット
①明るいシーンでは白飛びしない
②暗いシーンでは暗くなりすぎない
③Bloomなどが綺麗に見える
④マッハバンドが起きにくくなる
■HDRのデメリット
①VRAM 使用量が増加する
③トーンマッピングを使用する場合により多く計算コストがかかる
③ハードウェアのアンチエイリアシングは HDR レンダリングと互換性がない
■ゲーム側の設定で画面の明るさ調整する機能を追加することの必要性
公式ドキュメントでは以下のように記載されているので、ゲーム側の設定で画面の明るさ調整する機能を実装したほうが良い。
重要なトーン マッピング値
HDR ディスプレイの機能を適切に利用するには、トーンマッピング設定でターゲット ディスプレイの機能、特に次の 3 つの値 (nits 単位) を考慮する必要があります。
サポートされている最小の明るさ。
サポートされている最大の明るさ。
ペーパーホワイト値: この値は、ディスプレイ上に表示されるペーパーホワイトの表面の明るさを表し、ディスプレイ全体の明るさを決定します。
注: ロー ダイナミック レンジ (LDR) コンテンツとハイ ダイナミック レンジ (HDR) コンテンツは、同じ Paper White 値のディスプレイでは同じように明るく表示されません。 これは、ディスプレイが低ダイナミック レンジのコンテンツに追加の処理を適用し、輝度レベルを上げるためです。 このため、アプリケーションに調整メニューを実装することがベスト プラクティスです。
・グラフィックAPIごとのシェーダーの書き方
グラフィックAPIによってシェーダーの書き方が違う。
参照サイトにはそれらが載っている。
参照サイト
・Auto Graphics API
Auto Graphics APIを有効にすると、ゲームしている端末によって適切なグラフィックAPIを使用する設定項目である。
ただ、使わないグラフィックAPIがある場合この設定を有効にしていると、不要なシェーダーバリアントはまで作成されてパフォーマンス上良くないのでなるべく有効にしないほうが良い。
無効にすると、グラフィックAPIを選択でき、一番上が最初に使用され、もし使用している端末が一番上のグラフィックAPIに対応していなければ二番目のを使用するという流れ。
参照サイト
・Metal
Metal は、Apple プラットフォームの標準的な グラフィックス APIである。
Apple デバイス用に最適化されているため、サポートするプラットフォーム用にオーバーヘッドの少ない API を提供する。
これについて今回は述べていく
■Auto Graphics APIの設定がない
■OpenGL と OpenGL ES のサポートを廃止
Apple は OpenGL と OpenGL ES のサポートを廃止しました。OpenGL/OpenGL ES を使用するアプリケーションは App Store に提出できません。
■レンダーパイプラインの互換性
HDRPだけがMacosのみ対応している。
それ以外のレンダーパイプラインはiosもMacosも対応している。
■シェーダーの互換性
シェーダーコンパイルターゲット が最低 3.5 のシェーダーをサポートしています。
また、Metal はジオメトリシェーダーをサポートしていません。
■シェーダーのデータ型
一部の Metal デバイスは、16 ビットの half データ型をサポートしていません。Unity シェーダーはこうしたデバイスでは half を 32 ビットの float として表現します。同様に、real データ型は、モバイルデバイスでは half、デスクトッププラットフォームでは float として Unity シェーダーによって表現される。
以下が各GPUにおけるシェーダーの対応しているデータ型である。
■デバッグ
Unity の フレームデバッガー は、Metal をサポートしており、Metal を使用する Unity アプリケーションのグラフィックの問題をデバッグするにあたって最初に使用するべきツールです。より詳細な、Metal 固有のグラフィックス問題に関しては、Xcode が API Validation や Shader Validation などのグラフィックスデバッグツールを提供しています。
※ デバッグはCPU リソースの負荷が高くなるため、デバッグを行う目的でのみ行ってください。
■メモリレスレンダー テクスチャによる最適化
RenderTexture (レンダーテクスチャ) へのレンダリングを、システムメモリにバックアップすることなく行えます。Unity はレンダリング中にコンテンツをタイル上のメモリに一時的にのみ保存します。
これによって、CPU または GPU メモリには保存されないので、アプリのメモリ使用量が削減されますが、これらのレンダー テクスチャの読み取りや書き込みはできないことに注意してください。
メモリレス レンダー テクスチャは、iOS/tvOS 10.0 以降の Metal および Vulkan でのみサポートしている。
参照サイト、参照サイト、参照サイト、参照サイト
・OpenGLCore
OpenGL コアは、Windows、MacOS X、Linux で最新の OpenGL 機能をサポートするバックエンド機能である。
Auto Graphics APIを無効にして、追加できるが、Macだけ廃止予定のDeprecatedが付いていた。
OpenGL 要件、macOS OpenGL ドライバー制限、OpenGLCore機能、シェーダー変更などは参照サイト参照
参照サイト
・Statistics
Statisticsは以下である。
それぞれの詳しい内容は参照サイトをチェック。
参照サイト
・Frame Debugger
詳しい内容は参照サイトをチェック。
参照サイト
・UnityがサポートしているAndroidのグラフィックAPI
Vulkan あり
OpenGL ES 1.0 なし
OpenGL ES 1.1 なし
OpenGL ES 2.0 あり ※
OpenGL ES 3.0 あり
OpenGL ES 3.1 あり
OpenGL ES 3.2 あり
※新規の Unity プロジェクトは、デフォルトでは OpenGL ES 2.0 をサポートしていません。
なので、Auto Graphics APIを無効にして自分で追加する必要がある。
参照サイト
・UnityがサポートしているAndroidのレンダーパイプライン
HDRP以外は対応している。
参照サイト
・Androidでビデオファイルの再生
①Android でビデオファイルを再生するには、Video Player コンポーネントを使用してください。アプリケーションがデバイスのサポートしていないビデオファイルを再生しようとした場合、Unity はビデオを再生しません。
②ターゲットデバイスがサポートしている範囲内であれば、使用できる解像度やオーディオチャンネル数に制限はありません。ノート: 640 × 360 を超える解像度はサポートしていないデバイスもあります。
③Unity は非圧縮アセットバンドルからの再生をサポートしています。Android Pie 以上の場合、Unity は圧縮アセットバンドルからの再生をサポートします。
④Unity はネイティブの webM/VP8 の透明度をサポートしていません。VP8 でエンコードされた透明度を持つ webM クリップを再生するには、サポートされている形式にクリップをトランスコードする必要があります。
⑤6.0.1 より前のバージョンの Android では、透明度を持つ、解像度がデバイスのサポート解像度より高いビデオの場合に、サポート解像度を超えるピクセルが白としてレンダリングされます。
⑥Unity は adb logcat 出力内で形式の互換性の問題をレポートし、それにプレフィックス AndroidVideoMedia を付加します。このファイルは、Unity がレポートするビデオ形式関連の問題の近くに、デバイス固有の他のエラーメッセージを表示する場合があります。こうしたデバイス固有のエラーは Unity からは不可視で、多くの場合、互換性の問題が何であるかを説明しています。
参照サイト
・複数デバイスの解像度対応
参照サイト
・UI 要素をコンテンツのサイズに合わせる
参照サイト
・ワールドUIのサイズ見積もり
参照サイト
・動的にUIを作成する際
参照サイト
・カーソル中に画像を設定
参照サイト
・スプラッシュイメージ終わったかチェック
参照サイト
・Use Animated Autorotationをオンにすると、デバイスを回転させたときちょっとしたアニメーションがつく。オフだと即座に変わる。ios
参照サイト
・Requires Fullscreenでマルチタスキング機能を無効か。iPad
参照サイト
・iOSでステータスバーの表示・非表示(Status Bar Hidden)
Androidでは常に非表示
参照サイト、参照サイト
・Hide home button on iPhone Xを有効にしてiphone10のホームボタンを非表示
参照サイト、参照サイト
・アプリのアイコンを設定
Player SettingsのIconからできる。
参照サイト、参照サイト、参照サイト
・アプリを起動した際のアプリのウィンドウのサイズを設定
Player SettingsのFullscreen Modeからできる。
Default Window Width、Default Window Height、Minimum Window Width、Minimum Window Heightでサイズを指定できる。
参照サイト
・マルチウィンドウ機能を使う
マルチウィンドウとは、画面上で複数のアプリを使用できる。
Player SettingsのResizable Windowで可能。
参照サイト
・スマホの上のナビゲーションバーを消す
スマホの上のナビゲーションバーとは、電源やアプリのアイコンが載っているUIのことである
Player SettingsのHide Navigation Barで可能
参照サイト
・ノッチのある端末でSafeare外も描画するかしないかの設定
Player SettingsのRender outside safe areaで可能
参照サイト、参照サイト
・Player SettingsのAspect Ratio Mode
アプリケーションがサポートする最大アスペクト比を指定します。デバイスのアスペクト比がこのアスペクト比より大きい場合、Unity はアプリケーションにこのアスペクト比を使用し、アプリケーションが引き伸ばされないように黒帯を追加します。
スマホのアスペクト比までサポートするのか、自分でアスペクト比をカスタムできる。
参照サイト
・アプリの画面の向き変える
Player SettingsのDefault Orientationで可能
参照サイト
・Android または iOS で、ネイティブ UI の上にレンダリングするかどうかの設定
Player SettingsのRender Over Native UIで可能
参照サイト
・ロードしているUIを表示するかしないか
Player SettingsのShow Loading Indicatorで可能
参照サイト
・Splash Imageを設定
Splash Imageとは、アプリを起動した際に表示されるロゴのことである。
Player SettingsのSplash Image欄で様々な設定が可能
参照サイト
・Shader precision model
シェーダーで使用されるサンプラーのデフォルトの精度を制御できる。
参照サイト、参照サイト
・Load/Store Action Debug Mode
モバイルプラットフォームでレンダリングの問題を引き起こす可能性のある未定義のピクセルをハイライトします。
参照サイト
・Minimum API LevelとTarget API Levelで、OSのバージョン調整する必要がある
参照サイト、参照サイト
・iOS,Android デバイスで、アプリケーションの画面の向きをScreen.orientationを使用してい制御できる。
自動回転の制御もできるプロパティもある。
参照サイト、参照サイト
・Android 向けシングルパスステレオレンダリング
Unity はマルチビューをサポートする Android デバイスの シングルパスステレオレンダリング をサポートします。
VRとかXRでアプリを作成する際は、シェーダーを書く際気を付ける必要がある。
詳しくは参照サイトをチェック
参照サイト
・AndroidのBuild SettingsのTexture Compression
ビルドに使用するテクスチャ圧縮形式。
以下の設定項目がある。
Use Player Settings: Player Settingsで設定したテクスチャ圧縮形式を使用します。
ETC (GLES 2.0): ETC 形式を使用します。
ETC2 (GLES 3.0): ETC2 形式を使用します。
ASTC: ASTC 形式を使用します。
DXT (Tegra): DXT 形式を使用します。
PVRTC (PowerVR): PVRTC 形式を使用します。
参照サイト
・ロードしているときのぐるぐるを表示
Handheld.StartActivityIndicatorで実現可能
参照サイト
・VFXToolboxでUnity上で一つ一つのテクスチャを一枚のテクスチャにできる
参照サイト
Discussion