rj-action-library/Runtime/Shading/Generators/Generic/ShaderGenerator.cs

147 lines
3.2 KiB
C#
Raw Normal View History

using Godot;
using System.Reflection;
using System.Collections.Generic;
using System.IO;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class ShaderGenerator:Node
{
[ExportToolButton( "Create" )]
public Callable CreateButton => Callable.From(
()=>
{
UpdateShader();
}
);
[Export]
public string path;
[Export]
public string shaderName;
[Export]
public Shader shader;
[Export]
public bool sendGodotUpdateMessage = false;
2025-09-17 08:25:03 +00:00
[Export]
public int numVariants = -1;
public virtual List<ShaderPhase> GetPhases()
{
return new List<ShaderPhase>();
}
public virtual List<ShaderGenerationModule> GetShaderGenerationModules( ShaderPhase phase )
{
return new List<ShaderGenerationModule>();
}
public virtual ShaderGenerationContext GenerateShaderVariants()
{
2025-09-17 08:25:03 +00:00
numVariants = 0;
var context = new ShaderGenerationContext();
var phases = GetPhases();
2025-09-17 08:25:03 +00:00
// this.LogInfo( context.variants );
phases.ForEach(
( phase )=>
{
context.phase = phase;
var modules = GetShaderGenerationModules( phase );
2025-09-17 08:25:03 +00:00
// this.LogInfo( "PHASE", phase, ">>", context.variants, "MODS:", modules == null ? "-" : ( modules.Map( m => m.GetType().Name ) ));
if ( modules == null )
{
return;
}
modules.ForEach(
( m )=>
{
2025-09-17 08:25:03 +00:00
var variants = m.GetVariants( context );
if ( variants == null )
{
return;
}
2025-09-17 08:25:03 +00:00
variants.ForEach(
c =>
{
c.shaderCode.ForEach(
cs =>
{
cs.phase = phase;
cs.sortableCode = m.CodeIsSortable( phase );
}
);
}
);
this.LogInfo( phase, m.GetType().Name, ">>", variants.Count );
context.AddVariants( variants );
}
);
}
);
return context;
}
public void UpdateShader()
{
2025-09-17 08:25:03 +00:00
numVariants = 0;
var context = GenerateShaderVariants();
2025-09-17 08:25:03 +00:00
numVariants = context.variants.Count;
// this.LogInfo( "Created variants:", context.variants );
var first = true;
foreach ( var variant in context.variants )
{
var shaderCode = variant.GetCode( context );
var absolutePath = path;
if ( absolutePath.StartsWith( "res://" ) || absolutePath.StartsWith( "user://" ) )
{
absolutePath = ProjectSettings.GlobalizePath( path );
}
2025-09-17 08:25:03 +00:00
// this.LogInfo( shaderCode );
var filePath = FilePath.Join( absolutePath, shaderName + variant.variantName + ".gdshader" );
FilesSync.SaveUTF8( filePath, shaderCode );
if ( sendGodotUpdateMessage )
{
GodotEditorHelper.UpdateFile( filePath );
}
if ( first )
{
shader = ResourceLoader.Load<Shader>( filePath );
}
first =false;
}
}
}
}