You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现纹理向近黑色平滑融合且无色彩溢出伪影?

解决方案:平滑暗化纹理至近黑色且避免色彩溢出

问题本质

这种现象根源是低精度颜色格式的量化误差:当RGB值趋近于0时,通道的离散数值无法维持原色调比例,导致色彩失衡;直接线性暗化会放大暗部的精度损失。同时Unity中关闭环境光后,光照计算的暗部缺乏精度缓冲,进一步暴露了该问题。

核心数学方法

1. 色调保持的暗化算法

先提取颜色的色调(Hue)和饱和度(Saturation),仅对明度(Value/Luminance)做非线性压缩,确保暗部色调比例稳定:

  • 将RGB转换为HSV色彩空间
  • 对V通道应用平滑渐近压缩,比如用 V_new = 1 - exp(-k * V_old) 的逆运算,或平滑阶梯函数避免V值突变到0
  • 转换回RGB空间,保证通道值在量化范围内维持比例

2. 暗部精度补偿

在暗化后的颜色中加入极细微、与原色调一致的“锚点”值,避免通道值直接掉到0,同时不破坏视觉上的近黑色效果:

finalRGB = max(darkenedRGB, anchorRGB);

其中anchorRGB是原RGB比例乘以极小值(如0.001),既能维持色调平衡,又不会影响深色表现。

Unity URP 着色器实现示例

以下是基于URP Lit着色器修改的暗化处理代码,可集成到片元着色器阶段:

float3 SmoothDarkenToBlack(float3 rgb, float darkenFactor) {
    // 转换到HSV空间
    float3 hsv = RGBToHSV(rgb);
    
    // 对明度通道做平滑压缩,避免线性衰减的精度问题
    float v = hsv.z;
    // 指数平滑确保暗部过渡平缓
    float smoothedV = 1.0 - exp(-v / max(darkenFactor, 0.001));
    // 限制最小值,防止完全黑死
    smoothedV = max(smoothedV, 0.0005);
    
    hsv.z = smoothedV;
    float3 result = HSVToRGB(hsv);
    
    // 添加色调锚点,维持暗部比例
    float3 anchor = rgb * 0.0008;
    result = max(result, anchor);
    
    return result;
}

// 片元着色器中调用
float3 baseColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, i.uv).rgb;
// _DarkenFactor控制暗化程度:1.0为原亮度,0.0为近黑色
baseColor = SmoothDarkenToBlack(baseColor, _DarkenFactor);

额外优化

  • 纹理导入时勾选线性颜色空间(Unity中关闭"SRGB (Color Texture)"选项,仅伽马空间纹理需开启)
  • 在URP设置中开启高精度渲染(Project Settings > Graphics > URP Settings > Precision > High),减少暗部精度损失

Gimp中的处理方法

  • 将图像转换为32位浮点格式(Image > Precision > 32-bit Float),提升暗部精度
  • 使用曲线调整时,在暗部区域添加多个锚点,构建平滑渐近曲线,避免线性下拉到0
  • 导出前添加0.1%左右的增益,防止通道值完全为0

内容的提问来源于stack exchange,提问作者marai.hmm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 06:22:54