81 lines
2.9 KiB
C#
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;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|