using Godot; using System.Reflection; using System.Collections.Generic; namespace Rokojori { public enum ShaderTransformSpace { Local, World, View } public enum ShaderStage { Vertex, Fragment } public static class ShaderTransformSpaceUtility { public static string Convert( ShaderTransformSpace fromSpace, ShaderTransformSpace toSpace, bool isDirection, ShaderStage shaderStage, string varName ) { if ( ShaderTransformSpace.Local == fromSpace ) { return ConvertFromLocal( toSpace, isDirection, shaderStage, varName ); } if ( ShaderTransformSpace.World == fromSpace ) { return ConvertFromWorld( toSpace, isDirection, varName ); } if ( ShaderTransformSpace.View == fromSpace ) { return ConvertFromView( toSpace, isDirection, shaderStage, varName ); } return null; } public static string FromViewPoint( ShaderTransformSpace toSpace, string varName = "VERTEX" ) { return ConvertFromView( toSpace, false, ShaderStage.Fragment, varName ); } public static string FromPoint( ShaderTransformSpace fromSpace, ShaderTransformSpace toSpace, string varName = "VERTEX" ) { return Convert( fromSpace, toSpace, false, ShaderStage.Fragment, varName ); } public static string FromViewDirection( ShaderTransformSpace toSpace, string varName = "VERTEX" ) { return ConvertFromView( toSpace, false, ShaderStage.Fragment, varName ); } public static string ConvertFromLocal( ShaderTransformSpace toSpace, bool isDirection, ShaderStage shaderStage, string varName ) { if ( ShaderTransformSpace.Local == toSpace ) { return varName; } var target = ShaderTransformSpace.World == toSpace ? "World" : "View"; var matrix = ShaderTransformSpace.World == toSpace ? "MODEL_MATRIX" : "MODELVIEW_MATRIX"; if ( ShaderStage.Fragment == shaderStage ) { matrix = ShaderTransformSpace.World == toSpace ? "MODEL_MATRIX" : "VIEW_MATRIX * MODEL_MATRIX"; } var direction = isDirection ? "Direction" : ""; return $"localTo{target}{direction}( {varName}, {matrix} )"; } public static string ConvertFromWorld( ShaderTransformSpace toSpace, bool isDirection, string varName ) { if ( ShaderTransformSpace.World == toSpace ) { return varName; } var target = ShaderTransformSpace.Local == toSpace ? "Local" : "View"; var matrix = ShaderTransformSpace.Local == toSpace ? "MODEL_MATRIX" : "VIEW_MATRIX"; var direction = isDirection ? "Direction" : ""; return $"worldTo{target}{direction}( {varName}, {matrix} )"; } public static string ConvertFromView( ShaderTransformSpace toSpace, bool isDirection, ShaderStage shaderStage, string varName ) { if ( ShaderTransformSpace.View == toSpace ) { return varName; } var target = ShaderTransformSpace.Local == toSpace ? "Local" : "World"; var matrix = ShaderTransformSpace.Local == toSpace ? "MODELVIEW_MATRIX " : "INV_VIEW_MATRIX"; if ( ShaderStage.Fragment == shaderStage ) { matrix = ShaderTransformSpace.Local == toSpace ? "INV_VIEW_MATRIX, MODEL_MATRIX" : "INV_VIEW_MATRIX"; } var direction = isDirection ? "Direction" : ""; return $"viewTo{target}{direction}( {varName}, {matrix} )"; } } }