此示例中的 Unity 着色器将在网格上绘制纹理。
使用带有颜色输入的 URP 无光照着色器一节中的 Unity 着色器源文件,并对__ ShaderLab__Unity 用于定义着色器对象结构的语言。更多信息
See in Glossary 代码进行以下更改:
在 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 批处理程序 (SRP Batcher) 兼容,请使用
UnityPerMaterial名称在单个CBUFFER代码块中声明所有材质属性。有关 SRP 批处理程序的更多信息,请参阅有关可编程渲染管线 (SRP) 批处理程序的文档。
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 代码。
// This shader draws a texture on the mesh.
Shader "Example/URPUnlitShaderTexture"
{
// The _BaseMap variable is visible in the Material's Inspector, as a field
// called 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;
// The uv variable contains the UV coordinate on the texture for the
// given vertex.
float2 uv : TEXCOORD0;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
// The uv variable contains the UV coordinate on the texture for the
// given vertex.
float2 uv : TEXCOORD0;
};
// This macro declares _BaseMap as a Texture2D object.
TEXTURE2D(_BaseMap);
// This macro declares the sampler for the _BaseMap texture.
SAMPLER(sampler_BaseMap);
CBUFFER_START(UnityPerMaterial)
// The following line declares the _BaseMap_ST variable, so that you
// can use the _BaseMap variable in the fragment shader. The _ST
// suffix is necessary for the tiling and offset function to work.
float4 _BaseMap_ST;
CBUFFER_END
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
// The TRANSFORM_TEX macro performs the tiling and offset
// transformation.
OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap);
return OUT;
}
half4 frag(Varyings IN) : SV_Target
{
// The SAMPLE_TEXTURE2D marco samples the texture with the given
// sampler.
half4 color = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv);
return color;
}
ENDHLSL
}
}
}
可视化法线矢量一节介绍了如何在网格上使法线矢量可视化。