From 90d5759d26e8690e61530c07f6f7f3dbd3ee385e Mon Sep 17 00:00:00 2001 From: Josef Date: Sat, 24 Jan 2026 14:39:35 +0100 Subject: [PATCH] Gradient Fog --- .../Fog/FogCompositorEffect.cs | 13 + .../Fog/FogCompositorEffect.cs.uid | 1 + .../Fog/GradientFog/GradientFogEffect.cs | 133 ++++++++ .../Fog/GradientFog/GradientFogEffect.cs.uid | 1 + .../Character/Drunken.tres | 13 +- .../Fog/GradientFog/GradientFog.glsl | 322 ++++++++++++++++++ .../Fog/GradientFog/GradientFog.glsl.import | 14 + .../Fog/GradientFog/RG_GradientFog.cs | 17 + .../Fog/GradientFog/RG_GradientFog.cs.uid | 1 + 9 files changed, 509 insertions(+), 6 deletions(-) create mode 100644 Runtime/Rendering/Compositor/CompositorEffects/Fog/FogCompositorEffect.cs create mode 100644 Runtime/Rendering/Compositor/CompositorEffects/Fog/FogCompositorEffect.cs.uid create mode 100644 Runtime/Rendering/Compositor/CompositorEffects/Fog/GradientFog/GradientFogEffect.cs create mode 100644 Runtime/Rendering/Compositor/CompositorEffects/Fog/GradientFog/GradientFogEffect.cs.uid create mode 100644 Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/GradientFog.glsl create mode 100644 Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/GradientFog.glsl.import create mode 100644 Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/RG_GradientFog.cs create mode 100644 Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/RG_GradientFog.cs.uid diff --git a/Runtime/Rendering/Compositor/CompositorEffects/Fog/FogCompositorEffect.cs b/Runtime/Rendering/Compositor/CompositorEffects/Fog/FogCompositorEffect.cs new file mode 100644 index 0000000..d268c5f --- /dev/null +++ b/Runtime/Rendering/Compositor/CompositorEffects/Fog/FogCompositorEffect.cs @@ -0,0 +1,13 @@ + +using Godot; +using System.Collections.Generic; + +namespace Rokojori +{ + [Tool] + [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/FogCompositorEffect.svg")] + public abstract partial class FogCompositorEffect:RDGraphCompositorEffect + { + + } +} diff --git a/Runtime/Rendering/Compositor/CompositorEffects/Fog/FogCompositorEffect.cs.uid b/Runtime/Rendering/Compositor/CompositorEffects/Fog/FogCompositorEffect.cs.uid new file mode 100644 index 0000000..b1fdb38 --- /dev/null +++ b/Runtime/Rendering/Compositor/CompositorEffects/Fog/FogCompositorEffect.cs.uid @@ -0,0 +1 @@ +uid://cuaweg0ohqox8 diff --git a/Runtime/Rendering/Compositor/CompositorEffects/Fog/GradientFog/GradientFogEffect.cs b/Runtime/Rendering/Compositor/CompositorEffects/Fog/GradientFog/GradientFogEffect.cs new file mode 100644 index 0000000..92d41f4 --- /dev/null +++ b/Runtime/Rendering/Compositor/CompositorEffects/Fog/GradientFog/GradientFogEffect.cs @@ -0,0 +1,133 @@ + +using Godot; + +namespace Rokojori +{ + [Tool] + [GlobalClass] + public partial class GradientFogEffect:FogCompositorEffect + { + public GradientFogEffect():base() + { + Initialize(); + } + + + [ExportGroup( "Main")] + [Export( PropertyHint.Range, "0,1") ] + public float amount = 1f; + + [Export] + public float zStart = 1f; + + [Export] + public float zEnd = 1f; + + [Export( PropertyHint.Range, "-1,1") ] + public float zSpread = 0f; + + + + [Export] + public GradientTexture1D gradient = new GradientTexture1D(); + + [Export] + public float gradientUVScale = 1f; + + [Export] + public float gradientUVOffset = 0f; + + [Export] + public float gradientUVScroll = 0f; + + [Export] + public float gradientUVScrollFPS = 0f; + + [Export] + public TimeLine gradientUVScrollTimeline = null; + + [Export] + public CurveTexture opacity = new CurveTexture().WithCurve( new Curve().WithValues( 1, 1 ) ); + + + RG_ScreenColorTexure screenColorTexture; + RG_ScreenDepthTexture screenDepthTexture; + + RG_ImageTexture gradientTexture; + RG_ImageTexture opacityTexture; + + RG_GradientFog gradientFog; + + + void Initialize() + { + screenColorTexture = new RG_ScreenColorTexure( graph ); + screenDepthTexture = new RG_ScreenDepthTexture( graph ); + + gradientTexture = new RG_ImageTexture( graph ); + opacityTexture = new RG_ImageTexture( graph ); + + gradientFog = new RG_GradientFog( graph ); + + + graph.InitializeNodes(); + + gradientFog.SetTextureSlotInputs( screenColorTexture, screenColorTexture ); + gradientFog.AddTextureSlotInput( screenDepthTexture ).UseLinearSamplerEdgeClamped(); + gradientFog.AddTextureSlotInput( gradientTexture ).UseLinearSamplerEdgeClamped(); + gradientFog.AddTextureSlotInput( opacityTexture ).UseLinearSamplerEdgeClamped(); + + graph.SetProcessOrder( + screenColorTexture, + screenDepthTexture, + + gradientTexture, + opacityTexture, + + gradientFog + ); + + } + + + protected override void ForAllViews() + { + gradientTexture.SetImageTexture( gradient ); + opacityTexture.SetImageTexture( opacity ); + + var projection = context.GetCameraProjection().Inverse(); + + var tl = TimeLineManager.Ensure( gradientUVScrollTimeline ); + + float tlPosition = tl.position; + + if ( gradientUVScrollFPS > 0f ) + { + float stepTime = 1.0f / gradientUVScrollFPS; + tlPosition = MathX.SnapFloored( tlPosition, stepTime ); + } + + var gradientOffset = ( tlPosition * gradientUVScroll + gradientUVOffset ) % 1f; + + gradientFog.constants.Set( + projection.X, + projection.Y, + projection.Z, + projection.W, + + amount, + Mathf.Pow( 10f, zSpread ), + zStart, + zEnd, + + gradientUVScale, + gradientOffset, + 0f, + 0f + + ); + + } + + } +} \ No newline at end of file diff --git a/Runtime/Rendering/Compositor/CompositorEffects/Fog/GradientFog/GradientFogEffect.cs.uid b/Runtime/Rendering/Compositor/CompositorEffects/Fog/GradientFog/GradientFogEffect.cs.uid new file mode 100644 index 0000000..d7d4136 --- /dev/null +++ b/Runtime/Rendering/Compositor/CompositorEffects/Fog/GradientFog/GradientFogEffect.cs.uid @@ -0,0 +1 @@ +uid://dqgedhwm3die2 diff --git a/Runtime/Rendering/Compositor/CompositorVFXPresets/Character/Drunken.tres b/Runtime/Rendering/Compositor/CompositorVFXPresets/Character/Drunken.tres index 69979b8..081e0e5 100644 --- a/Runtime/Rendering/Compositor/CompositorVFXPresets/Character/Drunken.tres +++ b/Runtime/Rendering/Compositor/CompositorVFXPresets/Character/Drunken.tres @@ -16,7 +16,7 @@ script = ExtResource("2_ysy1a") script = ExtResource("3_fp4l4") owner = SubResource("Resource_fy8er") -[sub_resource type="CompositorEffect" id="CompositorEffect_i5utj"] +[sub_resource type="CompositorEffect" id="CompositorEffect_ifhyp"] resource_local_to_scene = false resource_name = "" enabled = true @@ -47,7 +47,7 @@ metadata/_custom_type_script = "uid://dvvfvlutisecy" script = ExtResource("3_fp4l4") owner = SubResource("Resource_fy8er") -[sub_resource type="CompositorEffect" id="CompositorEffect_gxlxg"] +[sub_resource type="CompositorEffect" id="CompositorEffect_wx28p"] resource_local_to_scene = false resource_name = "" enabled = true @@ -55,7 +55,7 @@ effect_callback_type = 4 needs_motion_vectors = false needs_normal_roughness = false script = ExtResource("6_kwewy") -amount = 0.05 +amount = 0.0 scale = 5.0619 smearingSteps = 5 smearing = 1.2095 @@ -72,7 +72,7 @@ metadata/_custom_type_script = "uid://cidk0x7sb1pxl" script = ExtResource("3_fp4l4") owner = SubResource("Resource_fy8er") -[sub_resource type="CompositorEffect" id="CompositorEffect_ixn1d"] +[sub_resource type="CompositorEffect" id="CompositorEffect_ysy1a"] resource_local_to_scene = false resource_name = "" enabled = true @@ -98,7 +98,7 @@ metadata/_custom_type_script = "uid://b2oxy6ln560ys" script = ExtResource("3_fp4l4") owner = SubResource("Resource_fy8er") -[sub_resource type="CompositorEffect" id="CompositorEffect_y3g14"] +[sub_resource type="CompositorEffect" id="CompositorEffect_fp4l4"] resource_local_to_scene = false resource_name = "" enabled = true @@ -106,10 +106,11 @@ effect_callback_type = 4 needs_motion_vectors = false needs_normal_roughness = false script = ExtResource("7_wx28p") +smearingFrames = 10.0 compositorEffectID = SubResource("Resource_3tnad") metadata/_custom_type_script = "uid://cowk70ifagygb" [resource] script = ExtResource("9_srrpj") -effects = [SubResource("CompositorEffect_i5utj"), SubResource("CompositorEffect_gxlxg"), SubResource("CompositorEffect_ixn1d"), SubResource("CompositorEffect_y3g14")] +effects = [SubResource("CompositorEffect_ifhyp"), SubResource("CompositorEffect_wx28p"), SubResource("CompositorEffect_ysy1a"), SubResource("CompositorEffect_fp4l4")] metadata/_custom_type_script = "uid://ckixweetchlo0" diff --git a/Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/GradientFog.glsl b/Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/GradientFog.glsl new file mode 100644 index 0000000..83ade3e --- /dev/null +++ b/Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/GradientFog.glsl @@ -0,0 +1,322 @@ +#[compute] +#version 450 + +float clamp01( float 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 ) ); +} + +float mapClamped( float value, float inMin, float inMax, float outMin, float outMax ) +{ + return mix( outMin, outMax, normalizeToRange01( value, inMin, inMax ) ); +} + +vec3 applyMatrix( vec3 v, mat4 m ) +{ + return ( m * vec4( v, 1.0 ) ).xyz; +} + +vec3 applyMatrixWithoutTranslation( vec3 v, mat4 m ) +{ + return ( m * vec4( v, 0.0 ) ).xyz; +} + +vec3 applyMatrix( vec3 v, mat3 m ) +{ + return ( m * v ).xyz; +} + + +vec3 localToWorld( vec3 local, mat4 _MODEL_MATRIX ) +{ + return applyMatrix( local, _MODEL_MATRIX ); +} + +vec3 localToWorldDirection( vec3 local, mat4 _MODEL_MATRIX ) +{ + return applyMatrixWithoutTranslation( local, _MODEL_MATRIX ); +} + +vec3 localToView( vec3 local, mat4 _MODELVIEW_MATRIX ) +{ + return applyMatrix( local, _MODELVIEW_MATRIX ); +} + +vec3 localToViewDirection( vec3 local, mat4 _MODELVIEW_MATRIX ) +{ + return applyMatrixWithoutTranslation( local, _MODELVIEW_MATRIX ); +} + +vec3 localToViewDirection( vec3 local, mat3 _MODELVIEW_NORMAL_MATRIX ) +{ + return applyMatrix( local, _MODELVIEW_NORMAL_MATRIX ); +} + +vec3 worldToLocal( vec3 world, mat4 _MODEL_MATRIX ) +{ + mat4 inversedMatrix = inverse( _MODEL_MATRIX ); + return applyMatrix( world, inversedMatrix ); +} + +vec3 worldToLocalDirection( vec3 world, mat4 _MODEL_MATRIX ) +{ + mat4 inversedMatrix = inverse( _MODEL_MATRIX ); + return applyMatrixWithoutTranslation( world, inversedMatrix ); +} + + +vec3 worldToView( vec3 world, mat4 _VIEW_MATRIX ) +{ + return applyMatrix( world, _VIEW_MATRIX ); +} + +vec3 worldToViewDirection( vec3 worldDirection, mat4 _VIEW_MATRIX ) +{ + return applyMatrixWithoutTranslation( worldDirection, _VIEW_MATRIX ); +} + +vec3 viewToWorld( vec3 view, mat4 _INV_VIEW_MATRIX ) +{ + return applyMatrix( view, _INV_VIEW_MATRIX ); +} + +vec3 viewToWorldDirection( vec3 viewDirection, mat4 _INV_VIEW_MATRIX ) +{ + return applyMatrixWithoutTranslation( viewDirection, _INV_VIEW_MATRIX ); +} + +vec3 viewToLocal( vec3 view, mat4 _INV_VIEW_MATRIX, mat4 _MODEL_MATRIX ) +{ + vec3 world = viewToWorld( view, _INV_VIEW_MATRIX ); + return worldToLocal( world, _MODEL_MATRIX ); +} + +vec3 viewToLocal( vec3 view, mat4 _MODELVIEW_MATRIX ) +{ + mat4 inversedMatrix = inverse( _MODELVIEW_MATRIX ); + return applyMatrix( view, inversedMatrix ); +} + +vec3 viewToLocalDirection( vec3 viewDirection, mat4 _MODELVIEW_MATRIX ) +{ + mat4 inversedMatrix = inverse( _MODELVIEW_MATRIX ); + return applyMatrixWithoutTranslation( viewDirection, inversedMatrix ); +} + +vec3 viewToLocalDirection( vec3 view, mat4 _INV_VIEW_MATRIX, mat4 _MODEL_MATRIX ) +{ + vec3 world = viewToWorldDirection( view, _INV_VIEW_MATRIX ); + return worldToLocalDirection( world, _MODEL_MATRIX ); +} + +vec4 viewToClip( vec3 view, mat4 _PROJECTION_MATRIX ) +{ + vec4 clip = _PROJECTION_MATRIX * vec4( view, 1.0 ); + clip /= clip.w; + return clip; +} + +vec2 clipToScreen( vec4 clip ) +{ + return ( clip.xy / clip.w ) * 0.5 + vec2( 0.5 ); +} + +vec4 screenToClip( vec2 screen, float z ) +{ + return vec4( screen * 2.0 - 1.0, z, 1.0 ); +} + +vec4 clipToView( vec4 clip, mat4 _INV_PROJECTION_MATRIX ) +{ + vec4 view = _INV_PROJECTION_MATRIX * clip; + view /= view.w; + return view; +} + +vec4 screenToView( vec2 screen, float z, mat4 _INV_PROJECTION_MATRIX ) +{ + vec4 clip = screenToClip( screen, z ); + vec4 view = clipToView( clip, _INV_PROJECTION_MATRIX ); + + return view; +} + +vec3 screenToWorld( vec2 screen, float z, mat4 _INV_PROJECTION_MATRIX, mat4 _INV_VIEW_MATRIX ) +{ + vec4 view = screenToView( screen, z, _INV_PROJECTION_MATRIX ); + + return viewToWorld( view.xyz, _INV_VIEW_MATRIX ); +} + +vec3 screenToLocal( vec2 screen_point, float z, mat4 _PROJECTION_MATRIX, mat4 _VIEW_MATRIX, mat4 _MODEL_MATRIX ) +{ + vec4 clip = vec4( screen_point * 2.0 - 1.0, z, 1.0 ); + vec4 view4 = inverse( _PROJECTION_MATRIX ) * clip; + view4 /= view4.w; + vec3 view = view4.xyz; + mat4 m = inverse( _VIEW_MATRIX * _MODEL_MATRIX ); + return ( m * vec4( view, 1.0 ) ).xyz; +} + +vec2 viewToScreen( vec3 view, mat4 _PROJECTION_MATRIX ) +{ + vec4 clip = viewToClip( view, _PROJECTION_MATRIX ); + + return clipToScreen( clip ); +} + +vec2 localToScreen( vec3 local, mat4 _MODELVIEW_MATRIX, mat4 _PROJECTION_MATRIX ) +{ + vec3 view = localToView( local, _MODELVIEW_MATRIX ); + return viewToScreen( view, _PROJECTION_MATRIX ); +} + +vec2 worldToScreen( vec3 world, mat4 _VIEW_MATRIX, mat4 _PROJECTION_MATRIX ) +{ + vec3 view = worldToView( world, _VIEW_MATRIX ); + vec4 clip = viewToClip( view, _PROJECTION_MATRIX ); + vec2 screen = clipToScreen( clip ); + + return screen; +} + + +vec3 extractTranslation( mat4 matrix ) +{ + return vec3( matrix[ 3 ][ 0 ], matrix[ 3 ][ 1 ], matrix[ 3 ][ 2 ] ); +} + +vec3 extractScale( mat3 matrix ) +{ + mat3 m = matrix; + + float x = length( vec3( m[ 0 ][ 0 ], m[ 1 ][ 0 ], m[ 2 ][ 0 ] ) ); + float y = length( vec3( m[ 0 ][ 1 ], m[ 1 ][ 1 ], m[ 2 ][ 1 ] ) ); + float z = length( vec3( m[ 0 ][ 2 ], m[ 1 ][ 2 ], m[ 2 ][ 2 ] ) ); + + return vec3( x, y, z ); +} + +vec3 extractScale( mat4 matrix ) +{ + mat4 m = matrix; + + float x = length( vec3( m[ 0 ][ 0 ], m[ 1 ][ 0 ], m[ 2 ][ 0 ] ) ); + float y = length( vec3( m[ 0 ][ 1 ], m[ 1 ][ 1 ], m[ 2 ][ 1 ] ) ); + float z = length( vec3( m[ 0 ][ 2 ], m[ 1 ][ 2 ], m[ 2 ][ 2 ] ) ); + + return vec3( x, y, z ); +} + +mat3 extractRotationMatrix( mat4 m ) +{ + vec3 x = normalize( m[ 0 ].xyz ); + vec3 y = normalize( m[ 1 ].xyz ); + vec3 z = normalize( m[ 2 ].xyz ); + + return mat3( x, y, z ); +} + +vec3 SRGBtoLINEAR( vec3 sRGB ) +{ + return mix( pow( (sRGB + vec3( 0.055 )) * ( 1.0 / ( 1.0 + 0.055 )),vec3( 2.4 )),sRGB * ( 1.0 / 12.92 ),lessThan( sRGB,vec3( 0.04045 )) ); +} + +vec4 SRGBtoLINEAR( vec4 sRGB ) +{ + return vec4( SRGBtoLINEAR( sRGB.rgb ), sRGB.a ); +} + + +layout( local_size_x = 8, local_size_y = 8, local_size_z = 1 ) in; + +layout( rgba16, set = 0, binding = 0 ) +uniform image2D inputImage; + +layout( rgba16, set = 1, binding = 0 ) +uniform restrict writeonly image2D outputImage; + +layout( set = 2, binding = 0 ) +uniform sampler2D depthSampler; + +layout( set = 3, binding = 0 ) +uniform sampler2D gradientSampler; + +layout( set = 4, binding = 0 ) +uniform sampler2D opacitySampler; + +layout( push_constant, std430 ) +uniform Parameters +{ + vec4 m0; + vec4 m1; + vec4 m2; + vec4 m3; + + float amount; + float zSpread; + float zStart; + float zEnd; + + float gradientUVScale; + float gradientUVOffset; + float p0; + float p1; + + +} parameters; + +float getZ( vec2 uv, float depth, mat4 INV_PROJ ) +{ + vec4 position = screenToView( uv, depth, INV_PROJ ); + return max( 0.0, -position.z ); +} + +void main() +{ + ivec2 size = imageSize( outputImage ); + ivec2 xy = ivec2( gl_GlobalInvocationID.xy ); + + if ( any( greaterThanEqual( xy, size ) ) ) + { + return; + } + + vec2 uv = ( vec2( xy ) + vec2( 0.5 ) ) / vec2( size ); + + mat4 INV_PROJ = mat4( parameters.m0, parameters.m1, parameters.m2, parameters.m3 ); + + float depth = texture( depthSampler, uv ).r; + float z = getZ( uv, depth, INV_PROJ ); + + float mappedZ = normalizeToRange01( z, parameters.zStart, parameters.zEnd ); + mappedZ = pow( mappedZ, parameters.zSpread ); + + vec2 gradientUV = vec2( mappedZ * parameters.gradientUVScale + parameters.gradientUVOffset, 0.0 ); + gradientUV.x = fract( gradientUV.x ); + vec4 gradientColor = SRGBtoLINEAR( textureLod( gradientSampler, gradientUV, 0 ) ); + vec4 opacity = textureLod( opacitySampler, vec2( mappedZ, 0.0 ), 0 ); + + gradientColor.a *= opacity.r; + + vec4 color = imageLoad( inputImage, xy ); + + color = mix( color, vec4( gradientColor.rgb, color.a ), gradientColor.a * parameters.amount ); + + imageStore( outputImage, xy, color ); +} diff --git a/Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/GradientFog.glsl.import b/Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/GradientFog.glsl.import new file mode 100644 index 0000000..029f303 --- /dev/null +++ b/Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/GradientFog.glsl.import @@ -0,0 +1,14 @@ +[remap] + +importer="glsl" +type="RDShaderFile" +uid="uid://57k6v5nde7nt" +path="res://.godot/imported/GradientFog.glsl-c786da44a43475e54892406d1370a236.res" + +[deps] + +source_file="res://addons/rokojori_action_library/Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/GradientFog.glsl" +dest_files=["res://.godot/imported/GradientFog.glsl-c786da44a43475e54892406d1370a236.res"] + +[params] + diff --git a/Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/RG_GradientFog.cs b/Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/RG_GradientFog.cs new file mode 100644 index 0000000..adbbef4 --- /dev/null +++ b/Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/RG_GradientFog.cs @@ -0,0 +1,17 @@ + +using Godot; +using System.Collections.Generic; + +namespace Rokojori +{ + public class RG_GradientFog:RG_ImageProcessor + { + public static readonly string shaderPath = + RDGraph.Path( "Nodes/Processors/Fog/GradientFog/GradientFog.glsl" ); + + public RG_GradientFog( RDGraph graph ):base( graph, shaderPath ) + {} + + + } +} \ No newline at end of file diff --git a/Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/RG_GradientFog.cs.uid b/Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/RG_GradientFog.cs.uid new file mode 100644 index 0000000..b2e5e8f --- /dev/null +++ b/Runtime/Rendering/RenderGraph/Nodes/Processors/Fog/GradientFog/RG_GradientFog.cs.uid @@ -0,0 +1 @@ +uid://dyoo2wrv34ods