Compositor Effects Update

This commit is contained in:
Josef 2025-04-24 15:39:00 +02:00
parent 50e4bf74b4
commit 89138f1a1c
59 changed files with 1250 additions and 95 deletions

View File

@ -13,7 +13,6 @@ namespace Rokojori
RokojoriPlugin.Path( "Runtime/Rendering/CompositorEffects/DepthAntiAliasing/DepthAntiAliasingShader.glsl" );
RDPushConstants constants = new RDPushConstants();
RDSampler sampler;
[Export( PropertyHint.Range, "0,1") ]
@ -56,7 +55,7 @@ namespace Rokojori
protected override void ForAllViews()
protected override void SetConstants()
{
constants.Set(
(Vector2)context.internalSize,

View File

@ -39,9 +39,7 @@ namespace Rokojori
sampler = Sampler( RenderingDevice.SamplerFilter.Nearest, RenderingDevice.SamplerRepeatMode.ClampToEdge );
}
protected override void ForAllViews()
protected override void SetConstants()
{
constants.Set(
(Vector2)context.internalSize,

View File

@ -20,9 +20,7 @@ namespace Rokojori
_groupSize = 8;
}
RDPushConstants constants = new RDPushConstants();
protected override void ForAllViews()
protected override void SetConstants()
{
constants.Set(
(Vector2)context.internalSize,

View File

@ -25,9 +25,7 @@ namespace Rokojori
_groupSize = 8;
}
RDPushConstants constants = new RDPushConstants();
protected override void ForAllViews()
protected override void SetConstants()
{
constants.Set(
(Vector2)context.internalSize,

View File

@ -31,9 +31,8 @@ namespace Rokojori
_groupSize = 32;
}
RDPushConstants constants = new RDPushConstants();
protected override void ForAllViews()
protected override void SetConstants()
{
constants.Set(
center,

View File

@ -0,0 +1,82 @@
using Godot;
using Godot.Collections;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class RadialBlur2:_XX_CompositorEffectGraph
{
public RadialBlur2()
{
CreateGraphNodes();
}
[Export]
public Vector2 center = new Vector2( 0.5f, 0.5f );
[Export]
public float radius = 0.5f;
[Export]
public float intensity = 0.5f;
[Export]
public float samples = 16f;
CEG_ScreenColorTexure screenColorTexture;
CEG_BufferTexture bufferTexture;
CEG_Copy copy;
CEG_RadialBlur radialBlur;
void Initialize()
{
CreateGraphNodes();
ConnectGraph();
AssignData();
}
void CreateGraphNodes()
{
screenColorTexture = new CEG_ScreenColorTexure( this );
bufferTexture = CEG_BufferTexture.ScreenSize( this );
copy = new CEG_Copy( this );
radialBlur = new CEG_RadialBlur( this );
}
void ConnectGraph()
{
copy.SetTextureSlotInputs( screenColorTexture, bufferTexture );
radialBlur.SetTextureSlotInputs( copy.output, copy.input );
SetProcessOrder(
screenColorTexture, bufferTexture,
copy, radialBlur
);
}
void AssignData()
{
radialBlur.constants.Set(
center,
radius,
intensity,
samples,
Vector2.Zero
);
}
protected override void OnPreProcess()
{
AssignData();
}
}
}

View File

@ -0,0 +1 @@
uid://dq0uf1bqoefv

View File

@ -0,0 +1,39 @@
#[compute]
#version 450
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout(rgba16, set = 0, binding = 0)
uniform restrict image2D lastProcessedImage;
layout(rgba16, set = 1, binding = 0)
uniform restrict image2D currentImage;
layout( push_constant, std430 )
uniform Params
{
float amount;
float smearing;
float luma;
float minBrightness;
float saturate;
} params;
void main()
{
ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy );
vec4 currentPixel = imageLoad( currentImage, currentPosition );
vec4 lastPixel = imageLoad( lastProcessedImage, currentPosition );
float luminance = min( 1.0, length( vec3( lastPixel.r, lastPixel.g, lastPixel.b ) ) );
float amount = ( luminance - params.minBrightness ) / ( 1.0 - params.minBrightness );
amount = min( max( 0.0, amount * params.saturate ), 1.0 ) * params.smearing;
amount = mix( 1.0, amount, params.luma );
vec4 nextPixel = currentPixel + min( 1.0, amount * params.smearing ) * ( lastPixel - currentPixel );
imageStore( currentImage, currentPosition, mix( currentPixel, nextPixel, params.amount ) );
imageStore( lastProcessedImage, currentPosition, nextPixel );
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://cd1ysd752pjrn"
path="res://.godot/imported/TemporalSmear.glsl-b228c3fd9c0b0985d61f64e14d6b8842.res"
[deps]
source_file="res://addons/rokojori_action_library/Runtime/Rendering/CompositorEffects/TemporalSmear/TemporalSmear.glsl"
dest_files=["res://.godot/imported/TemporalSmear.glsl-b228c3fd9c0b0985d61f64e14d6b8842.res"]
[params]

View File

@ -0,0 +1,75 @@
using Godot;
using Godot.Collections;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class TemporalSmearEffect:SingleShaderCompositorEffect
{
public static readonly string shaderPath =
RokojoriPlugin.Path( "Runtime/Rendering/CompositorEffects/TemporalSmear/TemporalSmear.glsl" );
[Export( PropertyHint.Range, "0,1")]
public float amount = 1f;
[Export( PropertyHint.Range, "0,1")]
public float smearing = 0.5f;
[Export( PropertyHint.Range, "0,1")]
public float lumaAmount = 0.5f;
[Export( PropertyHint.Range, "0,1")]
public float lumaTreshold = 0.5f;
[Export( PropertyHint.Range, "0.5,5")]
public float lumaSaturate = 1.3f;
protected override void OnConfigure()
{
EffectCallbackType = EffectCallbackTypeEnum.PostTransparent;
_shaderPath = shaderPath;
_groupSize = 8;
}
protected override void SetConstants()
{
constants.Set(
amount,
smearing,
lumaAmount,
lumaTreshold,
lumaSaturate
);
}
RDTexture _bufferTexture;
protected override void RenderView()
{
if ( _bufferTexture == null || _bufferTexture.size != context.internalSize )
{
if ( _bufferTexture != null )
{
rd.FreeRid( _bufferTexture.rid );
_bufferTexture = null;
}
_bufferTexture = RDTexture.Create( this, context.internalSize );
}
context.AssignUniformSet_Texture( _bufferTexture );
context.Assign_ScreenColorTexture();
context.pushConstants = constants;
context.Render();
}
}
}

View File

@ -0,0 +1 @@
uid://djyhjsfnb6cxw

View File

@ -0,0 +1,18 @@
#[compute]
#version 450
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout(rgba16, set = 0, binding = 0)
uniform restrict readonly image2D inputImage;
layout(rgba16, set = 1, binding = 0)
uniform restrict writeonly image2D outputImage;
void main()
{
ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy );
vec4 currentPixel = imageLoad( inputImage, currentPosition );
imageStore( outputImage, currentPosition, currentPixel );
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://b281d2ovcc1wm"
path="res://.godot/imported/Copy.glsl-440875809e1224bd8f12ab4747b61bfc.res"
[deps]
source_file="res://addons/rokojori_action_library/Runtime/Rendering/CompositorEffects/TextureDilation/Copy.glsl"
dest_files=["res://.godot/imported/Copy.glsl-440875809e1224bd8f12ab4747b61bfc.res"]
[params]

View File

@ -0,0 +1,61 @@
#[compute]
#version 450
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout(rgba16, set = 0, binding = 0) uniform restrict readonly image2D inputImage;
layout(rgba16, set = 1, binding = 0) uniform restrict readonly image2D originalImage;
layout(rgba16, set = 2, binding = 0) uniform restrict writeonly image2D outputImage;
layout(std430, set = 3, binding = 0) buffer restrict readonly OutlinesSizeBuffer { int size; } osb;
void main()
{
ivec2 current_position = ivec2(gl_GlobalInvocationID.xy);
vec4 current_pixel = imageLoad(inputImage, current_position);
ivec2 current_seed_position = ivec2(packUnorm2x16(current_pixel.xy), packUnorm2x16(current_pixel.zw));
// The "rough" outline generated by the Jump Flood Algorithm contains all the pixels of the desired outline + some more
// If the current pixel is not a seed, then it can't be part of the outline
if (current_seed_position.x == 0 && current_seed_position.y == 0)
{
imageStore(outputImage, current_position, vec4(0.0f));
return;
}
float distance_to_seed = distance(vec2(current_position), vec2(current_seed_position));
float outlinesSize = float(osb.size);
// The current pixel is outside the outline range
if (distance_to_seed > outlinesSize) {
imageStore(outputImage, current_position, vec4(0.0f));
return;
}
vec4 original_pixel = imageLoad(originalImage, current_seed_position);
// The current pixel is on the edge of the outline, outer side
if (distance_to_seed > outlinesSize - 1.0f)
{
float smoothing = 1.0f - (distance_to_seed - (outlinesSize - 1.0f));
imageStore(outputImage, current_position, vec4(original_pixel.xyz, smoothing));
return;
}
// The current pixel is part of the object to outline
if (distance_to_seed == 0.0f)
{
imageStore(outputImage, current_position, vec4(0.0f));
return;
}
// The current pixel is on the edge of the outline, inner side
if (distance_to_seed < 1.0f)
{
float smoothing = distance_to_seed;
imageStore(outputImage, current_position, vec4(original_pixel.xyz, smoothing));
return;
}
// The current pixel is part of the outline
imageStore(outputImage, current_position, vec4(original_pixel.xyz, original_pixel.a));
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://fjarrr31htov"
path="res://.godot/imported/JFA_Assign.glsl-d64da3d1862c7dbd2f410c2e5f98e270.res"
[deps]
source_file="res://addons/rokojori_action_library/Runtime/Rendering/CompositorEffects/TextureDilation/JFA_Assign.glsl"
dest_files=["res://.godot/imported/JFA_Assign.glsl-d64da3d1862c7dbd2f410c2e5f98e270.res"]
[params]

View File

@ -0,0 +1,33 @@
#[compute]
#version 450
layout( local_size_x = 8, local_size_y = 8, local_size_z = 1 ) in;
layout( rgba16, set = 0, binding = 0 )
uniform restrict readonly image2D inputImage;
layout( rgba16, set = 1, binding = 0 )
uniform restrict writeonly image2D outputImage;
layout( push_constant, std430 )
uniform Params
{
float alphaTreshold;
} params;
void main()
{
ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy );
vec4 currentPixel = imageLoad( inputImage, currentPosition );
if ( currentPixel.a < params.alphaTreshold )
{
vec4 packedZero = vec4( unpackUnorm2x16( 0 ), unpackUnorm2x16( 0 ) );
imageStore( outputImage, currentPosition, packedZero );
return;
}
vec4 packedPosition = vec4( unpackUnorm2x16( currentPosition.x ), unpackUnorm2x16( currentPosition.y ) );
imageStore( outputImage, currentPosition, packedPosition);
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://eqgl8l1lmgrl"
path="res://.godot/imported/JFA_Initialize.glsl-8eec6889b219c52896e1b7597ec3dbbd.res"
[deps]
source_file="res://addons/rokojori_action_library/Runtime/Rendering/CompositorEffects/TextureDilation/JFA_Initialize.glsl"
dest_files=["res://.godot/imported/JFA_Initialize.glsl-8eec6889b219c52896e1b7597ec3dbbd.res"]
[params]

View File

@ -0,0 +1,61 @@
#[compute]
#version 450
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout(rgba16, set = 0, binding = 0)
uniform restrict readonly image2D inputImage;
layout(rgba16, set = 1, binding = 0)
uniform restrict writeonly image2D outputImage;
layout(std430, set = 2, binding = 0)
buffer restrict readonly JumpDistanceBuffer { int jump; } jdb;
void main()
{
ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy );
ivec2 imageSize = imageSize( inputImage );
float distanceToClosestSeed = 1.0f / 0.0f;
vec4 closestSeed = vec4( unpackUnorm2x16( 0 ), unpackUnorm2x16( 0 ) );
ivec2 jdbJump = ivec2( jdb.jump, jdb.jump );
for ( int x = -1; x <= 1; x++ )
{
for ( int y = -1; y <= 1; y++ )
{
ivec2 xy = ivec2( x, y );
ivec2 checkPosition = currentPosition + jdbJump * xy;
if ( checkPosition.x < 0 || checkPosition.y < 0 ||
checkPosition.x >= imageSize.x || checkPosition.y >= imageSize.y )
{
continue;
}
vec4 checkPixel = imageLoad( inputImage, checkPosition );
float checkSeedX = float( packUnorm2x16( checkPixel.xy ) );
float checkSeedY = float( packUnorm2x16( checkPixel.zw ) );
vec2 checkSeedPosition = vec2( checkSeedX, checkSeedY );
if ( checkSeedPosition.x == 0.0f && checkSeedPosition.y == 0.0f )
{
continue;
}
float distanceToSeed = distance( vec2( currentPosition ), checkSeedPosition );
if ( distanceToSeed < distanceToClosestSeed )
{
distanceToClosestSeed = distanceToSeed;
closestSeed = checkPixel;
}
}
}
imageStore( outputImage, currentPosition, closestSeed );
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://b263k73iy5pbl"
path="res://.godot/imported/JFA_Step.glsl-89a0d568e1c875744d558d5c62c00f0b.res"
[deps]
source_file="res://addons/rokojori_action_library/Runtime/Rendering/CompositorEffects/TextureDilation/JFA_Step.glsl"
dest_files=["res://.godot/imported/JFA_Step.glsl-89a0d568e1c875744d558d5c62c00f0b.res"]
[params]

View File

@ -11,46 +11,26 @@ namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class TextureDilationCompositerEffect:CompositorEffect
public partial class TextureDilationCompositerEffect:_XX_CompositorEffectGraph
{
RenderingDevice renderingDevice;
Rid frameBuffer;
public void _Init()
public TextureDilationCompositerEffect()
{
EffectCallbackType = EffectCallbackTypeEnum.PostOpaque;
renderingDevice = RenderingServer.GetRenderingDevice();
CreateGraph();
}
public override void _Notification(int what)
RDTexture color;
RDTexture bufferA;
RDTexture bufferB;
CEG_Copy copy;
void CreateGraph()
{
}
public override void _RenderCallback( int effectCallbackType, RenderData renderData )
void AssignData()
{
if ( renderingDevice == null || effectCallbackType != (int) EffectCallbackTypeEnum.PostOpaque )
{
return;
}
var renderBuffers = (RenderSceneBuffersRD) renderData.GetRenderSceneBuffers();
if ( renderBuffers == null )
{
return;
}
var size = renderBuffers.GetInternalSize();
if ( size.X == 0 || size.Y == 0 )
{
return;
}
var groups = new Vector3((size.X - 1.0f) / 8.0f + 1.0f, (size.Y - 1.0f) / 8.0f + 1.0f, 1.0f).Floor();
}
}

View File

@ -5,7 +5,12 @@ namespace Rokojori
{
public class CompositorEffectGraphConnection:CompositorEffectGraphNode
{
public CompositorEffectGraphConnection( _XX_CompositorEffectGraph graph ):base( graph ){}
protected CompositorEffectGraphProcessor _processor;
public CompositorEffectGraphConnection( CompositorEffectGraphProcessor processor ):base( processor.graph )
{
_processor = processor;
}
}
}

View File

@ -1,10 +0,0 @@
using Godot;
namespace Rokojori
{
public class CompositorEffectGraphInput:CompositorEffectGraphConnection
{
public CompositorEffectGraphInput( _XX_CompositorEffectGraph graph ):base( graph ){}
}
}

View File

@ -1,10 +0,0 @@
using Godot;
namespace Rokojori
{
public class CompositorEffectGraphOutput:CompositorEffectGraphConnection
{
public CompositorEffectGraphOutput( _XX_CompositorEffectGraph graph ):base( graph ){}
}
}

View File

@ -1,10 +1,13 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
public class CompositorEffectGraphProcessor:CompositorEffectGraphNode
{
protected List<CompositorEffectGraphConnection> _connections = new List<CompositorEffectGraphConnection>();
public CompositorEffectGraphProcessor( _XX_CompositorEffectGraph graph ):base( graph ){}
bool _initialized = false;

View File

@ -0,0 +1,62 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
public interface CompositorEffectGraphTextureSlotInput
{
public RDTexture GetTexture();
public CompositorEffectGraphProcessor GetProcessor();
public void SetConnected( CompositorEffectGraphTextureSlot slot );
public void ConnectTo( CompositorEffectGraphTextureSlot slot );
}
public class CompositorEffectGraphTextureSlot:CompositorEffectGraphConnection, CompositorEffectGraphTextureSlotInput
{
protected CompositorEffectGraphTextureSlotInput _input;
public CompositorEffectGraphTextureSlotInput input => _input;
public RDSampler sampler;
RDTexture _texture;
public RDTexture GetTexture()
{
return _texture;
}
public RDTexture ResolveTexture()
{
return _texture = _input.GetTexture();
}
public CompositorEffectGraphProcessor GetProcessor()
{
return _processor;
}
List<CompositorEffectGraphTextureSlot> _connectedSlots = new List<CompositorEffectGraphTextureSlot>();
public void SetConnected( CompositorEffectGraphTextureSlot slot )
{
_connectedSlots.Add( slot );
}
public CompositorEffectGraphTextureSlot( CompositorEffectGraphProcessor processor ):base( processor )
{
}
public void SetInput( CompositorEffectGraphTextureSlotInput input )
{
_input = input;
input.SetConnected( this );
}
public void ConnectTo( CompositorEffectGraphTextureSlot slot )
{
slot.SetInput( this );
}
}
}

View File

@ -0,0 +1 @@
uid://dpvnjuwxoc47d

View File

@ -16,8 +16,9 @@ namespace Rokojori
protected RDShader _shader;
protected RDPipeline _pipeline;
protected RDPushConstants _constants;
protected List<RDUniformSet> _uniformSets = new List<RDUniformSet>();
public RDPushConstants constants => _constants;
protected Vector3I _groupSize = new Vector3I( 8, 8, 0 );
protected List<CompositorEffectGraphTextureSlot> _textureSlots = new List<CompositorEffectGraphTextureSlot>();
protected override void OnInitialize()
{
@ -61,9 +62,16 @@ namespace Rokojori
var context = graph.context;
context.Clear();
context.ComputeGroups( _groupSize );
context.SetShaderAndPipeline( _shader, _pipeline );
_uniformSets.ForEach( context.AddUniformSet );
_textureSlots.ForEach( t =>
{
t.ResolveTexture();
graph.context.AssignUniformSet_Texture( t.GetTexture(), t.sampler );
}
);
context.pushConstants = _constants;

View File

@ -0,0 +1,17 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
public class CEG_RadialBlur:CEG_ImageProcessor
{
public static readonly string shaderPath =
_XX_CompositorEffectGraph.Path( "Nodes/Processors/Blurs/RadialBlur/RadialBlur.glsl" );
public CEG_RadialBlur( _XX_CompositorEffectGraph graph ):base( graph, shaderPath )
{}
}
}

View File

@ -0,0 +1,51 @@
#[compute]
#version 450
layout( local_size_x = 8, local_size_y = 8, local_size_z = 1 ) in;
layout( rgba16f, set = 0, binding = 0 )
uniform image2D inputImage;
layout( rgba16f, set = 1, binding = 0 )
uniform image2D outputImage;
layout( push_constant, std430 )
uniform Params
{
vec2 center; // 8 bytes
float radius; // 4 bytes
float intensity; // 4 bytes
float samples; // 4 bytes ( will be cast to int )
vec2 _padding; // 8 bytes ( matches 32-byte total )
} params;
void main( )
{
ivec2 img_size = imageSize( inputImage );
ivec2 texel_coord = ivec2( gl_GlobalInvocationID.xy );
if ( any( greaterThanEqual( texel_coord, img_size ) ) )
{
return;
}
vec2 uv = ( vec2( texel_coord ) + 0.5 ) / vec2( img_size );
vec2 dir = normalize( uv - params.center );
int num_samples = int( clamp( params.samples, 1.0, 64.0 ) );
vec4 color = vec4( 0.0 );
for ( int i = 0; i < num_samples; i++ )
{
float t = float( i ) / float( num_samples );
vec2 sample_uv = clamp( uv + dir * t * params.radius, vec2( 0.0 ), vec2( 1.0 ) );
ivec2 sample_coord = ivec2( sample_uv * vec2( img_size ) );
sample_coord = clamp( sample_coord, ivec2( 0 ), img_size - ivec2( 1 ) );
color += imageLoad( inputImage, sample_coord );
}
color /= float( num_samples );
vec4 original_color = imageLoad( inputImage, texel_coord );
imageStore( outputImage, texel_coord, mix( original_color, color, params.intensity ) );
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://bqsb2a6poa7b0"
path="res://.godot/imported/RadialBlur.glsl-2a7bbca9e049b45a9edfab7b714dd886.res"
[deps]
source_file="res://addons/rokojori_action_library/Runtime/Rendering/Objects/CompositorEffectGraph/Nodes/Processors/Blurs/RadialBlur/RadialBlur.glsl"
dest_files=["res://.godot/imported/RadialBlur.glsl-2a7bbca9e049b45a9edfab7b714dd886.res"]
[params]

View File

@ -0,0 +1,17 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
public class CEG_Copy:CEG_ImageProcessor
{
public static readonly string shaderPath =
_XX_CompositorEffectGraph.Path( "Nodes/Processors/Copy/CopyShader.glsl" );
public CEG_Copy( _XX_CompositorEffectGraph graph ):base( graph, shaderPath )
{}
}
}

View File

@ -0,0 +1 @@
uid://cdgu20aruad5x

View File

@ -0,0 +1,18 @@
#[compute]
#version 450
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout(rgba16, set = 0, binding = 0)
uniform restrict readonly image2D inputImage;
layout(rgba16, set = 1, binding = 0)
uniform restrict writeonly image2D outputImage;
void main()
{
ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy );
vec4 currentPixel = imageLoad( inputImage, currentPosition );
imageStore( outputImage, currentPosition, currentPixel );
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://dkmulxqa0tvis"
path="res://.godot/imported/Copy.glsl-04e877248c733e7d624480658e605c4c.res"
[deps]
source_file="res://addons/rokojori_action_library/Runtime/Rendering/Objects/CompositorEffectGraph/Nodes/Processors/Copy/Copy.glsl"
dest_files=["res://.godot/imported/Copy.glsl-04e877248c733e7d624480658e605c4c.res"]
[params]

View File

@ -0,0 +1,120 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
public class CEG_TextureCreator
{
public bool autoClean = true;
public void AutoClean( RDTexture texture, RenderingDevice rd )
{
if ( texture == null || ! autoClean )
{
return;
}
rd.FreeRid( texture.rid );
}
public virtual RDTexture Create( RDTexture texture, _XX_CompositorEffectGraph graph )
{
return texture;
}
}
public class CEG_TextureCreator_ScreenSize:CEG_TextureCreator
{
public RDTextureFormat format = RDTexture.DefaultFormat( -1, -1 );
public Vector2 scale = Vector2.One;
public override RDTexture Create( RDTexture texture, _XX_CompositorEffectGraph graph )
{
Vector2I scaledSize = (Vector2I) ( graph.context.internalSize * scale );
if ( texture == null || scaledSize != texture.size )
{
AutoClean( texture, graph.rd );
format = RDTexture.FormatChangeSize( format, scaledSize );
texture = RDTexture.Create( graph, format );
}
return texture;
}
}
public class CEG_TextureCreator_FixedSize:CEG_TextureCreator
{
public RDTextureFormat format = RDTexture.DefaultFormat( -1, -1 );
public override RDTexture Create( RDTexture texture, _XX_CompositorEffectGraph graph )
{
var formatSize = new Vector2I( (int) format.Width, (int) format.Height );
if ( texture == null || texture.size != formatSize )
{
AutoClean( texture, graph.rd );
texture = RDTexture.Create( graph, format );
}
return texture;
}
}
public class CEG_BufferTexture:CompositorEffectGraphProcessor, CompositorEffectGraphTextureSlotInput
{
RDTexture _texture;
CEG_TextureCreator _creator;
public RDTexture GetTexture()
{
return _texture;
}
public CompositorEffectGraphProcessor GetProcessor()
{
return this;
}
List<CompositorEffectGraphTextureSlot> _connectedSlots = new List<CompositorEffectGraphTextureSlot>();
public void SetConnected( CompositorEffectGraphTextureSlot slot )
{
_connectedSlots.Add( slot );
}
public CEG_BufferTexture( _XX_CompositorEffectGraph graph, CEG_TextureCreator creator ):base( graph )
{
_creator = creator;
}
public static CEG_BufferTexture ScreenSize( _XX_CompositorEffectGraph graph, Vector2? scale = null )
{
var screenSize = new CEG_TextureCreator_ScreenSize();
screenSize.scale = scale == null ? Vector2.One : (Vector2) scale;
return new CEG_BufferTexture( graph, screenSize );
}
public static CEG_BufferTexture FixedSize( _XX_CompositorEffectGraph graph )
{
return new CEG_BufferTexture( graph, new CEG_TextureCreator_FixedSize() );
}
public override void Process()
{
_texture = _creator.Create( _texture, graph );
}
public void ConnectTo( CompositorEffectGraphTextureSlot slot )
{
slot.SetInput( this );
}
}
}

View File

@ -0,0 +1,34 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
public class CEG_ImageProcessor:CompositorEffectShaderProcessor
{
public readonly CompositorEffectGraphTextureSlot input;
public readonly CompositorEffectGraphTextureSlot output;
public CEG_ImageProcessor( _XX_CompositorEffectGraph graph, string shaderPath ):base( graph, shaderPath )
{
input = new CompositorEffectGraphTextureSlot( this );
output = new CompositorEffectGraphTextureSlot( this );
_textureSlots.AddRange( new List<CompositorEffectGraphTextureSlot>{ input, output } );
}
public void SetTextureSlotInputs( CompositorEffectGraphTextureSlotInput inputSlot, CompositorEffectGraphTextureSlotInput outputSlot )
{
inputSlot.ConnectTo( input );
outputSlot.ConnectTo( output );
}
public void SetTextureSlotInputs( CEG_ImageProcessor imageProcessorBefore )
{
imageProcessorBefore.input.ConnectTo( input );
imageProcessorBefore.output.ConnectTo( output );
}
}
}

View File

@ -0,0 +1,42 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
public class CEG_ScreenColorTexure:CompositorEffectGraphProcessor, CompositorEffectGraphTextureSlotInput
{
RDTexture _texture;
public RDTexture GetTexture()
{
return _texture;
}
public CompositorEffectGraphProcessor GetProcessor()
{
return this;
}
List<CompositorEffectGraphTextureSlot> _connectedSlots = new List<CompositorEffectGraphTextureSlot>();
public void SetConnected( CompositorEffectGraphTextureSlot slot )
{
_connectedSlots.Add( slot );
}
public CEG_ScreenColorTexure( _XX_CompositorEffectGraph graph ):base( graph )
{}
public override void Process()
{
_texture = graph.context.GetScreenColorTexture();
}
public void ConnectTo( CompositorEffectGraphTextureSlot slot )
{
slot.SetInput( this );
}
}
}

View File

@ -0,0 +1,42 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
public class CEG_ScreenDepthTexture:CompositorEffectGraphProcessor, CompositorEffectGraphTextureSlotInput
{
RDTexture _texture;
public RDTexture GetTexture()
{
return _texture;
}
public CompositorEffectGraphProcessor GetProcessor()
{
return this;
}
List<CompositorEffectGraphTextureSlot> _connectedSlots = new List<CompositorEffectGraphTextureSlot>();
public void SetConnected( CompositorEffectGraphTextureSlot slot )
{
_connectedSlots.Add( slot );
}
public CEG_ScreenDepthTexture( _XX_CompositorEffectGraph graph ):base( graph )
{}
public override void Process()
{
_texture = graph.context.GetScreenDepthTexture();
}
public void ConnectTo( CompositorEffectGraphTextureSlot slot )
{
slot.SetInput( this );
}
}
}

View File

@ -0,0 +1,17 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
public class CEG_JFAInitialize:CEG_ImageProcessor
{
public static readonly string shaderPath =
_XX_CompositorEffectGraph.Path( "Nodes/Processors/JFA/JFA_Initialize.glsl" );
public CEG_JFAInitialize( _XX_CompositorEffectGraph graph ):base( graph, shaderPath )
{}
}
}

View File

@ -0,0 +1,17 @@
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
public class CEG_JFAIterate:CEG_ImageProcessor
{
public static readonly string shaderPath =
_XX_CompositorEffectGraph.Path( "Nodes/Processors/JFA/JFA_Iterate.glsl" );
public CEG_JFAIterate( _XX_CompositorEffectGraph graph ):base( graph, shaderPath )
{}
}
}

View File

@ -0,0 +1 @@
uid://dhgflubjnh736

View File

@ -0,0 +1,33 @@
#[compute]
#version 450
layout( local_size_x = 8, local_size_y = 8, local_size_z = 1 ) in;
layout( rgba16, set = 0, binding = 0 )
uniform restrict readonly image2D inputImage;
layout( rgba16, set = 1, binding = 0 )
uniform restrict writeonly image2D outputImage;
layout( push_constant, std430 )
uniform Params
{
float alphaTreshold;
} params;
void main()
{
ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy );
vec4 currentPixel = imageLoad( inputImage, currentPosition );
if ( currentPixel.a < params.alphaTreshold )
{
vec4 packedZero = vec4( unpackUnorm2x16( 0 ), unpackUnorm2x16( 0 ) );
imageStore( outputImage, currentPosition, packedZero );
return;
}
vec4 packedPosition = vec4( unpackUnorm2x16( currentPosition.x ), unpackUnorm2x16( currentPosition.y ) );
imageStore( outputImage, currentPosition, packedPosition);
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://diia0hlqqkna"
path="res://.godot/imported/JFA_Initialize.glsl-805a62d8bfe18f03d3fff707518fb98e.res"
[deps]
source_file="res://addons/rokojori_action_library/Runtime/Rendering/Objects/CompositorEffectGraph/Nodes/Processors/JFA/JFA_Initialize.glsl"
dest_files=["res://.godot/imported/JFA_Initialize.glsl-805a62d8bfe18f03d3fff707518fb98e.res"]
[params]

View File

@ -0,0 +1,61 @@
#[compute]
#version 450
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout(rgba16, set = 0, binding = 0)
uniform restrict readonly image2D inputImage;
layout(rgba16, set = 1, binding = 0)
uniform restrict writeonly image2D outputImage;
layout(std430, set = 2, binding = 0)
buffer restrict readonly JumpDistanceBuffer { int jump; } jdb;
void main()
{
ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy );
ivec2 imageSize = imageSize( inputImage );
float distanceToClosestSeed = 1.0f / 0.0f;
vec4 closestSeed = vec4( unpackUnorm2x16( 0 ), unpackUnorm2x16( 0 ) );
ivec2 jdbJump = ivec2( jdb.jump, jdb.jump );
for ( int x = -1; x <= 1; x++ )
{
for ( int y = -1; y <= 1; y++ )
{
ivec2 xy = ivec2( x, y );
ivec2 checkPosition = currentPosition + jdbJump * xy;
if ( checkPosition.x < 0 || checkPosition.y < 0 ||
checkPosition.x >= imageSize.x || checkPosition.y >= imageSize.y )
{
continue;
}
vec4 checkPixel = imageLoad( inputImage, checkPosition );
float checkSeedX = float( packUnorm2x16( checkPixel.xy ) );
float checkSeedY = float( packUnorm2x16( checkPixel.zw ) );
vec2 checkSeedPosition = vec2( checkSeedX, checkSeedY );
if ( checkSeedPosition.x == 0.0f && checkSeedPosition.y == 0.0f )
{
continue;
}
float distanceToSeed = distance( vec2( currentPosition ), checkSeedPosition );
if ( distanceToSeed < distanceToClosestSeed )
{
distanceToClosestSeed = distanceToSeed;
closestSeed = checkPixel;
}
}
}
imageStore( outputImage, currentPosition, closestSeed );
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://dntu82sa6clb4"
path="res://.godot/imported/JFA_Iterate.glsl-7375b6aced2100cd0023eb6c61803e61.res"
[deps]
source_file="res://addons/rokojori_action_library/Runtime/Rendering/Objects/CompositorEffectGraph/Nodes/Processors/JFA/JFA_Iterate.glsl"
dest_files=["res://.godot/imported/JFA_Iterate.glsl-7375b6aced2100cd0023eb6c61803e61.res"]
[params]

View File

@ -8,6 +8,45 @@ namespace Rokojori
[GlobalClass]
public partial class _XX_CompositorEffectGraph:RokojoriCompositorEffect
{
List<CompositorEffectGraphNode> _nodes;
public static readonly string path = "res://addons/rokojori_action_library/Runtime/Rendering/Objects/CompositorEffectGraph";
public static string Path( string subPath )
{
return path + "/" + subPath;
}
protected List<CompositorEffectGraphNode> _nodes = new List<CompositorEffectGraphNode>();
protected List<CompositorEffectGraphProcessor> _processors = new List<CompositorEffectGraphProcessor>();
protected List<CompositorEffectGraphProcessor> _processOrder = new List<CompositorEffectGraphProcessor>();
protected void SetProcessOrder( List<CompositorEffectGraphProcessor> order )
{
_processOrder.Clear();
_processOrder.AddRange( order );
}
protected void SetProcessOrder( params CompositorEffectGraphProcessor[] order )
{
_processOrder.Clear();
_processOrder.AddRange( order );
}
protected override void RenderView()
{
OnPreProcess();
_processOrder.ForEach( p => p.Process() );
OnPostProcess();
}
protected virtual void OnPreProcess()
{
}
protected virtual void OnPostProcess()
{
}
}
}

View File

@ -25,5 +25,91 @@ namespace Rokojori
return new RDTexture( context.effect, rid );
}
public RDTextureFormat format
{
get
{
return effect.rd.TextureGetFormat( rid );
}
}
public Vector2I size
{
get
{
var textureFormat = format;
return new Vector2I( (int) textureFormat.Width, (int) textureFormat.Height );
}
}
public static RDTexture Create( RokojoriCompositorEffect effect, RDTextureFormat format )
{
var view = new RDTextureView();
var rid = effect.rd.TextureCreate( format, view );
return new RDTexture( effect, rid );
}
public static RDTextureFormat DefaultFormat( int w, int h, RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Unorm )
{
var format = new RDTextureFormat();
format.Width = (uint) w;
format.Height = (uint) h;
format.Format = dataFormat;
format.UsageBits = RenderingDevice.TextureUsageBits.StorageBit | RenderingDevice.TextureUsageBits.SamplingBit;
return format;
}
public static RDTextureFormat FormatChangeSize( RDTextureFormat tf, Vector2I size )
{
return FormatChangeSize( tf, size.X, size.Y );
}
public static RDTextureFormat FormatChangeSize( RDTextureFormat tf, int w, int h )
{
var clone = FormatCopy( tf );
clone.Width = (uint) w;
clone.Height = (uint) h;
return clone;
}
public static RDTextureFormat FormatCopy( RDTextureFormat tf )
{
var format = new RDTextureFormat();
format.Format = tf.Format;
format.Width = tf.Width;
format.Height = tf.Height;
format.Depth = tf.Depth;
format.ArrayLayers = tf.ArrayLayers;
format.Mipmaps = tf.Mipmaps;
format.TextureType = tf.TextureType;
format.Samples = tf.Samples;
format.UsageBits = tf.UsageBits;
format.IsResolveBuffer = tf.IsResolveBuffer;
format.IsDiscardable = tf.IsDiscardable;
return tf;
}
public static RDTexture Create( RokojoriCompositorEffect effect, Vector2I size, RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Unorm )
{
return Create( effect, size.X, size.Y, dataFormat );
}
public static RDTexture Create( RokojoriCompositorEffect effect, int width, int height,
RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Unorm )
{
var view = new RDTextureView();
var format = DefaultFormat( width, height, dataFormat );
var rid = effect.rd.TextureCreate( format, view );
return new RDTexture( effect, rid );
}
}
}

View File

@ -101,6 +101,27 @@ namespace Rokojori
pushConstants = null;
}
public void SetGroups( Vector3I groups )
{
this._groups = groups;
}
public void ComputeGroups( int groupSize )
{
ComputeGroups( new Vector3I( groupSize, groupSize, 0 ) );
}
public void ComputeGroups( Vector3I groupSize )
{
var size = sceneBuffers.GetInternalSize();
var xGroups = Mathf.CeilToInt( size.X / (float) groupSize.X );
var yGroups = groupSize.Y == 0 ? 1 : Mathf.CeilToInt( size.Y / (float) groupSize.Y );
var zGroups = groupSize.Z == 0 ? 1 : Mathf.CeilToInt( size.Y / (float) groupSize.Y );
SetGroups( new Vector3I( xGroups, yGroups, zGroups ) );
}
public void Render()
{
try
@ -159,9 +180,6 @@ namespace Rokojori
this._view = view;
}
public void SetGroups( Vector3I groups )
{
this._groups = groups;
}
}
}

View File

@ -11,7 +11,7 @@ namespace Rokojori
protected RenderingDevice _rd;
public RenderingDevice rd => _rd;
protected int _groupSize = 16;
protected List<RenderingObject> _cleanUps = new List<RenderingObject>();
protected List<string> _cleanUpInfo = new List<string>();
@ -87,13 +87,14 @@ namespace Rokojori
_context.SetRenderData( renderData, sceneBuffers, sceneData );
_context.SetView( -1 );
_context.SetGroups( new Vector3I( 1, 1, 1 ) );
_hasContext = true;
var groups = ComputeGroups();
_context.SetGroups( groups );
// var groups = ComputeGroups();
// _context.SetGroups( groups );
ForAllViews();
@ -110,15 +111,7 @@ namespace Rokojori
_hasContext = false;
}
protected virtual Vector3I ComputeGroups()
{
var size = context.sceneBuffers.GetInternalSize();
var xGroups = Mathf.CeilToInt( size.X / (float) _groupSize );
var yGroups = Mathf.CeilToInt( size.Y / (float) _groupSize );
return new Vector3I( xGroups, yGroups, 1 );
}
public override void _Notification( int what )

View File

@ -12,6 +12,7 @@ namespace Rokojori
protected RDShader _shader;
protected RDPipeline _pipeline;
protected int _groupSize = 16;
protected override void OnInitialize()
{
@ -52,5 +53,20 @@ namespace Rokojori
context.SetShaderAndPipeline( _shader, _pipeline );
}
protected RDPushConstants _constants = new RDPushConstants();
public RDPushConstants constants => _constants;
protected override void ForAllViews()
{
context.ComputeGroups( _groupSize );
SetConstants();
}
protected virtual void SetConstants()
{
}
}
}