6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Unity]Blitで上下反転して描画される問題

Posted at

原因

GPUによって描画する際のy座標の0の基準が異なるらしいです。

  • Direct3D系:座標の一番 上が0。Direct3D、Metalなど
  • OpenGL 類:座標の一番 下が0。OpenGL、OpenGL ESなど

で、基本的にこれはUnityは勝手に吸収してくれるようなのですが、レンダテクスチャに描くときにその吸収する仕組みが悪さすることがあるようです。

▼参考:公式ドキュメント

対策

この仕組みが原因で上下反転する場合は、シェーダ書いて解決してね、と上記の公式ドキュメントに書いてありました。
具体的には DirectX系/Metalのときのみ、vertexシェーダーでUVを反転をさせるようです。

ReverseResolve.shader
#if UNITY_UV_STARTS_AT_TOP
    // DirectX系, Metalの場合はY軸反転.
    o.uv.y = 1 - o.uv.y;
#endif

UNITY_UV_STARTS_AT_TOPを使って、座標の一番上が0のGPUであるかどうかを分岐させ、trueの場合のみ反転させています。
これで解決できました。

余談

今回の件でハマったときいろいろ調べてたら、「CommandBufferでレンダリング結果を利用する場合には、Camera.forceIntoRenderTextureを有効にすると良い」という記事も見かけました。

自分のケースには当てはまりませんでしたが、そういうこともあるみたいです。

また、CommandBuffer.Blitの内部で行われるいろいろな処理分岐によるハマりポイント的な記事も見かけたので、こちらも備忘録として記載しておきます。

これ↓とかよく分からないけど何らかのハマりポイントになりそう…。

AfterEverything開始時の、CurrentActive, CameraTargetをsrcとしたBlit命令は、内部でBlit Copyではなく、Back BufferをsrcとしたGrab RenderTextureが発生する

シェーダー全文

ReverseResolve.shader
Shader "Camera/ReverseResolve"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
#if UNITY_UV_STARTS_AT_TOP
                // DirectX系, Metalの場合はY軸反転.
                o.uv.y = 1 - o.uv.y;
#endif
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                return col;
            }
            ENDCG
        }
    }
}
6
4
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
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?