《Unity着色器圣经》10.0.3 | UV coordinates and texture.

目录索引

译文

上一节中,我们通过变量m_mainTex和m_texSize定义了纹理及其维度;然而,最终结果对应于Sierpinski三角形的图形表示。

考虑到我们目前正在编写的脚本,在本节中,我们将为效果指定一个导入的纹理,为此,我们必须定义UV坐标。

我们将首先在C#脚本中声明一个名为“m_tex”的“texture”类型的新公共纹理。

public class USBSimpleColorController : MonoBehaviour
{
    public ComputeShader m_shader;
    public Texture m_tex;

    RenderTexture m_mainTex;
    int m_texSize = 256;
    Renderer m_rend;
    ...
}

由于数据对应于一个纹理,我们必须在计算着色器中声明一个类型Texture2D和另一个类型SamplerState。

RWTexture2D<float4> Result;

Texture2D<float4> ColTex;
SamplerState sampler_ColTex;
...

如上面的示例所示,纹理的声明与前面部分中看到的类似。同样,我们需要UV坐标来将纹理定位在我们正在使用的四边形上。我们可以使用CSMain内核中的GetDimensions函数来实现这一点。

RWTexture2D<float4> Result;

Texture2D<float4> ColTex;
SamplerState sampler_ColTex;

[numthreads(8, 8, 1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    uint width;
    uint height;
    Result.GetDimensions(width, height);
    ...
}

GetDimensions函数的类型为“void”,这意味着我们将保存Result变量的宽度和高度维度。尺寸对应于我们从USBSimpleColorController分配给变量“m_texSize”的值。

void GetDimensions(out uint width, out uint height);

然后,我们可以确定UV坐标的值,如下所示:

[numthreads(8, 8, 1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    uint width;
    uint height;
    Result.GetDimensions(width, height);

    float2 uv = float2(id.xy / float2(width, height));
    ...
}

与宽度和高度一样,id变量也是一个整数值,UV坐标对应于0.0f到1.0f的范围;因此,在前面的示例中,它们被声明为“float”类型的变量。

值得注意的是,分配给Quad的纹理的“wrap mode”。

以上操作完全适用于在“clamp”模式中声明的纹理。如果纹理被配置为“repeat”,我们将需要在id变量中添加0.5f;否则,它将在投影中反射边缘。

// if the texture has been configured as wrap mode = clamp
float2 uv = float2(id.xy / float2(width, height));

// if the texture has been configured as wrap mode = repeat
float2 uv = float2((id.xy + float2(0.5, 0.5)) / float2(width, height));

接下来,我们可以使用SampleLevel函数来确定内核中的纹理。

[numthreads(8, 8, 1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    uint width;
    uint height;
    Result.GetDimensions(width, height);

    float2 uv = float2(id.xy / float2(width, height));
    float4 col = ColTex.SampleLevel(sampler_ColTex, uv, 0);

    Result[id.xy] = col;
}

这样的函数可以返回标量值或多维向量。上一个练习已用于将RGBA采样值存储在向量“col”中

Object.SampleLevel(in SamplerState s, in float2 uv, in int LOD);

最后,我们必须返回USBSimpleColorController脚本,并通过SetTexture函数将纹理发送到Compute Shader,就像我们对“m_mainTex”变量所做的那样。

void Start()
{
    ...
    m_shader.SetTexture(0, "Result", m_mainTex);
    m_shader.SetTexture(0, "ColTex", m_tex);
    m_rend.material.SetTexture("_MainTex", m_mainTex);
    ...
}


如果一切顺利,我们将看到“m_tex”字段中指定的纹理投影在我们的Quad上。

图片[1]-《Unity着色器圣经》10.0.3 | UV coordinates and texture.-软件开发学习笔记
(Fig. 10.0.3a. The texture has been configured in Clamp mode)

原文对照

In the previous section, we defined a texture and its dimensions through the variables m_mainTex and m_texSize; however, the final result corresponds to the graphical representation of the Sierpinski triangle.


Considering the script we have been writing up to this point, in this section, we will assign an imported texture to the effect, and for this, we will have to define UV coordinates.


We will start by declaring a new public texture of type “Texture” called “m_tex” in our C# script.

public class USBSimpleColorController : MonoBehaviour
{
    public ComputeShader m_shader;
    public Texture m_tex;

    RenderTexture m_mainTex;
    int m_texSize = 256;
    Renderer m_rend;
    ...
}

Since the data corresponds to a texture, we will have to declare a type Texture2D and another type SamplerState in the Compute Shader.

RWTexture2D<float4> Result;

Texture2D<float4> ColTex;
SamplerState sampler_ColTex;
...

As shown in the example above, the declaration for a texture has the same analogy as those seen in previous sections. In the same way, we will need UV coordinates to position the texture on the Quad we are using. We can use the GetDimensions function within the CSMain Kernel to do this.

RWTexture2D<float4> Result;

Texture2D<float4> ColTex;
SamplerState sampler_ColTex;

[numthreads(8, 8, 1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    uint width;
    uint height;
    Result.GetDimensions(width, height);
    ...
}


The GetDimensions function is of type “void,” which means we are saving the dimensions of the Result variable in width and height. The dimensions correspond to the value we assigned to the variable “m_texSize” from USBSimpleColorController.

void GetDimensions(out uint width, out uint height);

We can then determine the values of the UV coordinates as follows:

[numthreads(8, 8, 1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    uint width;
    uint height;
    Result.GetDimensions(width, height);

    float2 uv = float2(id.xy / float2(width, height));
    ...
}

Like width and height, the id variable is also an integer value, and the UV coordinates correspond to a range from 0.0f to 1.0f; for that reason, they have been declared as “float” type variables in the previous example.


It is worth noting that such an operation has a technical aspect that we must evaluate according to the “texture wrap mode” that we assign to the Quad.


The above operation works perfectly for those textures declared in “clamp” mode. If the texture has been configured as “repeat,” we will need to add 0.5f to the id variable; otherwise, it will reflect the edges in its projection.

// if the texture has been configured as wrap mode = clamp
float2 uv = float2(id.xy / float2(width, height));

// if the texture has been configured as wrap mode = repeat
float2 uv = float2((id.xy + float2(0.5, 0.5)) / float2(width, height));


Next, we can then use the SampleLevel function to determine the texture in the Kernel.

[numthreads(8, 8, 1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    uint width;
    uint height;
    Result.GetDimensions(width, height);

    float2 uv = float2(id.xy / float2(width, height));
    float4 col = ColTex.SampleLevel(sampler_ColTex, uv, 0);

    Result[id.xy] = col;
}


Such a function can return a scalar value or multidimensional vector. The previous exercise has been used to store the RGBA sampling values in the vector “col.”

Object.SampleLevel(in SamplerState s, in float2 uv, in int LOD);


To conclude, we must return to the USBSimpleColorController script and send the texture to the Compute Shader through the SetTexture function, in the same way we did with the “m_mainTex” variable.

void Start()
{
    ...
    m_shader.SetTexture(0, "Result", m_mainTex);
    m_shader.SetTexture(0, "ColTex", m_tex);
    m_rend.material.SetTexture("_MainTex", m_mainTex);
    ...
}


If everything goes well, we will see the texture assigned in the “m_tex” field projected on our Quad.

图片[1]-《Unity着色器圣经》10.0.3 | UV coordinates and texture.-软件开发学习笔记
(Fig. 10.0.3a. The texture has been configured in Clamp mode)
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容