rj-action-library/Runtime/Shading/Generators/Spatial/TextureModule.cs

338 lines
8.7 KiB
C#
Raw Normal View History

using Godot;
using System.Reflection;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
2025-09-17 08:25:03 +00:00
public abstract partial class TextureModule:ShaderGenerationModule
{
public enum TextureChannelType
{
RGBA,
RGB,
2025-09-17 08:25:03 +00:00
ONE,
SCALAR
}
public enum TextureChannelSource
{
R,
G,
B,
2025-09-17 08:25:03 +00:00
A
}
public TextureChannelType _type;
public TextureChannelSource _channelSource;
public bool is1D => _type == TextureChannelType.ONE;
public string _domainName;
public string _domainValueName;
public string _domainScaleName;
public string _domainOffsetName;
2025-09-17 08:25:03 +00:00
public string _domainIntensityName;
public string _target;
public string _scaleTarget;
public string _uvChannel;
public bool _srgb = false;
2025-09-17 08:25:03 +00:00
public bool _normal = false;
public bool _repeat = true;
public enum DomainMode
{
Value,
Texture,
Texture_Scale,
2025-09-17 08:25:03 +00:00
Texture_Scale_Offset,
Texture_Scale_Intensity
}
2025-09-17 08:25:03 +00:00
public DomainMode _domainMode = DomainMode.Texture_Scale_Offset;
public float domainOffsetDefault = 0;
public float domainOffsetMin = -1;
public float domainOffsetMax = 1;
2025-09-17 08:25:03 +00:00
public float domainIntensityDefault = 1;
public float domainIntensityMin = 1;
public float domainIntensityMax = 20;
public float domainValueDefault = 0.5f;
public float domainValueMin = 0;
public float domainValueMax = 1;
2025-09-17 08:25:03 +00:00
public float domainScaleDefault = 1.0f;
public float domainScaleMin = 0;
public float domainScaleMax = 1;
public bool _clamp = false;
public enum AssignmentType
{
Set,
Add,
Subtract,
Multiply,
Divide
}
public AssignmentType _assignmentType = AssignmentType.Set;
public string assignmentOperator
{
get
{
if ( AssignmentType.Add == _assignmentType )
{
return " += ";
}
if ( AssignmentType.Subtract == _assignmentType )
{
return " -= ";
}
if ( AssignmentType.Multiply == _assignmentType )
{
return " *= ";
}
if ( AssignmentType.Divide == _assignmentType )
{
return " /= ";
}
return " = ";
}
}
public TextureChannelType scaleType = TextureChannelType.SCALAR;
public Color scaleColor = Colors.White;
public enum TextureDefault
{
White,
Black
}
public TextureDefault _textureDefault = TextureDefault.White;
public TextureFilter _textureFilter = TextureFilter.Linear_MipMap_Anisotropic;
public enum TextureFilter
{
Nearest,
Nearest_MipMap,
Nearest_MipMap_Anisotropic,
Linear,
Linear_MipMap,
Linear_MipMap_Anisotropic
}
public virtual void GrabValues()
{
}
2025-09-17 08:25:03 +00:00
public virtual string AddVariables()
{
return "";
}
public string GetSampledName()
{
return "sampled".ExtendVariableName( _domainName );
}
public override List<ShaderVariant> GetVariants( ShaderGenerationContext context )
{
GrabValues();
2025-09-17 08:25:03 +00:00
if ( _clamp && ShaderPhase.Includes == context.phase )
{
return ToVariants( IncludeMathLibrary() );
}
if ( ShaderPhase.Variables == context.phase )
{
var textureName = _domainName;
var valuesDefinition = "";
var samplerDefinition = "";
2025-09-17 08:25:03 +00:00
if ( DomainMode.Value != _domainMode )
{
var hints = new List<string>();
if ( _srgb )
{
hints.Add( "source_color" );
}
2025-09-17 08:25:03 +00:00
if ( _normal )
{
hints.Add( "hint_normal" );
}
else
{
hints.Add( TextureDefault.Black == _textureDefault ? "hint_default_black" : "hint_default_white" );
}
hints.Add( _repeat ? "repeat_enable" : "repeat_disable" );
hints.Add( "filter_" + ( _textureFilter + "" ).ToLower() );
var textureSamplerName = _domainName + "Texture";
samplerDefinition = UniformSampler( textureSamplerName, hints.Join() );
2025-09-17 08:25:03 +00:00
if ( _domainMode != DomainMode.Texture )
{
if ( is1D )
{
2025-09-17 08:25:03 +00:00
valuesDefinition += Uniform( _domainScaleName, domainScaleDefault, domainScaleMin, domainScaleMax );
}
else
{
2025-09-17 08:25:03 +00:00
if ( TextureChannelType.SCALAR == scaleType )
{
valuesDefinition += Uniform( _domainScaleName, domainScaleDefault, domainScaleMin, domainScaleMax );
}
else
{
valuesDefinition += Uniform( _domainScaleName, scaleColor );
}
}
valuesDefinition +="\n";
}
}
2025-09-17 08:25:03 +00:00
if ( DomainMode.Value == _domainMode )
{
valuesDefinition += Uniform( _domainValueName, domainValueDefault, domainValueMin, domainValueMax );
}
2025-09-17 08:25:03 +00:00
else if ( DomainMode.Texture_Scale_Offset == _domainMode )
{
valuesDefinition += "\n";
valuesDefinition += Uniform( _domainOffsetName, domainOffsetDefault, domainOffsetMin, domainOffsetMax );
valuesDefinition += "\n";
}
2025-09-17 08:25:03 +00:00
else if ( DomainMode.Texture_Scale_Intensity == _domainMode )
{
valuesDefinition += "\n";
valuesDefinition += Uniform( _domainIntensityName, domainIntensityDefault, domainIntensityMin, domainIntensityMax );
valuesDefinition += "\n";
}
2025-09-17 08:25:03 +00:00
var code = valuesDefinition + samplerDefinition;
2025-09-17 08:25:03 +00:00
code += AddVariables();
2025-09-17 08:25:03 +00:00
return ToVariants( AsUniformGroup( textureName, code ) );
}
if ( ShaderPhase.Fragment == context.phase )
{
if ( DomainMode.Texture == _domainMode ||
DomainMode.Texture_Scale == _domainMode ||
DomainMode.Texture_Scale_Offset == _domainMode ||
DomainMode.Texture_Scale_Intensity == _domainMode
)
{
var textureSamplerName = _domainName + "Texture";
var code = new List<string>();
var sampledName = GetSampledName();
var sampled = "vec4 " + sampledName + " = texture( " + textureSamplerName + ", " + _uvChannel + " );";
code.Add( sampled );
var member = "";
if ( TextureChannelType.RGB == _type )
{
member = ".rgb";
}
else if ( TextureChannelType.ONE== _type )
{
member = TextureChannelSource.R == _channelSource ? ".r" :
TextureChannelSource.G == _channelSource ? ".g" :
TextureChannelSource.B == _channelSource ? ".b" :
".a";
}
var scaleOffset = "";
var scaleMember = "";
if ( TextureChannelType.RGB == scaleType )
{
scaleMember = ".rgb";
}
else if ( TextureChannelType.ONE == scaleType )
{
scaleMember = TextureChannelSource.R == _channelSource ? ".r" :
TextureChannelSource.G == _channelSource ? ".g" :
TextureChannelSource.B == _channelSource ? ".b" :
".a";
}
// RJLog.Log( GetType().Name, "SCALE MEMBER", scaleMember, scaleType );
2025-09-17 08:25:03 +00:00
if ( DomainMode.Texture_Scale == _domainMode ||
DomainMode.Texture_Scale_Offset == _domainMode ||
DomainMode.Texture_Scale_Intensity == _domainMode
)
{
scaleOffset += " * " + _domainScaleName + scaleMember;
if ( DomainMode.Texture_Scale_Offset == _domainMode )
{
scaleOffset += " + " + _domainOffsetName + scaleMember;
}
else if ( DomainMode.Texture_Scale_Intensity == _domainMode )
{
scaleOffset += " * " + _domainIntensityName;
}
}
2025-09-17 08:25:03 +00:00
if ( DomainMode.Texture_Scale == _domainMode && _scaleTarget != "" && _scaleTarget != null )
{
code.Add( _target + assignmentOperator + sampledName + member + ";" );
code.Add( _scaleTarget + assignmentOperator + _domainScaleName + ";" );
}
else
{
code.Add( _target + assignmentOperator + sampledName + member + scaleOffset + ";" );
}
if ( _clamp )
{
code.Add( $"{_target} = clamp01( {_target} ); ");
}
return ToVariants( ToCode( code.Join( "\n" ).Indent( " " ).LineBreaks() ) );
}
else
{
}
}
return null;
}
}
}