rj-action-library/Runtime/Procedural/Textures/TextureCombiner/TextureCombinerBlendMode.cs

151 lines
4.7 KiB
C#
Raw Normal View History

2025-02-14 07:44:20 +00:00
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
namespace Rokojori
{
public enum TextureCombinerBlendMode
{
Normal,
Add,
2025-02-19 12:12:12 +00:00
Multiply,
Screen,
Overlay,
HardLight,
SoftLight
2025-02-14 07:44:20 +00:00
}
public class TextureCombinerBlendModeAlgorithm
{
public static void Blend( TextureCombinerBlendMode blendMode, int x, int y, int w, int h, float topOpacity,
2025-02-19 12:12:12 +00:00
TextureCombinerBuffer bottom, TextureCombinerBuffer top, TextureCombinerBuffer output
2025-02-14 07:44:20 +00:00
)
{
if ( TextureCombinerBlendMode.Normal == blendMode )
{
2025-02-19 12:12:12 +00:00
BlendMode( ColorX.Blend, x, y, w, h, topOpacity, bottom, top, output );
}
else if ( TextureCombinerBlendMode.Add == blendMode )
{
BlendMode( ColorX.BlendAdd, x, y, w, h, topOpacity, bottom, top, output );
}
else if ( TextureCombinerBlendMode.Multiply == blendMode )
{
BlendMode( ColorX.BlendMultiply, x, y, w, h, topOpacity, bottom, top, output );
}
else if ( TextureCombinerBlendMode.Screen == blendMode )
{
BlendMode( ColorX.BlendScreen, x, y, w, h, topOpacity, bottom, top, output );
}
else if ( TextureCombinerBlendMode.Overlay == blendMode )
{
BlendMode( ColorX.BlendOverlay, x, y, w, h, topOpacity, bottom, top, output );
}
else if ( TextureCombinerBlendMode.HardLight == blendMode )
{
BlendMode( ColorX.BlendHardLight, x, y, w, h, topOpacity, bottom, top, output );
}
else if ( TextureCombinerBlendMode.SoftLight == blendMode )
{
BlendMode( ColorX.BlendSoftLight, x, y, w, h, topOpacity, bottom, top, output );
}
}
static void BlendMode( System.Func<Color,Color,Color> blender, int x, int y, int w, int h, float topOpacity,
TextureCombinerBuffer bottom, TextureCombinerBuffer top, TextureCombinerBuffer output )
{
for ( int i = 0; i < w; i++ )
{
var rx = x + i;
for ( int j = 0; j < h; j++ )
{
var ry = y + j;
var index = output.ComputeIndexFromPosition( rx, ry );
var topColor = top.GetIndexed( index );
var bottomColor = bottom.GetIndexed( index );
var outputColor = blender( bottomColor, topColor );
outputColor = bottomColor.Blend( outputColor.FadeAlpha( topOpacity ) );
output.SetIndexed( index, outputColor );
}
2025-02-14 07:44:20 +00:00
}
}
2025-02-19 12:12:12 +00:00
public static void BlendMasked( TextureCombinerBlendMode blendMode, int x, int y, int w, int h, float topOpacity,
TextureCombinerBuffer mask,
TextureCombinerBuffer bottom, TextureCombinerBuffer top, TextureCombinerBuffer output
)
{
if ( TextureCombinerBlendMode.Normal == blendMode )
{
BlendModeMasked( ColorX.Blend, x, y, w, h, topOpacity, mask, bottom, top, output );
}
else if ( TextureCombinerBlendMode.Add == blendMode )
{
BlendModeMasked( ColorX.BlendAdd, x, y, w, h, topOpacity, mask, bottom, top, output );
}
else if ( TextureCombinerBlendMode.Multiply == blendMode )
{
BlendModeMasked( ColorX.BlendMultiply, x, y, w, h, topOpacity, mask, bottom, top, output );
}
else if ( TextureCombinerBlendMode.Screen == blendMode )
{
BlendModeMasked( ColorX.BlendScreen, x, y, w, h, topOpacity, mask, bottom, top, output );
}
else if ( TextureCombinerBlendMode.Overlay == blendMode )
{
BlendModeMasked( ColorX.BlendOverlay, x, y, w, h, topOpacity, mask, bottom, top, output );
}
else if ( TextureCombinerBlendMode.HardLight == blendMode )
{
BlendModeMasked( ColorX.BlendHardLight, x, y, w, h, topOpacity, mask, bottom, top, output );
}
else if ( TextureCombinerBlendMode.SoftLight == blendMode )
{
BlendModeMasked( ColorX.BlendSoftLight, x, y, w, h, topOpacity, mask, bottom, top, output );
}
}
static void BlendModeMasked( System.Func<Color,Color,Color> blender, int x, int y, int w, int h, float topOpacity,
TextureCombinerBuffer mask,
TextureCombinerBuffer bottom, TextureCombinerBuffer top, TextureCombinerBuffer output )
2025-02-14 07:44:20 +00:00
{
for ( int i = 0; i < w; i++ )
{
var rx = x + i;
for ( int j = 0; j < h; j++ )
{
var ry = y + j;
2025-02-19 12:12:12 +00:00
var index = output.ComputeIndexFromPosition( rx, ry );
2025-02-14 07:44:20 +00:00
2025-02-19 12:12:12 +00:00
var topColor = top.GetIndexed( index );
2025-02-14 07:44:20 +00:00
var bottomColor = bottom.GetIndexed( index );
2025-02-19 12:12:12 +00:00
var outputColor = blender( bottomColor, topColor );
var maskOpacity = mask.GetIndexed( index );
outputColor = bottomColor.Blend( outputColor.FadeAlpha( topOpacity * maskOpacity.R ) );
2025-02-14 07:44:20 +00:00
output.SetIndexed( index, outputColor );
}
}
}
}
}