区域去饱和度效果

类似鸣潮溢彩画册区域去饱和度效果

Github源码传送门————>ZoneDesaturation

Bilibili教程传送门————>小祥带你实现鸣潮溢彩画册区域降饱和度效果

实机

整体思路

可以看到游戏中效果是一个指定区域内物体饱和度被降低,但指定物体比如中间的画册及其特效当然还有我们玩家模型,是有在正常渲染的。第一步,我们首先排除后处理效果,这个效果显然不是后处理实现的。如果是一整个区域内所有物体都被去饱和度效果影响,我们是可以通过后处理来做的。但是这个效果区域内有指定的物体是没有被效果影响的,既有不透明物体又有透明物体。有人可能会说,那我渲染个遮罩出来,将玩家和指定物体剔除掉不就好了,那么接着要面临的问题是如何计算当前像素是否在影响范围内呢?通过深度贴图反推的话,如果影响范围的原点在相机视野外,又该如何处理?更何况透明物体没有写入深度,通过像素反推世界空间坐标就更不可能了。所以这次我们只能将去饱和度相关的内容置入每个会被影响的物体的材质中,使用子图(SubGraph)将其变成一个效果模块使用。具体实现思路比较清晰,渲染物体的时候判断当前像素坐标和影响范围中心点坐标的距离,如果影响范围内的话就应用去饱和度效果。

ZoneDesaturation.shader

SubGraph

对应shader代码大概是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
float4 baseColor = _BaseColor;

float3 luminanceWeight = float3(0.299, 0.587, 0.114);
float gray = dot(baseColor, luminanceWeight);
float3 desatColor = float3(gray, gray, gray);

float dist = distance(i.worldPos, _Center.xyz);
float mask = smoothstep(_DesaturationRadius - 5, _DesaturationRadius, dist);
float3 mixedColor = lerp(baseColor, desatColor, mask);

float3 finalColor = lerp(baseColor, mixedColor, _ApplyDesaturation);

return float4(finalColor, baseColor.a);
  • **float3(0.299, 0.587, 0.114)**这个加权系数是国际电信联盟组织(ITU)规定的Rec.601标准,用于将彩色转为灰度,计算得到的灰度值就是一个符合人眼感知的亮度值
  • 计算当前像素世界坐标与设定的中心位置坐标之间的距离,范围内的像素应用灰度值,使用**smoothstep()**方法使得去饱和度效果范围边缘过渡平滑
  • _DesaturationRadius 效果半径 _Center 效果中心坐标 _ApplyDesaturation是否应用去饱和效果 这些参数外配方便代码控制

完结撒花~

pid:133075782


区域去饱和度效果
https://baifabaiquan.cn/2025/08/08/ZoneDesaturation/
作者
白发败犬
发布于
2025年8月8日
许可协议