【URP】Unity[后处理]白平衡WhiteBalance

【从UnityURP开始探索游戏渲染】专栏-直达

白平衡概述

白平衡(White Balance)是Unity URP后处理系统中的重要组件,用于消除不真实的色偏,使现实中应显示为白色的物体在最终图像中呈现白色。它通过调整色温和色调来补偿不同光源条件下的色彩偏差,同时也可用于营造特定的场景氛围。

白平衡的概念源自摄影领域,旨在解决不同光源下色彩还原的问题。在Unity中,白平衡功能随着HDRP和URP渲染管线的演进不断完善,从最初的简单色彩校正发展到基于Volume框架的专业级色彩管理系统。

核心功能与作用

色彩校正

  • 消除因光源色温差异导致的色偏,确保白色物体在不同光照条件下保持中性色

氛围营造

  • 通过调整色温和色调参数,创造冷暖不同的整体画面效果

艺术表达

  • 突破真实色彩限制,实现风格化的视觉效果

实现原理

URP中的白平衡基于Volume框架实现,采用科学色彩空间转换算法。其核心是通过CIE色度图和LMS色彩空间的转换,调整输入颜色的色温和色调:

  • 将输入颜色从线性RGB空间转换到LMS色彩空间
  • 根据设定的色温和色调参数计算平衡系数
  • 应用平衡系数后转换回线性RGB空间

Unity URP中的白平衡(White Balance)后处理效果基于色彩空间转换算法实现,其核心原理是通过调整色温和色调参数来补偿不同光照条件下的色彩偏差。

底层原理详解

白平衡的数学实现主要分为以下几个步骤:

  • 色彩空间转换‌:将输入颜色从线性RGB空间转换到LMS色彩空间(长波、中波、短波锥体响应空间)
hlsl
float3x3 LIN_2_LMS_MAT = {
    3.90405e-1, 5.49941e-1, 8.92632e-3,
    7.08416e-2, 9.63172e-1, 1.35775e-3,
    2.31082e-2, 1.28021e-1, 9.36245e-1
};
float3 lms = mul(LIN_2_LMS_MAT, In);
  • 白点计算‌:根据设定的色温(Temperature)和色调(Tint)参数计算参考白点
hlsl
float t1 = Temperature * 10/6;
float t2 = Tint * 10/6;
float x = 0.31271 - t1 * (t1 < 0 ? 0.1 : 0.05);
float standardIlluminantY = 2.87*x - 3*x*x - 0.27509507;
float y = standardIlluminantY + t2 * 0.05hlsl
  • 平衡系数计算‌:比较当前白点与标准D65白点的差异
hlsl
float3 w1 = float3(0.949237, 1.03542, 1.08728); // D65白点
float3 w2 = float3(L, M, S); // 当前白点
float3 balance = float3(w1.x/w2.x, w1.y/w2.y, w1.z/w2.z);
  • 应用平衡并转换回RGB空间
hlsl
lms *= balance;
float3x3 LMS_2_LIN_MAT = {
    2.85847e+0, -1.62879e+0, -2.48910e-2,
    -2.10182e-1, 1.15820e+0, 3.24281e-4,
    -4.18120e-2, -1.18169e-1, 1.06867e+0
};
Out = mul(LMS_2_LIN_MAT, lms);

完整URP实现示例

  • WhiteBalanceEffect.shader

    Shader "Hidden/Universal Render Pipeline/WhiteBalance"
    {
        HLSLINCLUDE
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    
        float _Temperature;
        float _Tint;
    
        float3 ApplyWhiteBalance(float3 color)
        {
            // 温度转换系数
            float t1 = _Temperature * 10.0 / 6.0;
            float t2 = _Tint * 10.0 / 6.0;
    
            // 计算白点坐标
            float x = 0.31271 - t1 * (t1 < 0 ? 0.1 : 0.05);
            float standardIlluminantY = 2.87 * x - 3.0 * x * x - 0.27509507;
            float y = standardIlluminantY + t2 * 0.05;
    
            // 转换为XYZ空间
            float Y = 1.0;
            float X = Y * x / y;
            float Z = Y * (1.0 - x - y) / y;
    
            // 转换为LMS空间
            float L = 0.7328 * X + 0.4296 * Y - 0.1624 * Z;
            float M = -0.7036 * X + 1.6975 * Y + 0.0061 * Z;
            float S = 0.0030 * X + 0.0136 * Y + 0.9834 * Z;
    
            // 计算平衡系数
            float3 w1 = float3(0.949237, 1.03542, 1.08728); // D65
            float3 w2 = float3(L, M, S);
            float3 balance = float3(w1.x/w2.x, w1.y/w2.y, w1.z/w2.z);
    
            // RGB转LMS矩阵
            float3x3 RGB2LMS = float3x3(
                0.390405, 0.549941, 0.00892632,
                0.0708416, 0.963172, 0.00135775,
                0.0231082, 0.128021, 0.936245);
    
            // LMS转RGB矩阵
            float3x3 LMS2RGB = float3x3(
                2.85847, -1.62879, -0.024891,
                -0.210182, 1.15820, 0.000324281,
                -0.0418120, -0.118169, 1.06867);
    
            // 应用转换
            float3 lms = mul(RGB2LMS, color);
            lms *= balance;
            return mul(LMS2RGB, lms);
        }
        ENDHLSL
    }
    

参数作用机制

  • Temperature‌:通过改变CIE xy色度图中的x坐标值来调整色温,正值增加暖色调(红/黄),负值增加冷色调(蓝/青)
  • Tint‌:通过调整y坐标值来补偿绿色或洋红色偏,正值增加洋红色调,负值增加绿色调

该实现基于CIE标准色度学和色彩感知理论,通过精确的矩阵运算在不同色彩空间之间转换,确保色彩调整符合人眼视觉特性

URP实现流程

  • WhiteBalanceExample.cs

    using UnityEngine;
    using UnityEngine.Rendering;
    using UnityEngine.Rendering.Universal;
    
    public class WhiteBalanceExample : MonoBehaviour
    {
        [SerializeField] private VolumeProfile volumeProfile;
    
        private WhiteBalance whiteBalance;
    
        void Start()
        {
            // 从Volume Profile获取或添加白平衡覆盖
            if (!volumeProfile.TryGet(out whiteBalance))
            {
                whiteBalance = volumeProfile.Add<WhiteBalance>(true);
            }
    
            // 设置默认参数
            whiteBalance.temperature.Override(0f);
            whiteBalance.tint.Override(0f);
        }
    
        public void SetTemperature(float value)
        {
            whiteBalance.temperature.Override(value);
        }
    
        public void SetTint(float value)
        {
            whiteBalance.tint.Override(value);
        }
    }
    

配置步骤

  • 在Unity编辑器中创建URP Asset(如果尚未创建)
  • 在场景中添加Global Volume或Local Volume组件
  • 在Volume组件中添加White Balance覆盖
  • 通过脚本或直接调整参数控制效果

参数详解与用例

主要参数

参数 描述 典型值范围 应用场景
Temperature 控制色温,调整画面冷暖色调 -100到100 暖色调:黄昏/室内(7000K) 冷色调:夜晚/科幻(4000K)1
Tint 补偿绿色或洋红色偏 -100到100 修正荧光灯色偏(正值)或植被场景(负值)15

实际用例

日间户外场景

  • Temperature≈0,Tint≈0(中性白平衡,约5500K)

黄昏场景

  • Temperature=20-30,Tint=5(暖色调增强)

荧光灯室内

  • Temperature=-10,Tint=10(补偿绿色偏色)

科幻场景

  • Temperature=-30,Tint=-5(冷蓝色调)

进阶技巧

  • 动态调整‌:通过脚本在运行时根据场景光照条件自动调整白平衡
  • 风格化处理‌:结合Color Grading等其他后处理效果创造独特视觉风格
  • 性能优化‌:在移动平台适当降低白平衡计算精度

白平衡作为URP后处理管线的重要组成部分,既能实现专业级的色彩校正,又能为游戏场景创造丰富的情感表达


【从UnityURP开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)

posted @ 2025-11-15 10:34  SmalBox  阅读(10)  评论(0)    收藏  举报