297 lines
7.8 KiB
C#
297 lines
7.8 KiB
C#
![]() |
using Godot;
|
||
|
using System.Reflection;
|
||
|
using System.Collections.Generic;
|
||
|
using Microsoft.VisualBasic;
|
||
|
using System.Linq;
|
||
|
|
||
|
namespace Rokojori
|
||
|
{
|
||
|
[Tool]
|
||
|
[GlobalClass]
|
||
|
public abstract partial class ShaderGenerationModule:Resource
|
||
|
{
|
||
|
public bool sortableCode = true;
|
||
|
|
||
|
public virtual bool CodeIsSortable( ShaderPhase phase )
|
||
|
{
|
||
|
return sortableCode;
|
||
|
}
|
||
|
|
||
|
public virtual List<string> GetVariantNames()
|
||
|
{
|
||
|
return new List<string>(){ "" };
|
||
|
}
|
||
|
|
||
|
public virtual List<ShaderVariant> GetVariants( ShaderGenerationContext context )
|
||
|
{
|
||
|
return new List<ShaderVariant>(){};
|
||
|
}
|
||
|
|
||
|
public static ShaderVariant ToVariant( params ShaderCode[] code )
|
||
|
{
|
||
|
var variant = new ShaderVariant();
|
||
|
variant.shaderCode = code.ToList();
|
||
|
|
||
|
return variant;
|
||
|
}
|
||
|
|
||
|
public static List<ShaderVariant> ToVariants( params ShaderCode[] code )
|
||
|
{
|
||
|
return [ ToVariant( code ) ];
|
||
|
}
|
||
|
|
||
|
public string GetShaderCacheData()
|
||
|
{
|
||
|
var shaderHash = "";
|
||
|
var name = "[ " + GetType().FullName + " ]";
|
||
|
var exportedTuples = ReflectionHelper.GetExportedMembersAsJSON( this );
|
||
|
exportedTuples.Sort();
|
||
|
|
||
|
shaderHash = name + " { " + ( exportedTuples.Map( t => $"\"{t.Item1}\":{t.Item2}" ).Join( ", " ) ) + " } ";
|
||
|
|
||
|
|
||
|
return shaderHash.Replace( "\n", "" );
|
||
|
}
|
||
|
|
||
|
public string GetShaderCacheHash()
|
||
|
{
|
||
|
var name = GetType().Name.Substring( 0, 3 ).ToLower();
|
||
|
var exportedTuples = ReflectionHelper.GetExportedMembersAsJSON( this );
|
||
|
exportedTuples.Sort();
|
||
|
|
||
|
var allAtts = " { " + ( exportedTuples.Map( t => $"\"{t.Item1}\":{t.Item2}" ).Join( ", " ) ) + " } ";
|
||
|
|
||
|
|
||
|
return name + "." + allAtts.Length;
|
||
|
}
|
||
|
|
||
|
|
||
|
public static List<ShaderCode> IncludeFromLibrary( string path )
|
||
|
{
|
||
|
return ToCode( "#include \"res://addons/rokojori_action_library/Runtime/Shading/Library/" + path + ".gdshaderinc\"\n" );
|
||
|
}
|
||
|
|
||
|
public static List<ShaderCode> IncludeTransformLibrary(){ return IncludeFromLibrary( "Transform" ); }
|
||
|
|
||
|
public static List<ShaderCode> IncludeDepthLibrary(){ return IncludeFromLibrary( "Depth" ); }
|
||
|
|
||
|
public static List<ShaderCode> IncludeCamerasLibrary(){ return IncludeFromLibrary( "Cameras" ); }
|
||
|
|
||
|
public static List<ShaderCode> IncludeNoiseLibrary(){ return IncludeFromLibrary( "Noise" ); }
|
||
|
|
||
|
public static List<ShaderCode> IncludeDitheringLibrary(){ return IncludeFromLibrary( "Dithering" ); }
|
||
|
|
||
|
public static List<ShaderCode> IncludeSDFLibrary(){ return IncludeFromLibrary( "SDF" ); }
|
||
|
|
||
|
public static List<ShaderCode> IncludeMathLibrary(){ return IncludeFromLibrary( "Math" ); }
|
||
|
|
||
|
public static List<ShaderCode> IncludeLightLibrary(){ return IncludeFromLibrary( "Light" ); }
|
||
|
|
||
|
public static ShaderVariant ToVariant( List<ShaderCode> code )
|
||
|
{
|
||
|
var variant = new ShaderVariant();
|
||
|
variant.shaderCode = code;
|
||
|
|
||
|
return variant;
|
||
|
}
|
||
|
|
||
|
public static List<ShaderVariant> ToVariants( List<ShaderCode> code )
|
||
|
{
|
||
|
return [ ToVariant( code ) ];
|
||
|
}
|
||
|
|
||
|
public static List<ShaderVariant> ToVariants( params string[] values )
|
||
|
{
|
||
|
return ToVariants( ToCode( values ) );
|
||
|
}
|
||
|
|
||
|
public static List<ShaderCode> ToCode( params string[] values )
|
||
|
{
|
||
|
return Lists.From( (ShaderCode)new StringShaderCode( Lists.From( values ).Join( "" ) ) );
|
||
|
}
|
||
|
|
||
|
public static List<ShaderCode> ToCode( string value )
|
||
|
{
|
||
|
return Lists.From( (ShaderCode)new StringShaderCode( value ) );
|
||
|
}
|
||
|
|
||
|
public List<ShaderCode> AsUniformGroup( string name, string value )
|
||
|
{
|
||
|
var wideName = RegexUtility.UpperCaseAndWide( name );
|
||
|
var blockCode = value.Indent( " ", false );
|
||
|
|
||
|
var code =
|
||
|
@$"
|
||
|
// [ {wideName} ]
|
||
|
group_uniforms {name};
|
||
|
|
||
|
{blockCode}
|
||
|
|
||
|
group_uniforms;
|
||
|
";
|
||
|
|
||
|
return ToCode( code.Indent( "" ) );
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
public List<ShaderCode> AsUniformGroup( string name, List<ShaderCode> code )
|
||
|
{
|
||
|
var wideName = RegexUtility.UpperCaseAndWide( name );
|
||
|
|
||
|
var codeBefore =
|
||
|
@$"
|
||
|
// [ {wideName} ]
|
||
|
group_uniforms {name};
|
||
|
|
||
|
";
|
||
|
|
||
|
var codeAfter =
|
||
|
@$"
|
||
|
|
||
|
|
||
|
group_uniforms;
|
||
|
";
|
||
|
|
||
|
return Lists.From( ToCode( codeBefore.Indent("") ), code, ToCode( codeAfter.Indent("") ) );
|
||
|
}
|
||
|
|
||
|
public List<ShaderCode> StartUniformGroup( string name )
|
||
|
{
|
||
|
var wideName = RegexUtility.UpperCaseAndWide( name );
|
||
|
|
||
|
var codeBefore =
|
||
|
@$"
|
||
|
// [ {wideName} ]
|
||
|
group_uniforms {name};
|
||
|
|
||
|
";
|
||
|
|
||
|
return ToCode( codeBefore.Indent("") );
|
||
|
}
|
||
|
|
||
|
public List<ShaderCode> EndUniformGroup()
|
||
|
{
|
||
|
var codeAfter =
|
||
|
@$"
|
||
|
group_uniforms;
|
||
|
";
|
||
|
|
||
|
return ToCode( codeAfter.Indent("") );
|
||
|
}
|
||
|
|
||
|
public static List<ShaderCode> ToInnerBlock( string name, string block )
|
||
|
{
|
||
|
var wideName = RegexUtility.UpperCaseAndWide( name );
|
||
|
var blockCode = block.Indent( " ", false );
|
||
|
|
||
|
var code =
|
||
|
|
||
|
@$"
|
||
|
|
||
|
// [ {wideName} ]
|
||
|
|
||
|
{blockCode}
|
||
|
|
||
|
";
|
||
|
|
||
|
return ToCode( code.Indent( " " ) );
|
||
|
}
|
||
|
|
||
|
public static List<ShaderCode> ToCode( List<string> values )
|
||
|
{
|
||
|
return Lists.From( (ShaderCode)new StringShaderCode( Lists.From( values ).Join( "" ) ) );
|
||
|
}
|
||
|
|
||
|
public static string Uniform( Vector2Property property )
|
||
|
{
|
||
|
var name = property.propertyName.propertyName;
|
||
|
var x = property.value.X._G();
|
||
|
var y = property.value.Y._G();
|
||
|
|
||
|
return @$"uniform vec2 {name} = vec2( {x}, {y});";
|
||
|
}
|
||
|
|
||
|
public static string Uniform( string name, float value )
|
||
|
{
|
||
|
return @$"uniform float {name} = {value._G()};";
|
||
|
}
|
||
|
|
||
|
public static string Uniform01( string name, float value )
|
||
|
{
|
||
|
return Uniform( name, value, 0, 1 );
|
||
|
}
|
||
|
|
||
|
public static string Uniform( string name, float value, float min, float max )
|
||
|
{
|
||
|
var mi = min._G();
|
||
|
var ma = max._G();
|
||
|
var v = value._G();
|
||
|
|
||
|
return @$"uniform float {name}:hint_range( {mi}, {ma}) = {v};";
|
||
|
}
|
||
|
|
||
|
public static string UniformSampler( string name, string hints )
|
||
|
{
|
||
|
return @$"uniform sampler2D {name}:{hints};";
|
||
|
}
|
||
|
|
||
|
public static string Uniform( string name, Color color )
|
||
|
{
|
||
|
var r = color.R._G();
|
||
|
var g = color.G._G();
|
||
|
var b = color.B._G();
|
||
|
var a = color.A._G();
|
||
|
|
||
|
return @$"uniform vec4 {name}:source_color = vec4( {r}, {g}, {b}, {a});";
|
||
|
|
||
|
}
|
||
|
|
||
|
public static string Uniform( string name, Vector3 vec )
|
||
|
{
|
||
|
var x = vec.X._G();
|
||
|
var y = vec.Y._G();
|
||
|
var z = vec.Z._G();
|
||
|
|
||
|
return @$"uniform vec3 {name} = vec3( {x}, {y}, {z});";
|
||
|
}
|
||
|
|
||
|
|
||
|
public static string Varying( string type, string name )
|
||
|
{
|
||
|
return @$"varying {type} {name};";
|
||
|
}
|
||
|
|
||
|
public static string VaryingFloat( string name ){ return Varying( "float", name ); }
|
||
|
public static string VaryingVec2( string name ){ return Varying( "vec2", name ); }
|
||
|
public static string VaryingVec3( string name ){ return Varying( "vec3", name ); }
|
||
|
public static string VaryingVec4( string name ){ return Varying( "vec4", name ); }
|
||
|
|
||
|
public static string Uniform( string name, Vector4 vec )
|
||
|
{
|
||
|
var x = vec.X._G();
|
||
|
var y = vec.Y._G();
|
||
|
var z = vec.Z._G();
|
||
|
var w = vec.W._G();
|
||
|
|
||
|
return @$"uniform vec4 {name} = vec4( {x}, {y}, {z}, {w});";
|
||
|
}
|
||
|
|
||
|
public static string DepthTextureUniform()
|
||
|
{
|
||
|
return UniformSampler( "depthTexture", "hint_depth_texture, repeat_disable, filter_nearest" );
|
||
|
}
|
||
|
|
||
|
public static string ScreenTextureUniform()
|
||
|
{
|
||
|
return UniformSampler( "screenTexture", "hint_screen_texture, repeat_disable, filter_linear" );
|
||
|
}
|
||
|
|
||
|
public static string NormalRoughnessTextureUniform()
|
||
|
{
|
||
|
return UniformSampler( "normalRoughness", "hint_normal_roughness_texture, repeat_disable, filter_linear" );
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|