JFA Texture Dilation Working
This commit is contained in:
parent
66d24be2c1
commit
7b68cc7f1f
|
@ -42,6 +42,27 @@ namespace Rokojori
|
||||||
return MathX.Clamp01( f );
|
return MathX.Clamp01( f );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Color Gamma( this Color color, float gamma )
|
||||||
|
{
|
||||||
|
return new Color(
|
||||||
|
Mathf.Pow( color.R, gamma ),
|
||||||
|
Mathf.Pow( color.G, gamma ),
|
||||||
|
Mathf.Pow( color.B, gamma ),
|
||||||
|
color.A
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color linearToSRGB( this Color color )
|
||||||
|
{
|
||||||
|
return color.Gamma( 1.0f / 2.2f );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color srgbToLinear( this Color color )
|
||||||
|
{
|
||||||
|
return color.Gamma( 2.2f );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Color Blend( Color bottom, Color top )
|
public static Color Blend( Color bottom, Color top )
|
||||||
{
|
{
|
||||||
var fade = ( 1f - top.A );
|
var fade = ( 1f - top.A );
|
||||||
|
|
|
@ -210,6 +210,11 @@ namespace Rokojori
|
||||||
LogMessage( GetLogString( objects ) );
|
LogMessage( GetLogString( objects ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void LogWithTraceOffset( int offset, params object[] objects )
|
||||||
|
{
|
||||||
|
LogMessage( GetLogString( objects ), 3 + offset );
|
||||||
|
}
|
||||||
|
|
||||||
public static void Log( Node node, params object[] objects)
|
public static void Log( Node node, params object[] objects)
|
||||||
{
|
{
|
||||||
LogMessage( "[color=#55aaff]" + HierarchyName.Of( node ) + "[/color]\n" + GetLogString( objects ), 4 );
|
LogMessage( "[color=#55aaff]" + HierarchyName.Of( node ) + "[/color]\n" + GetLogString( objects ), 4 );
|
||||||
|
@ -225,7 +230,7 @@ namespace Rokojori
|
||||||
LogErrorMessage( GetLogString( objects ) );
|
LogErrorMessage( GetLogString( objects ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ErrorFull( params object[] objects)
|
public static void ErrorWithFullTrace( params object[] objects)
|
||||||
{
|
{
|
||||||
LogErrorWithFullTrace( GetLogString( objects ) );
|
LogErrorWithFullTrace( GetLogString( objects ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,21 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public MeshInstance3D meshInstance3D;
|
public MeshInstance3D meshInstance3D;
|
||||||
|
|
||||||
|
[Export( PropertyHint.Range, "0,1" ) ]
|
||||||
|
public float intensity;
|
||||||
|
|
||||||
|
[Export( PropertyHint.Range, "0,100" ) ]
|
||||||
|
public float noise;
|
||||||
|
|
||||||
|
[Export( PropertyHint.Range, "1,100" ) ]
|
||||||
|
public float kernelOffset;
|
||||||
|
|
||||||
|
[Export( PropertyHint.Range, "1,50" ) ]
|
||||||
|
public float kernelRadius;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[ExportToolButton( "Grab Texture")]
|
[ExportToolButton( "Grab Texture")]
|
||||||
public Callable GrabButton => Callable.From(
|
public Callable GrabButton => Callable.From(
|
||||||
|
@ -41,9 +56,6 @@ namespace Rokojori
|
||||||
viewport.RenderTargetUpdateMode = updateMode;
|
viewport.RenderTargetUpdateMode = updateMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var viewPortFormat = RDTextureFormats.GetDataFormat( viewport );
|
var viewPortFormat = RDTextureFormats.GetDataFormat( viewport );
|
||||||
var viewPortData = viewport.GetTexture().GetImage().GetData();
|
var viewPortData = viewport.GetTexture().GetImage().GetData();
|
||||||
var viewPortSize = viewport.Size;
|
var viewPortSize = viewport.Size;
|
||||||
|
@ -63,23 +75,27 @@ namespace Rokojori
|
||||||
var inputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
|
var inputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
|
||||||
inputTexture.SetData( viewPortData );
|
inputTexture.SetData( viewPortData );
|
||||||
|
|
||||||
|
this.LogInfo( "Creating graph" );
|
||||||
|
|
||||||
var graph = CreateGraph( ctx, inputTexture, outputTexture );
|
var graph = CreateGraph( ctx, inputTexture, outputTexture );
|
||||||
|
|
||||||
|
this.LogInfo( "Process graph" );
|
||||||
graph.ProcessForView();
|
graph.ProcessForView();
|
||||||
|
|
||||||
ctx.SubmitAndSync();
|
ctx.SubmitAndSync();
|
||||||
|
|
||||||
var width = outputTexture.width;
|
var width = inputTexture.width;
|
||||||
var height = outputTexture.height;
|
var height = inputTexture.height;
|
||||||
var format = outputTexture.imageFormat;
|
var format = inputTexture.imageFormat;
|
||||||
|
|
||||||
var data = outputTexture.GetData();
|
var data = inputTexture.GetData();
|
||||||
|
|
||||||
this.LogInfo( "Copying texture" );
|
|
||||||
|
|
||||||
ctx.SubmitAndSync();
|
ctx.SubmitAndSync();
|
||||||
await this.RequestNextFrame();
|
await this.RequestNextFrame();
|
||||||
|
|
||||||
|
|
||||||
|
this.LogInfo( "Copying texture" );
|
||||||
|
|
||||||
var image = Image.CreateFromData( width, height, false, format, data );
|
var image = Image.CreateFromData( width, height, false, format, data );
|
||||||
var buffer = TextureCombinerBuffer.From( ImageTexture.CreateFromImage( image ) );
|
var buffer = TextureCombinerBuffer.From( ImageTexture.CreateFromImage( image ) );
|
||||||
|
|
||||||
|
@ -93,9 +109,6 @@ namespace Rokojori
|
||||||
await this.RequestNextFrame();
|
await this.RequestNextFrame();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RDGraph CreateGraph( RDContext ctx, RDTexture it, RDTexture ot )
|
RDGraph CreateGraph( RDContext ctx, RDTexture it, RDTexture ot )
|
||||||
|
@ -106,27 +119,27 @@ namespace Rokojori
|
||||||
var bufferTexture = CEG_BufferTexture.From( graph, ot );
|
var bufferTexture = CEG_BufferTexture.From( graph, ot );
|
||||||
|
|
||||||
var copy = new CEG_Copy( graph );
|
var copy = new CEG_Copy( graph );
|
||||||
var radialBlur = new CEG_RadialBlur( graph );
|
var blur = new RD_BoxBlur( graph );
|
||||||
|
|
||||||
graph.InitializeNodes();
|
graph.InitializeNodes();
|
||||||
|
|
||||||
copy.SetTextureSlotInputs( viewTexture, bufferTexture );
|
copy.SetTextureSlotInputs( viewTexture, bufferTexture );
|
||||||
radialBlur.SetTextureSlotInputs( copy.output, copy.input );
|
blur.SetTextureSlotInputs( copy.output, copy.input );
|
||||||
|
|
||||||
|
|
||||||
graph.SetProcessOrder(
|
graph.SetProcessOrder(
|
||||||
viewTexture, bufferTexture,
|
viewTexture, bufferTexture,
|
||||||
copy, radialBlur
|
copy, blur
|
||||||
);
|
);
|
||||||
|
|
||||||
radialBlur.constants.Set(
|
blur.constants.Set(
|
||||||
new Vector2( 0.5f, 0.5f ),
|
intensity,
|
||||||
0.5f,
|
noise,
|
||||||
0.5f,
|
kernelOffset,
|
||||||
16,
|
kernelRadius
|
||||||
Vector2.Zero
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ctx.Verbose( "Radial Blur constants:", blur.constants.size );
|
||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,9 @@ namespace Rokojori
|
||||||
[Export]
|
[Export]
|
||||||
public TextureMerger X_textureMerger;
|
public TextureMerger X_textureMerger;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public TextureDilate X_textureDilate;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public SetBakingMaterials X_setBakingMaterials;
|
public SetBakingMaterials X_setBakingMaterials;
|
||||||
|
|
||||||
|
@ -159,6 +162,7 @@ namespace Rokojori
|
||||||
public Texture2D X_bakedTextureDepth;
|
public Texture2D X_bakedTextureDepth;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public bool X_baking = false;
|
public bool X_baking = false;
|
||||||
|
|
||||||
|
@ -196,6 +200,9 @@ namespace Rokojori
|
||||||
X_textureMerger.dilationRadius = dilationRadius;
|
X_textureMerger.dilationRadius = dilationRadius;
|
||||||
X_textureMerger.Initialize();
|
X_textureMerger.Initialize();
|
||||||
|
|
||||||
|
X_textureDilate = this.CreateChild<TextureDilate>( "Texture Dilate" );
|
||||||
|
X_textureDilate.viewport = X_textureMerger.X_textureMergerViewport;
|
||||||
|
|
||||||
X_outputMesh = this.CreateChild<MeshInstance3D>( "Output Mesh" );
|
X_outputMesh = this.CreateChild<MeshInstance3D>( "Output Mesh" );
|
||||||
|
|
||||||
X_texturePreview = this.CreateChild<MeshInstance3D>( "Texture Preview" );
|
X_texturePreview = this.CreateChild<MeshInstance3D>( "Texture Preview" );
|
||||||
|
@ -303,13 +310,14 @@ namespace Rokojori
|
||||||
|
|
||||||
await this.RequestNextFrame();
|
await this.RequestNextFrame();
|
||||||
|
|
||||||
Texture2D texture = X_textureMerger.X_textureMergerViewport.GetTexture();
|
// Texture2D texture = X_textureMerger.X_textureMergerViewport.GetTexture();
|
||||||
|
|
||||||
this.LogInfo( "Texture created:", bakingMaterialModes[ i ] );
|
// this.LogInfo( "Texture created:", bakingMaterialModes[ i ] );
|
||||||
|
|
||||||
await this.RequestNextFrame();
|
// await this.RequestNextFrame();
|
||||||
|
|
||||||
texture = await CPUTextureDilater.Dilate( texture, this.RequestNextFrame );
|
X_textureDilate.viewport = X_textureMerger.X_textureMergerViewport;
|
||||||
|
Texture2D texture = await X_textureDilate.Grab();
|
||||||
|
|
||||||
|
|
||||||
this.LogInfo( "Assigning Texture", bakingMaterialModes[ i ] );
|
this.LogInfo( "Assigning Texture", bakingMaterialModes[ i ] );
|
||||||
|
|
|
@ -0,0 +1,184 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class TextureDilate:SequenceAction
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public SubViewport viewport;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Texture2D target;
|
||||||
|
|
||||||
|
[Export( PropertyHint.Range, "0,15" ) ]
|
||||||
|
public int steps = 0;
|
||||||
|
|
||||||
|
[ExportToolButton( "Grab Texture")]
|
||||||
|
public Callable GrabButton => Callable.From(
|
||||||
|
() =>
|
||||||
|
{
|
||||||
|
Grab();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
public async Task<Texture2D> Grab()
|
||||||
|
{
|
||||||
|
var updateMode = viewport.RenderTargetUpdateMode;
|
||||||
|
|
||||||
|
if ( updateMode != SubViewport.UpdateMode.Always )
|
||||||
|
{
|
||||||
|
viewport.RenderTargetUpdateMode = SubViewport.UpdateMode.Always;
|
||||||
|
await this.RequestNextFrame();
|
||||||
|
viewport.RenderTargetUpdateMode = updateMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
var viewPortFormat = RDTextureFormats.GetDataFormat( viewport );
|
||||||
|
var viewPortData = viewport.GetTexture().GetImage().GetData();
|
||||||
|
var viewPortSize = viewport.Size;
|
||||||
|
|
||||||
|
this.LogInfo( "Grabbed viewport context", viewPortFormat, viewPortSize );
|
||||||
|
|
||||||
|
this.LogInfo( "Creating context" );
|
||||||
|
var ctx = RDContext.Local();
|
||||||
|
ctx.computeSize = viewPortSize;
|
||||||
|
ctx.messageLogLevel = Messages.GetLevel( MessageType.Verbose );
|
||||||
|
|
||||||
|
|
||||||
|
this.LogInfo( "Creating textures" );
|
||||||
|
|
||||||
|
var bufferTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
|
||||||
|
var bufferTexture2 = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
|
||||||
|
var resultTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
|
||||||
|
var initTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
|
||||||
|
|
||||||
|
|
||||||
|
var inputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
|
||||||
|
inputTexture.SetData( viewPortData );
|
||||||
|
|
||||||
|
this.LogInfo( "Creating graph" );
|
||||||
|
|
||||||
|
var graph = CreateGraph( ctx, inputTexture, initTexture, bufferTexture, bufferTexture2, resultTexture );
|
||||||
|
|
||||||
|
this.LogInfo( "Process graph" );
|
||||||
|
graph.ProcessForView();
|
||||||
|
|
||||||
|
ctx.SubmitAndSync();
|
||||||
|
|
||||||
|
var exportTexture = resultTexture;
|
||||||
|
var width = exportTexture.width;
|
||||||
|
var height = exportTexture.height;
|
||||||
|
var format = exportTexture.imageFormat;
|
||||||
|
|
||||||
|
var data = exportTexture.GetData();
|
||||||
|
|
||||||
|
ctx.SubmitAndSync();
|
||||||
|
await this.RequestNextFrame();
|
||||||
|
|
||||||
|
|
||||||
|
this.LogInfo( "Copying texture:", format );
|
||||||
|
|
||||||
|
var image = Image.CreateFromData( width, height, false, format, data );
|
||||||
|
|
||||||
|
var gammaConversion = 0;
|
||||||
|
|
||||||
|
if ( RenderingDevice.DataFormat.R16G16B16A16Sfloat == viewPortFormat )
|
||||||
|
{
|
||||||
|
gammaConversion = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var buffer = TextureCombinerBuffer.From( ImageTexture.CreateFromImage( image ), gammaConversion );
|
||||||
|
var texture = buffer.CreateImageTexture();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
target = texture;
|
||||||
|
|
||||||
|
ctx.CleanUp();
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
RDGraph CreateGraph( RDContext ctx, RDTexture it, RDTexture ii, RDTexture b1, RDTexture b2, RDTexture rt )
|
||||||
|
{
|
||||||
|
var graph = new RDGraph( ctx );
|
||||||
|
|
||||||
|
var viewTexture = CEG_BufferTexture.From( graph, it );
|
||||||
|
var initTexture = CEG_BufferTexture.From( graph, ii );
|
||||||
|
var bufferTexture = CEG_BufferTexture.From( graph, b1 );
|
||||||
|
var bufferTexture2 = CEG_BufferTexture.From( graph, b2 );
|
||||||
|
var resultTexture = CEG_BufferTexture.From( graph, rt );
|
||||||
|
|
||||||
|
ctx.Verbose( "Init Texture:", initTexture.GetTexture() );
|
||||||
|
|
||||||
|
var jfaInititialize = new CEG_JFAInitialize( graph );
|
||||||
|
jfaInititialize.constants.Set( 0.5f );
|
||||||
|
|
||||||
|
var copy = new CEG_Copy( graph );
|
||||||
|
var jfaIterate = new CEG_JFAIterate( graph );
|
||||||
|
var jfaAssign = new CEG_JFAAssign( graph );
|
||||||
|
var repeat = new RG_SwapRepeat( graph );
|
||||||
|
|
||||||
|
var numSteps = steps == 0 ?
|
||||||
|
( Mathf.RoundToInt( MathX.Exponent( 2, it.maxDimension ) ) - 1 ) :
|
||||||
|
steps;
|
||||||
|
|
||||||
|
RJLog.Log( "Steps >>", numSteps, Mathf.Pow( 2, numSteps ) );
|
||||||
|
|
||||||
|
repeat.repeats = numSteps;
|
||||||
|
repeat.imageProcessor = jfaIterate;
|
||||||
|
|
||||||
|
repeat.onPreProcess =
|
||||||
|
( index ) =>
|
||||||
|
{
|
||||||
|
var stepIndex = numSteps - ( index + 1 );
|
||||||
|
var jump = Mathf.RoundToInt( Mathf.Pow( 2, stepIndex ) );
|
||||||
|
|
||||||
|
this.LogInfo( "Jump:", jump );
|
||||||
|
jfaIterate.constants.Set(
|
||||||
|
jump
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
graph.InitializeNodes();
|
||||||
|
|
||||||
|
|
||||||
|
jfaInititialize.SetTextureSlotInputs( viewTexture, initTexture );
|
||||||
|
copy.SetTextureSlotInputs( initTexture, bufferTexture );
|
||||||
|
repeat.SetTextureSlotInputs( bufferTexture, bufferTexture2 );
|
||||||
|
|
||||||
|
var assignTexture = steps % 2 == 0 ? bufferTexture : bufferTexture2;
|
||||||
|
jfaAssign.SetTextureSlotInputs( assignTexture, resultTexture );
|
||||||
|
jfaAssign.AddTextureSlotInput( viewTexture );
|
||||||
|
|
||||||
|
graph.SetProcessOrder(
|
||||||
|
viewTexture,
|
||||||
|
bufferTexture,
|
||||||
|
bufferTexture2,
|
||||||
|
initTexture,
|
||||||
|
resultTexture,
|
||||||
|
jfaInititialize,
|
||||||
|
copy,
|
||||||
|
repeat,
|
||||||
|
jfaAssign
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
uid://bfiqjmyt04ils
|
|
@ -122,6 +122,7 @@ namespace Rokojori
|
||||||
X_textureMergerViewport.Size = (Vector2I) textureSize;
|
X_textureMergerViewport.Size = (Vector2I) textureSize;
|
||||||
X_textureMergerViewport.OwnWorld3D = true;
|
X_textureMergerViewport.OwnWorld3D = true;
|
||||||
X_textureMergerViewport.TransparentBg = true;
|
X_textureMergerViewport.TransparentBg = true;
|
||||||
|
X_textureMergerViewport.UseHdr2D = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,10 @@ namespace Rokojori
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextureCombinerBuffer From( Texture2D texture )
|
public static TextureCombinerBuffer From( Texture2D texture, int srgbConversion = 0)
|
||||||
{
|
{
|
||||||
var buffer = Create( texture.GetWidth(), texture.GetHeight() );
|
var buffer = Create( texture.GetWidth(), texture.GetHeight() );
|
||||||
buffer.CopyFrom( texture.GetImage(), 0, 0, 0, 0, texture.GetWidth(), texture.GetHeight() );
|
buffer.CopyFrom( texture.GetImage(), 0, 0, 0, 0, texture.GetWidth(), texture.GetHeight(), srgbConversion );
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,24 @@ namespace Rokojori
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyFrom( Image image, int sourceX, int sourceY, int ownX, int ownY, int w, int h )
|
public void CopyFrom( Image image, int sourceX, int sourceY, int ownX, int ownY, int w, int h, int srgbConversion = 0 )
|
||||||
|
{
|
||||||
|
if ( srgbConversion != 0 )
|
||||||
|
{
|
||||||
|
var gamma = Mathf.Pow( 2.2f, srgbConversion );
|
||||||
|
|
||||||
|
for ( int i = 0; i < w; i++ )
|
||||||
|
{
|
||||||
|
for ( int j = 0; j < h; j++ )
|
||||||
|
{
|
||||||
|
var sourcePixel = image == null ? new Color( 0, 0, 0 ) : image.GetPixel( sourceX + i, sourceY + j );
|
||||||
|
sourcePixel = sourcePixel.Gamma( gamma );
|
||||||
|
SetAt( ownX + i, ownY + j, sourcePixel );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
for ( int i = 0; i < w; i++ )
|
for ( int i = 0; i < w; i++ )
|
||||||
|
@ -81,12 +98,12 @@ namespace Rokojori
|
||||||
for ( int j = 0; j < h; j++ )
|
for ( int j = 0; j < h; j++ )
|
||||||
{
|
{
|
||||||
var sourcePixel = image == null ? new Color( 0, 0, 0 ) : image.GetPixel( sourceX + i, sourceY + j );
|
var sourcePixel = image == null ? new Color( 0, 0, 0 ) : image.GetPixel( sourceX + i, sourceY + j );
|
||||||
|
|
||||||
SetAt( ownX + i, ownY + j, sourcePixel );
|
SetAt( ownX + i, ownY + j, sourcePixel );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void CopyTo( int ownX, int ownY, int targetX, int targetY, int w, int h, TextureCombinerBuffer output )
|
public void CopyTo( int ownX, int ownY, int targetX, int targetY, int w, int h, TextureCombinerBuffer output )
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
|
||||||
|
using Godot;
|
||||||
|
using Godot.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class BoxBlurEffect:RDGraphCompositorEffect
|
||||||
|
{
|
||||||
|
public BoxBlurEffect():base()
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Export( PropertyHint.Range, "0,1")]
|
||||||
|
public float intensity = 1f;
|
||||||
|
|
||||||
|
[Export( PropertyHint.Range, "0,100")]
|
||||||
|
public float noise = 0f;
|
||||||
|
|
||||||
|
[Export( PropertyHint.Range, "1,100")]
|
||||||
|
public int kernelOffset = 5;
|
||||||
|
|
||||||
|
[Export( PropertyHint.Range, "1,30")]
|
||||||
|
public int kernelRadius = 2;
|
||||||
|
|
||||||
|
[Export( PropertyHint.Range, "1,4")]
|
||||||
|
public int iterations = 1;
|
||||||
|
|
||||||
|
|
||||||
|
CEG_ScreenColorTexure screenColorTexture;
|
||||||
|
CEG_BufferTexture bufferTexture;
|
||||||
|
|
||||||
|
CEG_Copy copy;
|
||||||
|
CEG_Copy copy2;
|
||||||
|
RD_BoxBlur boxBlur;
|
||||||
|
RD_BoxBlur boxBlur1;
|
||||||
|
RD_BoxBlur boxBlur2;
|
||||||
|
RD_BoxBlur boxBlur3;
|
||||||
|
|
||||||
|
List<RD_BoxBlur> _blurs;
|
||||||
|
|
||||||
|
void Initialize()
|
||||||
|
{
|
||||||
|
screenColorTexture = new CEG_ScreenColorTexure( graph );
|
||||||
|
bufferTexture = CEG_BufferTexture.ScreenSize( graph );
|
||||||
|
|
||||||
|
copy = new CEG_Copy( graph );
|
||||||
|
copy2 = new CEG_Copy( graph );
|
||||||
|
boxBlur = new RD_BoxBlur( graph );
|
||||||
|
boxBlur1 = new RD_BoxBlur( graph );
|
||||||
|
boxBlur2 = new RD_BoxBlur( graph );
|
||||||
|
boxBlur3 = new RD_BoxBlur( graph );
|
||||||
|
|
||||||
|
_blurs = new List<RD_BoxBlur>()
|
||||||
|
{
|
||||||
|
boxBlur, boxBlur1, boxBlur2, boxBlur3
|
||||||
|
};
|
||||||
|
|
||||||
|
graph.InitializeNodes();
|
||||||
|
|
||||||
|
copy.SetTextureSlotInputs( screenColorTexture, bufferTexture );
|
||||||
|
boxBlur.SetTextureSlotInputs( copy.output, copy.input );
|
||||||
|
boxBlur1.SetTextureSlotInputs( boxBlur.output, boxBlur.input );
|
||||||
|
boxBlur2.SetTextureSlotInputs( boxBlur1.output, boxBlur1.input );
|
||||||
|
boxBlur3.SetTextureSlotInputs( boxBlur2.output, boxBlur2.input );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int _lastIterations = -1;
|
||||||
|
|
||||||
|
|
||||||
|
protected override void ForAllViews()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
SetOrderForIterations();
|
||||||
|
|
||||||
|
_blurs.ForEach(
|
||||||
|
blur =>
|
||||||
|
{
|
||||||
|
blur.constants.Set(
|
||||||
|
intensity,
|
||||||
|
noise,
|
||||||
|
(float)kernelOffset,
|
||||||
|
(float)kernelRadius
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetOrderForIterations()
|
||||||
|
{
|
||||||
|
iterations = Mathf.Clamp( iterations, 1, _blurs.Count );
|
||||||
|
|
||||||
|
if ( _lastIterations == iterations )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var list = new List<RGGraphProcessor>
|
||||||
|
{
|
||||||
|
screenColorTexture,
|
||||||
|
bufferTexture,
|
||||||
|
copy
|
||||||
|
};
|
||||||
|
|
||||||
|
for ( int i = 0; i < iterations; i++ )
|
||||||
|
{
|
||||||
|
list.Add( _blurs[ i ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( iterations % 2 == 0 )
|
||||||
|
{
|
||||||
|
var lastBlur = _blurs[ iterations - 1 ];
|
||||||
|
copy2.SetTextureSlotInputs( lastBlur.output, lastBlur.input );
|
||||||
|
list.Add( copy2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastIterations = iterations;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
graph.SetProcessOrder( list );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
uid://dqsxgtt4e6vwu
|
|
@ -25,7 +25,7 @@ namespace Rokojori
|
||||||
|
|
||||||
if ( logMessages )
|
if ( logMessages )
|
||||||
{
|
{
|
||||||
RJLog.ErrorFull( message );
|
RJLog.ErrorWithFullTrace( message );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ namespace Rokojori
|
||||||
|
|
||||||
if ( logMessages && Messages.GetLevel( MessageType.Warning ) >= messageLogLevel )
|
if ( logMessages && Messages.GetLevel( MessageType.Warning ) >= messageLogLevel )
|
||||||
{
|
{
|
||||||
RJLog.ErrorFull( message );
|
RJLog.ErrorWithFullTrace( message );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ namespace Rokojori
|
||||||
|
|
||||||
if ( logMessages && Messages.GetLevel( MessageType.Info ) >= messageLogLevel )
|
if ( logMessages && Messages.GetLevel( MessageType.Info ) >= messageLogLevel )
|
||||||
{
|
{
|
||||||
RJLog.Log( message );
|
RJLog.LogWithTraceOffset( 1, message );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ namespace Rokojori
|
||||||
|
|
||||||
if ( logMessages && Messages.GetLevel( MessageType.Verbose ) >= messageLogLevel )
|
if ( logMessages && Messages.GetLevel( MessageType.Verbose ) >= messageLogLevel )
|
||||||
{
|
{
|
||||||
RJLog.Log( message );
|
RJLog.LogWithTraceOffset( 1, message );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,6 +107,19 @@ namespace Rokojori
|
||||||
AssignTexture( GetScreenDepthTexture(), sampler, setIndex );
|
AssignTexture( GetScreenDepthTexture(), sampler, setIndex );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RDTexture _missingTexture = null;
|
||||||
|
Vector2I _missingTextureSize = new Vector2I( 64, 64 );
|
||||||
|
|
||||||
|
public void AssignMissingTexture( RDSampler sampler = null, int setIndex = -1 )
|
||||||
|
{
|
||||||
|
if ( _missingTexture == null )
|
||||||
|
{
|
||||||
|
_missingTexture = RDTexture.Create( this, _missingTextureSize, RenderingDevice.DataFormat.R16G16B16A16Sfloat );
|
||||||
|
_missingTexture.SetData( new Color( 1, 0, 1, 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
AssignTexture( _missingTexture, sampler, setIndex );
|
||||||
|
}
|
||||||
|
|
||||||
public void AssignTexture( RDTexture texture, RDSampler sampler = null, int setIndex = -1 )
|
public void AssignTexture( RDTexture texture, RDSampler sampler = null, int setIndex = -1 )
|
||||||
{
|
{
|
||||||
|
@ -263,6 +276,7 @@ namespace Rokojori
|
||||||
|
|
||||||
if ( pushConstants != null )
|
if ( pushConstants != null )
|
||||||
{
|
{
|
||||||
|
Verbose( "Set constants", pushConstants.size );
|
||||||
computeList.SetPushConstants( pushConstants );
|
computeList.SetPushConstants( pushConstants );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,8 @@ namespace Rokojori
|
||||||
_AddVector4( (Vector4) objects[ i ] );
|
_AddVector4( (Vector4) objects[ i ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void _AddFloat( float value )
|
protected void _AddFloat( float value )
|
||||||
|
@ -85,7 +87,7 @@ namespace Rokojori
|
||||||
if ( _intIndex >= _ints.Count )
|
if ( _intIndex >= _ints.Count )
|
||||||
{
|
{
|
||||||
_ints.Add( value );
|
_ints.Add( value );
|
||||||
_intIndex = _floats.Count;
|
_intIndex = _ints.Count;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -217,9 +219,9 @@ namespace Rokojori
|
||||||
Array.Copy( intBytes, 0, _bytes, i * 4 + floatsOffset, 4 );
|
Array.Copy( intBytes, 0, _bytes, i * 4 + floatsOffset, 4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
var intsOffset = _ints.Count * 4;
|
var intsOffset = floatsOffset + _ints.Count * 4;
|
||||||
|
|
||||||
for ( int i = intsOffset + floatsOffset; i < _bytes.Length; i++ )
|
for ( int i = intsOffset; i < _bytes.Length; i++ )
|
||||||
{
|
{
|
||||||
_bytes[ i ] = 0;
|
_bytes[ i ] = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,7 @@ namespace Rokojori
|
||||||
|
|
||||||
public int width => (int) format.Width;
|
public int width => (int) format.Width;
|
||||||
public int height => (int) format.Height;
|
public int height => (int) format.Height;
|
||||||
|
public int maxDimension => Mathf.RoundToInt( Mathf.Max( width, height ) );
|
||||||
|
|
||||||
public RenderingDevice.DataFormat dataFormat => format.Format;
|
public RenderingDevice.DataFormat dataFormat => format.Format;
|
||||||
public Image.Format imageFormat => RDTextureFormats.DataFormatToImageFormat( dataFormat );
|
public Image.Format imageFormat => RDTextureFormats.DataFormatToImageFormat( dataFormat );
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
#[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 Parameters
|
||||||
|
{
|
||||||
|
float intensity;
|
||||||
|
float noise;
|
||||||
|
float kernelOffset;
|
||||||
|
float kernelRadius;
|
||||||
|
|
||||||
|
} parameters;
|
||||||
|
|
||||||
|
|
||||||
|
float randomFloat( vec2 uv )
|
||||||
|
{
|
||||||
|
return fract( sin( dot( uv.xy, vec2( 12.9898,78.233 ) ) ) * 43758.5453123 );
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 random( vec2 uv )
|
||||||
|
{
|
||||||
|
float x = randomFloat( uv );
|
||||||
|
float y = randomFloat( uv + vec2( 10002, -23589 ) );
|
||||||
|
|
||||||
|
return vec2( x, y ) * 2.0 - vec2( 1.0, 1.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void main( )
|
||||||
|
{
|
||||||
|
ivec2 size = imageSize( inputImage );
|
||||||
|
ivec2 pixelUV = ivec2( gl_GlobalInvocationID.xy );
|
||||||
|
|
||||||
|
if ( any( greaterThanEqual( pixelUV, size ) ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 color = vec4( 0.0 );
|
||||||
|
|
||||||
|
int kernelRadius = int( parameters.kernelRadius );
|
||||||
|
int kernelOffset = int( parameters.kernelOffset );
|
||||||
|
|
||||||
|
if ( parameters.noise > 0.0 )
|
||||||
|
{
|
||||||
|
for ( int x = -kernelRadius; x <= kernelRadius; x++ )
|
||||||
|
{
|
||||||
|
for ( int y = -kernelRadius; y <= kernelRadius; y++ )
|
||||||
|
{
|
||||||
|
ivec2 xy = ivec2( x, y ) * kernelOffset;
|
||||||
|
ivec2 kernelUV = pixelUV + xy;
|
||||||
|
|
||||||
|
kernelUV += ivec2( random( kernelUV ) * parameters.noise );
|
||||||
|
|
||||||
|
kernelUV.x = clamp( kernelUV.x, 0, size.x - 1 );
|
||||||
|
kernelUV.y = clamp( kernelUV.y, 0, size.y - 1 );
|
||||||
|
|
||||||
|
color += imageLoad( inputImage, kernelUV );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for ( int x = -kernelRadius; x <= kernelRadius; x++ )
|
||||||
|
{
|
||||||
|
for ( int y = -kernelRadius; y <= kernelRadius; y++ )
|
||||||
|
{
|
||||||
|
ivec2 xy = ivec2( x, y ) * kernelOffset;
|
||||||
|
ivec2 kernelUV = pixelUV + xy;
|
||||||
|
|
||||||
|
kernelUV.x = clamp( kernelUV.x, 0, size.x - 1 );
|
||||||
|
kernelUV.y = clamp( kernelUV.y, 0, size.y - 1 );
|
||||||
|
|
||||||
|
color += imageLoad( inputImage, kernelUV );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int numPixels = ( kernelRadius * 2 + 1 ) * ( kernelRadius * 2 + 1 );
|
||||||
|
|
||||||
|
color /= numPixels;
|
||||||
|
|
||||||
|
vec4 originalColor = imageLoad( inputImage, pixelUV );
|
||||||
|
vec4 mixedColor = mix( originalColor, color, parameters.intensity );
|
||||||
|
|
||||||
|
imageStore( outputImage, pixelUV, mixedColor );
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="glsl"
|
||||||
|
type="RDShaderFile"
|
||||||
|
uid="uid://c1xombr20y7ql"
|
||||||
|
path="res://.godot/imported/BoxBlur.glsl-de744fa8bcca6e5a6cafa48c0fa412eb.res"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/rokojori_action_library/Runtime/Rendering/RenderGraph/Nodes/Processors/Blurs/BoxBlur/BoxBlur.glsl"
|
||||||
|
dest_files=["res://.godot/imported/BoxBlur.glsl-de744fa8bcca6e5a6cafa48c0fa412eb.res"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class RD_BoxBlur:CEG_ImageProcessor
|
||||||
|
{
|
||||||
|
public static readonly string shaderPath =
|
||||||
|
RDGraph.Path( "Nodes/Processors/Blurs/BoxBlur/BoxBlur.glsl" );
|
||||||
|
|
||||||
|
public RD_BoxBlur( RDGraph graph ):base( graph, shaderPath )
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
uid://b1vkp54fq4kt7
|
|
@ -131,7 +131,9 @@ namespace Rokojori
|
||||||
public static CEG_BufferTexture From( RDGraph graph, RDTexture texture )
|
public static CEG_BufferTexture From( RDGraph graph, RDTexture texture )
|
||||||
{
|
{
|
||||||
var creator = new CEG_TextureCreator_Reference( texture );
|
var creator = new CEG_TextureCreator_Reference( texture );
|
||||||
return new CEG_BufferTexture( graph, creator );
|
var t = new CEG_BufferTexture( graph, creator );
|
||||||
|
t._texture = texture;
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Process()
|
public override void Process()
|
||||||
|
|
|
@ -29,6 +29,14 @@ namespace Rokojori
|
||||||
imageProcessorBefore.output.ConnectTo( output );
|
imageProcessorBefore.output.ConnectTo( output );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddTextureSlotInput( RDGraphTextureSlotInput inputSlot )
|
||||||
|
{
|
||||||
|
var slot = new CompositorEffectGraphTextureSlot( this );
|
||||||
|
_textureSlots.Add( slot );
|
||||||
|
|
||||||
|
inputSlot.ConnectTo( slot );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
uid://6scrdbsfh3vj
|
|
@ -7,18 +7,22 @@ layout( rgba16, set = 0, binding = 0 )
|
||||||
uniform restrict readonly image2D inputImage;
|
uniform restrict readonly image2D inputImage;
|
||||||
|
|
||||||
layout( rgba16, set = 1, binding = 0 )
|
layout( rgba16, set = 1, binding = 0 )
|
||||||
uniform restrict readonly image2D originalImage;
|
uniform restrict writeonly image2D outputImage;
|
||||||
|
|
||||||
layout( rgba16, set = 2, binding = 0 )
|
layout( rgba16, set = 2, binding = 0 )
|
||||||
uniform restrict writeonly image2D outputImage;
|
uniform restrict readonly image2D originalImage;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy );
|
ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy );
|
||||||
vec4 currentPixel = imageLoad( inputImage, currentPosition );
|
vec4 currentPixel = imageLoad( inputImage, currentPosition );
|
||||||
|
|
||||||
ivec2 seedPosition = ivec2( packUnorm2x16( currentPixel.xy ), packUnorm2x16( currentPixel.zw ) );
|
ivec2 seedPosition = ivec2( packUnorm2x16( currentPixel.xy ), packUnorm2x16( currentPixel.zw ) );
|
||||||
|
|
||||||
vec4 originalPixel = imageLoad( originalImage, seedPosition );
|
vec4 colorPixel = imageLoad( originalImage, seedPosition );
|
||||||
|
vec4 originalPixel = imageLoad( originalImage, currentPosition );
|
||||||
|
|
||||||
imageStore(outputImage, currentPosition, vec4(originalPixel.xyz, originalPixel.a));
|
vec2 seedUV = vec2( seedPosition ) / imageSize( inputImage );
|
||||||
|
|
||||||
|
imageStore( outputImage, currentPosition, vec4( colorPixel.rgb, originalPixel.a) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,11 @@ void main()
|
||||||
{
|
{
|
||||||
vec4 packedZero = vec4( unpackUnorm2x16( 0 ), unpackUnorm2x16( 0 ) );
|
vec4 packedZero = vec4( unpackUnorm2x16( 0 ), unpackUnorm2x16( 0 ) );
|
||||||
imageStore( outputImage, currentPosition, packedZero );
|
imageStore( outputImage, currentPosition, packedZero );
|
||||||
|
// imageStore( outputImage, currentPosition, vec4( 1, 0, 0, 1 ) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 packedPosition = vec4( unpackUnorm2x16( currentPosition.x ), unpackUnorm2x16( currentPosition.y ) );
|
vec4 packedPosition = vec4( unpackUnorm2x16( currentPosition.x ), unpackUnorm2x16( currentPosition.y ) );
|
||||||
imageStore( outputImage, currentPosition, packedPosition);
|
imageStore( outputImage, currentPosition, packedPosition);
|
||||||
|
// imageStore( outputImage, currentPosition, vec4( 0, 1, 0, 1 ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@ uniform restrict readonly image2D inputImage;
|
||||||
layout(rgba16, set = 1, binding = 0)
|
layout(rgba16, set = 1, binding = 0)
|
||||||
uniform restrict writeonly image2D outputImage;
|
uniform restrict writeonly image2D outputImage;
|
||||||
|
|
||||||
layout(std430, set = 2, binding = 0)
|
layout( push_constant, std430 )
|
||||||
buffer restrict readonly DistanceParameters
|
uniform DistanceParameters
|
||||||
{
|
{
|
||||||
int jump;
|
int jump;
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ void main()
|
||||||
ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy );
|
ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy );
|
||||||
ivec2 imageSize = imageSize( inputImage );
|
ivec2 imageSize = imageSize( inputImage );
|
||||||
|
|
||||||
float distanceToClosestSeed = 1.0f / 0.0f;
|
float distanceToClosestSeed = 100000.0;
|
||||||
vec4 closestSeed = vec4( unpackUnorm2x16( 0 ), unpackUnorm2x16( 0 ) );
|
vec4 closestSeed = vec4( unpackUnorm2x16( 0 ), unpackUnorm2x16( 0 ) );
|
||||||
|
|
||||||
ivec2 jump = ivec2( distanceParameters.jump, distanceParameters.jump );
|
ivec2 jump = ivec2( distanceParameters.jump, distanceParameters.jump );
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
|
||||||
|
using Godot;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Rokojori
|
||||||
|
{
|
||||||
|
public class RG_SwapRepeat:RGGraphProcessor
|
||||||
|
{
|
||||||
|
protected RG_TextureSlotEditable _input;
|
||||||
|
protected RG_TextureSlotEditable _output;
|
||||||
|
|
||||||
|
public CompositorEffectGraphTextureSlot input => _input;
|
||||||
|
public CompositorEffectGraphTextureSlot output => _output;
|
||||||
|
|
||||||
|
|
||||||
|
public CEG_ImageProcessor imageProcessor;
|
||||||
|
public int repeats = 1;
|
||||||
|
|
||||||
|
public System.Action onStart;
|
||||||
|
public System.Action<int> onPreProcess;
|
||||||
|
public System.Action<int> onPostProcess;
|
||||||
|
public System.Action onEnd;
|
||||||
|
|
||||||
|
public RG_SwapRepeat( RDGraph graph ):base( graph )
|
||||||
|
{
|
||||||
|
_input = new RG_TextureSlotEditable( this );
|
||||||
|
_output = new RG_TextureSlotEditable( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetTextureSlotInputs( RDGraphTextureSlotInput inputSlot, RDGraphTextureSlotInput outputSlot )
|
||||||
|
{
|
||||||
|
inputSlot.ConnectTo( input );
|
||||||
|
outputSlot.ConnectTo( output );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetTextureSlotInputs( CEG_ImageProcessor imageProcessorBefore )
|
||||||
|
{
|
||||||
|
imageProcessorBefore.input.ConnectTo( input );
|
||||||
|
imageProcessorBefore.output.ConnectTo( output );
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Process()
|
||||||
|
{
|
||||||
|
if ( onStart != null )
|
||||||
|
{
|
||||||
|
onStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
var cachedInputTexture = input.ResolveTexture();
|
||||||
|
var cachedOutputTexture = output.ResolveTexture();
|
||||||
|
|
||||||
|
imageProcessor.SetTextureSlotInputs( input, output );
|
||||||
|
|
||||||
|
for ( int i = 0; i < repeats; i++ )
|
||||||
|
{
|
||||||
|
graph.context.Verbose( "Repeat:", i );
|
||||||
|
|
||||||
|
if ( i % 2 == 0 )
|
||||||
|
{
|
||||||
|
_input.SetTexture( cachedInputTexture );
|
||||||
|
_output.SetTexture( cachedOutputTexture );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_input.SetTexture( cachedOutputTexture );
|
||||||
|
_output.SetTexture( cachedInputTexture );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( onPreProcess != null )
|
||||||
|
{
|
||||||
|
onPreProcess( i );
|
||||||
|
}
|
||||||
|
|
||||||
|
imageProcessor.Process();
|
||||||
|
|
||||||
|
if ( onPostProcess != null )
|
||||||
|
{
|
||||||
|
onPostProcess( i );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_input.SetTexture( cachedInputTexture );
|
||||||
|
_output.SetTexture( cachedOutputTexture );
|
||||||
|
|
||||||
|
if ( onEnd != null )
|
||||||
|
{
|
||||||
|
onEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
uid://bmpqy38ty2nlx
|
|
@ -54,14 +54,20 @@ namespace Rokojori
|
||||||
public void ProcessForView()
|
public void ProcessForView()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
var index = 1;
|
||||||
|
var num = _processOrder.Count;
|
||||||
|
|
||||||
_processOrder.ForEach(
|
_processOrder.ForEach(
|
||||||
p =>
|
p =>
|
||||||
{
|
{
|
||||||
context.Verbose( p.GetType() );
|
context.Verbose( index + "/" + num, p.GetType() );
|
||||||
p.Process();
|
p.Process();
|
||||||
|
index++;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
context.Verbose( "Render done" );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,7 +19,7 @@ namespace Rokojori
|
||||||
|
|
||||||
public RDSampler sampler;
|
public RDSampler sampler;
|
||||||
|
|
||||||
RDTexture _texture;
|
protected RDTexture _texture;
|
||||||
|
|
||||||
public RDTexture GetTexture()
|
public RDTexture GetTexture()
|
||||||
{
|
{
|
||||||
|
@ -59,4 +59,14 @@ namespace Rokojori
|
||||||
slot.SetInput( this );
|
slot.SetInput( this );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class RG_TextureSlotEditable:CompositorEffectGraphTextureSlot
|
||||||
|
{
|
||||||
|
public RG_TextureSlotEditable( RGGraphProcessor processor ):base( processor ){}
|
||||||
|
|
||||||
|
public void SetTexture( RDTexture texture )
|
||||||
|
{
|
||||||
|
_texture = texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -22,11 +22,11 @@ namespace Rokojori
|
||||||
|
|
||||||
protected override void OnInitialize()
|
protected override void OnInitialize()
|
||||||
{
|
{
|
||||||
graph.context.Verbose( "Trying to load shader: ", _shaderPath );
|
graph.context.Verbose( GetType().Name, "Trying to load shader: ", _shaderPath );
|
||||||
|
|
||||||
if ( _shaderPath == null )
|
if ( _shaderPath == null )
|
||||||
{
|
{
|
||||||
graph.context.Error( "_shaderPath == null" );
|
graph.context.Error( GetType().Name, "_shaderPath == null" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ namespace Rokojori
|
||||||
|
|
||||||
if ( glslFile == null )
|
if ( glslFile == null )
|
||||||
{
|
{
|
||||||
graph.context.Error( "Couldn't load shader at path:", _shaderPath );
|
graph.context.Error( GetType().Name, "Couldn't load shader at path:", _shaderPath );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ namespace Rokojori
|
||||||
|
|
||||||
if ( _shader == null )
|
if ( _shader == null )
|
||||||
{
|
{
|
||||||
graph.context.Error( "Couldn't create shader from code, path:", _shaderPath );
|
graph.context.Error( GetType().Name, "Couldn't create shader from code, path:", _shaderPath );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,11 +50,11 @@ namespace Rokojori
|
||||||
|
|
||||||
if ( _shader == null )
|
if ( _shader == null )
|
||||||
{
|
{
|
||||||
graph.context.Error( "Couldn't create pipeline from compiled shader, path:", _shaderPath );
|
graph.context.Error( GetType().Name, "Couldn't create pipeline from compiled shader, path:", _shaderPath );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
graph.context.Verbose( "Created shader at path: ", _shaderPath );
|
graph.context.Verbose( GetType().Name, "Created shader at path: ", _shaderPath );
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Process()
|
public override void Process()
|
||||||
|
@ -65,18 +65,49 @@ namespace Rokojori
|
||||||
context.CalculateSceneComputeGroups( _groupSize );
|
context.CalculateSceneComputeGroups( _groupSize );
|
||||||
context.SetShaderAndPipeline( _shader, _pipeline );
|
context.SetShaderAndPipeline( _shader, _pipeline );
|
||||||
|
|
||||||
|
context.Verbose( GetType().Name, "Setting texture uniforms", _textureSlots.Count );
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
_textureSlots.ForEach( t =>
|
_textureSlots.ForEach( t =>
|
||||||
{
|
{
|
||||||
|
index++;
|
||||||
|
|
||||||
t.ResolveTexture();
|
t.ResolveTexture();
|
||||||
graph.context.AssignTexture( t.GetTexture(), t.sampler );
|
var texture = t.GetTexture();
|
||||||
|
|
||||||
|
if ( texture == null || ! texture.rid.IsValid )
|
||||||
|
{
|
||||||
|
if ( texture == null )
|
||||||
|
{
|
||||||
|
context.Error( index, "Texture is null" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.Error( index, "Texture is not valid:", texture.rid );
|
||||||
|
}
|
||||||
|
|
||||||
|
graph.context.AssignMissingTexture( t.sampler );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
graph.context.AssignTexture( texture, t.sampler );
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
if ( _constants.size > 0 )
|
if ( _constants.size > 0 )
|
||||||
{
|
{
|
||||||
|
context.Verbose( GetType().Name, "Setting constants", _constants.size );
|
||||||
context.pushConstants = _constants;
|
context.pushConstants = _constants;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.Verbose( GetType().Name, "No constants" );
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Verbose( GetType().Name, "Process Compute Program", _constants.size );
|
||||||
context.ProcessComputeProgram();
|
context.ProcessComputeProgram();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue