【问题标题】:How to create a diagonal HLSL transition shader如何创建对角线 HLSL 过渡着色器
【发布时间】:2016-01-03 05:22:13
【问题描述】:

我正在尝试调整 Codeplex 上 WPF 像素着色器效果库中的几个 HLSL 着色器的代码,以创建一个像素着色器,该着色器通过在 Texture1 上滑动 Texture2 来创建从 Texture1 到 Texture2 的对角线过渡,就好像它正在覆盖一样(即 Texture1 保持“静止”,而 Texture2 逐渐取代 Texture1)从左上角开始。

我正在努力正确理解“uv”符号以及如何操纵它以实现我的目标。

到目前为止我已经尝试过

float Progress : register(C0);

sampler2D Texture1 : register(s0);
sampler2D Texture2 : register(s1);

struct VS_OUTPUT
{
    float4 Position  : POSITION;
    float4 Color     : COlOR;
    float2 UV        : TEXCOORD;
};

float4 SampleWithBorder(float4 border, sampler2D tex, float2 uv)
{
    if (any(saturate(uv) - uv))
{
    return border;
}
else
{
    return tex2D(tex, uv);
}
}

float4 SlideDiagonal(float2 uv,float progress)
{
  uv += progress;

  float4 c1 = SampleWithBorder(float4(0,0,0,0), Texture2, uv);

  if(c1.a <=0)
  {
        return tex2D(Texture1, uv);
  }

  return c1;
}

//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 main(VS_OUTPUT input) : COlOR
{
  return SlideDiagonal(input.UV, Progress/100);
}

还有

float Progress : register(C0);

sampler2D Texture1 : register(s1);
sampler2D Texture2 : register(s0);


float4 SampleWithBorder(float4 border, sampler2D tex, float2 uv)
{
if (any(saturate(uv) - uv))
{
    return border;
}
else
{
    return tex2D(tex, uv);
}
}

float4 Shrink(float2 uv,float progress)
{
float speed = 200;
float2 center = float2(0.001, 0.001);
float2 toUV = uv - center;
float distanceFromCenter = length(toUV);
float2 normToUV = toUV / distanceFromCenter;

float2 newUV = center + normToUV * (distanceFromCenter *(progress*speed+1));

float4 c1 = SampleWithBorder(float4(0,0,0,0), Texture2, newUV); 

if(c1.a <= 0)
{
    return tex2D(Texture1, uv);
}

return c1;

}

//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 main(float2 uv : TEXCOORD) : COlOR
{
return Shrink(uv, Progress/100);
}

但在这两种情况下,“幻灯片”都会反向操作,随着进度增加到 1,可见 Texture2 的数量会减少,而在前者的情况下,Texture1 根本不显示。

圣诞节期间,我多次回到这个问题上,但无济于事,现在我认为我正在遭受“以木换树”的问题。

如果有人知道这个特定问题的解决方案,将不胜感激。

本着“教人钓鱼”的精神,如果有任何信息可以帮助我理解如何操纵“紫外线”,那也很棒。

非常感谢您的帮助 问候 伊恩·卡森

【问题讨论】:

    标签: wpf hlsl pixel-shader


    【解决方案1】:

    纹理坐标 (uv) 指定查看纹理的位置。随着线

    uv += progress;
    

    您根据进度移动纹理坐标。如果为零,则使用原始坐标(并显示整个Texture2)。通过增加progress,你越来越多地走到Texture2的右下角,并在原来的位置绘制它。这让纹理滑向左上角。因此,如果您想要反过来,请尝试:

    uv += 1 - progress;
    

    【讨论】:

      【解决方案2】:

      非常感谢 Nico 在树上开辟了一片空地!他的回答让我改变了解决这个问题所需的观点。 @Nico - 为你点赞,谢谢伙计。

      为了完整起见,我已经包含了我的 Shazzam 修补程序的最终结果,它允许使用称为(想象中的)“Corner”的浮动输入从 4 个角中的任何一个角进行对角线滑动。在生产中,浮点数将被一个从可能的角枚举驱动的 int 替换 - TopLeft、TopRight、BottomRight、BottomLeft。代码中的顺序如1、2、3、4所示。

      这是着色器:

      /// <summary>Modifies the Progress value.</summary> 
      /// <minValue>0</minValue>
      /// <maxValue>100</maxValue>
      /// <defaultValue>0</defaultValue>
      float Progress : register(C0);
      
      /// <summary>Modifies the Corner value.</summary> 
      /// <minValue>1</minValue>
      /// <maxValue>1</maxValue>
      /// <defaultValue>1</defaultValue>
      float Corner : register(C1);
      
      sampler2D Texture1 : register(s0);
      sampler2D Texture2 : register(s1);
      
      float4 SampleWithBorder(float4 border, sampler2D tex, float2 uv, float corner)
      {
          if (any(saturate(uv) - uv))
          {
              return border;
          }
          else
          {
              float2 rev = uv;
      
              //Swap y position again to counteract the inversion caused by 
              //needing to get to get to corners BottomLeft and TopRight
              if(corner >=2 && corner < 3 || corner>=4
              {
                  rev.y = 1 - rev.y;
              }
      
              return tex2D(tex, rev);
          }
      }
      
      float4 SlideDiagonal(float2 uv, float progress, float corner)
      {
        float2 rev = uv;
      
        //Swap y position to get to corners BottomLeft and TopRight
        if(corner >=2 && corner < 3 || corner>=4)
        {
            rev.y = 1 - rev.y;
        }
      
        float2 newUV;
      
        //TopLeft
        if(corner >= 1 && corner < 2)
        {
            newUV = rev + (1- progress);
        }
      
        //TopRight
        if(corner >= 2 && corner < 3)
        {
            newUV = rev - (1- progress);
        }
      
        //BottomRight
        if(corner >= 3 && corner < 4)
        {
            newUV = rev - (1- progress);
        }
      
        //BottomLeft
        if(corner >= 4)
        {
            newUV = rev + (1- progress);
        }
      
      
        float4 c1 = SampleWithBorder(float4(0,0,0,0), Texture2, newUV, corner);
      
        if(c1.a <=0)
        {
            return tex2D(Texture1, uv);
        }
      
        return c1;
      }
      
      //--------------------------------------------------------------------------------------
      // Pixel Shader
      //--------------------------------------------------------------------------------------
      float4 main(float2 input : TEXCOORD) : COlOR
      {
        return SlideDiagonal(input, Progress/100, Corner);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多