2025-03-27 18:35:48 +08:00
|
|
|
|
---
|
|
|
|
|
title: 未命名
|
|
|
|
|
date: 2025-03-27 17:37:02
|
|
|
|
|
excerpt:
|
|
|
|
|
tags:
|
|
|
|
|
rating: ⭐
|
|
|
|
|
---
|
|
|
|
|
# Toon Lumen
|
2025-03-27 22:45:49 +08:00
|
|
|
|
## 抹平法线思路
|
|
|
|
|
### ViewVector Fix WorldNormal
|
|
|
|
|
参考:
|
|
|
|
|
- [【UE5】环境光与GI 2:抹平法线](https://zhuanlan.zhihu.com/p/25839790454)
|
2025-03-27 18:35:48 +08:00
|
|
|
|
|
|
|
|
|
在`LumenScreenProbeGather.usf`中对法线进行抹平处理。其Pass位于
|
|
|
|
|
- DiffuseIndirectAndAO
|
|
|
|
|
- LumenScreenProbeGather
|
|
|
|
|
- Integrate
|
|
|
|
|
- SimpleDiffuse/SupportImportanceSampleBRDF?/SupportAll?
|
|
|
|
|
|
|
|
|
|
在如下位置添加代码:
|
|
|
|
|
```c++
|
|
|
|
|
if (IsValid(Material))
|
|
|
|
|
{
|
|
|
|
|
const float2 ScreenUV = (Coord.SvPosition + 0.5f) * View.BufferSizeAndInvSize.zw;
|
|
|
|
|
const float3 WorldPosition = GetWorldPositionFromScreenUV(ScreenUV, Material.SceneDepth);
|
|
|
|
|
const float3 WorldNormal = Material.WorldNormal;
|
|
|
|
|
//BlueRose Modify
|
|
|
|
|
if (Material.ShadingID == SHADINGMODELID_TOONSTANDARD)
|
|
|
|
|
{
|
|
|
|
|
//使用Yu-ki016的方法“抹平法线”
|
|
|
|
|
float3 V = normalize(LWCHackToFloat(PrimaryView.WorldCameraOrigin) - WorldPosition);
|
|
|
|
|
const uint ToonDataAssetID = GetToonDataAssetIDFromGBuffer(Material.GBufferData);
|
|
|
|
|
float DiffuseIndirectLightingFlatten = GetDiffuseIndirectLightingFlatten(ToonDataAssetID);
|
|
|
|
|
Material.WorldNormal = normalize(lerp(WorldNormal, V, DiffuseIndirectLightingFlatten));
|
|
|
|
|
}
|
|
|
|
|
//BlueRose Modify End
|
|
|
|
|
...
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
该方法存在一些问题:**当相机围绕角色旋转时,角色身上的 GI变化会比较明显**。
|
|
|
|
|
|
2025-03-27 22:45:49 +08:00
|
|
|
|
### 低频化WorldNormal & Spherical Harmonics
|
|
|
|
|
参考:
|
|
|
|
|
- [[UFSH2024]用虚幻引擎5为《幻塔》定制高品质动画流程风格化渲染管线 | 晨风 Neverwind 完美世界游戏】【精准空降到 12:55】](https://www.bilibili.com/video/BV1rW2LYvEox/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e&t=775)
|
|
|
|
|
- [[UFSH2024]用虚幻引擎5为《幻塔》定制高品质动画流程风格化渲染管线 | 晨风 Neverwind 完美世界游戏】 【精准空降到 36:52】](https://www.bilibili.com/video/BV1rW2LYvEox/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e&t=2212)
|
|
|
|
|
- [ ] 需要实现:法线平滑 => 饱和度平滑。(没说细节,不清楚算法)
|
|
|
|
|
- [[UFSH2024]用虚幻引擎5为《幻塔》定制高品质动画流程风格化渲染管线 | 晨风 Neverwind 完美世界游戏】【精准空降到 35:09】](https://www.bilibili.com/video/BV1rW2LYvEox/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e&t=2109)
|
|
|
|
|
- [ ] 小于等于High存储的是一个八面体,提前加一个Pass进行平滑:采样法线方向半球面的平均数值。
|
|
|
|
|
- [ ] 大于等于Epic存储的是一个三阶球谐,保持1阶球谐数值不变,对2~3阶球谐按照系数进行平滑。并且添加能量补偿,大致与PBR的结果接近。
|
|
|
|
|
![[Lumen_SHData.png|800]]
|
|
|
|
|
|
2025-03-28 15:32:21 +08:00
|
|
|
|
![[Lumen_能量补偿1.png|800]]
|
|
|
|
|
![[Lumen_能量补偿2.png|800]]
|
2025-03-27 18:35:48 +08:00
|
|
|
|
UE5中采样球谐贴图方法(ReflectionEnvironmentShared.ush):
|
|
|
|
|
```c++
|
|
|
|
|
/**
|
|
|
|
|
* Computes sky diffuse lighting from the SH irradiance map.
|
|
|
|
|
* This has the SH basis evaluation and diffuse convolution weights combined for minimal ALU's - see "Stupid Spherical Harmonics (SH) Tricks"
|
|
|
|
|
*/
|
|
|
|
|
float3 GetSkySHDiffuse(float3 Normal)
|
|
|
|
|
{
|
|
|
|
|
float4 NormalVector = float4(Normal, 1.0f);
|
|
|
|
|
|
|
|
|
|
float3 Intermediate0, Intermediate1, Intermediate2;
|
|
|
|
|
Intermediate0.x = dot(SkyIrradianceEnvironmentMap[0], NormalVector);
|
|
|
|
|
Intermediate0.y = dot(SkyIrradianceEnvironmentMap[1], NormalVector);
|
|
|
|
|
Intermediate0.z = dot(SkyIrradianceEnvironmentMap[2], NormalVector);
|
|
|
|
|
|
|
|
|
|
float4 vB = NormalVector.xyzz * NormalVector.yzzx;
|
|
|
|
|
Intermediate1.x = dot(SkyIrradianceEnvironmentMap[3], vB);
|
|
|
|
|
Intermediate1.y = dot(SkyIrradianceEnvironmentMap[4], vB);
|
|
|
|
|
Intermediate1.z = dot(SkyIrradianceEnvironmentMap[5], vB);
|
|
|
|
|
|
|
|
|
|
float vC = NormalVector.x * NormalVector.x - NormalVector.y * NormalVector.y;
|
|
|
|
|
Intermediate2 = SkyIrradianceEnvironmentMap[6].xyz * vC;
|
|
|
|
|
|
|
|
|
|
// max to not get negative colors
|
|
|
|
|
return max(0, Intermediate0 + Intermediate1 + Intermediate2);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2025-03-27 22:45:49 +08:00
|
|
|
|
## Cel适配
|
|
|
|
|
需要实现Cel多光源方案。
|
|
|
|
|
|
|
|
|
|
大致的思路就是Copy Lumen结果,之后在[[Toon多光源参考|Toon多光源Pass]]中提取亮度,再根据亮度采样Ramp计算光影结果。
|