2023-12-08 18:00:41 +08:00
|
|
|
|
---
|
2023-12-18 09:59:26 +08:00
|
|
|
|
title: GBuffer&Material&BasePass
|
2023-12-08 18:00:41 +08:00
|
|
|
|
date: 2023-12-08 17:34:58
|
|
|
|
|
excerpt:
|
|
|
|
|
tags:
|
|
|
|
|
rating: ⭐
|
|
|
|
|
---
|
2023-12-18 09:59:26 +08:00
|
|
|
|
|
|
|
|
|
# # GBuffer
|
2024-02-28 19:06:34 +08:00
|
|
|
|
目前UE5.3会调用
|
|
|
|
|
- WriteGBufferInfoAutogen()
|
|
|
|
|
- **EncodeGBufferToMRT()**
|
2024-02-29 16:38:31 +08:00
|
|
|
|
动态生成BasePassPixelShader.usf中的**EncodeGBufferToMRT()** 的代码,并且会生成一个AutogenShaderHeaders.ush文件。其路径为:
|
|
|
|
|
`Engine\Intermediate\ShaderAutogen\PCD3D_SM5`或者`Engine\Intermediate\ShaderAutogen\PCD3D_ES3_1`
|
|
|
|
|
|
|
|
|
|
1. ***给FGBufferData添加结构体数据时需要在此添加额外代码逻辑***
|
|
|
|
|
2. GBuffer精度在FetchLegacyGBufferInfo()设置
|
2024-02-28 19:06:34 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-12-18 09:59:26 +08:00
|
|
|
|
UE5 GBuffer内容:
|
2023-12-19 15:13:51 +08:00
|
|
|
|
[[UE GBuffer存储数据]]
|
2023-12-08 18:00:41 +08:00
|
|
|
|
```c#
|
|
|
|
|
OutGBufferA = WorldNormal/PerObjectGBufferData
|
|
|
|
|
OutGBufferB = Metallic/Specular/Roughness/EncodeShadingModelIdAndSelectiveOutputMask(GBuffer.ShadingModelID, GBuffer.SelectiveOutputMask);
|
|
|
|
|
OutGBufferC = BaseColor/GBufferAO
|
|
|
|
|
OutGBufferD = GBuffer.CustomData;
|
|
|
|
|
OutGBufferE = GBuffer.PrecomputedShadowFactors;
|
2023-12-18 10:48:54 +08:00
|
|
|
|
|
|
|
|
|
// 0..1, 2 bits, use CastContactShadow(GBuffer) or HasDynamicIndirectShadowCasterRepresentation(GBuffer) to extract
|
|
|
|
|
half PerObjectGBufferData;
|
2023-12-08 18:00:41 +08:00
|
|
|
|
```
|
2023-12-18 09:59:26 +08:00
|
|
|
|
|
2023-12-18 10:48:54 +08:00
|
|
|
|
ToonGBuffer修改&数据存储:
|
2023-12-08 18:00:41 +08:00
|
|
|
|
```c#
|
2023-12-18 11:48:10 +08:00
|
|
|
|
OutGBufferA:PerObjectGBufferData => 可以存储额外的有关Tonn渲染功能参数。
|
|
|
|
|
OutGBufferB:Metallic/Specular/Roughness =>
|
|
|
|
|
? / SpcularMask(控制高光形状与Mask) / ? / ?
|
|
|
|
|
//ToonHairMask OffsetShadowMask/SpcularMask/SpecularValue
|
|
|
|
|
OutGBufferD:CustomData.xyzw =>
|
|
|
|
|
ShaderColor.rgb / NoLOffset //ShadowColor这里可以在Material里通过主光向量、ShadowStep、Shadow羽化计算多层阴影效果。
|
|
|
|
|
OutGBufferE:GBuffer.PrecomputedShadowFactors.xyzw =>
|
|
|
|
|
ToonDataID/ ToonObjectID(判断是否是一个物体) /OutlineMask 控制Outline绘制以及Outline强度 / ToonAO
|
|
|
|
|
OutGBufferF:velocity =>
|
|
|
|
|
? / ? / ? / ?
|
2023-12-08 18:00:41 +08:00
|
|
|
|
```
|
|
|
|
|
|
2023-12-18 11:48:10 +08:00
|
|
|
|
蓝色协议的方案
|
|
|
|
|
![[蓝色协议的方案#GBuffer]]
|
2023-12-18 10:48:54 +08:00
|
|
|
|
|
2023-12-18 11:48:10 +08:00
|
|
|
|
## Toon PerObjectGBufferData具体功能表
|
|
|
|
|
从3开始,0、1、2已被占用。
|
|
|
|
|
- ?
|
2023-12-18 10:48:54 +08:00
|
|
|
|
|
2023-12-18 11:48:10 +08:00
|
|
|
|
## ToonData
|
2023-12-08 18:00:41 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 高光
|
|
|
|
|
- PBR高光(使用Roughness控制是否可行?是否需要传入GBuffer一个Mask贴图)
|
|
|
|
|
- 自定义高光:高光贴图、高光颜色、参数化高光形状、多层高光
|
|
|
|
|
|
2023-12-18 11:48:10 +08:00
|
|
|
|
# 顶点色
|
|
|
|
|
## 蓝色协议
|
2023-12-08 18:00:41 +08:00
|
|
|
|
用于存储一些低精度数据,插值即可
|
2023-12-18 11:48:10 +08:00
|
|
|
|
- 顶点色:
|
|
|
|
|
- R:阴影区域控制(强度) 0~1
|
|
|
|
|
- G:描边宽度
|
|
|
|
|
- B:ToonAO
|
|
|
|
|
- 第二套顶点色(UV Channel1):
|
|
|
|
|
- R:深度偏移
|
|
|
|
|
- G:用来区分内轮廓不同部位的ID
|
2023-12-08 18:00:41 +08:00
|
|
|
|
|
2023-12-18 11:48:10 +08:00
|
|
|
|
蓝色协议的R:阴影区域标记 与 B:AO,而罪恶装备使用贴图来传递信息。
|
|
|
|
|
## 罪恶装备
|
|
|
|
|
对阴影判断阈值的偏移。(见前面着色部分,顶点AO+手绘修正)
|
|
|
|
|
R:阴影偏移
|
|
|
|
|
G:轮廓线根据与相机的距离扩大多少的系数
|
|
|
|
|
B:等高线 Z 轴偏移值
|
|
|
|
|
|
|
|
|
|
# 罪恶装备
|
|
|
|
|
8,G为阴影控(AO),R为高光强度参数,金属和光滑材质的部分设置的更大一些。B通道:用于照明控制。最大值为高光,反之,值越小高光越淡。
|
2023-12-08 18:00:41 +08:00
|
|
|
|

|
|
|
|
|
|
|
|
|
|
https://zhuanlan.zhihu.com/p/360229590一文中介绍了崩坏3与原神的计算方式
|
|
|
|
|
|
|
|
|
|
崩坏3的LightMap计算方式:
|
|
|
|
|
```c++
|
|
|
|
|
half4 baseColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv.xy);
|
|
|
|
|
half4 LightMapColor = SAMPLE_TEXTURE2D(_LightMap, sampler_LightMap, input.uv.xy);
|
|
|
|
|
half3 ShadowColor = baseColor.rgb * _ShadowMultColor.rgb;
|
|
|
|
|
half3 DarkShadowColor = baseColor.rgb * _DarkShadowMultColor.rgb;
|
|
|
|
|
|
|
|
|
|
//如果SFactor = 0,ShallowShadowColor为一级阴影色,否则为BaseColor。
|
|
|
|
|
float SWeight = (LightMapColor.g * input.color.r + input.lambert) * 0.5 + 1.125;
|
|
|
|
|
float SFactor = floor(SWeight - _ShadowArea);
|
|
|
|
|
half3 ShallowShadowColor = SFactor * baseColor.rgb + (1 - SFactor) * ShadowColor.rgb;
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
二级阴影计算:
|
|
|
|
|
```c++
|
|
|
|
|
//如果SFactor = 0,DarkShadowColor为二级阴影色,否则为一级阴影色。
|
|
|
|
|
SFactor = floor(SWeight - _DarkShadowArea);
|
|
|
|
|
DarkShadowColor = SFactor * (_FixDarkShadow * ShadowColor + (1 - _FixDarkShadow) * ShallowShadowColor) + (1 - SFactor) * DarkShadowColor;
|
|
|
|
|
|
|
|
|
|
// 平滑阴影边缘
|
|
|
|
|
half rampS = smoothstep(0, _ShadowSmooth, input.lambert - _ShadowArea);
|
|
|
|
|
half rampDS = smoothstep(0, _DarkShadowSmooth, input.lambert - _DarkShadowArea);
|
|
|
|
|
ShallowShadowColor.rgb = lerp(ShadowColor, baseColor.rgb, rampS);
|
|
|
|
|
DarkShadowColor.rgb = lerp(DarkShadowColor.rgb, ShadowColor, rampDS);
|
|
|
|
|
|
|
|
|
|
//如果SFactor = 0,FinalColor为二级阴影,否则为一级阴影。
|
|
|
|
|
SFactor = floor(LightMapColor.g * input.color.r + 0.9f);
|
|
|
|
|
half4 FinalColor;
|
|
|
|
|
FinalColor.rgb = SFactor * ShallowShadowColor + (1 - SFactor) * DarkShadowColor;
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
**罪恶装备**:
|
|
|
|
|
对阴影判断阈值的偏移。(见前面着色部分,顶点AO+手绘修正)
|
|
|
|
|
G : 轮廓线根据与相机的距离扩大多少的系数
|
|
|
|
|
B : 等高线 Z 轴偏移值
|
|
|
|
|
A : 轮廓厚度系数。0.5为标准,1为最大厚度,0为无等高线
|
|
|
|
|
|
2023-12-18 11:48:10 +08:00
|
|
|
|
# 蓝色协议
|
2023-12-16 23:09:19 +08:00
|
|
|
|
[[蓝色协议的方案]]
|
|
|
|
|
|
2023-12-18 11:48:10 +08:00
|
|
|
|
# 米哈游
|