RenderStuff Updates

This commit is contained in:
Josef 2025-04-29 21:46:45 +02:00
parent 966cb7e28c
commit 66d24be2c1
34 changed files with 1364 additions and 91 deletions

View File

@ -10,22 +10,52 @@ namespace Rokojori
return ( 1 << bit );
}
public static long GetInt64BitMask( int bit )
{
return ( 1 << bit );
}
public static int SetBit( int value, int bitPosition )
{
return value | GetInt32BitMask( bitPosition );
}
public static long SetBit( long value, int bitPosition )
{
return value | GetInt64BitMask( bitPosition );
}
public static int UnsetBit( int value, int bitPosition )
{
return value & ~GetInt32BitMask( bitPosition );
}
public static long UnsetBit( long value, int bitPosition )
{
return value & ~GetInt64BitMask( bitPosition );
}
public static bool IsBitSet( int value, int bitPosition )
{
var mask = GetInt32BitMask( bitPosition );
return ( value & mask ) == mask;
}
public static bool IsBitSet( long value, int bitPosition )
{
var mask = GetInt64BitMask( bitPosition );
return ( value & mask ) == mask;
}
public static bool IsMaskSet( int value, int mask )
{
return ( value & mask ) == mask;
}
public static bool IsMaskSet( long value, long mask )
{
return ( value & mask ) == mask;
}
}
}

View File

@ -145,6 +145,13 @@ namespace Rokojori
GD.PrintRich( trace );
}
static void LogErrorWithFullTrace( string message )
{
var trace = GetFullTrace();
GD.PrintErr("\n" + message );
GD.PrintRich( trace );
}
static void LogErrorMessage( string message, int frameIndex = 3 )
{
var trace = GetTrace( frameIndex );
@ -218,6 +225,11 @@ namespace Rokojori
LogErrorMessage( GetLogString( objects ) );
}
public static void ErrorFull( params object[] objects)
{
LogErrorWithFullTrace( GetLogString( objects ) );
}
public static void Error( Node node, params object[] objects)
{
LogErrorMessage( "" + HierarchyName.Of( node ) + "\n" + GetLogString( objects ), 4 );

View File

@ -54,7 +54,15 @@ namespace Rokojori
public Callable GrabTextureButton => Callable.From(
async () =>
{
texture2D = await alphaGrabTestEffect.GetImageTexture( async ()=> await this.RequestNextFrame() );
var result = await alphaGrabTestEffect.GetImageTexture( async ()=> await this.RequestNextFrame() );
if ( result == null )
{
this.LogError( "No texture" );
return;
}
texture2D = result;
}
);

View File

@ -0,0 +1,135 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Linq;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class GrabTexture2:Action
{
[Export]
public SubViewport viewport;
[Export]
public Texture2D target;
[Export]
public MeshInstance3D meshInstance3D;
[ExportToolButton( "Grab Texture")]
public Callable GrabButton => Callable.From(
() =>
{
Grab();
}
);
async void 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( "Creating context" );
var ctx = RDContext.Local();
ctx.computeSize = viewPortSize;
ctx.messageLogLevel = Messages.GetLevel( MessageType.Verbose );
this.LogInfo( "Creating textures" );
var outputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
this.LogInfo( "Usage", RDTextureFormats.UsageInfo( outputTexture.format.UsageBits ) );
var inputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
inputTexture.SetData( viewPortData );
var graph = CreateGraph( ctx, inputTexture, outputTexture );
graph.ProcessForView();
ctx.SubmitAndSync();
var width = outputTexture.width;
var height = outputTexture.height;
var format = outputTexture.imageFormat;
var data = outputTexture.GetData();
this.LogInfo( "Copying texture" );
ctx.SubmitAndSync();
await this.RequestNextFrame();
var image = Image.CreateFromData( width, height, false, format, data );
var buffer = TextureCombinerBuffer.From( ImageTexture.CreateFromImage( image ) );
target = buffer.CreateImageTexture();
var material3D = (StandardMaterial3D) meshInstance3D.MaterialOverride;
material3D.AlbedoTexture = target;
ctx.CleanUp();
await this.RequestNextFrame();
}
RDGraph CreateGraph( RDContext ctx, RDTexture it, RDTexture ot )
{
var graph = new RDGraph( ctx );
var viewTexture = CEG_BufferTexture.From( graph, it );
var bufferTexture = CEG_BufferTexture.From( graph, ot );
var copy = new CEG_Copy( graph );
var radialBlur = new CEG_RadialBlur( graph );
graph.InitializeNodes();
copy.SetTextureSlotInputs( viewTexture, bufferTexture );
radialBlur.SetTextureSlotInputs( copy.output, copy.input );
graph.SetProcessOrder(
viewTexture, bufferTexture,
copy, radialBlur
);
radialBlur.constants.Set(
new Vector2( 0.5f, 0.5f ),
0.5f,
0.5f,
16,
Vector2.Zero
);
return graph;
}
}
}

View File

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

View File

@ -0,0 +1,120 @@
using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Linq;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class GrabTextureRD:Action
{
[Export]
public SubViewport viewport;
[Export]
public Texture2D target;
[Export]
public MeshInstance3D meshInstance3D;
[ExportToolButton( "Grab Texture")]
public Callable GrabButton => Callable.From(
() =>
{
Grab();
}
);
async void 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();
this.LogInfo( "Creating context" );
var ctx = RDContext.Local();
ctx.messageLogLevel = Messages.GetLevel( MessageType.Verbose );
this.LogInfo( "Creating program" );
ctx.SetProgramFromPath( CEG_AlphaColorDilation.shaderPath );
this.LogInfo( "Creating textures" );
var outputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
this.LogInfo( "Usage", RDTextureFormats.UsageInfo( outputTexture.format.UsageBits ) );
outputTexture.SetData( new Color( 1, 1, 1, 1 ) );
// var inputTexture = RDTexture.CreateCopyFrom( ctx, viewport );
var inputTexture = RDTexture.Create( ctx, viewport.Size, viewPortFormat );
inputTexture.SetData( viewPortData );
// inputTexture.SetData( new Color( 0, 1, 0, 1 ) );
this.LogInfo( "Assigning input texture:", ctx.shader, ctx.shader.rid );
ctx.AssignTexture( inputTexture );
this.LogInfo( "Assigning output texture" );
ctx.AssignTexture( outputTexture );
this.LogInfo( "Compute group sizes" );
ctx.CalculateComputeGroups( 8, viewport.Size );
this.LogInfo( "Process compute program" );
ctx.ProcessComputeProgram();
this.LogInfo( "Waiting to render" );
ctx.SubmitAndSync();
var width = outputTexture.width;
var height = outputTexture.height;
var format = outputTexture.imageFormat;
var data = outputTexture.GetData();
data = data.ToList().ToArray();
this.LogInfo( "Copying texture" );
ctx.SubmitAndSync();
await this.RequestNextFrame();
var image = Image.CreateFromData( width, height, false, format, data );
var buffer = TextureCombinerBuffer.From( ImageTexture.CreateFromImage( image ) );
target = buffer.CreateImageTexture();
var material3D = (StandardMaterial3D) meshInstance3D.MaterialOverride;
material3D.AlbedoTexture = target;
ctx.CleanUp();
await this.RequestNextFrame();
}
}
}

View File

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

View File

@ -14,6 +14,15 @@ namespace Rokojori
Initialize();
}
[Export]
public Vector2 rShift = new Vector2( -0.001f, 0.0f );
[Export]
public Vector2 gShift = new Vector2( 0.0f, 0.0f );
[Export]
public Vector2 bShift = new Vector2( 0.001f, 0.0f );
[Export]
public float intensity = 0.5f;
@ -24,15 +33,6 @@ namespace Rokojori
[Export]
public float unshiftCenter = 16f;
[Export]
public Vector2 rShift = new Vector2( -0.001f, 0.0f );
[Export]
public Vector2 gShift = new Vector2( 0.0f, 0.0f );
[Export]
public Vector2 bShift = new Vector2( 0.001f, 0.0f );
CEG_ScreenColorTexure screenColorTexture;
@ -52,8 +52,6 @@ namespace Rokojori
graph.InitializeNodes();
copy.SetTextureSlotInputs( screenColorTexture, bufferTexture );
chromaticAberation.SetTextureSlotInputs( copy.output, copy.input );
@ -68,12 +66,13 @@ namespace Rokojori
protected override void ForAllViews()
{
chromaticAberation.constants.Set(
intensity,
shiftAll,
unshiftCenter,
rShift,
gShift,
bShift
bShift,
intensity,
shiftAll,
unshiftCenter
);
}

View File

@ -58,7 +58,7 @@ namespace Rokojori
protected override void ForAllViews()
{
context.CalculateComputeGroups( _groupSize );
context.CalculateSceneComputeGroups( _groupSize );
SetConstants();
}

View File

@ -17,6 +17,24 @@ namespace Rokojori
return;
}
if ( ! ro.rid.IsValid )
{
Verbose( "Not valid rid:", ro.rid );
return;
}
if ( ro is RDPipeline )
{
Verbose( "Not cleaning pipelines" );
return;
}
if ( ro is RDUniformSet )
{
Verbose( "Not cleaning uniform sets" );
return;
}
Verbose( "Cleaning up: ", info, ro.rid );
renderingDevice.FreeRid( ro.rid );
}
@ -29,7 +47,7 @@ namespace Rokojori
_cleanUps.ForEach(
c =>
{
Free( c, "_cleanUps[" + index + "]");
Free( c, _cleanUpInfo[ index ] );
index ++;
}
);

View File

@ -25,7 +25,7 @@ namespace Rokojori
if ( logMessages )
{
RJLog.Log( message );
RJLog.ErrorFull( message );
}
}
@ -37,7 +37,7 @@ namespace Rokojori
if ( logMessages && Messages.GetLevel( MessageType.Warning ) >= messageLogLevel )
{
RJLog.Log( message );
RJLog.ErrorFull( message );
}
}

View File

@ -6,19 +6,36 @@ namespace Rokojori
{
public partial class RDContext
{
protected RenderingDevice _renderingDevice;
public RenderingDevice renderingDevice => _renderingDevice;
protected bool _localRenderingDevice;
public bool isLocalRenderingDevice => _localRenderingDevice;
protected RDShader _shader;
public RDShader shader => _shader;
protected RDPipeline _pipeline;
public RDPipeline pipeline => _pipeline;
public static RDContext Local()
{
var ctx = new RDContext();
ctx.Initialize( true );
return ctx;
}
public void Initialize( bool local = false)
{
_localRenderingDevice = local;
_renderingDevice = local ? RenderingServer.Singleton.CreateLocalRenderingDevice():
RenderingServer.Singleton.GetRenderingDevice();
if ( _renderingDevice == null )
{
Error( "Could not initialize rendering device" );
}
}
@ -52,6 +69,17 @@ namespace Rokojori
return RDTexture.Depth( this );
}
public void SetProgram( RDProgram p )
{
SetShaderAndPipeline( p.shader, p.pipeline );
}
public void SetProgramFromPath( string path )
{
Verbose( "Creating program:", path );
var program = RDProgram.FromPath( this, path );
SetProgram( program );
}
public void SetShaderAndPipeline( RDShader shader, RDPipeline pipeline )
{
@ -79,6 +107,7 @@ namespace Rokojori
AssignTexture( GetScreenDepthTexture(), sampler, setIndex );
}
public void AssignTexture( RDTexture texture, RDSampler sampler = null, int setIndex = -1 )
{
// effect.Verbose( "Incoming Uniform Index", setIndex );
@ -110,33 +139,111 @@ namespace Rokojori
_uniformSets.Add( uniformSet );
}
public void CreateUniformaSet( params RDUniform[] uniforms )
{
var setIndex = _uniformSets.Count;
_CreateUniformSetRid( setIndex, uniforms );
}
public Rid _CreateUniformSetRid( int index, params RDUniform[] uniforms )
{
var array = new Godot.Collections.Array<RDUniform>();
array.AddRange( uniforms );
if ( ! isLocalRenderingDevice )
{
return UniformSetCacheRD.GetCache( shader.rid, (uint) index, array );
}
else
{
return renderingDevice.UniformSetCreate( array, shader.rid, (uint) index );
}
}
public void Clear()
{
_uniformSets.Clear();
pushConstants = null;
}
public Vector2I computeSize = new Vector2I( 512, 512 );
public Vector2I GetComputeSize()
{
if ( _sceneBuffers != null )
{
return _sceneBuffers.GetInternalSize();
}
return computeSize;
}
public void SetComputeGroups( Vector3I groups )
{
this._groups = groups;
}
public void CalculateComputeGroups( int groupSize )
public void CalculateSceneComputeGroups( int groupSize )
{
CalculateComputeGroups( new Vector3I( groupSize, groupSize, 0 ) );
var size = GetComputeSize();
CalculateComputeGroups( new Vector3I( groupSize, groupSize, 0 ), size );
}
public void CalculateComputeGroups( Vector3I groupSize )
public void CalculateSceneComputeGroups( Vector3I groupSize )
{
var size = sceneBuffers.GetInternalSize();
var size = GetComputeSize();
CalculateComputeGroups( groupSize, size );
}
public void CalculateComputeGroups( int groupSize, Vector2I size )
{
CalculateComputeGroups( new Vector3I( groupSize, groupSize, 0 ), size );
}
public void CalculateComputeGroups( Vector3I groupSize, Vector2I size )
{
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 );
var zGroups = 1;
SetComputeGroups( new Vector3I( xGroups, yGroups, zGroups ) );
}
public void Submit()
{
if ( ! isLocalRenderingDevice )
{
Error( "You can only submit or sync in non-local rendering devices" );
return;
}
renderingDevice.Submit();
}
public void Sync()
{
if ( ! isLocalRenderingDevice )
{
Error( "You can only submit or sync in non-local rendering devices" );
return;
}
renderingDevice.Sync();
}
public void SubmitAndSync()
{
if ( ! isLocalRenderingDevice )
{
Error( "You can only submit or sync in non-local rendering devices" );
return;
}
Submit();
Sync();
}
public void ProcessComputeProgram()
{
try

View File

@ -7,6 +7,14 @@ namespace Rokojori
public class RDProgram
{
protected RDContext _context;
public RDContext context => _context;
public RDProgram( RDContext context )
{
_context = context;
}
public enum Type
{
VertexFragment,
@ -17,9 +25,32 @@ namespace Rokojori
public Type type => _type;
protected RDShader _shader;
public RDShader shader;
public RDShader shader => _shader;
protected RDPipeline _pipeline;
public RDPipeline pipeline;
public RDPipeline pipeline => _pipeline;
public static RDProgram FromPath( RDContext context, string path )
{
var p = new RDProgram( context );
p._shader = RDShader.FromPath( context, path );
if ( p._shader == null || ! p._shader.rid.IsValid )
{
context.Error( "Invalid shader", path );
return null;
}
p._pipeline = RDPipeline.Create( context, p._shader );
if ( p._pipeline == null || ! p._pipeline.rid.IsValid )
{
context.Error( "Invalid pipeline", path );
return null;
}
return p;
}
}
}

View File

@ -8,10 +8,38 @@ namespace Rokojori
public RDShader( RDContext context, Rid rid ):base( context, rid )
{}
public static RDShader CreateFromSpirV( RDContext context, RDShaderSpirV rDShaderSpirV )
public static RDShader CreateFromSpirV( RDContext context, RDShaderSpirV rDShaderSpirV, string pathInfo = null )
{
var shaderID = context.renderingDevice.ShaderCreateFromSpirV( rDShaderSpirV );
if ( ! shaderID.IsValid )
{
context.Error( "Couldn't create shader from spirV. PathInfo:", pathInfo );
return null;
}
return new RDShader( context, shaderID );
}
public static RDShader FromPath( RDContext context, string path )
{
var glslFile = GD.Load<RDShaderFile>( path );
if ( glslFile == null )
{
context.Error( "File not found:", path );
return null;
}
var spirV = glslFile.GetSpirV();
if ( spirV == null )
{
context.Error( "SpirV is null", path );
return null;
}
return CreateFromSpirV( context, spirV, path );
}
}
}

View File

@ -26,6 +26,121 @@ namespace Rokojori
return new RDTexture( context, rid );
}
public void SetData( byte[] data, int layer = 0 )
{
var error = context.renderingDevice.TextureUpdate( rid, (uint) layer, data );
if ( error == Error.Ok )
{
context.Verbose( "Data was set" );
return;
}
context.Error( error );
}
public void SetData( Viewport viewport )
{
SetData( viewport.GetTexture().GetImage() );
}
public void SetData( Image image )
{
var textureDataFormat = RDTextureFormats.ImageFormatToDataFormat( image.GetFormat() );
if ( textureDataFormat != format.Format )
{
context.Error( "Incompatible image format:", textureDataFormat, " Expected:", format.Format );
return;
}
SetData( image.GetData() );
}
public int numPixels => (int) ( format.Width * format.Height );
public int channelsPerPixel => RDTextureFormats.GetNumChannels( format.Format );
public RDTextureFormats.PixelChannelEncoding pixelChannelEncoding => RDTextureFormats.GetPixelChannelEncoding( format.Format );
public int bytesPerPixel => RDTextureFormats.NumBytesFor( pixelChannelEncoding ) * channelsPerPixel;
public int GetNumBytes( int layer = 0 )
{
var bytes = numPixels * bytesPerPixel;
while ( layer > 0 )
{
bytes /= 4;
layer --;
}
return bytes;
}
public void SetData( Color color )
{
var fmt = format.Format;
var colorBytes = RDTextureFormats.ColorToBytes( color, fmt );
if ( colorBytes == null )
{
context.Error( "Unsupported texture format" );
return;
}
context.Verbose( "ColorBytes:", colorBytes );
var bytes = new byte[ GetNumBytes() ];
context.Verbose( "NumPixels", numPixels, "BytesPerPixel", bytesPerPixel, "Num Bytes", GetNumBytes( 0 ) );
for ( int i = 0; i < bytes.Length; i+= colorBytes.Length )
{
System.Array.Copy( colorBytes, 0, bytes, i, colorBytes.Length );
}
context.Verbose( "First Byte", bytes[ 0 ], bytes[ 1 ], bytes[ 2 ], bytes[ 3 ] );
SetData( bytes );
}
public byte[] GetData( int layer = 0)
{
return context.renderingDevice.TextureGetData( rid, (uint) layer );
}
public int width => (int) format.Width;
public int height => (int) format.Height;
public RenderingDevice.DataFormat dataFormat => format.Format;
public Image.Format imageFormat => RDTextureFormats.DataFormatToImageFormat( dataFormat );
public Image GetImage()
{
var fmt = format;
var imgF = RDTextureFormats.DataFormatToImageFormat( format.Format );
var data = GetData();
var output = "";
for ( int i = 0; i < 20; i++ )
{
if ( i != 0 ){ output += ", "; }
output += data[ i ] + "";
}
context.Verbose( "Converting:", fmt.Format, ">>", imgF, "output:", output );
return Image.CreateFromData( (int) fmt.Width, (int)fmt.Height, false, imgF, data );
}
public Texture2D GetTexture2D()
{
return ImageTexture.CreateFromImage( GetImage() );
}
public RDTextureFormat format
{
get
@ -67,7 +182,7 @@ namespace Rokojori
return new RDTexture( context, rid );
}
public static RDTextureFormat DefaultFormat( int w, int h, RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Unorm )
public static RDTextureFormat DefaultFormat( int w, int h, RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Sfloat)
{
var format = new RDTextureFormat();
@ -77,60 +192,51 @@ namespace Rokojori
format.UsageBits = RenderingDevice.TextureUsageBits.StorageBit |
RenderingDevice.TextureUsageBits.SamplingBit |
RenderingDevice.TextureUsageBits.CanCopyFromBit |
RenderingDevice.TextureUsageBits.CanUpdateBit |
RenderingDevice.TextureUsageBits.CanCopyToBit |
RenderingDevice.TextureUsageBits.CpuReadBit
;
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( RDContext context, Vector2I size, RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Unorm )
public static RDTexture Create( RDContext context, Vector2I size, RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Sfloat )
{
return Create( context, size.X, size.Y, dataFormat );
}
public static RDTexture Create( RDContext context, int width, int height,
RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Unorm )
RenderingDevice.DataFormat dataFormat = RenderingDevice.DataFormat.R16G16B16A16Sfloat,
RenderingDevice.TextureUsageBits textureUsageBits = RDTextureFormats.Usage_Default )
{
var view = new RDTextureView();
var format = DefaultFormat( width, height, dataFormat );
var format = RDTextureFormats.DefaultFormat( width, height, dataFormat );
format.UsageBits = textureUsageBits;
context.Verbose( "Format:", format, "DataFormat", dataFormat);
var rid = context.renderingDevice.TextureCreate( format, view );
return new RDTexture( context, rid );
}
public static RDTexture CreateCopyFrom( RDContext context, SubViewport viewport )
{
var dataFormat = RDTextureFormats.GetDataFormat( viewport );
var bytes = RDTextureFormats.GetNumBytes( viewport );
var image = viewport.GetTexture().GetImage();
var viewPortImageFormat = image.GetFormat();
var rdFormat = RDTextureFormats.ImageFormatToDataFormat( viewPortImageFormat );
var data = image.GetData();
RJLog.Log( "Data", data.Length, Lists.SubList( data, 0, 100 ) );
RJLog.Log( "Copying Texture From", viewport.Size, viewPortImageFormat, rdFormat, "Bytes", bytes );
var texture = Create( context, viewport.Size, dataFormat );
texture.SetData( data );
return texture;
}
}
}

View File

@ -0,0 +1,440 @@
using System;
using Godot;
using System.Collections.Generic;
using System.Text;
namespace Rokojori
{
public class RDTextureFormats
{
public enum PixelChannelEncoding
{
Unknown,
uInt8,
sInt8,
uInt16,
sInt16,
sFloat16,
uNorm16,
sNorm16,
uInt32,
sInt32,
sFloat32
}
public static readonly List<PixelChannelEncoding> bits8 = new List<PixelChannelEncoding>()
{
PixelChannelEncoding.uInt8,
PixelChannelEncoding.sInt8
};
public static readonly List<PixelChannelEncoding> bits32 = new List<PixelChannelEncoding>()
{
PixelChannelEncoding.uInt32,
PixelChannelEncoding.sInt32,
PixelChannelEncoding.sFloat32
};
public static int NumBytesFor( PixelChannelEncoding encoding )
{
if ( PixelChannelEncoding.Unknown == encoding )
{
return -1;
}
if ( bits8.Contains( encoding ) )
{
return 1;
}
if ( bits32.Contains( encoding ) )
{
return 4;
}
return 2;
}
public static string UsageInfo( RenderingDevice.TextureUsageBits bits )
{
var enums = Enum.GetValues<RenderingDevice.TextureUsageBits>();
var sb = new StringBuilder();
var first = true;
Array.ForEach( enums,
e =>
{
if ( ! BitMath.IsMaskSet( (long)bits, (long)e ) )
{
return;
}
if ( first ){ first = false; }
else { sb.Append( ", " ); }
sb.Append( e + "" );
}
);
return sb.ToString();
}
public const RenderingDevice.TextureUsageBits Usage_Default =
RenderingDevice.TextureUsageBits.SamplingBit |
RenderingDevice.TextureUsageBits.StorageBit |
RenderingDevice.TextureUsageBits.CpuReadBit |
RenderingDevice.TextureUsageBits.CanUpdateBit |
RenderingDevice.TextureUsageBits.CanCopyFromBit |
RenderingDevice.TextureUsageBits.CanCopyToBit;
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 = Usage_Default;
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 int GetNumPixels( SubViewport viewport )
{
return viewport.Size.X * viewport.Size.Y;
}
public static int GetNumBytes( SubViewport viewport )
{
var numChannels = viewport.TransparentBg ? 4 : 3;
var encoding = viewport.UseHdr2D ? 2 : 1;
return GetNumPixels( viewport ) * numChannels * encoding;
}
public static RenderingDevice.DataFormat GetDataFormat( Viewport viewport )
{
var imageFormat = viewport.GetTexture().GetImage().GetFormat();
return ImageFormatToDataFormat( imageFormat );
}
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 RenderingDevice.DataFormat DataFormat( int channels, PixelChannelEncoding encoding )
{
if ( 1 == channels )
{
return DataFormat_1Channel( encoding );
}
if ( 2 == channels )
{
return DataFormat_2Channels( encoding );
}
if ( 3 == channels )
{
return DataFormat_3Channels( encoding );
}
if ( 4 == channels )
{
return DataFormat_4Channels( encoding );
}
return RenderingDevice.DataFormat.Max;
}
public static RenderingDevice.DataFormat ImageFormatToDataFormat( Image.Format imageFormat )
{
RJLog.Log( "ImageFormatToDataFormat", imageFormat );
switch ( imageFormat )
{
case Image.Format.Rgb8: return RenderingDevice.DataFormat.R8G8B8Uint;
case Image.Format.Rgba8: return RenderingDevice.DataFormat.R8G8B8A8Uint;
case Image.Format.Rgbah: return RenderingDevice.DataFormat.R16G16B16A16Sfloat;
}
return RenderingDevice.DataFormat.Max;
}
public static Image.Format DataFormatToImageFormat( RenderingDevice.DataFormat dataFormat )
{
switch ( dataFormat )
{
case RenderingDevice.DataFormat.R8G8B8A8Uint: return Image.Format.Rgba8;
case RenderingDevice.DataFormat.R8G8B8Uint: return Image.Format.Rgb8;
case RenderingDevice.DataFormat.R16G16B16A16Sfloat: return Image.Format.Rgbah;
}
return Image.Format.Max;
}
public static RenderingDevice.DataFormat DataFormat_1Channel( PixelChannelEncoding encoding )
{
switch ( encoding )
{
case PixelChannelEncoding.uInt8: return RenderingDevice.DataFormat.R8Uint;
}
return RenderingDevice.DataFormat.Max;
}
public static RenderingDevice.DataFormat DataFormat_2Channels( PixelChannelEncoding encoding )
{
switch ( encoding )
{
case PixelChannelEncoding.uInt8: return RenderingDevice.DataFormat.R8Uint;
}
return RenderingDevice.DataFormat.Max;
}
public static RenderingDevice.DataFormat DataFormat_3Channels( PixelChannelEncoding encoding )
{
switch ( encoding )
{
case PixelChannelEncoding.uInt8: return RenderingDevice.DataFormat.R8G8B8Uint;
case PixelChannelEncoding.sInt8: return RenderingDevice.DataFormat.R8G8B8Sint;
case PixelChannelEncoding.uInt16: return RenderingDevice.DataFormat.R16G16B16Uint;
case PixelChannelEncoding.sInt16: return RenderingDevice.DataFormat.R16G16B16Sint;
case PixelChannelEncoding.sFloat16: return RenderingDevice.DataFormat.R16G16B16Sfloat;
case PixelChannelEncoding.uNorm16: return RenderingDevice.DataFormat.R16G16B16Unorm;
case PixelChannelEncoding.sNorm16: return RenderingDevice.DataFormat.R16G16B16Snorm;
case PixelChannelEncoding.uInt32: return RenderingDevice.DataFormat.R32G32B32Uint;
case PixelChannelEncoding.sInt32: return RenderingDevice.DataFormat.R32G32B32Sint;
case PixelChannelEncoding.sFloat32: return RenderingDevice.DataFormat.R32G32B32Sfloat;
}
return RenderingDevice.DataFormat.Max;
}
public static RenderingDevice.DataFormat DataFormat_4Channels( PixelChannelEncoding encoding )
{
switch ( encoding )
{
case PixelChannelEncoding.uInt8: return RenderingDevice.DataFormat.R8G8B8A8Uint;
case PixelChannelEncoding.sInt8: return RenderingDevice.DataFormat.R8G8B8A8Sint;
case PixelChannelEncoding.uInt16: return RenderingDevice.DataFormat.R16G16B16A16Uint;
case PixelChannelEncoding.sInt16: return RenderingDevice.DataFormat.R16G16B16A16Sint;
case PixelChannelEncoding.sFloat16: return RenderingDevice.DataFormat.R16G16B16A16Sfloat;
case PixelChannelEncoding.uNorm16: return RenderingDevice.DataFormat.R16G16B16A16Unorm;
case PixelChannelEncoding.sNorm16: return RenderingDevice.DataFormat.R16G16B16A16Snorm;
case PixelChannelEncoding.uInt32: return RenderingDevice.DataFormat.R32G32B32A32Uint;
case PixelChannelEncoding.sInt32: return RenderingDevice.DataFormat.R32G32B32A32Sint;
case PixelChannelEncoding.sFloat32: return RenderingDevice.DataFormat.R32G32B32A32Sfloat;
}
return RenderingDevice.DataFormat.Max;
}
// m: case ((?:\w|\.)*): return ((?:\w|\.)*);
// r: case $2: return $1;
public static PixelChannelEncoding GetPixelChannelEncoding( RenderingDevice.DataFormat format )
{
switch ( format )
{
case RenderingDevice.DataFormat.R8G8B8Sint: return PixelChannelEncoding.sInt8;
case RenderingDevice.DataFormat.R16G16B16Uint: return PixelChannelEncoding.uInt16;
case RenderingDevice.DataFormat.R16G16B16Sint: return PixelChannelEncoding.sInt16;
case RenderingDevice.DataFormat.R16G16B16Sfloat: return PixelChannelEncoding.sFloat16;
case RenderingDevice.DataFormat.R16G16B16Unorm: return PixelChannelEncoding.uNorm16;
case RenderingDevice.DataFormat.R16G16B16Snorm: return PixelChannelEncoding.sNorm16;
case RenderingDevice.DataFormat.R32G32B32Uint: return PixelChannelEncoding.uInt32;
case RenderingDevice.DataFormat.R32G32B32Sint: return PixelChannelEncoding.sInt32;
case RenderingDevice.DataFormat.R32G32B32Sfloat: return PixelChannelEncoding.sFloat32;
case RenderingDevice.DataFormat.R8G8B8A8Uint: return PixelChannelEncoding.uInt8;
case RenderingDevice.DataFormat.R8G8B8A8Sint: return PixelChannelEncoding.sInt8;
case RenderingDevice.DataFormat.R16G16B16A16Uint: return PixelChannelEncoding.uInt16;
case RenderingDevice.DataFormat.R16G16B16A16Sint: return PixelChannelEncoding.sInt16;
case RenderingDevice.DataFormat.R16G16B16A16Sfloat: return PixelChannelEncoding.sFloat16;
case RenderingDevice.DataFormat.R16G16B16A16Unorm: return PixelChannelEncoding.uNorm16;
case RenderingDevice.DataFormat.R16G16B16A16Snorm: return PixelChannelEncoding.sNorm16;
case RenderingDevice.DataFormat.R32G32B32A32Uint: return PixelChannelEncoding.uInt32;
case RenderingDevice.DataFormat.R32G32B32A32Sint: return PixelChannelEncoding.sInt32;
case RenderingDevice.DataFormat.R32G32B32A32Sfloat: return PixelChannelEncoding.sFloat32;
}
return PixelChannelEncoding.Unknown;
}
public static int GetNumChannels( RenderingDevice.DataFormat format )
{
switch ( format )
{
case RenderingDevice.DataFormat.R8G8B8Sint:
case RenderingDevice.DataFormat.R16G16B16Uint:
case RenderingDevice.DataFormat.R16G16B16Sint:
case RenderingDevice.DataFormat.R16G16B16Sfloat:
case RenderingDevice.DataFormat.R16G16B16Unorm:
case RenderingDevice.DataFormat.R16G16B16Snorm:
case RenderingDevice.DataFormat.R32G32B32Uint:
case RenderingDevice.DataFormat.R32G32B32Sint:
case RenderingDevice.DataFormat.R32G32B32Sfloat:
return 3;
case RenderingDevice.DataFormat.R8G8B8A8Uint:
case RenderingDevice.DataFormat.R8G8B8A8Sint:
case RenderingDevice.DataFormat.R16G16B16A16Uint:
case RenderingDevice.DataFormat.R16G16B16A16Sint:
case RenderingDevice.DataFormat.R16G16B16A16Sfloat:
case RenderingDevice.DataFormat.R16G16B16A16Unorm:
case RenderingDevice.DataFormat.R16G16B16A16Snorm:
case RenderingDevice.DataFormat.R32G32B32A32Uint:
case RenderingDevice.DataFormat.R32G32B32A32Sint:
case RenderingDevice.DataFormat.R32G32B32A32Sfloat:
return 4;
}
return -1;
}
static void WriteUShort( ushort shortValue, byte[] output, int offset )
{
output[ offset + 0 ] = (byte)(shortValue & 0xFF);
output[ offset + 1 ] = (byte)((shortValue >> 8) & 0xFF);
}
static void WriteUNorm( float value, byte[] output, int offset )
{
var shortValue = (ushort)( Mathf.Clamp( value, 0.0f, 1.0f ) * 65535 );
WriteUShort( shortValue, output, offset );
}
static ushort FloatToHalf( float value )
{
uint fbits = BitConverter.SingleToUInt32Bits(value);
uint sign = (fbits >> 16) & 0x8000;
uint val = (fbits & 0x7FFFFFFF);
// NaN / Inf -> maximal darstellen
if ( val > 0x47FFEFFF )
{
return (ushort)(sign | 0x7FFF);
}
if ( val < 0x38800000) // Subnormal
{
uint mant = (val & 0x007FFFFF) | 0x00800000;
int exp = 113 - (int)(val >> 23);
mant = (mant >> exp);
return (ushort)(sign | (mant >> 13));
}
else
{
uint exp = (val >> 23) - 112;
uint mant = (val & 0x007FFFFF);
return (ushort)(sign | (exp << 10) | (mant >> 13));
}
}
static void WriteFloat16( float value, byte[] output, int offset )
{
ushort r = FloatToHalf( value );
WriteUShort( r, output, offset );
}
public static byte[] ColorToBytes( Color color, RenderingDevice.DataFormat format )
{
switch ( format )
{
case RenderingDevice.DataFormat.R8G8B8A8Uint:
{
var bytes = new byte[ 4 ];
bytes[ 0 ] = (byte) ( color.R * 255 );
bytes[ 1 ] = (byte) ( color.G * 255 );
bytes[ 2 ] = (byte) ( color.B * 255 );
bytes[ 3 ] = (byte) ( color.A * 255 );
return bytes;
}
case RenderingDevice.DataFormat.R16G16B16A16Unorm:
{
var bytes = new byte[ 8 ];
WriteUNorm( color.R, bytes, 0 );
WriteUNorm( color.G, bytes, 2 );
WriteUNorm( color.B, bytes, 4 );
WriteUNorm( color.A, bytes, 6 );
return bytes;
}
case RenderingDevice.DataFormat.R16G16B16A16Sfloat:
{
var bytes = new byte[ 8 ];
WriteFloat16( color.R, bytes, 0 );
WriteFloat16( color.G, bytes, 2 );
WriteFloat16( color.B, bytes, 4 );
WriteFloat16( color.A, bytes, 6 );
return bytes;
}
}
return null;
}
}
}

View File

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

View File

@ -21,8 +21,9 @@ namespace Rokojori
uniform.Binding = 0;
uniform.AddId( texture.rid );
var rd = context.renderingDevice;
var rid = UniformSetCacheRD.GetCache( context.shader.rid, (uint) setIndex, new Array<RDUniform> { uniform } );
var rid = context._CreateUniformSetRid( setIndex, uniform );
// UniformSetCacheRD.GetCache( context.shader.rid, (uint) setIndex, new Array<RDUniform> { uniform } );
// var rid = rd.UniformSetCreate( new Array<RDUniform>{ uniform }, effect.context.shader.rid, (uint) setIndex );
return new RDUniformSet( context, setIndex, rid );
@ -36,9 +37,8 @@ namespace Rokojori
uniform.AddId( sampler.rid );
uniform.AddId( texture.rid ) ;
var rd = context.renderingDevice;
var rid = UniformSetCacheRD.GetCache( context.shader.rid, (uint) setIndex, new Array<RDUniform>{ uniform } );
// var rid = UniformSetCacheRD.GetCache( context.shader.rid, (uint) setIndex, new Array<RDUniform>{ uniform } );
var rid = context._CreateUniformSetRid( setIndex, uniform );
// var rid = rd.UniformSetCreate( new Array<RDUniform>{ uniform }, effect.context.shader.rid, (uint) setIndex );
return new RDUniformSet( context, setIndex, rid );

View File

@ -17,6 +17,10 @@ namespace Rokojori
{
this._context = context;
this._rid = rid;
this._context.AddToCleanUp( this, GetType().Name + "@" + _rid );
context.Verbose( "Creating", GetType().Name, rid );
}
}

View File

@ -0,0 +1,93 @@
#[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;
void main( )
{
float treshold = 0.5;
ivec2 size = imageSize( inputImage );
ivec2 texelCoord = ivec2( gl_GlobalInvocationID.xy );
if ( any( greaterThanEqual( texelCoord, size ) ) )
{
return;
}
vec4 color = imageLoad( inputImage, texelCoord );
// color = vec4( 1.0, 0.0, 0.0, 0.0 );
if ( color.a >= treshold )
{
imageStore( outputImage, texelCoord, color );
return;
}
// else
// {
// imageStore( outputImage, texelCoord, vec4(1,1,1,1) );
// return;
// }
// if ( color.a <= treshold )
// {
// color = vec4( 1.0, 0.5, color.a, 1.0 );
// }
// else
// {
// color = vec4( 0.0, 1.0, 0.0, 1.0 );
// }
// imageStore( outputImage, texelCoord, color );
// imageStore( outputImage, texel_coord, vec4( color.a, color.a, color.a, 1.0 ) );
int kernelRadius = 16;
float closestDistance = kernelRadius * kernelRadius * 2;
vec4 closestColor = color;
for ( int x = -kernelRadius; x <= kernelRadius; x++ )
{
for ( int y = -kernelRadius; y <= kernelRadius; y++ )
{
ivec2 offset = ivec2( x, y );
float d = length( vec2( offset ) );
if ( d >= closestDistance )
{
continue;
}
ivec2 t = texelCoord + ivec2( x, y );
if ( t.x < 0 || t.y < 0 || ( any( greaterThanEqual( texelCoord, size ) ) ) )
{
continue;
}
vec4 nColor = imageLoad( inputImage, t );
if ( nColor.a < treshold )
{
continue;
}
closestDistance = d;
closestColor = nColor;
}
}
imageStore( outputImage, texelCoord, vec4( closestColor.rgb, color.a ) );
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://byc7b6xlw0fnj"
path="res://.godot/imported/AlphaColorDilation.glsl-7665d7fc960d5dbc00617ba2dd53045f.res"
[deps]
source_file="res://addons/rokojori_action_library/Runtime/Rendering/RenderGraph/Nodes/Processors/Color/AlphaColorDilation/AlphaColorDilation.glsl"
dest_files=["res://.godot/imported/AlphaColorDilation.glsl-7665d7fc960d5dbc00617ba2dd53045f.res"]
[params]

View File

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

View File

@ -12,12 +12,12 @@ uniform image2D outputImage;
layout( push_constant, std430 )
uniform Params
{
float amount;
float shiftAll;
float unshiftCenter;
vec2 rShift;
vec2 gShift;
vec2 bShift;
float amount;
float shiftAll;
float unshiftCenter;
} params;

View File

@ -11,7 +11,14 @@ uniform restrict writeonly image2D outputImage;
void main()
{
ivec2 imgSize = imageSize( inputImage );
ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy );
if ( any( greaterThanEqual( currentPosition, imgSize ) ) )
{
return;
}
vec4 currentPixel = imageLoad( inputImage, currentPosition );
imageStore( outputImage, currentPosition, currentPixel );

View File

@ -37,7 +37,7 @@ namespace Rokojori
if ( texture == null || scaledSize != texture.size )
{
AutoClean( texture, graph.context.renderingDevice );
format = RDTexture.FormatChangeSize( format, scaledSize );
format = RDTextureFormats.FormatChangeSize( format, scaledSize );
texture = RDTexture.Create( graph.context, format );
}
@ -63,6 +63,20 @@ namespace Rokojori
}
}
public class CEG_TextureCreator_Reference:CEG_TextureCreator
{
public RDTexture _texture;
public CEG_TextureCreator_Reference( RDTexture texture )
{
this._texture = texture;
}
public override RDTexture Create( RDTexture texture, RDGraph graph )
{
return _texture;
}
}
public class CEG_BufferTexture:RGGraphProcessor, RDGraphTextureSlotInput
@ -106,6 +120,20 @@ namespace Rokojori
return new CEG_BufferTexture( graph, new CEG_TextureCreator_FixedSize() );
}
public static CEG_BufferTexture FixedSize( RDGraph graph, Vector2I size )
{
var creator = new CEG_TextureCreator_FixedSize();
creator.format.Width = (uint) size.X;
creator.format.Height = (uint) size.Y;
return new CEG_BufferTexture( graph, creator );
}
public static CEG_BufferTexture From( RDGraph graph, RDTexture texture )
{
var creator = new CEG_TextureCreator_Reference( texture );
return new CEG_BufferTexture( graph, creator );
}
public override void Process()
{
_texture = _creator.Create( _texture, graph );

View File

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

View File

@ -0,0 +1,24 @@
#[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;
void main()
{
ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy );
vec4 currentPixel = imageLoad( inputImage, currentPosition );
ivec2 seedPosition = ivec2( packUnorm2x16( currentPixel.xy ), packUnorm2x16( currentPixel.zw ) );
vec4 originalPixel = imageLoad( originalImage, seedPosition );
imageStore(outputImage, currentPosition, vec4(originalPixel.xyz, originalPixel.a));
}

View File

@ -0,0 +1,14 @@
[remap]
importer="glsl"
type="RDShaderFile"
uid="uid://1ovj3jsq1vp6"
path="res://.godot/imported/JFA_Assign.glsl-fb7dfb3a0e8b719d928d34ea126deab2.res"
[deps]
source_file="res://addons/rokojori_action_library/Runtime/Rendering/RenderGraph/Nodes/Processors/JFA/JFA_Assign.glsl"
dest_files=["res://.godot/imported/JFA_Assign.glsl-fb7dfb3a0e8b719d928d34ea126deab2.res"]
[params]

View File

@ -10,18 +10,18 @@ layout( rgba16, set = 1, binding = 0 )
uniform restrict writeonly image2D outputImage;
layout( push_constant, std430 )
uniform Params
uniform Parameters
{
float alphaTreshold;
} params;
} parameters;
void main()
{
ivec2 currentPosition = ivec2( gl_GlobalInvocationID.xy );
vec4 currentPixel = imageLoad( inputImage, currentPosition );
if ( currentPixel.a < params.alphaTreshold )
if ( currentPixel.a < parameters.alphaTreshold )
{
vec4 packedZero = vec4( unpackUnorm2x16( 0 ), unpackUnorm2x16( 0 ) );
imageStore( outputImage, currentPosition, packedZero );

View File

@ -10,7 +10,11 @@ layout(rgba16, set = 1, binding = 0)
uniform restrict writeonly image2D outputImage;
layout(std430, set = 2, binding = 0)
buffer restrict readonly JumpDistanceBuffer { int jump; } jdb;
buffer restrict readonly DistanceParameters
{
int jump;
} distanceParameters;
void main()
{
@ -20,7 +24,7 @@ void main()
float distanceToClosestSeed = 1.0f / 0.0f;
vec4 closestSeed = vec4( unpackUnorm2x16( 0 ), unpackUnorm2x16( 0 ) );
ivec2 jdbJump = ivec2( jdb.jump, jdb.jump );
ivec2 jump = ivec2( distanceParameters.jump, distanceParameters.jump );
for ( int x = -1; x <= 1; x++ )
{
@ -28,7 +32,7 @@ void main()
{
ivec2 xy = ivec2( x, y );
ivec2 checkPosition = currentPosition + jdbJump * xy;
ivec2 checkPosition = currentPosition + jump * xy;
if ( checkPosition.x < 0 || checkPosition.y < 0 ||
checkPosition.x >= imageSize.x || checkPosition.y >= imageSize.y )

View File

@ -62,7 +62,7 @@ namespace Rokojori
var context = graph.context;
context.Clear();
context.CalculateComputeGroups( _groupSize );
context.CalculateSceneComputeGroups( _groupSize );
context.SetShaderAndPipeline( _shader, _pipeline );
_textureSlots.ForEach( t =>

View File

@ -10,6 +10,7 @@ namespace Rokojori
public static class Lists
{
public static bool IsOneOf<T>( T value, params T[] values )
{
for ( int i = 0; i < values.Length; i++ )
@ -239,6 +240,18 @@ namespace Rokojori
return ToList( elements );
}
public static List<T> SubList<T>( T[] elements, int offset, int length )
{
var list = new List<T>();
for ( int i = 0; i < length; i++ )
{
list.Add( elements[ i + offset ] );
}
return list;
}
public static List<T> ToList<T>( T[] array )
{
var list = new List<T>();