Custom Render Texture で存在しないパスを参照するとクラッシュします.
2021.X で Fixed ですが,2022.X でも発生します.Unity 6.0 では発生しません.
また,上記の Issue にあるように,別のマテリアルをアタッチしたり,アタッチされているマテリアルのシェーダーを別のシェーダーに変更したりしてクラッシュした場合は,Unity が自動で修正してくれて,次にプロジェクトを開くときにはクラッシュが発生しないような状態になっています.
しかし,シェーダーを直接編集してクラッシュした場合は Unity が何とかしてくれるとは限らないので自力で直す必要があります.場合によってはプロジェクトを開くことすらできなくなるので割と焦りますが,実はたいしたことないです.
再現手順
Custom Render Texture 用に複数のパスを持つシェーダーを作成します.
Shader "Test/CrtCrasher/Sample"
{
Properties {}
CGINCLUDE
#pragma vertex CustomRenderTextureVertexShader
#pragma fragment frag
#include "UnityCustomRenderTexture.cginc"
ENDCG
SubShader
{
Pass
{
CGPROGRAM
float4 frag(v2f_customrendertexture IN) : SV_Target
{
return float4(0,0,0,1);
}
ENDCG
}
Pass
{
CGPROGRAM
float4 frag(v2f_customrendertexture IN) : SV_Target
{
return float4(0,0,0,1);
}
ENDCG
}
}
}
Custom Render Texture を作成し,上記のシェーダーの最後のパス <Unnamed Pass 1> を選択します.特に,Update Zones で選択する Shader Pass をシェーダーの最後のパスにしておくと,クラッシュしたときに Unity が自動で修正してくれなくなります.
Initialization Mode は OnLoad, Update Mode は Realtime にしておくとよさそうです.
Scene 上に Quad を置いて,Unlit/Texture などのマテリアルをアタッチし,作成した Custom Render Texture をテクスチャとしてセットします.
また,Scnene View で,Always Reflesh を有効にしておきます.
こうすることで,クラッシュ後にプロジェクトを開くことができなくなります.
ここまでセットアップできたら,一度 Scene を保存し,プロジェクトを閉じます.プロジェクトを閉じることで,Always Refresh の設定変更が確実に保存されます.
再びプロジェクトを開きます.
先ほど作成したシェーダーを開き,最後のパスをコメントアウトします.
Shader "Test/CrtCrasher/Sample"
{
Properties {}
CGINCLUDE
#pragma vertex CustomRenderTextureVertexShader
#pragma fragment frag
#include "UnityCustomRenderTexture.cginc"
ENDCG
SubShader
{
Pass
{
CGPROGRAM
float4 frag(v2f_customrendertexture IN) : SV_Target
{
return float4(0,0,0,1);
}
ENDCG
}
// Pass
// {
// CGPROGRAM
// float4 frag(v2f_customrendertexture IN) : SV_Target
// {
// return float4(0,0,0,1);
// }
// ENDCG
// }
}
}
Unity にフォーカスするとシェーダーがコンパイルされ,Unity がクラッシュします.
再びプロジェクトを開くと,ウィンドウ自体は開きますが,画面が真っ白のままクラッシュして落ちるようになります.
解決法① シェーダーにパスを追加する
シェーダーをいじったせいでクラッシュしたので,元に戻せば直ります.
また,Custom Render Texture でのパスの参照は,「上から何番目のパスか」しか見ていないので,Custom Render Texture で元々どのパスを参照していたかわからなくても,該当のシェーダーに適当なパスをたくさん追加しておけばクラッシュは起きなくなります.
Shader "Test/CrtCrasher/Sample"
{
Properties {}
CGINCLUDE
#pragma vertex CustomRenderTextureVertexShader
#pragma fragment frag
#include "UnityCustomRenderTexture.cginc"
ENDCG
SubShader
{
Pass
{
CGPROGRAM
float4 frag(v2f_customrendertexture IN) : SV_Target
{
return float4(0,0,0,1);
}
ENDCG
}
// Pass
// {
// CGPROGRAM
// float4 frag(v2f_customrendertexture IN) : SV_Target
// {
// return float4(0,0,0,1);
// }
// ENDCG
// }
Pass
{
CGPROGRAM
float4 frag(v2f_customrendertexture IN) : SV_Target
{
return float4(0,0,0,1);
}
ENDCG
}
Pass
{
CGPROGRAM
float4 frag(v2f_customrendertexture IN) : SV_Target
{
return float4(0,0,0,1);
}
ENDCG
}
Pass
{
CGPROGRAM
float4 frag(v2f_customrendertexture IN) : SV_Target
{
return float4(0,0,0,1);
}
ENDCG
}
}
}
解決法② Custom Render Texture を削除する
プロジェクトを開くことすらできないとエディタ上で削除することもできませんが,そもそもファイルエクスプローラ(MacならFinder)上で削除してしまえば,当然クラッシュもなくなります.Custom Render Texture の拡張子は .asset です.
解決法③ 参照 Pass をテキストエディタで変更する
Custom Render Texture はテクスチャですが,定義自体は YAML ファイルなので,テキストエディタで編集できます.
今回作成した Custom Render Texture をテキストエディタで開いてみます.
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!86 &8600000
CustomRenderTexture:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Sample
m_ImageContentsHash:
serializedVersion: 2
Hash: 00000000000000000000000000000000
m_ForcedFallbackFormat: 4
m_DownscaleFallback: 0
m_IsAlphaChannelOptional: 0
serializedVersion: 5
m_Width: 256
m_Height: 256
m_AntiAliasing: 1
m_MipCount: -1
m_DepthStencilFormat: 94
m_ColorFormat: 8
m_MipMap: 0
m_GenerateMips: 1
m_SRGB: 0
m_UseDynamicScale: 0
m_BindMS: 0
m_EnableCompatibleFormat: 1
m_EnableRandomWrite: 0
m_TextureSettings:
serializedVersion: 2
m_FilterMode: 1
m_Aniso: 0
m_MipBias: 0
m_WrapU: 1
m_WrapV: 1
m_WrapW: 1
m_Dimension: 2
m_VolumeDepth: 1
m_ShadowSamplingMode: 2
m_Material: {fileID: 2100000, guid: (ユニークな値が入ります), type: 2}
m_InitSource: 0
m_InitMaterial: {fileID: 0}
m_InitColor: {r: 1, g: 1, b: 1, a: 1}
m_InitTexture: {fileID: 0}
m_UpdateMode: 1
m_InitializationMode: 0
m_UpdateZoneSpace: 0
m_CurrentUpdateZoneSpace: 0
m_UpdateZones:
- updateZoneCenter: {x: 0.5, y: 0.5, z: 0.5}
updateZoneSize: {x: 1, y: 1, z: 1}
rotation: 0
passIndex: 1
needSwap: 0
m_UpdatePeriod: 0
m_ShaderPass: 0
m_CubemapFaceMask: 4294967295
m_DoubleBuffered: 0
m_WrapUpdateZones: 0
下から11行目に m_UpdateZones: とあり,ここが Update Zones のリストであることがわかります.リストの要素に passIndex: 1 とあるので,これを passIndex: 0 など存在するパスに変更して保存すればクラッシュはなくなります.
原因の Custom Render Texture がわからない場合
基本的にはシェーダーを自分で編集した場合にしか発生しない現象なので,原因となる Custom Render Texture はわかるはずですが,わからない場合はしらみつぶしに探すしかなさそうです.
とりあえず,プロジェクトを開くために,クラッシュが発生したときに開いていた Scene を封印します.
ファイルエクスプローラで該当の Scene を探します.Scene の拡張子は .unity です.
見つかったら,拡張子を .txt などに変更します.
この状態でプロジェクトを開くと,「Untitled」というデフォルトのシーンが開きます.
あとはひたすらファイルをあさって原因の Custom Render Texture を探します.クラッシュの原因となっている Custom Render Texture は選択しただけで Unity がクラッシュするはずなのですぐに判別できます.見つかったら上で説明したどれかの手段で修正してください.
解決したら,拡張子を変更した Scene ファイルをもとの拡張子 .unity に戻してください.
雑記
このクラッシュは Unity 6.0 では発生しないので,もはや VRChatter にしか役立たない情報ですが... でもまだしばらくは 2022.3 のままなんじゃないかという気がしています.





