#ifndef UNIVERSAL_LIT_INPUT_INCLUDED //使用#ifndef 指令判断该文件是否已经引入,防止在编写Shader过程中重复引入该文件,作用类同C++中的头文件定义方式
#define UNIVERSAL_LIT_INPUT_INCLUDED //如果没有则引入该文件,#define与#endif之间为文件代码
//引入这五个文件,后面会用到这些文件中定义的结构体和函数
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ParallaxMapping.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl"
#if defined(_DETAIL_MULX2) || defined(_DETAIL_SCALED)//看看是否有Detail map
#define _DETAIL
#endif
// NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts.
CBUFFER_START(UnityPerMaterial) //声明属性变量,其位于常量缓冲区中Constant Buffer,改CBuffer名字为UnityPerMaterial
float4 _BaseMap_ST; //常量缓冲区是位于GPU内的一块用于存储常量的区域,只读,可以同时被多个Shader使用
float4 _DetailAlbedoMap_ST;
half4 _BaseColor;
half4 _SpecColor;
half4 _EmissionColor;
half _Cutoff;
half _Smoothness;
half _Metallic;
half _BumpScale;
half _Parallax;
half _OcclusionStrength;
half _ClearCoatMask;
half _ClearCoatSmoothness;
half _DetailAlbedoMapScale;
half _DetailNormalMapScale;
half _Surface;
CBUFFER_END
// NOTE: Do not ifdef the properties for dots instancing, but ifdef the actual usage.
// Otherwise you might break CPU-side as property constant-buffer offsets change per variant.
// NOTE: Dots instancing is orthogonal to the constant buffer above.
#ifdef UNITY_DOTS_INSTANCING_ENABLED
UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata)
UNITY_DOTS_INSTANCED_PROP(float4, _BaseColor)
UNITY_DOTS_INSTANCED_PROP(float4, _SpecColor)
UNITY_DOTS_INSTANCED_PROP(float4, _EmissionColor)
UNITY_DOTS_INSTANCED_PROP(float , _Cutoff)
UNITY_DOTS_INSTANCED_PROP(float , _Smoothness)
UNITY_DOTS_INSTANCED_PROP(float , _Metallic)
UNITY_DOTS_INSTANCED_PROP(float , _BumpScale)
UNITY_DOTS_INSTANCED_PROP(float , _Parallax)
UNITY_DOTS_INSTANCED_PROP(float , _OcclusionStrength)
UNITY_DOTS_INSTANCED_PROP(float , _ClearCoatMask)
UNITY_DOTS_INSTANCED_PROP(float , _ClearCoatSmoothness)
UNITY_DOTS_INSTANCED_PROP(float , _DetailAlbedoMapScale)
UNITY_DOTS_INSTANCED_PROP(float , _DetailNormalMapScale)
UNITY_DOTS_INSTANCED_PROP(float , _Surface)
UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata)
#define _BaseColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata_BaseColor)
#define _SpecColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata_SpecColor)
#define _EmissionColor UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float4 , Metadata_EmissionColor)
#define _Cutoff UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_Cutoff)
#define _Smoothness UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_Smoothness)
#define _Metallic UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_Metallic)
#define _BumpScale UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_BumpScale)
#define _Parallax UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_Parallax)
#define _OcclusionStrength UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_OcclusionStrength)
#define _ClearCoatMask UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_ClearCoatMask)
#define _ClearCoatSmoothness UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_ClearCoatSmoothness)
#define _DetailAlbedoMapScale UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_DetailAlbedoMapScale)
#define _DetailNormalMapScale UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_DetailNormalMapScale)
#define _Surface UNITY_ACCESS_DOTS_INSTANCED_PROP_FROM_MACRO(float , Metadata_Surface)
#endif
//纹理声明,这些纹理属性在Lit.Shader文件中声明过 //纹理使用的采样器声明,sampler_textureName表示使用面板中设置的采样方式,这个属性的值通过材质面板传过来
TEXTURE2D(_ParallaxMap); SAMPLER(sampler_ParallaxMap);
TEXTURE2D(_OcclusionMap); SAMPLER(sampler_OcclusionMap);
TEXTURE2D(_DetailMask); SAMPLER(sampler_DetailMask);
TEXTURE2D(_DetailAlbedoMap); SAMPLER(sampler_DetailAlbedoMap);
TEXTURE2D(_DetailNormalMap); SAMPLER(sampler_DetailNormalMap);
TEXTURE2D(_MetallicGlossMap); SAMPLER(sampler_MetallicGlossMap);
TEXTURE2D(_SpecGlossMap); SAMPLER(sampler_SpecGlossMap);
TEXTURE2D(_ClearCoatMap); SAMPLER(sampler_ClearCoatMap);
#ifdef _SPECULAR_SETUP //高光设置,这个关键字在Lit.Shader中声明过。如果在面板上设置了高光,则走高光工作流对_SpecGlossMap采样,否则对_MetallicGlossMap采样
#define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_SpecGlossMap, sampler_SpecGlossMap, uv)
#else
#define SAMPLE_METALLICSPECULAR(uv) SAMPLE_TEXTURE2D(_MetallicGlossMap, sampler_MetallicGlossMap, uv)
#endif
half4 SampleMetallicSpecGloss(float2 uv, half albedoAlpha) //金属和高光采样函数,参数为二维浮点数精度的uv坐标、半浮点数的透明度通道,返回值为四维的半浮点数精度的颜色
{
half4 specGloss;
#ifdef _METALLICSPECGLOSSMAP //Lit.Shader中定义的材质关键字,如果在材质面板上给了贴图
specGloss = half4(SAMPLE_METALLICSPECULAR(uv));//采样,SAMPLE_METALLICSPECULAR为上面定义的
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A //Lit.Shader中定义的材质关键字,对应面板上的source选择,意思是透明度通道来自哪
specGloss.a = albedoAlpha * _Smoothness;//来自Albedo,随后乘了粗糙度,为什么乘以这个,看URP Channel packing的说明
#else
specGloss.a *= _Smoothness;//来自Metallic Map或者Specular Map
#endif
#else // _METALLICSPECGLOSSMAP //如果没给贴图
#if _SPECULAR_SETUP
specGloss.rgb = _SpecColor.rgb; //对于高光工作流,采样结果的颜色值使用设置的高光的RPG
#else
specGloss.rgb = _Metallic.rrr; //对于金属工作流,采样结果的颜色值是使用slider的值,范围为0~1,是个灰度的
#endif
#ifdef _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A//同上
specGloss.a = albedoAlpha * _Smoothness;
#else
specGloss.a = _Smoothness;
#endif
#endif
return specGloss;
}
half SampleOcclusion(float2 uv)//采样AO图,即环境遮挡贴图,参数为二维浮点数精度的uv坐标,返回值为半浮点数精度的值
{
#ifdef _OCCLUSIONMAP //Lit.Shader中定义的材质关键字,如果在材质面板上给了贴图
// TODO: Controls things like these by exposing SHADER_QUALITY levels (low, medium, high)
#if defined(SHADER_API_GLES)//如果调用的API是OpenGLES
return SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g;//取的G通道的值,为什么取G,看URP Channel packing的说明
#else
half occ = SAMPLE_TEXTURE2D(_OcclusionMap, sampler_OcclusionMap, uv).g;
return LerpWhiteTo(occ, _OcclusionStrength);//可以写成Lerp(1, occ, _OcclusionStrength),做了个插值
#endif
#else
return half(1.0); //没有给图,直接返回1
#endif
}
// Returns clear coat parameters
// .x/.r == mask
// .y/.g == smoothness
half2 SampleClearCoat(float2 uv)//采样透明漆,车漆相关的东西
{
#if defined(_CLEARCOAT) || defined(_CLEARCOATMAP)
half2 clearCoatMaskSmoothness = half2(_ClearCoatMask, _ClearCoatSmoothness);
#if defined(_CLEARCOATMAP)
clearCoatMaskSmoothness *= SAMPLE_TEXTURE2D(_ClearCoatMap, sampler_ClearCoatMap, uv).rg;
#endif
return clearCoatMaskSmoothness;
#else
return half2(0.0, 1.0);
#endif // _CLEARCOAT
}
void ApplyPerPixelDisplacement(half3 viewDirTS, inout float2 uv)//inout关键字表示改uv既用于输入,又用于输出,这个方法在用到的时候再说
{
#if defined(_PARALLAXMAP)
uv += ParallaxMapping(TEXTURE2D_ARGS(_ParallaxMap, sampler_ParallaxMap), viewDirTS, _Parallax, uv);
#endif
}
// Used for scaling detail albedo. Main features:
// - Depending if detailAlbedo brightens or darkens, scale magnifies effect.
// - No effect is applied if detailAlbedo is 0.5.
half3 ScaleDetailAlbedo(half3 detailAlbedo, half scale)
{
// detailAlbedo = detailAlbedo * 2.0h - 1.0h;
// detailAlbedo *= _DetailAlbedoMapScale;
// detailAlbedo = detailAlbedo * 0.5h + 0.5h;
// return detailAlbedo * 2.0f;
// A bit more optimized
return half(2.0) * detailAlbedo * scale - scale + half(1.0);//不清楚为什么这样算
}
half3 ApplyDetailAlbedo(float2 detailUv, half3 albedo, half detailMask)//添加detailBaseMap的漫反射值
{
#if defined(_DETAIL)
half3 detailAlbedo = SAMPLE_TEXTURE2D(_DetailAlbedoMap, sampler_DetailAlbedoMap, detailUv).rgb;//根据贴图、采样方法、uv得到采样结果
// In order to have same performance as builtin, we do scaling only if scale is not 1.0 (Scaled version has 6 additional instructions)
#if defined(_DETAIL_SCALED)
detailAlbedo = ScaleDetailAlbedo(detailAlbedo, _DetailAlbedoMapScale);//缩放漫反射值
#else
detailAlbedo = half(2.0) * detailAlbedo;
#endif
return albedo * LerpWhiteTo(detailAlbedo, detailMask);
#else
return albedo;//没有细节贴图直接返回
#endif
}
half3 ApplyDetailNormal(float2 detailUv, half3 normalTS, half detailMask)//添加detail normal map得值
{
#if defined(_DETAIL)
#if BUMP_SCALE_NOT_SUPPORTED
half3 detailNormalTS = UnpackNormal(SAMPLE_TEXTURE2D(_DetailNormalMap, sampler_DetailNormalMap, detailUv));//unpackNormal是将通道值从0到1恢复到-1到1
#else
half3 detailNormalTS = UnpackNormalScale(SAMPLE_TEXTURE2D(_DetailNormalMap, sampler_DetailNormalMap, detailUv), _DetailNormalMapScale);
#endif
// With UNITY_NO_DXT5nm unpacked vector is not normalized for BlendNormalRNM
// For visual consistancy we going to do in all cases
detailNormalTS = normalize(detailNormalTS);
return lerp(normalTS, BlendNormalRNM(normalTS, detailNormalTS), detailMask); // todo: detailMask should lerp the angle of the quaternion rotation, not the normals
#else
return normalTS;
#endif
}
inline void InitializeStandardLitSurfaceData(float2 uv, out SurfaceData outSurfaceData)//初始化Lit.Shader的表面数据,inline关键字和C++中的inline的作用一样
{ //SurfaceData是结构体,在SurfaceData.hlsl中定义的,在其他文件中引入的
half4 albedoAlpha = SampleAlbedoAlpha(uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap));//采样BaseMap获取漫反射的透明通道
outSurfaceData.alpha = Alpha(albedoAlpha.a, _BaseColor, _Cutoff);//再根据BaseColor和Cutoff得到表面最终的透明通道值,这两个属性再Lit.shader中定义了
half4 specGloss = SampleMetallicSpecGloss(uv, albedoAlpha.a);//采样漫反射,见上面的解释
outSurfaceData.albedo = albedoAlpha.rgb * _BaseColor.rgb;//得到表面数据漫反射值
#if _SPECULAR_SETUP//高光设置
outSurfaceData.metallic = half(1.0);
outSurfaceData.specular = specGloss.rgb;
#else
outSurfaceData.metallic = specGloss.r;
outSurfaceData.specular = half3(0.0, 0.0, 0.0);
#endif
outSurfaceData.smoothness = specGloss.a;//粗糙度
outSurfaceData.normalTS = SampleNormal(uv, TEXTURE2D_ARGS(_BumpMap, sampler_BumpMap), _BumpScale);//法线的TS
outSurfaceData.occlusion = SampleOcclusion(uv);//采样遮挡,见上面的解释
outSurfaceData.emission = SampleEmission(uv, _EmissionColor.rgb, TEXTURE2D_ARGS(_EmissionMap, sampler_EmissionMap));//采样自发光
#if defined(_CLEARCOAT) || defined(_CLEARCOATMAP)//如果有clearcoat
half2 clearCoat = SampleClearCoat(uv);
outSurfaceData.clearCoatMask = clearCoat.r;
outSurfaceData.clearCoatSmoothness = clearCoat.g;
#else
outSurfaceData.clearCoatMask = half(0.0);
outSurfaceData.clearCoatSmoothness = half(0.0);
#endif
#if defined(_DETAIL)//如果有细节图
half detailMask = SAMPLE_TEXTURE2D(_DetailMask, sampler_DetailMask, uv).a;//获取detailMask的透明通道
float2 detailUv = uv * _DetailAlbedoMap_ST.xy + _DetailAlbedoMap_ST.zw;//算uv,一般就这样算
outSurfaceData.albedo = ApplyDetailAlbedo(detailUv, outSurfaceData.albedo, detailMask);
outSurfaceData.normalTS = ApplyDetailNormal(detailUv, outSurfaceData.normalTS, detailMask);
#endif
}
#endif // UNIVERSAL_INPUT_SURFACE_PBR_INCLUDED
URP Lit Shader解析(2)—LitInput.hlsl
最新推荐文章于 2025-05-30 14:23:17 发布