目录索引
译文
这个函数指的是一个数字的绝对值,作为参数,我们可以传递标量值和向量。
其语法如下:
// return the absolute value of n
float abs(float n)
{
return max(-n, n);
}
float2 abs (float2 n);
float3 abs (float3 n);
float4 abs (float4 n);
一个绝对值总是会返回到一个正数,它的数学符号由两个框住一个数字的边条组成。
|−3| = 3 absolute value of −3 equals 3
|−5| = 5 absolute value of −5 equals 5
| 6 | = 6 absolute value of 6 is equal to itself
我们的程序可以使用abs(n)函数实现多种效果,包括重新创建万花筒或生成三平面图。事实上,对于第一种情况,我们可以通过计算UV坐标中的绝对值来执行这样的效果。同时,在三平面映射中,我们可以确定网格法线的绝对值,从而在正轴和负轴上生成投影。
![图片[1]-《Unity着色器圣经》4.0.8. | Abs function.-软件开发学习笔记](https://gamedevfan.cn/wp-content/uploads/2025/05/image-49-1024x432.jpeg)
如果我们注意上图UV坐标中的起点,我们会注意到U坐标以四边形为中心减去0.5f,最小值变成负数 [-0.5f].
在本例中,纹素会被拉伸,因为纹理已设置选项“wrap mode”的值为“clamp”。在这种情况下,我们可以应用绝对值来生成“镜像”效果。
![图片[2]-《Unity着色器圣经》4.0.8. | Abs function.-软件开发学习笔记](https://gamedevfan.cn/wp-content/uploads/2025/05/image-48-1024x475.jpeg)
接下来,我们将开发万花筒的效果,以充分理解这个概念。我们将从创建一个新的着色器类型“Unlet shader”开始,我们将其称为“USB_function_ABS”。然后,我们在着色器属性中声明一个新属性,稍后将使用该属性来旋转UV坐标。
Shader "USB/USB_function_ABS"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
// let's add a property to rotate the UV
_Rotation ("Rotation", Range(0, 360)) = 0
}
}
由于完整旋转是360度,因此_Rotation的范围是0到360之间。然后我们定义全局变量_Rotation来连接这个属性。
Pass
{
CGPROGRAM
...
sampler2D _MainTex;
float4 _MainTex_ST;
float _Rotation;
...
ENDCG
}
我们可以计算U和V坐标的绝对值来生成效果,并在片段着色器阶段将这些新值用于输出颜色。
fixed4 frag (v2f i) : SV_Target
{
// let's calculate the absolute value of U
float u = abs(i.uv.x - 0.5);
// let's calculate the absolute value of V
float v = abs(i.uv.y - 0.5);
fixed col = tex2D(_MainTex, float2(u, v));
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
根据我们指定为_MainTex的纹理配置,可能会发生两件主要的事情,
1.如果纹理设置为“Repeat”,则UV坐标的负区域将填充相同纹素的重复。
2.另一方面,如果纹理配置对应于“Clamp”,则图像的纹素将以与图4.0.8a中相同的方式拉伸。
无论配置如何,镜像效应都会很明显,因为我们使用了每个坐标的abs(n)函数。
如果要旋转UV坐标,可以使用“ Shader Graph package”包中包含的Unity_rotate_Degrees_float函数。
void Unity_Rotate_Degrees_float
(
float2 UV,
float2 Center,
float Rotation,
out float2 Out
)
{
Rotation = Rotation * (UNITY_PI / 180.0f);
UV -= Center;
float s = sin(Rotation);
float c = cos(Rotation);
float2x2 rMatrix = float2x2(c, -s, s, c);
rMatrix *= 0.5;
rMatrix += 0.5;
rMatrix = rMatrix * 2 - 1;
UV.xy = mul(UV.yx, rMatrix);
UV += Center;
Out = UV;
}
由于函数的类型为“void”,因此我们必须初始化片段着色器阶段字段中的一些变量,然后将它们作为参数传递。
Unity_Rotate_Degrees_float() { … }
fixed4 frag (v2f i) : SV_Target
{
float u = abs(i.uv.x - 0.5);
float v = abs(i.uv.y - 0.5);
// we link the rotation property
float rotation = _Rotation;
// we center the rotation pivot
float center = 0.5;
// let's generate new UV coordinates for the texture
float2 uv = 0;
Unity_Rotate_Degrees_float(float2(u,v), center, rotation, uv);
fixed4 col = tex2D(_MainTex, uv);
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
函数Unity_Rotate_Degrees_float中的第一个参数对应于我们要旋转的UV坐标,然后是旋转中心,然后是度数,最后我们要获取的输出值:纹理新的旋转角度。
原文对照
This function refers to the absolute value of a number, and as an argument, we can pass both a scalar value and a vector.
Its syntax is as follows:
// return the absolute value of n
float abs(float n)
{
return max(-n, n);
}
float2 abs (float2 n);
float3 abs (float3 n);
float4 abs (float4 n);
An absolute value will always return to a positive number, and its mathematical symbology consists of two sidebars that frame a number.
|−3| = 3 absolute value of −3 equals 3
|−5| = 5 absolute value of −5 equals 5
| 6 | = 6 absolute value of 6 is equal to itself
Our program could use the abs(n) function for multiple effects, including recreating a kaleidoscope or generating a triplanar mapping. In fact, for the first case, we could perform such an effect by calculating the absolute value in the UV coordinates. At the same time, in the triplanar mapping, we could determine the absolute value of the mesh’s normals to generate projections on both positive and negative axes.
![图片[1]-《Unity着色器圣经》4.0.8. | Abs function.-软件开发学习笔记](https://gamedevfan.cn/wp-content/uploads/2025/05/image-49-1024x432.jpeg)
If we pay attention to the starting point in the UV coordinates of the previous figure, we will notice that the U coordinate is centered on the Quad by subtracting 0.5f, and the minimum value becomes a negative number [-0.5f].
In the example, the texels get stretched because the texture has been set to clamp in the wrap mode. In this context, we could apply the absolute value to generate a “mirror” effect.
![图片[2]-《Unity着色器圣经》4.0.8. | Abs function.-软件开发学习笔记](https://gamedevfan.cn/wp-content/uploads/2025/05/image-48-1024x475.jpeg)
Next, we will develop the effect of a kaleidoscope to understand the concept fully. We will start by creating a new shader type, “Unlit Shader”, which we will call “USB_function_ABS”. Then, we declare a new property in the shader properties that we will use later to rotate the UV coordinates.
Shader "USB/USB_function_ABS"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
// let's add a property to rotate the UV
_Rotation ("Rotation", Range(0, 360)) = 0
}
}
Since a complete rotation has 360 degrees, _Rotation is equal to a range between 0 and 360. We continue with the global or connection variable for the property.
Pass
{
CGPROGRAM
...
sampler2D _MainTex;
float4 _MainTex_ST;
float _Rotation;
...
ENDCG
}
We can calculate both the U and V coordinates’ absolute values to generate the effect and use these new values for the output color in the fragment shader stage.
fixed4 frag (v2f i) : SV_Target
{
// let's calculate the absolute value of U
float u = abs(i.uv.x - 0.5);
// let's calculate the absolute value of V
float v = abs(i.uv.y - 0.5);
fixed col = tex2D(_MainTex, float2(u, v));
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
Two main things can happen depending on the texture configuration we are assigning as _MainTex,
1. If the texture is set as “Repeat”, the negative area of the UV coordinates will be filled with the repetition of the same texels.
2. On the other hand, if the texture configuration corresponds to “Clamp”, the texels of the image will be stretched in the same way as in Figure 4.0.8a.
Regardless of the configuration, the mirror effect will be evident since we use each coordinate’s abs(n) function.
If we want to rotate the UV coordinates, we can use the Unity_Rotate_Degrees_float function, included in the Shader Graph package.
void Unity_Rotate_Degrees_float
(
float2 UV,
float2 Center,
float Rotation,
out float2 Out
)
{
Rotation = Rotation * (UNITY_PI / 180.0f);
UV -= Center;
float s = sin(Rotation);
float c = cos(Rotation);
float2x2 rMatrix = float2x2(c, -s, s, c);
rMatrix *= 0.5;
rMatrix += 0.5;
rMatrix = rMatrix * 2 - 1;
UV.xy = mul(UV.yx, rMatrix);
UV += Center;
Out = UV;
}
Since the function is of type “void”, we will have to initialize some variables within the field of the fragment shader stage and then pass them as arguments.
Unity_Rotate_Degrees_float() { … }
fixed4 frag (v2f i) : SV_Target
{
float u = abs(i.uv.x - 0.5);
float v = abs(i.uv.y - 0.5);
// we link the rotation property
float rotation = _Rotation;
// we center the rotation pivot
float center = 0.5;
// let's generate new UV coordinates for the texture
float2 uv = 0;
Unity_Rotate_Degrees_float(float2(u,v), center, rotation, uv);
fixed4 col = tex2D(_MainTex, uv);
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
The first argument in the function Unity_Rotate_Degrees_float corresponds to the UV coordinates that we want to rotate, continues the center of rotation or pivot, then the number of degrees, and finally the output with the new coordinate values that we will use for the texture.
暂无评论内容