《Unity着色器圣经》3.3.3 | Cg/HLSL片元着色器

目录索引

译文

下一个,也是 pass 中的最后一个功能是片元着色器,也就是我们的着色器代码中名为的“frag”的函数。我们之所以能将 frag 函数称为片元着色器是因为程序中声明了 #pragma fragment 语义。

#pragma fragment frag 
fixed4 frag (v2f i) : SV_Target 
{ 
    // 片元着色器内的功能 
}

“片元”一词指的是屏幕上的由一个单独的片元或一组共同覆盖一个对象区域的片元组成的像素。这意味着片元着色器阶段将处理电脑屏幕上与我们看到的物体有关的每一个像素。

我们将分析 frag 函数的结构。frag 函数以数据类型“fixed4”开始,这意味着我们必须返回一个四维向量。

需要注意的是,由于这个着色器目前是用 Cg 编写的,因此只能在内置渲染管线(Built-in RP)中编译。如果我们想让该着色器同时在通用渲染管线(URP)和高清渲染管线(HDRP)中编译,就必须将 frag 函数的返回类型改为“half4”或“float4”,否则程序可能会出错。

// Cg 语言中
fixed4 frag (v2f i) : SV_Target { … } 

// HLSL 语言中
half4 frag (v2f i) : SV_Target { … }

在数据类型之后,该函数被命名为“frag”。它的参数是一个名为“i”的“v2f”类型的变量。

与顶点着色器阶段不同,该函数有一个名为“SV_Target”的输出,它允许我们在中间缓冲区(渲染目标)中渲染场景,而不是将数据直接发送到帧缓冲里。在旧版(第 9 版或更低版本)的 Direct3D 中,片元着色器中的颜色输出使用 COLOR 语义。但在现代 GPU(第 10 版及以后的版本)中,该语义被更新为 SV_Target,即“系统值目标”。在将图像投射到电脑屏幕上之前,片元着色器可以为图像编写额外的效果。在片元着色器中,我们可以找到一个名为“col”的 fixed4 类型的向量,它与 tex2D 函数类似,它接收 _MainTex 纹理和 UV 坐标输入作为参数。基本上,该操作就是在 col 向量中存储纹理。

col 向量有四个维度的原因有两个: 第一个原因是 frag 函数是一个四维向量,因此我们必须返回一个具有相同维数的向量;第二个原因是我们将纹理颜色按 RGBA 四个通道存储在 col 向量中,因此如果我们使用的纹理具有 Alpha 通道(透明度),那么它将反映在模型中。

fixed4 frag (v2f i) : SV_Target 
{ 
    // 将纹理存储到col向量中
    fixed4 col = tex2D(_MainTex, i.uv); 
    // 返回纹理颜色
    return col; 
}

原文对照

Our next and last function in the Pass corresponds to the fragment shader stage that appears in our shader with the name “frag“. The reason we can tell that frag is the function of the fragment shader stage is because it has been declared as such in the #pragma fragment.

#pragma fragment frag 
fixed4 frag (v2f i) : SV_Target 
{ 
    // fragment shader functions here 
}

The word “fragment” refers to a pixel on the screen; to an individual fragment or to a group that together cover an object area. This means that the fragment shader stage will process every pixel on the computer screen concerning the object we are viewing.

We are going to analyze the structure of the frag function. It starts with the data type “fixed4” which means that we will have to return a vector of four dimensions.

On the other hand, let’s remember that this shader is currently written in Cg, so it will only compile in Built-in RP. If we want our shader to compile both in Universal RP and High Definition RP, we will have to change this data type for “half4 or float4“, otherwise our program could generate an error.

// Cg language 
fixed4 frag (v2f i) : SV_Target { … } 

// HLSL language 
half4 frag (v2f i) : SV_Target { … }

After the data type, the name continues with “frag” and as an argument, it has a “v2f” type variable called “i”.

Unlike the vertex shader stage, this function has an output called “SV_Target”, which allows us to render our scene in an intermediate buffer (render target) instead of sending the data to the Frame Buffer. In previous versions of Direct3D (version 9 and lower), the color output in the fragment shader appeared with the COLOR semantic. However, in modern GPUs (version 10 onwards), this semantics is updated by , which means “system value target”. It can apply additional effects to the image before projecting them on the computer screen. Inside the fragment shader stage we can find a fixed4 vector type called “col” which is the same as the tex2D function, where, as an argument, it receives the _MainTex texture and UV coordinate input. Basically what this operation does is store a texture within the col vector.

The reason why this vector has four dimensions is due to two conditions: The first because the frag function is a four-dimensional vector, so we will have to return a vector with an equal quantity of dimensions, and the second is because within the col vector we are going to store the colors of the texture in its RGBA channels, therefore, if the texture we use has an alpha channel (transparency), then it will be reflected in the object.

fixed4 frag (v2f i) : SV_Target 
{ 
    // store the texture in the col vector 
    fixed4 col = tex2D(_MainTex, i.uv); 
    // return the texture color 
    return col; 
}
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容