news 2026/10/21 23:36:06

【URP】Unity[后处理]通道混合ChannelMixer

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【URP】Unity[后处理]通道混合ChannelMixer

核心功能与参数

‌通道混合原理‌

通过修改输入颜色通道(Red/Green/Blue)对输出通道的贡献权重,实现如单色保留、色调偏移等效果。例如增加绿色通道对红色输出的影响会使绿色区域偏红。

ChannelMixer在Unity URP后处理中的底层原理基于颜色通道的线性代数变换,通过对RGB通道的权重矩阵运算实现色彩重构.

输出通道 = (R × R权重) + (G × G权重) + (B × B权重) + 常数偏移

该计算在片元着色器中逐像素执行,通过矩阵乘法实现颜色空间转换.

数学原理分解

‌通道变换矩阵

每个输出通道由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)时,新红色通道值为原RGB通道的50%+30%+20%混合。

‌动态参数传递‌

URP通过Volume组件将参数打包为Vector4(xyz为RGB权重,w为常数偏移),每帧更新至Shader。例如电影级调色常用配置:

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);

}

}

实际应用案例

‌电影感调色‌

将蓝色通道注入红色输出(如设置RedOut为(0.8, 0, 0.2)),可创造类似《黑客帝国》的青色阴影效果。

‌风格化渲染‌

通过反转绿色通道贡献(GreenOut设为(-0.5, 1, 0)),实现赛博朋克风格的色彩偏移。

‌黑白滤镜‌

统一各通道权重(如RedOut=(0.3,0.6,0.1))可生成高质量灰度图像,比直接去饱和度更可控。

胶片模拟‌

设置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标准管线的一部分,通过Volume系统实现非破坏性调整,比传统Shader方案更易集成到美术工作流中

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/21 6:18:50

基于自适应RBF神经网络滑模控制的机械臂轨迹跟踪仿真附Simulink仿真

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码及仿真咨询…

作者头像 李华
网站建设 2026/10/22 2:13:24

ByteMorph项目核心突破:BM-Model图像转换技术详解与资源指南

ByteMorph项目核心突破&#xff1a;BM-Model图像转换技术详解与资源指南 【免费下载链接】BM-Model 项目地址: https://ai.gitcode.com/hf_mirrors/ByteDance-Seed/BM-Model 在人工智能图像生成领域&#xff0c;ByteDance-Seed团队近期推出的BM-Model引发行业广泛关注。…

作者头像 李华
网站建设 2026/10/22 7:33:01

腾讯Hunyuan-7B-Instruct-AWQ-Int4开源:重塑大模型轻量化部署格局

在人工智能技术日新月异的当下&#xff0c;大语言模型的高效部署已成为行业发展的关键议题。腾讯近期正式开源的Hunyuan-7B-Instruct-AWQ-Int4模型&#xff0c;正是瞄准这一技术痛点推出的创新解决方案。该模型通过前沿的量化技术与架构优化&#xff0c;在保证卓越性能的同时大…

作者头像 李华
网站建设 2026/10/21 3:36:34

A.每日一题——3606. 优惠券校验器

题目链接&#xff1a;3606. 优惠券校验器&#xff08;简单&#xff09; 算法原理&#xff1a; 解法&#xff1a;模拟 击败47.54% 时间复杂度O(Nlogn) 这题的思路非常简单&#xff0c;但是实现起来比较麻烦&#xff0c;感觉应该算个中等题&#xff0c;主要就是考察排序 记忆&…

作者头像 李华
网站建设 2026/10/22 5:40:45

C++起源与核心:版本演进+命名空间法

一、C的发展历史 -我们将C的发展史归纳为节点的形式展示 关键节点&#xff1a; 起源&#xff08;1979–1983&#xff09;&#xff1a;丹麦科学家本贾尼斯特劳斯特卢普在贝尔实验室开发“带类的 C 语言”&#xff0c;旨在为 C 语言添加面向对象特性&#xff0c;1983 年正式命…

作者头像 李华
网站建设 2026/10/22 8:28:31

时间序列分析

时间序列分析&#xff1a;从随机过程理论到 SARIMA 模型构建 一、 时间序列的数学定义与性质 1.1 随机序列与观察值 在数学上&#xff0c;时间序列不仅仅是一组数字&#xff0c;它是一个随机过程&#xff08;Stochastic Process&#xff09;。 设 TTT 为一个时间索引集合&#…

作者头像 李华