338 lines
8.7 KiB
C#
338 lines
8.7 KiB
C#
using Godot;
|
|
using System.Reflection;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Rokojori
|
|
{
|
|
[Tool]
|
|
[GlobalClass]
|
|
public abstract partial class TextureModule:ShaderGenerationModule
|
|
{
|
|
public enum TextureChannelType
|
|
{
|
|
RGBA,
|
|
RGB,
|
|
ONE,
|
|
SCALAR
|
|
}
|
|
|
|
public enum TextureChannelSource
|
|
{
|
|
R,
|
|
G,
|
|
B,
|
|
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;
|
|
public string _domainIntensityName;
|
|
public string _target;
|
|
public string _scaleTarget;
|
|
|
|
public string _uvChannel;
|
|
|
|
public bool _srgb = false;
|
|
public bool _normal = false;
|
|
public bool _repeat = true;
|
|
|
|
public enum DomainMode
|
|
{
|
|
Value,
|
|
Texture,
|
|
Texture_Scale,
|
|
Texture_Scale_Offset,
|
|
Texture_Scale_Intensity
|
|
}
|
|
|
|
public DomainMode _domainMode = DomainMode.Texture_Scale_Offset;
|
|
public float domainOffsetDefault = 0;
|
|
public float domainOffsetMin = -1;
|
|
public float domainOffsetMax = 1;
|
|
|
|
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;
|
|
|
|
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()
|
|
{
|
|
|
|
}
|
|
|
|
public virtual string AddVariables()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
public string GetSampledName()
|
|
{
|
|
return "sampled".ExtendVariableName( _domainName );
|
|
|
|
}
|
|
|
|
public override List<ShaderVariant> GetVariants( ShaderGenerationContext context )
|
|
{
|
|
GrabValues();
|
|
|
|
if ( _clamp && ShaderPhase.Includes == context.phase )
|
|
{
|
|
return ToVariants( IncludeMathLibrary() );
|
|
}
|
|
|
|
if ( ShaderPhase.Variables == context.phase )
|
|
{
|
|
var textureName = _domainName;
|
|
|
|
var valuesDefinition = "";
|
|
var samplerDefinition = "";
|
|
|
|
|
|
if ( DomainMode.Value != _domainMode )
|
|
{
|
|
var hints = new List<string>();
|
|
|
|
if ( _srgb )
|
|
{
|
|
hints.Add( "source_color" );
|
|
}
|
|
|
|
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() );
|
|
|
|
if ( _domainMode != DomainMode.Texture )
|
|
{
|
|
if ( is1D )
|
|
{
|
|
valuesDefinition += Uniform( _domainScaleName, domainScaleDefault, domainScaleMin, domainScaleMax );
|
|
}
|
|
else
|
|
{
|
|
if ( TextureChannelType.SCALAR == scaleType )
|
|
{
|
|
valuesDefinition += Uniform( _domainScaleName, domainScaleDefault, domainScaleMin, domainScaleMax );
|
|
}
|
|
else
|
|
{
|
|
valuesDefinition += Uniform( _domainScaleName, scaleColor );
|
|
}
|
|
|
|
}
|
|
|
|
valuesDefinition +="\n";
|
|
}
|
|
}
|
|
|
|
if ( DomainMode.Value == _domainMode )
|
|
{
|
|
valuesDefinition += Uniform( _domainValueName, domainValueDefault, domainValueMin, domainValueMax );
|
|
}
|
|
else if ( DomainMode.Texture_Scale_Offset == _domainMode )
|
|
{
|
|
valuesDefinition += "\n";
|
|
valuesDefinition += Uniform( _domainOffsetName, domainOffsetDefault, domainOffsetMin, domainOffsetMax );
|
|
valuesDefinition += "\n";
|
|
}
|
|
else if ( DomainMode.Texture_Scale_Intensity == _domainMode )
|
|
{
|
|
valuesDefinition += "\n";
|
|
valuesDefinition += Uniform( _domainIntensityName, domainIntensityDefault, domainIntensityMin, domainIntensityMax );
|
|
valuesDefinition += "\n";
|
|
}
|
|
|
|
var code = valuesDefinition + samplerDefinition;
|
|
|
|
code += AddVariables();
|
|
|
|
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 );
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
} |