欧美精产国品一二三区,国产成人一区二区三区A片免费,特级毛片www免费版,成人做爰A片免费看黄冈宾馆,日韩精品人妻中文字幕有码

【URP】Unity[后處理]通道混(hun)合ChannelMixer

專欄-直達

ChannelMixer是Unity URP后(hou)處理系統(tong)中用(yong)于顏色通道混合的(de)(de)核心效(xiao)果組件(jian),主要用(yong)于調整RGB通道的(de)(de)混合比例以實現特定的(de)(de)色彩(cai)分級效(xiao)果。其發展(zhan)歷史可追(zhui)溯(su)至影視行業(ye)的(de)(de)傳(chuan)統(tong)調色技術,后(hou)被整合到Unity的(de)(de)Post Processing Stack中,并隨著(zhu)URP的(de)(de)演進成為Volume框架下(xia)的(de)(de)標準化(hua)模塊(kuai)

核心功能與參數

?通道混合原理?

通過修改輸(shu)入(ru)顏色(se)(se)(se)通道(dao)(Red/Green/Blue)對輸(shu)出通道(dao)的(de)貢獻權重,實現如(ru)單色(se)(se)(se)保留(liu)、色(se)(se)(se)調(diao)偏(pian)移等(deng)效果。例如(ru)增加綠色(se)(se)(se)通道(dao)對紅色(se)(se)(se)輸(shu)出的(de)影響(xiang)會(hui)使綠色(se)(se)(se)區域偏(pian)紅。

ChannelMixer在Unity URP后處(chu)理(li)中(zhong)的底層原(yuan)理(li)基(ji)于顏色通道(dao)的線性(xing)代(dai)數(shu)變換,通過(guo)對(dui)RGB通道(dao)的權重(zhong)矩陣運算實現色彩重(zhong)構.

輸出通道(dao) = (R × R權(quan)重(zhong)) + (G × G權(quan)重(zhong)) + (B × B權(quan)重(zhong)) + 常數偏(pian)移

該計算(suan)在片元著色器中逐像素執行,通過(guo)矩(ju)陣(zhen)乘法實現顏色空間轉換.

數學原理分解

  • ?通道變換矩陣
    • 每個輸出通道由3×4變換矩陣控制(包含常數項),例如紅色輸出通道計算為:
    • $R_{out}=R_{in}\times M_{00}+G_{in}\times M_{01}+B_{in}\times M_{02}+M_{03}$
    • 其中M_03為常數偏移量。
  • ?亮度保持機制?
    • 當啟用Preserve Luminosity時,系統會自動歸一化權重系數,確保滿足:
    • $M_{00}+M_{01}+M_{02}=1.0$
    • 防止畫面過曝或欠曝

URP實現示例 關鍵實現解析

  • ?矩陣運算階段?

    片元著色器通過dot(col.rgb, _RedOut.xyz)實現向量點乘,等效于矩陣乘法。例如設置_RedOut=(0.5,0.3,0.2)時(shi),新紅色通(tong)道值為原RGB通(tong)道的50%+30%+20%混合。

  • ?動態參數傳遞?

    URP通(tong)過Volume組件將參(can)數(shu)打包為Vector4(xyz為RGB權重,w為常數(shu)偏移(yi)),每幀(zhen)更新至(zhi)Shader。例(li)如電影級調色常用(yong)配(pei)置:

    csharp
    _RedOut = new Vector4(0.8f, 0.1f, 0.1f, 0);// 強化紅色主基調
    _GreenOut = new Vector4(0f, 1.2f, -0.2f, 0);// 增強綠色并抑制藍色
    
  • ?后處理管線集成?

    RendererFeature在BeforeRenderingPostProcessing事件點插入通道混合操作,通過雙次Blit避免直接修改源紋理。臨時渲染目標_TempChannelMixerTexture確保混合過程可逆.

  • ChannelMixer.shader

    Shader "PostProcessing/ChannelMixer" {
    Properties {
    _MainTex ("Texture", 2D) = "white" {}
    _RedOut ("Red Output", Vector) = (1,0,0,0)
    _GreenOut ("Green Output", Vector) = (0,1,0,0)
    _BlueOut ("Blue Output", Vector) = (0,0,1,0)
    }
    SubShader {
    HLSLPROGRAM
    #pragma only_renderers d3d11
    #pragma exclude_renderers gles
    #pragma target 5.0
    #pragma multi_compile_postprocess
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/PostProcessing.hlsl"
    
        TEXTURE2D(_MainTex);
        SAMPLER(sampler_MainTex);
        float4 _RedOut;
        float4 _GreenOut;
        float4 _BlueOut;
    
        struct v2f {
            float2 uv : TEXCOORD0;
            float4 vertex : SV_POSITION;
        };
    
        v2f vert(appdata v) {
            v2f o;
            o.vertex = TransformWorldToClipPos(v.vertex);
            o.uv = v.uv;
            return o;
        }
    
        float4 frag(v2f i) : SV_Target {
            float4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
            float3 result;
            result.r = dot(col.rgb, _RedOut.xyz) + _RedOut.w;
            result.g = dot(col.rgb, _GreenOut.xyz) + _GreenOut.w;
            result.b = dot(col.rgb, _BlueOut.xyz) + _BlueOut.w;
            return float4(result, col.a);
        }
        ENDHLSL
    }
    }
    
  • ChannelMixerRendererFeature.cs

    using UnityEngine;
    using UnityEngine.Rendering;
    using UnityEngine.Rendering.Universal;
    
    public class ChannelMixerRendererFeature : ScriptableRendererFeature {
        class CustomRenderPass : ScriptableRenderPass {
            Material _material;
            RenderTargetHandle _tempTexture;
    
            public CustomRenderPass(Material material) {
                _material = material;
                _tempTexture.Init("_TempChannelMixerTexture");
            }
    
            public override void Execute(ScriptableRenderContext context, ref RenderingData data) {
                CommandBuffer cmd = CommandBufferPool.Get("Channel Mixer");
                RenderTextureDescriptor desc = data.cameraData.cameraTargetDescriptor;
    
                cmd.GetTemporaryRT(_tempTexture.id, desc);
                Blit(cmd, source: "_CameraColorTexture", dest: _tempTexture.id, _material);
                Blit(cmd, source: _tempTexture.id, dest: "_CameraColorTexture");
    
                cmd.ReleaseTemporaryRT(_tempTexture.id);
                context.ExecuteCommandBuffer(cmd);
                CommandBufferPool.Release(cmd);
            }
        }
    
        [System.Serializable]
        public class Settings {
            public Material material;
        }
    
        public Settings settings = new Settings();
        CustomRenderPass _scriptablePass;
    
        public override void Create() {
            _scriptablePass = new CustomRenderPass(settings.material);
            _scriptablePass.renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
        }
    
        public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData data) {
            renderer.EnqueuePass(_scriptablePass);
        }
    }
    

?參數說明?

  • ?Output Channel?:選擇要調整的目標通道(Red/Green/Blue)
  • ?Red/Green/Blue Contribution?:各輸入通道對當前輸出通道的影響權重(范圍-2到2)
  • ?Preserve Luminosity?:保持整體亮度不變,避免過度曝光。

實現流程示例

ChannelMixerExample.cs

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class ChannelMixerExample : VolumeComponent, IPostProcessComponent {
    public Vector3Parameter redOut = new(new Vector3(1, 0, 0));
    public Vector3Parameter greenOut = new(new Vector3(0, 1, 0)); 
    public Vector3Parameter blueOut = new(new Vector3(0, 0, 1));

    public bool IsActive() => true;
    public bool IsTileCompatible() => false;
}

ChannelMixerRenderPass.cs

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class ChannelMixerRenderPass : ScriptableRenderPass {
    private Material _material;
    private ChannelMixerExample _volume;

    public override void Execute(ScriptableRenderContext context, ref RenderingData data) {
        _volume = VolumeManager.instance.stack.GetComponent<ChannelMixerExample>();
        if (_volume == null) return;

        var cmd = CommandBufferPool.Get("ChannelMixer");
        _material.SetVector("_RedOut", _volume.redOut.value);
        _material.SetVector("_GreenOut", _volume.greenOut.value);
        _material.SetVector("_BlueOut", _volume.blueOut.value);
        Blit(cmd, ref data, _material, 0);
        context.ExecuteCommandBuffer(cmd);
    }
}

實際應用案例

?電影感調色?

將藍色(se)通道注入(ru)紅色(se)輸出(如設(she)置RedOut為(0.8, 0, 0.2)),可創造類似(si)《黑客帝國(guo)》的(de)青色(se)陰影效(xiao)果。

?風格化渲染?

通過反轉(zhuan)綠色(se)通道貢獻(xian)(GreenOut設(she)為(wei)(-0.5, 1, 0)),實(shi)現賽博朋(peng)克風格的色(se)彩(cai)偏移。

?黑白濾鏡?

統(tong)一(yi)各(ge)通道權重(如RedOut=(0.3,0.6,0.1))可生成高質量灰度(du)圖像,比(bi)直接(jie)去飽和度(du)更可控。

膠片模擬?

  • 設置BlueOut=(0,0,0.9,0.1)使藍色通道輕微壓縮,模擬柯達膠片特性

?色盲輔助?

  • 將紅色通道注入綠色輸出(GreenOut=(0.5,0.5,0,0))提升紅綠色盲辨識度

?風格化渲染?

  • 負值權重創造互補色效果,如RedOut=(1, -0.2, 0, 0)產生賽博朋克色調

操作步驟

  • 在Volume中添加Channel Mixer效果
  • 調整目標通道的RGB權重三角滑塊
  • 啟用Preserve Luminosity避免過曝

該技術現已成為URP標(biao)準(zhun)管(guan)線的一(yi)部分,通過Volume系統實現非(fei)破壞性調整,比傳統Shader方案更(geng)易(yi)集成到美(mei)術工作流中


專欄-直達
(歡迎點贊留言探(tan)討,更多人加入進來能更加完(wan)善這個探(tan)索的(de)過程,??)

posted @ 2025-11-01 19:29  SmalBox  閱讀(51)  評論(0)    收藏  舉報