rj-action-library/Runtime/Shading/Generators/Spatial/Fading/Line/LineFading.cs

229 lines
7.2 KiB
C#

using Godot;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class LineFading:FadingModifier
{
public enum Mode
{
World,
WorldPoint_To_Camera,
Screen
}
[Export]
public Mode mode;
public override bool IsSameType( FadingModifier modifier )
{
if ( modifier is LineFading lf )
{
return lf.mode == mode;
}
return false;
}
public override List<ShaderCode> GetFadingCode( ShaderGenerationContext context, int offsetIndex, AlphaFadeMode parentFadeMode )
{
var alphaFadeMode = GetFadeMode( parentFadeMode );
var suffix = GetSuffix( offsetIndex );
if ( context.isIncludesPhase )
{
return IncludeTransformLibrary().Concat( IncludeFromLibrary( "Line3" ) ).Concat( IncludeSDFLibrary() );
}
if ( context.isVariablesPhase )
{
if ( Mode.Screen == mode )
{
List<string> variables =
[
Uniform( "screenLineDistanceFadeWorldPositionA" + suffix, Vector3.Zero ),
Uniform( "screenLineDistanceFadeWorldPositionB" + suffix, Vector3.One ),
VaryingVec3( "screenLineDistanceFadeScreenPositionA" + suffix ),
VaryingVec3( "screenLineDistanceFadeScreenPositionB" + suffix ),
Uniform( "screenLineDistanceFadeInnerRadius" + suffix, 0.1f ),
Uniform( "screenLineDistanceFadeOuterRadius" + suffix, 0.15f ),
VaryingVec2( "screenLineDistanceViewportRatio" + suffix )
];
variables = variables.Map( v => v.LineBreak() );
return ToCode( variables );
}
else if ( Mode.World == mode )
{
List<string> variables =
[
Uniform( "worldLineDistanceFadeWorldPositionA" + suffix, Vector3.Zero ),
Uniform( "worldLineDistanceFadeWorldPositionB" + suffix, Vector3.One ),
VaryingVec3( "worldLineDistanceFadeViewPositionA" + suffix ),
VaryingVec3( "worldLineDistanceFadeViewPositionB" + suffix ),
Uniform( "worldLineDistanceFadeInnerRadius" + suffix, 0.1f ),
Uniform( "worldLineDistanceFadeOuterRadius" + suffix, 0.15f )
];
variables = variables.Map( v => v.LineBreak() );
return ToCode( variables );
}
else if ( Mode.WorldPoint_To_Camera == mode )
{
List<string> variables =
[
Uniform( "worldCameraLineDistanceFadeWorldPosition" + suffix, Vector3.Zero ),
VaryingVec3( "worldCameraLineDistanceFadeViewPosition" + suffix ),
Uniform( "worldCameraLineDistanceFadeInnerRadius" + suffix, 0.1f ),
Uniform( "worldCameraLineDistanceFadeOuterRadius" + suffix, 0.15f )
];
variables = variables.Map( v => v.LineBreak() );
return ToCode( variables );
}
}
if ( context.isVertexPhase )
{
if ( Mode.Screen == mode )
{
var code =
$@"
screenLineDistanceFadeScreenPositionA{suffix} = vec3( worldToScreen( screenLineDistanceFadeWorldPositionA{suffix}, VIEW_MATRIX, PROJECTION_MATRIX ), 0.0 );
screenLineDistanceFadeScreenPositionB{suffix} = vec3( worldToScreen( screenLineDistanceFadeWorldPositionB{suffix}, VIEW_MATRIX, PROJECTION_MATRIX ), 0.0 );
";
return ToCode( code.Indent( " ") );
}
else if ( Mode.World == mode )
{
var code =
$@"
worldLineDistanceFadeViewPositionA{suffix} = worldToView( worldLineDistanceFadeWorldPositionA{suffix}, VIEW_MATRIX );
worldLineDistanceFadeViewPositionB{suffix} = worldToView( worldLineDistanceFadeWorldPositionB{suffix}, VIEW_MATRIX );
";
return ToCode( code.Indent( " ") );
}
else if ( Mode.WorldPoint_To_Camera == mode )
{
var code =
$@"
worldCameraLineDistanceFadeViewPosition{suffix} = worldToView( worldCameraLineDistanceFadeWorldPosition{suffix}, VIEW_MATRIX );
";
return ToCode( code.Indent( " ") );
}
}
if ( context.isFragmentPhase )
{
if ( Mode.Screen == mode )
{
var fadeVariable = "screenLineDistanceFadeAmount" + suffix;
var fade = AlphaFade.Fragment( fadeVariable, alphaFadeMode );
var code =
$@"
{{
vec2 screenRatioMultiply = VIEWPORT_SIZE;
if ( screenRatioMultiply.x > screenRatioMultiply.y )
{{
screenRatioMultiply /= VIEWPORT_SIZE.x;
}}
else
{{
screenRatioMultiply /= VIEWPORT_SIZE.y;
}}
vec2 screenVertex = viewToScreen( VERTEX, PROJECTION_MATRIX ) * screenRatioMultiply;
Line3 screenLineDistanceFadeLine3;
screenLineDistanceFadeLine3.start = screenLineDistanceFadeScreenPositionA{suffix} * vec3( screenRatioMultiply, 1.0 );
screenLineDistanceFadeLine3.end = screenLineDistanceFadeScreenPositionB{suffix} * vec3( screenRatioMultiply, 1.0 );
float screenLineDistanceFadeDistance = Line3_getDistance( screenLineDistanceFadeLine3, vec3( screenVertex, 0.0 ) );
float {fadeVariable} = clamp( smoothstep( screenLineDistanceFadeInnerRadius{suffix}, screenLineDistanceFadeOuterRadius{suffix}, screenLineDistanceFadeDistance ), 0.0, 1.0 );
{fade}
}}
";
return ToCode( code.Indent( " ") );
}
else if ( Mode.World == mode )
{
var fadeVariable = "worldLineDistanceFadeAmount" + suffix;
var fade = AlphaFade.Fragment( fadeVariable, alphaFadeMode );
var code =
$@"
{{
Line3 worldLineDistanceFadeLine3;
worldLineDistanceFadeLine3.start = worldLineDistanceFadeViewPositionA{suffix};
worldLineDistanceFadeLine3.end = worldLineDistanceFadeViewPositionB{suffix};
float worldLineDistanceFadeDistance = Line3_getDistance( worldLineDistanceFadeLine3, VERTEX );
float {fadeVariable} = clamp( smoothstep( worldLineDistanceFadeInnerRadius{suffix}, worldLineDistanceFadeOuterRadius{suffix}, worldLineDistanceFadeDistance ), 0.0, 1.0 );
{fade}
}}
";
return ToCode( code.Indent( " ") );
}
else if ( Mode.WorldPoint_To_Camera == mode )
{
var fadeVariable = "worldLineDistanceFadeAmount" + suffix;
var fade = AlphaFade.Fragment( fadeVariable, alphaFadeMode );
var code =
$@"
{{
float worldLineDistanceFadeDistance = sdRoundCone( VERTEX, vec3( 0.0, 0.0, 0.0), worldCameraLineDistanceFadeViewPosition{suffix}, 0, worldCameraLineDistanceFadeInnerRadius );
float {fadeVariable} = clamp( smoothstep( 0, ( worldCameraLineDistanceFadeOuterRadius{suffix} - worldCameraLineDistanceFadeInnerRadius{suffix} ), worldLineDistanceFadeDistance ), 0.0, 1.0 );
{fade}
}}
";
return ToCode( code.Indent( " ") );
}
}
return [];
}
}
}