使用输入纹理像素数据的统一着色器中的位移顶点

时间:2018-12-01 17:45:50

标签: c# unity3d shader hlsl post-processing

我正在统一实现后处理效果。我想使用RGBA图像作为顶点位移数据的参考。例如,每个顶点坐标(i, j)在主要纹理的另一个位置(x, y)上发现数据x, y是从RGBA纹理提取的值。

用于制作2字节整数的红色(较重要的位)和绿色(较不重要的位)通道的整数值显示参考像素的水平轴值,蓝色和alpha通道显示垂直轴值。

要测试我的着色器,我想使用相同的输入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

0 个答案:

没有答案