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

151 lines
4.7 KiB
C#

using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
namespace Rokojori
{
public enum TextureCombinerBlendMode
{
Normal,
Add,
Multiply,
Screen,
Overlay,
HardLight,
SoftLight
}
public class TextureCombinerBlendModeAlgorithm
{
public static void Blend( TextureCombinerBlendMode blendMode, int x, int y, int w, int h, float topOpacity,
TextureCombinerBuffer bottom, TextureCombinerBuffer top, TextureCombinerBuffer output
)
{
if ( TextureCombinerBlendMode.Normal == blendMode )
{
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 );
}
}
}
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 )
{
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 );
var maskOpacity = mask.GetIndexed( index );
outputColor = bottomColor.Blend( outputColor.FadeAlpha( topOpacity * maskOpacity.R ) );
output.SetIndexed( index, outputColor );
}
}
}
}
}