Вершина смещения в шейдере единицы с использованием входных данных пикселей текстуры - PullRequest
0 голосов
/ 01 декабря 2018

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

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

Для тестирования моего шейдера я хочу использоватьидентичный входной 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);

Он создает это изображение (уменьшенное для импорта в вопросе)

displacement mask 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
        }
    }
}

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

original

affected

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

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

float targetX = translation.g;

Выход:

only green channel

...