RenderStuff Updates
This commit is contained in:
parent
966cb7e28c
commit
66d24be2c1
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://ctj2rxanlda0d
|
|
@ -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();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://cl0fx4gpluvhh
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace Rokojori
|
|||
|
||||
protected override void ForAllViews()
|
||||
{
|
||||
context.CalculateComputeGroups( _groupSize );
|
||||
context.CalculateSceneComputeGroups( _groupSize );
|
||||
|
||||
SetConstants();
|
||||
}
|
||||
|
|
|
@ -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 ++;
|
||||
}
|
||||
);
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://bwinqvkypbchr
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 ) );
|
||||
|
||||
}
|
|
@ -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]
|
||||
|
|
@ -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 )
|
||||
{}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
uid://daimt0g1aluu4
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 )
|
||||
{}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
|
@ -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]
|
||||
|
|
@ -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 );
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 =>
|
||||
|
|
|
@ -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>();
|
||||
|
|
Loading…
Reference in New Issue