Вершина смещения в шейдере единицы с использованием входных пиксельных данных текстуры

Я реализую постпроцессный эффект в единстве. Я хочу использовать изображение RGBA в качестве ссылки на данные о смещении вершин. Например, координата каждой вершины (i, j) найти данные по другой позиции (x, y) основной текстуры, которая x, y являются значениями, извлеченными из текстуры RGBA.

Целочисленные значения в красном (как более важные биты) и зеленом (как менее важные биты) каналах, которые используются для создания двухбайтового целого числа, показывают значение горизонтальной оси ссылочного пикселя, поэтому синие и альфа-каналы показывают значение вертикальной оси.

Для тестирования моего шейдера я хочу использовать идентичный входной размер изображения png (1920, 1080). поэтому я использую эти строки кода для создания такого изображения

System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(Convert.ToInt32(1920), Convert.ToInt32(1080), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
for (int i=0; i<1920; i++)
{
    for (int j=0; j<1080; j++)
    {
        bitmap.SetPixel(i, j, System.Drawing.Color.FromArgb(j%256, i/256, i%256, j/256));
    }
}
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);
bitmap.Save(@"MYPATH", System.Drawing.Imaging.ImageFormat.Png);

Это производит это изображение (уменьшенный, чтобы импортировать рассматриваемый)

маска смещения png

вот мой код шейдера

Shader "JShaders/Warp"
{
    HLSLINCLUDE
        #include "PostProcessing/Shaders/StdLib.hlsl"
        #define UNITY_MATRIX_MVP mul(unity_MatrixVP, unity_ObjectToWorld)

        TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
        TEXTURE2D_SAMPLER2D(_WarpTex, sampler_WarpTex);

        struct Attributes
        {
            float4 position : POSITION;
        };

        struct Varyings
        {
            float4 position : SV_POSITION;
            float3 worldPosition : TEXCOORD0;
            float2 texcoord : TEXCOORD1;
            float2 texcoordStereo : TEXCOORD2;
        };

        Varyings Vert(Attributes v)
        {
            Varyings o;
            o.position = float4(v.position.xy, 0.0, 1.0);
            o.texcoord = TransformTriangleVertexToUV(v.position.xy);
            #if UNITY_UV_STARTS_AT_TOP
            o.texcoord = o.texcoord * float2(1.0,-1.0) + float2(0.0, 1.0);
            #endif
            o.texcoordStereo = TransformStereoScreenSpaceTex(o.texcoord, 1.0);
            o.worldPosition = mul(unity_ObjectToWorld, v.position);
            return o;
        }

        float4 Frag(Varyings i) : SV_Target
        {
            // _ScreenParams.x = 1920
            // _ScreenParams.y = 1080
            float4 translation = SAMPLE_TEXTURE2D(_WarpTex, sampler_WarpTex, i.texcoordStereo);

            float targetX = ((translation.g * 256) / 1920) - (translation.r * 256 * 256 / 1920);    
            float targetY = i.texcoordStereo.y;

            return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, float2(targetX, targetY));
        }
    ENDHLSL

    SubShader
    {
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            HLSLPROGRAM
                #pragma vertex Vert
                #pragma fragment Frag
            ENDHLSL
        }
    }
}

Как видите, я сейчас обеспокоен только горизонтальным смещением. Вот мой оригинальный и затронутый результат рендеринга:

оригинал

пострадавших

Он должен быть одинаковым (без смещения). В чем проблема?

Обновление: Когда я использую только значение зеленого канала, как показано ниже, вывод корректен. Проблема с красным значением канала:

float targetX = translation.g;

Выход:

только зеленый канал

0 ответов

Другие вопросы по тегам