157 lines
3.3 KiB
C#
157 lines
3.3 KiB
C#
using Godot;
|
|
using System.Reflection;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace Rokojori
|
|
{
|
|
[Tool]
|
|
[GlobalClass]
|
|
public abstract partial class SpatialOverlayLayer:ShaderGenerationModule
|
|
{
|
|
[Export]
|
|
public SpatialMask[] masks;
|
|
|
|
[Export]
|
|
public SpatialMaskFormulaType maskFormulaType = SpatialMaskFormulaType.Multiply;
|
|
|
|
[Export]
|
|
public string customMaskFormula;
|
|
|
|
public enum OverlayMode
|
|
{
|
|
Mix,
|
|
Blend_Alpha
|
|
}
|
|
|
|
[Export]
|
|
public OverlayMode overlayMode;
|
|
|
|
public enum ChannelType
|
|
{
|
|
RGBA,
|
|
RGB,
|
|
RG,
|
|
R,
|
|
G,
|
|
B,
|
|
A,
|
|
Float
|
|
}
|
|
|
|
public ChannelType channelType = ChannelType.RGB;
|
|
|
|
public string GetDataType()
|
|
{
|
|
if ( ChannelType.RGBA == channelType )
|
|
{
|
|
return "vec4";
|
|
}
|
|
|
|
if ( ChannelType.RGB == channelType )
|
|
{
|
|
return "vec3";
|
|
}
|
|
|
|
if ( ChannelType.RG == channelType )
|
|
{
|
|
return "vec2";
|
|
}
|
|
|
|
return "float";
|
|
}
|
|
|
|
|
|
public bool IsColorBlendMode()
|
|
{
|
|
List<OverlayMode> modes =
|
|
[
|
|
OverlayMode.Blend_Alpha
|
|
];
|
|
|
|
return modes.IndexOf( overlayMode ) != -1;
|
|
}
|
|
|
|
|
|
public List<ShaderCode> GetOverlayCode( ShaderGenerationContext context, string name, string oldValue, string targetValue )
|
|
{
|
|
var list = new List<ShaderCode>();
|
|
var currentValueName = $"{name}Value";
|
|
|
|
if ( context.isFragmentPhase )
|
|
{
|
|
var dataType = GetDataType();
|
|
var initData = $"{dataType} {currentValueName};\n";
|
|
list.Add( ToCode( initData.Indent( " " ) ) );
|
|
|
|
var valueCode = GetLayerCode( context, name, currentValueName );
|
|
list.Add( valueCode );
|
|
var maskName = $"{name}CombinedMask";
|
|
var maskCode = SpatialMaskFormulaTypeUtility.GetFragmentMaskCode(
|
|
context, maskFormulaType, customMaskFormula, masks, name, maskName );
|
|
list.Add( maskCode );
|
|
|
|
|
|
|
|
|
|
if ( OverlayMode.Mix == overlayMode )
|
|
{
|
|
var blendCode =
|
|
@$"
|
|
|
|
{targetValue} = mix( {oldValue}, {currentValueName}, {maskName} );
|
|
|
|
";
|
|
|
|
list.Add( ToCode( blendCode.Indent( " " ) ) );
|
|
}
|
|
else if ( IsColorBlendMode() )
|
|
{
|
|
var blendModeFunction = ( overlayMode + "" ).Replace( "Blend_", "" ).ToLower();
|
|
|
|
var blendCode =
|
|
@$"
|
|
|
|
{targetValue} = blend_{blendModeFunction}( {oldValue}, fade( {currentValueName} * {maskName} ) );
|
|
|
|
";
|
|
|
|
list.Add( ToCode( blendCode.Indent( " " ) ) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var maskIndex = 0;
|
|
|
|
masks.ForEach(
|
|
( m )=>
|
|
{
|
|
var maskName = $"{name}Mask{maskIndex}";
|
|
var maskCode = m.GetMaskCode( context, name, maskName );
|
|
|
|
if ( maskCode != null )
|
|
{
|
|
list.Add( maskCode );
|
|
}
|
|
|
|
maskIndex++;
|
|
}
|
|
);
|
|
|
|
var layerCode = GetLayerCode( context, name, currentValueName );
|
|
|
|
if ( layerCode != null )
|
|
{
|
|
list.Add( layerCode );
|
|
}
|
|
|
|
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
public abstract List<ShaderCode> GetLayerCode( ShaderGenerationContext context, string name, string currentValueName );
|
|
|
|
}
|
|
} |