《Unity着色器圣经》4.0.9. | Ceil function.

目录索引

译文

根据NVIDIA的官方文档:

Ceil returns the smallest integer not less
than a scalar or each vector component.

这是什么意思?函数ceil(n)将返回一个整数,也就是说,没有小数,接近其参数,例如,如果数字等于0.5f,ceil将返回1。

ceil(0.1) = 1
ceil(0.3) = 1
ceil(1.7) = 2
ceil(1.3) = 2

0.0f和1.0f之间的所有数字都将返回1,因为后者将是不小于其参数的最小整数值。

其语法如下:

// it returns an integer value
float ceil(float n)
{
    return -floor(-n);
}

float2 ceil (float2 n);
float3 ceil (float3 n);
float4 ceil (float4 n);

此功能对于在电子游戏中生成“缩放或放大镜”效果非常有用。要做到这一点,我们只需计算U和V坐标的ceil(n)值,将最终值乘以0.5,然后在UV的默认值和ceil(n)函数产生的值之间生成线性插值。

为了深入理解这个概念,我们将执行以下操作:我们将创建一个新的着色器类型“Unlit shader”,我们将称之为USB_function_CEIL,并在片段着色器阶段声明纹理_MainTex的新UV坐标。

fixed4 frag (v2f i) : SV_Target
{
    // let's ceil the U coordinate
    float u = ceil(i.uv.x);
    // let's ceil the V coordinate
    float v = ceil(i.uv.y);
    // we assign the new values for the texture
    fixed4 col = tex2D(_MainTex, float2(u, v));
    UNITY_APPLY_FOG(i.fogCoord, col);
    return col;
}

我们在上面执行的操作将返回纹素位置[1,1],原因是什么?因为U和V坐标都从0.0f开始,到1.0f结束,所以ceil(n)将只返回纹理中的最后一个texel。因此,它将生成从纹理的右上角点到左下角的缩放效果。

图片[1]-《Unity着色器圣经》4.0.9. | Ceil function.-软件开发学习笔记

对于这种效果,我们需要一个可以增加或减少纹理大小的属性。为此,我们将转到属性并声明一个浮动范围,我们将称之为_Zoom。

Shader "USB/USB_function_CEIL"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Zoom ("Zoom", Range(0, 1)) = 0
    }
}

在该范围内,“0”表示零缩放,“1”相当于百分之百。然后我们在程序中声明连接变量。

Pass
{
   ...
    sampler2D _MainTex;
    float4 _MainTex_ST;
    float _Zoom;
   ...
}

由于我们需要缩放点从纹理的中心开始,我们可以通过将运算乘以0.5来修改其位置,如下所示:

fixed4 frag (v2f i) : SV_Target
{
    // let's ceil the U coordinate
    float u = ceil(i.uv.x) * 0.5;
    // Let's do the same with the V coordinate
    float v = ceil(i.uv.y) * 0.5;

    // we assign the new values for the texture
    fixed4 col = tex2D(_MainTex, float2(u, v));

    UNITY_APPLY_FOG(i.fogCoord, col);
    return col;
}

此时,纹理已从其中心展开。然而,我们仍然无法欣赏缩放效果,因为ceil(n)函数继续返回1;因此,我们将继续看到单一颜色填充四边形区域。我们可以做的是在UV的默认值和ceil(n)函数产生的值之间生成线性插值,

fixed4 frag (v2f i) : SV_Target
{
    float u = ceil(i.uv.x) * 0.5;
    float v = ceil(i.uv.y) * 0.5;
    float uLerp = lerp(u, i.uv.x, _Zoom);
    float vLerp = lerp(v, i.uv.y, _Zoom);

    // we assign the new values for the texture
    fixed4 col = tex2D(_MainTex, float2(uLerp, vLerp));

    UNITY_APPLY_FOG(i.fogCoord, col);
    return col;
}

在上面的例子中,我们为不同的坐标创建了两个名为uLerp和vLerp的变量。我们正在通过属于Cg/HLSL语言的lerp(x,y,s)函数进行线性插值。此外,还包括了属性_Zoom,其范围在0.0f到1.0f之间。如果我们从Unity Inspector中修改属性_Zoom的值,我们可以看到纹理是如何增加或减少其大小的,并将其中心点作为参考。

图片[2]-《Unity着色器圣经》4.0.9. | Ceil function.-软件开发学习笔记

原文对照

According to NVIDIA’s official documentation,

Ceil returns the smallest integer not less
than a scalar or each vector component.

What does this mean? The function ceil(n) will return an integer, that is, without decimals, close to its argument, e.g., if the number is equal to 0.5f, ceil will return one.

ceil(0.1) = 1
ceil(0.3) = 1
ceil(1.7) = 2
ceil(1.3) = 2

All numbers between 0.0f and 1.0f will return one, since the latter would be the smallest integer value no less than its argument.
its syntax is the following:

// it returns an integer value
float ceil(float n)
{
    return -floor(-n);
}

float2 ceil (float2 n);
float3 ceil (float3 n);
float4 ceil (float4 n);

This function is quite helpful for generating “zoom or magnifying glass” effects in a video game. To do this, we simply have to calculate the value of ceil(n) for both the U and V coordinates, multiply the final value by 0.5 and then generate a linear interpolation between the UV’s default values and those resulting from the ceil(n) function.
To understand the concept in-depth, we will do the following: We will create a new shader type, “Unlit Shader”, which we will call USB_function_CEIL, and we will start by declaring the new UV coordinates for the texture _MainTex, in the fragment shader stage.

fixed4 frag (v2f i) : SV_Target
{
    // let's ceil the U coordinate
    float u = ceil(i.uv.x);
    // let's ceil the V coordinate
    float v = ceil(i.uv.y);
    // we assign the new values for the texture
    fixed4 col = tex2D(_MainTex, float2(u, v));
    UNITY_APPLY_FOG(i.fogCoord, col);
    return col;
}

The operation we performed above will return the texel position [1, 1], for what reason? Because both the U and V coordinates start at 0.0f and end at 1.0f, ceil(n) will only return the last texel in the texture. Consequently, it will generate a zoom effect that will go from the upper right point of the texture to the lower-left end.

图片[1]-《Unity着色器圣经》4.0.9. | Ceil function.-软件开发学习笔记

For this effect, we will need a property that allows us to increase or decrease the size of the texture. To do this, we will go to the properties and declare a floating range that we will call _Zoom.

Shader "USB/USB_function_CEIL"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Zoom ("Zoom", Range(0, 1)) = 0
    }
}

In the range, “0” symbolizes zero per cent zoom, and “1” is equivalent to one hundred per cent. Then we declare the connection variable within the program.

Pass
{
   ...
    sampler2D _MainTex;
    float4 _MainTex_ST;
    float _Zoom;
   ...
}

Since we need the zoom point to start in the center of the texture, we can modify its position by multiplying the operation by 0.5 as follows:

fixed4 frag (v2f i) : SV_Target
{
    // let's ceil the U coordinate
    float u = ceil(i.uv.x) * 0.5;
    // Let's do the same with the V coordinate
    float v = ceil(i.uv.y) * 0.5;

    // we assign the new values for the texture
    fixed4 col = tex2D(_MainTex, float2(u, v));

    UNITY_APPLY_FOG(i.fogCoord, col);
    return col;
}

At this point, the texture is already expanding from its center. However, we still can not appreciate the zoom effect since the ceil(n) function continues returning one; therefore, we will continue to see a single color filling the Quad area. What we can do is generate a linear interpolation between the UV’s default values and those resulting from the ceil(n) function,

fixed4 frag (v2f i) : SV_Target
{
    float u = ceil(i.uv.x) * 0.5;
    float v = ceil(i.uv.y) * 0.5;
    float uLerp = lerp(u, i.uv.x, _Zoom);
    float vLerp = lerp(v, i.uv.y, _Zoom);

    // we assign the new values for the texture
    fixed4 col = tex2D(_MainTex, float2(uLerp, vLerp));

    UNITY_APPLY_FOG(i.fogCoord, col);
    return col;
}

In the example above, we created two variables called uLerp and vLerp for the different coordinates. We are doing a linear interpolation through the lerp(x, y, s) function belonging to the Cg/HLSL language. In addition, the property _Zoom has been included, which has a range between 0.0f and 1.0f. If we modify the values of the property _Zoom from the Unity Inspector, we can see how the texture increases or decreases its size, taking as a reference its central point.

图片[2]-《Unity着色器圣经》4.0.9. | Ceil function.-软件开发学习笔记
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容