博客 / 詳情

返回

【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開始探索遊戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,🙏)
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.