From 2c64caf28478d164aaeb99beabfbbf4dbe94af12 Mon Sep 17 00:00:00 2001 From: Josef Date: Sun, 14 Dec 2025 13:18:57 +0100 Subject: [PATCH] Render Updates --- .../Actions/Node3D/CopyYawFromDirection.cs | 34 +++++ .../Node3D/CopyYawFromDirection.cs.uid | 1 + Runtime/Actions/Visual/TweenColor.cs | 133 ++++++++++++++++++ Runtime/Actions/Visual/TweenColor.cs.uid | 1 + .../Animation/Highlight/HighlightEffect.cs | 5 + .../CameraTypes/LookAtCamera/LookAtCamera.cs | 14 ++ Runtime/Cameras/VirtualCamera.cs | 13 ++ .../Procedural/Parametric/Spline/Spline.cs | 5 + .../Parametric/Spline/SplineMesh.cs | 8 ++ .../CompositorEffects/Rim/RimShader.glsl | 1 + .../Vignette/VignetteEffect.cs | 53 +++++-- .../Vignette/VignetteShader.glsl | 132 ++++++++++++++--- Runtime/Rendering/Objects/RDPushConstants.cs | 76 +++------- Runtime/Rendering/RenderingManager.cs | 37 +++++ Runtime/Shading/Library/Math.gdshaderinc | 4 +- Runtime/Shading/Library/SDF.gdshaderinc | 6 + 16 files changed, 435 insertions(+), 88 deletions(-) create mode 100644 Runtime/Actions/Node3D/CopyYawFromDirection.cs create mode 100644 Runtime/Actions/Node3D/CopyYawFromDirection.cs.uid create mode 100644 Runtime/Actions/Visual/TweenColor.cs create mode 100644 Runtime/Actions/Visual/TweenColor.cs.uid diff --git a/Runtime/Actions/Node3D/CopyYawFromDirection.cs b/Runtime/Actions/Node3D/CopyYawFromDirection.cs new file mode 100644 index 0000000..fe0ee91 --- /dev/null +++ b/Runtime/Actions/Node3D/CopyYawFromDirection.cs @@ -0,0 +1,34 @@ + +using Godot; + + +namespace Rokojori +{ + [Tool][GlobalClass ] + public partial class CopyYawFromDirection : Action + { + [Export] + public Node3D sourceA; + + [Export] + public Node3D sourceB; + + [Export] + public Node3D target; + + protected override void _OnTrigger() + { + if ( sourceA == null || sourceB == null || target == null ) + { + return; + } + + var direction = sourceB.GlobalPosition - sourceA.GlobalPosition; + var yaw = Math3D.GlobalYaw( direction ); + target.SetGlobalYaw( yaw ); + + } + + + } +} \ No newline at end of file diff --git a/Runtime/Actions/Node3D/CopyYawFromDirection.cs.uid b/Runtime/Actions/Node3D/CopyYawFromDirection.cs.uid new file mode 100644 index 0000000..ce14470 --- /dev/null +++ b/Runtime/Actions/Node3D/CopyYawFromDirection.cs.uid @@ -0,0 +1 @@ +uid://barfbywochbs3 diff --git a/Runtime/Actions/Visual/TweenColor.cs b/Runtime/Actions/Visual/TweenColor.cs new file mode 100644 index 0000000..de69bb3 --- /dev/null +++ b/Runtime/Actions/Visual/TweenColor.cs @@ -0,0 +1,133 @@ + +using System; +using Godot; + + +namespace Rokojori +{ + [Tool] + [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Tween.svg")] + public partial class TweenColor:SequenceAction, Animator + { + [Export] + public GodotObject target; + + [Export] + public string targetMemberPath; + + [Export] + public Color endValue; + + [Export] + public Duration duration; + + [Export] + public Curve curve; + + public void OnAnimatorStart(){} + public void OnAnimatorEnd(){} + public void OnAnimatorCancel(){} + + int _actionID = -1; + int _timeID = -1; + + + + public Color GetTargetValue( GodotObject go, string targetMember, Color alternative ) + { + var path = targetMember.Split( "/" ); + var prop = path[ path.Length - 1 ]; + + var target = ReflectionHelper.GetMemberByPath( go, path, false ); + + return target == null ? alternative : ReflectionHelper.GetValue( target, prop ); + + } + + public void SetTargetValue( GodotObject go, string targetMember, Color value ) + { + var path = targetMember.Split( "/" ); + var prop = path[ path.Length - 1 ]; + + var target = ReflectionHelper.GetMemberByPath( go, path, false ); + + if ( target == null ) + { + return; + } + + ReflectionHelper.SetValue( target, prop, value ); + } + + protected override void _OnTrigger() + { + this.LogInfo( "Started Float Tween" ); + + + // if ( Engine.IsEditorHint() ) + // { + // return; + // } + + if ( _actionID != -1 ) + { + CancelAction( _actionID ); + } + + _actionID = DispatchStart(); + + // var startValue = ReflectionHelper.GetValue( target, targetMember ); + var startValue = GetTargetValue( target, targetMemberPath, Colors.White ); + + AnimationManager.StartAnimation( this, target, targetMemberPath ); + + this.LogInfo( "Start Value Float Tween", HierarchyName.OfAny( target ), target.GetType().Name, targetMemberPath, ">>", startValue ); + + _timeID = TimeLineManager.ScheduleSpanWith( duration, + ( span, type )=> + { + + // this.LogInfo( "Update Float Tween", startValue ); + if ( span.id != _timeID ) + { + return; + } + + if ( ! AnimationManager.IsAnimating( this, target, targetMemberPath ) ) + { + return; + } + + var phase = span.phase; + + if ( curve != null ) + { + phase = curve.Sample( phase ); + } + + var value = ColorX.Lerp( startValue, endValue, phase ); + + // this.LogInfo( "Updating Float Tween", "phase:", phase, "value:", value, target ); + + // ReflectionHelper.SetValue( target, targetMember, value ); + // target._Set( targetMember, value ); + SetTargetValue( target, targetMemberPath, value ); + + if ( type == TimeLineSpanUpdateType.End ) + { + // this.LogInfo( "End Float Tween", endValue ); + + SetTargetValue( target, targetMemberPath, value ); + AnimationManager.EndAnimation( this, target, targetMemberPath ); + DispatchEnd( _actionID ); + _actionID = -1; + _timeID = -1; + } + }, + + this + ).id; + } + + } +} \ No newline at end of file diff --git a/Runtime/Actions/Visual/TweenColor.cs.uid b/Runtime/Actions/Visual/TweenColor.cs.uid new file mode 100644 index 0000000..ad4b58a --- /dev/null +++ b/Runtime/Actions/Visual/TweenColor.cs.uid @@ -0,0 +1 @@ +uid://c5x4cvwov6iog diff --git a/Runtime/Animation/Highlight/HighlightEffect.cs b/Runtime/Animation/Highlight/HighlightEffect.cs index beee383..d26a4e6 100644 --- a/Runtime/Animation/Highlight/HighlightEffect.cs +++ b/Runtime/Animation/Highlight/HighlightEffect.cs @@ -194,6 +194,11 @@ namespace Rokojori targets.ForEach( ( t )=> { + if ( t == null ) + { + return; + } + highlighted[ t ] = this; } ); diff --git a/Runtime/Cameras/CameraTypes/LookAtCamera/LookAtCamera.cs b/Runtime/Cameras/CameraTypes/LookAtCamera/LookAtCamera.cs index ff6bc9e..9ffda99 100644 --- a/Runtime/Cameras/CameraTypes/LookAtCamera/LookAtCamera.cs +++ b/Runtime/Cameras/CameraTypes/LookAtCamera/LookAtCamera.cs @@ -21,6 +21,20 @@ namespace Rokojori [Export] public TimeLine timeLine; + [ExportToolButton( "Copy Camera Pose With Target")] + public Callable copyCameraPoseWithTargetButton => Callable.From( + ()=> + { + #if TOOLS + + var camera = EditorInterface.Singleton.GetEditorViewport3D().GetCamera3D(); + target.GlobalPosition = camera.GlobalPosition + camera.GlobalForward() * 25; + Pose.CopyTo( camera, this ); + + #endif + } + ); + public override void _Process( double delta ) { if ( Engine.IsEditorHint() ) diff --git a/Runtime/Cameras/VirtualCamera.cs b/Runtime/Cameras/VirtualCamera.cs index 4798050..f9daf57 100644 --- a/Runtime/Cameras/VirtualCamera.cs +++ b/Runtime/Cameras/VirtualCamera.cs @@ -18,6 +18,19 @@ namespace Rokojori [Export] public bool inputEnabled = true; + [ExportToolButton( "Copy Camera Pose")] + public Callable copyCameraPoseButton => Callable.From( + ()=> + { + #if TOOLS + + var camera = EditorInterface.Singleton.GetEditorViewport3D().GetCamera3D(); + Pose.CopyTo( camera, this ); + + #endif + } + ); + public Vector3 GetCameraPosition() { return GlobalPosition; diff --git a/Runtime/Procedural/Parametric/Spline/Spline.cs b/Runtime/Procedural/Parametric/Spline/Spline.cs index f60def0..c028520 100644 --- a/Runtime/Procedural/Parametric/Spline/Spline.cs +++ b/Runtime/Procedural/Parametric/Spline/Spline.cs @@ -112,6 +112,11 @@ namespace Rokojori return splinePoints; } + public void ResetCurve() + { + splineCurve = null; + } + public SplineCurve GetCurve() { if ( splineCurve == null ) diff --git a/Runtime/Procedural/Parametric/Spline/SplineMesh.cs b/Runtime/Procedural/Parametric/Spline/SplineMesh.cs index 245ae8e..6b30291 100644 --- a/Runtime/Procedural/Parametric/Spline/SplineMesh.cs +++ b/Runtime/Procedural/Parametric/Spline/SplineMesh.cs @@ -34,6 +34,9 @@ namespace Rokojori [Export] public bool undistortSplineSegments = false; + [Export] + public bool updateSpline = false; + protected override void _OnTrigger() { CreateMesh(); @@ -41,6 +44,11 @@ namespace Rokojori public void CreateMesh() { + if ( updateSpline ) + { + spline.ResetCurve(); + } + var curve = spline.GetCurve(); var length = curve.ComputeLength( 100 ); diff --git a/Runtime/Rendering/Compositor/CompositorEffects/Rim/RimShader.glsl b/Runtime/Rendering/Compositor/CompositorEffects/Rim/RimShader.glsl index 870968c..a4c04a9 100644 --- a/Runtime/Rendering/Compositor/CompositorEffects/Rim/RimShader.glsl +++ b/Runtime/Rendering/Compositor/CompositorEffects/Rim/RimShader.glsl @@ -1,6 +1,7 @@ #[compute] #version 450 + layout( local_size_x = 8, local_size_y = 8, local_size_z = 1 ) in; layout( rgba16f, set = 0, binding = 0 ) diff --git a/Runtime/Rendering/Compositor/CompositorEffects/Vignette/VignetteEffect.cs b/Runtime/Rendering/Compositor/CompositorEffects/Vignette/VignetteEffect.cs index 91f1c1e..03f6079 100644 --- a/Runtime/Rendering/Compositor/CompositorEffects/Vignette/VignetteEffect.cs +++ b/Runtime/Rendering/Compositor/CompositorEffects/Vignette/VignetteEffect.cs @@ -11,23 +11,47 @@ namespace Rokojori { public static readonly string shaderPath = Path( "Vignette/VignetteShader.glsl" ); + [ExportGroup("Vignette")] [Export( PropertyHint.Range, "0,1")] public float amount = 1.0f; - [Export( PropertyHint.Range, "0.01,10")] - public float radius = 0.5f; + [Export( PropertyHint.Range, "-1,1")] + public float fadePosition; + + [Export( PropertyHint.Range, "-2,2")] + public float fadeInOffset = -0.1f; + + [Export( PropertyHint.Range, "-2,2")] + public float fadeOutOffset= 0.1f; + + [Export( PropertyHint.Range, "-10,10")] + public float fadePower= 1f; + + [Export( PropertyHint.Range, "0,1")] + public float ellipseToCircle= 0.5f; + + [ExportGroup("Colors")] [Export] - public float power = 1.0f; + public Color colorTop = Colors.Black; [Export] - public float offset = 1.0f; - + public Color colorBottom = Colors.Black; + + + [ExportGroup("Blend Mode")] [Export] - public Color colorTop; + public float replace = 1.0f; [Export] - public Color colorBottom; + public float add = 0.0f; + + [Export] + public float multiply = 0.0f; + + [Export] + public float colorize = 0.0f; + [Export] public string info = ""; @@ -42,11 +66,18 @@ namespace Rokojori protected override void SetConstants() { constants.Set( + colorTop.SrgbToLinear(), + colorBottom.SrgbToLinear(), + (Vector2) context.internalSize, amount, - radius, - power, - offset, - (Vector2) context.internalSize + fadePosition + fadeInOffset, + fadePosition + fadeOutOffset, + ellipseToCircle, + Mathf.Pow( 10f, fadePower / 10f ), + replace, + add, + multiply, + colorize ); info = "constants: " + constants.info; diff --git a/Runtime/Rendering/Compositor/CompositorEffects/Vignette/VignetteShader.glsl b/Runtime/Rendering/Compositor/CompositorEffects/Vignette/VignetteShader.glsl index 94ed5b0..36cfb59 100644 --- a/Runtime/Rendering/Compositor/CompositorEffects/Vignette/VignetteShader.glsl +++ b/Runtime/Rendering/Compositor/CompositorEffects/Vignette/VignetteShader.glsl @@ -1,41 +1,135 @@ #[compute] #version 450 +float clamp01( float value ) +{ + return clamp( value, 0.0, 1.0 ); +} + +vec4 clamp01_v4( vec4 value ) +{ + value.r = clamp01( value.r ); + value.g = clamp01( value.g ); + value.b = clamp01( value.b ); + value.a = clamp01( value.a ); + + return value; +} + +vec2 clamp01( vec2 value ) +{ + return clamp( value, 0.0, 1.0 ); +} + +vec3 clamp01( vec3 value ) +{ + return clamp( value, 0.0, 1.0 ); +} + +vec4 clamp01( vec4 value ) +{ + return clamp( value, 0.0, 1.0 ); +} + +float normalizeToRange( float value, float min, float max ) +{ + return ( value - min ) / ( max - min ); +} + +float normalizeToRange01( float value, float min, float max ) +{ + return clamp01( normalizeToRange( value, min, max ) ); +} + +float map( float value, float inMin, float inMax, float outMin, float outMax ) +{ + return mix( outMin, outMax, normalizeToRange( value, inMin, inMax ) ); +} + +vec2 map_v2( vec2 value, vec2 inMin, vec2 inMax, vec2 outMin, vec2 outMax ) +{ + float x = map( value.x, inMin.x, inMax.x, outMin.x, outMax.x ); + float y = map( value.y, inMin.y, inMax.y, outMin.y, outMax.y ); + + return vec2( x, y ); +} + +float mapClamped( float value, float inMin, float inMax, float outMin, float outMax ) +{ + return mix( outMin, outMax, normalizeToRange01( value, inMin, inMax ) ); +} + +vec3 colorize( vec3 original, vec3 color ) +{ + float grey = ( original.r + original.g + original.b ) / 3.0; + + return grey < 0.5 ? mix( vec3( 0.0 ), color, grey * 2.0 ) : + mix( color, vec3( 1.0 ), ( grey - 0.5 ) * 2.0 ); +} + layout( local_size_x = 16, local_size_y = 16, local_size_z = 1 ) in; layout( rgba16f, set = 0, binding = 0) -uniform image2D color_image; +uniform image2D screenImage; -layout(push_constant, std430) -uniform Params -{ - float amount; - float radius; - float power; - float offset; - vec2 raster_size; +layout( push_constant, std430 ) +uniform Parameters +{ + vec4 topColor; // 4 + vec4 bottomColor; // 8 + vec2 rasterSize; // 6 + float amount; // 7 + float fadeIn; // 8 + float fadeOut; // 9 -} params; + float circelize; // 10 + float power; // 12 + + float replace; // 13 + float add; // 14 + float multiply; // 15 + float colorize; // 16 + + +} parameters; void main() { - ivec2 uv = ivec2( gl_GlobalInvocationID.xy ); - ivec2 size = ivec2( params.raster_size ); + ivec2 coordinate = ivec2( gl_GlobalInvocationID.xy ); + ivec2 size = ivec2( parameters.rasterSize ); - if ( uv.x >= size.x || uv.y >= size.y ) + if ( coordinate.x >= size.x || coordinate.y >= size.y ) { return; } - vec4 color = imageLoad( color_image, uv ); + vec4 color = imageLoad( screenImage, coordinate ); + // color = vec4( 0.0, 0.0, 0.0, 1.0 ); + vec2 uv = ( vec2( coordinate ) + vec2( 0.5 ) ) / vec2( parameters.rasterSize ) ; - float d = length( uv - size/2 ) / length( size/2 * params.radius ); - d = pow( d, params.power ); - float amount = clamp( 1.0 - d + params.offset, 0.0, 1.0 ); + float ratio = parameters.rasterSize.y / parameters.rasterSize.x; + + uv.y = mix( uv.y, ( uv.y - 0.5 ) * ratio + 0.5, parameters.circelize ); + + float centerDistance = length( uv - vec2( 0.5 ) ); + float distanceAmount = mapClamped( centerDistance, parameters.fadeIn, parameters.fadeOut, 0.0, 1.0 ); + distanceAmount = pow( distanceAmount, parameters.power ); + + vec4 vignetteColor = mix( parameters.topColor, parameters.bottomColor, uv.y ); + + vec4 multiplied = vignetteColor * color; + vec4 added = vignetteColor + color; + vec4 colorized = vec4( colorize( color.rgb, vignetteColor.rgb ), 1.0 ); - color.rgb = mix( color.rgb, vec3( 0.01, 0.01, 0.02 ), ( 1.0 - amount ) * params.amount ); + vec4 mixed = vignetteColor * parameters.replace + + added * parameters.add + + multiplied * parameters.multiply + + colorized * parameters.colorize; - imageStore( color_image, uv, color ); + color.rgb = mix( color.rgb, mixed.rgb, vignetteColor.a * distanceAmount * parameters.amount ); + // color.rgb = vignetteColor.rgb; + + imageStore( screenImage, coordinate, color ); } \ No newline at end of file diff --git a/Runtime/Rendering/Objects/RDPushConstants.cs b/Runtime/Rendering/Objects/RDPushConstants.cs index 44dd497..62c653c 100644 --- a/Runtime/Rendering/Objects/RDPushConstants.cs +++ b/Runtime/Rendering/Objects/RDPushConstants.cs @@ -50,88 +50,52 @@ namespace Rokojori for ( int i = 0; i < objects.Length; i++ ) { - if ( objects[ i ] is int ) + if ( objects[ i ] is int intValue) { - _AddInt( (int) objects[ i ] ); + _AddInt( intValue ); } - else if ( objects[ i ] is float ) + else if ( objects[ i ] is float floatValue ) { - _AddFloat( (float) objects[ i ] ); + _AddFloat( floatValue ); } - else if ( objects[ i ] is Vector2 ) + else if ( objects[ i ] is Vector2 vec2 ) { - _AddVector2( (Vector2) objects[ i ] ); + _AddVector2( vec2 ); } - else if ( objects[ i ] is Vector2I ) + else if ( objects[ i ] is Vector2I vec2I ) { - _AddVector2( (Vector2I) objects[ i ] ); + _AddVector2( vec2I ); } - else if ( objects[ i ] is Vector3 ) + else if ( objects[ i ] is Vector3 vec3 ) { - _AddVector3( (Vector3) objects[ i ] ); + _AddVector3( vec3 ); } - else if ( objects[ i ] is Vector3I ) + else if ( objects[ i ] is Vector3I vec3I ) { - _AddVector3( (Vector3I) objects[ i ] ); + _AddVector3( vec3I ); } - else if ( objects[ i ] is Vector4 ) + else if ( objects[ i ] is Vector4 vec4 ) { - _AddVector4( (Vector4) objects[ i ] ); + _AddVector4( vec4 ); + } + + else if ( objects[ i ] is Color color ) + { + _AddVector4( color.ToVector4() ); } } - } public void Set( params object[] objects ) { - Reset(); - - for ( int i = 0; i < objects.Length; i++ ) - { - if ( objects[ i ] is int ) - { - _AddInt( (int) objects[ i ] ); - } - - else if ( objects[ i ] is float ) - { - _AddFloat( (float) objects[ i ] ); - } - - else if ( objects[ i ] is Vector2 ) - { - _AddVector2( (Vector2) objects[ i ] ); - } - - else if ( objects[ i ] is Vector2I ) - { - _AddVector2( (Vector2I) objects[ i ] ); - } - - else if ( objects[ i ] is Vector3 ) - { - _AddVector3( (Vector3) objects[ i ] ); - } - - else if ( objects[ i ] is Vector3I ) - { - _AddVector3( (Vector3I) objects[ i ] ); - } - - else if ( objects[ i ] is Vector4 ) - { - _AddVector4( (Vector4) objects[ i ] ); - } - } - - + SetOrAdd( true, objects ); } protected void _AddFloat( float value ) diff --git a/Runtime/Rendering/RenderingManager.cs b/Runtime/Rendering/RenderingManager.cs index 18ff1e9..46672fc 100644 --- a/Runtime/Rendering/RenderingManager.cs +++ b/Runtime/Rendering/RenderingManager.cs @@ -22,6 +22,43 @@ namespace Rokojori } ); + + [ExportToolButton( "Update Shaders")] + public Callable updateShadersButton => Callable.From( + ()=> + { + shaders.ForEach( + ( s )=> + { + var code = RenderingServer.Singleton.ShaderGetCode( s.GetRid() ); + code += "\n "; + + RenderingServer.Singleton.ShaderSetCode( s.GetRid(), code ); + } + ); + } + ); + [Export] + public Shader[] shaders; + + [ExportToolButton( "Get Material Code")] + public Callable getMaterialCodeButton => Callable.From( + ()=> + { + var shaderRID = material._GetShaderRid(); + var code = RenderingServer.Singleton.ShaderGetCode( shaderRID ); + + this.LogInfo( "Shader:", code ); + } + ); + + [Export] + public Material material; + + + + + void EnsureGlobalShaderProperties() { var globalProperties = RenderingServer.GlobalShaderParameterGetList(); diff --git a/Runtime/Shading/Library/Math.gdshaderinc b/Runtime/Shading/Library/Math.gdshaderinc index 74c1f08..e631cd7 100644 --- a/Runtime/Shading/Library/Math.gdshaderinc +++ b/Runtime/Shading/Library/Math.gdshaderinc @@ -1,11 +1,11 @@ // #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Math.gdshaderinc" -const float DegreesToRadians = PI/180.0; +const float DegreesToRadians = 3.14159265358979/180.0; float clamp01( float value ) { return clamp( value, 0.0, 1.0 ); -} +} vec4 clamp01_v4( vec4 value ) { diff --git a/Runtime/Shading/Library/SDF.gdshaderinc b/Runtime/Shading/Library/SDF.gdshaderinc index e855662..4d68ad0 100644 --- a/Runtime/Shading/Library/SDF.gdshaderinc +++ b/Runtime/Shading/Library/SDF.gdshaderinc @@ -115,6 +115,12 @@ float sdBox( in vec2 p, in vec2 b ) return length(max(d,0.0)) + min(max(d.x,d.y),0.0); } +float sdSegment( in vec2 p, in vec2 a, in vec2 b ) +{ + vec2 pa = p-a, ba = b-a; + float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); + return length( pa - ba*h ); +} /*