rokojori_action_library/Runtime/Procedural/Textures/TextureStack/TextureStackBlendMode.cs

81 lines
2.9 KiB
C#

using Godot;
using System;
using Rokojori.Extensions;
namespace Rokojori
{
/** Blend modes for a TextureStackLayer.
The first four are *native* modes: BlitMaterial carries them as a runtime
blend_mode, so they need no shader at all and no ping-pong buffer - the
hardware blends the layer straight onto the accumulation. The remaining
six have no hardware equivalent and are computed in
TextureStackComposite.gdshader, which needs the accumulation handed in as
a source texture (see TextureStackCompositor.NeedsCompositeShader).
The formulas mirror the CPU predecessor in
Procedural/Textures/TextureCombiner ( TextureCombinerBlendMode /
TextureCombinerBlendModeAlgorithm / ColorX.Blend* ). Two copies of the
same math exist on purpose - see the note in TextureStack.gdshaderinc -
so a fix to one belongs in the other as well.
Order matches the int values the composite shader switches on. Do not
renumber without updating TextureStack.gdshaderinc.
*/
public enum TextureStackBlendMode
{
// Native - BlitMaterial.BlendModeEnum, no shader needed.
Mix = 0,
Add = 1,
Sub = 2,
Multiply = 3,
// In-shader only, require the accumulation as a source.
Screen = 4,
Overlay = 5,
HardLight = 6,
SoftLight = 7,
Color = 8,
Hue = 9
}
public static class TextureStackBlendModeX
{
/** True for the four modes BlitMaterial can do in hardware.
Note this says nothing about whether the *layer* can take the native
path - a mask, clip-to-below or a non-trivial alpha requirement still
forces the composite shader. TextureStackCompositor decides that.
*/
public static bool IsNative( this TextureStackBlendMode mode )
{
return mode == TextureStackBlendMode.Mix
|| mode == TextureStackBlendMode.Add
|| mode == TextureStackBlendMode.Sub
|| mode == TextureStackBlendMode.Multiply;
}
/** Spike finding G5/constraint 2: the hardware blend applies to alpha too,
so Add and Sub drive the target's alpha somewhere unintended even with a
fully opaque source. Only safe where the target's alpha does not matter.
*/
public static bool NativePreservesAlpha( this TextureStackBlendMode mode )
{
return mode == TextureStackBlendMode.Mix;
}
public static BlitMaterial.BlendModeEnum ToBlitBlendMode( this TextureStackBlendMode mode )
{
switch ( mode )
{
case TextureStackBlendMode.Mix: return BlitMaterial.BlendModeEnum.Mix;
case TextureStackBlendMode.Add: return BlitMaterial.BlendModeEnum.Add;
case TextureStackBlendMode.Sub: return BlitMaterial.BlendModeEnum.Sub;
case TextureStackBlendMode.Multiply: return BlitMaterial.BlendModeEnum.Mul;
}
return BlitMaterial.BlendModeEnum.Mix;
}
}
}