因为CG英伟达不再维护,并且支持的功能比较少,基本和DX9的功能差不多,随前显卡的更新换代,unity在URP和HDRP中使用了HLSL,支持DX11相关的API,并有逐步抛弃CG的意途,而且还可以用ShaderGraph来创建shader,方便美术和策划创作。
HLSL的语法总体来说和CG差不多,只不过有一些小的差别,首先从格式上,基本上致,只是多了一些标签,例如
RenderPipeline = "UniversalRenderPipline"
代码放在HLSLPROGRAM ... HLSLEND
之间
还有一些方法的变化
例如:
- 将模型空间转到屏幕裁切空间
UnityObjectToClipPos(vertex)
变成了TransformObjectToHClip(vertex.xyz)
Sampler2D _MainTex
变成了Texture2D _MainTex
- 采样
tex2D(_MainTex, i.texcoord)
变成了_MainTex.Sample(_MainTex, Sampler_MainTex)
而Sampler_MainTex
是采样器名称,需要声明SamplerState Sampler_MainTex
- 为了支持
SRP Batch
需要把shader中的变量加到CBUFFTER_START(UnityPerMaterial) ... CBUFFER_END
中,但是不能加贴图变量(如Texture2D _MainTex),因为这个缓存区的大小有限,贴图占用的空间太大。
下面是一个无光照的Shader示例
下面的代码中还有shader instance相关的代码,只是被注释掉了。
Shader "URP/Unlit"
{
Properties
{
_MainTex("MainTex",2D) = "white"{}
_BaseColor("BaseColor",Color)=(1,1,1,1)
}
SubShader
{
Tags
{
"RenderPipeline" = "UniversalRenderPipeline"
"RenderType" = "Opaque"
"IgnoreProjector" = "True"
}
Lod 200
pass
{
Cull back
Zwrite On
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
// #pragma prefer_hlslcc gles
// #pragma exclude_renderers d3d11_9x
// #pragma multi_compile_instancing
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
CBUFFER_START(UnityPerMaterial)
float4 _MainTex_ST;
half4 _BaseColor;
CBUFFER_END
Texture2D _MainTex;//贴图,相当于 TEXTURE2D(_MainTex);
SamplerState sampler_MainTex; //声明采样器,相当于 SAMPLER(sampler_MainTex); ;
struct Atributes
{
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
// UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
// UNITY_VERTEX_INPUT_INSTANCE_ID
// UNITY_VERTEX_OUTPUT_STEREO
};
Varyings vert(Atributes input)
{
Varyings o = (Varyings)0;
// UNITY_SETUP_INSTANCE_ID(input);
// UNITY_TRANSFER_INSTANCE_ID(input, o);
// UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.positionCS = TransformObjectToHClip(input.positionOS.xyz);
o.uv = TRANSFORM_TEX(input.uv,_MainTex);
return o;
}
half4 frag(Varyings input):SV_TARGET
{
// UNITY_SETUP_INSTANCE_ID(input);
// UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
half2 uv = input.uv;
return _MainTex.Sample(sampler_MainTex,uv)* _BaseColor; //SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,uv) * _BaseColor;
}
ENDHLSL
}
}
}