Shader实验室:remap函数

Number of views 280

remap字面意思为重映射,它将值从一个范围重映射到另一个范围。该算法不属于shader api的一部分,但是在实际开发中又显得很重要。

image.png

上图演示的是用remap算法把uv的横纵坐标从01范围转变为-11范围(UV坐标从左下角开始计算),remap算法与smoothstep算法(可参考Shader实验室:smoothstep函数一节)中的某一部分计算方式有点类似,下面我们进入原理部分。

原理

要介绍remap算法,就不得不先介绍下它的公式。

remap算法公式: y = (x - t1) / (t2 - t1) * (s2 - s1) + s1。

先分析其前半部分: y = (x - t1) / (t2 - t1)。

假设 t2 = 0.7, t1 = - 0.8 代入至公式中,可得:

y = (x - (-0.8)) / (0.7 - (-0.8)),从代入式可知:

当 x = -0.8 时,y = 0;

当 x = 0.7 时,y = 1;

根据结论我们作图如下:

image.png

根据求取的结果与示意图,我们可得出如下结论:

当x = t1时,y = 0;

当x = t2时,y = 1;

该结论很重要,它可以使我们很容易在思考该类问题时,在大脑中建立抽象的坐标系,这让我们处理图形图像相关问题时显得更加得心应手。

前半部分的计算我们已经分析完毕了,其实这部分算法也是remap算法,因为它已经能让我们达到重映射的目的了。接下来我们结合整个公式进行分析,分析方式还是以代入数字的方式进行。

对 y = (x - t1) / (t2 - t1) * (s2 - s1) + s1 公式进行数字代入。

假设 t2 = 0.7,t1 = -0.8保持不变,令s2 = 0.3,s1 = 0.2待入至公式得:

y = (x - (-0.8)) / (0.7 - (-0.8)) * (0.3 - 0.2) + 0.2。

根据代入结果,作图如下:

image.png

可得结果:

当 x = -0.8时,y = 0.2;

当 x = 0.7 时, y = 0.3;

也就是,

当 x = t1 时,y = s1;

当 x = t2 时,y = s2;

根据分析结果,下面进入实验部分,我们会做出文章开头那张图片的效果,并对其进行进一步处理。

实验

  • 首先新建Shader与材质文件,Shader文件选择Unlit类型。
  • 在Shader Pass内部定义remap函数,如下:
half remap(half x, half t1, half t2, half s1, half s2)
{
    return (x - t1) / (t2 - t1) * (s2 - s1) + s1;
}
  • 在Pass中的frag函数进行如下操作:
fixed4 frag (v2f i) : SV_Target
{
    //当uv.x = 0时,结果等于 s1 = -1
    //当uv.x = 1.0时,结果等于 s2 = 1  
    half remapX = remap(i.uv.x, 0, 1.0, -1.0, 1.0);
    //当uv.y = 0时,结果等于 s1 = -1
    //当uv.y = 1.0时,结果等于 s2 = 1
    half remapY = remap(i.uv.y, 0, 1.0, -1.0, 1.0);
    return float4(remapX, remapX, 0, 1);
}
  • 完成Shader代码,赋值该Shader到新建的材质,并把该材质赋予Quad
  • 得到的结果如下:

image.png

感兴趣的小伙伴可扫描下方二维码关注我们。

image.png

0 Answers