2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Unity】モバイルのVertexシェーダーでテクスチャのBilinearサンプルができない

2
Posted at

シェーダーはFragmentシェーダーでテクスチャをサンプルするのが普通ですが,GPUパーティクルなどではVertexシェーダーでもテクスチャをサンプルします.
Vertexシェーダーでテクスチャをサンプルする場合でも,テクスチャの設定でFilterをBilinearに設定しておけば tex2Dlod() などでサンプルするときに線形補間されます.
...と思っていたのですが,モバイル環境では強制的にPointサンプルになる場合があるようです.SampleLevel() も試してみましたがダメでした.

仕方ないのでマニュアルでBilinearサンプルにします.

Sampler sampler_point_clamp;

float4 BilinearSample( Texture2D<float4> tex, float4 texelSize, float2 uv )
{
    float4 scaledUv;
    scaledUv.xy = uv * texelSize.zw - 0.5;
    scaledUv.zw = scaledUv.xy + 1.0;
    scaledUv = clamp( scaledUv, 0, texelSize.zwzw - 1.0 );
    float2 ratio = frac( scaledUv.xy );
    float4 sampleUv = ( floor( scaledUv ) + 0.5 ) * texelSize.xyxy;

    float4 c00 = tex.SampleLevel( sampler_point_clamp, sampleUv.xy, 0 );
    float4 c10 = tex.SampleLevel( sampler_point_clamp, sampleUv.zy, 0 );
    float4 c01 = tex.SampleLevel( sampler_point_clamp, sampleUv.xw, 0 );
    float4 c11 = tex.SampleLevel( sampler_point_clamp, sampleUv.zw, 0 );

    return lerp(
        lerp( c00, c10, ratio.x ),
        lerp( c01, c11, ratio.x ),
        ratio.y
    );
}

#define BILINEAR_SAMPLE( tex, uv ) BilinearSample( tex, tex##_TexelSize, uv )

...

Texture2D<float4> _MainTex;
float4 _MainTex_TexelSize;

v2f vert( appdata v )
{
    ...
    
    float4 data = BILINEAR_SAMPLE( _MainTex, v.uv.xy );

    ...
}

こんな感じでしょうか.サンプルの負荷が増えそうですが,仕方がないですね.
VertexステージでBilinearサンプルしなくて済むように設計するのがベストなんだと思います.

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?