モバイル環境 (Android, Quest) でテクスチャをメモリとして使いたいときにサンプル方法でつまずいたので記録しておきます.
問題
シェーダーでテクスチャをサンプルする場合,普通は tex2D* を使います.
sampler2D _MainTex;
float4 flag( v2f IN ) : SV_Target
{
...
float4 tex = tex2Dlod( _MainTex, float4( IN.uv.xy, 0, 0 ) );
...
}
サンプルするテクスチャが R32G32B32A32_SFloat の場合,PC 環境では期待通りに動作しますが,モバイル環境 だとなぜか half4 の精度になってしまいます.
対策
Sample* を使うと,モバイル環境でも float4 でサンプルできました12.
Texture2D<float4> _MainTex;
SamplerState sampler_MainTex;
float4 flag( v2f IN ) : SV_Target
{
...
float4 tex = _MainTex.SampleLevel( sampler_MainTex, IN.uv.xy, 0 );
...
}
ちなみに,筆者の手元の Android スマホと Quest3 でしか試していないので,一般的に使える方法なのかは不明です.
雑記
PC 環境では float half fixed は全部 float になるらしいですが,モバイル環境では half はちゃんと half みたいなので要注意ですね.UnityCG.cginc にある v2f_img の uv がなぜか half2 だったので地味に嵌りました.
ちなみに,fixed は OpenGL ES 2.0 までしかサポートされていないそうです3.モバイルですら登場することはもうなさそうな気がします.