Files
AIC-Project/docs/superpowers/specs/2026-07-15-xpbr-shader-design.md
T
2026-07-15 10:16:36 +08:00

2.8 KiB
Raw Blame History

XPbr Shader 设计文档

日期:2026-07-15 状态:已确认

目标

Client/Assets/Game/shader/XShader/ 下新增一个 URP12.1.6PBR shader,支持两张贴图:

  1. 基础贴图 _MainTex:RGB = 颜色/漫反射,A = 透明或 AO(材质开关切换语义)
  2. 混合贴图 _MixTex(必选):RG = 球面编码压缩法线,B = 金属度,A = 粗糙度

文件

  • Client/Assets/Game/shader/XShader/XPbr.shader — Shader 名 Test/XPbr(与现有 Test/XTex 风格一致)
  • Client/Assets/Game/shader/XShader/XPbr_Base.hlsl — CBUFFER、结构体、公共函数

独立自包含,不 include XTex_Base.hlsl(避免 CBUFFER 与 keyword 耦合);DecodeSphereMapSampleXRuntimeAmbientInitializeInputData 等公共函数复制入本 shader 的 Base 文件,与目录内 XTex/XTerrain 各自一份的现状一致。

Properties

属性 类型 说明
_BaseColor Color 颜色叠乘,默认白
_MainTex 2D RGB=漫反射,A=透明或 AO
_MixTex 2D RG=球面编码法线,B=金属度,A=粗糙度,必选
[Toggle(_ALPHATEST_ON)] _AlphaTest Float 勾选:A 当透明,clip(a - _Cutoff)AO=1;不勾选:A 当 AOalpha=1
_Cutoff Range(0,1) 透明裁剪阈值,默认 0.5
_Metallic Range(0,2) 金属度缩放
_Roughness Range(0,2) 粗糙度缩放
_AO Range(0,1) AO 强度:occlusion = lerp(1, baseA, _AO)(仅 AO 模式)

Fragment 逻辑

albedoAlpha = SAMPLE(_MainTex, uv);  mix = SAMPLE(_MixTex, uv)
albedo     = albedoAlpha.rgb * _BaseColor.rgb
normalTS   = DecodeSphereMap(mix.rg)
metallic   = saturate(mix.b * _Metallic)
smoothness = 1 - saturate(mix.a * _Roughness)
#if _ALPHATEST_ON: clip(albedoAlpha.a - _Cutoff); occlusion=1; alpha=albedoAlpha.a
#else:             occlusion = lerp(1, albedoAlpha.a, _AO); alpha=1
→ 切线空间法线经 TBN 转世界空间 → UniversalFragmentPBR → MixFog

Pass

  1. ForwardLitLightMode=UniversalForward):multi_compile 阵容与 XTex 相同(_MAIN_LIGHT_SHADOWS*_ADDITIONAL_LIGHTS*LIGHTMAP_ONDYNAMICLIGHTMAP_ON_ADDITIONAL_LIGHT_SHADOWS_SHADOWS_SOFT*),外加 #pragma shader_feature_local_fragment _ALPHATEST_ON。环境光接 SampleXRuntimeAmbient 全局覆盖(与 XTex 行为一致)。
  2. ShadowCaster:支持 _ALPHATEST_ON 裁剪,透明模式下阴影镂空。

TagsRenderType=OpaqueRenderPipeline=UniversalPipelineFallBack Off。

不做(YAGNI

自发光、视差、程序化法线 fallback、半透明混合(Alpha Blend)、DepthOnly/Meta pass。

验证方式

Unity 编辑器中编译无报错;创建材质赋两张贴图,检查法线/金属/粗糙响应;切换 _AlphaTest 开关验证 A 通道两种语义。