绘制纹理
此示例中的 Unity 着色器将在网格上绘制纹理。
使用带有颜色输入的 URP 无光照着色器一节中的 Unity 着色器源文件,并对 ShaderLab 代码进行以下更改:
在 Properties 代码块中,将现有代码替换为
_BaseMap
属性定义。Properties { [MainTexture] _BaseMap("Base Map", 2D) = "white" }
在 Properties 代码块中声明纹理属性时,Unity 会将带有 Base Map 标签的
_BaseMap
属性添加到材质,并添加 Tiling 和 Offset 控制项。使用
[MainTexture]
特性声明一个属性时,Unity 使用这个属性作为材质的主纹理。注意:出于兼容性原因,
_MainTex
属性名称是保留名称。Unity 使用名为_MainTex
的属性作为主纹理,即使它没有[MainTexture]
特性也是如此。在
struct Attributes
和struct Varyings
中,为纹理上的 UV 坐标添加uv
变量:float2 uv : TEXCOORD0;
将纹理定义为 2D 纹理并为其指定采样器。在 CBUFFER 代码块之前添加以下代码行:
TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap);
TEXTURE2D 和 SAMPLER 宏在
Core.hlsl
中引用的文件之一中进行定义。要使平铺和偏移有效,有必要在“CBUFFER”代码块中使用
_ST
后缀来声明纹理属性。之所以有必要使用_ST
后缀,是因为某些宏(例如,TRANSFORM_TEX
)要使用它。注意:为确保 Unity 着色器与 SRP Batcher 兼容,请在名为
UnityPerMaterial
的单个CBUFFER
代码块中声明所有材质属性。有关 SRP Batcher 的更多信息,请参阅可编程渲染管线 SRP Batcher 页面。CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; CBUFFER_END
要应用平铺和偏移变换,请在顶点着色器中添加以下行:
OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap);
TRANSFORM_TEX
宏在Macros.hlsl
文件中进行定义。#include
声明包含对该文件的引用。在片元着色器中,使用
SAMPLE_TEXTURE2D
宏对纹理进行采样:half4 frag(Varyings IN) : SV_Target { half4 color = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv); return color; }
现在可以在 Inspector 窗口的 Base Map 字段中选择一个纹理。着色器便会在网格上绘制该纹理。
以下是此示例的完整 ShaderLab 代码。
// 此着色器将在网格上绘制纹理。
Shader "Example/URPUnlitShaderTexture"
{
// _BaseMap 变量在材质的 Inspector 中显示为一个名为
// Base Map 的字段。
Properties
{
[MainTexture] _BaseMap("Base Map", 2D) = "white"
}
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
// uv 变量包含给定顶点的纹理上的
// UV 坐标。
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
// uv 变量包含给定顶点的纹理上的
// UV 坐标。
float2 uv : TEXCOORD0;
};
// 此宏将 _BaseMap 声明为 Texture2D 对象。
TEXTURE2D(_BaseMap);
// This macro declares the sampler for the _BaseMap texture.
SAMPLER(sampler_BaseMap);
CBUFFER_START(UnityPerMaterial)
// 以下行声明 _BaseMap_ST 变量,以便可以
// 在片元着色器中使用 _BaseMap 变量。为了
// 使平铺和偏移有效,有必要使用 _ST 后缀。
float4 _BaseMap_ST;
CBUFFER_END
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
// TRANSFORM_TEX 宏执行平铺和偏移
// 变换。
OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap);
return OUT;
}
half4 frag(Varyings IN) : SV_Target
{
// SAMPLE_TEXTURE2D 宏使用给定的采样器对纹理进行
// 采样。
half4 color = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv);
return color;
}
ENDHLSL
}
}
}
可视化法线矢量一节介绍了如何在网格上使法线矢量可视化。