ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Godot 4 RenderingDevice 渲染管线颜色混合状态详解:RDPipelineColorBlendState 与 RDPipelineColorBlendStateAttachment

Godot 4 RenderingDevice 渲染管线颜色混合状态详解:RDPipelineColorBlendState 与 RDPipelineColorBlendStateAttachment
  • 文档
  • 教程
  • 游戏开发

【免费下载链接】godot-docs

Godot Engine official documentation

项目地址:https://gitcode.com/GitHub_Trending/go/godot-docs
点击查看免费下载

本篇技术指南以 Godot 4 官方文档 class_rdpipelinecolorblendstate.rst 与 class_rdpipelinecolorblendstateattachment.rst 为骨架,系统讲解 RenderingDevice 底层渲染管线中颜色混合(color blend)状态的配置方法:从顶层RDPipelineColorBlendState的四大属性,到逐通道的RDPipelineColorBlendStateAttachment混合因子与混合算子,再到 Mix、Add、Subtract、Multiply、Pre-multiplied alpha 五组可直接复用的 GDScript 配方。读完你将掌握如何为自建图形管线精确控制颜色输出、alpha 合成与可选的逻辑运算,并能把混合状态正确接入render_pipeline_create()调用链。

RDPipelineColorBlendState 在渲染管线中的定位

RDPipelineColorBlendState继承自RefCounted(进而继承Object),是 GodotRenderingDevice渲染管线创建流程中的状态描述对象之一。它的用途非常聚焦:为图形管线描述"颜色如何混合"的完整配置,包括一组逐渲染目标(attachment)的混合设置、一个全局混合常数颜色,以及可选的帧缓冲逻辑运算。

在 class_renderingdevice.rst 中,render_pipeline_create()的方法签名清晰地展示了它的位置:

RID render_pipeline_create( shader: RID, framebuffer_format: int, vertex_format: int, primitive: RenderPrimitive, rasterization_state: RDPipelineRasterizationState, multisample_state: RDPipelineMultisampleState, stencil_state: RDPipelineDepthStencilState, color_blend_state: RDPipelineColorBlendState, dynamic_state_flags: PipelineDynamicStateFlags = 0, for_render_pass: int = 0, specialization_constants: Array[RDPipelineSpecializationConstant] = [] )

可以看到,color_blend_state是与光栅化状态、多重采样状态、深度模板状态并列的第 8 个参数,属于创建图形管线时不可缺失的一环。方法返回一个RID,该 RID 可通过free_rid()显式释放,也会在shader被释放时自动回收。

RDPipelineColorBlendState 的四大属性

原文档给出了该对象完整属性表(默认值取自 class_rdpipelinecolorblendstate.rst):

属性类型默认值含义
attachmentsArray[RDPipelineColorBlendStateAttachment][]参与混合的渲染目标(attachment)数组
blend_constantColorColor(0, 0, 0, 1)用于混合的常数颜色
enable_logic_opboolfalse是否执行logic_op定义的逻辑运算
logic_opLogicOperation(枚举)0(即LOGIC_OP_CLEAR)混合时执行的逻辑运算,仅在enable_logic_op为true时生效

attachments:逐渲染目标的混合规则

attachments是一个RDPipelineColorBlendStateAttachment数组,用于描述每一个颜色渲染目标各自的混合方式,即"The attachments that are blended together."。当管线绑定多个颜色附件(如 MRTS 多目标渲染)时,数组中的第 N 个元素对应第 N 个颜色附件;每个元素都可以独立配置是否启用混合、源/目标混合因子与混合算子(详见下文)。默认值为空数组[]。

blend_constant:混合常数颜色

blend_constant默认值为Color(0, 0, 0, 1)(黑色、不透明 alpha)。它作为混合因子体系中的"常数项"来源,当某个附件把src_*_blend_factor或dst_*_blend_factor设置为BLEND_FACTOR_CONSTANT_COLOR、BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR、BLEND_FACTOR_CONSTANT_ALPHA或BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA时,该颜色与 alpha 值就会被代入混合方程。

原文档还特别提示它与RenderingDevice.draw_list_set_blend_constants()的关联。查证 class_renderingdevice.rst 可知:

  • draw_list_set_blend_constants(draw_list, color)用于在绘制列表上把混合常数设置为指定color;
  • 但混合常数只有在管线以DYNAMIC_STATE_BLEND_CONSTANTS标志创建时才会被该调用实际采用。

DYNAMIC_STATE_BLEND_CONSTANTS = 4,它属于 PipelineDynamicStateFlags 位标志之一(另有DYNAMIC_STATE_LINE_WIDTH = 1、DYNAMIC_STATE_DEPTH_BIAS = 2)。也就是说:blend_constant是静态配置的默认值,而启用动态状态后即可在每帧绘制前用draw_list_set_blend_constants()按需覆盖,实现随时间变化的半透明特效。

enable_logic_op 与 logic_op:帧缓冲逻辑运算

当enable_logic_op为true时,混合阶段会改为执行logic_op指定的位级逻辑运算(此时混合因子与混合算子不参与,逻辑运算直接作用在源颜色与目标颜色之间)。logic_op的类型为LogicOperation枚举,默认值0对应LOGIC_OP_CLEAR,即结果恒为0——因此在未显式配置时开启逻辑运算会得到全黑输出,务必同时设置正确的运算类型。

LogicOperation 枚举全表

LogicOperation定义于 class_renderingdevice.rst,共 17 个成员(含大小哨兵)。逻辑运算的两个操作数分别为源颜色(source)与目标/帧缓冲颜色(destination):

常量值运算语义
LOGIC_OP_CLEAR0清除,结果恒为0(参考LOGIC_OP_SET)
LOGIC_OP_AND1按位与
LOGIC_OP_AND_REVERSE2目标取反后再与源做按位与(~dst & src)
LOGIC_OP_COPY3拷贝,结果保持源值不变(参考COPY_INVERTED/NO_OP)
LOGIC_OP_AND_INVERTED4源取反后再与目标做按位与(~src & dst)
LOGIC_OP_NO_OP5空操作,结果保持目标值不变(参考COPY)
LOGIC_OP_XOR6按位异或
LOGIC_OP_OR7按位或
LOGIC_OP_NOR8按位或非
LOGIC_OP_EQUIVALENT9同或(XNOR)
LOGIC_OP_INVERT10取反(仅对目标)
LOGIC_OP_OR_REVERSE11目标取反后再与源做按位或(~dst \| src)
LOGIC_OP_COPY_INVERTED12取反拷贝,结果为源取反
LOGIC_OP_OR_INVERTED13源取反后再与目标做按位或(~src \| dst)
LOGIC_OP_NAND14按位与非
LOGIC_OP_SET15置位,结果恒为1(参考LOGIC_OP_CLEAR)
LOGIC_OP_MAX16枚举大小哨兵,非真实运算

逻辑运算通常用于非标准颜色合成(例如 CRT 扫描线效果、图案混合、通道复用等低层技巧),多数常规渲染场景保持enable_logic_op = false即可。

混合基础:RDPipelineColorBlendStateAttachment 逐属性解析

RDPipelineColorBlendStateAttachment(继承自RefCounted)负责描述单个颜色渲染目标的混合规则,官方描述为"Controls how blending between source and destination fragments is performed when using RenderingDevice.",即控制源片元与目标片元之间的混合方式。其 11 个属性与 1 个便捷方法如下(默认值见 class_rdpipelinecolorblendstateattachment.rst):

属性类型默认值含义
enable_blendboolfalse是否启用混合;关闭时混合因子/混合算子不生效
color_blend_opBlendOperation0(BLEND_OP_ADD)RGB 颜色通道使用的混合算子
alpha_blend_opBlendOperation0(BLEND_OP_ADD)Alpha 通道使用的混合算子
src_color_blend_factorBlendFactor0(BLEND_FACTOR_ZERO)颜色通道的源混合因子
dst_color_blend_factorBlendFactor0(BLEND_FACTOR_ZERO)颜色通道的目标混合因子
src_alpha_blend_factorBlendFactor0(BLEND_FACTOR_ZERO)Alpha 通道的源混合因子
dst_alpha_blend_factorBlendFactor0(BLEND_FACTOR_ZERO)Alpha 通道的目标混合因子
write_rbooltrue是否把新红色通道写入最终结果
write_gbooltrue是否把新绿色通道写入最终结果
write_bbooltrue是否把新蓝色通道写入最终结果
write_abooltrue是否把新 Alpha 通道写入最终结果

各属性的精确语义(依据原文档):

  • enable_blend:为true时,按照src_color_blend_factor、dst_color_blend_factor、src_alpha_blend_factor、dst_alpha_blend_factor四个因子执行源与目标之间的混合;同时color_blend_op、alpha_blend_op决定混合方程采用哪种算子,而write_r/g/b/a控制最终哪些通道被写入输出。
  • color_blend_op/alpha_blend_op:分别为 RGB 颜色通道与 Alpha 通道选择混合算子(加法、减法、反向减法、取最小、取最大)。
  • 四个混合因子:分别控制"源片元"与"目标片元"如何决定颜色通道与 Alpha 通道的混合系数。源(source)指当前片元着色器输出,目标(destination)指帧缓冲中已存在的颜色。
  • write_r/g/b/a:四个写入开关默认全为true,即默认所有通道都会被新结果覆盖;若某个通道关闭写入,则该通道保留帧缓冲原有值——常用于只写 alpha 或只写深度的特殊用途(例如模板通道复用、逐通道排序技巧)。

set_as_mix():标准混合便捷方法

除属性外,RDPipelineColorBlendStateAttachment还提供一个无参便捷方法set_as_mix(),原文档(class_rdpipelinecolorblendstateattachment.rst)说明它用于执行直通(非预乘)alpha 的标准混合,等价于一次性设置:

  • enable_blend = true
  • src_color_blend_factor = BLEND_FACTOR_SRC_ALPHA
  • dst_color_blend_factor = BLEND_FACTOR_ONE_MINUS_SRC_ALPHA
  • src_alpha_blend_factor = BLEND_FACTOR_SRC_ALPHA
  • dst_alpha_blend_factor = BLEND_FACTOR_ONE_MINUS_SRC_ALPHA

即常见的"Alpha 混合"最简写法:result = src * src_alpha + dst * (1 - src_alpha),相当于下文 Mix 配方的快捷版。

常见混合模式的 GDScript 配方

原文档在RDPipelineColorBlendStateAttachment中给出了 Godot 2D 渲染器五种常见混合模式的参考实现,以下完整继承并逐条解读。这些代码块可直接用于构造附件对象。

Mix(标准 Alpha 混合)

var attachment = RDPipelineColorBlendStateAttachment.new() attachment.enable_blend = true attachment.color_blend_op = RenderingDevice.BLEND_OP_ADD attachment.src_color_blend_factor = RenderingDevice.BLEND_FACTOR_SRC_ALPHA attachment.dst_color_blend_factor = RenderingDevice.BLEND_FACTOR_ONE_MINUS_SRC_ALPHA attachment.alpha_blend_op = RenderingDevice.BLEND_OP_ADD attachment.src_alpha_blend_factor = RenderingDevice.BLEND_FACTOR_ONE attachment.dst_alpha_blend_factor = RenderingDevice.BLEND_FACTOR_ONE_MINUS_SRC_ALPHA

颜色通道按src * src_alpha + dst * (1 - src_alpha)合成;Alpha 通道则按src * 1 + dst * (1 - src_alpha),即源 alpha 原样保留、目标 alpha 以(1 - src_alpha)衰减——这正是直通 alpha 的"覆盖式"合成,与set_as_mix()等价(仅 alpha 源因子写法不同)。

Add(加法混合,适用于发光/粒子叠加)

var attachment = RDPipelineColorBlendStateAttachment.new() attachment.enable_blend = true attachment.alpha_blend_op = RenderingDevice.BLEND_OP_ADD attachment.color_blend_op = RenderingDevice.BLEND_OP_ADD attachment.src_color_blend_factor = RenderingDevice.BLEND_FACTOR_SRC_ALPHA attachment.dst_color_blend_factor = RenderingDevice.BLEND_FACTOR_ONE attachment.src_alpha_blend_factor = RenderingDevice.BLEND_FACTOR_SRC_ALPHA attachment.dst_alpha_blend_factor = RenderingDevice.BLEND_FACTOR_ONE

颜色与 Alpha 均为src * src_alpha + dst * 1,只增不减,适合火花、光晕、能量场等"累加发光"效果。

Subtract(减法混合)

var attachment = RDPipelineColorBlendStateAttachment.new() attachment.enable_blend = true attachment.alpha_blend_op = RenderingDevice.BLEND_OP_REVERSE_SUBTRACT attachment.color_blend_op = RenderingDevice.BLEND_OP_REVERSE_SUBTRACT attachment.src_color_blend_factor = RenderingDevice.BLEND_FACTOR_SRC_ALPHA attachment.dst_color_blend_factor = RenderingDevice.BLEND_FACTOR_ONE attachment.src_alpha_blend_factor = RenderingDevice.BLEND_FACTOR_SRC_ALPHA attachment.dst_alpha_blend_factor = RenderingDevice.BLEND_FACTOR_ONE

混合算子为BLEND_OP_REVERSE_SUBTRACT,方程是dst - src(目标减源),颜色与 Alpha 通道均执行该减法。注意这不是BLEND_OP_SUBTRACT(那是src - dst),方向相反,切勿混用。

Multiply(乘法混合,用于阴影/暗化)

var attachment = RDPipelineColorBlendStateAttachment.new() attachment.enable_blend = true attachment.alpha_blend_op = RenderingDevice.BLEND_OP_ADD attachment.color_blend_op = RenderingDevice.BLEND_OP_ADD attachment.src_color_blend_factor = RenderingDevice.BLEND_FACTOR_DST_COLOR attachment.dst_color_blend_factor = RenderingDevice.BLEND_FACTOR_ZERO attachment.src_alpha_blend_factor = RenderingDevice.BLEND_FACTOR_DST_ALPHA attachment.dst_alpha_blend_factor = RenderingDevice.BLEND_FACTOR_ZERO

颜色通道为src * dst_color + dst * 0,即"源颜色乘以目标颜色",整体输出只会变暗;Alpha 通道同理取src * dst_alpha。适合透光阴影、遮罩压暗等场景。

Pre-multiplied alpha(预乘 Alpha 混合)

var attachment = RDPipelineColorBlendStateAttachment.new() attachment.enable_blend = true attachment.alpha_blend_op = RenderingDevice.BLEND_OP_ADD attachment.color_blend_op = RenderingDevice.BLEND_OP_ADD attachment.src_color_blend_factor = RenderingDevice.BLEND_FACTOR_ONE attachment.dst_color_blend_factor = RenderingDevice.BLEND_FACTOR_ONE_MINUS_SRC_ALPHA attachment.src_alpha_blend_factor = RenderingDevice.BLEND_FACTOR_ONE attachment.dst_alpha_blend_factor = RenderingDevice.BLEND_FACTOR_ONE_MINUS_SRC_ALPHA

与 Mix 的区别在于:源颜色因子直接用BLEND_FACTOR_ONE,因为纹理/颜色数据在进入管线前已经乘过 alpha(颜色通道已预乘)。预乘方案可避免直通 alpha 合成中常见的"边缘暗边/亮边"瑕疵,是高质量半透明渲染的常用选择。

注意:五个配方都要求先RDPipelineColorBlendStateAttachment.new()实例化(RefCounted无需手动释放),并按需把write_r/g/b/a四个写入开关调整为true/false。

支撑枚举:BlendFactor 与 BlendOperation 全表

配方中的常量来自RenderingDevice的两个枚举,完整定义见 class_renderingdevice.rst。

BlendFactor(混合因子,20 个成员)

常量值颜色通道因子Alpha 通道因子
BLEND_FACTOR_ZERO0常数0.0常数0.0
BLEND_FACTOR_ONE1常数1.0常数1.0
BLEND_FACTOR_SRC_COLOR2源颜色源 Alpha
BLEND_FACTOR_ONE_MINUS_SRC_COLOR31.0 - 源颜色1.0 - 源 Alpha
BLEND_FACTOR_DST_COLOR4目标颜色目标 Alpha
BLEND_FACTOR_ONE_MINUS_DST_COLOR51.0 - 目标颜色1.0 - 目标 Alpha
BLEND_FACTOR_SRC_ALPHA6源 Alpha源 Alpha
BLEND_FACTOR_ONE_MINUS_SRC_ALPHA71.0 - 源 Alpha1.0 - 源 Alpha
BLEND_FACTOR_DST_ALPHA8目标 Alpha目标 Alpha
BLEND_FACTOR_ONE_MINUS_DST_ALPHA91.0 - 目标 Alpha1.0 - 目标 Alpha
BLEND_FACTOR_CONSTANT_COLOR10混合常数颜色混合常数 Alpha
BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR111.0 - 混合常数颜色1.0 - 混合常数 Alpha
BLEND_FACTOR_CONSTANT_ALPHA12混合常数 Alpha混合常数 Alpha
BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA131.0 - 混合常数 Alpha1.0 - 混合常数 Alpha
BLEND_FACTOR_SRC_ALPHA_SATURATE14min(源 Alpha, 1.0 - 目标 Alpha)常数1.0
BLEND_FACTOR_SRC1_COLOR15第二源颜色(双源混合专用)第二源 Alpha
BLEND_FACTOR_ONE_MINUS_SRC1_COLOR161.0 - 第二源颜色1.0 - 第二源 Alpha
BLEND_FACTOR_SRC1_ALPHA17第二源 Alpha第二源 Alpha
BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA181.0 - 第二源 Alpha1.0 - 第二源 Alpha
BLEND_FACTOR_MAX19枚举大小哨兵—

其中BLEND_FACTOR_SRC1_*系列仅在使用双源混合(dual-source blending,如某些描边/轮廓着色技术)时相关;BLEND_FACTOR_CONSTANT_*系列与上文blend_constant、draw_list_set_blend_constants()配合使用。

BlendOperation(混合算子,6 个成员)

常量值方程
BLEND_OP_ADD0源 + 目标
BLEND_OP_SUBTRACT1源 - 目标
BLEND_OP_REVERSE_SUBTRACT2目标 - 源
BLEND_OP_MINIMUM3取两者中较低值
BLEND_OP_MAXIMUM4取两者中较高值
BLEND_OP_MAX5枚举大小哨兵

结合上文可知,Add/Subtract 等常见混合模式就是由"混合算子 + 四组混合因子"组合出来的:混合因子决定参与方程的颜色权重,混合算子决定权重加权后的运算形式。

实战:把颜色混合状态接入渲染管线

以下是完整的接入思路,将两个状态对象与RenderingDevice的管线创建流程串起来。完整的本地 RenderingDevice 使用流程可参考官方教程 compute_shaders.rst(含RenderingServer.create_local_rendering_device()、shader_create_from_spirv()等步骤),这里聚焦混合状态部分:

# 1. 创建混合附件(以 Mix 模式为例) var attachment = RDPipelineColorBlendStateAttachment.new() attachment.enable_blend = true attachment.color_blend_op = RenderingDevice.BLEND_OP_ADD attachment.src_color_blend_factor = RenderingDevice.BLEND_FACTOR_SRC_ALPHA attachment.dst_color_blend_factor = RenderingDevice.BLEND_FACTOR_ONE_MINUS_SRC_ALPHA attachment.alpha_blend_op = RenderingDevice.BLEND_OP_ADD attachment.src_alpha_blend_factor = RenderingDevice.BLEND_FACTOR_ONE attachment.dst_alpha_blend_factor = RenderingDevice.BLEND_FACTOR_ONE_MINUS_SRC_ALPHA # 2. 组装颜色混合状态(附件数组下标与帧缓冲颜色附件一一对应) var blend_state = RDPipelineColorBlendState.new() blend_state.attachments = [attachment] blend_state.blend_constant = Color(0, 0, 0, 1) # 使用 CONSTANT_* 因子时的取值来源 blend_state.enable_logic_op = false blend_state.logic_op = RenderingDevice.LOGIC_OP_COPY # 3. 创建图形管线(其余状态对象按需构造) var pipeline := rd.render_pipeline_create( shader, framebuffer_format, vertex_format, RenderingDevice.RENDER_PRIMITIVE_TRIANGLES, rasterization_state, multisample_state, depth_stencil_state, blend_state ) # 4. 如需动态修改混合常数,管线须以 DYNAMIC_STATE_BLEND_CONSTANTS 创建 var pipeline_dynamic := rd.render_pipeline_create( shader, framebuffer_format, vertex_format, RenderingDevice.RENDER_PRIMITIVE_TRIANGLES, rasterization_state, multisample_state, depth_stencil_state, blend_state, RenderingDevice.DYNAMIC_STATE_BLEND_CONSTANTS ) # 之后在每帧绘制前: # rd.draw_list_set_blend_constants(draw_list, Color(...))

需要注意的工程细节:

  • attachments数组中的顺序必须与帧缓冲格式中颜色附件的顺序一致,否则混合规则会错位;单附件场景只填一个元素即可。
  • 逻辑运算(enable_logic_op = true)与常规混合互斥:开启逻辑运算后混合因子与算子不再参与计算,且由于默认LOGIC_OP_CLEAR会让结果恒为0,务必显式选择所需运算。
  • 管线 RID 使用完毕后应调用free_rid()释放;它也会随shader释放而自动回收(依据 class_renderingdevice.rst)。

从源码看实现:文档来源与权威性说明

RDPipelineColorBlendState与RDPipelineColorBlendStateAttachment两个类文档均由 Godot 引擎源码自动生成:文件头部明确标注 "Generated automatically from Godot engine sources",生成器为make_rst.py,XML 源头分别是 Godot 仓库中RDPipelineColorBlendState.xml与RDPipelineColorBlendStateAttachment.xml。因此本文所引用的属性默认值、枚举取值与语义均直接对应引擎实现,而非手工整理的二手资料。

本仓库(godot-docs)是 Godot Engine 官方文档的 reStructuredText 源码仓库(见 README.md),使用 Sphinx 构建为 HTML 文档。与之配套可继续深入阅读的仓库文件包括:

  • class_rdpipelinecolorblendstate.rst:本文核心对象(4 属性)
  • class_rdpipelinecolorblendstateattachment.rst:逐渲染目标混合规则(11 属性 +set_as_mix())
  • class_renderingdevice.rst:render_pipeline_create()、draw_list_set_blend_constants()、三个混合相关枚举及PipelineDynamicStateFlags的权威定义
  • class_refcounted.rst:两个状态对象的基类(引用计数生命周期)
  • compute_shaders.rst:RenderingDevice 本地设备创建、SPIR-V 着色器加载与管线使用的完整实战流程

掌握RDPipelineColorBlendState的配置逻辑后,你便能在 Godot 4 的 RenderingDevice 渲染路径上自由组合混合因子与混合算子,复现 2D 渲染器中的 Mix / Add / Subtract / Multiply / 预乘 Alpha 等全部混合模式,并为自研着色器、自定义后处理与多目标渲染管线提供精确的颜色合成控制。

  • 文档
  • 教程
  • 游戏开发

【免费下载链接】godot-docs

Godot Engine official documentation

项目地址:https://gitcode.com/GitHub_Trending/go/godot-docs
点击查看免费下载

相关推荐

上一篇:免费开源AMD Ryzen调试工具SMUDebugTool:硬件级精准控制完全指南
下一篇:免费微信聊天记录导出终极指南:5步轻松备份珍贵对话

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进