Вершина смещения в шейдере единицы с использованием входных пиксельных данных текстуры
Я реализую постпроцессный эффект в единстве. Я хочу использовать изображение 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);
Это производит это изображение (уменьшенный, чтобы импортировать рассматриваемый)
вот мой код шейдера
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;
Выход: